diff options
author | Andrew Tridgell <tridge@samba.org> | 2001-08-27 08:19:43 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2001-08-27 08:19:43 +0000 |
commit | e8e98c9ea0690e3acf1126b50882e59e1056c7b3 (patch) | |
tree | 2fa75bc825f7e5da041809fe49080e3319656506 | |
parent | 3820578473da81b7ae0dfa978605da809be59f62 (diff) | |
download | samba-e8e98c9ea0690e3acf1126b50882e59e1056c7b3.tar.gz samba-e8e98c9ea0690e3acf1126b50882e59e1056c7b3.tar.bz2 samba-e8e98c9ea0690e3acf1126b50882e59e1056c7b3.zip |
converted smbd to use NTSTATUS by default
major changes include:
- added NSTATUS type
- added automatic mapping between dos and nt error codes
- changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT()
these calls auto-translate to the client error code system
- got rid of the cached error code and the writebmpx code
We eventually will need to also:
- get rid of BOOL, so we don't lose error info
- replace all ERROR_DOS() calls with ERROR_NT() calls
but that is too much for one night
(This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518)
28 files changed, 1260 insertions, 1605 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 8e10722cf9..68de10959b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -130,7 +130,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/namequery.o libsmb/nmblib.o libsmb/clistr.o \ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ - libsmb/clioplock.o \ + libsmb/clioplock.o libsmb/errormap.o \ libsmb/passchange.o libsmb/unexpected.o $(RPC_PARSE_OBJ1) LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \ @@ -310,7 +310,7 @@ UMOUNT_OBJ = client/smbumount.o \ NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \ $(LIBSMB_OBJ) $(LIB_OBJ) -SMBTORTURE_OBJ = torture/torture.o torture/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ +SMBTORTURE_OBJ = torture/torture.o torture/nbio.o torture/scanner.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) MASKTEST_OBJ = torture/masktest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ diff --git a/source3/include/msdfs.h b/source3/include/msdfs.h index 2c0f9a19ba..0748577b0b 100644 --- a/source3/include/msdfs.h +++ b/source3/include/msdfs.h @@ -64,13 +64,13 @@ struct dfs_path #define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \ { if(((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES)) && \ dfs_redirect(name,conn)) \ - return(dfs_path_error(inbuf,outbuf)); } + return ERROR_NT(NT_STATUS_PATH_NOT_COVERED); } #define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf) \ { if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) || \ get_remote_arch()==RA_WIN95) \ if(dfs_findfirst_redirect(directory,conn)) \ - return(dfs_path_error(inbuf,outbuf)); } + return ERROR_NT(NT_STATUS_PATH_NOT_COVERED); } #define init_dfsroot(conn, inbuf, outbuf) \ { if(lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) \ diff --git a/source3/include/smb.h b/source3/include/smb.h index a4887e1529..d8b5540510 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -205,9 +205,10 @@ typedef struct nttime_info { uint32 low; uint32 high; - } NTTIME; +typedef uint32 NTSTATUS; + /* Allowable account control bits */ #define ACB_DISABLED 0x0001 /* 1 = User account disabled */ #define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */ @@ -370,7 +371,6 @@ typedef struct files_struct SMB_OFF_T size; mode_t mode; uint16 vuid; - write_bmpx_struct *wbmpx_ptr; write_cache *wcp; struct timeval open_time; int share_mode; diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index e1deaf58ea..0c66a8e7a9 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -67,16 +67,14 @@ #define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn) #define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \ - return(ERROR(ERRDOS,ERRbadfid)); \ + return(ERROR_DOS(ERRDOS,ERRbadfid)); \ else if((fsp)->fd == -1) \ - return(ERROR(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadaccess)) #define CHECK_READ(fsp) if (!(fsp)->can_read) \ - return(ERROR(ERRDOS,ERRbadaccess)) + return(ERROR_DOS(ERRDOS,ERRbadaccess)) #define CHECK_WRITE(fsp) if (!(fsp)->can_write) \ - return(ERROR(ERRDOS,ERRbadaccess)) -#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \ - return(CACHED_ERROR(fsp)) + return(ERROR_DOS(ERRDOS,ERRbadaccess)) /* translates a connection number into a service number */ #define SNUM(conn) ((conn)?(conn)->service:-1) @@ -134,22 +132,15 @@ #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(inbuf,outbuf,fsp,__LINE__) - /* these are the datagram types */ #define DGRAM_DIRECT_UNIQUE 0x10 -#define ERROR(class,x) error_packet(inbuf,outbuf,class,x,__LINE__) +#define ERROR_DOS(class,code) error_packet(outbuf,0,class,code,__LINE__) +#define ERROR_NT(status) error_packet(outbuf,status,0,0,__LINE__) +#define ERROR_BOTH(status,class,code) error_packet(outbuf,status,class,code,__LINE__) /* this is how errors are generated */ -#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,__LINE__) +#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__) #define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1)) diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b3933f41e0..87c8348853 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,6 +112,9 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; } + if (cli->capabilities & CAP_STATUS32) { + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 59a11dcc60..896360ce98 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -75,7 +75,6 @@ char *cli_errstr(struct cli_state *cli) int i; /* Case #1: 32-bit NT errors */ - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { uint32 status = IVAL(cli->inbuf,smb_rcls); @@ -90,7 +89,6 @@ char *cli_errstr(struct cli_state *cli) return cli_smb_errstr(cli); /* Case #3: RAP error */ - for (i = 0; rap_errmap[i].message != NULL; i++) { if (rap_errmap[i].err == cli->rap_error) { return rap_errmap[i].message; @@ -103,69 +101,45 @@ char *cli_errstr(struct cli_state *cli) return error_message; } -/* Return the 32-bit NT status code from the last packet */ +/* Return the 32-bit NT status code from the last packet */ uint32 cli_nt_error(struct cli_state *cli) { int flgs2 = SVAL(cli->inbuf,smb_flg2); if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { - - /* Eek! We've requested a NT error when the packet that - came back does not contain one. What do we return - here? */ - - DEBUG(1, ("ERROR: cli_nt_error() called to read a status code " - "from a packet that does not contain one!\n")); - - return NT_STATUS_UNSUCCESSFUL; + int class = CVAL(cli->inbuf,smb_rcls); + int code = SVAL(cli->inbuf,smb_err); + return dos_to_ntstatus(class, code); } return IVAL(cli->inbuf,smb_rcls); } + /* Return the DOS error from the last packet - an error class and an error code. */ - -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { int flgs2; char rcls; int code; - if (eclass) - *eclass = 0; - - if (num) - *num = 0; - - if(!cli->initialised) - return; - - if(!cli->inbuf) - return; + if(!cli->initialised) return; flgs2 = SVAL(cli->inbuf,smb_flg2); if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* Eek! We've requested a DOS error when the packet that - came back does not contain one. What do we return - here? */ - - DEBUG(1, ("ERROR: cli_dos_error() called to read a dos error " - "code from a packet that does not contain one!\n")); - + uint32 ntstatus = IVAL(cli->inbuf, smb_rcls); + ntstatus_to_dos(ntstatus, eclass, ecode); return; } rcls = CVAL(cli->inbuf,smb_rcls); code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) - return; - if (eclass) *eclass = rcls; - if (num ) *num = code; + if (ecode) *ecode = code; } /* Return a UNIX errno from a dos error class, error number tuple */ @@ -256,9 +230,7 @@ BOOL cli_is_error(struct cli_state *cli) uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* Return error is error bits are set */ - rcls = IVAL(cli->inbuf, smb_rcls); return (rcls & 0xF0000000) == 0xC0000000; } @@ -286,3 +258,4 @@ BOOL cli_is_dos_error(struct cli_state *cli) return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } + diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 4822508e38..6ae1014435 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -412,20 +412,25 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); /* allocate it */ - tdata = Realloc(*data,total_data); - if (!tdata) { - DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); - return False; + if (total_data) { + tdata = Realloc(*data,total_data); + if (!tdata) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); + return False; + } else { + *data = tdata; + } } - else - *data = tdata; - tparam = Realloc(*param,total_param); - if (!tparam) { - DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); - return False; + + if (total_param) { + tparam = Realloc(*param,total_param); + if (!tparam) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); + return False; + } else { + *param = tparam; + } } - else - *param = tparam; while (1) { this_data = SVAL(cli->inbuf,smb_ntr_DataCount); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 581af9b957..c0c586eceb 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1650,7 +1650,7 @@ int smbc_opendir(const char *fname) free(smbc_file_table[slot]); } smbc_file_table[slot] = NULL; - errno = cli_error(&srv->cli); + errno = cli_errno(&srv->cli); return -1; } diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index dc2f39e7d9..e21effe6eb 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -30,6 +30,8 @@ extern int DEBUGLEVEL; +#define ZERO_ZERO 0 + /* This contains elements that differentiate locks. The smbpid is a client supplied pid, and is essentially the locking context for this client */ @@ -116,6 +118,32 @@ static BOOL brl_conflict(struct lock_struct *lck1, return True; } +#if ZERO_ZERO +static BOOL brl_conflict1(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { + return False; + } + + if (brl_same_context(&lck1->context, &lck2->context) && + lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + return False; + } + + if (lck2->start == 0 && lck2->size == 0 && lck1->size != 0) { + return True; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + + return True; +} +#endif + /**************************************************************************** Check to see if this lock conflicts, but ignore our own locks on the same fnum only. @@ -231,6 +259,21 @@ void brl_shutdown(int read_only) tdb_close(tdb); } +#if ZERO_ZERO +/**************************************************************************** +compare two locks for sorting +****************************************************************************/ +static int lock_compare(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->start != lck2->start) return (lck1->start - lck2->start); + if (lck2->size != lck1->size) { + return ((int)lck1->size - (int)lck2->size); + } + return 0; +} +#endif + /**************************************************************************** Lock a range of bytes. ****************************************************************************/ @@ -249,10 +292,10 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; -#if 0 +#if !ZERO_ZERO if (start == 0 && size == 0) { - tdb_delete(tdb, kbuf); - return True; + DEBUG(0,("client sent 0/0 lock - please report this\n")); + return False; } #endif @@ -275,23 +318,27 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, if (brl_conflict(&locks[i], &lock)) { goto fail; } +#if ZERO_ZERO + if (lock.start == 0 && lock.size == 0 && + locks[i].size == 0) { + break; + } +#endif } } -#if 0 - if (start == 0 && size == 0) { - if (dbuf.dptr) free(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return True; - } -#endif - /* no conflicts - add it to the list of locks */ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); if (!tp) goto fail; else dbuf.dptr = tp; memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); dbuf.dsize += sizeof(lock); + +#if ZERO_ZERO + /* sort the lock list */ + qsort(dbuf.dptr, dbuf.dsize/sizeof(lock), sizeof(lock), lock_compare); +#endif + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); free(dbuf.dptr); @@ -337,6 +384,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); +#if ZERO_ZERO for (i=0; i<count; i++) { struct lock_struct *lock = &locks[i]; @@ -362,6 +410,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return True; } } +#endif locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 81b2e92f68..d6915140a5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -99,14 +99,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, - int *eclass,uint32 *ecode) +NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { BOOL ok = False; if (!lp_locking(SNUM(conn))) - return(True); + return NT_STATUS_NOPROBLEMO; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -142,31 +141,25 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, } } - if (!ok) { - *eclass = ERRDOS; - *ecode = ERRlock; - return False; - } - return True; /* Got lock */ + if (!ok) return NT_STATUS_FILE_LOCK_CONFLICT; + + return NT_STATUS_NOPROBLEMO; /* Got lock */ } /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset, - int *eclass,uint32 *ecode) +NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset) { BOOL ok = False; if (!lp_locking(SNUM(conn))) - return(True); + return NT_STATUS_NOPROBLEMO; if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { - *eclass = ERRDOS; - *ecode = ERRbadfid; - return False; + return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", @@ -183,17 +176,15 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); - *eclass = ERRDOS; - *ecode = ERRnotlocked; - return False; + return NT_STATUS_LOCK_NOT_GRANTED; } if (!lp_posix_locking(SNUM(conn))) - return True; + return NT_STATUS_NOPROBLEMO; (void)release_posix_lock(fsp, offset, count); - return True; /* Did unlock */ + return NT_STATUS_NOPROBLEMO; /* Did unlock */ } /**************************************************************************** diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 1fa16d4006..3377507ca3 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -23,7 +23,6 @@ extern int DEBUGLEVEL; extern pstring global_myname; -extern uint32 global_client_caps; #ifdef WITH_MSDFS @@ -598,17 +597,6 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) return reply_size; } -int dfs_path_error(char* inbuf, char* outbuf) -{ - enum remote_arch_types ra_type = get_remote_arch(); - BOOL NT_arch = ((ra_type==RA_WINNT) || (ra_type == RA_WIN2K)); - if(NT_arch && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32)) ) { - SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0,0xc0000000|NT_STATUS_PATH_NOT_COVERED)); - } - return(ERROR(ERRSRV,ERRbadpath)); -} - /********************************************************************** The following functions are called by the NETDFS RPC pipe functions **********************************************************************/ diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index 6545dc59c2..2ec8de6835 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -65,7 +65,6 @@ files_struct *print_fsp_open(connection_struct *conn) fsp->directory_delete_on_close = False; fsp->conn = conn; string_set(&fsp->fsp_name,print_job_fname(jobid)); - fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf); fsp->mode = sbuf.st_mode; diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index d37aa04761..a541f2f2b0 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -126,7 +126,7 @@ END { gotstart = 1; } - if( $0 ~ /^smb_iconv_t|^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) { + if( $0 ~ /^smb_iconv_t|^long|^char|^uint|^NTSTATUS|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) { gotstart = 1; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 48d3c8a24a..697e1df194 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -170,16 +170,13 @@ static void reply_lockingX_success(blocking_lock_record *blr) Return a generic lock fail error blocking call. *****************************************************************************/ -static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { char *outbuf = OutBuffer; char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); - if(eclass == 0) /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - - ERROR(eclass,ecode); + ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("generic_blocking_lock_error: send_smb failed.\n"); } @@ -189,72 +186,68 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i obtained first. *****************************************************************************/ -static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) { - char *inbuf = blr->inbuf; - files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; - uint16 lock_pid; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; - int i; - - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - /* - * Ensure we don't do a remove on the lock that just failed, - * as under POSIX rules, if we have a lock already there, we - * will delete it (and we shouldn't) ..... - */ - - for(i = blr->lock_num - 1; i >= 0; i--) { - int dummy1; - uint32 dummy2; - BOOL err; - - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); - - /* - * We know err cannot be set as if it was the lock - * request would never have been queued. JRA. - */ - - do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); - } - - generic_blocking_lock_error(blr, eclass, ecode); + char *inbuf = blr->inbuf; + files_struct *fsp = blr->fsp; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; + uint16 lock_pid; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + char *data; + int i; + + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + /* + * Ensure we don't do a remove on the lock that just failed, + * as under POSIX rules, if we have a lock already there, we + * will delete it (and we shouldn't) ..... + */ + + for(i = blr->lock_num - 1; i >= 0; i--) { + BOOL err; + + lock_pid = get_lock_pid( data, i, large_file_format); + count = get_lock_count( data, i, large_file_format); + offset = get_lock_offset( data, i, large_file_format, &err); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ + + do_unlock(fsp,conn,lock_pid,count,offset); + } + + generic_blocking_lock_error(blr, status); } /**************************************************************************** Return a lock fail error. *****************************************************************************/ -static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { - switch(blr->com_type) { - case SMBlock: - generic_blocking_lock_error(blr, eclass, ecode); - break; - case SMBlockread: - generic_blocking_lock_error(blr, eclass, ecode); - break; - case SMBlockingX: - reply_lockingX_error(blr, eclass, ecode); - break; - default: - DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } + switch(blr->com_type) { + case SMBlock: + case SMBlockread: + generic_blocking_lock_error(blr, status); + break; + case SMBlockingX: + reply_lockingX_error(blr, status); + break; + default: + DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } } /**************************************************************************** @@ -264,68 +257,68 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int static BOOL process_lockread(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - ssize_t nread = -1; - char *data, *p; - int outsize = 0; - SMB_OFF_T startpos; - size_t numtoread; - int eclass; - uint32 ecode; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = blr->fsp; - - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); - - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + ssize_t nread = -1; + char *data, *p; + int outsize = 0; + SMB_OFF_T startpos; + size_t numtoread; + NTSTATUS status; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = blr->fsp; + + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); + + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { - if((errno != EACCES) && (errno != EAGAIN)) { - /* - * We have other than a "can't get lock" POSIX - * error. Send an error. - * Return True so we get dequeued. - */ - - generic_blocking_lock_error(blr, eclass, ecode); - return True; - } - - /* - * Still waiting for lock.... - */ - - DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - nread = read_file(fsp,data,startpos,numtoread); - - if (nread < 0) { - generic_blocking_lock_error(blr,ERRDOS,ERRnoaccess); - return True; - } - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,5,0,True); - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - p = smb_buf(outbuf); - *p++ = 1; - SSVAL(p,0,nread); p += 2; - set_message_end(outbuf, p+nread); - - DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", - fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); - - send_blocking_reply(outbuf,outsize); - return True; + status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, + (SMB_BIG_UINT)startpos, READ_LOCK); + if (status != NT_STATUS_NOPROBLEMO) { + if ((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + generic_blocking_lock_error(blr, status); + return True; + } + + /* + * Still waiting for lock.... + */ + + DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + nread = read_file(fsp,data,startpos,numtoread); + + if (nread < 0) { + generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED); + return True; + } + + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,5,0,True); + + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + p = smb_buf(outbuf); + *p++ = 1; + SSVAL(p,0,nread); p += 2; + set_message_end(outbuf, p+nread); + + DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", + fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); + + send_blocking_reply(outbuf,outsize); + return True; } /**************************************************************************** @@ -335,52 +328,50 @@ static BOOL process_lockread(blocking_lock_record *blr) static BOOL process_lock(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - int outsize; - SMB_OFF_T count = 0, offset = 0; - int eclass; - uint32 ecode; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = blr->fsp; - - count = IVAL(inbuf,smb_vwv1); - offset = IVAL(inbuf,smb_vwv3); - - errno = 0; - if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { - if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Send an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get the lock - keep waiting. - */ - - DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - /* - * Success - we got the lock. - */ - - DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", - fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,0,0,True); - send_blocking_reply(outbuf,outsize); - return True; + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + int outsize; + SMB_OFF_T count = 0, offset = 0; + NTSTATUS status; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = blr->fsp; + + count = IVAL(inbuf,smb_vwv1); + offset = IVAL(inbuf,smb_vwv3); + + errno = 0; + status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, + (SMB_BIG_UINT)offset, WRITE_LOCK); + if (status != NT_STATUS_NOPROBLEMO) { + if((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, status); + return True; + } + /* + * Still can't get the lock - keep waiting. + */ + DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + /* + * Success - we got the lock. + */ + + DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", + fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); + + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,0,0,True); + send_blocking_reply(outbuf,outsize); + return True; } /**************************************************************************** @@ -390,75 +381,72 @@ static BOOL process_lock(blocking_lock_record *blr) static BOOL process_lockingX(blocking_lock_record *blr) { - char *inbuf = blr->inbuf; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - uint16 lock_pid; - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; - int eclass=0; - uint32 ecode=0; - - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(; blr->lock_num < num_locks; blr->lock_num++) { - BOOL err; - - lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); - count = get_lock_count( data, blr->lock_num, large_file_format); - offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); - - /* - * We know err cannot be set as if it was the lock - * request would never have been queued. JRA. - */ - errno = 0; - if(!do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), - &eclass, &ecode)) - break; - } - - if(blr->lock_num == num_locks) { - - /* - * Success - we got all the locks. - */ - - DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", - fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); - - reply_lockingX_success(blr); - return True; - - } else if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get all the locks - keep waiting. - */ - - DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ -Waiting....\n", blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); - - return False; + char *inbuf = blr->inbuf; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + files_struct *fsp = blr->fsp; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; + uint16 lock_pid; + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + char *data; + NTSTATUS status = 0; + + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(; blr->lock_num < num_locks; blr->lock_num++) { + BOOL err; + + lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); + count = get_lock_count( data, blr->lock_num, large_file_format); + offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ + errno = 0; + status = do_lock(fsp,conn,count,lock_pid,offset, + ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); + if (status != NT_STATUS_NOPROBLEMO) break; + } + + if(blr->lock_num == num_locks) { + /* + * Success - we got all the locks. + */ + + DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", + fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); + + reply_lockingX_success(blr); + return True; + } else if ((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Free any locks we had and return an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, status); + return True; + } + + /* + * Still can't get all the locks - keep waiting. + */ + + DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ +Waiting....\n", + blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); + + return False; } /**************************************************************************** @@ -523,7 +511,7 @@ void remove_pending_lock_requests_by_mid(int mid) DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); - blocking_lock_reply_error(blr,0,NT_STATUS_CANCELLED); + blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -588,7 +576,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -600,7 +588,7 @@ void process_blocking_lock_queue(time_t t) /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -611,7 +599,7 @@ void process_blocking_lock_queue(time_t t) /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); unbecome_user(); diff --git a/source3/smbd/close.c b/source3/smbd/close.c index dd1a25293d..1a98a8bca5 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -102,10 +102,6 @@ static int close_filestruct(files_struct *fsp) fsp->stat_open = False; conn->num_files_open--; - if(fsp->wbmpx_ptr) { - free((char *)fsp->wbmpx_ptr); - fsp->wbmpx_ptr = NULL; - } return ret; } diff --git a/source3/smbd/error.c b/source3/smbd/error.c index 472a8d8fd1..27dacda377 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -28,23 +28,6 @@ int unix_ERR_class=SMB_SUCCESS; int unix_ERR_code=0; -/**************************************************************************** - create an error packet from a cached error. -****************************************************************************/ -int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line) -{ - write_bmpx_struct *wbmpx = fsp->wbmpx_ptr; - - int32 eclass = wbmpx->wr_errclass; - int32 err = wbmpx->wr_error; - - /* We can now delete the auxiliary struct */ - free((char *)wbmpx); - fsp->wbmpx_ptr = NULL; - return error_packet(inbuf,outbuf,eclass,err,line); -} - - struct { int unixerror; @@ -79,68 +62,72 @@ struct /**************************************************************************** create an error packet from errno ****************************************************************************/ -int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line) +int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line) { - int eclass=def_class; - int ecode=def_code; - int i=0; - - if (unix_ERR_class != SMB_SUCCESS) - { - eclass = unix_ERR_class; - ecode = unix_ERR_code; - unix_ERR_class = SMB_SUCCESS; - unix_ERR_code = 0; - } - else - { - while (unix_smb_errmap[i].smbclass != 0) - { - if (unix_smb_errmap[i].unixerror == errno) - { - eclass = unix_smb_errmap[i].smbclass; - ecode = unix_smb_errmap[i].smbcode; - break; - } - i++; - } - } - - return(error_packet(inbuf,outbuf,eclass,ecode,line)); + int eclass=def_class; + int ecode=def_code; + int i=0; + + if (unix_ERR_class != SMB_SUCCESS) { + eclass = unix_ERR_class; + ecode = unix_ERR_code; + unix_ERR_class = SMB_SUCCESS; + unix_ERR_code = 0; + } else { + while (unix_smb_errmap[i].smbclass != 0) { + if (unix_smb_errmap[i].unixerror == errno) { + eclass = unix_smb_errmap[i].smbclass; + ecode = unix_smb_errmap[i].smbcode; + break; + } + i++; + } + } + + return error_packet(outbuf,0,eclass,ecode,line); } /**************************************************************************** create an error packet. Normally called using the ERROR() macro ****************************************************************************/ -int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line) +int error_packet(char *outbuf,uint32 ntstatus, + uint8 eclass,uint32 ecode,int line) { - int outsize = set_message(outbuf,0,0,True); - int cmd = CVAL(inbuf,smb_com); - int flgs2 = SVAL(outbuf,smb_flg2); - - if (errno != 0) - DEBUG(3,("error string = %s\n",strerror(errno))); - - if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES) - { - SIVAL(outbuf,smb_rcls,error_code); - - DEBUG( 3, ( "32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n", - line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf) ) ); - } - else - { - CVAL(outbuf,smb_rcls) = error_class; - SSVAL(outbuf,smb_err,error_code); - DEBUG( 3, ( "error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n", - line, - (int)CVAL(inbuf,smb_com), - smb_fn_name(CVAL(inbuf,smb_com)), - error_class, - error_code ) ); + int outsize = set_message(outbuf,0,0,True); + extern uint32 global_client_caps; - } + if (errno != 0) + DEBUG(3,("error string = %s\n",strerror(errno))); - return(outsize); + if (global_client_caps & CAP_STATUS32) { + if (ntstatus == 0 && eclass) { + ntstatus = dos_to_ntstatus(eclass, ecode); + } + SIVAL(outbuf,smb_rcls,ntstatus); + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); + DEBUG(3,("error packet at line %d cmd=%d (%s) %s\n", + line, + (int)CVAL(outbuf,smb_com), + smb_fn_name(CVAL(outbuf,smb_com)), + get_nt_error_msg(ntstatus))); + return outsize; + } + + if (eclass == 0 && ntstatus) { + ntstatus_to_dos(ntstatus, &eclass, &ecode); + } + + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES); + SVAL(outbuf,smb_rcls) = eclass; + SSVAL(outbuf,smb_err,ecode); + + DEBUG(3,("error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n", + line, + (int)CVAL(outbuf,smb_com), + smb_fn_name(CVAL(outbuf,smb_com)), + eclass, + ecode)); + + return outsize; } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index e853112bfe..a323261d88 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -36,7 +36,6 @@ extern fstring local_machine; #define NERR_notsupported 50 extern int smb_read_error; -extern uint32 global_client_caps; /******************************************************************* copies parameters and data, as needed, into the smb buffer @@ -98,21 +97,12 @@ void send_trans_reply(char *outbuf, align = ((this_lparam)%4); - set_message(outbuf,10,1+align+this_ldata+this_lparam,True); - - if (buffer_too_large) - { - /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */ - if (!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) { - /* Win9x version. */ - SSVAL(outbuf, smb_err, ERRmoredata); - SCVAL(outbuf, smb_rcls, ERRDOS); - } else { - SIVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - SIVAL(outbuf, smb_rcls, 0x80000000 | STATUS_BUFFER_OVERFLOW); - } + if (buffer_too_large) { + ERROR_NT(STATUS_BUFFER_OVERFLOW); } + set_message(outbuf,10,1+align+this_ldata+this_lparam,True); + copy_trans_params_and_data(outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); @@ -395,7 +385,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if((data = (char *)malloc(tdscnt)) == NULL) { DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt)); END_PROFILE(SMBtrans); - return(ERROR(ERRDOS,ERRnomem)); + return(ERROR_DOS(ERRDOS,ERRnomem)); } memcpy(data,smb_base(inbuf)+dsoff,dscnt); } @@ -404,7 +394,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if((params = (char *)malloc(tpscnt)) == NULL) { DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt)); END_PROFILE(SMBtrans); - return(ERROR(ERRDOS,ERRnomem)); + return(ERROR_DOS(ERRDOS,ERRnomem)); } memcpy(params,smb_base(inbuf)+psoff,pscnt); } @@ -414,7 +404,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) { DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16)))); END_PROFILE(SMBtrans); - return(ERROR(ERRDOS,ERRnomem)); + return(ERROR_DOS(ERRDOS,ERRnomem)); } for (i=0;i<suwcnt;i++) setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD); @@ -451,7 +441,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (setup) free(setup); END_PROFILE(SMBtrans); - return(ERROR(ERRSRV,ERRerror)); + return(ERROR_DOS(ERRSRV,ERRerror)); } show_msg(inbuf); @@ -528,7 +518,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (outsize == 0) { END_PROFILE(SMBtrans); - return(ERROR(ERRSRV,ERRnosupport)); + return(ERROR_DOS(ERRSRV,ERRnosupport)); } END_PROFILE(SMBtrans); diff --git a/source3/smbd/message.c b/source3/smbd/message.c index a5726d44f8..f2e88352ee 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -114,7 +114,7 @@ int reply_sends(connection_struct *conn, if (! (*lp_msg_command())) { END_PROFILE(SMBsends); - return(ERROR(ERRSRV,ERRmsgoff)); + return(ERROR_DOS(ERRSRV,ERRmsgoff)); } outsize = set_message(outbuf,0,0,True); @@ -153,7 +153,7 @@ int reply_sendstrt(connection_struct *conn, if (! (*lp_msg_command())) { END_PROFILE(SMBsendstrt); - return(ERROR(ERRSRV,ERRmsgoff)); + return(ERROR_DOS(ERRSRV,ERRmsgoff)); } outsize = set_message(outbuf,1,0,True); @@ -185,7 +185,7 @@ int reply_sendtxt(connection_struct *conn, if (! (*lp_msg_command())) { END_PROFILE(SMBsendtxt); - return(ERROR(ERRSRV,ERRmsgoff)); + return(ERROR_DOS(ERRSRV,ERRmsgoff)); } outsize = set_message(outbuf,0,0,True); @@ -216,7 +216,7 @@ int reply_sendend(connection_struct *conn, if (! (*lp_msg_command())) { END_PROFILE(SMBsendend); - return(ERROR(ERRSRV,ERRmsgoff)); + return(ERROR_DOS(ERRSRV,ERRmsgoff)); } outsize = set_message(outbuf,0,0,True); diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 5bc3522506..6eda7e39db 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -157,95 +157,97 @@ reply for the nt protocol ****************************************************************************/ static int reply_nt1(char *outbuf) { - /* dual names + lock_and_read + nt SMBs + remote API calls */ - int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_LEVEL_II_OPLOCKS| - (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) | - ((lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) ? - CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS : 0) | - (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0); - - -/* - other valid capabilities which we may support at some time... - CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS; - */ - - int secword=0; - BOOL doencrypt = SMBENCRYPT(); - time_t t = time(NULL); - struct cli_state *cli = NULL; - char cryptkey[8]; - char crypt_len = 0; - char *p, *q; - - if (lp_security() == SEC_SERVER) { - DEBUG(5,("attempting password server validation\n")); - cli = server_cryptkey(); - } else { - DEBUG(5,("not attempting password server validation\n")); - } - - if (cli) { - DEBUG(3,("using password server validation\n")); - doencrypt = ((cli->sec_mode & 2) != 0); - } else { - DEBUG(3,("not using password server validation\n")); - } - - if (doencrypt) { - crypt_len = 8; - if (!cli) { - generate_next_challenge(cryptkey); - } else { - memcpy(cryptkey, cli->cryptkey, 8); - set_challenge(cli->cryptkey); - } - } - - if (lp_readraw() && lp_writeraw()) { - capabilities |= CAP_RAW_MODE; - } - - - /* allow for disabling unicode */ - if (lp_unicode()) { - capabilities |= CAP_UNICODE; - } - + /* dual names + lock_and_read + nt SMBs + remote API calls */ + int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ| + CAP_LEVEL_II_OPLOCKS|CAP_STATUS32; + + int secword=0; + BOOL doencrypt = SMBENCRYPT(); + time_t t = time(NULL); + struct cli_state *cli = NULL; + char cryptkey[8]; + char crypt_len = 0; + char *p, *q; + + if (lp_security() == SEC_SERVER) { + DEBUG(5,("attempting password server validation\n")); + cli = server_cryptkey(); + } else { + DEBUG(5,("not attempting password server validation\n")); + } + + if (cli) { + DEBUG(3,("using password server validation\n")); + doencrypt = ((cli->sec_mode & 2) != 0); + } else { + DEBUG(3,("not using password server validation\n")); + } + + if (doencrypt) { + crypt_len = 8; + if (!cli) { + generate_next_challenge(cryptkey); + } else { + memcpy(cryptkey, cli->cryptkey, 8); + set_challenge(cli->cryptkey); + } + } + + if (lp_nt_smb_support()) { + capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS; + } + + if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) { + capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; + } + + if (SMB_OFF_T_BITS == 64) { + capabilities |= CAP_LARGE_FILES; + } + + if (lp_readraw() && lp_writeraw()) { + capabilities |= CAP_RAW_MODE; + } + + /* allow for disabling unicode */ + if (lp_unicode()) { + capabilities |= CAP_UNICODE; + } + #ifdef WITH_MSDFS - if(lp_host_msdfs()) - capabilities |= CAP_DFS; + if(lp_host_msdfs()) + capabilities |= CAP_DFS; #endif - - if (lp_security() >= SEC_USER) secword |= 1; - if (doencrypt) secword |= 2; - - set_message(outbuf,17,0,True); - - CVAL(outbuf,smb_vwv1) = secword; - SSVALS(outbuf,smb_vwv16+1,crypt_len); - - Protocol = PROTOCOL_NT1; - - SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ - SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */ - SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */ - SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */ - SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */ - SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */ - put_long_date(outbuf+smb_vwv11+1,t); - SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60); - - p = q = smb_buf(outbuf); - if (doencrypt) memcpy(p, cryptkey, 8); - p += 8; - p += srvstr_push(outbuf, p, global_myworkgroup, -1, - STR_UNICODE|STR_TERMINATE|STR_NOALIGN); - - SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */ - set_message_end(outbuf, p); - - return (smb_len(outbuf)+4); + + if (lp_security() >= SEC_USER) secword |= 1; + if (doencrypt) secword |= 2; + + set_message(outbuf,17,0,True); + + CVAL(outbuf,smb_vwv1) = secword; + SSVALS(outbuf,smb_vwv16+1,crypt_len); + + Protocol = PROTOCOL_NT1; + + SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ + SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */ + SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */ + SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */ + SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */ + SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */ + put_long_date(outbuf+smb_vwv11+1,t); + SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60); + + p = q = smb_buf(outbuf); + if (doencrypt) memcpy(p, cryptkey, 8); + p += 8; + p += srvstr_push(outbuf, p, global_myworkgroup, -1, + STR_UNICODE|STR_TERMINATE|STR_NOALIGN); + + SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */ + set_message_end(outbuf, p); + + return (smb_len(outbuf)+4); } /* these are the protocol lists used for auto architecture detection: diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 3c21ce1e1b..a2a979b776 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -54,16 +54,7 @@ static void change_notify_reply_packet(char *inbuf, uint32 error_code) memset(outbuf, '\0', sizeof(outbuf)); construct_reply_common(inbuf, outbuf); - /* - * If we're returning a 'too much in the directory changed' we need to - * set this is an NT error status flags. If we don't then the (probably - * untested) code in the NT redirector has a bug in that it doesn't re-issue - * the change notify.... Ah - I *love* it when I get so deeply into this I - * can even determine how MS failed to test stuff and why.... :-). JRA. - */ - - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - ERROR(0,error_code); + ERROR_NT(error_code); /* * Seems NT needs a transact command with an error code diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index f0195fc0dd..2981c6bfb2 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -84,10 +84,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err set_message(outbuf,18,0,True); if(nt_error != 0) { - /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - - ERROR(0,nt_error); + ERROR_NT(nt_error); } /* @@ -475,14 +472,14 @@ static int nt_open_pipe(char *fname, connection_struct *conn, /* See if it is one we want to handle. */ if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); for( i = 0; known_nt_pipes[i]; i++ ) if( strequal(fname,known_nt_pipes[i])) break; if ( known_nt_pipes[i] == NULL ) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); /* Strip \\ off the name. */ fname++; @@ -491,7 +488,7 @@ static int nt_open_pipe(char *fname, connection_struct *conn, p = open_rpc_pipe_p(fname, conn, vuid); if (!p) - return(ERROR(ERRSRV,ERRnofids)); + return(ERROR_DOS(ERRSRV,ERRnofids)); *ppnum = p->pnum; @@ -582,7 +579,7 @@ int reply_ntcreate_and_X(connection_struct *conn, return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize); } else { END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRbadaccess)); + return(ERROR_DOS(ERRDOS,ERRbadaccess)); } } @@ -594,7 +591,7 @@ int reply_ntcreate_and_X(connection_struct *conn, if((smb_ofun = map_create_disposition( create_disposition )) == -1) { END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRbadaccess)); + return(ERROR_DOS(ERRDOS,ERRbadaccess)); } /* @@ -610,7 +607,7 @@ int reply_ntcreate_and_X(connection_struct *conn, if(!dir_fsp) { END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); } if(!dir_fsp->is_directory) { @@ -621,12 +618,11 @@ int reply_ntcreate_and_X(connection_struct *conn, srvstr_pull(inbuf, fname, smb_buf(inbuf), sizeof(fname), -1, STR_TERMINATE); if( strchr_m(fname, ':')) { - SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); END_PROFILE(SMBntcreateX); - return(ERROR(0, NT_STATUS_OBJECT_PATH_NOT_FOUND)); + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); } /* @@ -662,7 +658,7 @@ int reply_ntcreate_and_X(connection_struct *conn, share_access, file_attributes)) == -1) { END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; @@ -753,7 +749,7 @@ int reply_ntcreate_and_X(connection_struct *conn, SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); END_PROFILE(SMBntcreateX); - return(ERROR(0, NT_STATUS_FILE_IS_A_DIRECTORY)); + return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY); } oplock_request = 0; @@ -812,7 +808,7 @@ int reply_ntcreate_and_X(connection_struct *conn, if (!fsp->is_directory && (fmode & aDIR)) { close_file(fsp,False); END_PROFILE(SMBntcreateX); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* @@ -904,7 +900,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, if(total_parameter_count < 54) { DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } srvstr_pull(inbuf, fname, params+53, sizeof(fname), -1, STR_TERMINATE); @@ -915,7 +911,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, /* Realloc the size of parameters and data we will return */ params = Realloc(*ppparams, 69); if(params == NULL) - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); *ppparams = params; @@ -1074,7 +1070,7 @@ static int call_nt_transact_create(connection_struct *conn, return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, bufsize, ppsetup, ppparams, ppdata); else - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } /* @@ -1083,7 +1079,7 @@ static int call_nt_transact_create(connection_struct *conn, if(total_parameter_count < 54) { DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count)); - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } flags = IVAL(params,0); @@ -1102,7 +1098,7 @@ static int call_nt_transact_create(connection_struct *conn, */ if((smb_ofun = map_create_disposition( create_disposition )) == -1) - return(ERROR(ERRDOS,ERRbadmem)); + return ERROR_DOS(ERRDOS,ERRbadmem); /* * Get the file name. @@ -1117,7 +1113,7 @@ static int call_nt_transact_create(connection_struct *conn, size_t dir_name_len; if(!dir_fsp) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); if(!dir_fsp->is_directory) { /* @@ -1127,11 +1123,10 @@ static int call_nt_transact_create(connection_struct *conn, srvstr_pull(inbuf, fname, params+53, sizeof(fname), -1, STR_TERMINATE); if( strchr_m(fname, ':')) { - SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_OBJECT_PATH_NOT_FOUND)); + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); } /* @@ -1163,7 +1158,7 @@ static int call_nt_transact_create(connection_struct *conn, if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access, share_access, file_attributes)) == -1) - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; @@ -1226,7 +1221,7 @@ static int call_nt_transact_create(connection_struct *conn, restore_case_semantics(file_attributes); SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_FILE_IS_A_DIRECTORY)); + return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY); } oplock_request = 0; @@ -1280,7 +1275,7 @@ static int call_nt_transact_create(connection_struct *conn, if (fmode & aDIR) { close_file(fsp,False); restore_case_semantics(file_attributes); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* @@ -1303,7 +1298,7 @@ static int call_nt_transact_create(connection_struct *conn, if (!set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION, &error_class, &error_code)) { close_file(fsp,False); restore_case_semantics(file_attributes); - return(ERROR(error_class, error_code)); + return ERROR_DOS(error_class, error_code); } restore_case_semantics(file_attributes); @@ -1311,7 +1306,7 @@ static int call_nt_transact_create(connection_struct *conn, /* Realloc the size of parameters and data we will return */ params = Realloc(*ppparams, 69); if(params == NULL) - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); *ppparams = params; @@ -1416,10 +1411,10 @@ static int call_nt_transact_notify_change(connection_struct *conn, DEBUG(3,("call_nt_transact_notify_change\n")); if(!fsp) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); if((!fsp->is_directory) || (conn != fsp->conn)) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); if (!change_notify_set(inbuf, fsp, conn, flags)) { return(UNIXERROR(ERRDOS,ERRbadfid)); @@ -1496,13 +1491,13 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, files_struct *fsp = file_fsp(params,0); if(!fsp) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name )); params = Realloc(*ppparams, 4); if(params == NULL) - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); *ppparams = params; @@ -1530,7 +1525,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, data = Realloc(*ppdata, sd_size); if(data == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *ppdata = data; @@ -1543,7 +1538,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, if ((mem_ctx = talloc_init()) == NULL) { DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n")); - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } prs_init(&pd, 0, mem_ctx, MARSHALL); @@ -1601,10 +1596,10 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, return(UNIXERROR(ERRDOS,ERRnoaccess)); if(total_parameter_count < 8) - return(ERROR(ERRDOS,ERRbadfunc)); + return ERROR_DOS(ERRDOS,ERRbadfunc); if((fsp = file_fsp(params,0)) == NULL) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); security_info_sent = IVAL(params,4); @@ -1612,7 +1607,7 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, (unsigned int)security_info_sent )); if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code)) - return (ERROR(error_class, error_code)); + return ERROR_DOS(error_class, error_code); send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0); return -1; @@ -1632,7 +1627,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n")); logged_message = True; /* Only print this once... */ } - return(ERROR(ERRSRV,ERRnosupport)); + return ERROR_DOS(ERRSRV,ERRnosupport); } /**************************************************************************** @@ -1674,7 +1669,7 @@ due to being in oplock break state.\n" )); if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) { END_PROFILE(SMBnttrans); - return (ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); } outsize = set_message(outbuf,0,0,True); @@ -1688,7 +1683,7 @@ due to being in oplock break state.\n" )); DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n", CVAL(inbuf, smb_wct), 19 + (setup_count/2))); END_PROFILE(SMBnttrans); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } /* Allocate the space for the setup, the maximum needed parameters and data */ @@ -1707,7 +1702,7 @@ due to being in oplock break state.\n" )); safe_free(data); DEBUG(0,("reply_nttrans : Out of memory\n")); END_PROFILE(SMBnttrans); - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } /* Copy the param and data bytes sent with this request into @@ -1761,7 +1756,7 @@ due to being in oplock break state.\n" )); if(setup) free(setup); END_PROFILE(SMBnttrans); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } /* Revise total_params and total_data in case they have changed downwards */ @@ -1837,7 +1832,7 @@ due to being in oplock break state.\n" )); if(data) free(data); END_PROFILE(SMBnttrans); - return (ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } /* As we do not know how many data packets will need to be diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 2e1ddb07fb..6a1eac7602 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -200,7 +200,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, fsp->directory_delete_on_close = False; fsp->conn = conn; string_set(&fsp->fsp_name,fname); - fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -969,8 +968,7 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, fsp->directory_delete_on_close = False; fsp->conn = conn; string_set(&fsp->fsp_name,fname); - fsp->wbmpx_ptr = NULL; - fsp->wcp = NULL; /* Write cache pointer. */ + fsp->wcp = NULL; /* Write cache pointer. */ conn->num_files_open++; @@ -1133,7 +1131,6 @@ files_struct *open_directory(connection_struct *conn, char *fname, fsp->directory_delete_on_close = False; fsp->conn = conn; string_set(&fsp->fsp_name,fname); - fsp->wbmpx_ptr = NULL; conn->num_files_open++; diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index c7e0c3a5e5..162ad1603d 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -59,7 +59,7 @@ int reply_open_pipe_and_X(connection_struct *conn, /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); DEBUG(4,("Opening pipe %s.\n", pipe_name)); @@ -69,7 +69,7 @@ int reply_open_pipe_and_X(connection_struct *conn, break; if (pipe_names[i].client_pipe == NULL) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); /* Strip \PIPE\ off the name. */ pstrcpy(fname, pipe_name + PIPELEN); @@ -89,7 +89,7 @@ int reply_open_pipe_and_X(connection_struct *conn, smb_ofun |= FILE_CREATE_IF_NOT_EXIST; p = open_rpc_pipe_p(fname, conn, vuid); - if (!p) return(ERROR(ERRSRV,ERRnofids)); + if (!p) return(ERROR_DOS(ERRSRV,ERRnofids)); /* Prepare the reply */ set_message(outbuf,15,0,True); @@ -125,7 +125,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) char *data; if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); data = smb_buf(inbuf) + 3; @@ -165,7 +165,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) char *data; if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); data = smb_base(inbuf) + smb_doff; @@ -225,7 +225,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) #endif if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); set_message(outbuf,12,0,True); data = smb_buf(outbuf); @@ -254,12 +254,12 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) int outsize = set_message(outbuf,0,0,True); if (!p) - return(ERROR(ERRDOS,ERRbadfid)); + return(ERROR_DOS(ERRDOS,ERRbadfid)); DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); if (!close_rpc_pipe_hnd(p, conn)) - return(ERROR(ERRDOS,ERRbadfid)); + return ERROR_DOS(ERRDOS,ERRbadfid); return(outsize); } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 2b75197c38..ce1e855e29 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -352,9 +352,9 @@ struct smb_message_struct /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER}, /* 0x1c */ { "SMBreadBs",NULL,AS_USER}, /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER}, -/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER}, -/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER}, -/* 0x20 */ { "SMBwritec",NULL,AS_USER}, +/* 0x1e */ { NULL,NULL,0}, +/* 0x1f */ { NULL,NULL,0}, +/* 0x20 */ { NULL,NULL,0}, /* 0x21 */ { NULL, NULL, 0 }, /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE }, /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER }, @@ -695,7 +695,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize /* does this protocol need a valid tree connection? */ if ((flags & AS_USER) && !conn) { - return ERROR(ERRSRV, ERRinvnid); + return ERROR_DOS(ERRSRV, ERRinvnid); } @@ -704,7 +704,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize if (flags & AS_GUEST) flags &= ~AS_USER; else - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); } /* this code is to work around a bug is MS client 3 without @@ -715,23 +715,23 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize /* does it need write permission? */ if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); /* ipc services are limited */ if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) { - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); } /* load service specific parameters */ if (conn && !become_service(conn,(flags & AS_USER)?True:False)) { - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); } /* does this protocol need to be run as guest? */ if ((flags & AS_GUEST) && (!become_guest() || !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) { - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); } last_inbuf = inbuf; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 02531bd1cd..236bb48ce9 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -162,9 +162,9 @@ work out what error to give to a failed connection static int connection_error(char *inbuf,char *outbuf,int ecode) { if (ecode == ERRnoipc || ecode == ERRnosuchshare) - return(ERROR(ERRDOS,ecode)); + return(ERROR_DOS(ERRDOS,ecode)); - return(ERROR(ERRSRV,ecode)); + return(ERROR_DOS(ERRSRV,ecode)); } @@ -272,7 +272,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (passlen > MAX_PASS_LEN) { overflow_attack(passlen); - return(ERROR(ERRDOS,ERRbuftoosmall)); + return(ERROR_DOS(ERRDOS,ERRbuftoosmall)); } memcpy(password,smb_buf(inbuf),passlen); @@ -295,7 +295,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt q = strchr_m(path+2,'\\'); if (!q) { END_PROFILE(SMBtconX); - return(ERROR(ERRDOS,ERRnosuchshare)); + return(ERROR_DOS(ERRDOS,ERRnosuchshare)); } fstrcpy(service,q+1); } @@ -391,7 +391,7 @@ int reply_unknown(char *inbuf,char *outbuf) DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n", smb_fn_name(type), type, type)); - return(ERROR(ERRSRV,ERRunknownsmb)); + return(ERROR_DOS(ERRSRV,ERRunknownsmb)); } @@ -418,7 +418,7 @@ int reply_ioctl(connection_struct *conn, break; default: END_PROFILE(SMBioctl); - return(ERROR(ERRSRV,ERRnosupport)); + return(ERROR_DOS(ERRSRV,ERRnosupport)); } outsize = set_message(outbuf,8,replysize+1,True); @@ -496,72 +496,50 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out ret = pdb_getsampwnam(sam_trust_acct, user); } else { DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); pdb_free_sam(sam_trust_acct); - return(ERROR(0, NT_STATUS_LOGON_FAILURE)); + return(ERROR_NT(NT_STATUS_LOGON_FAILURE)); } if (ret == False) { /* lkclXXXX: workstation entry doesn't exist */ DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); pdb_free_sam(sam_trust_acct); - return(ERROR(0, NT_STATUS_NO_SUCH_USER)); + return(ERROR_NT(NT_STATUS_NO_SUCH_USER)); } else { if ((smb_passlen != 24) || (smb_nt_passlen != 24)) { DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); pdb_free_sam(sam_trust_acct); - return(ERROR(0, NT_STATUS_LOGON_FAILURE)); + return(ERROR_NT(NT_STATUS_LOGON_FAILURE)); } if (!smb_password_ok(sam_trust_acct, &user_info, &server_info)) { DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - pdb_free_sam(sam_trust_acct); - return(ERROR(0, NT_STATUS_LOGON_FAILURE)); + pdb_free_sam(sam_trust_acct); + return(ERROR_NT(NT_STATUS_LOGON_FAILURE)); } acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct); pdb_free_sam(sam_trust_acct); if (acct_ctrl & ACB_DOMTRUST) { DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)); + return(ERROR_NT(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)); } if (acct_ctrl & ACB_SVRTRUST) { DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT)); + return(ERROR_NT(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT)); } if (acct_ctrl & ACB_WSTRUST) { DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user)); - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)); + return(ERROR_NT(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)); } } /* don't know what to do: indicate logon failure */ - SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0, NT_STATUS_LOGON_FAILURE)); + return(ERROR_NT(NT_STATUS_LOGON_FAILURE)); } -/**************************************************************************** - Return a bad password error configured for the correct client type. -****************************************************************************/ - -static int bad_password_error(char *inbuf,char *outbuf) -{ - - if (global_client_caps & CAP_STATUS32) { - SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0,NT_STATUS_LOGON_FAILURE)); - } - - return(ERROR(ERRSRV,ERRbadpw)); -} /**************************************************************************** reply to a session setup command @@ -598,7 +576,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int smb_apasslen = SVAL(inbuf,smb_vwv7); if (smb_apasslen > MAX_PASS_LEN) { overflow_attack(smb_apasslen); - return(ERROR(ERRDOS,ERRbuftoosmall)); + return(ERROR_DOS(ERRDOS,ERRbuftoosmall)); } memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); @@ -632,7 +610,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int if (passlen1 > MAX_PASS_LEN) { overflow_attack(passlen1); - return(ERROR(ERRDOS,ERRbuftoosmall)); + return ERROR_DOS(ERRDOS,ERRbuftoosmall); } passlen1 = MIN(passlen1, MAX_PASS_LEN); @@ -719,7 +697,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int alpha_strcpy(user, user, ". _-$", sizeof(user)); alpha_strcpy(domain, domain, ". _-", sizeof(domain)); if (strstr(user, "..") || strstr(domain,"..")) { - return bad_password_error(inbuf, outbuf); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } if (lp_security() == SEC_SHARE) { @@ -754,7 +732,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int if (!*user && !*smb_apasswd && !*domain) { DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n")); END_PROFILE(SMBsesssetupX); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } } @@ -825,9 +803,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int { if (lp_map_to_guest() == NEVER_MAP_TO_GUEST) { - DEBUG(1,("Rejecting user '%s': authentication failed\n", user)); - END_PROFILE(SMBsesssetupX); - return bad_password_error(inbuf,outbuf); + DEBUG(1,("Rejecting user '%s': authentication failed\n", user)); + END_PROFILE(SMBsesssetupX); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) @@ -836,7 +814,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int { DEBUG(1,("Rejecting user '%s': bad password\n", user)); END_PROFILE(SMBsesssetupX); - return bad_password_error(inbuf,outbuf); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } } @@ -889,7 +867,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); END_PROFILE(SMBsesssetupX); - return bad_password_error(inbuf,outbuf); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } gid = pw->pw_gid; uid = pw->pw_uid; @@ -905,7 +883,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest, full_name); if (sess_vuid == -1) { - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -949,28 +927,15 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size ok = S_ISDIR(sbuf.st_mode); } - if (!ok) - { + if (!ok) { /* We special case this - as when a Windows machine is parsing a path is steps through the components one at a time - if a component fails it expects ERRbadpath, not ERRbadfile. */ - if(errno == ENOENT) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - -#if 0 - /* Ugly - NT specific hack - maybe not needed ? (JRA) */ - if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && - (get_remote_arch() == RA_WINNT)) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbaddirectory; + if(errno == ENOENT) { + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } -#endif return(UNIXERROR(ERRDOS,ERRbadpath)); } @@ -1258,7 +1223,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return (UNIXERROR(ERRDOS,ERRnofids)); } END_PROFILE(SMBsearch); - return(ERROR(ERRDOS,ERRnofids)); + return ERROR_DOS(ERRDOS,ERRnofids); } dptr_set_wcard(dptr_num, strdup(mask)); } @@ -1375,7 +1340,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (status_len == 0) { END_PROFILE(SMBfclose); - return(ERROR(ERRSRV,ERRsrverror)); + return ERROR_DOS(ERRSRV,ERRsrverror); } memcpy(status,p,21); @@ -1446,7 +1411,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, DEBUG(3,("attempt to open a directory %s\n",fname)); close_file(fsp,False); END_PROFILE(SMBopen); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } outsize = set_message(outbuf,7,0,True); @@ -1505,7 +1470,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize); } else { END_PROFILE(SMBopenX); - return (ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); } } @@ -1538,7 +1503,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (fmode & aDIR) { close_file(fsp,False); END_PROFILE(SMBopenX); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* If the caller set the extended oplock request bit @@ -1798,139 +1763,140 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype) ****************************************************************************/ int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf, - int dirtype, char *name) + int dirtype, char *name) { - pstring directory; - pstring mask; - char *p; - int count=0; - int error = ERRnoaccess; - BOOL has_wild; - BOOL exists=False; - BOOL bad_path = False; - BOOL rc = True; - SMB_STRUCT_STAT sbuf; - - *directory = *mask = 0; - - rc = unix_convert(name,conn,0,&bad_path,&sbuf); - - p = strrchr_m(name,'/'); - if (!p) { - pstrcpy(directory,"./"); - pstrcpy(mask,name); - } else { - *p = 0; - pstrcpy(directory,name); - pstrcpy(mask,p+1); - } - - /* - * We should only check the mangled cache - * here if unix_convert failed. This means - * that the path in 'mask' doesn't exist - * on the file system and so we need to look - * for a possible mangle. This patch from - * Tine Smukavec <valentin.smukavec@hermes.si>. - */ - - if (!rc && is_mangled(mask)) - check_mangled_cache( mask ); - - has_wild = ms_has_wild(mask); - - if (!has_wild) { - pstrcat(directory,"/"); - pstrcat(directory,mask); - if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory)) - count++; - if (!count) - exists = vfs_file_exist(conn,directory,&sbuf); - } else { - void *dirptr = NULL; - char *dname; - - if (check_name(directory,conn)) - dirptr = OpenDir(conn, directory, True); - - /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then - the pattern matches against the long name, otherwise the short name - We don't implement this yet XXXX - */ - - if (dirptr) - { - error = ERRbadfile; - - if (strequal(mask,"????????.???")) - pstrcpy(mask,"*"); - - while ((dname = ReadDirName(dirptr))) - { - pstring fname; - pstrcpy(fname,dname); - - if(!mask_match(fname, mask, case_sensitive)) continue; + pstring directory; + pstring mask; + char *p; + int count=0; + int error = ERRnoaccess; + BOOL has_wild; + BOOL exists=False; + BOOL bad_path = False; + BOOL rc = True; + SMB_STRUCT_STAT sbuf; + + *directory = *mask = 0; + + rc = unix_convert(name,conn,0,&bad_path,&sbuf); + + p = strrchr_m(name,'/'); + if (!p) { + pstrcpy(directory,"./"); + pstrcpy(mask,name); + } else { + *p = 0; + pstrcpy(directory,name); + pstrcpy(mask,p+1); + } + + /* + * We should only check the mangled cache + * here if unix_convert failed. This means + * that the path in 'mask' doesn't exist + * on the file system and so we need to look + * for a possible mangle. This patch from + * Tine Smukavec <valentin.smukavec@hermes.si>. + */ + + if (!rc && is_mangled(mask)) + check_mangled_cache( mask ); + + has_wild = ms_has_wild(mask); + + if (!has_wild) { + pstrcat(directory,"/"); + pstrcat(directory,mask); + if (!can_delete(directory,conn,dirtype)) { + return ERROR_NT(NT_STATUS_SHARING_VIOLATION); + } + if (vfs_unlink(conn,directory) == 0) { + count++; + } + if (!count) + exists = vfs_file_exist(conn,directory,&sbuf); + } else { + void *dirptr = NULL; + char *dname; + + if (check_name(directory,conn)) + dirptr = OpenDir(conn, directory, True); + + /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then + the pattern matches against the long name, otherwise the short name + We don't implement this yet XXXX + */ + + if (dirptr) { + error = ERRbadfile; + + if (strequal(mask,"????????.???")) + pstrcpy(mask,"*"); - error = ERRnoaccess; - slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); - if (!can_delete(fname,conn,dirtype)) continue; - if (!vfs_unlink(conn,fname)) count++; - DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname)); - } - CloseDir(dirptr); - } - } - - if (count == 0) { - if (exists) - return(ERROR(ERRDOS,error)); - else { - if((errno == ENOENT) && bad_path) { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - return(UNIXERROR(ERRDOS,error)); - } - } - - return 0; + while ((dname = ReadDirName(dirptr))) { + pstring fname; + pstrcpy(fname,dname); + + if(!mask_match(fname, mask, case_sensitive)) continue; + + error = ERRnoaccess; + slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); + if (!can_delete(fname,conn,dirtype)) continue; + if (vfs_unlink(conn,fname) == 0) count++; + DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname)); + } + CloseDir(dirptr); + } + } + + if (count == 0) { + if (exists) + return ERROR_DOS(ERRDOS,error); + else { + if((errno == ENOENT) && bad_path) { + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadpath; + } + return(UNIXERROR(ERRDOS,error)); + } + } + + return 0; } /**************************************************************************** Reply to a unlink ****************************************************************************/ -int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, + int dum_buffsize) { - int outsize = 0; - pstring name; - int dirtype; - START_PROFILE(SMBunlink); - - dirtype = SVAL(inbuf,smb_vwv0); - - srvstr_pull(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), -1, STR_TERMINATE); - - RESOLVE_DFSPATH(name, conn, inbuf, outbuf); - - DEBUG(3,("reply_unlink : %s\n",name)); - - outsize = unlink_internals(conn, inbuf, outbuf, dirtype, name); - if(outsize == 0) { - - /* - * Win2k needs a changenotify request response before it will - * update after a rename.. - */ - - process_pending_change_notify_queue((time_t)0); - - outsize = set_message(outbuf,0,0,True); - } + int outsize = 0; + pstring name; + int dirtype; + START_PROFILE(SMBunlink); + + dirtype = SVAL(inbuf,smb_vwv0); + + srvstr_pull(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), -1, STR_TERMINATE); + + RESOLVE_DFSPATH(name, conn, inbuf, outbuf); + + DEBUG(3,("reply_unlink : %s\n",name)); + + outsize = unlink_internals(conn, inbuf, outbuf, dirtype, name); + if(outsize == 0) { + /* + * Win2k needs a changenotify request response before it will + * update after a rename.. + */ + process_pending_change_notify_queue((time_t)0); + + outsize = set_message(outbuf,0,0,True); + } - END_PROFILE(SMBunlink); - return(outsize); + END_PROFILE(SMBunlink); + return outsize; } @@ -2089,68 +2055,69 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s ****************************************************************************/ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz) { - ssize_t nread = -1; - char *data; - int outsize = 0; - SMB_OFF_T startpos; - size_t numtoread; - int eclass; - uint32 ecode; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBlockread); + ssize_t nread = -1; + char *data; + int outsize = 0; + SMB_OFF_T startpos; + size_t numtoread; + NTSTATUS status; + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + START_PROFILE(SMBlockread); - CHECK_FSP(fsp,conn); - CHECK_READ(fsp); - CHECK_ERROR(fsp); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); - release_level_2_oplocks_on_change(fsp); + release_level_2_oplocks_on_change(fsp); - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); - outsize = set_message(outbuf,5,3,True); - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; - - /* - * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+ - * protocol request that predates the read/write lock concept. - * Thus instead of asking for a read lock here we need to ask - * for a write lock. JRA. - */ + outsize = set_message(outbuf,5,3,True); + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; + + /* + * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+ + * protocol request that predates the read/write lock concept. + * Thus instead of asking for a read lock here we need to ask + * for a write lock. JRA. + */ + + status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), + (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK); - if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &eclass, &ecode)) { - if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(inbuf, length, -1, 0)) + if (status != NT_STATUS_NOPROBLEMO) { + if (lp_blocking_locks(SNUM(conn))) { + /* + * A blocking lock was requested. Package up + * this smb into a queued request and push it + * onto the blocking lock queue. + */ + if(push_blocking_lock_request(inbuf, length, -1, 0)) + END_PROFILE(SMBlockread); + return -1; + } END_PROFILE(SMBlockread); - return -1; - } - END_PROFILE(SMBlockread); - return (ERROR(eclass,ecode)); - } - - nread = read_file(fsp,data,startpos,numtoread); - - if (nread < 0) { - END_PROFILE(SMBlockread); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } + return ERROR_NT(status); + } - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - SSVAL(smb_buf(outbuf),1,nread); + nread = read_file(fsp,data,startpos,numtoread); - DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n", - fsp->fnum, (int)numtoread, (int)nread ) ); + if (nread < 0) { + END_PROFILE(SMBlockread); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + SSVAL(smb_buf(outbuf),1,nread); + + DEBUG(3,("lockread fnum=%d num=%d nread=%d\n", + fsp->fnum, (int)numtoread, (int)nread)); - END_PROFILE(SMBlockread); - return(outsize); + END_PROFILE(SMBlockread); + return(outsize); } @@ -2170,23 +2137,23 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int CHECK_FSP(fsp,conn); CHECK_READ(fsp); - CHECK_ERROR(fsp); numtoread = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); - + + outsize = set_message(outbuf,5,3,True); numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBread); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } if (numtoread > 0) nread = read_file(fsp,data,startpos,numtoread); - + if (nread < 0) { END_PROFILE(SMBread); return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2227,7 +2194,6 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt CHECK_FSP(fsp,conn); CHECK_READ(fsp); - CHECK_ERROR(fsp); set_message(outbuf,12,0,True); data = smb_buf(outbuf); @@ -2249,7 +2215,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) )); END_PROFILE(SMBreadX); - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } #endif /* LARGE_SMB_OFF_T */ @@ -2258,10 +2224,10 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBreadX); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } nread = read_file(fsp,data,startpos,smb_maxcnt); - + if (nread < 0) { END_PROFILE(SMBreadX); return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2297,7 +2263,6 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); - CHECK_ERROR(fsp); tcount = IVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv3); @@ -2319,7 +2284,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwritebraw); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } if (numtowrite>0) @@ -2399,86 +2364,66 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, reply to a writeunlock (core+) ****************************************************************************/ -int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) +int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, + int size, int dum_buffsize) { - ssize_t nwritten = -1; - size_t numtowrite; - SMB_OFF_T startpos; - char *data; - int eclass; - uint32 ecode; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - int outsize = 0; - START_PROFILE(SMBwriteunlock); - - CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); - CHECK_ERROR(fsp); - - numtowrite = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); - data = smb_buf(inbuf) + 3; - - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { - END_PROFILE(SMBwriteunlock); - return(ERROR(ERRDOS,ERRlock)); - } + ssize_t nwritten = -1; + size_t numtowrite; + SMB_OFF_T startpos; + char *data; + NTSTATUS status; + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + int outsize = 0; + START_PROFILE(SMBwriteunlock); + + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); - /* The special X/Open SMB protocol handling of - zero length writes is *NOT* done for - this call */ - if(numtowrite == 0) - nwritten = 0; - else - nwritten = write_file(fsp,data,startpos,numtowrite); + numtowrite = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); + data = smb_buf(inbuf) + 3; - if (lp_syncalways(SNUM(conn))) - sync_file(conn,fsp); - - if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - END_PROFILE(SMBwriteunlock); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode)) { - END_PROFILE(SMBwriteunlock); - return(ERROR(eclass,ecode)); - } + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, + WRITE_LOCK,False)) { + END_PROFILE(SMBwriteunlock); + return ERROR_DOS(ERRDOS,ERRlock); + } - outsize = set_message(outbuf,1,0,True); - - SSVAL(outbuf,smb_vwv0,nwritten); + /* The special X/Open SMB protocol handling of + zero length writes is *NOT* done for + this call */ + if(numtowrite == 0) + nwritten = 0; + else + nwritten = write_file(fsp,data,startpos,numtowrite); - DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n", - fsp->fnum, (int)numtowrite, (int)nwritten ) ); - - END_PROFILE(SMBwriteunlock); - return(outsize); -} - -/**************************************************************************** - Return correct error for space allocation fail. -****************************************************************************/ + if (lp_syncalways(SNUM(conn))) + sync_file(conn,fsp); -int allocate_space_error(char *inbuf,char *outbuf, int errno_val) -{ - errno = errno_val; - if (!(global_client_caps & CAP_STATUS32)) - return (UNIXERROR(ERRHRD,ERRdiskfull)); - - /* Use more specific WNT/W2K error codes. */ -#ifdef EDQUOT - if (errno_val == ENOSPC || errno_val == EDQUOT) { -#else - if (errno_val == ENOSPC) { -#endif - SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0,NT_STATUS_DISK_FULL)); + if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { + END_PROFILE(SMBwriteunlock); + return(UNIXERROR(ERRDOS,ERRnoaccess)); } - return (UNIXERROR(ERRHRD,ERRdiskfull)); + status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, + (SMB_BIG_UINT)startpos); + if (status != NT_STATUS_NOPROBLEMO) { + END_PROFILE(SMBwriteunlock); + return ERROR_NT(status); + } + + outsize = set_message(outbuf,1,0,True); + + SSVAL(outbuf,smb_vwv0,nwritten); + + DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n", + fsp->fnum, (int)numtowrite, (int)nwritten)); + + END_PROFILE(SMBwriteunlock); + return outsize; } + /**************************************************************************** Reply to a write. ****************************************************************************/ @@ -2501,7 +2446,6 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); - CHECK_ERROR(fsp); numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -2509,7 +2453,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwrite); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } /* X/Open SMB protocol says that if smb_vwv1 is @@ -2519,9 +2463,8 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d /* This is actually an allocate call, not set EOF. JRA */ nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos); if (nwritten < 0) { - int ret = allocate_space_error(inbuf, outbuf, errno); - END_PROFILE(SMBwrite); - return ret; + END_PROFILE(SMBwrite); + return ERROR_NT(NT_STATUS_DISK_FULL); } } else nwritten = write_file(fsp,data,startpos,numtowrite); @@ -2575,7 +2518,6 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); - CHECK_ERROR(fsp); /* Deal with possible LARGE_WRITEX */ if (large_writeX) @@ -2583,7 +2525,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) { END_PROFILE(SMBwriteX); - return(ERROR(ERRDOS,ERRbadmem)); + return ERROR_DOS(ERRDOS,ERRbadmem); } data = smb_base(inbuf) + smb_doff; @@ -2605,7 +2547,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \ 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) )); END_PROFILE(SMBwriteX); - return(ERROR(ERRDOS,ERRbadaccess)); + return ERROR_DOS(ERRDOS,ERRbadaccess); } #endif /* LARGE_SMB_OFF_T */ @@ -2613,7 +2555,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwriteX); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } /* X/Open SMB protocol says that, unlike SMBwrite @@ -2666,7 +2608,6 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int START_PROFILE(SMBlseek); CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); flush_write_cache(fsp, SEEK_FLUSH); @@ -2745,9 +2686,6 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int START_PROFILE(SMBflush); CHECK_FSP(fsp,conn); - if (fsp) { - CHECK_ERROR(fsp); - } if (!fsp) { file_sync_all(conn); @@ -2806,12 +2744,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, if(!fsp || (fsp->conn != conn)) { END_PROFILE(SMBclose); - return(ERROR(ERRDOS,ERRbadfid)); - } - - if(HAS_CACHED_ERROR(fsp)) { - eclass = fsp->wbmpx_ptr->wr_errclass; - err = fsp->wbmpx_ptr->wr_error; + return ERROR_DOS(ERRDOS,ERRbadfid); } if(fsp->is_directory || fsp->stat_open) { @@ -2862,7 +2795,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, /* We have a cached error */ if(eclass || err) { END_PROFILE(SMBclose); - return(ERROR(eclass,err)); + return ERROR_DOS(eclass,err); } END_PROFILE(SMBclose); @@ -2889,7 +2822,6 @@ int reply_writeclose(connection_struct *conn, CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); - CHECK_ERROR(fsp); numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -2898,7 +2830,7 @@ int reply_writeclose(connection_struct *conn, if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwriteclose); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } nwritten = write_file(fsp,data,startpos,numtowrite); @@ -2938,13 +2870,11 @@ int reply_lock(connection_struct *conn, { int outsize = set_message(outbuf,0,0,True); SMB_BIG_UINT count,offset; - int eclass; - uint32 ecode; + NTSTATUS status; files_struct *fsp = file_fsp(inbuf,smb_vwv0); START_PROFILE(SMBlock); CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); release_level_2_oplocks_on_change(fsp); @@ -2954,20 +2884,21 @@ int reply_lock(connection_struct *conn, DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fd, fsp->fnum, (double)offset, (double)count)); - if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &eclass, &ecode)) { - if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(inbuf, length, -1, 0)) { - END_PROFILE(SMBlock); - return -1; - } - } - END_PROFILE(SMBlock); - return (ERROR(eclass,ecode)); + status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK); + if (status != NT_STATUS_NOPROBLEMO) { + if (status != NT_STATUS_NOPROBLEMO && lp_blocking_locks(SNUM(conn))) { + /* + * A blocking lock was requested. Package up + * this smb into a queued request and push it + * onto the blocking lock queue. + */ + if(push_blocking_lock_request(inbuf, length, -1, 0)) { + END_PROFILE(SMBlock); + return -1; + } + } + END_PROFILE(SMBlock); + return ERROR_NT(status); } END_PROFILE(SMBlock); @@ -2978,31 +2909,31 @@ int reply_lock(connection_struct *conn, /**************************************************************************** reply to a unlock ****************************************************************************/ -int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) +int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, + int dum_buffsize) { - int outsize = set_message(outbuf,0,0,True); - SMB_BIG_UINT count,offset; - int eclass; - uint32 ecode; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBunlock); - - CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); - - count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1); - offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); + int outsize = set_message(outbuf,0,0,True); + SMB_BIG_UINT count,offset; + NTSTATUS status; + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + START_PROFILE(SMBunlock); - if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, &eclass, &ecode)) { - END_PROFILE(SMBunlock); - return (ERROR(eclass,ecode)); - } + CHECK_FSP(fsp,conn); + + count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1); + offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); + + status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset); + if (status != NT_STATUS_NOPROBLEMO) { + END_PROFILE(SMBunlock); + return ERROR_NT(status); + } - DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n", - fsp->fd, fsp->fnum, (double)offset, (double)count ) ); - - END_PROFILE(SMBunlock); - return(outsize); + DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n", + fsp->fd, fsp->fnum, (double)offset, (double)count ) ); + + END_PROFILE(SMBunlock); + return(outsize); } @@ -3021,7 +2952,7 @@ int reply_tdis(connection_struct *conn, if (!conn) { DEBUG(4,("Invalid connection in tdis\n")); END_PROFILE(SMBtdis); - return(ERROR(ERRSRV,ERRinvnid)); + return ERROR_DOS(ERRSRV,ERRinvnid); } conn->used = False; @@ -3087,7 +3018,7 @@ int reply_printopen(connection_struct *conn, if (!CAN_PRINT(conn)) { END_PROFILE(SMBsplopen); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* Open for exclusive use, write only. */ @@ -3121,11 +3052,10 @@ int reply_printclose(connection_struct *conn, START_PROFILE(SMBsplclose); CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); if (!CAN_PRINT(conn)) { END_PROFILE(SMBsplclose); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } DEBUG(3,("printclose fd=%d fnum=%d\n", @@ -3161,7 +3091,7 @@ int reply_printqueue(connection_struct *conn, get it right (tridge) */ if (!CAN_PRINT(conn)) { END_PROFILE(SMBsplretq); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } SSVAL(outbuf,smb_vwv0,0); @@ -3227,12 +3157,11 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_ if (!CAN_PRINT(conn)) { END_PROFILE(SMBsplwr); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } CHECK_FSP(fsp,conn); CHECK_WRITE(fsp); - CHECK_ERROR(fsp); numtowrite = SVAL(smb_buf(inbuf),1); data = smb_buf(inbuf) + 3; @@ -3771,7 +3700,7 @@ int rename_internals(connection_struct *conn, if (count == 0) { if (exists) - return(ERROR(ERRDOS,error)); + return ERROR_DOS(ERRDOS,error); else { if((errno == ENOENT) && (bad_path1 || bad_path2)) { unix_ERR_class = ERRDOS; @@ -3938,7 +3867,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, /* can't currently handle inter share copies XXXX */ DEBUG(3,("Rejecting inter-share copy\n")); END_PROFILE(SMBcopy); - return(ERROR(ERRSRV,ERRinvdevice)); + return ERROR_DOS(ERRSRV,ERRinvdevice); } RESOLVE_DFSPATH(name, conn, inbuf, outbuf); @@ -3951,19 +3880,19 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if ((flags&1) && target_is_directory) { END_PROFILE(SMBcopy); - return(ERROR(ERRDOS,ERRbadfile)); + return ERROR_DOS(ERRDOS,ERRbadfile); } if ((flags&2) && !target_is_directory) { END_PROFILE(SMBcopy); - return(ERROR(ERRDOS,ERRbadpath)); + return ERROR_DOS(ERRDOS,ERRbadpath); } if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) { /* wants a tree copy! XXXX */ DEBUG(3,("Rejecting tree copy\n")); END_PROFILE(SMBcopy); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } p = strrchr_m(name,'/'); @@ -4045,7 +3974,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (exists) { END_PROFILE(SMBcopy); - return(ERROR(ERRDOS,error)); + return ERROR_DOS(ERRDOS,error); } else { if((errno == ENOENT) && (bad_path1 || bad_path2)) @@ -4079,7 +4008,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size snum = SNUM(conn); if (!CAN_SETDIR(snum)) { END_PROFILE(pathworks_setdir); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } srvstr_pull(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), -1, STR_TERMINATE); @@ -4095,7 +4024,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (!ok) { END_PROFILE(pathworks_setdir); - return(ERROR(ERRDOS,ERRbadpath)); + return ERROR_DOS(ERRDOS,ERRbadpath); } outsize = set_message(outbuf,0,0,True); @@ -4212,182 +4141,180 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - unsigned char locktype = CVAL(inbuf,smb_vwv3); - unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_BIG_UINT count = 0, offset = 0; - uint16 lock_pid; - int32 lock_timeout = IVAL(inbuf,smb_vwv4); - int i; - char *data; - uint32 ecode=0, dummy2; - int eclass=0, dummy1; - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; - BOOL err; - START_PROFILE(SMBlockingX); - - CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); - - data = smb_buf(inbuf); - - /* Check if this is an oplock break on a file - we have granted an oplock on. - */ - if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) - { - /* Client can insist on breaking to none. */ - BOOL break_to_none = (oplocklevel == 0); - - DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n", - (unsigned int)oplocklevel, fsp->fnum )); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + unsigned char locktype = CVAL(inbuf,smb_vwv3); + unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + SMB_BIG_UINT count = 0, offset = 0; + uint16 lock_pid; + int32 lock_timeout = IVAL(inbuf,smb_vwv4); + int i; + char *data; + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; + BOOL err; + NTSTATUS status; - /* - * Make sure we have granted an exclusive or batch oplock on this file. - */ + START_PROFILE(SMBlockingX); + + CHECK_FSP(fsp,conn); + + data = smb_buf(inbuf); + + /* Check if this is an oplock break on a file + we have granted an oplock on. + */ + if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) { + /* Client can insist on breaking to none. */ + BOOL break_to_none = (oplocklevel == 0); + + DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n", + (unsigned int)oplocklevel, fsp->fnum )); - if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) - { - DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \ + /* + * Make sure we have granted an exclusive or batch oplock on this file. + */ + + if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { + DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); - /* if this is a pure oplock break request then don't send a reply */ - if (num_locks == 0 && num_ulocks == 0) { - END_PROFILE(SMBlockingX); - return -1; - } else { - END_PROFILE(SMBlockingX); - return ERROR(ERRDOS,ERRlock); - } - } - - if (remove_oplock(fsp, break_to_none) == False) { - DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n", - fsp->fsp_name )); - } - - /* if this is a pure oplock break request then don't send a reply */ - if (num_locks == 0 && num_ulocks == 0) - { - /* Sanity check - ensure a pure oplock break is not a - chained request. */ - if(CVAL(inbuf,smb_vwv0) != 0xff) - DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n", - (unsigned int)CVAL(inbuf,smb_vwv0) )); - END_PROFILE(SMBlockingX); - return -1; - } - } - - /* - * We do this check *after* we have checked this is not a oplock break - * response message. JRA. - */ - - release_level_2_oplocks_on_change(fsp); - - /* Data now points at the beginning of the list - of smb_unlkrng structs */ - for(i = 0; i < (int)num_ulocks; i++) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); - - /* - * There is no error code marked "stupid client bug".... :-). - */ - if(err) { - END_PROFILE(SMBlockingX); - return ERROR(ERRDOS,ERRnoaccess); - } - - DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n", - (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); - - if(!do_unlock(fsp,conn,lock_pid,count,offset, &eclass, &ecode)) { - END_PROFILE(SMBlockingX); - return ERROR(eclass,ecode); - } - } - - /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000); - - /* Now do any requested locks */ - data += ((large_file_format ? 20 : 10)*num_ulocks); - - /* Data now points at the beginning of the list - of smb_lkrng structs */ + /* if this is a pure oplock break request then don't send a reply */ + if (num_locks == 0 && num_ulocks == 0) { + END_PROFILE(SMBlockingX); + return -1; + } else { + END_PROFILE(SMBlockingX); + return ERROR_DOS(ERRDOS,ERRlock); + } + } - for(i = 0; i < (int)num_locks; i++) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + if (remove_oplock(fsp, break_to_none) == False) { + DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n", + fsp->fsp_name )); + } + + /* if this is a pure oplock break request then don't send a reply */ + if (num_locks == 0 && num_ulocks == 0) { + /* Sanity check - ensure a pure oplock break is not a + chained request. */ + if(CVAL(inbuf,smb_vwv0) != 0xff) + DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n", + (unsigned int)CVAL(inbuf,smb_vwv0) )); + END_PROFILE(SMBlockingX); + return -1; + } + } - /* - * There is no error code marked "stupid client bug".... :-). - */ - if(err) { - END_PROFILE(SMBlockingX); - return ERROR(ERRDOS,ERRnoaccess); - } - - DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s\n", - (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); + /* + * We do this check *after* we have checked this is not a oplock break + * response message. JRA. + */ + + release_level_2_oplocks_on_change(fsp); + + /* Data now points at the beginning of the list + of smb_unlkrng structs */ + for(i = 0; i < (int)num_ulocks; i++) { + lock_pid = get_lock_pid( data, i, large_file_format); + count = get_lock_count( data, i, large_file_format); + offset = get_lock_offset( data, i, large_file_format, &err); + + /* + * There is no error code marked "stupid client bug".... :-). + */ + if(err) { + END_PROFILE(SMBlockingX); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } - if(!do_lock(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), - &eclass, &ecode)) { - if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(inbuf, length, lock_timeout, i)) { - END_PROFILE(SMBlockingX); - return -1; + DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n", + (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); + + status = do_unlock(fsp,conn,lock_pid,count,offset); + if (status != NT_STATUS_NOPROBLEMO) { + END_PROFILE(SMBlockingX); + return ERROR_NT(status); + } } - } - break; - } - } - /* If any of the above locks failed, then we must unlock - all of the previous locks (X/Open spec). */ - if(i != num_locks && num_locks != 0) { - /* - * Ensure we don't do a remove on the lock that just failed, - * as under POSIX rules, if we have a lock already there, we - * will delete it (and we shouldn't) ..... - */ - for(i--; i >= 0; i--) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + /* Setup the timeout in seconds. */ + lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000); + + /* Now do any requested locks */ + data += ((large_file_format ? 20 : 10)*num_ulocks); + + /* Data now points at the beginning of the list + of smb_lkrng structs */ + + for(i = 0; i < (int)num_locks; i++) { + lock_pid = get_lock_pid( data, i, large_file_format); + count = get_lock_count( data, i, large_file_format); + offset = get_lock_offset( data, i, large_file_format, &err); + + /* + * There is no error code marked "stupid client bug".... :-). + */ + if(err) { + END_PROFILE(SMBlockingX); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + + DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s\n", + (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); + + status = do_lock(fsp,conn,lock_pid, count,offset, + ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); + if (status != NT_STATUS_NOPROBLEMO) { + if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { + /* + * A blocking lock was requested. Package up + * this smb into a queued request and push it + * onto the blocking lock queue. + */ + if(push_blocking_lock_request(inbuf, length, lock_timeout, i)) { + END_PROFILE(SMBlockingX); + return -1; + } + } + break; + } + } + + /* If any of the above locks failed, then we must unlock + all of the previous locks (X/Open spec). */ + if (i != num_locks && num_locks != 0) { + /* + * Ensure we don't do a remove on the lock that just failed, + * as under POSIX rules, if we have a lock already there, we + * will delete it (and we shouldn't) ..... + */ + for(i--; i >= 0; i--) { + lock_pid = get_lock_pid( data, i, large_file_format); + count = get_lock_count( data, i, large_file_format); + offset = get_lock_offset( data, i, large_file_format, &err); + + /* + * There is no error code marked "stupid client bug".... :-). + */ + if(err) { + END_PROFILE(SMBlockingX); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + + do_unlock(fsp,conn,lock_pid,count,offset); + } + END_PROFILE(SMBlockingX); + return ERROR_NT(status); + } - /* - * There is no error code marked "stupid client bug".... :-). - */ - if(err) { + set_message(outbuf,2,0,True); + + DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", + fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) ); + END_PROFILE(SMBlockingX); - return ERROR(ERRDOS,ERRnoaccess); - } - - do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); - } - END_PROFILE(SMBlockingX); - return ERROR(eclass,ecode); - } - - set_message(outbuf,2,0,True); - - DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", - fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) ); - - END_PROFILE(SMBlockingX); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,outbuf,length,bufsize); } @@ -4411,14 +4338,13 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, /* this function doesn't seem to work - disable by default */ if (!lp_readbmpx()) { END_PROFILE(SMBreadBmpx); - return(ERROR(ERRSRV,ERRuseSTD)); + return ERROR_DOS(ERRSRV,ERRuseSTD); } outsize = set_message(outbuf,8,0,True); CHECK_FSP(fsp,conn); CHECK_READ(fsp); - CHECK_ERROR(fsp); startpos = IVAL(inbuf,smb_vwv1); maxcount = SVAL(inbuf,smb_vwv3); @@ -4434,7 +4360,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBreadBmpx); - return(ERROR(ERRDOS,ERRlock)); + return ERROR_DOS(ERRDOS,ERRlock); } do @@ -4466,200 +4392,6 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, return(-1); } -/**************************************************************************** - reply to a SMBwritebmpx (write block multiplex primary) request -****************************************************************************/ - -int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) -{ - size_t numtowrite; - ssize_t nwritten = -1; - int outsize = 0; - SMB_OFF_T startpos; - size_t tcount; - BOOL write_through; - int smb_doff; - char *data; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBwriteBmpx); - - CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); - CHECK_ERROR(fsp); - - tcount = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv3); - write_through = BITSETW(inbuf+smb_vwv7,0); - numtowrite = SVAL(inbuf,smb_vwv10); - smb_doff = SVAL(inbuf,smb_vwv11); - - data = smb_base(inbuf) + smb_doff; - - /* If this fails we need to send an SMBwriteC response, - not an SMBwritebmpx - set this up now so we don't forget */ - CVAL(outbuf,smb_com) = SMBwritec; - - if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) { - END_PROFILE(SMBwriteBmpx); - return(ERROR(ERRDOS,ERRlock)); - } - - nwritten = write_file(fsp,data,startpos,numtowrite); - - if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); - - if(nwritten < (ssize_t)numtowrite) { - END_PROFILE(SMBwriteBmpx); - return(UNIXERROR(ERRHRD,ERRdiskfull)); - } - - /* If the maximum to be written to this file - is greater than what we just wrote then set - up a secondary struct to be attached to this - fd, we will use this to cache error messages etc. */ - if((ssize_t)tcount > nwritten) - { - write_bmpx_struct *wbms; - if(fsp->wbmpx_ptr != NULL) - wbms = fsp->wbmpx_ptr; /* Use an existing struct */ - else - wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct)); - if(!wbms) - { - DEBUG(0,("Out of memory in reply_readmpx\n")); - END_PROFILE(SMBwriteBmpx); - return(ERROR(ERRSRV,ERRnoresource)); - } - wbms->wr_mode = write_through; - wbms->wr_discard = False; /* No errors yet */ - wbms->wr_total_written = nwritten; - wbms->wr_errclass = 0; - wbms->wr_error = 0; - fsp->wbmpx_ptr = wbms; - } - - /* We are returning successfully, set the message type back to - SMBwritebmpx */ - CVAL(outbuf,smb_com) = SMBwriteBmpx; - - outsize = set_message(outbuf,1,0,True); - - SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */ - - DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n", - fsp->fnum, (int)numtowrite, (int)nwritten ) ); - - if (write_through && tcount==nwritten) { - /* we need to send both a primary and a secondary response */ - smb_setlen(outbuf,outsize - 4); - if (!send_smb(smbd_server_fd(),outbuf)) - exit_server("reply_writebmpx: send_smb failed.\n"); - - /* now the secondary */ - outsize = set_message(outbuf,1,0,True); - CVAL(outbuf,smb_com) = SMBwritec; - SSVAL(outbuf,smb_vwv0,nwritten); - } - - END_PROFILE(SMBwriteBmpx); - return(outsize); -} - - -/**************************************************************************** - reply to a SMBwritebs (write block multiplex secondary) request -****************************************************************************/ -int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) -{ - size_t numtowrite; - ssize_t nwritten = -1; - int outsize = 0; - SMB_OFF_T startpos; - size_t tcount; - BOOL write_through; - int smb_doff; - char *data; - write_bmpx_struct *wbms; - BOOL send_response = False; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBwriteBs); - - CHECK_FSP(fsp,conn); - CHECK_WRITE(fsp); - - tcount = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); - numtowrite = SVAL(inbuf,smb_vwv6); - smb_doff = SVAL(inbuf,smb_vwv7); - - data = smb_base(inbuf) + smb_doff; - - /* We need to send an SMBwriteC response, not an SMBwritebs */ - CVAL(outbuf,smb_com) = SMBwritec; - - /* This fd should have an auxiliary struct attached, - check that it does */ - wbms = fsp->wbmpx_ptr; - if(!wbms) { - END_PROFILE(SMBwriteBs); - return(-1); - } - - /* If write through is set we can return errors, else we must - cache them */ - write_through = wbms->wr_mode; - - /* Check for an earlier error */ - if(wbms->wr_discard) { - END_PROFILE(SMBwriteBs); - return -1; /* Just discard the packet */ - } - - nwritten = write_file(fsp,data,startpos,numtowrite); - - if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); - - if (nwritten < (ssize_t)numtowrite) - { - if(write_through) - { - /* We are returning an error - we can delete the aux struct */ - if (wbms) free((char *)wbms); - fsp->wbmpx_ptr = NULL; - END_PROFILE(SMBwriteBs); - return(ERROR(ERRHRD,ERRdiskfull)); - } - END_PROFILE(SMBwriteBs); - return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull)); - } - - /* Increment the total written, if this matches tcount - we can discard the auxiliary struct (hurrah !) and return a writeC */ - wbms->wr_total_written += nwritten; - if(wbms->wr_total_written >= tcount) - { - if (write_through) - { - outsize = set_message(outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,wbms->wr_total_written); - send_response = True; - } - - free((char *)wbms); - fsp->wbmpx_ptr = NULL; - } - - if(send_response) { - END_PROFILE(SMBwriteBs); - return(outsize); - } - - END_PROFILE(SMBwriteBs); - return(-1); -} - /**************************************************************************** reply to a SMBsetattrE @@ -4675,7 +4407,6 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, outsize = set_message(outbuf,0,0,True); CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); /* Convert the DOS times into unix times. Ignore create time as UNIX can't set this. @@ -4708,7 +4439,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, /* Set the date on this file */ if(file_utime(conn, fsp->fsp_name, &unix_times)) { END_PROFILE(SMBsetattrE); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n", @@ -4734,7 +4465,6 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, outsize = set_message(outbuf,11,0,True); CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); /* Do an fstat on this file */ if(vfs_fstat(fsp,fsp->fd, &sbuf)) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 13db9948ad..cb4ca994f4 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -218,7 +218,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, fname,open_mode, open_attr, open_ofun, open_size)); if (IS_IPC(conn)) { - return(ERROR(ERRSRV,ERRaccess)); + return(ERROR_DOS(ERRSRV,ERRaccess)); } /* XXXX we need to handle passed times, sattr and flags */ @@ -256,13 +256,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, inode = sbuf.st_ino; if (fmode & aDIR) { close_file(fsp,False); - return(ERROR(ERRDOS,ERRnoaccess)); + return(ERROR_DOS(ERRDOS,ERRnoaccess)); } /* Realloc the size of parameters and data we will return */ params = Realloc(*pparams, 28); if( params == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + return(ERROR_DOS(ERRDOS,ERRnomem)); } *pparams = params; @@ -669,7 +669,7 @@ static int call_trans2findfirst(connection_struct *conn, case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: break; default: - return(ERROR(ERRDOS,ERRunknownlevel)); + return(ERROR_DOS(ERRDOS,ERRunknownlevel)); } srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE); @@ -710,15 +710,15 @@ static int call_trans2findfirst(connection_struct *conn, pdata = Realloc(*ppdata, max_data_bytes + 1024); if( pdata == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + return(ERROR_DOS(ERRDOS,ERRnomem)); } *ppdata = pdata; memset((char *)pdata,'\0',max_data_bytes + 1024); /* Realloc the params space */ params = Realloc(*pparams, 10); - if( params == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + if (params == NULL) { + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; @@ -731,7 +731,7 @@ static int call_trans2findfirst(connection_struct *conn, if(!(wcard = strdup(mask))) { dptr_close(&dptr_num); - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } dptr_set_wcard(dptr_num, wcard); @@ -803,10 +803,9 @@ static int call_trans2findfirst(connection_struct *conn, * from observation of NT. */ - if(numentries == 0) - { - dptr_close(&dptr_num); - return(ERROR(ERRDOS,ERRbadfile)); + if(numentries == 0) { + dptr_close(&dptr_num); + return ERROR_DOS(ERRDOS,ERRbadfile); } /* At this point pdata points to numentries directory entries. */ @@ -900,12 +899,12 @@ resume_key = %d resume name = %s continue=%d level = %d\n", case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: break; default: - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); } pdata = Realloc( *ppdata, max_data_bytes + 1024); if(pdata == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *ppdata = pdata; memset((char *)pdata,'\0',max_data_bytes + 1024); @@ -913,20 +912,20 @@ resume_key = %d resume name = %s continue=%d level = %d\n", /* Realloc the params space */ params = Realloc(*pparams, 6*SIZEOFWORD); if( params == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; /* Check that the dptr is valid */ if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) - return(ERROR(ERRDOS,ERRnofiles)); + return ERROR_DOS(ERRDOS,ERRnofiles); string_set(&conn->dirpath,dptr_path(dptr_num)); /* Get the wildcard mask from the dptr */ if((p = dptr_wcard(dptr_num))== NULL) { DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num)); - return (ERROR(ERRDOS,ERRnofiles)); + return ERROR_DOS(ERRDOS,ERRnofiles); } pstrcpy(mask, p); pstrcpy(directory,conn->dirpath); @@ -1116,12 +1115,12 @@ static int call_trans2qfsinfo(connection_struct *conn, if(vfs_stat(conn,".",&st)!=0) { DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); - return (ERROR(ERRSRV,ERRinvdevice)); + return ERROR_DOS(ERRSRV,ERRinvdevice); } pdata = Realloc(*ppdata, max_data_bytes + 1024); if ( pdata == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *ppdata = pdata; memset((char *)pdata,'\0',max_data_bytes + 1024); @@ -1215,7 +1214,7 @@ static int call_trans2qfsinfo(connection_struct *conn, } /* drop through */ default: - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); } @@ -1241,7 +1240,7 @@ static int call_trans2setfsinfo(connection_struct *conn, DEBUG(3,("call_trans2setfsinfo\n")); if (!CAN_WRITE(conn)) - return(ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); outsize = set_message(outbuf,10,0,True); @@ -1308,7 +1307,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, * Original code - this is an open file. */ CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); pstrcpy(fname, fsp->fsp_name); if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { @@ -1361,21 +1359,21 @@ static int call_trans2qfilepathinfo(connection_struct *conn, params = Realloc(*pparams,2); if (params == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; memset((char *)params,'\0',2); data_size = max_data_bytes + 1024; pdata = Realloc(*ppdata, data_size); if ( pdata == NULL ) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *ppdata = pdata; if (total_data > 0 && IVAL(pdata,0) == total_data) { /* uggh, EAs for OS2 */ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data)); - return(ERROR(ERRDOS,ERReasnotsupported)); + return ERROR_DOS(ERRDOS,ERReasnotsupported); } memset((char *)pdata,'\0',data_size); @@ -1419,7 +1417,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; case 6: - return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */ + return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */ case SMB_QUERY_FILE_BASIC_INFO: case 1004: @@ -1688,7 +1686,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, #endif default: - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); } send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size); @@ -1757,7 +1755,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, * Original code - this is an open file. */ CHECK_FSP(fsp,conn); - CHECK_ERROR(fsp); pstrcpy(fname, fsp->fsp_name); fd = fsp->fd; @@ -1794,7 +1791,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, } if (!CAN_WRITE(conn)) - return(ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n", tran_call,fname,info_level,total_data)); @@ -1802,7 +1799,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, /* Realloc the parameter and data sizes */ params = Realloc(*pparams,2); if(params == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; @@ -1816,7 +1813,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, if (total_data > 4 && IVAL(pdata,0) == total_data) { /* uggh, EAs for OS2 */ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data)); - return(ERROR(ERRDOS,ERReasnotsupported)); + return ERROR_DOS(ERRDOS,ERReasnotsupported); } switch (info_level) @@ -1891,7 +1888,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); #else /* LARGE_SMB_OFF_T */ if (IVAL(pdata,4) != 0) /* more than 32 bits? */ - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); #endif /* LARGE_SMB_OFF_T */ DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)size )); @@ -1928,8 +1925,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, } else { ret = vfs_allocate_file_space(fsp, size); } - if (ret == -1) - return allocate_space_error(inbuf, outbuf, errno); + if (ret == -1) return ERROR_NT(NT_STATUS_DISK_FULL); sbuf.st_size = size; } @@ -1944,7 +1940,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); #else /* LARGE_SMB_OFF_T */ if (IVAL(pdata,4) != 0) /* more than 32 bits? */ - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); #endif /* LARGE_SMB_OFF_T */ DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size )); break; @@ -1956,7 +1952,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, BOOL delete_on_close = (CVAL(pdata,0) ? True : False); if (tran_call != TRANSACT2_SETFILEINFO) - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); if (fsp == NULL) return(UNIXERROR(ERRDOS,ERRbadfid)); @@ -1968,7 +1964,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) { DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n", fsp->fsp_name )); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } if(fsp->is_directory) { @@ -1996,13 +1992,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn, delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); if (lock_share_entry_fsp(fsp) == False) - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) { DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n", fsp->fsp_name )); unlock_share_entry_fsp(fsp); - return(ERROR(ERRDOS,ERRnoaccess)); + return ERROR_DOS(ERRDOS,ERRnoaccess); } /* @@ -2039,7 +2035,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, default: { - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); } } @@ -2162,7 +2158,7 @@ static int call_trans2mkdir(connection_struct *conn, BOOL bad_path = False; if (!CAN_WRITE(conn)) - return(ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE); @@ -2186,7 +2182,7 @@ static int call_trans2mkdir(connection_struct *conn, /* Realloc the parameter and data sizes */ params = Realloc(*pparams,2); if(params == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; @@ -2218,13 +2214,13 @@ static int call_trans2findnotifyfirst(connection_struct *conn, case 2: break; default: - return(ERROR(ERRDOS,ERRunknownlevel)); + return ERROR_DOS(ERRDOS,ERRunknownlevel); } /* Realloc the parameter and data sizes */ params = Realloc(*pparams,6); if(params == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; @@ -2258,7 +2254,7 @@ static int call_trans2findnotifynext(connection_struct *conn, /* Realloc the parameter and data sizes */ params = Realloc(*pparams,4); if(params == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *pparams = params; @@ -2286,12 +2282,12 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, DEBUG(10,("call_trans2getdfsreferral\n")); if(!lp_host_msdfs()) - return(ERROR(ERRDOS,ERRbadfunc)); + return ERROR_DOS(ERRDOS,ERRbadfunc); srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0) - return(ERROR(ERRDOS,ERRbadfile)); + return ERROR_DOS(ERRDOS,ERRbadfile); SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size); @@ -2317,7 +2313,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { pdata = Realloc(*ppdata, 32); if(pdata == NULL) { - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } *ppdata = pdata; @@ -2331,7 +2327,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, return(-1); } else { DEBUG(2,("Unknown TRANS2_IOCTL\n")); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } } @@ -2434,7 +2430,7 @@ int reply_trans2(connection_struct *conn, if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) { END_PROFILE(SMBtrans2); - return(ERROR(ERRSRV,ERRaccess)); + return ERROR_DOS(ERRSRV,ERRaccess); } outsize = set_message(outbuf,0,0,True); @@ -2458,7 +2454,7 @@ int reply_trans2(connection_struct *conn, DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt)); DEBUG(2,("Transaction is %d\n",tran_call)); END_PROFILE(SMBtrans2); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } } @@ -2475,7 +2471,7 @@ int reply_trans2(connection_struct *conn, if(data) free(data); END_PROFILE(SMBtrans2); - return(ERROR(ERRDOS,ERRnomem)); + return ERROR_DOS(ERRDOS,ERRnomem); } /* Copy the param and data bytes sent with this request into @@ -2517,7 +2513,7 @@ int reply_trans2(connection_struct *conn, if(data) free(data); END_PROFILE(SMBtrans2); - return(ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } /* Revise total_params and total_data in case @@ -2641,7 +2637,7 @@ int reply_trans2(connection_struct *conn, if(data) free(data); END_PROFILE(SMBtrans2); - return (ERROR(ERRSRV,ERRerror)); + return ERROR_DOS(ERRSRV,ERRerror); } /* As we do not know how many data packets will need to be diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c index 82eee773f2..0339576b11 100644 --- a/source3/torture/locktest.c +++ b/source3/torture/locktest.c @@ -37,13 +37,15 @@ static BOOL use_oplocks; #define LOCKBASE 0 #define MINLENGTH 0 +#define ZERO_ZERO 1 + /* #define LOCKBASE (0x40000000 - 50) */ #define READ_PCT 50 -#define LOCK_PCT 35 -#define UNLOCK_PCT 55 +#define LOCK_PCT 45 +#define UNLOCK_PCT 70 #define RANGE_MULTIPLE 1 #define NSERVERS 2 #define NCONNECTIONS 2 @@ -52,9 +54,11 @@ static BOOL use_oplocks; #define NASTY_POSIX_LOCK_HACK 0 +enum lock_op {OP_LOCK, OP_UNLOCK, OP_REOPEN}; struct record { - char r1, r2; + enum lock_op lock_op; + int lock_type; char conn, f; SMB_BIG_UINT start, len; char needed; @@ -64,10 +68,37 @@ struct record { #if PRESETS static struct record preset[] = { -{36, 5, 0, 0, 0, 8, 1}, -{ 2, 6, 0, 1, 0, 1, 1}, -{53, 92, 0, 0, 0, 0, 1}, -{99, 11, 0, 0, 7, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 3, 0, 1}, +{OP_UNLOCK, 0 , 0, 0, 2, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + +{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, READ_LOCK, 0, 0, 1, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + +{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 3, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + +{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 1, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + +{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, READ_LOCK, 0, 0, 1, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + +{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1}, +{OP_LOCK, READ_LOCK, 0, 0, 3, 1, 1}, +{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1}, +{OP_REOPEN, 0, 0, 0, 0, 0, 1}, + }; #endif @@ -240,19 +271,12 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], unsigned f = rec->f; SMB_BIG_UINT start = rec->start; SMB_BIG_UINT len = rec->len; - unsigned r1 = rec->r1; - unsigned r2 = rec->r2; - unsigned op; + unsigned op = rec->lock_type; int server; BOOL ret[NSERVERS]; - if (r1 < READ_PCT) { - op = READ_LOCK; - } else { - op = WRITE_LOCK; - } - - if (r2 < LOCK_PCT) { + switch (rec->lock_op) { + case OP_LOCK: /* set a lock */ for (server=0;server<NSERVERS;server++) { ret[server] = cli_lock64(cli[server][conn], @@ -268,7 +292,9 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], } if (showall || ret[0] != ret[1]) show_locks(); if (ret[0] != ret[1]) return False; - } else if (r2 < LOCK_PCT+UNLOCK_PCT) { + break; + + case OP_UNLOCK: /* unset a lock */ for (server=0;server<NSERVERS;server++) { ret[server] = cli_unlock64(cli[server][conn], @@ -283,7 +309,9 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], } if (showall || ret[0] != ret[1]) show_locks(); if (!hide_unlock_fails && ret[0] != ret[1]) return False; - } else { + break; + + case OP_REOPEN: /* reopen the file */ for (server=0;server<NSERVERS;server++) { cli_close(cli[server][conn], fnum[server][conn][f]); @@ -302,7 +330,9 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], conn, f); show_locks(); } + break; } + return True; } @@ -372,7 +402,7 @@ static void test_locks(char *share[NSERVERS]) { struct cli_state *cli[NSERVERS][NCONNECTIONS]; int fnum[NSERVERS][NCONNECTIONS][NFILES]; - int n, i, n1, skip; + int n, i, n1, skip, r1, r2; ZERO_STRUCT(fnum); ZERO_STRUCT(cli); @@ -392,9 +422,27 @@ static void test_locks(char *share[NSERVERS]) random() % (LOCKRANGE-(recorded[n].start-LOCKBASE)); recorded[n].start *= RANGE_MULTIPLE; recorded[n].len *= RANGE_MULTIPLE; - recorded[n].r1 = random() % 100; - recorded[n].r2 = random() % 100; + r1 = random() % 100; + r2 = random() % 100; + if (r1 < READ_PCT) { + recorded[n].lock_type = READ_LOCK; + } else { + recorded[n].lock_type = WRITE_LOCK; + } + if (r2 < LOCK_PCT) { + recorded[n].lock_op = OP_LOCK; + } else if (r2 < UNLOCK_PCT) { + recorded[n].lock_op = OP_UNLOCK; + } else { + recorded[n].lock_op = OP_REOPEN; + } recorded[n].needed = True; +#if !ZERO_ZERO + if (recorded[n].start == 0 && + recorded[n].len == 0) { + recorded[n].len = 1; + } +#endif #if PRESETS } #endif @@ -416,8 +464,9 @@ static void test_locks(char *share[NSERVERS]) reconnect(cli, fnum, share); open_files(cli, fnum); - for (i=0;i<n-skip;i++) { + for (i=0;i<n-skip;i+=skip) { int m, j; + printf("excluding %d-%d\n", i, i+skip-1); for (j=i;j<i+skip;j++) { recorded[j].needed = False; } @@ -460,9 +509,9 @@ static void test_locks(char *share[NSERVERS]) close_files(cli, fnum); for (i=0;i<n;i++) { - printf("{%u, %u, %u, %u, %.0f, %.0f, %u},\n", - recorded[i].r1, - recorded[i].r2, + printf("{%d, %d, %u, %u, %.0f, %.0f, %u},\n", + recorded[i].lock_op, + recorded[i].lock_type, recorded[i].conn, recorded[i].f, (double)recorded[i].start, @@ -576,7 +625,6 @@ static void usage(void) DEBUG(0,("seed=%u\n", seed)); srandom(seed); - locking_init(1); test_locks(share); return(0); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index cd35abdbc6..36d88d518a 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -119,7 +119,7 @@ static BOOL open_nbt_connection(struct cli_state *c) return True; } -static BOOL open_connection(struct cli_state *c) +BOOL torture_open_connection(struct cli_state *c) { ZERO_STRUCTP(c); @@ -153,7 +153,7 @@ static BOOL open_connection(struct cli_state *c) } -static BOOL close_connection(struct cli_state *c) +BOOL torture_close_connection(struct cli_state *c) { BOOL ret = True; if (!cli_tdis(c)) { @@ -195,8 +195,8 @@ static BOOL check_error(int line, struct cli_state *c, status = cli_nt_error(c); if (nterr != status) { - printf("unexpected error code 0x%08x\n", status); - printf(" expected 0x%08x (line=%d)\n", nterr, line); + printf("unexpected error code %s\n", get_nt_error_msg(status)); + printf(" expected %s (line=%d)\n", get_nt_error_msg(nterr), line); return False; } } @@ -314,7 +314,7 @@ static BOOL run_torture(int dummy) ret = rw_torture(&cli); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { ret = False; } @@ -501,7 +501,7 @@ static BOOL run_readwritetest(int dummy) static struct cli_state cli1, cli2; BOOL test1, test2; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } cli_sockopt(&cli1, sockops); @@ -515,11 +515,11 @@ static BOOL run_readwritetest(int dummy) test2 = rw_torture2(&cli1, &cli1); printf("Passed readwritetest v2: %s\n", BOOLSTR(test2)); - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { test1 = False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { test2 = False; } @@ -538,7 +538,7 @@ static BOOL run_readwritemulti(int dummy) printf("run_readwritemulti: fname %s\n", randomfname); test = rw_torture3(&cli, randomfname); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { test = False; } @@ -554,7 +554,7 @@ static BOOL run_readwritelarge(int dummy) char buf[0x10000]; BOOL correct = True; - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } cli_sockopt(&cli1, sockops); @@ -609,7 +609,7 @@ static BOOL run_readwritelarge(int dummy) correct = False; } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } return correct; @@ -715,7 +715,7 @@ static BOOL run_netbench(int client) printf("+"); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -766,7 +766,7 @@ static BOOL run_locktest1(int dummy) int fnum1, fnum2, fnum3; time_t t1, t2; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } cli_sockopt(&cli1, sockops); @@ -851,11 +851,11 @@ static BOOL run_locktest1(int dummy) } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { return False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { return False; } @@ -874,7 +874,7 @@ static BOOL run_tcon_test(int dummy) uint16 cnum; char buf[4]; - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } cli_sockopt(&cli1, sockops); @@ -929,7 +929,7 @@ static BOOL run_tcon_test(int dummy) return False; } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { return False; } @@ -956,7 +956,7 @@ static BOOL run_locktest2(int dummy) int fnum1, fnum2, fnum3; BOOL correct = True; - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -1070,7 +1070,7 @@ static BOOL run_locktest2(int dummy) return False; } - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -1095,7 +1095,7 @@ static BOOL run_locktest3(int dummy) #define NEXT_OFFSET offset += (~(uint32)0) / numops - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } cli_sockopt(&cli1, sockops); @@ -1190,11 +1190,11 @@ static BOOL run_locktest3(int dummy) return False; } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { correct = False; } @@ -1219,7 +1219,7 @@ static BOOL run_locktest4(int dummy) char buf[1000]; BOOL correct = True; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } @@ -1370,8 +1370,8 @@ static BOOL run_locktest4(int dummy) cli_close(&cli1, fnum1); cli_close(&cli2, fnum2); cli_unlink(&cli1, fname); - close_connection(&cli1); - close_connection(&cli2); + torture_close_connection(&cli1); + torture_close_connection(&cli2); printf("finished locktest4\n"); return correct; @@ -1389,7 +1389,7 @@ static BOOL run_locktest5(int dummy) char buf[1000]; BOOL correct = True; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } @@ -1489,10 +1489,10 @@ static BOOL run_locktest5(int dummy) cli_close(&cli1, fnum1); cli_close(&cli2, fnum2); cli_unlink(&cli1, fname); - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { correct = False; } @@ -1532,7 +1532,7 @@ static BOOL run_denytest1(int dummy) {-1, NULL}}; BOOL correct = True; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } cli_sockopt(&cli1, sockops); @@ -1586,10 +1586,10 @@ static BOOL run_denytest1(int dummy) cli_unlink(&cli1, fnames[f]); } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { correct = False; } @@ -1629,7 +1629,7 @@ static BOOL run_denytest2(int dummy) {-1, NULL}}; BOOL correct = True; - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } cli_sockopt(&cli1, sockops); @@ -1682,7 +1682,7 @@ static BOOL run_denytest2(int dummy) cli_unlink(&cli1, fnames[f]); } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } @@ -1701,7 +1701,7 @@ static BOOL run_fdpasstest(int dummy) int fnum1; pstring buf; - if (!open_connection(&cli1) || !open_connection(&cli2)) { + if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { return False; } cli_sockopt(&cli1, sockops); @@ -1736,8 +1736,8 @@ static BOOL run_fdpasstest(int dummy) cli_close(&cli1, fnum1); cli_unlink(&cli1, fname); - close_connection(&cli1); - close_connection(&cli2); + torture_close_connection(&cli1); + torture_close_connection(&cli2); printf("finished fdpasstest\n"); return True; @@ -1756,7 +1756,7 @@ static BOOL run_unlinktest(int dummy) int fnum; BOOL correct = True; - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -1785,7 +1785,7 @@ static BOOL run_unlinktest(int dummy) cli_close(&cli, fnum); cli_unlink(&cli, fname); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -1844,7 +1844,7 @@ static BOOL run_maxfidtest(int dummy) printf("%6d\n", 0); printf("maxfid test finished\n"); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } return correct; @@ -1876,7 +1876,7 @@ static BOOL run_negprot_nowait(int dummy) cli_negprot_send(&cli); } - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -1900,7 +1900,7 @@ static BOOL run_randomipc(int dummy) printf("starting random ipc test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -1923,7 +1923,7 @@ static BOOL run_randomipc(int dummy) } printf("%d/%d\n", i, count); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -1953,7 +1953,7 @@ static BOOL run_browsetest(int dummy) printf("starting browse test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -1967,7 +1967,7 @@ static BOOL run_browsetest(int dummy) SV_TYPE_ALL, browse_callback, NULL); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -1991,7 +1991,7 @@ static BOOL run_attrtest(int dummy) printf("starting attrib test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -2032,7 +2032,7 @@ static BOOL run_attrtest(int dummy) cli_unlink(&cli, fname); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -2058,7 +2058,7 @@ static BOOL run_trans2test(int dummy) printf("starting trans2 test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -2155,7 +2155,7 @@ static BOOL run_trans2test(int dummy) cli_unlink(&cli, fname2); cli_rmdir(&cli, dname); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -2164,71 +2164,6 @@ static BOOL run_trans2test(int dummy) return correct; } - -/**************************************************************************** -check for existance of a trans2 call -****************************************************************************/ -static BOOL scan_trans2(struct cli_state *cli, int op, int level) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = op; - pstring param; - char *rparam=NULL, *rdata=NULL; - - param_len = 6; - SSVAL(param, 0, level); - SSVAL(param, 2, level); - SSVAL(param, 4, level); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - printf("recv failed op=%d level=%d %s\n", op, level, cli_errstr(cli)); - return False; - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -static BOOL run_trans2_scan(int dummy) -{ - static struct cli_state cli; - int op, level; - - printf("starting trans2 scan test\n"); - - if (!open_connection(&cli)) { - return False; - } - - for (op=1; op<200; op++) { - for (level = 1; level < 300; level++) { - scan_trans2(&cli, op, level); - } - } - - close_connection(&cli); - - printf("trans2 scan finished\n"); - return True; -} - - - /* This checks new W2K calls. */ @@ -2261,7 +2196,7 @@ static BOOL run_w2ktest(int dummy) printf("starting w2k test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -2274,7 +2209,7 @@ static BOOL run_w2ktest(int dummy) cli_close(&cli, fnum); - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -2296,7 +2231,7 @@ static BOOL run_oplock1(int dummy) printf("starting oplock test 1\n"); - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } @@ -2327,7 +2262,7 @@ static BOOL run_oplock1(int dummy) return False; } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } @@ -2354,7 +2289,7 @@ static BOOL run_oplock2(int dummy) printf("starting oplock test 2\n"); - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; return False; @@ -2363,7 +2298,7 @@ static BOOL run_oplock2(int dummy) cli1.use_oplocks = True; cli1.use_level_II_oplocks = True; - if (!open_connection(&cli2)) { + if (!torture_open_connection(&cli2)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; return False; @@ -2457,7 +2392,7 @@ static BOOL run_oplock2(int dummy) correct = False; } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } @@ -2496,7 +2431,7 @@ static BOOL run_oplock3(int dummy) /* Child code */ use_oplocks = True; use_level_II_oplocks = True; - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { *shared_correct = False; exit(0); } @@ -2510,7 +2445,7 @@ static BOOL run_oplock3(int dummy) /* parent code */ use_oplocks = True; use_level_II_oplocks = True; - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } cli_oplock_handler(&cli, oplock3_handler); @@ -2542,7 +2477,7 @@ static BOOL run_deletetest(int dummy) printf("starting delete test\n"); - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } @@ -2816,7 +2751,7 @@ static BOOL run_deletetest(int dummy) cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - if (!open_connection(&cli2)) { + if (!torture_open_connection(&cli2)) { printf("[8] failed to open second connection.\n"); return False; } @@ -2871,10 +2806,10 @@ static BOOL run_deletetest(int dummy) cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } - if (!close_connection(&cli2)) { + if (!torture_close_connection(&cli2)) { correct = False; } return correct; @@ -2894,7 +2829,7 @@ static BOOL run_opentest(int dummy) printf("starting open test\n"); - if (!open_connection(&cli1)) { + if (!torture_open_connection(&cli1)) { return False; } @@ -3038,7 +2973,7 @@ static BOOL run_opentest(int dummy) cli_unlink(&cli1, tmp_path); } - if (!close_connection(&cli1)) { + if (!torture_close_connection(&cli1)) { correct = False; } @@ -3063,7 +2998,7 @@ static BOOL run_dirtest(int dummy) printf("starting directory test\n"); - if (!open_connection(&cli)) { + if (!torture_open_connection(&cli)) { return False; } @@ -3096,7 +3031,7 @@ static BOOL run_dirtest(int dummy) cli_unlink(&cli, fname); } - if (!close_connection(&cli)) { + if (!torture_close_connection(&cli)) { correct = False; } @@ -3129,8 +3064,8 @@ static double create_procs(BOOL (*fn)(int), BOOL *result) return -1; } - memset(child_status, 0, sizeof(pid_t)*nprocs); - memset(child_status_out, True, sizeof(BOOL)*nprocs); + memset((void *)child_status, 0, sizeof(pid_t)*nprocs); + memset((void *)child_status_out, True, sizeof(BOOL)*nprocs); start_timer(); @@ -3144,7 +3079,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result) while (1) { memset(¤t_cli, 0, sizeof(current_cli)); - if (open_connection(¤t_cli)) break; + if (torture_open_connection(¤t_cli)) break; if (tries-- == 0) { printf("pid %d failed to start\n", (int)getpid()); _exit(1); @@ -3237,7 +3172,8 @@ static struct { {"OPEN", run_opentest, 0}, {"DELETE", run_deletetest, 0}, {"W2K", run_w2ktest, 0}, - {"TRANS2SCAN", run_trans2_scan, 0}, + {"TRANS2SCAN", torture_trans2_scan, 0}, + {"NTTRANSSCAN", torture_nttrans_scan, 0}, {NULL, NULL, 0}}; |