1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-21 12:59:09 +03:00

r6172: Tidy up error processing significantly. Remove unix_ERR_XXX global nastyness.

Jeremy.
This commit is contained in:
Jeremy Allison
2005-04-01 23:11:28 +00:00
committed by Gerald (Jerry) Carter
parent 981b44e600
commit d3379fe61b
12 changed files with 182 additions and 227 deletions

View File

@ -56,6 +56,7 @@ typedef uint32 WERROR;
#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))

View File

@ -37,6 +37,9 @@
#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. */

View File

@ -357,14 +357,14 @@ typedef struct time_info
} UTIME;
/* Structure used when SMBwritebmpx is active */
typedef struct
{
size_t wr_total_written; /* So we know when to discard this */
int32 wr_timeout;
int32 wr_errclass;
int32 wr_error; /* Cached errors */
BOOL wr_mode; /* write through mode) */
BOOL wr_discard; /* discard all further data */
typedef struct {
size_t wr_total_written; /* So we know when to discard this */
int32 wr_timeout;
int32 wr_errclass; /* Cached errors */
int32 wr_error; /* Cached errors */
NTSTATUS wr_status; /* Cached errors */
BOOL wr_mode; /* write through mode) */
BOOL wr_discard; /* discard all further data */
} write_bmpx_struct;
typedef struct write_cache
@ -1384,13 +1384,6 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
*/
#define COPYBUF_SIZE (8*1024)
/*
* Values used to override error codes.
*/
extern int unix_ERR_class;
extern int unix_ERR_code;
extern NTSTATUS unix_ERR_ntstatus;
/*
* Used in chaining code.
*/

View File

@ -97,9 +97,6 @@
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
return(ERROR_DOS(ERRDOS,ERRbadaccess))
#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
return(CACHED_ERROR(fsp))
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
@ -158,25 +155,23 @@
#define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
#define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
/* Macro to cache an error in a write_bmpx_struct */
#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
w->wr_discard = True, -1)
/* Macro to test if an error has been cached for this fnum */
#define HAS_CACHED_ERROR(fsp) ((fsp)->wbmpx_ptr && \
(fsp)->wbmpx_ptr->wr_discard)
/* Macro to turn the cached error into an error packet */
#define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__)
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
#define ERROR_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,False,__LINE__,__FILE__)
#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,True,__LINE__,__FILE__)
#define ERROR_NT(status) error_packet(outbuf,status,0,0,False,__LINE__,__FILE__)
#define ERROR_BOTH(status,class,code) error_packet(outbuf,status,class,code,False,__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__)
/* this is how errors are generated */
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
#define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x))

View File

@ -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)
{
unix_ERR_class = SMB_SUCCESS;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
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)
{
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 (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
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;
}
/*
* 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 (eclass == (uint8)-1) {
force_nt_status = True;
} else if (NT_STATUS_IS_INVALID(ntstatus)) {
force_dos_status = True;
}
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 (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;
}
} else {
/* We're returning a DOS error only. */
if (eclass == 0 && NT_STATUS_V(ntstatus)) {
ntstatus_to_dos(ntstatus, &eclass, &ecode);
}
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);
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));
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;
}

View File

@ -95,15 +95,13 @@ files_struct *file_new(connection_struct *conn)
}
DEBUG(0,("ERROR! Out of file structures\n"));
unix_ERR_class = ERRSRV;
unix_ERR_code = ERRnofids;
set_saved_error_triple(ERRSRV, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES);
return NULL;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
unix_ERR_class = ERRSRV;
unix_ERR_code = ERRnofids;
set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
return NULL;
}

View File

