1998-08-17 13:11:34 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
1998-08-17 13:11:34 +00: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"
2002-01-16 21:27:57 +00:00
/* From lib/error.c */
extern struct unix_error_map unix_dos_nt_errmap [ ] ;
2005-04-06 16:28:04 +00:00
extern uint32 global_client_caps ;
2004-06-09 00:43:43 +00:00
2001-10-19 00:56:03 +00:00
/****************************************************************************
Create an error packet from a cached error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-19 22:40:32 +00:00
int cached_error_packet ( const char * inbuf , char * outbuf , files_struct * fsp , int line , const char * file )
2001-10-19 00:56:03 +00:00
{
write_bmpx_struct * wbmpx = fsp - > wbmpx_ptr ;
int32 eclass = wbmpx - > wr_errclass ;
int32 err = wbmpx - > wr_error ;
2005-04-01 23:11:28 +00:00
NTSTATUS ntstatus = wbmpx - > wr_status ;
2001-10-19 00:56:03 +00:00
/* We can now delete the auxiliary struct */
2005-04-01 23:11:28 +00:00
SAFE_FREE ( fsp - > wbmpx_ptr ) ;
2007-04-19 22:40:32 +00:00
return error_packet ( inbuf , outbuf , eclass , err , ntstatus , line , file ) ;
2001-10-19 00:56:03 +00:00
}
1998-08-17 13:11:34 +00:00
/****************************************************************************
2002-01-16 21:27:57 +00:00
Create an error packet from errno .
1998-08-17 13:11:34 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-16 21:27:57 +00:00
2007-04-19 22:40:32 +00:00
int unix_error_packet ( const char * inbuf , char * outbuf , int def_class , uint32 def_code , NTSTATUS def_status , int line , const char * file )
1998-08-17 13:11:34 +00:00
{
2001-08-27 08:19:43 +00:00
int eclass = def_class ;
int ecode = def_code ;
2005-04-01 23:11:28 +00:00
NTSTATUS ntstatus = def_status ;
2001-08-27 08:19:43 +00:00
int i = 0 ;
2005-04-01 23:11:28 +00:00
if ( errno ! = 0 ) {
DEBUG ( 3 , ( " unix_error_packet: error string = %s \n " , strerror ( errno ) ) ) ;
2002-01-16 21:27:57 +00: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 08:19:43 +00:00
break ;
}
i + + ;
}
}
2007-04-19 22:40:32 +00:00
return error_packet ( inbuf , outbuf , eclass , ecode , ntstatus , line , file ) ;
1998-08-17 13:11:34 +00:00
}
2006-07-11 18:01:26 +00:00
BOOL use_nt_status ( void )
{
return lp_nt_status_support ( ) & & ( global_client_caps & CAP_STATUS32 ) ;
}
1998-08-17 13:11:34 +00:00
/****************************************************************************
2002-01-16 21:27:57 +00:00
Create an error packet . Normally called using the ERROR ( ) macro .
2005-04-01 23:11:28 +00:00
Setting eclass and ecode only and status to NT_STATUS_OK forces DOS errors .
Setting status only and eclass and ecode to zero forces NT errors .
If the override errors are set they take precedence over any passed in values .
1998-08-17 13:11:34 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-16 21:27:57 +00:00
2006-08-14 16:53:14 +00:00
void error_packet_set ( char * outbuf , uint8 eclass , uint32 ecode , NTSTATUS ntstatus , int line , const char * file )
1998-08-17 13:11:34 +00:00
{
2005-04-01 23:11:28 +00:00
BOOL force_nt_status = False ;
BOOL force_dos_status = False ;
if ( eclass = = ( uint8 ) - 1 ) {
force_nt_status = True ;
2006-07-11 18:01:26 +00:00
} else if ( NT_STATUS_IS_DOS ( ntstatus ) ) {
2005-04-01 23:11:28 +00:00
force_dos_status = True ;
}
if ( force_nt_status | | ( ! force_dos_status & & lp_nt_status_support ( ) & & ( global_client_caps & CAP_STATUS32 ) ) ) {
/* We're returning an NT error. */
if ( NT_STATUS_V ( ntstatus ) = = 0 & & eclass ) {
2001-08-27 08:19:43 +00:00
ntstatus = dos_to_ntstatus ( eclass , ecode ) ;
2005-04-01 23:11:28 +00:00
}
2001-08-27 17:52:23 +00:00
SIVAL ( outbuf , smb_rcls , NT_STATUS_V ( ntstatus ) ) ;
2001-08-27 08:19:43 +00:00
SSVAL ( outbuf , smb_flg2 , SVAL ( outbuf , smb_flg2 ) | FLAGS2_32_BIT_ERROR_CODES ) ;
2001-09-05 10:18:58 +00:00
DEBUG ( 3 , ( " error packet at %s(%d) cmd=%d (%s) %s \n " ,
file , line ,
2001-08-27 08:19:43 +00:00
( int ) CVAL ( outbuf , smb_com ) ,
smb_fn_name ( CVAL ( outbuf , smb_com ) ) ,
2002-03-17 04:36:35 +00:00
nt_errstr ( ntstatus ) ) ) ;
2005-04-01 23:11:28 +00:00
} else {
/* We're returning a DOS error only. */
2006-07-11 18:01:26 +00:00
if ( NT_STATUS_IS_DOS ( ntstatus ) ) {
eclass = NT_STATUS_DOS_CLASS ( ntstatus ) ;
ecode = NT_STATUS_DOS_CODE ( ntstatus ) ;
} else if ( eclass = = 0 & & NT_STATUS_V ( ntstatus ) ) {
2005-04-01 23:11:28 +00:00
ntstatus_to_dos ( ntstatus , & eclass , & ecode ) ;
}
SSVAL ( outbuf , smb_flg2 , SVAL ( outbuf , smb_flg2 ) & ~ FLAGS2_32_BIT_ERROR_CODES ) ;
SSVAL ( outbuf , smb_rcls , eclass ) ;
SSVAL ( outbuf , smb_err , ecode ) ;
DEBUG ( 3 , ( " error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d \n " ,
file , line ,
( int ) CVAL ( outbuf , smb_com ) ,
smb_fn_name ( CVAL ( outbuf , smb_com ) ) ,
eclass ,
ecode ) ) ;
}
2006-08-14 16:53:14 +00:00
}
2001-08-27 08:19:43 +00:00
2007-04-19 22:40:32 +00:00
int error_packet ( const char * inbuf , char * outbuf , uint8 eclass , uint32 ecode , NTSTATUS ntstatus , int line , const char * file )
2006-08-14 16:53:14 +00:00
{
2007-04-19 22:40:32 +00:00
int outsize = set_message ( inbuf , outbuf , 0 , 0 , True ) ;
2006-08-14 16:53:14 +00:00
error_packet_set ( outbuf , eclass , ecode , ntstatus , line , file ) ;
2001-08-27 08:19:43 +00:00
return outsize ;
1998-08-17 13:11:34 +00:00
}