smbd/error.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    error packet handling
00004    Copyright (C) Andrew Tridgell 1992-1998
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 /* From lib/error.c */
00024 extern struct unix_error_map unix_dos_nt_errmap[];
00025 
00026 extern uint32 global_client_caps;
00027 
00028 /****************************************************************************
00029  Create an error packet from a cached error.
00030 ****************************************************************************/
00031  
00032 int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file)
00033 {
00034         write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
00035         int32 eclass = wbmpx->wr_errclass;
00036         int32 err = wbmpx->wr_error;
00037         NTSTATUS ntstatus = wbmpx->wr_status;
00038  
00039         /* We can now delete the auxiliary struct */
00040         SAFE_FREE(fsp->wbmpx_ptr);
00041         return error_packet(outbuf,eclass,err,ntstatus,line,file);
00042 }
00043 
00044 /****************************************************************************
00045  Create an error packet from errno.
00046 ****************************************************************************/
00047 
00048 int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_status, int line, const char *file)
00049 {
00050         int eclass=def_class;
00051         int ecode=def_code;
00052         NTSTATUS ntstatus = def_status;
00053         int i=0;
00054 
00055         if (errno != 0) {
00056                 DEBUG(3,("unix_error_packet: error string = %s\n",strerror(errno)));
00057   
00058                 while (unix_dos_nt_errmap[i].dos_class != 0) {
00059                         if (unix_dos_nt_errmap[i].unix_error == errno) {
00060                                 eclass = unix_dos_nt_errmap[i].dos_class;
00061                                 ecode = unix_dos_nt_errmap[i].dos_code;
00062                                 ntstatus = unix_dos_nt_errmap[i].nt_error;
00063                                 break;
00064                         }
00065                         i++;
00066                 }
00067         }
00068 
00069         return error_packet(outbuf,eclass,ecode,ntstatus,line,file);
00070 }
00071 
00072 BOOL use_nt_status(void)
00073 {
00074         return lp_nt_status_support() && (global_client_caps & CAP_STATUS32);
00075 }
00076 
00077 /****************************************************************************
00078  Create an error packet. Normally called using the ERROR() macro.
00079  Setting eclass and ecode only and status to NT_STATUS_OK forces DOS errors.
00080  Setting status only and eclass and ecode to zero forces NT errors.
00081  If the override errors are set they take precedence over any passed in values.
00082 ****************************************************************************/
00083 
00084 void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
00085 {
00086         BOOL force_nt_status = False;
00087         BOOL force_dos_status = False;
00088 
00089         if (eclass == (uint8)-1) {
00090                 force_nt_status = True;
00091         } else if (NT_STATUS_IS_DOS(ntstatus)) {
00092                 force_dos_status = True;
00093         }
00094 
00095         if (force_nt_status || (!force_dos_status && lp_nt_status_support() && (global_client_caps & CAP_STATUS32))) {
00096                 /* We're returning an NT error. */
00097                 if (NT_STATUS_V(ntstatus) == 0 && eclass) {
00098                         ntstatus = dos_to_ntstatus(eclass, ecode);
00099                 }
00100                 SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus));
00101                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES);
00102                 DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n",
00103                          file, line,
00104                          (int)CVAL(outbuf,smb_com),
00105                          smb_fn_name(CVAL(outbuf,smb_com)),
00106                          nt_errstr(ntstatus)));
00107         } else {
00108                 /* We're returning a DOS error only. */
00109                 if (NT_STATUS_IS_DOS(ntstatus)) {
00110                         eclass = NT_STATUS_DOS_CLASS(ntstatus);
00111                         ecode = NT_STATUS_DOS_CODE(ntstatus);
00112                 } else  if (eclass == 0 && NT_STATUS_V(ntstatus)) {
00113                         ntstatus_to_dos(ntstatus, &eclass, &ecode);
00114                 }
00115 
00116                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES);
00117                 SSVAL(outbuf,smb_rcls,eclass);
00118                 SSVAL(outbuf,smb_err,ecode);  
00119 
00120                 DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
00121                           file, line,
00122                           (int)CVAL(outbuf,smb_com),
00123                           smb_fn_name(CVAL(outbuf,smb_com)),
00124                           eclass,
00125                           ecode));
00126         }
00127 }
00128 
00129 int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
00130 {
00131         int outsize = set_message(outbuf,0,0,True);
00132         error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
00133         return outsize;
00134 }
00135 
00136 /*******************************************************************************
00137  Special error map processing needed for returning DOS errors on open calls.
00138 *******************************************************************************/
00139 
00140 int error_open(char *outbuf, NTSTATUS status, int line, const char *file)
00141 {
00142         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
00143                 /*
00144                  * We hit an existing file, and if we're returning DOS
00145                  * error codes OBJECT_NAME_COLLISION would map to
00146                  * ERRDOS/183, we need to return ERRDOS/80, see bug
00147                  * 4852.
00148                  */
00149                 return error_packet(outbuf, ERRDOS, ERRfilexists,
00150                                 NT_STATUS_OBJECT_NAME_COLLISION, line, file);
00151         }
00152         return error_packet(outbuf,0,0,status,line,file);
00153 }

Sambaに対してSat Aug 29 21:23:23 2009に生成されました。  doxygen 1.4.7