Author: vlendec Date: 2006-05-19 19:50:33 +0000 (Fri, 19 May 2006) New Revision: 15720
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15720 Log: Steal the NT_STATUS_DOS trick to stash forced DOS error codes into NTSTATUS from Samba4. Get rid of set_saved_error_triple. The places where DOS and NTSTATUS codes are actually not mappable are made explicit in the code by looking at what kind of code is required. Volker Modified: trunk/source/include/nt_status.h trunk/source/include/nterr.h trunk/source/include/smb_macros.h trunk/source/smbd/error.c trunk/source/smbd/open.c trunk/source/smbd/process.c trunk/source/smbd/reply.c Changeset: Modified: trunk/source/include/nt_status.h =================================================================== --- trunk/source/include/nt_status.h 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/include/nt_status.h 2006-05-19 19:50:33 UTC (rev 15720) @@ -56,7 +56,6 @@ #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -#define NT_STATUS_IS_INVALID(x) (NT_STATUS_V(x) == 0xFFFFFFFF) #define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y)) #define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) #define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) @@ -67,4 +66,12 @@ }\ } while (0) +/* this defines special NTSTATUS codes to represent DOS errors. I + have chosen this macro to produce status codes in the invalid + NTSTATUS range */ +#define NT_STATUS_DOS(class, code) NT_STATUS(0xF1000000 | ((class)<<16) | code) +#define NT_STATUS_IS_DOS(status) ((NT_STATUS_V(status) & 0xFF000000) == 0xF1000000) +#define NT_STATUS_DOS_CLASS(status) ((NT_STATUS_V(status) >> 16) & 0xFF) +#define NT_STATUS_DOS_CODE(status) (NT_STATUS_V(status) & 0xFFFF) + #endif Modified: trunk/source/include/nterr.h =================================================================== --- trunk/source/include/nterr.h 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/include/nterr.h 2006-05-19 19:50:33 UTC (rev 15720) @@ -37,9 +37,6 @@ #define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) #define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) -/* Special "invalid" NT status code. */ -#define NT_STATUS_INVALID NT_STATUS(0xFFFFFFFF) - /* Win32 Error codes extracted using a loop in smbclient then printing a netmon sniff to a file. */ Modified: trunk/source/include/smb_macros.h =================================================================== --- trunk/source/include/smb_macros.h 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/include/smb_macros.h 2006-05-19 19:50:33 UTC (rev 15720) @@ -182,7 +182,6 @@ #define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__) #define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__) -#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_INVALID,__LINE__,__FILE__) #define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__) #define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__) #define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__) Modified: trunk/source/smbd/error.c =================================================================== --- trunk/source/smbd/error.c 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/smbd/error.c 2006-05-19 19:50:33 UTC (rev 15720) @@ -25,29 +25,11 @@ extern uint32 global_client_caps; /* these can be set by some functions to override the error codes */ -static int override_ERR_class; -static uint32 override_ERR_code; static NTSTATUS override_ERR_ntstatus; -/**************************************************************************** - 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 set_saved_error_triple(int eclass, int ecode, NTSTATUS status) -{ - override_ERR_class = eclass; - override_ERR_code = ecode; - override_ERR_ntstatus = status; -} - void set_saved_ntstatus(NTSTATUS status) { - uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */ override_ERR_ntstatus = status; - ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code); - override_ERR_class = tmp_eclass; - } /**************************************************************************** @@ -103,6 +85,10 @@ return error_packet(outbuf,eclass,ecode,ntstatus,line,file); } +BOOL use_nt_status(void) +{ + return lp_nt_status_support() && (global_client_caps & CAP_STATUS32); +} /**************************************************************************** Create an error packet. Normally called using the ERROR() macro. @@ -117,18 +103,14 @@ 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; + if (!NT_STATUS_IS_OK(override_ERR_ntstatus)) { ntstatus = override_ERR_ntstatus; - override_ERR_class = SMB_SUCCESS; - override_ERR_code = 0; override_ERR_ntstatus = NT_STATUS_OK; } if (eclass == (uint8)-1) { force_nt_status = True; - } else if (NT_STATUS_IS_INVALID(ntstatus)) { + } else if (NT_STATUS_IS_DOS(ntstatus)) { force_dos_status = True; } @@ -146,7 +128,10 @@ nt_errstr(ntstatus))); } else { /* We're returning a DOS error only. */ - if (eclass == 0 && NT_STATUS_V(ntstatus)) { + 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)) { ntstatus_to_dos(ntstatus, &eclass, &ecode); } Modified: trunk/source/smbd/open.c =================================================================== --- trunk/source/smbd/open.c 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/smbd/open.c 2006-05-19 19:50:33 UTC (rev 15720) @@ -1178,8 +1178,11 @@ if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) { /* OS/2 Workplace shell fix may be main code stream in a later * release. */ - set_saved_error_triple(ERRDOS, ERRcannotopen, - NT_STATUS_OBJECT_NAME_NOT_FOUND); + if (use_nt_status()) { + set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); + } else { + set_saved_ntstatus(NT_STATUS_DOS(ERRDOS, ERRcannotopen)); + } DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not " "supported.\n")); return NULL; @@ -1873,8 +1876,11 @@ DEBUG(5,("open_directory: FILE_CREATE " "requested for directory %s and it " "already exists.\n", fname )); - set_saved_error_triple(ERRDOS, ERRfilexists, - NT_STATUS_OBJECT_NAME_COLLISION); + if (use_nt_status()) { + set_saved_ntstatus(NT_STATUS_OBJECT_NAME_COLLISION); + } else { + set_saved_ntstatus(NT_STATUS_DOS(ERRDOS, ERRfilexists)); + } return NULL; } create_dir = True; Modified: trunk/source/smbd/process.c =================================================================== --- trunk/source/smbd/process.c 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/smbd/process.c 2006-05-19 19:50:33 UTC (rev 15720) @@ -958,7 +958,7 @@ if (flags & AS_GUEST) flags &= ~AS_USER; else - return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid)); + return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid))); } /* this code is to work around a bug is MS client 3 without Modified: trunk/source/smbd/reply.c =================================================================== --- trunk/source/smbd/reply.c 2006-05-19 18:37:35 UTC (rev 15719) +++ trunk/source/smbd/reply.c 2006-05-19 19:50:33 UTC (rev 15720) @@ -1367,7 +1367,7 @@ if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask, &share_mode, &create_disposition, &create_options)) { END_PROFILE(SMBopen); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } fsp = open_file_ntcreate(conn,fname,&sbuf, @@ -1490,7 +1490,7 @@ &create_disposition, &create_options)) { END_PROFILE(SMBopenX); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } fsp = open_file_ntcreate(conn,fname,&sbuf, @@ -4988,8 +4988,12 @@ END_PROFILE(SMBcopy); return ERROR_DOS(ERRDOS,error); } else { - if((errno == ENOENT) && (bad_path1 || bad_path2)) { - set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK); + if((errno == ENOENT) && (bad_path1 || bad_path2) && + !use_nt_status()) { + /* Samba 3.0.22 has ERRDOS/ERRbadpath in the + * DOS error code case + */ + set_saved_ntstatus(NT_STATUS_DOS(ERRDOS, ERRbadpath)); } END_PROFILE(SMBcopy); return(UNIXERROR(ERRDOS,error)); @@ -5222,7 +5226,7 @@ /* we don't support these - and CANCEL_LOCK makes w2k and XP reboot so I don't really want to be compatible! (tridge) */ - return ERROR_FORCE_DOS(ERRDOS, ERRnoatomiclocks); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); } if (locktype & LOCKING_ANDX_CANCEL_LOCK) {