2000-04-25 18:04:06 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-04-25 18:04:06 +04:00
client error handling routines
Copyright ( C ) Andrew Tridgell 1994 - 1998
2003-04-15 18:42:06 +04:00
Copyright ( C ) Jelmer Vernooij 2003
2006-02-24 08:05:09 +03:00
Copyright ( C ) Jeremy Allison 2006
2011-06-25 17:14:25 +04:00
2000-04-25 18:04:06 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2000-04-25 18:04:06 +04:00
( at your option ) any later version .
2011-06-25 17:14:25 +04:00
2000-04-25 18:04:06 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2011-06-25 17:14:25 +04:00
2000-04-25 18:04:06 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2000-04-25 18:04:06 +04:00
*/
# include "includes.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2000-04-25 18:04:06 +04:00
2001-08-10 10:00:33 +04:00
/***************************************************************************
Return an error message - either an NT error , SMB error or a RAP error .
Note some of the NT errors are actually warnings or " informational " errors
in which case they can be safely ignored .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-24 08:05:09 +03:00
2003-01-03 11:28:12 +03:00
const char * cli_errstr ( struct cli_state * cli )
2000-04-25 18:04:06 +04:00
{
2007-11-11 17:30:01 +03:00
fstring cli_error_message ;
char * result ;
2001-12-10 22:48:43 +03:00
2002-02-13 19:44:49 +03:00
if ( ! cli - > initialised ) {
fstrcpy ( cli_error_message , " [Programmer's error] cli_errstr called on unitialized cli_stat struct! \n " ) ;
2007-11-11 17:30:01 +03:00
goto done ;
2002-02-13 19:44:49 +03:00
}
2001-12-10 22:48:43 +03:00
/* Case #1: RAP error */
if ( cli - > rap_error ) {
2011-07-03 13:21:50 +04:00
strlcpy ( cli_error_message , win_errstr ( W_ERROR ( cli - > rap_error ) ) ,
sizeof ( cli_error_message ) ) ;
2007-11-11 17:30:01 +03:00
goto done ;
2001-12-10 22:48:43 +03:00
}
2000-04-25 18:04:06 +04:00
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) & & NT_STATUS_IS_OK ( cli - > raw_status ) ) {
2011-07-08 12:52:22 +04:00
return nt_errstr ( NT_STATUS_CONNECTION_DISCONNECTED ) ;
}
2007-11-11 17:30:01 +03:00
2011-07-08 12:52:22 +04:00
return nt_errstr ( cli - > raw_status ) ;
2007-11-11 17:30:01 +03:00
done :
result = talloc_strdup ( talloc_tos ( ) , cli_error_message ) ;
SMB_ASSERT ( result ) ;
return result ;
2000-04-25 18:04:06 +04:00
}
2006-02-24 08:05:09 +03:00
/****************************************************************************
Return the 32 - bit NT status code from the last packet .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 21:52:23 +04:00
NTSTATUS cli_nt_error ( struct cli_state * cli )
2001-08-10 10:00:33 +04:00
{
2006-02-24 08:05:09 +03:00
/* Deal with socket errors first. */
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) ) {
2011-07-08 11:45:05 +04:00
return NT_STATUS_CONNECTION_DISCONNECTED ;
2006-02-24 08:05:09 +03:00
}
2011-07-08 12:52:22 +04:00
if ( NT_STATUS_IS_DOS ( cli - > raw_status ) ) {
int e_class = NT_STATUS_DOS_CLASS ( cli - > raw_status ) ;
int code = NT_STATUS_DOS_CODE ( cli - > raw_status ) ;
2005-06-25 00:25:18 +04:00
return dos_to_ntstatus ( e_class , code ) ;
2011-07-08 12:52:22 +04:00
}
2001-08-10 10:00:33 +04:00
2011-07-08 12:52:22 +04:00
return cli - > raw_status ;
2001-08-10 10:00:33 +04:00
}
2001-08-27 12:19:43 +04:00
2006-02-24 08:05:09 +03:00
/****************************************************************************
Return the DOS error from the last packet - an error class and an error
code .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 12:19:43 +04:00
void cli_dos_error ( struct cli_state * cli , uint8 * eclass , uint32 * ecode )
2000-04-25 18:04:06 +04:00
{
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) ) {
2011-07-08 11:45:05 +04:00
* eclass = ERRDOS ;
* ecode = ERRnotconnected ;
2006-02-24 08:05:09 +03:00
return ;
}
2000-04-25 18:04:06 +04:00
2011-07-08 12:52:22 +04:00
if ( ! NT_STATUS_IS_DOS ( cli - > raw_status ) ) {
ntstatus_to_dos ( cli - > raw_status , eclass , ecode ) ;
return ;
}
2000-04-25 18:04:06 +04:00
2011-07-08 12:52:22 +04:00
* eclass = NT_STATUS_DOS_CLASS ( cli - > raw_status ) ;
* ecode = NT_STATUS_DOS_CODE ( cli - > raw_status ) ;
2001-08-10 10:00:33 +04:00
}
2000-04-25 18:04:06 +04:00
2001-08-10 10:00:33 +04:00
/* Return a UNIX errno appropriate for the error received in the last
packet . */
int cli_errno ( struct cli_state * cli )
{
2006-02-24 08:47:19 +03:00
NTSTATUS status ;
2006-02-24 08:05:09 +03:00
if ( cli_is_nt_error ( cli ) ) {
2006-02-24 08:47:19 +03:00
status = cli_nt_error ( cli ) ;
2008-10-08 01:43:42 +04:00
return map_errno_from_nt_status ( status ) ;
2006-02-24 08:05:09 +03:00
}
2001-08-10 10:00:33 +04:00
2001-08-28 05:28:01 +04:00
if ( cli_is_dos_error ( cli ) ) {
2001-08-10 10:00:33 +04:00
uint8 eclass ;
uint32 ecode ;
cli_dos_error ( cli , & eclass , & ecode ) ;
2006-02-24 08:47:19 +03:00
status = dos_to_ntstatus ( eclass , ecode ) ;
2008-10-08 01:43:42 +04:00
return map_errno_from_nt_status ( status ) ;
2001-08-10 10:00:33 +04:00
}
2007-05-07 07:07:39 +04:00
/*
* Yuck ! A special case for this Vista error . Since its high - order
* byte isn ' t 0xc0 , it doesn ' t match cli_is_nt_error ( ) above .
*/
status = cli_nt_error ( cli ) ;
if ( NT_STATUS_V ( status ) = = NT_STATUS_V ( NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT ) ) {
return EACCES ;
}
2006-02-24 08:05:09 +03:00
/* for other cases */
return EINVAL ;
2001-08-10 10:00:33 +04:00
}
/* Return true if the last packet was in error */
2007-10-19 04:40:25 +04:00
bool cli_is_error ( struct cli_state * cli )
2001-08-10 10:00:33 +04:00
{
2006-02-24 08:05:09 +03:00
/* A socket error is always an error. */
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) ) {
return true ;
2006-02-24 08:05:09 +03:00
}
2003-07-30 22:57:37 +04:00
2011-07-08 12:52:22 +04:00
if ( NT_STATUS_IS_DOS ( cli - > raw_status ) ) {
/* Return error if error class in non-zero */
uint8_t rcls = NT_STATUS_DOS_CLASS ( cli - > raw_status ) ;
return rcls ! = 0 ;
}
2001-08-10 10:00:33 +04:00
2011-07-08 12:52:22 +04:00
return NT_STATUS_IS_ERR ( cli - > raw_status ) ;
2001-08-10 10:00:33 +04:00
}
/* Return true if the last error was an NT error */
2007-10-19 04:40:25 +04:00
bool cli_is_nt_error ( struct cli_state * cli )
2001-08-10 10:00:33 +04:00
{
2006-02-24 08:05:09 +03:00
/* A socket error is always an NT error. */
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) ) {
return true ;
2006-02-24 08:05:09 +03:00
}
2011-07-08 12:52:22 +04:00
return cli_is_error ( cli ) & & ! NT_STATUS_IS_DOS ( cli - > raw_status ) ;
2001-08-10 10:00:33 +04:00
}
/* Return true if the last error was a DOS error */
2007-10-19 04:40:25 +04:00
bool cli_is_dos_error ( struct cli_state * cli )
2001-08-10 10:00:33 +04:00
{
2006-02-24 08:05:09 +03:00
/* A socket error is always a DOS error. */
2011-07-11 18:25:18 +04:00
if ( ! cli_state_is_connected ( cli ) ) {
return true ;
2006-02-24 08:05:09 +03:00
}
2011-07-08 12:52:22 +04:00
return cli_is_error ( cli ) & & NT_STATUS_IS_DOS ( cli - > raw_status ) ;
2001-08-10 10:00:33 +04:00
}
2005-09-30 21:13:37 +04:00
2010-03-25 15:20:56 +03:00
bool cli_state_is_connected ( struct cli_state * cli )
{
if ( cli = = NULL ) {
return false ;
}
if ( ! cli - > initialised ) {
return false ;
}
2011-07-22 11:39:52 +04:00
if ( cli - > conn . fd = = - 1 ) {
2010-03-25 15:20:56 +03:00
return false ;
}
return true ;
}
2011-07-11 16:33:54 +04:00
void cli_state_disconnect ( struct cli_state * cli )
{
2011-07-22 11:39:52 +04:00
if ( cli - > conn . fd ! = - 1 ) {
close ( cli - > conn . fd ) ;
2011-07-11 16:33:54 +04:00
}
2011-07-22 11:39:52 +04:00
cli - > conn . fd = - 1 ;
2011-07-11 16:33:54 +04:00
}