diff options
author | Andrew Tridgell <tridge@samba.org> | 1998-08-15 07:27:34 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1998-08-15 07:27:34 +0000 |
commit | 127655cc888ac40332d4e8e5b94aab03f5120aae (patch) | |
tree | 871cd3070589cbfbb9bc939125cd3b4d78923eef | |
parent | 37d5ba8eae030ef852ca64181a5f8e5dbdc52079 (diff) | |
download | samba-127655cc888ac40332d4e8e5b94aab03f5120aae.tar.gz samba-127655cc888ac40332d4e8e5b94aab03f5120aae.tar.bz2 samba-127655cc888ac40332d4e8e5b94aab03f5120aae.zip |
this checkin gets rid of the global Files[] array and makes it local
in files.c
it should now be faily easy to expand the default MAX_OPEN_FILES to
many thousands.
(This used to be commit b088c804f98908eb02f05ab2f2e8a61691a0a582)
-rw-r--r-- | source3/Makefile.in | 4 | ||||
-rw-r--r-- | source3/include/local.h | 15 | ||||
-rw-r--r-- | source3/include/proto.h | 49 | ||||
-rw-r--r-- | source3/include/smb.h | 37 | ||||
-rw-r--r-- | source3/locking/locking.c | 56 | ||||
-rw-r--r-- | source3/locking/locking_shm.c | 38 | ||||
-rw-r--r-- | source3/locking/locking_slow.c | 68 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 2 | ||||
-rw-r--r-- | source3/script/mkproto.awk | 2 | ||||
-rw-r--r-- | source3/smbd/files.c | 321 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 174 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 123 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 13 | ||||
-rw-r--r-- | source3/smbd/reply.c | 572 | ||||
-rw-r--r-- | source3/smbd/server.c | 378 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 45 | ||||
-rw-r--r-- | source3/utils/status.c | 1 | ||||
-rw-r--r-- | source3/web/swat.c | 1 |
18 files changed, 957 insertions, 942 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index d79873f7e8..51cf4feec1 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -120,7 +120,7 @@ LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \ PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \ passdb/pass_check.o passdb/ldap.o passdb/nispass.o -SMBD_OBJ1 = smbd/server.o smbd/chgpasswd.o smbd/connection.o \ +SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/dfree.o smbd/dir.o smbd/password.o \ smbd/groupname.o smbd/ipc.o smbd/mangle.o \ smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \ @@ -294,7 +294,7 @@ uninstallcp: @$(SHELL) $(srcdir)/script/uninstallcp.sh $(CODEPAGEDIR) $(CODEPAGELIST) clean: - rm -f core */*.o */*~ *~ config.cache bin/[!C]* + rm -f core */*.o */*~ *~ config.cache $(PROGS) proto: @echo rebuilding include/proto.h diff --git a/source3/include/local.h b/source3/include/local.h index fb67babcda..af12f83551 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -29,6 +29,10 @@ /* to a maximum of 8 if old smb clients break because of long printer names. */ #define MAXPRINTERLEN 15 +/* max number of directories open at once */ +/* note that with the new directory code this no longer requires a + file handle per directory, but large numbers do use more memory */ +#define MAX_OPEN_DIRECTORIES 64 /* define what facility to use for syslog */ #ifndef SYSLOG_FACILITY @@ -40,18 +44,13 @@ MAX_CONNECTIONS services, but any number of machines may connect at one time. */ #define MAX_CONNECTIONS 127 -#define MAX_OPEN_FILES 100 - -/* max number of directories open at once */ -/* note that with the new directory code this no longer requires a - file handle per directory, but large numbers do use more memory */ -#define MAX_OPEN_DIRECTORIES 64 -#define MAX_FNUMS (MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES) +/* this must be larger than the sum of the open files and directories */ +#define PIPE_HANDLE_OFFSET 0x7000 /* Default size of shared memory used for share mode locking */ #ifndef SHMEM_SIZE -#define SHMEM_SIZE (1024*(MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES)) +#define SHMEM_SIZE (1024*1024) #endif /* the max number of simultanous connections to the server by all clients */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 49d078b78a..9587828ea9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -474,12 +474,12 @@ char *smb_errstr(char *inbuf); BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); void process_blocking_lock_queue(time_t t); -BOOL is_locked(int fnum,connection_struct *conn, +BOOL is_locked(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset, int lock_type); -BOOL do_lock(int fnum,connection_struct *conn, +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int lock_type, int *eclass,uint32 *ecode); -BOOL do_unlock(int fnum,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int *eclass,uint32 *ecode); BOOL locking_init(int read_only); BOOL locking_end(void); @@ -490,9 +490,9 @@ BOOL unlock_share_entry(connection_struct *conn, int get_share_modes(connection_struct *conn, int token, uint32 dev, uint32 inode, share_mode_entry **shares); -void del_share_mode(int token, int fnum); -BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type); -BOOL remove_share_oplock(int fnum, int token); +void del_share_mode(int token, files_struct *fsp); +BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type); +BOOL remove_share_oplock(files_struct *fsp, int token); int share_mode_forall(void (*fn)(share_mode_entry *, char *)); void share_status(FILE *f); @@ -1941,6 +1941,20 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum ); char *DirCacheCheck( char *path, char *name, int snum ); void DirCacheFlush(int snum); +/*The following definitions come from smbd/files.c */ + +files_struct *find_free_file(void ); +file_fd_struct *fd_get_already_open(struct stat *sbuf); +file_fd_struct *fd_get_new(void); +void file_close_conn(connection_struct *conn); +void file_init(void); +files_struct *file_fsp(int fnum); +void file_close_user(int vuid); +files_struct *file_find_dit(int dev, int inode, struct timeval *tval); +files_struct *file_find_print(void); +void file_sync_all(connection_struct *conn); +void file_free(files_struct *fsp); + /*The following definitions come from smbd/groupname.c */ void load_groupname_map(void); @@ -1979,7 +1993,7 @@ int reply_ntcancel(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize); int reply_nttranss(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize); -void remove_pending_change_notify_requests_by_fid(int fnum); +void remove_pending_change_notify_requests_by_fid(files_struct *fsp); void remove_pending_change_notify_requests_by_mid(int mid); void process_pending_change_notify_queue(time_t t); int reply_nttrans(connection_struct *conn, @@ -2114,22 +2128,23 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times); BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime); BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, BOOL *bad_path); BOOL check_name(char *name,connection_struct *conn); -void sync_file(connection_struct *conn, int fnum); -void close_file(int fnum, BOOL normal_close); -void close_directory(int fnum); -int open_directory(int fnum,connection_struct *conn, +void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u); +void sync_file(connection_struct *conn, files_struct *fsp); +void close_file(files_struct *fsp, BOOL normal_close); +void close_directory(files_struct *fsp); +int open_directory(files_struct *fsp,connection_struct *conn, char *fname, int smb_ofun, int unixmode, int *action); BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op); int check_share_mode( share_mode_entry *share, int deny_mode, char *fname, BOOL fcbopen, int *flags); -void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mode,int ofun, +void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun, int mode,int oplock_request, int *Access,int *action); -int seek_file(int fnum,uint32 pos); -int read_file(int fnum,char *data,uint32 pos,int n); -int write_file(int fnum,char *data,int n); +int seek_file(files_struct *fsp,uint32 pos); +int read_file(files_struct *fsp,char *data,uint32 pos,int n); +int write_file(files_struct *fsp,char *data,int n); BOOL become_service(connection_struct *conn,BOOL do_chdir); int find_service(char *service); -int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line); +int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line); int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line); int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line); BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval); @@ -2139,7 +2154,7 @@ BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int tim BOOL snum_used(int snum); BOOL reload_services(BOOL test); connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode); -int find_free_file(void ); +BOOL attempt_close_oplocked_file(files_struct *fsp); int reply_corep(char *outbuf); int reply_coreplus(char *outbuf); int reply_lanman1(char *outbuf); diff --git a/source3/include/smb.h b/source3/include/smb.h index fa5d496ceb..801e134435 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -575,6 +575,7 @@ struct current_user typedef struct { + int fnum; connection_struct *conn; file_fd_struct *fd_ptr; int pos; @@ -599,6 +600,10 @@ typedef struct char *fsp_name; } files_struct; +/* this macro should always be used to extract an fnum (smb_fid) from + a packet to ensure chaining works correctly */ +#define GETFSP(buf,where) (chain_fsp?chain_fsp:file_fsp(SVAL(buf,where))) + /* Domain controller authentication protocol info */ struct dcinfo @@ -695,9 +700,9 @@ struct share_ops { BOOL (*lock_entry)(connection_struct *, uint32 , uint32 , int *); BOOL (*unlock_entry)(connection_struct *, uint32 , uint32 , int ); int (*get_entries)(connection_struct *, int , uint32 , uint32 , share_mode_entry **); - void (*del_entry)(int , int ); - BOOL (*set_entry)(int , int , uint16 , uint16 ); - BOOL (*remove_oplock)(int , int); + void (*del_entry)(int , files_struct *); + BOOL (*set_entry)(int, files_struct *, uint16 , uint16 ); + BOOL (*remove_oplock)(files_struct *, int); int (*forall)(void (*)(share_mode_entry *, char *)); void (*status)(FILE *); }; @@ -858,22 +863,21 @@ struct parm_struct #endif /* LOCKING_VERSION */ /* these are useful macros for checking validity of handles */ -#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < MAX_FNUMS)) -#define OPEN_FNUM(fnum) (VALID_FNUM(fnum) && Files[fnum].open && !Files[fnum].is_directory) +#define OPEN_FSP(fsp) ((fsp) && (fsp)->open && !(fsp)->is_directory) #define VALID_CNUM(cnum) (((cnum) >= 0) && ((cnum) < MAX_CONNECTIONS)) -#define OPEN_CNUM(conn) ((conn) && (conn)->open) +#define OPEN_CONN(conn) ((conn) && (conn)->open) #define IS_IPC(conn) ((conn) && (conn)->ipc) #define IS_PRINT(conn) ((conn) && (conn)->printer) -#define FNUM_OK(fnum,c) (OPEN_FNUM(fnum) && (c)==Files[fnum].conn) +#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn) -#define CHECK_FNUM(fnum,conn) if (!FNUM_OK(fnum,conn)) \ +#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \ return(ERROR(ERRDOS,ERRbadfid)) -#define CHECK_READ(fnum) if (!Files[fnum].can_read) \ +#define CHECK_READ(fsp) if (!(fsp)->can_read) \ return(ERROR(ERRDOS,ERRbadaccess)) -#define CHECK_WRITE(fnum) if (!Files[fnum].can_write) \ +#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \ return(ERROR(ERRDOS,ERRbadaccess)) -#define CHECK_ERROR(fnum) if (HAS_CACHED_ERROR(fnum)) \ - return(CACHED_ERROR(fnum)) +#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \ + return(CACHED_ERROR(fsp)) /* translates a connection number into a service number */ #define SNUM(conn) ((conn)?(conn)->service:-1) @@ -883,7 +887,7 @@ struct parm_struct #define PRINTCAP (lp_printcapname()) #define PRINTCOMMAND(snum) (lp_printcommand(snum)) #define PRINTERNAME(snum) (lp_printername(snum)) -#define CAN_WRITE(conn) (OPEN_CNUM(conn) && !conn->read_only) +#define CAN_WRITE(conn) (OPEN_CONN(conn) && !conn->read_only) #define VALID_SNUM(snum) (lp_snum_ok(snum)) #define GUEST_OK(snum) (VALID_SNUM(snum) && lp_guest_ok(snum)) #define GUEST_ONLY(snum) (VALID_SNUM(snum) && lp_guest_only(snum)) @@ -1432,11 +1436,10 @@ enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1}; #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(fnum) (Files[(fnum)].open && \ - Files[(fnum)].wbmpx_ptr && \ - Files[(fnum)].wbmpx_ptr->wr_discard) +#define HAS_CACHED_ERROR(fsp) ((fsp)->open && (fsp)->wbmpx_ptr && \ + (fsp)->wbmpx_ptr->wr_discard) /* Macro to turn the cached error into an error packet */ -#define CACHED_ERROR(fnum) cached_error_packet(inbuf,outbuf,fnum,__LINE__) +#define CACHED_ERROR(fsp) cached_error_packet(inbuf,outbuf,fsp,__LINE__) /* these are the datagram types */ #define DGRAM_DIRECT_UNIQUE 0x10 diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bb852b07d6..50c4af2265 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -33,7 +33,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern files_struct Files[]; extern int Client; static struct share_ops *share_ops; @@ -62,7 +61,7 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) { blocking_lock_record *blr; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); /* * Now queue an entry on the blocking lock queue. We setup @@ -88,7 +87,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int ubi_slAddTail(&blocking_lock_queue, blr); DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ -for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); +for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name )); return True; } @@ -96,16 +95,15 @@ for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); /**************************************************************************** Return a blocking lock success SMB. *****************************************************************************/ - static void blocking_lock_reply_success(blocking_lock_record *blr) { extern int chain_size; - extern int chain_fnum; + extern files_struct *chain_fsp; extern char *OutBuffer; char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); int outsize = 0; construct_reply_common(inbuf, outbuf); @@ -119,7 +117,7 @@ static void blocking_lock_reply_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_fnum = fnum; + chain_fsp = fsp; chain_size = 0; outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); @@ -142,7 +140,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -160,7 +158,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int for(i = blr->lock_num; i >= 0; i--) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fnum,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } construct_reply_common(inbuf, outbuf); @@ -177,7 +175,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -196,7 +194,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) break; } @@ -208,7 +206,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) */ DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", - fnum, (unsigned int)locktype, num_locks) ); + fsp->fnum, (unsigned int)locktype, num_locks) ); blocking_lock_reply_success(blr); return True; @@ -230,7 +228,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) */ DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting..\n", blr->lock_num, num_locks, fnum )); +Waiting..\n", blr->lock_num, num_locks, fsp->fnum)); return False; } @@ -252,13 +250,12 @@ void process_blocking_lock_queue(time_t t) */ while(blr != NULL) { - int fnum = GETFNUM(blr->inbuf,smb_vwv2); - files_struct *fsp = &Files[fnum]; + files_struct *fsp = GETFSP(blr->inbuf,smb_vwv2); uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fnum, fsp->name )); + fsp->fnum, fsp->name )); if((blr->expire_time != -1) && (blr->expire_time > t)) { /* @@ -266,7 +263,7 @@ void process_blocking_lock_queue(time_t t) * obtained locks and return lock error. */ DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fnum, fsp->name )); + fsp->fnum, fsp->name )); blocking_lock_reply_error(blr,ERRSRV,ERRaccess); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); @@ -356,11 +353,10 @@ static int map_lock_type( files_struct *fsp, int lock_type) /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ -BOOL is_locked(int fnum,connection_struct *conn, +BOOL is_locked(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset, int lock_type) { int snum = SNUM(conn); - files_struct *fsp = &Files[fnum]; if (count == 0) return(False); @@ -381,12 +377,11 @@ BOOL is_locked(int fnum,connection_struct *conn, /**************************************************************************** Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(int fnum,connection_struct *conn, +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; - files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(conn))) return(True); @@ -397,7 +392,7 @@ BOOL do_lock(int fnum,connection_struct *conn, return False; } - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); @@ -413,16 +408,15 @@ BOOL do_lock(int fnum,connection_struct *conn, /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(int fnum,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int *eclass,uint32 *ecode) { BOOL ok = False; - files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(conn))) return(True); - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { @@ -501,26 +495,26 @@ int get_share_modes(connection_struct *conn, Del the share mode of a file. ********************************************************************/ -void del_share_mode(int token, int fnum) +void del_share_mode(int token, files_struct *fsp) { - share_ops->del_entry(token, fnum); + share_ops->del_entry(token, fsp); } /******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type) +BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) { - return share_ops->set_entry(token, fnum, port, op_type); + return share_ops->set_entry(token, fsp, port, op_type); } /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ -BOOL remove_share_oplock(int fnum, int token) +BOOL remove_share_oplock(files_struct *fsp, int token) { - return share_ops->remove_oplock(fnum, token); + return share_ops->remove_oplock(fsp, token); } /******************************************************************* diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c index 84310d3a33..cded5e628d 100644 --- a/source3/locking/locking_shm.c +++ b/source3/locking/locking_shm.c @@ -37,7 +37,6 @@ #ifdef FAST_SHARE_MODES extern int DEBUGLEVEL; -extern files_struct Files[]; static struct shmem_ops *shmops; @@ -258,7 +257,7 @@ static int shm_get_share_modes(connection_struct *conn, /******************************************************************* del the share mode of a file. ********************************************************************/ -static void shm_del_share_mode(int token, int fnum) +static void shm_del_share_mode(int token, files_struct *fsp) { uint32 dev, inode; int *mode_array; @@ -270,8 +269,8 @@ static void shm_del_share_mode(int token, int fnum) BOOL found = False; int pid = getpid(); - dev = Files[fnum].fd_ptr->dev; - inode = Files[fnum].fd_ptr->inode; + dev = fsp->fd_ptr->dev; + inode = fsp->fd_ptr->inode; hash_entry = HASH_ENTRY(dev, inode); @@ -329,7 +328,7 @@ static void shm_del_share_mode(int token, int fnum) { if( (pid == entry_scanner_p->e.pid) && (memcmp(&entry_scanner_p->e.time, - &Files[fnum].open_time,sizeof(struct timeval)) == 0) ) + &fsp->open_time,sizeof(struct timeval)) == 0) ) { found = True; break; @@ -386,9 +385,8 @@ static void shm_del_share_mode(int token, int fnum) /******************************************************************* set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) +static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) { - files_struct *fs_p = &Files[fnum]; int32 dev, inode; int *mode_array; unsigned int hash_entry; @@ -398,8 +396,8 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) int new_entry_offset; BOOL found = False; - dev = fs_p->fd_ptr->dev; - inode = fs_p->fd_ptr->inode; + dev = fsp->fd_ptr->dev; + inode = fsp->fd_ptr->inode; hash_entry = HASH_ENTRY(dev, inode); @@ -428,7 +426,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) /* We must create a share_mode_record */ share_mode_record *new_mode_p = NULL; int new_offset = shmops->shm_alloc(sizeof(share_mode_record) + - strlen(fs_p->fsp_name) + 1); + strlen(fsp->fsp_name) + 1); if(new_offset == 0) { DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n")); return False; @@ -439,7 +437,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) new_mode_p->st_ino = inode; new_mode_p->num_share_mode_entries = 0; new_mode_p->share_mode_entries = 0; - pstrcpy(new_mode_p->file_name, fs_p->fsp_name); + pstrcpy(new_mode_p->file_name, fsp->fsp_name); /* Chain onto the start of the hash chain (in the hope we will be used first). */ new_mode_p->next_offset = mode_array[hash_entry]; @@ -448,7 +446,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) file_scanner_p = new_mode_p; DEBUG(3,("set_share_mode: Created share record for %s (dev %d inode %d)\n", - fs_p->fsp_name, dev, inode)); + fsp->fsp_name, dev, inode)); } /* Now create the share mode entry */ @@ -466,10 +464,10 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) new_entry_p = shmops->offset2addr(new_entry_offset); new_entry_p->e.pid = getpid(); - new_entry_p->e.share_mode = fs_p->share_mode; + new_entry_p->e.share_mode = fsp->share_mode; new_entry_p->e.op_port = port; new_entry_p->e.op_type = op_type; - memcpy( (char *)&new_entry_p->e.time, (char *)&fs_p->open_time, sizeof(struct timeval)); + memcpy( (char *)&new_entry_p->e.time, (char *)&fsp->open_time, sizeof(struct timeval)); /* Chain onto the share_mode_record */ new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries; @@ -487,7 +485,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) file_scanner_p->num_share_mode_entries += 1; DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n", - fs_p->fsp_name, fs_p->share_mode, new_entry_p->e.pid)); + fsp->fsp_name, fsp->share_mode, new_entry_p->e.pid)); return(True); } @@ -495,7 +493,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type) /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ -static BOOL shm_remove_share_oplock(int fnum, int token) +static BOOL shm_remove_share_oplock(files_struct *fsp, int token) { uint32 dev, inode; int *mode_array; @@ -507,8 +505,8 @@ static BOOL shm_remove_share_oplock(int fnum, int token) BOOL found = False; int pid = getpid(); - dev = Files[fnum].fd_ptr->dev; - inode = Files[fnum].fd_ptr->inode; + dev = fsp->fd_ptr->dev; + inode = fsp->fd_ptr->inode; hash_entry = HASH_ENTRY(dev, inode); @@ -565,9 +563,9 @@ static BOOL shm_remove_share_oplock(int fnum, int token) while(entry_scanner_p) { if( (pid == entry_scanner_p->e.pid) && - (entry_scanner_p->e.share_mode == Files[fnum].share_mode) && + (entry_scanner_p->e.share_mode == fsp->share_mode) && (memcmp(&entry_scanner_p->e.time, - &Files[fnum].open_time,sizeof(struct timeval)) == 0) ) + &fsp->open_time,sizeof(struct timeval)) == 0) ) { /* Delete the oplock info. */ entry_scanner_p->e.op_port = 0; diff --git a/source3/locking/locking_slow.c b/source3/locking/locking_slow.c index 9135ae29d2..8b56e7599b 100644 --- a/source3/locking/locking_slow.c +++ b/source3/locking/locking_slow.c @@ -37,7 +37,6 @@ #ifndef FAST_SHARE_MODES extern int DEBUGLEVEL; -extern files_struct Files[]; /* * Locking file header lengths & offsets. @@ -534,7 +533,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); /******************************************************************* del a share mode from a share mode file. ********************************************************************/ -static void slow_del_share_mode(int token, int fnum) +static void slow_del_share_mode(int token, files_struct *fsp) { pstring fname; int fd = (int)token; @@ -543,15 +542,14 @@ static void slow_del_share_mode(int token, int fnum) int num_entries; int newsize; int i; - files_struct *fs_p = &Files[fnum]; int pid; BOOL deleted = False; BOOL new_file; - share_name(fs_p->conn, fs_p->fd_ptr->dev, - fs_p->fd_ptr->inode, fname); + share_name(fsp->conn, fsp->fd_ptr->dev, + fsp->fd_ptr->inode, fname); - if(read_share_file( fs_p->conn, fd, fname, &buf, &new_file) != 0) + if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0) { DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n", fname)); @@ -562,7 +560,7 @@ static void slow_del_share_mode(int token, int fnum) { DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n", fname)); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return; } @@ -586,7 +584,7 @@ for share file %d\n", num_entries, fname)); fname)); if(buf) free(buf); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return; } @@ -602,9 +600,9 @@ for share file %d\n", num_entries, fname)); { char *p = base + (i*SMF_ENTRY_LENGTH); - if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || - (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) || - (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || + if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || + (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) || + (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || (IVAL(p,SME_PID_OFFSET) != pid)) continue; @@ -637,7 +635,7 @@ for share file %d\n", num_entries, fname)); fname)); if(buf) free(buf); - delete_share_file(fs_p->conn,fname); + delete_share_file(fsp->conn,fname); return; } @@ -675,9 +673,8 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); /******************************************************************* set the share mode of a file ********************************************************************/ -static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type) +static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16 op_type) { - files_struct *fs_p = &Files[fnum]; pstring fname; int fd = (int)token; int pid = (int)getpid(); @@ -687,8 +684,8 @@ static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type) int header_size; char *p; - share_name(fs_p->conn, fs_p->fd_ptr->dev, - fs_p->fd_ptr->inode, fname); + share_name(fsp->conn, fsp->fd_ptr->dev, + fsp->fd_ptr->inode, fname); if(fstat(fd, &sb) != 0) { @@ -735,7 +732,7 @@ locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION)); if(buf) free(buf); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return False; } @@ -748,7 +745,7 @@ locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET), deleting it.\n", fname)); if(buf) free(buf); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return False; } @@ -757,23 +754,23 @@ deleting it.\n", fname)); { /* New file - just use a single_entry. */ if((buf = (char *)malloc(SMF_HEADER_LENGTH + - strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL) + strlen(fsp->name) + 1 + SMF_ENTRY_LENGTH)) == NULL) { DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n")); return False; } SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION); SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0); - SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1); - pstrcpy(buf + SMF_HEADER_LENGTH, fs_p->name); + SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->name) + 1); + pstrcpy(buf + SMF_HEADER_LENGTH, fsp->name); } num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH); - SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec); - SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec); - SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode); + SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec); + SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec); + SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode); SIVAL(p,SME_PID_OFFSET,pid); SSVAL(p,SME_PORT_OFFSET,port); SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type); @@ -796,7 +793,7 @@ deleting it.\n", fname)); { DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \ deleting it (%s).\n",fname, strerror(errno))); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); if(buf) free(buf); return False; @@ -818,7 +815,7 @@ mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entr free(buf); DEBUG(3,("set_share_mode: Created share file %s with \ -mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid)); +mode 0x%X pid=%d\n",fname,fsp->share_mode,pid)); return True; } @@ -826,7 +823,7 @@ mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid)); /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ -static BOOL slow_remove_share_oplock(int fnum, int token) +static BOOL slow_remove_share_oplock(files_struct *fsp, int token) { pstring fname; int fd = (int)token; @@ -835,15 +832,14 @@ static BOOL slow_remove_share_oplock(int fnum, int token) int num_entries; int fsize; int i; - files_struct *fs_p = &Files[fnum]; int pid; BOOL found = False; BOOL new_file; - share_name(fs_p->conn, fs_p->fd_ptr->dev, - fs_p->fd_ptr->inode, fname); + share_name(fsp->conn, fsp->fd_ptr->dev, + fsp->fd_ptr->inode, fname); - if(read_share_file( fs_p->conn, fd, fname, &buf, &new_file) != 0) + if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0) { DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n", fname)); @@ -854,7 +850,7 @@ static BOOL slow_remove_share_oplock(int fnum, int token) { DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \ deleting it.\n", fname)); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return False; } @@ -878,7 +874,7 @@ for share file %d\n", num_entries, fname)); fname)); if(buf) free(buf); - delete_share_file(fs_p->conn, fname); + delete_share_file(fsp->conn, fname); return False; } @@ -894,9 +890,9 @@ for share file %d\n", num_entries, fname)); { char *p = base + (i*SMF_ENTRY_LENGTH); - if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || - (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) || - (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || + if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || + (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) || + (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || (IVAL(p,SME_PID_OFFSET) != pid)) continue; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index d792a16426..bd29578f0e 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -35,8 +35,6 @@ static int chain_pnum = -1; #define MAX_OPEN_PIPES 50 #endif -#define PIPE_HANDLE_OFFSET 0x800 - pipes_struct Pipes[MAX_OPEN_PIPES]; #define P_OPEN(p) ((p)->open) diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 28a68e29e2..0b963cbc80 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -80,7 +80,7 @@ END { next; } -!/^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ { +!/^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ { next; } diff --git a/source3/smbd/files.c b/source3/smbd/files.c new file mode 100644 index 0000000000..a37d190f01 --- /dev/null +++ b/source3/smbd/files.c @@ -0,0 +1,321 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Files[] structure handling + Copyright (C) Andrew Tridgell 1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + +#define MAX_OPEN_FILES 100 + +#define MAX_FNUMS (MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES) +#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < MAX_FNUMS)) + +static files_struct Files[MAX_FNUMS]; + +/* + * Indirection for file fd's. Needed as POSIX locking + * is based on file/process, not fd/process. + */ +static file_fd_struct FileFd[MAX_OPEN_FILES]; +static int max_file_fd_used = 0; + + +/**************************************************************************** + find first available file slot +****************************************************************************/ +files_struct *find_free_file(void ) +{ + int i; + static int first_file; + + /* we want to give out file handles differently on each new + connection because of a common bug in MS clients where they try to + reuse a file descriptor from an earlier smb connection. This code + increases the chance that the errant client will get an error rather + than causing corruption */ + if (first_file == 0) { + first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS; + if (first_file == 0) first_file = 1; + } + + if (first_file >= MAX_FNUMS) + first_file = 1; + + for (i=first_file;i<MAX_FNUMS;i++) + if (!Files[i].open && !Files[i].reserved) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + Files[i].fnum = i; + return &Files[i]; + } + + /* returning a file handle of 0 is a bad idea - so we start at 1 */ + for (i=1;i<first_file;i++) + if (!Files[i].open && !Files[i].reserved) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + Files[i].fnum = i; + return &Files[i]; + } + + /* + * Before we give up, go through the open files + * and see if there are any files opened with a + * batch oplock. If so break the oplock and then + * re-use that entry (if it becomes closed). + * This may help as NT/95 clients tend to keep + * files batch oplocked for quite a long time + * after they have finished with them. + */ + for (i=first_file;i<MAX_FNUMS;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + Files[i].fnum = i; + return &Files[i]; + } + } + + for (i=1;i<MAX_FNUMS;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + Files[i].fnum = i; + return &Files[i]; + } + } + + DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); + return NULL; +} + + + +/**************************************************************************** +fd support routines - attempt to find an already open file by dev +and inode - increments the ref_count of the returned file_fd_struct *. +****************************************************************************/ +file_fd_struct *fd_get_already_open(struct stat *sbuf) +{ + int i; + file_fd_struct *fd_ptr; + + if(sbuf == 0) + return 0; + + for(i = 0; i <= max_file_fd_used; i++) { + fd_ptr = &FileFd[i]; + if((fd_ptr->ref_count > 0) && + (((uint32)sbuf->st_dev) == fd_ptr->dev) && + (((uint32)sbuf->st_ino) == fd_ptr->inode)) { + fd_ptr->ref_count++; + DEBUG(3, + ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n", + i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count)); + return fd_ptr; + } + } + return 0; +} + +/**************************************************************************** +fd support routines - attempt to find a empty slot in the FileFd array. +Increments the ref_count of the returned entry. +****************************************************************************/ +file_fd_struct *fd_get_new(void) +{ + extern struct current_user current_user; + int i; + file_fd_struct *fd_ptr; + + for(i = 0; i < MAX_OPEN_FILES; i++) { + fd_ptr = &FileFd[i]; + if(fd_ptr->ref_count == 0) { + fd_ptr->dev = (uint32)-1; + fd_ptr->inode = (uint32)-1; + fd_ptr->fd = -1; + fd_ptr->fd_readonly = -1; + fd_ptr->fd_writeonly = -1; + fd_ptr->real_open_flags = -1; + fd_ptr->uid_cache_count = 0; + fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid); + fd_ptr->ref_count++; + /* Increment max used counter if neccessary, cuts down + on search time when re-using */ + if(i > max_file_fd_used) + max_file_fd_used = i; + DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n", + i, fd_ptr->dev, fd_ptr->inode)); + return fd_ptr; + } + } + DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n")); + return 0; +} + + +/**************************************************************************** +close all open files for a connection +****************************************************************************/ +void file_close_conn(connection_struct *conn) +{ + int i; + for (i=0;i<MAX_FNUMS;i++) + if (Files[i].conn == conn && Files[i].open) { + if(Files[i].is_directory) + close_directory(&Files[i]); + else + close_file(&Files[i],False); + } +} + +/**************************************************************************** +initialise file structures +****************************************************************************/ +void file_init(void) +{ + int i; + +#ifdef HAVE_GETRLIMIT +#ifdef RLIMIT_NOFILE + { + struct rlimit rlp; + getrlimit(RLIMIT_NOFILE, &rlp); + /* Set the fd limit to be MAX_OPEN_FILES + 10 to + * account for the extra fd we need to read + * directories, as well as the log files and standard + * handles etc. */ + rlp.rlim_cur = (MAX_FNUMS+10>rlp.rlim_max)? + rlp.rlim_max:MAX_FNUMS+10; + setrlimit(RLIMIT_NOFILE, &rlp); + getrlimit(RLIMIT_NOFILE, &rlp); + DEBUG(3,("Maximum number of open files per session is %d\n", + (int)rlp.rlim_cur)); + } +#endif +#endif + + + + for (i=0;i<MAX_FNUMS;i++) { + Files[i].open = False; + string_init(&Files[i].fsp_name,""); + } + + for (i=0;i<MAX_OPEN_FILES;i++) { + file_fd_struct *fd_ptr = &FileFd[i]; + fd_ptr->ref_count = 0; + fd_ptr->dev = (int32)-1; + fd_ptr->inode = (int32)-1; + fd_ptr->fd = -1; + fd_ptr->fd_readonly = -1; + fd_ptr->fd_writeonly = -1; + fd_ptr->real_open_flags = -1; + } +} + +/**************************************************************************** +find a fsp given a fnum +****************************************************************************/ +files_struct *file_fsp(int fnum) +{ + if (!VALID_FNUM(fnum)) return NULL; + return &Files[fnum]; +} + + +/**************************************************************************** +close files open by a specified vuid +****************************************************************************/ +void file_close_user(int vuid) +{ + int i; + for (i=0;i<MAX_FNUMS;i++) { + files_struct *fsp = &Files[i]; + if ((fsp->vuid == vuid) && fsp->open) { + if(!fsp->is_directory) + close_file(fsp,False); + else + close_directory(fsp); + } + } +} + + +/**************************************************************************** +find a fsp given a device, inode and timevalue +****************************************************************************/ +files_struct *file_find_dit(int dev, int inode, struct timeval *tval) +{ + int i; + for (i=0;i<MAX_FNUMS;i++) { + files_struct *fsp = &Files[i]; + if (fsp->open && + fsp->fd_ptr->dev == dev && + fsp->fd_ptr->inode == inode && + fsp->open_time.tv_sec == tval->tv_sec && + fsp->open_time.tv_usec == tval->tv_usec) { + return fsp; + } + } + return NULL; +} + +/**************************************************************************** +find a fsp that is open for printing +****************************************************************************/ +files_struct *file_find_print(void) +{ + int i; + + for (i=0;i<MAX_FNUMS;i++) { + files_struct *fsp = &Files[i]; + if (fsp->open && fsp->print_file) { + return fsp; + } + } + return NULL; +} + + +/**************************************************************************** +sync open files on a connection +****************************************************************************/ +void file_sync_all(connection_struct *conn) +{ + int i; + for (i=0;i<MAX_FNUMS;i++) { + files_struct *fsp = &Files[i]; + if (fsp->open && conn == fsp->conn) { + sync_file(conn,fsp); + } + } +} + + +void file_free(files_struct *fsp) +{ + memset(fsp, 0, sizeof(*fsp)); +} diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 63495f0479..ae225956a2 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -36,7 +36,6 @@ extern int DEBUGLEVEL; extern int max_send; -extern files_struct Files[]; extern fstring local_machine; extern fstring global_myworkgroup; @@ -1913,108 +1912,105 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - struct pack_desc desc; - char *str1 = param+2; - char *str2 = skip_string(str1,1); - char *p = skip_string(str2,1); - int jobid, snum; - int uLevel = SVAL(p,2); - int function = SVAL(p,4); /* what is this ?? */ - int i; - char *s = data; + struct pack_desc desc; + char *str1 = param+2; + char *str2 = skip_string(str1,1); + char *p = skip_string(str2,1); + int jobid, snum; + int uLevel = SVAL(p,2); + int function = SVAL(p,4); /* what is this ?? */ + int i; + char *s = data; + files_struct *fsp; - printjob_decode(SVAL(p,0), &snum, &jobid); + printjob_decode(SVAL(p,0), &snum, &jobid); - *rparam_len = 4; - *rparam = REALLOC(*rparam,*rparam_len); + *rparam_len = 4; + *rparam = REALLOC(*rparam,*rparam_len); - *rdata_len = 0; - - /* check it's a supported varient */ - if ((strcmp(str1,"WWsTP")) || (!check_printjob_info(&desc,uLevel,str2))) - return(False); + *rdata_len = 0; + + /* check it's a supported varient */ + if ((strcmp(str1,"WWsTP")) || + (!check_printjob_info(&desc,uLevel,str2))) + return(False); - switch (function) { - case 0x6: /* change job place in the queue, data gives the new place */ - if (snum >= 0 && VALID_SNUM(snum)) - { - print_queue_struct *queue=NULL; - int count; + switch (function) { + case 0x6: /* change job place in the queue, + data gives the new place */ + if (snum >= 0 && VALID_SNUM(snum)) { + print_queue_struct *queue=NULL; + int count; - lpq_reset(snum); - count = get_printqueue(snum,conn,&queue,NULL); - for (i=0;i<count;i++) /* find job */ - if ((queue[i].job&0xFF) == jobid) break; + lpq_reset(snum); + count = get_printqueue(snum,conn,&queue,NULL); + for (i=0;i<count;i++) /* find job */ + if ((queue[i].job&0xFF) == jobid) break; - if (i==count) { - desc.errcode=NERR_JobNotFound; - if (queue) free(queue); - } - else { - desc.errcode=NERR_Success; - i++; + if (i==count) { + desc.errcode=NERR_JobNotFound; + if (queue) free(queue); + } else { + desc.errcode=NERR_Success; + i++; #if 0 - { - int place= SVAL(data,0); - /* we currently have no way of doing this. Can any unix do it? */ - if (i < place) /* move down */; - else if (i > place ) /* move up */; - } + { + int place= SVAL(data,0); + /* we currently have no way of + doing this. Can any unix do it? */ + if (i < place) /* move down */; + else if (i > place ) /* move up */; + } #endif - desc.errcode=NERR_notsupported; /* not yet supported */ - if (queue) free(queue); - } - } - else desc.errcode=NERR_JobNotFound; - break; - case 0xb: /* change print job name, data gives the name */ - /* jobid, snum should be zero */ - if (isalpha((int)*s)) - { - pstring name; - int l = 0; - while (l<64 && *s) - { - if (issafe(*s)) name[l++] = *s; - s++; - } - name[l] = 0; + desc.errcode=NERR_notsupported; /* not yet + supported */ + if (queue) free(queue); + } + } else { + desc.errcode=NERR_JobNotFound; + } + break; + + case 0xb: /* change print job name, data gives the name */ + /* jobid, snum should be zero */ + if (isalpha((int)*s)) { + pstring name; + int l = 0; + while (l<64 && *s) { + if (issafe(*s)) name[l++] = *s; + s++; + } + name[l] = 0; - DEBUG(3,("Setting print name to %s\n",name)); + DEBUG(3,("Setting print name to %s\n",name)); - become_root(True); - - for (i=0;i<MAX_FNUMS;i++) - if (Files[i].open && Files[i].print_file) - { - pstring wd; - connection_struct *fconn = Files[i].conn; - GetWd(wd); - unbecome_user(); + fsp = file_find_print(); + + if (fsp) { + connection_struct *fconn = fsp->conn; + unbecome_user(); - if (!become_user(fconn,vuid) || - !become_service(fconn,True)) - break; + if (!become_user(fconn,vuid) || + !become_service(fconn,True)) + break; - if (sys_rename(Files[i].fsp_name,name) == 0) { - string_set(&Files[i].fsp_name,name); - } - break; - } + if (sys_rename(fsp->fsp_name,name) == 0) { + string_set(&fsp->fsp_name,name); + } + break; + } + } + desc.errcode=NERR_Success; + break; - unbecome_root(True); - } - desc.errcode=NERR_Success; - - break; - default: /* not implemented */ - return False; - } + default: /* not implemented */ + return False; + } - SSVALS(*rparam,0,desc.errcode); - SSVAL(*rparam,2,0); /* converter word */ - - return(True); + SSVALS(*rparam,0,desc.errcode); + SSVAL(*rparam,2,0); /* converter word */ + + return(True); } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 94ecbfea49..d396b05a62 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -24,8 +24,7 @@ extern int DEBUGLEVEL; extern int Protocol; -extern int chain_fnum; -extern files_struct Files[]; +extern files_struct *chain_fsp; extern int Client; extern int oplock_sock; extern int smb_read_error; @@ -388,7 +387,8 @@ static int nt_open_pipe(char *fname, connection_struct *conn, if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); - *ppnum = pnum + 0x800; /* Mark file handle up into high range. */ + *ppnum = pnum + PIPE_HANDLE_OFFSET; /* Mark file handle up into high + range. */ return 0; } @@ -399,7 +399,6 @@ int reply_ntcreate_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - int fnum = -1; uint32 flags = IVAL(inbuf,smb_ntcreate_Flags); uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes); @@ -413,7 +412,7 @@ int reply_ntcreate_and_X(connection_struct *conn, /* Breakout the oplock request bits so we can set the reply bits separately. */ int oplock_request = 0; - int unixmode; + int unixmode, pnum = -1; int fmode=0,mtime=0,rmode=0; off_t file_len = 0; struct stat sbuf; @@ -449,10 +448,9 @@ int reply_ntcreate_and_X(connection_struct *conn, /* If it's an IPC, use the pipe handler. */ if (IS_IPC(conn)) { - int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum); + int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum); if(ret != 0) return ret; - fsp = &Files[fnum]; smb_action = FILE_WAS_OPENED; } else { @@ -468,20 +466,18 @@ int reply_ntcreate_and_X(connection_struct *conn, unix_convert(fname,conn,0,&bad_path); - fnum = find_free_file(); - if (fnum < 0) { + fsp = find_free_file(); + if (!fsp) { restore_case_semantics(file_attributes); return(ERROR(ERRSRV,ERRnofids)); } - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); restore_case_semantics(file_attributes); @@ -500,13 +496,13 @@ int reply_ntcreate_and_X(connection_struct *conn, if(flags & OPEN_DIRECTORY) { oplock_request = 0; - open_directory(fnum, conn, fname, smb_ofun, + open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action); restore_case_semantics(file_attributes); if(!fsp->open) { - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } } else { @@ -527,7 +523,7 @@ int reply_ntcreate_and_X(connection_struct *conn, * before issuing an oplock break request to * our client. JRA. */ - open_file_shared(fnum,conn,fname,smb_open_mode, + open_file_shared(fsp,conn,fname,smb_open_mode, smb_ofun,unixmode, oplock_request,&rmode,&smb_action); @@ -551,10 +547,10 @@ int reply_ntcreate_and_X(connection_struct *conn, if(errno == EISDIR) { oplock_request = 0; - open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action); + open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action); if(!fsp->open) { - fsp->reserved = False; + file_free(fsp); restore_case_semantics(file_attributes); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -564,7 +560,7 @@ int reply_ntcreate_and_X(connection_struct *conn, unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); restore_case_semantics(file_attributes); @@ -575,13 +571,13 @@ int reply_ntcreate_and_X(connection_struct *conn, if(fsp->is_directory) { if(sys_stat(fsp->fsp_name, &sbuf) != 0) { - close_directory(fnum); + close_directory(fsp); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } } else { if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); + close_file(fsp,False); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -595,7 +591,7 @@ int reply_ntcreate_and_X(connection_struct *conn, fmode = FILE_ATTRIBUTE_NORMAL; mtime = sbuf.st_mtime; if (!fsp->is_directory && (fmode & aDIR)) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -623,7 +619,11 @@ int reply_ntcreate_and_X(connection_struct *conn, SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0)); p++; - SSVAL(p,0,fnum); + if (IS_IPC(conn)) { + SSVAL(p,0,pnum); + } else { + SSVAL(p,0,fsp->fnum); + } p += 2; SIVAL(p,0,smb_action); p += 4; @@ -664,11 +664,10 @@ int reply_ntcreate_and_X(connection_struct *conn, SCVAL(p,0,fsp->is_directory ? 1 : 0); } - chain_fnum = fnum; + chain_fsp = fsp; - - DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n", - fnum, fsp->fsp_name)); + DEBUG(5,("reply_ntcreate_and_X: open name = %s\n", + fsp->fsp_name)); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -683,7 +682,6 @@ static int call_nt_transact_create(connection_struct *conn, char **ppdata) { pstring fname; - int fnum = -1; char *params = *ppparams; uint32 flags = IVAL(params,0); uint32 desired_access = IVAL(params,8); @@ -698,7 +696,7 @@ static int call_nt_transact_create(connection_struct *conn, /* Breakout the oplock request bits so we can set the reply bits separately. */ int oplock_request = 0; - int unixmode; + int unixmode, pnum = -1; int fmode=0,mtime=0,rmode=0; off_t file_len = 0; struct stat sbuf; @@ -732,7 +730,7 @@ static int call_nt_transact_create(connection_struct *conn, /* If it's an IPC, use the pipe handler. */ if (IS_IPC(conn)) { - int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum); + int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum); if(ret != 0) return ret; smb_action = FILE_WAS_OPENED; @@ -745,14 +743,12 @@ static int call_nt_transact_create(connection_struct *conn, unix_convert(fname,conn,0,&bad_path); - fnum = find_free_file(); - if (fnum < 0) { - restore_case_semantics(file_attributes); - return(ERROR(ERRSRV,ERRnofids)); + fsp = find_free_file(); + if (!fsp) { + restore_case_semantics(file_attributes); + return(ERROR(ERRSRV,ERRnofids)); } - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { unix_ERR_class = ERRDOS; @@ -784,10 +780,10 @@ static int call_nt_transact_create(connection_struct *conn, * CreateDirectory() call. */ - open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action); + open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action); if(!fsp->open) { - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } } else { @@ -796,7 +792,7 @@ static int call_nt_transact_create(connection_struct *conn, * Ordinary file case. */ - open_file_shared(fnum,conn,fname,smb_open_mode,smb_ofun,unixmode, + open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode, oplock_request,&rmode,&smb_action); if (!fsp->open) { @@ -804,7 +800,7 @@ static int call_nt_transact_create(connection_struct *conn, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); restore_case_semantics(file_attributes); @@ -812,7 +808,7 @@ static int call_nt_transact_create(connection_struct *conn, } if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); + close_file(fsp,False); restore_case_semantics(file_attributes); @@ -826,7 +822,7 @@ static int call_nt_transact_create(connection_struct *conn, mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum,False); + close_file(fsp,False); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -855,7 +851,11 @@ static int call_nt_transact_create(connection_struct *conn, p = params; SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0)); p += 2; - SSVAL(p,0,fnum); + if (IS_IPC(conn)) { + SSVAL(p,0,pnum); + } else { + SSVAL(p,0,fsp->fnum); + } p += 2; SIVAL(p,0,smb_action); p += 8; @@ -940,17 +940,17 @@ static int call_nt_transact_rename(connection_struct *conn, { char *params = *ppparams; pstring new_name; - int fnum = SVAL(params, 0); + files_struct *fsp = GETFSP(params, 0); BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)), ((uint32)sizeof(new_name)-1)); int outsize = 0; - CHECK_FNUM(fnum, conn); + CHECK_FSP(fsp, conn); StrnCpy(new_name,params+4,fname_len); new_name[fname_len] = '\0'; - outsize = rename_internals(conn, inbuf, outbuf, Files[fnum].fsp_name, + outsize = rename_internals(conn, inbuf, outbuf, fsp->fsp_name, new_name, replace_if_exists); if(outsize == 0) { /* @@ -959,7 +959,7 @@ static int call_nt_transact_rename(connection_struct *conn, send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0); DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", - Files[fnum].fsp_name, new_name)); + fsp->fsp_name, new_name)); outsize = -1; } @@ -976,7 +976,7 @@ static int call_nt_transact_rename(connection_struct *conn, typedef struct { ubi_slNode msg_next; - int fnum; + files_struct *fsp; connection_struct *conn; time_t next_check_time; time_t modify_time; /* Info from the directory we're monitoring. */ @@ -1023,14 +1023,13 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro /**************************************************************************** Delete entries by fnum from the change notify pending queue. *****************************************************************************/ - -void remove_pending_change_notify_requests_by_fid(int fnum) +void remove_pending_change_notify_requests_by_fid(files_struct *fsp) { change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue ); change_notify_buf *prev = NULL; while(cnbp != NULL) { - if(cnbp->fnum == fnum) { + if(cnbp->fsp == fsp) { free((char *)ubi_slRemNext( &change_notify_queue, prev)); cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); continue; @@ -1085,9 +1084,8 @@ void process_pending_change_notify_queue(time_t t) while((cnbp != NULL) && (cnbp->next_check_time <= t)) { struct stat st; - int fnum = cnbp->fnum; + files_struct *fsp = cnbp->fsp; connection_struct *conn = cnbp->conn; - files_struct *fsp = &Files[fnum]; uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(cnbp->request_buf,smb_uid); @@ -1133,8 +1131,8 @@ Error was %s.\n", fsp->fsp_name, strerror(errno) )); /* * Remove the entry and return a change notify to the client. */ - DEBUG(5,("process_pending_change_notify_queue: directory fnum = %d, name = %s changed\n", - fnum, fsp->fsp_name )); + DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed\n", + fsp->fsp_name )); change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR); free((char *)ubi_slRemNext( &change_notify_queue, prev)); cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); @@ -1164,19 +1162,16 @@ static int call_nt_transact_notify_change(connection_struct *conn, { char *setup = *ppsetup; files_struct *fsp; - int fnum = -1; change_notify_buf *cnbp; struct stat st; - fnum = SVAL(setup,4); + fsp = GETFSP(setup,4); - DEBUG(3,("call_nt_transact_notify_change: fnum = %d.\n", fnum)); + DEBUG(3,("call_nt_transact_notify_change\n")); - if(!VALID_FNUM(fnum)) + if(!fsp) return(ERROR(ERRDOS,ERRbadfid)); - fsp = &Files[fnum]; - if((!fsp->open) || (!fsp->is_directory) || (conn != fsp->conn)) return(ERROR(ERRDOS,ERRbadfid)); @@ -1198,14 +1193,14 @@ static int call_nt_transact_notify_change(connection_struct *conn, */ if(sys_stat(fsp->fsp_name, &st) < 0) { - DEBUG(0,("call_nt_transact_notify_change: Unable to stat fnum = %d, name = %s. \ -Error was %s\n", fnum, fsp->fsp_name, strerror(errno) )); + DEBUG(0,("call_nt_transact_notify_change: Unable to stat name = %s. \ +Error was %s\n", fsp->fsp_name, strerror(errno) )); free((char *)cnbp); return(UNIXERROR(ERRDOS,ERRbadfid)); } memcpy(cnbp->request_buf, inbuf, smb_size); - cnbp->fnum = fnum; + cnbp->fsp = fsp; cnbp->conn = conn; cnbp->modify_time = st.st_mtime; cnbp->status_time = st.st_ctime; @@ -1221,7 +1216,7 @@ Error was %s\n", fnum, fsp->fsp_name, strerror(errno) )); ubi_slAddTail(&change_notify_queue, cnbp); DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \ -fid=%d, name = %s\n", fnum, fsp->fsp_name )); +name = %s\n", fsp->fsp_name )); return -1; } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2a51e83946..9ec77c08ca 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -44,7 +44,6 @@ extern int Client; #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) -#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum) /* this macro should always be used to extract an pnum (smb_fid) from a packet to ensure chaining works correctly */ @@ -84,7 +83,7 @@ int reply_open_pipe_and_X(connection_struct *conn, if( strequal(fname,pipe_names[i].client_pipe) ) break; - if ( pipe_names[i].client_pipe == NULL ) + if (pipe_names[i].client_pipe == NULL) return(ERROR(ERRSRV,ERRaccess)); /* Strip \PIPE\ off the name. */ @@ -111,7 +110,9 @@ int reply_open_pipe_and_X(connection_struct *conn, rmode = 1; } - SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */ + SSVAL(outbuf,smb_vwv2, pnum + PIPE_HANDLE_OFFSET); /* mark file + handle up into + high range */ SSVAL(outbuf,smb_vwv3,fmode); put_dos_date3(outbuf,smb_vwv4,mtime); SIVAL(outbuf,smb_vwv6,size); @@ -138,12 +139,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) char *data; BOOL ok = False; -/* - CHECK_FNUM(fnum,cnum); - CHECK_READ(fnum); - CHECK_ERROR(fnum); -*/ - set_message(outbuf,12,0,True); data = smb_buf(outbuf); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 626d2e9617..e9a25ea79a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -33,9 +33,8 @@ extern int Protocol; extern int DEBUGLEVEL; extern int max_send; extern int max_recv; -extern int chain_fnum; +extern files_struct *chain_fsp; extern char magic_char; -extern files_struct Files[]; extern BOOL case_sensitive; extern BOOL case_preserve; extern BOOL short_case_preserve; @@ -44,11 +43,6 @@ extern fstring global_myworkgroup; extern int Client; extern int global_oplock_break; -/* this macro should always be used to extract an fnum (smb_fid) from -a packet to ensure chaining works correctly */ -#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) - - /**************************************************************************** report a possible attack via the password buffer overflow bug ****************************************************************************/ @@ -1232,7 +1226,6 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - int fnum = -1; int outsize = 0; int fmode=0; int share_mode; @@ -1250,12 +1243,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, pstrcpy(fname,smb_buf(inbuf)+1); unix_convert(fname,conn,0,&bad_path); - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (!fsp) return(ERROR(ERRSRV,ERRnofids)); - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) @@ -1263,13 +1254,13 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } unixmode = unix_mode(conn,aARCH); - open_file_shared(fnum,conn,fname,share_mode,3,unixmode, + open_file_shared(fsp,conn,fname,share_mode,3,unixmode, oplock_request,&rmode,NULL); if (!fsp->open) @@ -1279,12 +1270,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1294,12 +1285,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (fmode & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fname)); - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } outsize = set_message(outbuf,7,0,True); - SSVAL(outbuf,smb_vwv0,fnum); + SSVAL(outbuf,smb_vwv0,fsp->fnum); SSVAL(outbuf,smb_vwv1,fmode); if(lp_dos_filetime_resolution(SNUM(conn)) ) put_dos_date3(outbuf,smb_vwv2,mtime & ~1); @@ -1324,7 +1315,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - int fnum = -1; int smb_mode = SVAL(inbuf,smb_vwv3); int smb_attr = SVAL(inbuf,smb_vwv5); /* Breakout the oplock request bits so we can set the @@ -1354,12 +1344,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt pstrcpy(fname,smb_buf(inbuf)); unix_convert(fname,conn,0,&bad_path); - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (!fsp) return(ERROR(ERRSRV,ERRnofids)); - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) @@ -1367,13 +1355,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } unixmode = unix_mode(conn,smb_attr | aARCH); - open_file_shared(fnum,conn,fname,smb_mode,smb_ofun,unixmode, + open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode, oplock_request, &rmode,&smb_action); if (!fsp->open) @@ -1383,12 +1371,12 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1396,7 +1384,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt fmode = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1427,7 +1415,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } set_message(outbuf,15,0,True); - SSVAL(outbuf,smb_vwv2,fnum); + SSVAL(outbuf,smb_vwv2,fsp->fnum); SSVAL(outbuf,smb_vwv3,fmode); if(lp_dos_filetime_resolution(SNUM(conn)) ) put_dos_date3(outbuf,smb_vwv4,mtime & ~1); @@ -1437,7 +1425,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt SSVAL(outbuf,smb_vwv8,rmode); SSVAL(outbuf,smb_vwv11,smb_action); - chain_fnum = fnum; + chain_fsp = fsp; return chain_reply(inbuf,outbuf,length,bufsize); } @@ -1458,16 +1446,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length, /* in user level security we are supposed to close any files open by this user */ if ((vuser != 0) && (lp_security() != SEC_SHARE)) { - int i; - for (i=0;i<MAX_FNUMS;i++) { - files_struct *fsp = &Files[i]; - if ((fsp->vuid == vuid) && fsp->open) { - if(!fsp->is_directory) - close_file(i,False); - else - close_directory(i); - } - } + file_close_user(vuid); } invalidate_vuid(vuid); @@ -1487,7 +1466,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, { pstring fname; int com; - int fnum = -1; int outsize = 0; int createmode; mode_t unixmode; @@ -1509,12 +1487,10 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unixmode = unix_mode(conn,createmode); - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (!fsp) return(ERROR(ERRSRV,ERRnofids)); - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) @@ -1522,7 +1498,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -1538,7 +1514,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } /* Open file in dos compatibility share mode. */ - open_file_shared(fnum,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, + open_file_shared(fsp,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, oplock_request, NULL, NULL); if (!fsp->open) @@ -1548,12 +1524,12 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } outsize = set_message(outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,fnum); + SSVAL(outbuf,smb_vwv0,fsp->fnum); if (oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; @@ -1563,8 +1539,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; DEBUG( 2, ( "new file %s\n", fname ) ); - DEBUG( 3, ( "mknew %s fd=%d fnum=%d dmode=%d umode=%o\n", - fname, fsp->fd_ptr->fd, fnum, createmode, (int)unixmode ) ); + DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", + fname, fsp->fd_ptr->fd, createmode, (int)unixmode ) ); return(outsize); } @@ -1577,7 +1553,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, { pstring fname; pstring fname2; - int fnum = -1; int outsize = 0; int createmode; mode_t unixmode; @@ -1592,12 +1567,10 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unixmode = unix_mode(conn,createmode); - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (fsp) return(ERROR(ERRSRV,ERRnofids)); - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) @@ -1605,7 +1578,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -1613,7 +1586,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, /* Open file in dos compatibility share mode. */ /* We should fail if file exists. */ - open_file_shared(fnum,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, + open_file_shared(fsp,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, oplock_request, NULL, NULL); if (!fsp->open) @@ -1623,12 +1596,12 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } outsize = set_message(outbuf,1,2 + strlen(fname2),True); - SSVAL(outbuf,smb_vwv0,fnum); + SSVAL(outbuf,smb_vwv0,fsp->fnum); CVAL(smb_buf(outbuf),0) = 4; pstrcpy(smb_buf(outbuf) + 1,fname2); @@ -1640,8 +1613,8 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; DEBUG( 2, ( "created temp file %s\n", fname2 ) ); - DEBUG( 3, ( "ctemp %s fd=%d fnum=%d dmode=%d umode=%o\n", - fname2, fsp->fd_ptr->fd, fnum, createmode, (int)unixmode ) ); + DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n", + fname2, fsp->fd_ptr->fd, createmode, (int)unixmode ) ); return(outsize); } @@ -1777,7 +1750,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size ****************************************************************************/ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) { - int maxcount,mincount,fnum; + int maxcount,mincount; int nread = 0; uint32 startpos; char *header = outbuf; @@ -1800,7 +1773,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s return -1; } - fnum = GETFNUM(inbuf,smb_vwv0); + fsp = GETFSP(inbuf,smb_vwv0); startpos = IVAL(inbuf,smb_vwv1); maxcount = SVAL(inbuf,smb_vwv3); @@ -1810,23 +1783,18 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s maxcount = MIN(65535,maxcount); maxcount = MAX(mincount,maxcount); - if (!FNUM_OK(fnum,conn) || !Files[fnum].can_read) - { - DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fnum)); - _smb_setlen(header,0); - transfer_file(0,Client,0,header,4,0); - return(-1); - } - else - { - fsp = &Files[fnum]; - - fd = fsp->fd_ptr->fd; - fname = fsp->fsp_name; + if (!FNUM_OK(fsp,conn) || !fsp->can_read) { + DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fsp->fnum)); + _smb_setlen(header,0); + transfer_file(0,Client,0,header,4,0); + return(-1); + } else { + fd = fsp->fd_ptr->fd; + fname = fsp->fsp_name; } - if (!is_locked(fnum,conn,maxcount,startpos, F_RDLCK)) + if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK)) { int size = fsp->size; int sizeneeded = startpos + maxcount; @@ -1846,7 +1814,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s nread = 0; DEBUG( 3, ( "readbraw fnum=%d start=%d max=%d min=%d nread=%d\n", - fnum, startpos, + fsp->fnum, startpos, maxcount, mincount, nread ) ); #if UNSAFE_READRAW @@ -1860,7 +1828,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s #endif if ((nread-predict) > 0) - seek_file(fnum,startpos + predict); + seek_file(fsp,startpos + predict); ret = transfer_file(fd,Client,nread-predict,header,4+predict, startpos+predict); @@ -1871,7 +1839,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s fname,startpos,nread,ret)); #else - ret = read_file(fnum,header+4,startpos,nread); + ret = read_file(fsp,header+4,startpos,nread); if (ret < mincount) ret = 0; _smb_setlen(header,ret); @@ -1888,19 +1856,17 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s ****************************************************************************/ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) { - int fnum; int nread = -1; char *data; int outsize = 0; uint32 startpos, numtoread; int eclass; uint32 ecode; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_READ(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); + CHECK_ERROR(fsp); numtoread = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -1909,10 +1875,10 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fnum, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) + if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) return (ERROR(eclass,ecode)); - nread = read_file(fnum,data,startpos,numtoread); + nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -1923,7 +1889,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si SSVAL(smb_buf(outbuf),1,nread); DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n", - fnum, numtoread, nread ) ); + fsp->fnum, numtoread, nread ) ); return(outsize); } @@ -1934,17 +1900,16 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si ****************************************************************************/ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int numtoread,fnum; + int numtoread; int nread = 0; char *data; uint32 startpos; int outsize = 0; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_READ(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); + CHECK_ERROR(fsp); numtoread = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -1953,11 +1918,11 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if (is_locked(fnum,conn,numtoread,startpos, F_RDLCK)) + if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); if (numtoread > 0) - nread = read_file(fnum,data,startpos,numtoread); + nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -1969,7 +1934,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, SSVAL(smb_buf(outbuf),1,nread); DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", - fnum, numtoread, nread ) ); + fsp->fnum, numtoread, nread ) ); return(outsize); } @@ -1980,7 +1945,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, ****************************************************************************/ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint32 smb_offs = IVAL(inbuf,smb_vwv3); int smb_maxcnt = SVAL(inbuf,smb_vwv5); int smb_mincnt = SVAL(inbuf,smb_vwv6); @@ -1992,16 +1957,16 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (IS_IPC(conn)) return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); - CHECK_FNUM(fnum,conn); - CHECK_READ(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); + CHECK_ERROR(fsp); set_message(outbuf,12,0,True); data = smb_buf(outbuf); - if (is_locked(fnum,conn,smb_maxcnt,smb_offs, F_RDLCK)) + if (is_locked(fsp,conn,smb_maxcnt,smb_offs, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); - nread = read_file(fnum,data,smb_offs,smb_maxcnt); + nread = read_file(fsp,data,smb_offs,smb_maxcnt); ok = True; if (nread < 0) @@ -2012,9 +1977,9 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt SSVAL(smb_buf(outbuf),-2,nread); DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n", - fnum, smb_mincnt, smb_maxcnt, nread ) ); + fsp->fnum, smb_mincnt, smb_maxcnt, nread ) ); - chain_fnum = fnum; + chain_fsp = fsp; return chain_reply(inbuf,outbuf,length,bufsize); } @@ -2028,18 +1993,16 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s int nwritten=0; int total_written=0; int numtowrite=0; - int fnum; int outsize = 0; long startpos; char *data=NULL; BOOL write_through; int tcount; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); tcount = IVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv3); @@ -2059,17 +2022,17 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s CVAL(inbuf,smb_com) = SMBwritec; CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,conn,tcount,startpos, F_WRLCK)) + if (is_locked(fsp,conn,tcount,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - if (seek_file(fnum,startpos) != startpos) + if (seek_file(fsp,startpos) != startpos) DEBUG(0,("couldn't seek to %ld in writebraw\n",startpos)); if (numtowrite>0) - nwritten = write_file(fnum,data,numtowrite); + nwritten = write_file(fsp,data,numtowrite); DEBUG(3,("writebraw1 fnum=%d start=%ld num=%d wrote=%d sync=%d\n", - fnum, startpos, numtowrite, nwritten, write_through)); + fsp->fnum, startpos, numtowrite, nwritten, write_through)); if (nwritten < numtowrite) return(UNIXERROR(ERRHRD,ERRdiskfull)); @@ -2097,7 +2060,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s tcount,nwritten,numtowrite)); } - nwritten = transfer_file(Client,Files[fnum].fd_ptr->fd,numtowrite,NULL,0, + nwritten = transfer_file(Client,fsp->fd_ptr->fd,numtowrite,NULL,0, startpos+nwritten); total_written += nwritten; @@ -2112,10 +2075,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s } if (lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fnum); + sync_file(conn,fsp); DEBUG(3,("writebraw2 fnum=%d start=%ld num=%d wrote=%d\n", - fnum, startpos, numtowrite, total_written)); + fsp->fnum, startpos, numtowrite, total_written)); /* we won't return a status if write through is not selected - this follows what WfWg does */ @@ -2131,28 +2094,26 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s ****************************************************************************/ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int nwritten = -1; int outsize = 0; char *data; uint32 numtowrite,startpos; int eclass; uint32 ecode; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + 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(fnum,conn,numtowrite,startpos, F_WRLCK)) + if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,startpos); + seek_file(fsp,startpos); /* The special X/Open SMB protocol handling of zero length writes is *NOT* done for @@ -2160,15 +2121,15 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum if(numtowrite == 0) nwritten = 0; else - nwritten = write_file(fnum,data,numtowrite); + nwritten = write_file(fsp,data,numtowrite); if (lp_syncalways(SNUM(conn))) - sync_file(conn,fnum); + sync_file(conn,fsp); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); - if(!do_unlock(fnum, conn, numtowrite, startpos, &eclass, &ecode)) + if(!do_unlock(fsp, conn, numtowrite, startpos, &eclass, &ecode)) return(ERROR(eclass,ecode)); outsize = set_message(outbuf,1,0,True); @@ -2176,7 +2137,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum SSVAL(outbuf,smb_vwv0,nwritten); DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n", - fnum, numtowrite, nwritten ) ); + fsp->fnum, numtowrite, nwritten ) ); return(outsize); } @@ -2187,37 +2148,36 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum ****************************************************************************/ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize) { - int numtowrite,fnum; + int numtowrite; int nwritten = -1; int outsize = 0; int startpos; char *data; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + 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(fnum,conn,numtowrite,startpos, F_WRLCK)) + if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,startpos); + seek_file(fsp,startpos); /* X/Open SMB protocol says that if smb_vwv1 is zero then the file size should be extended or truncated to the size given in smb_vwv[2-3] */ if(numtowrite == 0) - nwritten = set_filelen(Files[fnum].fd_ptr->fd, startpos); + nwritten = set_filelen(fsp->fd_ptr->fd, startpos); else - nwritten = write_file(fnum,data,numtowrite); + nwritten = write_file(fsp,data,numtowrite); if (lp_syncalways(SNUM(conn))) - sync_file(conn,fnum); + sync_file(conn,fsp); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2232,7 +2192,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i } DEBUG(3,("write fnum=%d num=%d wrote=%d\n", - fnum, numtowrite, nwritten)); + fsp->fnum, numtowrite, nwritten)); return(outsize); } @@ -2243,7 +2203,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i ****************************************************************************/ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint32 smb_offs = IVAL(inbuf,smb_vwv3); int smb_dsize = SVAL(inbuf,smb_vwv10); int smb_doff = SVAL(inbuf,smb_vwv11); @@ -2251,16 +2211,16 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng int nwritten = -1; char *data; - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); data = smb_base(inbuf) + smb_doff; - if (is_locked(fnum,conn,smb_dsize,smb_offs, F_WRLCK)) + if (is_locked(fsp,conn,smb_dsize,smb_offs, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,smb_offs); + seek_file(fsp,smb_offs); /* X/Open SMB protocol says that, unlike SMBwrite if the length is zero then NO truncation is @@ -2269,7 +2229,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng if(smb_dsize == 0) nwritten = 0; else - nwritten = write_file(fnum,data,smb_dsize); + nwritten = write_file(fsp,data,smb_dsize); if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2284,12 +2244,12 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng } DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", - fnum, smb_dsize, nwritten)); + fsp->fnum, smb_dsize, nwritten)); - chain_fnum = fnum; + chain_fsp = fsp; if (lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fnum); + sync_file(conn,fsp); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -2300,17 +2260,14 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng ****************************************************************************/ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; uint32 startpos; int32 res= -1; int mode,umode; int outsize = 0; - files_struct *fsp; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); mode = SVAL(inbuf,smb_vwv1) & 3; startpos = IVAL(inbuf,smb_vwv2); @@ -2324,8 +2281,6 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, umode = SEEK_SET; break; } - fsp = &Files[fnum]; - res = lseek(fsp->fd_ptr->fd,startpos,umode); fsp->pos = res; @@ -2333,7 +2288,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, SIVALS(outbuf,smb_vwv0,res); DEBUG(3,("lseek fnum=%d ofs=%d mode=%d\n", - fnum, startpos, mode)); + fsp->fnum, startpos, mode)); return(outsize); } @@ -2344,28 +2299,21 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, ****************************************************************************/ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int outsize = set_message(outbuf,0,0,True); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - fnum = GETFNUM(inbuf,smb_vwv0); - - if (fnum != 0xFFFF) { - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + if (fsp) { + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); } - if (fnum == 0xFFFF) { - int i; - for (i=0;i<MAX_FNUMS;i++) { - if (OPEN_FNUM(i)) { - sync_file(conn,i); - } - } + if (!fsp) { + file_sync_all(conn); } else { - sync_file(conn,fnum); + sync_file(conn,fsp); } - DEBUG( 3, ( "flush fnum=%d\n", fnum ) ); + DEBUG(3,("flush\n")); return(outsize); } @@ -2389,7 +2337,6 @@ int reply_exit(connection_struct *conn, int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int outsize = 0; time_t mtime; int32 eclass = 0, err = 0; @@ -2402,18 +2349,16 @@ int reply_close(connection_struct *conn, return reply_pipe_close(conn, inbuf,outbuf); } - fnum = GETFNUM(inbuf,smb_vwv0); + fsp = GETFSP(inbuf,smb_vwv0); /* - * We can only use CHECK_FNUM if we know it's not a directory. + * We can only use CHECK_FSP if we know it's not a directory. */ - if(!(VALID_FNUM(fnum) && Files[fnum].open && Files[fnum].is_directory)) - CHECK_FNUM(fnum,conn); + if(!(fsp && fsp->open && fsp->is_directory)) + CHECK_FSP(fsp,conn); - fsp = &Files[fnum]; - - if(HAS_CACHED_ERROR(fnum)) { + if(HAS_CACHED_ERROR(fsp)) { eclass = fsp->wbmpx_ptr->wr_errclass; err = fsp->wbmpx_ptr->wr_error; } @@ -2423,8 +2368,8 @@ int reply_close(connection_struct *conn, * Special case - close NT SMB directory * handle. */ - DEBUG(3,("close directory fnum=%d\n", fnum)); - close_directory(fnum); + DEBUG(3,("close directory fnum=%d\n", fsp->fnum)); + close_directory(fsp); } else { /* * Close ordinary file. @@ -2435,10 +2380,10 @@ int reply_close(connection_struct *conn, set_filetime(conn, fsp->fsp_name,mtime); DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n", - fsp->fd_ptr->fd, fnum, + fsp->fd_ptr->fd, fsp->fnum, conn->num_files_open)); - close_file(fnum,True); + close_file(fsp,True); } /* We have a cached error */ @@ -2455,37 +2400,36 @@ int reply_close(connection_struct *conn, int reply_writeclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int numtowrite,fnum; + int numtowrite; int nwritten = -1; int outsize = 0; int startpos; char *data; time_t mtime; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); numtowrite = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); mtime = make_unix_date3(inbuf+smb_vwv4); data = smb_buf(inbuf) + 1; - if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK)) + if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,startpos); + seek_file(fsp,startpos); - nwritten = write_file(fnum,data,numtowrite); + nwritten = write_file(fsp,data,numtowrite); - set_filetime(conn, Files[fnum].fsp_name,mtime); + set_filetime(conn, fsp->fsp_name,mtime); - close_file(fnum,True); + close_file(fsp,True); DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n", - fnum, numtowrite, nwritten, + fsp->fnum, numtowrite, nwritten, conn->num_files_open)); if (nwritten <= 0) @@ -2504,24 +2448,22 @@ int reply_writeclose(connection_struct *conn, int reply_lock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int outsize = set_message(outbuf,0,0,True); uint32 count,offset; int eclass; uint32 ecode; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); count = IVAL(inbuf,smb_vwv1); offset = IVAL(inbuf,smb_vwv3); DEBUG(3,("lock fd=%d fnum=%d ofs=%d cnt=%d\n", - Files[fnum].fd_ptr->fd, fnum, offset, count)); + fsp->fd_ptr->fd, fsp->fnum, offset, count)); - if (!do_lock(fnum, conn, count, offset, F_WRLCK, &eclass, &ecode)) + if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) return (ERROR(eclass,ecode)); return(outsize); @@ -2533,25 +2475,23 @@ int reply_lock(connection_struct *conn, ****************************************************************************/ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int outsize = set_message(outbuf,0,0,True); uint32 count,offset; int eclass; uint32 ecode; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); count = IVAL(inbuf,smb_vwv1); offset = IVAL(inbuf,smb_vwv3); - if(!do_unlock(fnum, conn, count, offset, &eclass, &ecode)) + if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode)) return (ERROR(eclass,ecode)); DEBUG( 3, ( "unlock fd=%d fnum=%d ofs=%d cnt=%d\n", - Files[fnum].fd_ptr->fd, fnum, offset, count ) ); + fsp->fd_ptr->fd, fsp->fnum, offset, count ) ); return(outsize); } @@ -2624,7 +2564,6 @@ int reply_printopen(connection_struct *conn, { pstring fname; pstring fname2; - int fnum = -1; int outsize = 0; files_struct *fsp; @@ -2649,26 +2588,24 @@ int reply_printopen(connection_struct *conn, slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s); } - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (!fsp) return(ERROR(ERRSRV,ERRnofids)); - - fsp = &Files[fnum]; pstrcpy(fname2,(char *)mktemp(fname)); if (!check_name(fname2,conn)) { - fsp->reserved = False; + file_free(fsp); return(ERROR(ERRDOS,ERRnoaccess)); } /* Open for exclusive use, write only. */ - open_file_shared(fnum,conn,fname2, + open_file_shared(fsp,conn,fname2, (DENY_ALL<<4)|1, 0x12, unix_mode(conn,0), 0, NULL, NULL); if (!fsp->open) { - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -2676,10 +2613,10 @@ int reply_printopen(connection_struct *conn, fsp->print_file = True; outsize = set_message(outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,fnum); + SSVAL(outbuf,smb_vwv0,fsp->fnum); DEBUG(3,("openprint %s fd=%d fnum=%d\n", - fname2, fsp->fd_ptr->fd, fnum)); + fname2, fsp->fd_ptr->fd, fsp->fnum)); return(outsize); } @@ -2691,21 +2628,19 @@ int reply_printopen(connection_struct *conn, int reply_printclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; int outsize = set_message(outbuf,0,0,True); - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); if (!CAN_PRINT(conn)) return(ERROR(ERRDOS,ERRnoaccess)); DEBUG(3,("printclose fd=%d fnum=%d\n", - Files[fnum].fd_ptr->fd,fnum)); + fsp->fd_ptr->fd,fsp->fnum)); - close_file(fnum,True); + close_file(fsp,True); return(outsize); } @@ -2786,26 +2721,25 @@ int reply_printqueue(connection_struct *conn, ****************************************************************************/ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int numtowrite,fnum; + int numtowrite; int outsize = set_message(outbuf,0,0,True); char *data; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); if (!CAN_PRINT(conn)) return(ERROR(ERRDOS,ERRnoaccess)); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); numtowrite = SVAL(smb_buf(inbuf),1); data = smb_buf(inbuf) + 3; - if (write_file(fnum,data,numtowrite) != numtowrite) + if (write_file(fsp,data,numtowrite) != numtowrite) return(UNIXERROR(ERRDOS,ERRnoaccess)); - DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fnum, numtowrite ) ); + DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) ); return(outsize); } @@ -3323,7 +3257,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, int Access,action; struct stat st; int ret=0; - int fnum1,fnum2; + files_struct *fsp1,*fsp2; pstring dest; pstrcpy(dest,dest1); @@ -3339,43 +3273,43 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, if (!file_exist(src,&st)) return(False); - fnum1 = find_free_file(); - if (fnum1<0) return(False); - open_file_shared(fnum1,conn,src,(DENY_NONE<<4), + fsp1 = find_free_file(); + if (!fsp1) return(False); + open_file_shared(fsp1,conn,src,(DENY_NONE<<4), 1,0,0,&Access,&action); - if (!Files[fnum1].open) { - Files[fnum1].reserved = False; + if (!fsp1->open) { + fsp1->reserved = False; return(False); } if (!target_is_directory && count) ofun = 1; - fnum2 = find_free_file(); - if (fnum2<0) { - close_file(fnum1,False); - return(False); + fsp2 = find_free_file(); + if (!fsp2) { + close_file(fsp1,False); + return(False); } - open_file_shared(fnum2,conn,dest,(DENY_NONE<<4)|1, + open_file_shared(fsp2,conn,dest,(DENY_NONE<<4)|1, ofun,st.st_mode,0,&Access,&action); - if (!Files[fnum2].open) { - close_file(fnum1,False); - Files[fnum2].reserved = False; + if (!fsp2->open) { + close_file(fsp1,False); + fsp2->reserved = False; return(False); } if ((ofun&3) == 1) { - lseek(Files[fnum2].fd_ptr->fd,0,SEEK_END); + lseek(fsp2->fd_ptr->fd,0,SEEK_END); } if (st.st_size) - ret = transfer_file(Files[fnum1].fd_ptr->fd, - Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0); + ret = transfer_file(fsp1->fd_ptr->fd, + fsp2->fd_ptr->fd,st.st_size,NULL,0,0); - close_file(fnum1,False); - close_file(fnum2,False); + close_file(fsp1,False); + close_file(fsp2,False); return(ret == st.st_size); } @@ -3556,7 +3490,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size ****************************************************************************/ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); unsigned char locktype = CVAL(inbuf,smb_vwv3); #if 0 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1); @@ -3570,8 +3504,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, uint32 ecode=0, dummy2; int eclass=0, dummy1; - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); data = smb_buf(inbuf); @@ -3581,28 +3515,27 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) { int token; - files_struct *fsp = &Files[fnum]; uint32 dev = fsp->fd_ptr->dev; uint32 inode = fsp->fd_ptr->inode; DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n", - fnum)); + fsp->fnum)); /* * Make sure we have granted an oplock on this file. */ if(!fsp->granted_oplock) { DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \ -no oplock granted on this file.\n", fnum)); +no oplock granted on this file.\n", fsp->fnum)); return ERROR(ERRDOS,ERRlock); } /* Remove the oplock flag from the sharemode. */ lock_share_entry(fsp->conn, dev, inode, &token); - if(remove_share_oplock( fnum, token)==False) { + if(remove_share_oplock(fsp, token)==False) { DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \ dev = %x, inode = %x\n", - fnum, dev, inode)); + fsp->fnum, dev, inode)); unlock_share_entry(fsp->conn, dev, inode, token); } else { unlock_share_entry(fsp->conn, dev, inode, token); @@ -3628,7 +3561,7 @@ dev = %x, inode = %x\n", for(i = 0; i < (int)num_ulocks; i++) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - if(!do_unlock(fnum,conn,count,offset,&eclass, &ecode)) + if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode)) return ERROR(eclass,ecode); } @@ -3642,7 +3575,7 @@ dev = %x, inode = %x\n", for(i = 0; i < (int)num_locks; i++) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) #if 0 /* JRATEST - blocking lock code. */ if((ecode == ERRlock) && (lock_timeout != 0)) { @@ -3663,7 +3596,7 @@ dev = %x, inode = %x\n", for(; i >= 0; i--) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fnum,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } return ERROR(eclass,ecode); } @@ -3671,9 +3604,9 @@ dev = %x, inode = %x\n", set_message(outbuf,2,0,True); DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", - fnum, (unsigned int)locktype, num_locks, num_ulocks ) ); + fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) ); - chain_fnum = fnum; + chain_fsp = fsp; return chain_reply(inbuf,outbuf,length,bufsize); } @@ -3684,7 +3617,6 @@ dev = %x, inode = %x\n", ****************************************************************************/ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - int fnum; int nread = -1; int total_read; char *data; @@ -3693,6 +3625,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, int max_per_packet; int tcount; int pad; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); /* this function doesn't seem to work - disable by default */ if (!lp_readbmpx()) @@ -3700,11 +3633,9 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, outsize = set_message(outbuf,8,0,True); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_READ(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); + CHECK_ERROR(fsp); startpos = IVAL(inbuf,smb_vwv1); maxcount = SVAL(inbuf,smb_vwv3); @@ -3719,14 +3650,14 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, tcount = maxcount; total_read = 0; - if (is_locked(fnum,conn,maxcount,startpos, F_RDLCK)) + if (is_locked(fsp,conn,maxcount,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); do { int N = MIN(max_per_packet,tcount-total_read); - nread = read_file(fnum,data,startpos,N); + nread = read_file(fsp,data,startpos,N); if (nread <= 0) nread = 0; @@ -3755,18 +3686,17 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, ****************************************************************************/ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int numtowrite,fnum; + int numtowrite; int nwritten = -1; int outsize = 0; uint32 startpos; int tcount, write_through, smb_doff; char *data; - - fnum = GETFNUM(inbuf,smb_vwv0); + files_struct *fsp = GETFSP(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); tcount = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv3); @@ -3780,14 +3710,14 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s not an SMBwritebmpx - set this up now so we don't forget */ CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,conn,tcount,startpos,F_WRLCK)) + if (is_locked(fsp,conn,tcount,startpos,F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,startpos); - nwritten = write_file(fnum,data,numtowrite); + seek_file(fsp,startpos); + nwritten = write_file(fsp,data,numtowrite); if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fnum); + sync_file(conn,fsp); if(nwritten < numtowrite) return(UNIXERROR(ERRHRD,ERRdiskfull)); @@ -3799,8 +3729,8 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s if(tcount > nwritten) { write_bmpx_struct *wbms; - if(Files[fnum].wbmpx_ptr != NULL) - wbms = Files[fnum].wbmpx_ptr; /* Use an existing struct */ + 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) @@ -3813,7 +3743,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s wbms->wr_total_written = nwritten; wbms->wr_errclass = 0; wbms->wr_error = 0; - Files[fnum].wbmpx_ptr = wbms; + fsp->wbmpx_ptr = wbms; } /* We are returning successfully, set the message type back to @@ -3825,7 +3755,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */ DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n", - fnum, numtowrite, nwritten ) ); + fsp->fnum, numtowrite, nwritten ) ); if (write_through && tcount==nwritten) { /* we need to send both a primary and a secondary response */ @@ -3847,18 +3777,18 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s ****************************************************************************/ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int numtowrite,fnum; + int numtowrite; int nwritten = -1; int outsize = 0; int32 startpos; int tcount, write_through, smb_doff; char *data; write_bmpx_struct *wbms; - BOOL send_response = False; - - fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,conn); - CHECK_WRITE(fnum); + BOOL send_response = False; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); + + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); tcount = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -3872,7 +3802,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz /* This fd should have an auxiliary struct attached, check that it does */ - wbms = Files[fnum].wbmpx_ptr; + wbms = fsp->wbmpx_ptr; if(!wbms) return(-1); /* If write through is set we can return errors, else we must @@ -3883,18 +3813,18 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz if(wbms->wr_discard) return -1; /* Just discard the packet */ - seek_file(fnum,startpos); - nwritten = write_file(fnum,data,numtowrite); + seek_file(fsp,startpos); + nwritten = write_file(fsp,data,numtowrite); if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fnum); + sync_file(conn,fsp); if (nwritten < numtowrite) { if(write_through) { /* We are returning an error - we can delete the aux struct */ if (wbms) free((char *)wbms); - Files[fnum].wbmpx_ptr = NULL; + fsp->wbmpx_ptr = NULL; return(ERROR(ERRHRD,ERRdiskfull)); } return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull)); @@ -3912,7 +3842,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz } free((char *)wbms); - Files[fnum].wbmpx_ptr = NULL; + fsp->wbmpx_ptr = NULL; } if(send_response) @@ -3927,16 +3857,14 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz ****************************************************************************/ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; struct utimbuf unix_times; int outsize = 0; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); outsize = set_message(outbuf,0,0,True); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); /* Convert the DOS times into unix times. Ignore create time as UNIX can't set this. @@ -3954,7 +3882,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si /* Ignore request */ if( DEBUGLVL( 3 ) ) { - dbgtext( "reply_setattrE fnum=%d ", fnum); + dbgtext( "reply_setattrE fnum=%d ", fsp->fnum); dbgtext( "ignoring zero request - not setting timestamps of 0\n" ); } return(outsize); @@ -3966,11 +3894,11 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si } /* Set the date on this file */ - if(file_utime(conn, Files[fnum].fsp_name, &unix_times)) + if(file_utime(conn, fsp->fsp_name, &unix_times)) return(ERROR(ERRDOS,ERRnoaccess)); DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n", - fnum, (int)unix_times.actime, (int)unix_times.modtime ) ); + fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) ); return(outsize); } @@ -3981,23 +3909,21 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si ****************************************************************************/ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum; struct stat sbuf; int outsize = 0; int mode; + files_struct *fsp = GETFSP(inbuf,smb_vwv0); outsize = set_message(outbuf,11,0,True); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); /* Do an fstat on this file */ - if(fstat(Files[fnum].fd_ptr->fd, &sbuf)) + if(fstat(fsp->fd_ptr->fd, &sbuf)) return(UNIXERROR(ERRDOS,ERRnoaccess)); - mode = dos_mode(conn,Files[fnum].fsp_name,&sbuf); + mode = dos_mode(conn,fsp->fsp_name,&sbuf); /* Convert the times into dos times. Set create date to be last modify date as UNIX doesn't save @@ -4017,7 +3943,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si } SSVAL(outbuf,smb_vwv10, mode); - DEBUG( 3, ( "reply_getattrE fnum=%d\n", fnum)); + DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum)); return(outsize); } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index ba93ceaa16..8b656ab264 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -66,14 +66,6 @@ extern int dcelogin_atmost_once; extern DOM_SID global_machine_sid; static connection_struct Connections[MAX_CONNECTIONS]; -files_struct Files[MAX_FNUMS]; - -/* - * Indirection for file fd's. Needed as POSIX locking - * is based on file/process, not fd/process. - */ -file_fd_struct FileFd[MAX_OPEN_FILES]; -int max_file_fd_used = 0; extern int Protocol; @@ -89,8 +81,8 @@ int max_send = BUFFER_SIZE; */ int max_recv = BUFFER_SIZE; -/* a fnum to use when chaining */ -int chain_fnum = -1; +/* a fsp to use when chaining */ +files_struct *chain_fsp = NULL; /* number of open connections */ static int num_connections_open = 0; @@ -807,7 +799,7 @@ static int fd_attempt_open(char *fname, int flags, int mode) Cache a uid_t currently with this file open. This is an optimization only used when multiple sessionsetup's have been done to one smbd. ****************************************************************************/ -static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u) +void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u) { if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t)) return; @@ -844,67 +836,6 @@ static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u) return False; } -/**************************************************************************** -fd support routines - attempt to find an already open file by dev -and inode - increments the ref_count of the returned file_fd_struct *. -****************************************************************************/ -static file_fd_struct *fd_get_already_open(struct stat *sbuf) -{ - int i; - file_fd_struct *fd_ptr; - - if(sbuf == 0) - return 0; - - for(i = 0; i <= max_file_fd_used; i++) { - fd_ptr = &FileFd[i]; - if((fd_ptr->ref_count > 0) && - (((uint32)sbuf->st_dev) == fd_ptr->dev) && - (((uint32)sbuf->st_ino) == fd_ptr->inode)) { - fd_ptr->ref_count++; - DEBUG(3, - ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n", - i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count)); - return fd_ptr; - } - } - return 0; -} - -/**************************************************************************** -fd support routines - attempt to find a empty slot in the FileFd array. -Increments the ref_count of the returned entry. -****************************************************************************/ -static file_fd_struct *fd_get_new(void) -{ - extern struct current_user current_user; - int i; - file_fd_struct *fd_ptr; - - for(i = 0; i < MAX_OPEN_FILES; i++) { - fd_ptr = &FileFd[i]; - if(fd_ptr->ref_count == 0) { - fd_ptr->dev = (uint32)-1; - fd_ptr->inode = (uint32)-1; - fd_ptr->fd = -1; - fd_ptr->fd_readonly = -1; - fd_ptr->fd_writeonly = -1; - fd_ptr->real_open_flags = -1; - fd_ptr->uid_cache_count = 0; - fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid); - fd_ptr->ref_count++; - /* Increment max used counter if neccessary, cuts down - on search time when re-using */ - if(i > max_file_fd_used) - max_file_fd_used = i; - DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n", - i, fd_ptr->dev, fd_ptr->inode)); - return fd_ptr; - } - } - DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n")); - return 0; -} /**************************************************************************** fd support routines - attempt to re-open an already open fd as O_RDWR. @@ -934,8 +865,7 @@ static int fd_attempt_close(file_fd_struct *fd_ptr) { extern struct current_user current_user; - DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n", - fd_ptr - &FileFd[0], + DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n", fd_ptr->fd, fd_ptr->dev, fd_ptr->inode, fd_ptr->real_open_flags, fd_ptr->ref_count)); @@ -1034,14 +964,13 @@ static BOOL check_access_allowed_for_current_user( char *fname, int accmode ) /**************************************************************************** open a file ****************************************************************************/ -static void open_file(int fnum,connection_struct *conn, +static void open_file(files_struct *fsp,connection_struct *conn, char *fname1,int flags,int mode, struct stat *sbuf) { extern struct current_user current_user; pstring fname; struct stat statbuf; file_fd_struct *fd_ptr; - files_struct *fsp = &Files[fnum]; int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR)); fsp->open = False; @@ -1296,13 +1225,13 @@ static void open_file(int fnum,connection_struct *conn, */ if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) { DEBUG(3,("Writing postscript line\n")); - write_file(fnum,"%!\n",3); + write_file(fsp,"%!\n",3); } - DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n", + DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", *sesssetup_user ? sesssetup_user : conn->user,fname, BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), - conn->num_files_open,fnum)); + conn->num_files_open)); } @@ -1325,28 +1254,28 @@ static void open_file(int fnum,connection_struct *conn, /******************************************************************* sync a file ********************************************************************/ -void sync_file(connection_struct *conn, int fnum) +void sync_file(connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC if(lp_strict_sync(SNUM(conn))) - fsync(Files[fnum].fd_ptr->fd); + fsync(fsp->fd_ptr->fd); #endif } /**************************************************************************** run a file if it is a magic script ****************************************************************************/ -static void check_magic(int fnum,connection_struct *conn) +static void check_magic(files_struct *fsp,connection_struct *conn) { if (!*lp_magicscript(SNUM(conn))) return; - DEBUG(5,("checking magic for %s\n",Files[fnum].fsp_name)); + DEBUG(5,("checking magic for %s\n",fsp->fsp_name)); { char *p; - if (!(p = strrchr(Files[fnum].fsp_name,'/'))) - p = Files[fnum].fsp_name; + if (!(p = strrchr(fsp->fsp_name,'/'))) + p = fsp->fsp_name; else p++; @@ -1358,7 +1287,7 @@ static void check_magic(int fnum,connection_struct *conn) int ret; pstring magic_output; pstring fname; - pstrcpy(fname,Files[fnum].fsp_name); + pstrcpy(fname,fsp->fsp_name); if (*lp_magicoutput(SNUM(conn))) pstrcpy(magic_output,lp_magicoutput(SNUM(conn))); @@ -1379,7 +1308,7 @@ static void close_filestruct(files_struct *fsp) { connection_struct *conn = fsp->conn; - fsp->reserved = False; + file_free(fsp); fsp->open = False; fsp->is_directory = False; @@ -1405,69 +1334,66 @@ static void close_filestruct(files_struct *fsp) the closing of the connection. In the latter case printing and magic scripts are not run. ****************************************************************************/ -void close_file(int fnum, BOOL normal_close) +void close_file(files_struct *fsp, BOOL normal_close) { - files_struct *fs_p = &Files[fnum]; - uint32 dev = fs_p->fd_ptr->dev; - uint32 inode = fs_p->fd_ptr->inode; + uint32 dev = fsp->fd_ptr->dev; + uint32 inode = fsp->fd_ptr->inode; int token; - connection_struct *conn = fs_p->conn; + connection_struct *conn = fsp->conn; - close_filestruct(fs_p); + close_filestruct(fsp); #if USE_READ_PREDICTION - invalidate_read_prediction(fs_p->fd_ptr->fd); + invalidate_read_prediction(fsp->fd_ptr->fd); #endif if (lp_share_modes(SNUM(conn))) { lock_share_entry(conn, dev, inode, &token); - del_share_mode(token, fnum); + del_share_mode(token, fsp); } - fd_attempt_close(fs_p->fd_ptr); + fd_attempt_close(fsp->fd_ptr); if (lp_share_modes(SNUM(conn))) unlock_share_entry(conn, dev, inode, token); /* NT uses smbclose to start a print - weird */ - if (normal_close && fs_p->print_file) - print_file(conn, fs_p); + if (normal_close && fsp->print_file) + print_file(conn, fsp); /* check for magic scripts */ if (normal_close) { - check_magic(fnum,conn); + check_magic(fsp,conn); } - if(fs_p->granted_oplock == True) + if(fsp->granted_oplock == True) global_oplocks_open--; - fs_p->sent_oplock_break = False; + fsp->sent_oplock_break = False; DEBUG(2,("%s closed file %s (numopen=%d)\n", - conn->user,fs_p->fsp_name, + conn->user,fsp->fsp_name, conn->num_files_open)); - if (fs_p->fsp_name) { - string_free(&fs_p->fsp_name); + if (fsp->fsp_name) { + string_free(&fsp->fsp_name); } - /* we will catch bugs faster by zeroing this structure */ - memset(fs_p, 0, sizeof(*fs_p)); + file_free(fsp); } /**************************************************************************** Close a directory opened by an NT SMB call. ****************************************************************************/ -void close_directory(int fnum) +void close_directory(files_struct *fsp) { - files_struct *fsp = &Files[fnum]; /* TODO - walk the list of pending change notify requests and free - any pertaining to this fnum. */ + any pertaining to this fsp. */ - remove_pending_change_notify_requests_by_fid(fnum); + remove_pending_change_notify_requests_by_fid(fsp); /* * Do the code common to files and directories. @@ -1477,18 +1403,16 @@ void close_directory(int fnum) if (fsp->fsp_name) string_free(&fsp->fsp_name); - /* we will catch bugs faster by zeroing this structure */ - memset(fsp, 0, sizeof(*fsp)); + file_free(fsp); } /**************************************************************************** Open a directory from an NT SMB call. ****************************************************************************/ -int open_directory(int fnum,connection_struct *conn, +int open_directory(files_struct *fsp,connection_struct *conn, char *fname, int smb_ofun, int unixmode, int *action) { extern struct current_user current_user; - files_struct *fsp = &Files[fnum]; struct stat st; if (smb_ofun & 0x10) { @@ -1521,8 +1445,8 @@ int open_directory(int fnum,connection_struct *conn, *action = FILE_WAS_OPENED; } - DEBUG(5,("open_directory: opening directory %s, fnum = %d\n", - fname, fnum )); + DEBUG(5,("open_directory: opening directory %s\n", + fname)); /* * Setup the files_struct for it. @@ -1745,19 +1669,17 @@ free_and_exit: Helper for open_file_shared. Truncate a file after checking locking; close file if locked. **************************************************************************/ -static void truncate_unless_locked(int fnum, connection_struct *conn, int token, +static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token, BOOL *share_locked) { - files_struct *fsp = &Files[fnum]; - if (fsp->can_write){ - if (is_locked(fnum,conn,0x3FFFFFFF,0,F_WRLCK)){ + if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){ /* If share modes are in force for this connection we have the share entry locked. Unlock it before closing. */ if (*share_locked && lp_share_modes(SNUM(conn))) unlock_share_entry( conn, fsp->fd_ptr->dev, fsp->fd_ptr->inode, token); - close_file(fnum,False); + close_file(fsp,False); /* Share mode no longer locked. */ *share_locked = False; errno = EACCES; @@ -1813,10 +1735,9 @@ int check_share_mode( share_mode_entry *share, int deny_mode, char *fname, /**************************************************************************** open a file with a share mode ****************************************************************************/ -void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mode,int ofun, +void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun, int mode,int oplock_request, int *Access,int *action) { - files_struct *fs_p = &Files[fnum]; int flags=0; int flags2=0; int deny_mode = (share_mode>>4)&7; @@ -1829,8 +1750,8 @@ void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mod uint32 inode = 0; int num_share_modes = 0; - fs_p->open = False; - fs_p->fd_ptr = 0; + fsp->open = False; + fsp->fd_ptr = 0; /* this is for OS/2 EAs - try and say we don't support them */ if (strstr(fname,".+,;=[].")) @@ -1992,22 +1913,22 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n", flags,flags2,mode)); - open_file(fnum,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0); - if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) + open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0); + if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen) { flags = O_RDONLY; - open_file(fnum,conn,fname,flags,mode,file_existed ? &sbuf : 0 ); + open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 ); } - if (fs_p->open) + if (fsp->open) { int open_mode=0; if((share_locked == False) && lp_share_modes(SNUM(conn))) { /* We created the file - thus we must now lock the share entry before creating it. */ - dev = fs_p->fd_ptr->dev; - inode = fs_p->fd_ptr->inode; + dev = fsp->fd_ptr->dev; + inode = fsp->fd_ptr->inode; lock_share_entry(conn, dev, inode, &token); share_locked = True; } @@ -2025,7 +1946,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); break; } - fs_p->share_mode = (deny_mode<<4) | open_mode; + fsp->share_mode = (deny_mode<<4) | open_mode; if (Access) (*Access) = open_mode; @@ -2051,8 +1972,8 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && !IS_VETO_OPLOCK_PATH(conn,fname)) { - fs_p->granted_oplock = True; - fs_p->sent_oplock_break = False; + fsp->granted_oplock = True; + fsp->sent_oplock_break = False; global_oplocks_open++; port = oplock_port; @@ -2065,11 +1986,11 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode)); port = 0; oplock_request = 0; } - set_share_mode(token, fnum, port, oplock_request); + set_share_mode(token, fsp, port, oplock_request); } if ((flags2&O_TRUNC) && file_existed) - truncate_unless_locked(fnum,conn,token,&share_locked); + truncate_unless_locked(fsp,conn,token,&share_locked); } if (share_locked && lp_share_modes(SNUM(conn))) @@ -2079,10 +2000,9 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode)); /**************************************************************************** seek a file. Try to avoid the seek if possible ****************************************************************************/ -int seek_file(int fnum,uint32 pos) +int seek_file(files_struct *fsp,uint32 pos) { uint32 offset = 0; - files_struct *fsp = &Files[fnum]; if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; @@ -2094,10 +2014,9 @@ int seek_file(int fnum,uint32 pos) /**************************************************************************** read from a file ****************************************************************************/ -int read_file(int fnum,char *data,uint32 pos,int n) +int read_file(files_struct *fsp,char *data,uint32 pos,int n) { int ret=0,readret; - files_struct *fsp = &Files[fnum]; #if USE_READ_PREDICTION if (!fsp->can_write) @@ -2129,7 +2048,7 @@ int read_file(int fnum,char *data,uint32 pos,int n) if (n <= 0) return(ret); - if (seek_file(fnum,pos) != pos) + if (seek_file(fsp,pos) != pos) { DEBUG(3,("Failed to seek to %d\n",pos)); return(ret); @@ -2147,9 +2066,8 @@ int read_file(int fnum,char *data,uint32 pos,int n) /**************************************************************************** write to a file ****************************************************************************/ -int write_file(int fnum,char *data,int n) +int write_file(files_struct *fsp,char *data,int n) { - files_struct *fsp = &Files[fnum]; if (!fsp->can_write) { errno = EPERM; @@ -2318,16 +2236,16 @@ int find_service(char *service) /**************************************************************************** create an error packet from a cached error. ****************************************************************************/ -int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line) +int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line) { - write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr; + 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); - Files[fnum].wbmpx_ptr = NULL; + fsp->wbmpx_ptr = NULL; return error_packet(inbuf,outbuf,eclass,err,line); } @@ -2890,7 +2808,6 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) char *inbuf = NULL; char *outbuf = NULL; files_struct *fsp = NULL; - int fnum; time_t start_time; BOOL shutdown_server = False; connection_struct *saved_conn; @@ -2906,18 +2823,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) /* We need to search the file open table for the entry containing this dev and inode, and ensure we have an oplock on it. */ - for( fnum = 0; fnum < MAX_FNUMS; fnum++) - { - if(OPEN_FNUM(fnum)) - { - if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) && - (Files[fnum].open_time.tv_sec == tval->tv_sec) && - (Files[fnum].open_time.tv_usec == tval->tv_usec)) { - fsp = &Files[fnum]; - break; - } - } - } + fsp = file_find_dit(dev, inode, tval); if(fsp == NULL) { @@ -2925,7 +2831,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) if( DEBUGLVL( 0 ) ) { dbgtext( "oplock_break: cannot find open file with " ); - dbgtext( "dev = %x, inode = %x (fnum = %d) ", dev, inode, fnum ); + dbgtext( "dev = %x, inode = %x ", dev, inode); dbgtext( "allowing break to succeed.\n" ); } return True; @@ -2944,8 +2850,8 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) { if( DEBUGLVL( 0 ) ) { - dbgtext( "oplock_break: file %s (fnum = %d, ", fsp->fsp_name, fnum ); - dbgtext( "dev = %x, inode = %x) has no oplock.\n", dev, inode ); + dbgtext( "oplock_break: file %s ", fsp->fsp_name ); + dbgtext( "(dev = %x, inode = %x) has no oplock.\n", dev, inode ); dbgtext( "Allowing break to succeed regardless.\n" ); } return True; @@ -2957,8 +2863,8 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) if( DEBUGLVL( 0 ) ) { dbgtext( "oplock_break: ERROR: oplock_break already sent for " ); - dbgtext( "file %s (fnum = %d, ", fsp->fsp_name, fnum ); - dbgtext( "dev = %x, inode = %x)\n", dev, inode ); + dbgtext( "file %s ", fsp->fsp_name); + dbgtext( "(dev = %x, inode = %x)\n", dev, inode ); } /* We have to fail the open here as we cannot send another oplock break on @@ -3000,7 +2906,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) SSVAL(outbuf,smb_uid,0); SSVAL(outbuf,smb_mid,0xFFFF); SCVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv2,fnum); + SSVAL(outbuf,smb_vwv2,fsp->fnum); SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE); /* Change this when we have level II oplocks. */ SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE); @@ -3029,7 +2935,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) GetWd(saved_dir); unbecome_user(); - while(OPEN_FNUM(fnum) && fsp->granted_oplock) + while(OPEN_FSP(fsp) && fsp->granted_oplock) { if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False) { @@ -3048,7 +2954,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) OPLOCK_BREAK_TIMEOUT ) ); DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) ); - DEBUGADD( 0, ( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode)); + DEBUGADD( 0, ( "(dev = %x, inode = %x).\n", dev, inode)); shutdown_server = True; break; } @@ -3075,7 +2981,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) dbgtext( "oplock_break: no break received from client " ); dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT ); dbgtext( "oplock_break failed for file %s ", fsp->fsp_name ); - dbgtext( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode ); + dbgtext( "(dev = %x, inode = %x).\n", dev, inode ); } shutdown_server = True; break; @@ -3118,7 +3024,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) exit_server("oplock break failure"); } - if(OPEN_FNUM(fnum)) + if(OPEN_FSP(fsp)) { /* The lockingX reply will have removed the oplock flag from the sharemode. */ @@ -3139,7 +3045,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) if( DEBUGLVL( 3 ) ) { dbgtext( "oplock_break: returning success for " ); - dbgtext( "fnum = %d, dev = %x, inode = %x.\n", fnum, dev, inode ); + dbgtext( "dev = %x, inode = %x.\n", dev, inode ); dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open ); } @@ -3791,8 +3697,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int Used as a last ditch attempt to free a space in the file table when we have run out. ****************************************************************************/ - -static BOOL attempt_close_oplocked_file(files_struct *fsp) +BOOL attempt_close_oplocked_file(files_struct *fsp) { DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name)); @@ -3810,75 +3715,6 @@ static BOOL attempt_close_oplocked_file(files_struct *fsp) return False; } -/**************************************************************************** - find first available file slot -****************************************************************************/ -int find_free_file(void ) -{ - int i; - static int first_file; - - /* we want to give out file handles differently on each new - connection because of a common bug in MS clients where they try to - reuse a file descriptor from an earlier smb connection. This code - increases the chance that the errant client will get an error rather - than causing corruption */ - if (first_file == 0) { - first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS; - if (first_file == 0) first_file = 1; - } - - if (first_file >= MAX_FNUMS) - first_file = 1; - - for (i=first_file;i<MAX_FNUMS;i++) - if (!Files[i].open && !Files[i].reserved) { - memset(&Files[i], 0, sizeof(Files[i])); - first_file = i+1; - Files[i].reserved = True; - return(i); - } - - /* returning a file handle of 0 is a bad idea - so we start at 1 */ - for (i=1;i<first_file;i++) - if (!Files[i].open && !Files[i].reserved) { - memset(&Files[i], 0, sizeof(Files[i])); - first_file = i+1; - Files[i].reserved = True; - return(i); - } - - /* - * Before we give up, go through the open files - * and see if there are any files opened with a - * batch oplock. If so break the oplock and then - * re-use that entry (if it becomes closed). - * This may help as NT/95 clients tend to keep - * files batch oplocked for quite a long time - * after they have finished with them. - */ - for (i=first_file;i<MAX_FNUMS;i++) { - if(attempt_close_oplocked_file( &Files[i])) { - memset(&Files[i], 0, sizeof(Files[i])); - first_file = i+1; - Files[i].reserved = True; - return(i); - } - } - - for (i=1;i<MAX_FNUMS;i++) { - if(attempt_close_oplocked_file( &Files[i])) { - memset(&Files[i], 0, sizeof(Files[i])); - first_file = i+1; - Files[i].reserved = True; - return(i); - } - } - - DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); - return(-1); -} - /**************************************************************************** reply for the core protocol @@ -4267,23 +4103,6 @@ static int reply_negprot(connection_struct *conn, /**************************************************************************** -close all open files for a connection -****************************************************************************/ -static void close_open_files(connection_struct *conn) -{ - int i; - for (i=0;i<MAX_FNUMS;i++) - if (Files[i].conn == conn && Files[i].open) { - if(Files[i].is_directory) - close_directory(i); - else - close_file(i,False); - } -} - - - -/**************************************************************************** close a cnum ****************************************************************************/ void close_cnum(connection_struct *conn, uint16 vuid) @@ -4309,7 +4128,7 @@ void close_cnum(connection_struct *conn, uint16 vuid) if (lp_status(SNUM(conn))) yield_connection(conn,"STATUS.",MAXSTATUS); - close_open_files(conn); + file_close_conn(conn); dptr_closecnum(conn); /* execute any "postexec = " line */ @@ -4702,7 +4521,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize } /* load service specific parameters */ - if (OPEN_CNUM(conn) && + if (OPEN_CONN(conn) && !become_service(conn,(flags & AS_USER)?True:False)) { return(ERROR(ERRSRV,ERRaccess)); } @@ -4881,7 +4700,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) smb_last_time = time(NULL); chain_size = 0; - chain_fnum = -1; + chain_fsp = NULL; reset_chain_pnum(); if (msg_type != 0) @@ -5135,23 +4954,7 @@ static void init_structs(void ) string_init(&Connections[i].origpath,""); } - for (i=0;i<MAX_FNUMS;i++) - { - Files[i].open = False; - string_init(&Files[i].fsp_name,""); - } - - for (i=0;i<MAX_OPEN_FILES;i++) - { - file_fd_struct *fd_ptr = &FileFd[i]; - fd_ptr->ref_count = 0; - fd_ptr->dev = (int32)-1; - fd_ptr->inode = (int32)-1; - fd_ptr->fd = -1; - fd_ptr->fd_readonly = -1; - fd_ptr->fd_writeonly = -1; - fd_ptr->real_open_flags = -1; - } + file_init(); /* for RPC pipes */ init_rpc_pipe_hnd(); @@ -5297,25 +5100,6 @@ static void usage(char *pname) DEBUG( 1, ( "smbd version %s started.\n", VERSION ) ); DEBUGADD( 1, ( "Copyright Andrew Tridgell 1992-1997\n" ) ); -#ifdef HAVE_GETRLIMIT -#ifdef RLIMIT_NOFILE - { - struct rlimit rlp; - getrlimit(RLIMIT_NOFILE, &rlp); - /* - * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the - * extra fd we need to read directories, as well as the log files - * and standard handles etc. - */ - rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10; - setrlimit(RLIMIT_NOFILE, &rlp); - getrlimit(RLIMIT_NOFILE, &rlp); - DEBUG(3,("Maximum number of open files per session is %d\n",(int)rlp.rlim_cur)); - } -#endif -#endif - - DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 992d8cd616..67db3aeb2a 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -26,13 +26,13 @@ extern int DEBUGLEVEL; extern int Protocol; -extern files_struct Files[]; extern BOOL case_sensitive; extern int Client; extern int oplock_sock; extern int smb_read_error; extern fstring local_machine; extern int global_oplock_break; +extern files_struct *chain_fsp; /**************************************************************************** Send the required number of replies back. @@ -200,7 +200,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int16 namelen = strlen(pname)+1; pstring fname; - int fnum = -1; int unixmode; int size=0,fmode=0,mtime=0,rmode; int32 inode = 0; @@ -218,12 +217,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, unix_convert(fname,conn,0,&bad_path); - fnum = find_free_file(); - if (fnum < 0) + fsp = find_free_file(); + if (!fsp) return(ERROR(ERRSRV,ERRnofids)); - fsp = &Files[fnum]; - if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) @@ -231,13 +228,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } unixmode = unix_mode(conn,open_attr | aARCH); - open_file_shared(fnum,conn,fname,open_mode,open_ofun,unixmode, + open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode, oplock_request, &rmode,&smb_action); if (!fsp->open) @@ -247,12 +244,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - fsp->reserved = False; + file_free(fsp); return(UNIXERROR(ERRDOS,ERRnoaccess)); } if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -261,7 +258,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, mtime = sbuf.st_mtime; inode = sbuf.st_ino; if (fmode & aDIR) { - close_file(fnum,False); + close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -271,7 +268,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, return(ERROR(ERRDOS,ERRnomem)); bzero(params,28); - SSVAL(params,0,fnum); + SSVAL(params,0,fsp->fnum); SSVAL(params,2,fmode); put_dos_date2(params,4, mtime); SIVAL(params,8, size); @@ -1212,18 +1209,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn, BOOL bad_path = False; if (tran_call == TRANSACT2_QFILEINFO) { - int16 fnum = SVALS(params,0); + files_struct *fsp = GETFSP(params,0); info_level = SVAL(params,2); - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); - fname = Files[fnum].fsp_name; - if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno))); + fname = fsp->fsp_name; + if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } - pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR); + pos = lseek(fsp->fd_ptr->fd,0,SEEK_CUR); } else { /* qpathinfo */ info_level = SVAL(params,0); @@ -1437,14 +1434,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn, return(ERROR(ERRSRV,ERRaccess)); if (tran_call == TRANSACT2_SETFILEINFO) { - int16 fnum = SVALS(params,0); + files_struct *fsp = GETFSP(params,0); info_level = SVAL(params,2); - CHECK_FNUM(fnum,conn); - CHECK_ERROR(fnum); + CHECK_FSP(fsp,conn); + CHECK_ERROR(fsp); - fname = Files[fnum].fsp_name; - fd = Files[fnum].fd_ptr->fd; + fname = fsp->fsp_name; + fd = fsp->fd_ptr->fd; if(fstat(fd,&st)!=0) { DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno))); diff --git a/source3/utils/status.c b/source3/utils/status.c index 848f87623e..737700639b 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -61,7 +61,6 @@ int locks_only = 0; /* Added by RJS */ /* we need these because we link to locking*.o */ void become_root(BOOL save_dir) {} void unbecome_root(BOOL restore_dir) {} -files_struct Files[MAX_OPEN_FILES]; /* added by OH */ diff --git a/source3/web/swat.c b/source3/web/swat.c index 7c7a2ef205..3a56c82229 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -36,7 +36,6 @@ static pstring servicesf = CONFIGFILE; void unbecome_root(BOOL restore_dir) {} /* We need this because we link to password.o */ BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override) {return False;} -files_struct Files[MAX_OPEN_FILES]; static int enum_index(int value, struct enum_list *enumlist) { |