From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/smbd/server.c | 1501 ++++++++++++++++++++++++------------------------- 1 file changed, 726 insertions(+), 775 deletions(-) (limited to 'source3/smbd/server.c') diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 143b45e9ef..9c7bafd9dd 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -65,7 +65,7 @@ extern int dcelogin_atmost_once; */ extern DOM_SID global_machine_sid; -connection_struct Connections[MAX_CONNECTIONS]; +static connection_struct Connections[MAX_CONNECTIONS]; files_struct Files[MAX_FNUMS]; /* @@ -116,8 +116,6 @@ extern int extra_time_offset; extern pstring myhostname; -static int find_free_connection(int hash); - /* for readability... */ #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0) #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0) @@ -156,7 +154,7 @@ void killkids(void) Then apply create mask, then add force bits. ****************************************************************************/ -mode_t unix_mode(int cnum,int dosmode) +mode_t unix_mode(connection_struct *conn,int dosmode) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); @@ -168,23 +166,23 @@ mode_t unix_mode(int cnum,int dosmode) can always create a file in a read-only directory. */ result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR); /* Apply directory mask */ - result &= lp_dir_mode(SNUM(cnum)); + result &= lp_dir_mode(SNUM(conn)); /* Add in force bits */ - result |= lp_force_dir_mode(SNUM(cnum)); + result |= lp_force_dir_mode(SNUM(conn)); } else { - if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode)) + if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) result |= S_IXUSR; - if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode)) + if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) result |= S_IXGRP; - if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode)) + if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) result |= S_IXOTH; /* Apply mode mask */ - result &= lp_create_mode(SNUM(cnum)); + result &= lp_create_mode(SNUM(conn)); /* Add in force bits */ - result |= lp_force_create_mode(SNUM(cnum)); + result |= lp_force_create_mode(SNUM(conn)); } return(result); } @@ -193,16 +191,16 @@ mode_t unix_mode(int cnum,int dosmode) /**************************************************************************** change a unix mode to a dos mode ****************************************************************************/ -int dos_mode(int cnum,char *path,struct stat *sbuf) +int dos_mode(connection_struct *conn,char *path,struct stat *sbuf) { int result = 0; extern struct current_user current_user; - DEBUG(8,("dos_mode: %d %s\n", cnum, path)); + DEBUG(8,("dos_mode: %s\n", path)); - if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) { + if (CAN_WRITE(conn) && !lp_alternate_permissions(SNUM(conn))) { if (!((sbuf->st_mode & S_IWOTH) || - Connections[cnum].admin_user || + conn->admin_user || ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) || ((sbuf->st_mode & S_IWGRP) && in_group(sbuf->st_gid,current_user.gid, @@ -213,13 +211,13 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) result |= aRONLY; } - if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0)) + if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; - if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0)) + if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) result |= aSYSTEM; - if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0)) + if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) result |= aHIDDEN; if (S_ISDIR(sbuf->st_mode)) @@ -233,7 +231,7 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) #endif /* hide files with a name starting with a . */ - if (lp_hide_dot_files(SNUM(cnum))) + if (lp_hide_dot_files(SNUM(conn))) { char *p = strrchr(path,'/'); if (p) @@ -247,7 +245,7 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) /* Optimization : Only call is_hidden_path if it's not already hidden. */ - if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path)) + if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { result |= aHIDDEN; } @@ -268,7 +266,7 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) /******************************************************************* chmod a file - but preserve some bits ********************************************************************/ -int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st) +int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) { struct stat st1; int mask=0; @@ -282,9 +280,9 @@ int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st) if (S_ISDIR(st->st_mode)) dosmode |= aDIR; - if (dos_mode(cnum,fname,st) == dosmode) return(0); + if (dos_mode(conn,fname,st) == dosmode) return(0); - unixmode = unix_mode(cnum,dosmode); + unixmode = unix_mode(conn,dosmode); /* preserve the s bits */ mask |= (S_ISUID | S_ISGID); @@ -295,9 +293,9 @@ int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st) #endif /* possibly preserve the x bits */ - if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR; - if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP; - if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH; + if (!MAP_ARCHIVE(conn)) mask |= S_IXUSR; + if (!MAP_SYSTEM(conn)) mask |= S_IXGRP; + if (!MAP_HIDDEN(conn)) mask |= S_IXOTH; unixmode |= (st->st_mode & mask); @@ -323,7 +321,7 @@ Wrapper around sys_utime that possibly allows DOS semantics rather than POSIX. *******************************************************************/ -int file_utime(int cnum, char *fname, struct utimbuf *times) +int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) { extern struct current_user current_user; struct stat sb; @@ -337,7 +335,7 @@ int file_utime(int cnum, char *fname, struct utimbuf *times) if((errno != EPERM) && (errno != EACCES)) return -1; - if(!lp_dos_filetimes(SNUM(cnum))) + if(!lp_dos_filetimes(SNUM(conn))) return -1; /* We have permission (given by the Samba admin) to @@ -350,9 +348,9 @@ int file_utime(int cnum, char *fname, struct utimbuf *times) return -1; /* Check if we have write access. */ - if (CAN_WRITE(cnum)) { + if (CAN_WRITE(conn)) { if (((sb.st_mode & S_IWOTH) || - Connections[cnum].admin_user || + conn->admin_user || ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) || ((sb.st_mode & S_IWGRP) && in_group(sb.st_gid,current_user.gid, @@ -371,7 +369,7 @@ int file_utime(int cnum, char *fname, struct utimbuf *times) Change a filetime - possibly allowing DOS semantics. *******************************************************************/ -BOOL set_filetime(int cnum, char *fname, time_t mtime) +BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) { struct utimbuf times; @@ -379,7 +377,7 @@ BOOL set_filetime(int cnum, char *fname, time_t mtime) times.modtime = times.actime = mtime; - if (file_utime(cnum, fname, ×)) { + if (file_utime(conn, fname, ×)) { DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); } @@ -445,7 +443,7 @@ scan a directory to find a filename, matching without case sensitivity If the name looks like a mangled name then try via the mangling functions ****************************************************************************/ -static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) +static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache) { void *cur_dir; char *dname; @@ -458,7 +456,7 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) if (*path == 0) path = "."; - if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) { + if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) { pstrcpy(name, dname); return(True); } @@ -474,7 +472,7 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) mangled = !check_mangled_cache( name ); /* open the directory */ - if (!(cur_dir = OpenDir(cnum, path, True))) + if (!(cur_dir = OpenDir(conn, path, True))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); return(False); @@ -488,13 +486,13 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) continue; pstrcpy(name2,dname); - if (!name_map_mangle(name2,False,SNUM(cnum))) continue; + if (!name_map_mangle(name2,False,SNUM(conn))) continue; if ((mangled && mangled_equal(name,name2)) || fname_equal(name, name2)) { /* we've found the file, change it's name and return */ - if (docache) DirCacheAdd(path,name,dname,SNUM(cnum)); + if (docache) DirCacheAdd(path,name,dname,SNUM(conn)); pstrcpy(name, dname); CloseDir(cur_dir); return(True); @@ -526,7 +524,7 @@ used to pick the correct error code to return between ENOENT and ENOTDIR as Windows applications depend on ERRbadpath being returned if a component of a pathname does not exist. ****************************************************************************/ -BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path) +BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, BOOL *bad_path) { struct stat st; char *start, *end; @@ -563,7 +561,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa strnorm(name); /* check if it's a printer file */ - if (Connections[cnum].printer) + if (conn->printer) { if ((! *name) || strchr(name,'/') || !is_8_3(name, True)) { @@ -584,7 +582,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa saved_errno = errno; - DEBUG(5,("unix_convert(%s,%d)\n",name,cnum)); + DEBUG(5,("unix_convert(%s)\n",name)); /* a special case - if we don't have any mangling chars and are case sensitive then searching won't help */ @@ -637,7 +635,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa /* try to find this part of the path in the directory */ if (strchr(start,'?') || strchr(start,'*') || - !scan_directory(dirpath, start, cnum, end?True:False)) + !scan_directory(dirpath, start, conn, end?True:False)) { if (end) { @@ -701,26 +699,25 @@ This is called by every routine before it allows an operation on a filename. It does any final confirmation necessary to ensure that the filename is a valid one for the user to access. ****************************************************************************/ -BOOL check_name(char *name,int cnum) +BOOL check_name(char *name,connection_struct *conn) { BOOL ret; errno = 0; - if( IS_VETO_PATH(cnum, name)) - { - DEBUG(5,("file path name %s vetoed\n",name)); - return(0); - } + if (IS_VETO_PATH(conn, name)) { + DEBUG(5,("file path name %s vetoed\n",name)); + return(0); + } - ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum))); + ret = reduce_name(name,conn->connectpath,lp_widelinks(SNUM(conn))); /* Check if we are allowing users to follow symlinks */ /* Patch from David Clerc University of Geneva */ #ifdef S_ISLNK - if (!lp_symlinks(SNUM(cnum))) + if (!lp_symlinks(SNUM(conn))) { struct stat statbuf; if ( (sys_lstat(name,&statbuf) != -1) && @@ -1037,7 +1034,8 @@ static BOOL check_access_allowed_for_current_user( char *fname, int accmode ) /**************************************************************************** open a file ****************************************************************************/ -static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf) +static void open_file(int fnum,connection_struct *conn, + char *fname1,int flags,int mode, struct stat *sbuf) { extern struct current_user current_user; pstring fname; @@ -1065,14 +1063,13 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct * JRA. */ - if (!CAN_WRITE(cnum) && !Connections[cnum].printer) { + if (conn->read_only && !conn->printer) { /* It's a read-only share - fail if we wanted to write. */ if(accmode != O_RDONLY) { DEBUG(3,("Permission denied opening %s\n",fname)); check_for_pipe(fname); return; - } - else if(flags & O_CREAT) { + } else if(flags & O_CREAT) { /* We don't want to write - but we must make sure that O_CREAT doesn't create the file if we have write access into the directory. @@ -1083,8 +1080,9 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct /* this handles a bug in Win95 - it doesn't say to create the file when it should */ - if (Connections[cnum].printer) - flags |= O_CREAT; + if (conn->printer) { + flags |= O_CREAT; + } /* if (flags == O_WRONLY) @@ -1212,7 +1210,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct } if ((fd_ptr->fd >=0) && - Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) { + conn->printer && lp_minprintspace(SNUM(conn))) { pstring dname; int dum1,dum2,dum3; char *p; @@ -1220,7 +1218,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct p = strrchr(dname,'/'); if (p) *p = 0; if (sys_disk_free(dname,&dum1,&dum2,&dum3) < - lp_minprintspace(SNUM(cnum))) { + lp_minprintspace(SNUM(conn))) { fd_attempt_close(fd_ptr); fsp->fd_ptr = 0; if(fd_ptr->ref_count == 0) @@ -1260,7 +1258,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct fd_ptr->inode = (uint32)sbuf->st_ino; fsp->fd_ptr = fd_ptr; - Connections[cnum].num_files_open++; + conn->num_files_open++; fsp->mode = sbuf->st_mode; GetTimeOfDay(&fsp->open_time); fsp->vuid = current_user.vuid; @@ -1273,12 +1271,12 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct fsp->can_read = ((flags & O_WRONLY)==0); fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); fsp->share_mode = 0; - fsp->print_file = Connections[cnum].printer; + fsp->print_file = conn->printer; fsp->modified = False; fsp->granted_oplock = False; fsp->sent_oplock_break = False; fsp->is_directory = False; - fsp->cnum = cnum; + fsp->conn = conn; /* * Note that the file name here is the *untranslated* name * ie. it is still in the DOS codepage sent from the client. @@ -1286,7 +1284,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct * functions which will do the dos_to_unix translation before * mapping into a UNIX filename. JRA. */ - string_set(&fsp->name,fname); + string_set(&fsp->fsp_name,fname); fsp->wbmpx_ptr = NULL; /* @@ -1296,32 +1294,30 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct * This has a similar effect as CtrlD=0 in WIN.INI file. * tim@fsg.com 09/06/94 */ - if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write) - { - DEBUG(3,("Writing postscript line\n")); - write_file(fnum,"%!\n",3); + if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) { + DEBUG(3,("Writing postscript line\n")); + write_file(fnum,"%!\n",3); } - DEBUG( 2, ( "%s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n", - *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname, - BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), - Connections[cnum].num_files_open,fnum ) ); + DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n", + *sesssetup_user ? sesssetup_user : conn->user,fname, + BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), + conn->num_files_open,fnum)); } #if WITH_MMAP /* mmap it if read-only */ - if (!fsp->can_write) - { - fsp->mmap_size = file_size(fname); - fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size, - PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0); - - if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) - { - DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno))); - fsp->mmap_ptr = NULL; - } + if (!fsp->can_write) { + fsp->mmap_size = file_size(fname); + fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size, + PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0); + + if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) { + DEBUG(3,("Failed to mmap() %s - %s\n", + fname,strerror(errno))); + fsp->mmap_ptr = NULL; + } } #endif } @@ -1329,10 +1325,10 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct /******************************************************************* sync a file ********************************************************************/ -void sync_file(int cnum, int fnum) +void sync_file(connection_struct *conn, int fnum) { #ifdef HAVE_FSYNC - if(lp_strict_sync(SNUM(cnum))) + if(lp_strict_sync(SNUM(conn))) fsync(Files[fnum].fd_ptr->fd); #endif } @@ -1340,21 +1336,21 @@ void sync_file(int cnum, int fnum) /**************************************************************************** run a file if it is a magic script ****************************************************************************/ -static void check_magic(int fnum,int cnum) +static void check_magic(int fnum,connection_struct *conn) { - if (!*lp_magicscript(SNUM(cnum))) + if (!*lp_magicscript(SNUM(conn))) return; - DEBUG(5,("checking magic for %s\n",Files[fnum].name)); + DEBUG(5,("checking magic for %s\n",Files[fnum].fsp_name)); { char *p; - if (!(p = strrchr(Files[fnum].name,'/'))) - p = Files[fnum].name; + if (!(p = strrchr(Files[fnum].fsp_name,'/'))) + p = Files[fnum].fsp_name; else p++; - if (!strequal(lp_magicscript(SNUM(cnum)),p)) + if (!strequal(lp_magicscript(SNUM(conn)),p)) return; } @@ -1362,10 +1358,10 @@ static void check_magic(int fnum,int cnum) int ret; pstring magic_output; pstring fname; - pstrcpy(fname,Files[fnum].name); + pstrcpy(fname,Files[fnum].fsp_name); - if (*lp_magicoutput(SNUM(cnum))) - pstrcpy(magic_output,lp_magicoutput(SNUM(cnum))); + if (*lp_magicoutput(SNUM(conn))) + pstrcpy(magic_output,lp_magicoutput(SNUM(conn))); else slprintf(magic_output,sizeof(fname)-1, "%s.out",fname); @@ -1379,28 +1375,25 @@ static void check_magic(int fnum,int cnum) /**************************************************************************** Common code to close a file or a directory. ****************************************************************************/ - static void close_filestruct(files_struct *fsp) { - int cnum = fsp->cnum; + connection_struct *conn = fsp->conn; - fsp->reserved = False; - fsp->open = False; - fsp->is_directory = False; + fsp->reserved = False; + fsp->open = False; + fsp->is_directory = False; - Connections[cnum].num_files_open--; - if(fsp->wbmpx_ptr) - { - free((char *)fsp->wbmpx_ptr); - fsp->wbmpx_ptr = NULL; - } + conn->num_files_open--; + if(fsp->wbmpx_ptr) { + free((char *)fsp->wbmpx_ptr); + fsp->wbmpx_ptr = NULL; + } #if WITH_MMAP - if(fsp->mmap_ptr) - { - munmap(fsp->mmap_ptr,fsp->mmap_size); - fsp->mmap_ptr = NULL; - } + if(fsp->mmap_ptr) { + munmap(fsp->mmap_ptr,fsp->mmap_size); + fsp->mmap_ptr = NULL; + } #endif } @@ -1412,55 +1405,54 @@ 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) { - files_struct *fs_p = &Files[fnum]; - int cnum = fs_p->cnum; - uint32 dev = fs_p->fd_ptr->dev; - uint32 inode = fs_p->fd_ptr->inode; - int token; + files_struct *fs_p = &Files[fnum]; + uint32 dev = fs_p->fd_ptr->dev; + uint32 inode = fs_p->fd_ptr->inode; + int token; + connection_struct *conn = fs_p->conn; - close_filestruct(fs_p); + close_filestruct(fs_p); #if USE_READ_PREDICTION - invalidate_read_prediction(fs_p->fd_ptr->fd); + invalidate_read_prediction(fs_p->fd_ptr->fd); #endif - if (lp_share_modes(SNUM(cnum))) - { - lock_share_entry( cnum, dev, inode, &token); - del_share_mode(token, fnum); - } + if (lp_share_modes(SNUM(conn))) { + lock_share_entry(conn, dev, inode, &token); + del_share_mode(token, fnum); + } - fd_attempt_close(fs_p->fd_ptr); + fd_attempt_close(fs_p->fd_ptr); - if (lp_share_modes(SNUM(cnum))) - unlock_share_entry( cnum, dev, inode, token); + 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(fnum); + /* NT uses smbclose to start a print - weird */ + if (normal_close && fs_p->print_file) + print_file(conn, fs_p); - /* check for magic scripts */ - if (normal_close) - check_magic(fnum,cnum); + /* check for magic scripts */ + if (normal_close) { + check_magic(fnum,conn); + } - if(fs_p->granted_oplock == True) - global_oplocks_open--; + if(fs_p->granted_oplock == True) + global_oplocks_open--; - fs_p->sent_oplock_break = False; + fs_p->sent_oplock_break = False; - DEBUG( 2, ( "%s closed file %s (numopen=%d)\n", - Connections[cnum].user,fs_p->name, - Connections[cnum].num_files_open ) ); + DEBUG(2,("%s closed file %s (numopen=%d)\n", + conn->user,fs_p->fsp_name, + conn->num_files_open)); - if (fs_p->name) { - string_free(&fs_p->name); - } + if (fs_p->fsp_name) { + string_free(&fs_p->fsp_name); + } - /* we will catch bugs faster by zeroing this structure */ - memset(fs_p, 0, sizeof(*fs_p)); + /* we will catch bugs faster by zeroing this structure */ + memset(fs_p, 0, sizeof(*fs_p)); } /**************************************************************************** @@ -1482,8 +1474,8 @@ void close_directory(int fnum) */ close_filestruct(fsp); - if (fsp->name) - string_free(&fsp->name); + if (fsp->fsp_name) + string_free(&fsp->fsp_name); /* we will catch bugs faster by zeroing this structure */ memset(fsp, 0, sizeof(*fsp)); @@ -1492,83 +1484,81 @@ void close_directory(int fnum) /**************************************************************************** Open a directory from an NT SMB call. ****************************************************************************/ - -int open_directory(int fnum,int cnum,char *fname, int smb_ofun, int unixmode, int *action) +int open_directory(int fnum,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) { - /* - * Create the directory. - */ - - if(sys_mkdir(fname, unixmode) < 0) { - DEBUG(0,("open_directory: unable to create %s. Error was %s\n", - fname, strerror(errno) )); - return -1; - } - - *action = FILE_WAS_CREATED; - - } else { - - /* - * Check that it *was* a directory. - */ - - if(sys_stat(fname, &st) < 0) { - DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n", - fname, strerror(errno) )); - return -1; - } + extern struct current_user current_user; + files_struct *fsp = &Files[fnum]; + struct stat st; + + if (smb_ofun & 0x10) { + /* + * Create the directory. + */ + + if(sys_mkdir(fname, unixmode) < 0) { + DEBUG(0,("open_directory: unable to create %s. Error was %s\n", + fname, strerror(errno) )); + return -1; + } - if(!S_ISDIR(st.st_mode)) { - DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - return -1; - } - *action = FILE_WAS_OPENED; - } + *action = FILE_WAS_CREATED; + } else { + /* + * Check that it *was* a directory. + */ - DEBUG(5,("open_directory: opening directory %s, fnum = %d\n", - fname, fnum )); + if(sys_stat(fname, &st) < 0) { + DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n", + fname, strerror(errno) )); + return -1; + } - /* - * Setup the files_struct for it. - */ + if(!S_ISDIR(st.st_mode)) { + DEBUG(0,("open_directory: %s is not a directory !\n", fname )); + return -1; + } + *action = FILE_WAS_OPENED; + } + + DEBUG(5,("open_directory: opening directory %s, fnum = %d\n", + fname, fnum )); - fsp->fd_ptr = NULL; - Connections[cnum].num_files_open++; - fsp->mode = 0; - GetTimeOfDay(&fsp->open_time); - fsp->vuid = current_user.vuid; - fsp->size = 0; - fsp->pos = -1; - fsp->open = True; - fsp->mmap_ptr = NULL; - fsp->mmap_size = 0; - fsp->can_lock = True; - fsp->can_read = False; - fsp->can_write = False; - fsp->share_mode = 0; - fsp->print_file = False; - fsp->modified = False; - fsp->granted_oplock = False; - fsp->sent_oplock_break = False; - fsp->is_directory = True; - fsp->cnum = cnum; - /* - * Note that the file name here is the *untranslated* name - * ie. it is still in the DOS codepage sent from the client. - * All use of this filename will pass though the sys_xxxx - * functions which will do the dos_to_unix translation before - * mapping into a UNIX filename. JRA. - */ - string_set(&fsp->name,fname); - fsp->wbmpx_ptr = NULL; + /* + * Setup the files_struct for it. + */ + + fsp->fd_ptr = NULL; + conn->num_files_open++; + fsp->mode = 0; + GetTimeOfDay(&fsp->open_time); + fsp->vuid = current_user.vuid; + fsp->size = 0; + fsp->pos = -1; + fsp->open = True; + fsp->mmap_ptr = NULL; + fsp->mmap_size = 0; + fsp->can_lock = True; + fsp->can_read = False; + fsp->can_write = False; + fsp->share_mode = 0; + fsp->print_file = False; + fsp->modified = False; + fsp->granted_oplock = False; + fsp->sent_oplock_break = False; + fsp->is_directory = True; + fsp->conn = conn; + /* + * Note that the file name here is the *untranslated* name + * ie. it is still in the DOS codepage sent from the client. + * All use of this filename will pass though the sys_xxxx + * functions which will do the dos_to_unix translation before + * mapping into a UNIX filename. JRA. + */ + string_set(&fsp->fsp_name,fname); + fsp->wbmpx_ptr = NULL; - return 0; + return 0; } enum {AFAIL,AREAD,AWRITE,AALL}; @@ -1628,7 +1618,7 @@ static int access_table(int new_deny,int old_deny,int old_mode, check if the share mode on a file allows it to be deleted or unlinked return True if sharing doesn't prevent the operation ********************************************************************/ -BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op) +BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op) { int i; int ret = False; @@ -1639,7 +1629,7 @@ BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op) int pid = getpid(); uint32 dev, inode; - if(!lp_share_modes(SNUM(cnum))) + if(!lp_share_modes(SNUM(conn))) return True; if (sys_stat(fname,&sbuf) == -1) return(True); @@ -1647,8 +1637,8 @@ BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op) dev = (uint32)sbuf.st_dev; inode = (uint32)sbuf.st_ino; - lock_share_entry(cnum, dev, inode, &token); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + lock_share_entry(conn, dev, inode, &token); + num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares); /* * Check if the share modes will give us access. @@ -1707,7 +1697,7 @@ batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode)); dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode)); /* Oplock break.... */ - unlock_share_entry(cnum, dev, inode, token); + unlock_share_entry(conn, dev, inode, token); if(request_oplock_break(share_entry, dev, inode) == False) { free((char *)old_shares); @@ -1715,7 +1705,7 @@ dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode)); dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); return False; } - lock_share_entry(cnum, dev, inode, &token); + lock_share_entry(conn, dev, inode, &token); broke_oplock = True; break; } @@ -1731,7 +1721,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); if(broke_oplock) { free((char *)old_shares); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares); } } while(broke_oplock); } @@ -1744,7 +1734,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); free_and_exit: - unlock_share_entry(cnum, dev, inode, token); + unlock_share_entry(conn, dev, inode, token); if(old_shares != NULL) free((char *)old_shares); return(ret); @@ -1755,17 +1745,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, int cnum, int token, +static void truncate_unless_locked(int fnum, connection_struct *conn, int token, BOOL *share_locked) { files_struct *fsp = &Files[fnum]; if (fsp->can_write){ - if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){ + if (is_locked(fnum,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(cnum))) - unlock_share_entry( cnum, fsp->fd_ptr->dev, + 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); /* Share mode no longer locked. */ @@ -1823,7 +1813,7 @@ 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,int cnum,char *fname,int share_mode,int ofun, +void open_file_shared(int fnum,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]; @@ -1894,7 +1884,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, #endif /* O_SYNC */ if (flags != O_RDONLY && file_existed && - (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) + (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) { if (!fcbopen) { @@ -1913,7 +1903,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (deny_mode == DENY_FCB) deny_mode = DENY_DOS; - if (lp_share_modes(SNUM(cnum))) + if (lp_share_modes(SNUM(conn))) { int i; share_mode_entry *old_shares = 0; @@ -1922,9 +1912,9 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, { dev = (uint32)sbuf.st_dev; inode = (uint32)sbuf.st_ino; - lock_share_entry(cnum, dev, inode, &token); + lock_share_entry(conn, dev, inode, &token); share_locked = True; - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares); } /* @@ -1957,7 +1947,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode)); /* Oplock break.... */ - unlock_share_entry(cnum, dev, inode, token); + unlock_share_entry(conn, dev, inode, token); if(request_oplock_break(share_entry, dev, inode) == False) { free((char *)old_shares); @@ -1968,7 +1958,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); unix_ERR_code = ERRbadshare; return; } - lock_share_entry(cnum, dev, inode, &token); + lock_share_entry(conn, dev, inode, &token); broke_oplock = True; break; } @@ -1978,7 +1968,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False) { free((char *)old_shares); - unlock_share_entry(cnum, dev, inode, token); + unlock_share_entry(conn, dev, inode, token); errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadshare; @@ -1990,7 +1980,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); if(broke_oplock) { free((char *)old_shares); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares); } } while(broke_oplock); } @@ -2002,23 +1992,23 @@ 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,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0); + open_file(fnum,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0); if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) { flags = O_RDONLY; - open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 ); + open_file(fnum,conn,fname,flags,mode,file_existed ? &sbuf : 0 ); } if (fs_p->open) { int open_mode=0; - if((share_locked == False) && lp_share_modes(SNUM(cnum))) + 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; - lock_share_entry(cnum, dev, inode, &token); + lock_share_entry(conn, dev, inode, &token); share_locked = True; } @@ -2050,7 +2040,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); truncate can fail due to locking and have to close the file (which expects the share_mode_entry to be there). */ - if (lp_share_modes(SNUM(cnum))) + if (lp_share_modes(SNUM(conn))) { uint16 port = 0; /* JRA. Currently this only services Exlcusive and batch @@ -2058,8 +2048,8 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); be extended to level II oplocks (multiple reader oplocks). */ - if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && - !IS_VETO_OPLOCK_PATH(cnum,fname)) + 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; @@ -2079,11 +2069,11 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode)); } if ((flags2&O_TRUNC) && file_existed) - truncate_unless_locked(fnum,cnum,token,&share_locked); + truncate_unless_locked(fnum,conn,token,&share_locked); } - if (share_locked && lp_share_modes(SNUM(cnum))) - unlock_share_entry( cnum, dev, inode, token); + if (share_locked && lp_share_modes(SNUM(conn))) + unlock_share_entry( conn, dev, inode, token); } /**************************************************************************** @@ -2094,7 +2084,7 @@ int seek_file(int fnum,uint32 pos) uint32 offset = 0; files_struct *fsp = &Files[fnum]; - if (fsp->print_file && POSTSCRIPT(fsp->cnum)) + if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); @@ -2170,9 +2160,9 @@ int write_file(int fnum,char *data,int n) struct stat st; fsp->modified = True; if (fstat(fsp->fd_ptr->fd,&st) == 0) { - int dosmode = dos_mode(fsp->cnum,fsp->name,&st); - if (MAP_ARCHIVE(fsp->cnum) && !IS_DOS_ARCHIVE(dosmode)) { - dos_chmod(fsp->cnum,fsp->name,dosmode | aARCH,&st); + int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); + if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { + dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); } } } @@ -2184,44 +2174,42 @@ int write_file(int fnum,char *data,int n) /**************************************************************************** load parameters specific to a connection/service ****************************************************************************/ -BOOL become_service(int cnum,BOOL do_chdir) +BOOL become_service(connection_struct *conn,BOOL do_chdir) { - extern char magic_char; - static int last_cnum = -1; - int snum; + extern char magic_char; + static connection_struct *last_conn; + int snum; - if (!OPEN_CNUM(cnum)) - { - last_cnum = -1; - return(False); - } + if (!conn || !conn->open) { + last_conn = NULL; + return(False); + } - Connections[cnum].lastused = smb_last_time; + conn->lastused = smb_last_time; - snum = SNUM(cnum); + snum = SNUM(conn); - if (do_chdir && - ChDir(Connections[cnum].connectpath) != 0 && - ChDir(Connections[cnum].origpath) != 0) - { - DEBUG( 0, ( "chdir (%s) failed cnum=%d\n", - Connections[cnum].connectpath, cnum ) ); - return(False); - } + if (do_chdir && + ChDir(conn->connectpath) != 0 && + ChDir(conn->origpath) != 0) { + DEBUG(0,("chdir (%s) failed\n", + conn->connectpath)); + return(False); + } - if (cnum == last_cnum) - return(True); + if (conn == last_conn) + return(True); - last_cnum = cnum; + last_conn = conn; - case_default = lp_defaultcase(snum); - case_preserve = lp_preservecase(snum); - short_case_preserve = lp_shortpreservecase(snum); - case_mangle = lp_casemangle(snum); - case_sensitive = lp_casesensitive(snum); - magic_char = lp_magicchar(snum); - use_mangled_map = (*lp_mangled_map(snum) ? True:False); - return(True); + case_default = lp_defaultcase(snum); + case_preserve = lp_preservecase(snum); + short_case_preserve = lp_shortpreservecase(snum); + case_mangle = lp_casemangle(snum); + case_sensitive = lp_casesensitive(snum); + magic_char = lp_magicchar(snum); + use_mangled_map = (*lp_mangled_map(snum) ? True:False); + return(True); } @@ -2906,7 +2894,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) int fnum; time_t start_time; BOOL shutdown_server = False; - int saved_cnum; + connection_struct *saved_conn; int saved_vuid; pstring saved_dir; @@ -2957,7 +2945,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) { if( DEBUGLVL( 0 ) ) { - dbgtext( "oplock_break: file %s (fnum = %d, ", fsp->name, fnum ); + dbgtext( "oplock_break: file %s (fnum = %d, ", fsp->fsp_name, fnum ); dbgtext( "dev = %x, inode = %x) has no oplock.\n", dev, inode ); dbgtext( "Allowing break to succeed regardless.\n" ); } @@ -2970,7 +2958,7 @@ 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->name, fnum ); + dbgtext( "file %s (fnum = %d, ", fsp->fsp_name, fnum ); dbgtext( "dev = %x, inode = %x)\n", dev, inode ); } @@ -3008,7 +2996,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) set_message(outbuf,8,0,True); SCVAL(outbuf,smb_com,SMBlockingX); - SSVAL(outbuf,smb_tid,fsp->cnum); + SSVAL(outbuf,smb_tid,fsp->conn->cnum); SSVAL(outbuf,smb_pid,0xFFFF); SSVAL(outbuf,smb_uid,0); SSVAL(outbuf,smb_mid,0xFFFF); @@ -3037,7 +3025,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) * Save the information we need to re-become the * user, then unbecome the user whilst we're doing this. */ - saved_cnum = fsp->cnum; + saved_conn = fsp->conn; saved_vuid = current_user.vuid; GetWd(saved_dir); unbecome_user(); @@ -3060,7 +3048,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n", OPLOCK_BREAK_TIMEOUT ) ); - DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->name ) ); + DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) ); DEBUGADD( 0, ( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode)); shutdown_server = True; break; @@ -3087,7 +3075,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->name ); + dbgtext( "oplock_break failed for file %s ", fsp->fsp_name ); dbgtext( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode ); } shutdown_server = True; @@ -3099,7 +3087,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) * Go back to being the user who requested the oplock * break. */ - if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid)) + if(!become_user(saved_conn, saved_vuid)) { DEBUG( 0, ( "oplock_break: unable to re-become user!" ) ); DEBUGADD( 0, ( "Shutting down server\n" ) ); @@ -3322,7 +3310,7 @@ should be %d\n", pid, share_entry->op_port, oplock_port)); time_left -= (time(NULL) - start_time); } - DEBUG( 3, ( "%s request_oplock_break: broke oplock.\n" ) ); + DEBUG(3,("request_oplock_break: broke oplock.\n")); return True; } @@ -3365,11 +3353,13 @@ check if a snum is in use ****************************************************************************/ BOOL snum_used(int snum) { - int i; - for (i=0;iread_only = lp_readonly(snum); + /* add it as a possible user name */ + add_session_user(service); - { - pstring list; - StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1); - string_sub(list,"%S",service); + /* shall we let them in? */ + if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) { + DEBUG( 2, ( "Invalid username/password for %s\n", service ) ); + *ecode = ERRbadpw; + return NULL; + } + + conn = find_free_connection(str_checksum(service) + str_checksum(user)); + if (!conn) { + DEBUG(0,("Couldn't find free connection.\n")); + *ecode = ERRnoresource; + return NULL; + } - if (user_in_list(user,list)) - pcon->read_only = True; + /* find out some info about the user */ + pass = Get_Pwnam(user,True); - StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1); - string_sub(list,"%S",service); + if (pass == NULL) { + DEBUG(0,( "Couldn't find account %s\n",user)); + *ecode = ERRbaduid; + return NULL; + } - if (user_in_list(user,list)) - pcon->read_only = False; - } + conn->read_only = lp_readonly(snum); - /* admin user check */ + { + pstring list; + StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1); + string_sub(list,"%S",service); + + if (user_in_list(user,list)) + conn->read_only = True; + + StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1); + string_sub(list,"%S",service); + + if (user_in_list(user,list)) + conn->read_only = False; + } - /* JRA - original code denied admin user if the share was - marked read_only. Changed as I don't think this is needed, - but old code left in case there is a problem here. - */ - if (user_in_list(user,lp_admin_users(snum)) + /* admin user check */ + + /* JRA - original code denied admin user if the share was + marked read_only. Changed as I don't think this is needed, + but old code left in case there is a problem here. + */ + if (user_in_list(user,lp_admin_users(snum)) #if 0 - && !pcon->read_only) -#else - ) + && !conn->read_only #endif - { - pcon->admin_user = True; - DEBUG(0,("%s logged in as admin user (root privileges)\n",user)); - } - else - pcon->admin_user = False; + ) { + conn->admin_user = True; + DEBUG(0,("%s logged in as admin user (root privileges)\n",user)); + } else { + conn->admin_user = False; + } - pcon->force_user = force; - pcon->vuid = vuid; - pcon->uid = pass->pw_uid; - pcon->gid = pass->pw_gid; - pcon->num_files_open = 0; - pcon->lastused = time(NULL); - pcon->service = snum; - pcon->used = True; - pcon->printer = (strncmp(dev,"LPT",3) == 0); - pcon->ipc = (strncmp(dev,"IPC",3) == 0); - pcon->dirptr = NULL; - pcon->veto_list = NULL; - pcon->hide_list = NULL; - pcon->veto_oplock_list = NULL; - string_set(&pcon->dirpath,""); - string_set(&pcon->user,user); - + conn->force_user = force; + conn->vuid = vuid; + conn->uid = pass->pw_uid; + conn->gid = pass->pw_gid; + conn->num_files_open = 0; + conn->lastused = time(NULL); + conn->service = snum; + conn->used = True; + conn->printer = (strncmp(dev,"LPT",3) == 0); + conn->ipc = (strncmp(dev,"IPC",3) == 0); + conn->dirptr = NULL; + conn->veto_list = NULL; + conn->hide_list = NULL; + conn->veto_oplock_list = NULL; + string_set(&conn->dirpath,""); + string_set(&conn->user,user); + #ifdef HAVE_GETGRNAM - if (*lp_force_group(snum)) - { - struct group *gptr; - pstring gname; - - StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1); - /* default service may be a group name */ - string_sub(gname,"%S",service); - gptr = (struct group *)getgrnam(gname); - - if (gptr) - { - pcon->gid = gptr->gr_gid; - DEBUG(3,("Forced group %s\n",gname)); + if (*lp_force_group(snum)) { + struct group *gptr; + pstring gname; + + StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1); + /* default service may be a group name */ + string_sub(gname,"%S",service); + gptr = (struct group *)getgrnam(gname); + + if (gptr) { + conn->gid = gptr->gr_gid; + DEBUG(3,("Forced group %s\n",gname)); + } else { + DEBUG(1,("Couldn't find group %s\n",gname)); + } } - else - DEBUG(1,("Couldn't find group %s\n",gname)); - } #endif - - if (*lp_force_user(snum)) - { - struct passwd *pass2; - fstring fuser; - fstrcpy(fuser,lp_force_user(snum)); - pass2 = (struct passwd *)Get_Pwnam(fuser,True); - if (pass2) - { - pcon->uid = pass2->pw_uid; - string_set(&pcon->user,fuser); - fstrcpy(user,fuser); - pcon->force_user = True; - DEBUG(3,("Forced user %s\n",fuser)); + + if (*lp_force_user(snum)) { + struct passwd *pass2; + fstring fuser; + fstrcpy(fuser,lp_force_user(snum)); + pass2 = (struct passwd *)Get_Pwnam(fuser,True); + if (pass2) { + conn->uid = pass2->pw_uid; + string_set(&conn->user,fuser); + fstrcpy(user,fuser); + conn->force_user = True; + DEBUG(3,("Forced user %s\n",fuser)); + } else { + DEBUG(1,("Couldn't find user %s\n",fuser)); + } } - else - DEBUG(1,("Couldn't find user %s\n",fuser)); - } - { - pstring s; - pstrcpy(s,lp_pathname(snum)); - standard_sub(cnum,s); - string_set(&pcon->connectpath,s); - DEBUG(3,("Connect path is %s\n",s)); - } - - /* groups stuff added by ih */ - pcon->ngroups = 0; - pcon->groups = NULL; - - if (!IS_IPC(cnum)) - { - /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(pcon->user,pcon->uid,pcon->gid, - &pcon->ngroups,&pcon->groups); - - /* check number of connections */ - if (!claim_connection(cnum, - lp_servicename(SNUM(cnum)), - lp_max_connections(SNUM(cnum)),False)) { - DEBUG(1,("too many connections - rejected\n")); - return(-8); - } - - if (lp_status(SNUM(cnum))) - claim_connection(cnum,"STATUS.",MAXSTATUS,False); - } /* IS_IPC */ - - pcon->open = True; - - /* execute any "root preexec = " line */ - if (*lp_rootpreexec(SNUM(cnum))) - { - pstring cmd; - pstrcpy(cmd,lp_rootpreexec(SNUM(cnum))); - standard_sub(cnum,cmd); - DEBUG(5,("cmd=%s\n",cmd)); - smbrun(cmd,NULL,False); - } - - if (!become_user(&Connections[cnum], cnum,pcon->vuid)) - { - DEBUG(0,("Can't become connected user!\n")); - pcon->open = False; - if (!IS_IPC(cnum)) { - yield_connection(cnum, - lp_servicename(SNUM(cnum)), - lp_max_connections(SNUM(cnum))); - if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS); - } - return(-1); - } - - if (ChDir(pcon->connectpath) != 0) - { - DEBUG(0,("Can't change directory to %s (%s)\n", - pcon->connectpath,strerror(errno))); - pcon->open = False; - unbecome_user(); - if (!IS_IPC(cnum)) { - yield_connection(cnum, - lp_servicename(SNUM(cnum)), - lp_max_connections(SNUM(cnum))); - if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS); - } - return(-5); - } - - string_set(&pcon->origpath,pcon->connectpath); + pstring s; + pstrcpy(s,lp_pathname(snum)); + standard_sub(conn,s); + string_set(&conn->connectpath,s); + DEBUG(3,("Connect path is %s\n",s)); + } + /* groups stuff added by ih */ + conn->ngroups = 0; + conn->groups = NULL; + + if (!IS_IPC(conn)) { + /* Find all the groups this uid is in and + store them. Used by become_user() */ + setup_groups(conn->user,conn->uid,conn->gid, + &conn->ngroups,&conn->groups); + + /* check number of connections */ + if (!claim_connection(conn, + lp_servicename(SNUM(conn)), + lp_max_connections(SNUM(conn)), + False)) { + DEBUG(1,("too many connections - rejected\n")); + *ecode = ERRnoresource; + return NULL; + } + + if (lp_status(SNUM(conn))) + claim_connection(conn,"STATUS.", + MAXSTATUS,False); + } /* IS_IPC */ + + conn->open = True; + + /* execute any "root preexec = " line */ + if (*lp_rootpreexec(SNUM(conn))) { + pstring cmd; + pstrcpy(cmd,lp_rootpreexec(SNUM(conn))); + standard_sub(conn,cmd); + DEBUG(5,("cmd=%s\n",cmd)); + smbrun(cmd,NULL,False); + } + + if (!become_user(conn, conn->vuid)) { + DEBUG(0,("Can't become connected user!\n")); + conn->open = False; + if (!IS_IPC(conn)) { + yield_connection(conn, + lp_servicename(SNUM(conn)), + lp_max_connections(SNUM(conn))); + if (lp_status(SNUM(conn))) { + yield_connection(conn,"STATUS.",MAXSTATUS); + } + } + *ecode = ERRbadpw; + return NULL; + } + + if (ChDir(conn->connectpath) != 0) { + DEBUG(0,("Can't change directory to %s (%s)\n", + conn->connectpath,strerror(errno))); + conn->open = False; + unbecome_user(); + if (!IS_IPC(conn)) { + yield_connection(conn, + lp_servicename(SNUM(conn)), + lp_max_connections(SNUM(conn))); + if (lp_status(SNUM(conn))) + yield_connection(conn,"STATUS.",MAXSTATUS); + } + *ecode = ERRinvnetname; + return NULL; + } + + string_set(&conn->origpath,conn->connectpath); + #if SOFTLINK_OPTIMISATION - /* resolve any soft links early */ - { - pstring s; - pstrcpy(s,pcon->connectpath); - GetWd(s); - string_set(&pcon->connectpath,s); - ChDir(pcon->connectpath); - } + /* resolve any soft links early */ + { + pstring s; + pstrcpy(s,conn->connectpath); + GetWd(s); + string_set(&conn->connectpath,s); + ChDir(conn->connectpath); + } #endif - - num_connections_open++; - add_session_user(user); - - /* execute any "preexec = " line */ - if (*lp_preexec(SNUM(cnum))) - { - pstring cmd; - pstrcpy(cmd,lp_preexec(SNUM(cnum))); - standard_sub(cnum,cmd); - smbrun(cmd,NULL,False); - } - - /* we've finished with the sensitive stuff */ - unbecome_user(); - - /* Add veto/hide lists */ - if (!IS_IPC(cnum) && !IS_PRINT(cnum)) - { - set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum))); - set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum))); - set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum))); - } - - if( DEBUGLVL( IS_IPC(cnum) ? 3 : 1 ) ) - { - extern int Client; - - dbgtext( "%s (%s) ", remote_machine, client_addr(Client) ); - dbgtext( "connect to service %s ", lp_servicename(SNUM(cnum)) ); - dbgtext( "as user %s ", user ); - dbgtext( "(uid=%d, gid=%d) ", pcon->uid, pcon->gid ); - dbgtext( "(pid %d)\n", (int)getpid() ); - } - - return(cnum); + + num_connections_open++; + add_session_user(user); + + /* execute any "preexec = " line */ + if (*lp_preexec(SNUM(conn))) { + pstring cmd; + pstrcpy(cmd,lp_preexec(SNUM(conn))); + standard_sub(conn,cmd); + smbrun(cmd,NULL,False); + } + + /* we've finished with the sensitive stuff */ + unbecome_user(); + + /* Add veto/hide lists */ + if (!IS_IPC(conn) && !IS_PRINT(conn)) { + set_namearray( &conn->veto_list, lp_veto_files(SNUM(conn))); + set_namearray( &conn->hide_list, lp_hide_files(SNUM(conn))); + set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn))); + } + + if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { + extern int Client; + + dbgtext( "%s (%s) ", remote_machine, client_addr(Client) ); + dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) ); + dbgtext( "as user %s ", user ); + dbgtext( "(uid=%d, gid=%d) ", conn->uid, conn->gid ); + dbgtext( "(pid %d)\n", (int)getpid() ); + } + + return(conn); } /**************************************************************************** @@ -3783,7 +3797,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de static BOOL attempt_close_oplocked_file(files_struct *fsp) { - DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->name)); + DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name)); if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) { @@ -3867,41 +3881,6 @@ int find_free_file(void ) return(-1); } -/**************************************************************************** - find first available connection slot, starting from a random position. -The randomisation stops problems with the server dieing and clients -thinking the server is still available. -****************************************************************************/ -static int find_free_connection(int hash ) -{ - int i; - BOOL used=False; - hash = (hash % (MAX_CONNECTIONS-2))+1; - - again: - - for (i=hash+1;i!=hash;) - { - if (!Connections[i].open && Connections[i].used == used) - { - DEBUG(3,("found free connection number %d\n",i)); - return(i); - } - i++; - if (i == MAX_CONNECTIONS) - i = 1; - } - - if (!used) - { - used = !used; - goto again; - } - - DEBUG(1,("ERROR! Out of connection structures\n")); - return(-1); -} - /**************************************************************************** reply for the core protocol @@ -4183,7 +4162,9 @@ struct { /**************************************************************************** reply to a negprot ****************************************************************************/ -static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +static int reply_negprot(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, + int dum_buffsize) { int outsize = set_message(outbuf,1,0,True); int Index=0; @@ -4290,11 +4271,11 @@ static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz /**************************************************************************** close all open files for a connection ****************************************************************************/ -static void close_open_files(int cnum) +static void close_open_files(connection_struct *conn) { int i; for (i=0;iopen) { + DEBUG(0,("cnum not open\n")); + return; + } - DEBUG( IS_IPC(cnum)?3:1, ( "%s (%s) closed connection to service %s\n", - remote_machine,client_addr(Client), - lp_servicename(SNUM(cnum)) ) ); + DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n", + remote_machine,client_addr(Client), + lp_servicename(SNUM(conn)))); - yield_connection(cnum, - lp_servicename(SNUM(cnum)), - lp_max_connections(SNUM(cnum))); + yield_connection(conn, + lp_servicename(SNUM(conn)), + lp_max_connections(SNUM(conn))); - if (lp_status(SNUM(cnum))) - yield_connection(cnum,"STATUS.",MAXSTATUS); + if (lp_status(SNUM(conn))) + yield_connection(conn,"STATUS.",MAXSTATUS); - close_open_files(cnum); - dptr_closecnum(cnum); + close_open_files(conn); + dptr_closecnum(conn); - /* execute any "postexec = " line */ - if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid)) - { - pstring cmd; - pstrcpy(cmd,lp_postexec(SNUM(cnum))); - standard_sub(cnum,cmd); - smbrun(cmd,NULL,False); - unbecome_user(); - } - - unbecome_user(); - /* execute any "root postexec = " line */ - if (*lp_rootpostexec(SNUM(cnum))) - { - pstring cmd; - pstrcpy(cmd,lp_rootpostexec(SNUM(cnum))); - standard_sub(cnum,cmd); - smbrun(cmd,NULL,False); - } - - Connections[cnum].open = False; - num_connections_open--; - if (Connections[cnum].ngroups && Connections[cnum].groups) - { - free(Connections[cnum].groups); - Connections[cnum].groups = NULL; - Connections[cnum].ngroups = 0; - } + /* execute any "postexec = " line */ + if (*lp_postexec(SNUM(conn)) && + become_user(conn, vuid)) { + pstring cmd; + pstrcpy(cmd,lp_postexec(SNUM(conn))); + standard_sub(conn,cmd); + smbrun(cmd,NULL,False); + unbecome_user(); + } - free_namearray(Connections[cnum].veto_list); - free_namearray(Connections[cnum].hide_list); - free_namearray(Connections[cnum].veto_oplock_list); + unbecome_user(); + /* execute any "root postexec = " line */ + if (*lp_rootpostexec(SNUM(conn))) { + pstring cmd; + pstrcpy(cmd,lp_rootpostexec(SNUM(conn))); + standard_sub(conn,cmd); + smbrun(cmd,NULL,False); + } + + conn->open = False; + num_connections_open--; + if (conn->ngroups && conn->groups) { + free(conn->groups); + conn->groups = NULL; + conn->ngroups = 0; + } - string_set(&Connections[cnum].user,""); - string_set(&Connections[cnum].dirpath,""); - string_set(&Connections[cnum].connectpath,""); + free_namearray(conn->veto_list); + free_namearray(conn->hide_list); + free_namearray(conn->veto_oplock_list); + + string_set(&conn->user,""); + string_set(&conn->dirpath,""); + string_set(&conn->connectpath,""); } @@ -4406,6 +4384,7 @@ static BOOL dump_core(void) DEBUG(0,("Dumping core in %s\n",dname)); + abort(); return(True); } #endif @@ -4425,7 +4404,7 @@ void exit_server(char *reason) DEBUG(2,("Closing connections\n")); for (i=0;iDPTR_IDLE_TIMEOUT) - dptr_idlecnum(i); - - if (Connections[i].num_files_open > 0 || - (t-Connections[i].lastused)DPTR_IDLE_TIMEOUT) + dptr_idlecnum(&Connections[i]); + + if (Connections[i].num_files_open > 0 || + (t-Connections[i].lastused)0) - { - DEBUG( 2, ( "Closing idle connection 2.\n" ) ); - return; + if (allidle && num_connections_open>0) { + DEBUG(2,("Closing idle connection 2.\n")); + return; } if(global_machine_pasword_needs_changing) @@ -5189,7 +5140,7 @@ static void init_structs(void ) for (i=0;i