@ -889,10 +889,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(conn, file_attributes);
SSVAL(outbuf, smb_flg2,
SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
@ -909,7 +907,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
END_PROFILE(SMBntcreateX);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@ -1493,8 +1490,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(conn, file_attributes);
SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
@ -1510,7 +1506,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
restore_case_semantics(conn, file_attributes);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@ -1782,12 +1777,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&access_mode,&smb_action);
if (!fsp1) {
status = NT_STATUS_ACCESS_DENIED;
if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
status = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
get_saved_error_triple(NULL, NULL, &status);
if (NT_STATUS_IS_OK(status)) {
status = NT_STATUS_ACCESS_DENIED;
}
set_saved_error_triple(0, 0, NT_STATUS_OK);
return status;
}
@ -1796,12 +1790,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&access_mode,&smb_action);
if (!fsp2) {
status = NT_STATUS_ACCESS_DENIED;
if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
status = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
get_saved_error_triple(NULL, NULL, &status);
if (NT_STATUS_IS_OK(status)) {
status = NT_STATUS_ACCESS_DENIED;
}
set_saved_error_triple(0, 0, NT_STATUS_OK);
close_file(fsp1,False);
return status;
}
@ -1907,7 +1900,6 @@ int reply_ntrename(connection_struct *conn,
END_PROFILE(SMBntrename);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return ERROR_NT(status);

View File

@ -76,9 +76,7 @@ static void check_for_pipe(const char *fname)
strlower_m(s);
if (strstr(s,"pipe/")) {
DEBUG(3,("Rejecting named pipe open for %s\n",fname));
unix_ERR_class = ERRSRV;
unix_ERR_code = ERRaccess;
unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
set_saved_error_triple(ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED);
}
}
@ -250,9 +248,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
/* Don't create files with Microsoft wildcard characters. */
if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRinvalidname;
unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
set_saved_error_triple(ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID);
return False;
}
@ -487,9 +483,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
fname ));
/* Use errno to map to correct error. */
unix_ERR_class = SMB_SUCCESS;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
return False;
}
@ -529,10 +523,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
(!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
fname ));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@ -557,10 +548,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
fname ));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@ -573,18 +561,14 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
fname ));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
#if 0
/* Bluarc test may need this ... needs further investigation. */
if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
#endif
@ -614,10 +598,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
deny_mode,old_deny_mode,old_open_mode,
(int)share->pid,fname, fcbopen, *flags, access_allowed));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@ -768,10 +749,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
SAFE_FREE(old_shares);
errno = EACCES;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return -1;
}
@ -835,9 +813,7 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n"
if (del_share_entry(dev, inode, &broken_entry->entry, NULL) == -1) {
free_broken_entry_list(broken_entry_list);
errno = EACCES;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return -1;
}
@ -1104,9 +1080,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
delete_defered_open_entry_record(conn, dib.dev, dib.inode);
unlock_share_entry(conn, dib.dev, dib.inode);
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return NULL;
}
/* Ensure we don't reprocess this message. */
@ -1136,11 +1110,8 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
break;
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRinvalidparam;
unix_ERR_ntstatus = NT_STATUS_INVALID_LOCK_SEQUENCE;
/* need to reset errno or DEVELOPER will cause us to coredump */
errno = 0;
/* Cause caller to force dos errors. */
set_saved_error_triple(ERRDOS, ERRbadaccess, NT_STATUS_INVALID);
return NULL;
}
@ -1163,13 +1134,9 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
/* this is for OS/2 long file names - say we don't support them */
if (strstr(fname,".+,;=[].")) {
unix_ERR_class = ERRDOS;
/* OS/2 Workplace shell fix may be main code stream in a later release. */
unix_ERR_code = ERRcannotopen;
unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_NOT_FOUND;
set_saved_error_triple(ERRDOS, ERRcannotopen, NT_STATUS_OBJECT_NAME_NOT_FOUND);
DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n"));
/* need to reset errno or DEVELOPER will cause us to coredump */
errno = 0;
return NULL;
}
@ -1232,11 +1199,8 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
break;
default:
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRinvalidparam;
unix_ERR_ntstatus = NT_STATUS_INVALID_LOCK_SEQUENCE;
/* need to reset errno or DEVELOPER will cause us to coredump */
errno = 0;
/* Force DOS error. */
set_saved_error_triple(ERRDOS, ERRinvalidparam, NT_STATUS_INVALID);
return NULL;
}
@ -1311,9 +1275,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
if (!fsp_open && errno) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRnoaccess;
unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
/* Default error. */
set_saved_error_triple(ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED);
}
/*
@ -1321,9 +1284,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* the braindead 1 second delay.
*/
if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
/* The fsp->open_time here represents the current time of day. */
defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
if (!internal_only_open) {
NTSTATUS status;
get_saved_error_triple(NULL, NULL, &status);
if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
/* The fsp->open_time here represents the current time of day. */
defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
}
}
unlock_share_entry(conn, dev, inode);
@ -1333,9 +1300,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* We have detected a sharing violation here
* so return the correct error code
*/
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
}
file_free(fsp);
return NULL;
@ -1407,7 +1372,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* the braindead 1 second delay.
*/
if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
NTSTATUS status;
get_saved_error_triple(NULL, NULL, &status);
if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
/* The fsp->open_time here represents the current time of day. */
defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
}
@ -1419,9 +1386,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* We have detected a sharing violation here, so
* return the correct code.
*/
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return NULL;
}
@ -1549,9 +1514,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
fd_close(conn,fsp);
file_free(fsp);
ntstatus_to_dos(result, &u_e_c, &u_e_code);
unix_ERR_ntstatus = result;
unix_ERR_class = u_e_c;
unix_ERR_code = u_e_code;
set_saved_error_triple(u_e_c, u_e_code, result);
return NULL;
}
}
@ -1704,7 +1667,7 @@ files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STR
fname, strerror(errno) ));
file_free(fsp);
/* Ensure we return the correct NT status to the client. */
unix_ERR_ntstatus = status;
set_saved_error_triple(0, 0, status);
return NULL;
}

