diff options
author | Gerald Carter <jerry@samba.org> | 2005-04-18 16:08:52 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2005-04-18 16:08:52 +0000 |
commit | 4bdbd8bd0742c2c6e4ef65d7030a710412ad6234 (patch) | |
tree | b0b63f76422bf70560832976c5e4174f01c70fb0 /source/smbd/error.c | |
parent | 65e71c35f782cb1c8a22c61e88f1f853b585b297 (diff) | |
download | samba-4bdbd8bd0742c2c6e4ef65d7030a710412ad6234.tar.gz samba-4bdbd8bd0742c2c6e4ef65d7030a710412ad6234.tar.xz samba-4bdbd8bd0742c2c6e4ef65d7030a710412ad6234.zip |
r6369: update release notes
sync with SAMBA_3_0 (r6365).
Getting ready for 3.0.15pre2
Diffstat (limited to 'source/smbd/error.c')
-rw-r--r-- | source/smbd/error.c | 145 |
1 files changed, 82 insertions, 63 deletions
diff --git a/source/smbd/error.c b/source/smbd/error.c index d611e0ef873..090a2f6d813 100644 --- a/source/smbd/error.c +++ b/source/smbd/error.c @@ -20,23 +20,44 @@ #include "includes.h" -/* these can be set by some functions to override the error codes */ -int unix_ERR_class=SMB_SUCCESS; -int unix_ERR_code=0; -NTSTATUS unix_ERR_ntstatus = NT_STATUS_OK; - /* From lib/error.c */ extern struct unix_error_map unix_dos_nt_errmap[]; +extern uint32 global_client_caps; +/* these can be set by some functions to override the error codes */ +static int override_ERR_class; +static int override_ERR_code; +static NTSTATUS override_ERR_ntstatus; + /**************************************************************************** - Ensure we don't have any errors cached. + Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors. + Setting status only and eclass and ecode to -1 forces NT errors. ****************************************************************************/ -void clear_cached_errors(void) +void set_saved_error_triple(int eclass, int ecode, NTSTATUS status) +{ + override_ERR_class = eclass; + override_ERR_code = ecode; + override_ERR_ntstatus = status; +} + +/**************************************************************************** + Return the current settings of the error triple. Return True if any are set. +****************************************************************************/ + +BOOL get_saved_error_triple(int *peclass, int *pecode, NTSTATUS *pstatus) { - unix_ERR_class = SMB_SUCCESS; - unix_ERR_code = 0; - unix_ERR_ntstatus = NT_STATUS_OK; + if (peclass) { + *peclass = override_ERR_class; + } + if (pecode) { + *pecode = override_ERR_code; + } + if (pstatus) { + *pstatus = override_ERR_ntstatus; + } + + return (override_ERR_class || !NT_STATUS_IS_OK(override_ERR_ntstatus)); } /**************************************************************************** @@ -46,36 +67,29 @@ void clear_cached_errors(void) 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; + NTSTATUS ntstatus = wbmpx->wr_status; /* We can now delete the auxiliary struct */ - free((char *)wbmpx); - fsp->wbmpx_ptr = NULL; - return error_packet(outbuf,NT_STATUS_OK,eclass,err,False,line,file); + SAFE_FREE(fsp->wbmpx_ptr); + return error_packet(outbuf,eclass,err,ntstatus,line,file); } /**************************************************************************** Create an error packet from errno. ****************************************************************************/ -int unix_error_packet(char *outbuf,int def_class,uint32 def_code, - int line, const char *file) +int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_status, int line, const char *file) { int eclass=def_class; int ecode=def_code; - NTSTATUS ntstatus = NT_STATUS_OK; + NTSTATUS ntstatus = def_status; int i=0; - if (unix_ERR_class != SMB_SUCCESS) { - eclass = unix_ERR_class; - ecode = unix_ERR_code; - ntstatus = unix_ERR_ntstatus; - unix_ERR_class = SMB_SUCCESS; - unix_ERR_code = 0; - unix_ERR_ntstatus = NT_STATUS_OK; - } else { + if (errno != 0) { + DEBUG(3,("unix_error_packet: error string = %s\n",strerror(errno))); + 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; @@ -87,39 +101,43 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, } } - return error_packet(outbuf,ntstatus,eclass,ecode,False,line,file); + return error_packet(outbuf,eclass,ecode,ntstatus,line,file); } /**************************************************************************** Create an error packet. Normally called using the ERROR() macro. + 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. ****************************************************************************/ -int error_packet(char *outbuf,NTSTATUS ntstatus, - uint8 eclass,uint32 ecode,BOOL force_dos, int line, const char *file) +int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) { int outsize = set_message(outbuf,0,0,True); - extern uint32 global_client_caps; + BOOL force_nt_status = False; + BOOL force_dos_status = False; + + if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) { + eclass = override_ERR_class; + ecode = override_ERR_code; + ntstatus = override_ERR_ntstatus; + override_ERR_class = SMB_SUCCESS; + override_ERR_code = 0; + override_ERR_ntstatus = NT_STATUS_OK; + } - if (errno != 0) - DEBUG(3,("error string = %s\n",strerror(errno))); - -#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 - - /* - * 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. - */ - - if ((lp_nt_status_support() || (SVAL(outbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) && (global_client_caps & CAP_STATUS32) && (!force_dos)) { - if (NT_STATUS_V(ntstatus) == 0 && eclass) + if (eclass == (uint8)-1) { + force_nt_status = True; + } else if (NT_STATUS_IS_INVALID(ntstatus)) { + 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) { ntstatus = dos_to_ntstatus(eclass, ecode); + } SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus)); SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n", @@ -127,22 +145,23 @@ int error_packet(char *outbuf,NTSTATUS ntstatus, (int)CVAL(outbuf,smb_com), smb_fn_name(CVAL(outbuf,smb_com)), nt_errstr(ntstatus))); - return outsize; - } - - if (eclass == 0 && NT_STATUS_V(ntstatus)) - 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)); + } else { + /* We're returning a DOS error only. */ + if (eclass == 0 && NT_STATUS_V(ntstatus)) { + 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)); + } return outsize; } |