1998-08-17 17:11:34 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-17 17:11:34 +04:00
error packet handling
Copyright ( C ) Andrew Tridgell 1992 - 1998
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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
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 .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
1998-08-17 17:44:05 +04:00
/* these can be set by some functions to override the error codes */
int unix_ERR_class = SMB_SUCCESS ;
int unix_ERR_code = 0 ;
2002-11-06 00:47:03 +03:00
NTSTATUS unix_ERR_ntstatus = NT_STATUS_OK ;
1998-08-17 17:44:05 +04:00
2002-01-17 00:27:57 +03:00
/* From lib/error.c */
extern struct unix_error_map unix_dos_nt_errmap [ ] ;
2001-10-19 04:56:03 +04:00
/****************************************************************************
Create an error packet from a cached error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cached_error_packet ( char * outbuf , files_struct * fsp , int line , const char * file )
{
write_bmpx_struct * wbmpx = fsp - > wbmpx_ptr ;
int32 eclass = wbmpx - > wr_errclass ;
int32 err = wbmpx - > wr_error ;
/* We can now delete the auxiliary struct */
free ( ( char * ) wbmpx ) ;
fsp - > wbmpx_ptr = NULL ;
2004-05-05 03:01:00 +04:00
return error_packet ( outbuf , NT_STATUS_OK , eclass , err , False , line , file ) ;
2001-10-19 04:56:03 +04:00
}
1998-08-17 17:11:34 +04:00
/****************************************************************************
2002-01-17 00:27:57 +03:00
Create an error packet from errno .
1998-08-17 17:11:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 00:27:57 +03:00
2001-09-05 14:18:58 +04:00
int unix_error_packet ( char * outbuf , int def_class , uint32 def_code ,
int line , const char * file )
1998-08-17 17:11:34 +04:00
{
2001-08-27 12:19:43 +04:00
int eclass = def_class ;
int ecode = def_code ;
2002-01-17 00:27:57 +03:00
NTSTATUS ntstatus = NT_STATUS_OK ;
2001-08-27 12:19:43 +04:00
int i = 0 ;
if ( unix_ERR_class ! = SMB_SUCCESS ) {
eclass = unix_ERR_class ;
ecode = unix_ERR_code ;
2002-11-06 00:47:03 +03:00
ntstatus = unix_ERR_ntstatus ;
2003-10-02 21:26:42 +04:00
unix_ERR_class = SMB_SUCCESS ;
unix_ERR_code = 0 ;
unix_ERR_ntstatus = NT_STATUS_OK ;
2001-08-27 12:19:43 +04:00
} else {
2002-01-17 00:27:57 +03:00
while ( unix_dos_nt_errmap [ i ] . dos_class ! = 0 ) {
if ( unix_dos_nt_errmap [ i ] . unix_error = = errno ) {
eclass = unix_dos_nt_errmap [ i ] . dos_class ;
ecode = unix_dos_nt_errmap [ i ] . dos_code ;
ntstatus = unix_dos_nt_errmap [ i ] . nt_error ;
2001-08-27 12:19:43 +04:00
break ;
}
i + + ;
}
}
2004-05-05 03:01:00 +04:00
return error_packet ( outbuf , ntstatus , eclass , ecode , False , line , file ) ;
1998-08-17 17:11:34 +04:00
}
/****************************************************************************
2002-01-17 00:27:57 +03:00
Create an error packet . Normally called using the ERROR ( ) macro .
1998-08-17 17:11:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-17 00:27:57 +03:00
2001-08-27 21:52:23 +04:00
int error_packet ( char * outbuf , NTSTATUS ntstatus ,
2004-05-05 03:01:00 +04:00
uint8 eclass , uint32 ecode , BOOL force_dos , int line , const char * file )
1998-08-17 17:11:34 +04:00
{
2001-08-27 12:19:43 +04:00
int outsize = set_message ( outbuf , 0 , 0 , True ) ;
extern uint32 global_client_caps ;
1998-08-17 17:11:34 +04:00
2001-08-27 12:19:43 +04:00
if ( errno ! = 0 )
DEBUG ( 3 , ( " error string = %s \n " , strerror ( errno ) ) ) ;
1998-08-17 17:11:34 +04:00
2003-10-02 21:26:42 +04:00
# if defined(DEVELOPER)
if ( unix_ERR_class ! = SMB_SUCCESS | | unix_ERR_code ! = 0 | | ! NT_STATUS_IS_OK ( unix_ERR_ntstatus ) )
smb_panic ( " logic error in error processing " ) ;
# endif
2003-10-02 04:55:22 +04:00
2002-02-28 00:46:53 +03:00
/*
* We can explicitly force 32 bit error codes even when the
* parameter " nt status " is set to no by pre - setting the
* FLAGS2_32_BIT_ERROR_CODES bit in the smb_flg2 outbuf .
* This is to allow work arounds for client bugs that are needed
* when talking with clients that normally expect nt status codes . JRA .
*/
2004-05-05 03:01:00 +04:00
if ( ( lp_nt_status_support ( ) | | ( SVAL ( outbuf , smb_flg2 ) & FLAGS2_32_BIT_ERROR_CODES ) ) & & ( global_client_caps & CAP_STATUS32 ) & & ( ! force_dos ) ) {
2002-02-28 00:46:53 +03:00
if ( NT_STATUS_V ( ntstatus ) = = 0 & & eclass )
2001-08-27 12:19:43 +04:00
ntstatus = dos_to_ntstatus ( eclass , ecode ) ;
2001-08-27 21:52:23 +04:00
SIVAL ( outbuf , smb_rcls , NT_STATUS_V ( ntstatus ) ) ;
2001-08-27 12:19:43 +04:00
SSVAL ( outbuf , smb_flg2 , SVAL ( outbuf , smb_flg2 ) | FLAGS2_32_BIT_ERROR_CODES ) ;
2001-09-05 14:18:58 +04:00
DEBUG ( 3 , ( " error packet at %s(%d) cmd=%d (%s) %s \n " ,
file , line ,
2001-08-27 12:19:43 +04:00
( int ) CVAL ( outbuf , smb_com ) ,
smb_fn_name ( CVAL ( outbuf , smb_com ) ) ,
2002-03-17 07:36:35 +03:00
nt_errstr ( ntstatus ) ) ) ;
2001-08-27 12:19:43 +04:00
return outsize ;
}
2002-02-28 00:46:53 +03:00
if ( eclass = = 0 & & NT_STATUS_V ( ntstatus ) )
2001-08-27 12:19:43 +04:00
ntstatus_to_dos ( ntstatus , & eclass , & ecode ) ;
SSVAL ( outbuf , smb_flg2 , SVAL ( outbuf , smb_flg2 ) & ~ FLAGS2_32_BIT_ERROR_CODES ) ;
2001-08-27 23:46:22 +04:00
SSVAL ( outbuf , smb_rcls , eclass ) ;
2001-08-27 12:19:43 +04:00
SSVAL ( outbuf , smb_err , ecode ) ;
2001-09-05 14:18:58 +04:00
DEBUG ( 3 , ( " error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d \n " ,
file , line ,
2001-08-27 12:19:43 +04:00
( int ) CVAL ( outbuf , smb_com ) ,
smb_fn_name ( CVAL ( outbuf , smb_com ) ) ,
eclass ,
ecode ) ) ;
return outsize ;
1998-08-17 17:11:34 +04:00
}