View File

@ -934,6 +934,9 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
abort();
}
/* We know we have no saved errors here. */
set_saved_error_triple(0, 0, NT_STATUS_OK);
if( DEBUGLVL( 3 ) ) {
dbgtext( "oplock_break: returning success for " );
dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, file_id );

View File

@ -211,6 +211,7 @@ BOOL open_was_deferred(uint16 mid)
for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
if (SVAL(pml->buf.data,smb_mid) == mid) {
set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
return True;
}
}
@ -859,6 +860,8 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
pid = sys_getpid();
errno = 0;
set_saved_error_triple(0, 0, NT_STATUS_OK);
last_message = type;
/* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */

View File

@ -1206,7 +1206,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBopen);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@ -1304,7 +1303,6 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
END_PROFILE(SMBopenX);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@ -1453,7 +1451,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBcreate);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@ -1537,7 +1534,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBctemp);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@ -1599,20 +1595,19 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
return NT_STATUS_OK;
/* We need a better way to return NT status codes from open... */
unix_ERR_class = 0;
unix_ERR_code = 0;
set_saved_error_triple(0, 0, NT_STATUS_OK);
fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
if (!fsp) {
NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
ret = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
return ret;
NTSTATUS ret;
if (get_saved_error_triple(NULL, NULL, &ret)) {
set_saved_error_triple(0, 0, NT_STATUS_OK);
return ret;
}
set_saved_error_triple(0, 0, NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
return NT_STATUS_OK;
@ -1672,22 +1667,19 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_
don't do it here as we'll get it wrong. */
/* We need a better way to return NT status codes from open... */
unix_ERR_class = 0;
unix_ERR_code = 0;
set_saved_error_triple(0, 0, NT_STATUS_OK);
fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
if (!fsp) {
NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
ret = unix_ERR_ntstatus;
else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
ret = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
unix_ERR_ntstatus = NT_STATUS_OK;
return ret;
NTSTATUS ret;
if (get_saved_error_triple(NULL, NULL, &ret)) {
set_saved_error_triple(0, 0, NT_STATUS_OK);
return ret;
}
set_saved_error_triple(0, 0, NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
}
@ -1856,7 +1848,6 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return ERROR_NT(status);
@ -3456,21 +3447,6 @@ NTSTATUS mkdir_internal(connection_struct *conn, const pstring directory, BOOL b
return map_nt_error_from_unix(errno);
}
/* The following 2 clauses set explicit DOS error codes. JRA. */
if (ms_has_wild(directory)) {
DEBUG(5,("mkdir_internal: failing create on filename %s with wildcards\n", directory));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRinvalidname;
return NT_STATUS_OBJECT_NAME_INVALID;
}
if( strchr_m(directory, ':')) {
DEBUG(5,("mkdir_internal: failing create on filename %s with colon in name\n", directory));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRinvalidname;
return NT_STATUS_NOT_A_DIRECTORY;
}
if (bad_path) {
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
@ -3521,6 +3497,12 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
unix_convert(directory,conn,0,&bad_path,&sbuf);
if( strchr_m(directory, ':')) {
DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
END_PROFILE(SMBmkdir);
return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
}
status = mkdir_internal(conn, directory,bad_path);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmkdir);
@ -3530,7 +3512,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (lp_inherit_owner(SNUM(conn))) {
/* Ensure we're checking for a symlink here.... */
/* We don't want to get caught by a symlink racer. */
if(SMB_VFS_LSTAT(conn,directory, &sbuf) != 0) {
END_PROFILE(SMBmkdir);
return(UNIXERROR(ERRDOS,ERRnoaccess));
@ -4328,7 +4310,6 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBmv);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return ERROR_NT(status);
@ -4592,8 +4573,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_DOS(ERRDOS,error);
} else {
if((errno == ENOENT) && (bad_path1 || bad_path2)) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK);
}
END_PROFILE(SMBcopy);
return(UNIXERROR(ERRDOS,error));
@ -5149,7 +5129,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
CHECK_ERROR(fsp);
if (HAS_CACHED_ERROR(fsp)) {
return(CACHED_ERROR(fsp));
}
tcount = SVAL(inbuf,smb_vwv1);
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
@ -5292,8 +5274,12 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
END_PROFILE(SMBwriteBs);
return(ERROR_DOS(ERRHRD,ERRdiskfull));
}
wbms->wr_errclass = ERRHRD;
wbms->wr_error = ERRdiskfull;
wbms->wr_status = NT_STATUS_DISK_FULL;
wbms->wr_discard = True;
END_PROFILE(SMBwriteBs);
return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
return -1;
}
/* Increment the total written, if this matches tcount

View File

@ -814,7 +814,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
talloc_destroy(ctx);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);