summaryrefslogtreecommitdiff
path: root/source3/smbd/error.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-04-01 23:11:28 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:56:27 -0500
commit0557c6cba2a21c9df547fbc8ff4db2899bc1c171 (patch)
tree991fd0420cd111e03416f66ecbab723d2772f66f /source3/smbd/error.c
parentab8ffa822a38765301cb6a34dd917eb1c2963249 (diff)
downloadsamba-0557c6cba2a21c9df547fbc8ff4db2899bc1c171.tar.gz
samba-0557c6cba2a21c9df547fbc8ff4db2899bc1c171.tar.bz2
samba-0557c6cba2a21c9df547fbc8ff4db2899bc1c171.zip
r6172: Tidy up error processing significantly. Remove unix_ERR_XXX global nastyness.
Jeremy. (This used to be commit d3379fe61bb934082b51a37adac232a96bafcf46)
Diffstat (limited to 'source3/smbd/error.c')
-rw-r--r--source3/smbd/error.c143
1 files changed, 81 insertions, 62 deletions
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index d611e0ef87..6988d74f91 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -20,23 +20,43 @@
#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[];
+/* 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 +66,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 +100,44 @@ 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;
}