diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 2 | ||||
-rw-r--r-- | source3/smbd/connection.c | 24 | ||||
-rw-r--r-- | source3/smbd/dir.c | 128 | ||||
-rw-r--r-- | source3/smbd/groupname.c | 4 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 460 | ||||
-rw-r--r-- | source3/smbd/mangle.c | 25 | ||||
-rw-r--r-- | source3/smbd/message.c | 16 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 717 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 20 | ||||
-rw-r--r-- | source3/smbd/reply.c | 1785 | ||||
-rw-r--r-- | source3/smbd/server.c | 1501 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 609 | ||||
-rw-r--r-- | source3/smbd/uid.c | 303 |
13 files changed, 2648 insertions, 2946 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index af6746a699..6594c5f48c 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -80,7 +80,7 @@ static int findpty(char **slave) #else /* HAVE_GRANTPT */ fstrcpy( line, "/dev/ptyXX" ); - dirp = OpenDir(-1, "/dev", False); + dirp = OpenDir(NULL, "/dev", False); if (!dirp) return(-1); while ((dpname = ReadDirName(dirp)) != NULL) { if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) { diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 64b3f153cf..342a5f43bc 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -22,7 +22,6 @@ #include "includes.h" -extern connection_struct Connections[MAX_CONNECTIONS]; extern fstring remote_machine; extern int DEBUGLEVEL; @@ -30,7 +29,7 @@ extern int DEBUGLEVEL; /**************************************************************************** simple routines to do connection counting ****************************************************************************/ -BOOL yield_connection(int cnum,char *name,int max_connections) +BOOL yield_connection(connection_struct *conn,char *name,int max_connections) { struct connect_record crec; pstring fname; @@ -38,7 +37,7 @@ BOOL yield_connection(int cnum,char *name,int max_connections) int mypid = getpid(); int i; - DEBUG(3,("Yielding connection to %d %s\n",cnum,name)); + DEBUG(3,("Yielding connection to %s\n",name)); if (max_connections <= 0) return(True); @@ -73,11 +72,11 @@ BOOL yield_connection(int cnum,char *name,int max_connections) close(fd); return(False); } - if (crec.pid == mypid && crec.cnum == cnum) + if (crec.pid == mypid && crec.cnum == conn->cnum) break; } - if (crec.pid != mypid || crec.cnum != cnum) { + if (crec.pid != mypid || crec.cnum != conn->cnum) { if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) { DEBUG(0,("ERROR: can't release lock on %s\n", fname)); } @@ -113,7 +112,7 @@ BOOL yield_connection(int cnum,char *name,int max_connections) /**************************************************************************** simple routines to do connection counting ****************************************************************************/ -BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear) +BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear) { extern int Client; struct connect_record crec; @@ -192,11 +191,14 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear) bzero((void *)&crec,sizeof(crec)); crec.magic = 0x280267; crec.pid = getpid(); - crec.cnum = cnum; - if (cnum != -1) { - crec.uid = Connections[cnum].uid; - crec.gid = Connections[cnum].gid; - StrnCpy(crec.name,lp_servicename(SNUM(cnum)),sizeof(crec.name)-1); + if (conn) { + crec.cnum = conn->cnum; + crec.uid = conn->uid; + crec.gid = conn->gid; + StrnCpy(crec.name, + lp_servicename(SNUM(conn)),sizeof(crec.name)-1); + } else { + crec.cnum = -1; } crec.start = time(NULL); diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 44e0556f20..42ed68f713 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -22,7 +22,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern connection_struct Connections[]; /* This module implements directory related functions for Samba. @@ -36,18 +35,17 @@ static uint32 dircounter = 0; #define NUMDIRPTRS 256 -static struct dptr_struct -{ - int pid; - int cnum; - uint32 lastused; - void *ptr; - BOOL valid; - BOOL finished; - BOOL expect_close; - char *wcard; /* Field only used for lanman2 trans2_findfirst/next searches */ - uint16 attr; /* Field only used for lanman2 trans2_findfirst/next searches */ - char *path; +static struct dptr_struct { + int pid; + connection_struct *conn; + uint32 lastused; + void *ptr; + BOOL valid; + BOOL finished; + BOOL expect_close; + char *wcard; /* Field only used for trans2_ searches */ + uint16 attr; /* Field only used for trans2_ searches */ + char *path; } dirptrs[NUMDIRPTRS]; @@ -110,20 +108,20 @@ get the dir ptr for a dir index ****************************************************************************/ static void *dptr_get(int key,uint32 lastused) { - struct dptr_struct *dp = &dirptrs[key]; - - if (dp->valid) { - if (lastused) dp->lastused = lastused; - if (!dp->ptr) { - if (dptrs_open >= MAX_OPEN_DIRECTORIES) - dptr_idleoldest(); - DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dp->ptr = OpenDir(dp->cnum, dp->path, True))) - dptrs_open++; - } - return(dp->ptr); - } - return(NULL); + struct dptr_struct *dp = &dirptrs[key]; + + if (dp->valid) { + if (lastused) dp->lastused = lastused; + if (!dp->ptr) { + if (dptrs_open >= MAX_OPEN_DIRECTORIES) + dptr_idleoldest(); + DEBUG(4,("Reopening dptr key %d\n",key)); + if ((dp->ptr = OpenDir(dp->conn, dp->path, True))) + dptrs_open++; + } + return(dp->ptr); + } + return(NULL); } /**************************************************************************** @@ -217,22 +215,22 @@ void dptr_close(int key) /**************************************************************************** close all dptrs for a cnum ****************************************************************************/ -void dptr_closecnum(int cnum) +void dptr_closecnum(connection_struct *conn) { int i; for (i=0;i<NUMDIRPTRS;i++) - if (dirptrs[i].valid && dirptrs[i].cnum == cnum) + if (dirptrs[i].valid && dirptrs[i].conn == conn) dptr_close(i); } /**************************************************************************** idle all dptrs for a cnum ****************************************************************************/ -void dptr_idlecnum(int cnum) +void dptr_idlecnum(connection_struct *conn) { int i; for (i=0;i<NUMDIRPTRS;i++) - if (dirptrs[i].valid && dirptrs[i].cnum == cnum && dirptrs[i].ptr) + if (dirptrs[i].valid && dirptrs[i].conn == conn && dirptrs[i].ptr) dptr_idle(i); } @@ -251,37 +249,37 @@ void dptr_closepath(char *path,int pid) /**************************************************************************** start a directory listing ****************************************************************************/ -static BOOL start_dir(int cnum,char *directory) +static BOOL start_dir(connection_struct *conn,char *directory) { - DEBUG(5,("start_dir cnum=%d dir=%s\n",cnum,directory)); + DEBUG(5,("start_dir dir=%s\n",directory)); - if (!check_name(directory,cnum)) - return(False); + if (!check_name(directory,conn)) + return(False); - if (! *directory) - directory = "."; - - Connections[cnum].dirptr = OpenDir(cnum, directory, True); - if (Connections[cnum].dirptr) { - dptrs_open++; - string_set(&Connections[cnum].dirpath,directory); - return(True); - } + if (! *directory) + directory = "."; + + conn->dirptr = OpenDir(conn, directory, True); + if (conn->dirptr) { + dptrs_open++; + string_set(&conn->dirpath,directory); + return(True); + } - return(False); + return(False); } /**************************************************************************** create a new dir ptr ****************************************************************************/ -int dptr_create(int cnum,char *path, BOOL expect_close,int pid) +int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid) { int i; uint32 old; int oldi; - if (!start_dir(cnum,path)) + if (!start_dir(conn,path)) return(-2); /* Code to say use a unix error return code. */ if (dptrs_open >= MAX_OPEN_DIRECTORIES) @@ -325,11 +323,11 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) if (dirptrs[i].valid) dptr_close(i); - dirptrs[i].ptr = Connections[cnum].dirptr; + dirptrs[i].ptr = conn->dirptr; string_set(&dirptrs[i].path,path); dirptrs[i].lastused = dircounter++; dirptrs[i].finished = False; - dirptrs[i].cnum = cnum; + dirptrs[i].conn = conn; dirptrs[i].pid = pid; dirptrs[i].expect_close = expect_close; dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */ @@ -357,7 +355,7 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(False); } offset = TellDir(p); - DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,p,offset)); + DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,(unsigned)p,offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); return(True); @@ -410,7 +408,7 @@ void *dptr_fetch_lanman2(int dptr_num) /**************************************************************************** check a filetype for being valid ****************************************************************************/ -BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype) +BOOL dir_check_ftype(connection_struct *conn,int mode,struct stat *st,int dirtype) { if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) return False; @@ -420,7 +418,7 @@ BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype) /**************************************************************************** get a directory entry ****************************************************************************/ -BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend) +BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend) { char *dname; BOOL found = False; @@ -434,22 +432,22 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo *path = *pathreal = *filename = 0; - isrootdir = (strequal(Connections[cnum].dirpath,"./") || - strequal(Connections[cnum].dirpath,".") || - strequal(Connections[cnum].dirpath,"/")); + isrootdir = (strequal(conn->dirpath,"./") || + strequal(conn->dirpath,".") || + strequal(conn->dirpath,"/")); needslash = - ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/'); + ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); - if (!Connections[cnum].dirptr) + if (!conn->dirptr) return(False); while (!found) { - dname = ReadDirName(Connections[cnum].dirptr); + dname = ReadDirName(conn->dirptr); DEBUG(6,("readdir on dirptr 0x%x now at offset %d\n", - Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr))); + (unsigned)conn->dirptr,TellDir(conn->dirptr))); if (dname == NULL) return(False); @@ -459,7 +457,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || - (name_map_mangle(filename,True,SNUM(cnum)) && + (name_map_mangle(filename,True,SNUM(conn)) && mask_match(filename,mask,False,False))) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) @@ -467,7 +465,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo pstrcpy(fname,filename); *path = 0; - pstrcpy(path,Connections[cnum].dirpath); + pstrcpy(path,conn->dirpath); if(needslash) pstrcat(path,"/"); pstrcpy(pathreal,path); @@ -483,9 +481,9 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo !strequal(fname,".") && !strequal(fname,"..")) continue; - *mode = dos_mode(cnum,pathreal,&sbuf); + *mode = dos_mode(conn,pathreal,&sbuf); - if (!dir_check_ftype(cnum,*mode,&sbuf,dirtype)) { + if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) { DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); continue; } @@ -517,7 +515,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(int cnum, char *name, BOOL use_veto) +void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; @@ -538,7 +536,7 @@ void *OpenDir(int cnum, char *name, BOOL use_veto) int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if (use_veto && IS_VETO_PATH(cnum, n)) continue; + if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); diff --git a/source3/smbd/groupname.c b/source3/smbd/groupname.c index 33ce3adbfe..689fdbbbd9 100644 --- a/source3/smbd/groupname.c +++ b/source3/smbd/groupname.c @@ -197,8 +197,8 @@ Error was %s.\n", unixname, strerror(errno) )); ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep); } - DEBUG(10,("load_groupname_map: Added %d entries to groupname map.\n", - ubi_slCount( &groupname_map_list ) )); + DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n", + ubi_slCount(&groupname_map_list))); fclose(fp); } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f1467a7f8a..a72b442735 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -37,7 +37,6 @@ extern int DEBUGLEVEL; extern int max_send; extern files_struct Files[]; -extern connection_struct Connections[]; extern fstring local_machine; extern fstring global_myworkgroup; @@ -65,31 +64,32 @@ extern int Client; extern int oplock_sock; extern int smb_read_error; -static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len); -static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len); -static int CopyExpanded(int cnum, int snum, char** dst, char* src, int* n) +static int CopyExpanded(connection_struct *conn, + int snum, char** dst, char* src, int* n) { - pstring buf; - int l; + pstring buf; + int l; - if (!src || !dst || !n || !(*dst)) return(0); + if (!src || !dst || !n || !(*dst)) return(0); - StrnCpy(buf,src,sizeof(buf)/2); - string_sub(buf,"%S",lp_servicename(snum)); - standard_sub(cnum,buf); - StrnCpy(*dst,buf,*n); - l = strlen(*dst) + 1; - (*dst) += l; - (*n) -= l; - return l; + StrnCpy(buf,src,sizeof(buf)/2); + string_sub(buf,"%S",lp_servicename(snum)); + standard_sub(conn,buf); + StrnCpy(*dst,buf,*n); + l = strlen(*dst) + 1; + (*dst) += l; + (*n) -= l; + return l; } static int CopyAndAdvance(char** dst, char* src, int* n) @@ -103,24 +103,24 @@ static int CopyAndAdvance(char** dst, char* src, int* n) return l; } -static int StrlenExpanded(int cnum, int snum, char* s) +static int StrlenExpanded(connection_struct *conn, int snum, char* s) { - pstring buf; - if (!s) return(0); - StrnCpy(buf,s,sizeof(buf)/2); - string_sub(buf,"%S",lp_servicename(snum)); - standard_sub(cnum,buf); - return strlen(buf) + 1; + pstring buf; + if (!s) return(0); + StrnCpy(buf,s,sizeof(buf)/2); + string_sub(buf,"%S",lp_servicename(snum)); + standard_sub(conn,buf); + return strlen(buf) + 1; } -static char* Expand(int cnum, int snum, char* s) +static char* Expand(connection_struct *conn, int snum, char* s) { - static pstring buf; - if (!s) return(NULL); - StrnCpy(buf,s,sizeof(buf)/2); - string_sub(buf,"%S",lp_servicename(snum)); - standard_sub(cnum,buf); - return &buf[0]; + static pstring buf; + if (!s) return(NULL); + StrnCpy(buf,s,sizeof(buf)/2); + string_sub(buf,"%S",lp_servicename(snum)); + standard_sub(conn,buf); + return &buf[0]; } /******************************************************************* @@ -530,7 +530,7 @@ static int check_printq_info(struct pack_desc* desc, return True; } -static void fill_printjob_info(int cnum, int snum, int uLevel, +static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, struct pack_desc* desc, print_queue_struct* queue, int n) { @@ -577,7 +577,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, } } -static void fill_printq_info(int cnum, int snum, int uLevel, +static void fill_printq_info(connection_struct *conn, int snum, int uLevel, struct pack_desc* desc, int count, print_queue_struct* queue, print_status_struct* status) @@ -590,7 +590,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, case 3: case 4: case 5: - PACKS(desc,"z",Expand(cnum,snum,SERVICE(snum))); + PACKS(desc,"z",Expand(conn,snum,SERVICE(snum))); break; } @@ -608,7 +608,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, PACKI(desc,"W",LPSTAT_ERROR); } else if (!status || !status->message[0]) { - PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum))); + PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); PACKI(desc,"W",LPSTAT_OK); /* status */ } else { PACKS(desc,"z",status->message); @@ -625,7 +625,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, PACKS(desc,"z","WinPrint"); /* pszPrProc */ PACKS(desc,"z",""); /* pszParms */ if (!status || !status->message[0]) { - PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum))); /* pszComment */ + PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); /* pszComment */ PACKI(desc,"W",LPSTAT_OK); /* fsStatus */ } else { PACKS(desc,"z",status->message); /* pszComment */ @@ -639,7 +639,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, if (uLevel == 2 || uLevel == 4) { int i; for (i=0;i<count;i++) - fill_printjob_info(cnum,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i); + fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i); } if (uLevel==52) { @@ -788,7 +788,8 @@ int get_printerdrivernumber(int snum) return(i); } -static BOOL api_DosPrintQGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_DosPrintQGetInfo(connection_struct *conn, + uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -837,16 +838,16 @@ static BOOL api_DosPrintQGetInfo(int cnum,uint16 vuid, char *param,char *data, { count = get_printerdrivernumber(snum); DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count)); + } else { + count = get_printqueue(SNUM(conn), conn,&queue,&status); } - else - count = get_printqueue(snum,cnum,&queue,&status); if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt); desc.base = *rdata; desc.buflen = mdrcnt; if (init_package(&desc,1,count)) { desc.subcount = count; - fill_printq_info(cnum,snum,uLevel,&desc,count,queue,&status); + fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status); } *rdata_len = desc.usedlen; @@ -868,7 +869,7 @@ static BOOL api_DosPrintQGetInfo(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** view list of all print jobs on all queues ****************************************************************************/ -static BOOL api_DosPrintQEnum(int cnum, uint16 vuid, char* param, char* data, +static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data, int mdrcnt, int mprcnt, char **rdata, char** rparam, int *rdata_len, int *rparam_len) @@ -907,7 +908,7 @@ static BOOL api_DosPrintQEnum(int cnum, uint16 vuid, char* param, char* data, n = 0; for (i = 0; i < services; i++) if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) { - subcntarr[n] = get_printqueue(i,cnum,&queue[n],&status[n]); + subcntarr[n] = get_printqueue(i, conn,&queue[n],&status[n]); subcnt += subcntarr[n]; n++; } @@ -921,7 +922,7 @@ static BOOL api_DosPrintQEnum(int cnum, uint16 vuid, char* param, char* data, succnt = 0; for (i = 0; i < services; i++) if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) { - fill_printq_info(cnum,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]); + fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]); n++; if (desc.errcode == NERR_Success) succnt = n; } @@ -1180,7 +1181,7 @@ static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) view list of servers available (or possibly domains). The info is extracted from lists saved by nmbd on the local host ****************************************************************************/ -static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data, +static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data, int mdrcnt, int mprcnt, char **rdata, char **rparam, int *rdata_len, int *rparam_len) { @@ -1306,7 +1307,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data, /**************************************************************************** command 0x34 - suspected of being a "Lookup Names" stub api ****************************************************************************/ -static BOOL api_RNetGroupGetUsers(int cnum, uint16 vuid, char *param, char *data, +static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data, int mdrcnt, int mprcnt, char **rdata, char **rparam, int *rdata_len, int *rparam_len) { @@ -1360,7 +1361,7 @@ static BOOL check_share_info(int uLevel, char* id) return True; } -static int fill_share_info(int cnum, int snum, int uLevel, +static int fill_share_info(connection_struct *conn, int snum, int uLevel, char** buf, int* buflen, char** stringbuf, int* stringspace, char* baseaddr) { @@ -1382,7 +1383,7 @@ static int fill_share_info(int cnum, int snum, int uLevel, if (!buf) { len = 0; - if (uLevel > 0) len += StrlenExpanded(cnum,snum,lp_comment(snum)); + if (uLevel > 0) len += StrlenExpanded(conn,snum,lp_comment(snum)); if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1; if (buflen) *buflen = struct_len; if (stringspace) *stringspace = len; @@ -1415,7 +1416,7 @@ static int fill_share_info(int cnum, int snum, int uLevel, if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC; SSVAL(p,14,type); /* device type */ SIVAL(p,16,PTR_DIFF(p2,baseaddr)); - len += CopyExpanded(cnum,snum,&p2,lp_comment(snum),&l2); + len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2); } if (uLevel > 1) @@ -1455,7 +1456,7 @@ static int fill_share_info(int cnum, int snum, int uLevel, return len; } -static BOOL api_RNetShareGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1475,7 +1476,7 @@ static BOOL api_RNetShareGetInfo(int cnum,uint16 vuid, char *param,char *data, *rdata = REALLOC(*rdata,mdrcnt); p = *rdata; - *rdata_len = fill_share_info(cnum,snum,uLevel,&p,&mdrcnt,0,0,0); + *rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0); if (*rdata_len < 0) return False; *rparam_len = 6; @@ -1490,7 +1491,7 @@ static BOOL api_RNetShareGetInfo(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** view list of shares available ****************************************************************************/ -static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1516,7 +1517,7 @@ static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data, if (lp_browseable(i) && lp_snum_ok(i)) { total++; - data_len += fill_share_info(cnum,i,uLevel,0,&f_len,0,&s_len,0); + data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0); if (data_len <= buf_len) { counted++; @@ -1536,7 +1537,7 @@ static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data, s_len = string_len; for (i = 0; i < count;i++) if (lp_browseable(i) && lp_snum_ok(i)) - if (fill_share_info(cnum,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0) + if (fill_share_info(conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0) break; *rparam_len = 8; @@ -1557,7 +1558,7 @@ static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** get the time of day info ****************************************************************************/ -static BOOL api_NetRemoteTOD(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1606,7 +1607,7 @@ static BOOL api_NetRemoteTOD(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** set the user password ****************************************************************************/ -static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1682,7 +1683,7 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, Set the user password (SamOEM version - gets plaintext). ****************************************************************************/ -static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1760,7 +1761,7 @@ static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *dat delete a print job Form: <W> <> ****************************************************************************/ -static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1789,7 +1790,7 @@ static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, { print_queue_struct *queue=NULL; lpq_reset(snum); - count = get_printqueue(snum,cnum,&queue,NULL); + count = get_printqueue(snum,conn,&queue,NULL); for (i=0;i<count;i++) if ((queue[i].job&0xFF) == jobid) @@ -1797,13 +1798,13 @@ static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, switch (function) { case 81: /* delete */ DEBUG(3,("Deleting queue entry %d\n",queue[i].job)); - del_printqueue(cnum,snum,queue[i].job); + del_printqueue(conn,snum,queue[i].job); break; case 82: /* pause */ case 83: /* resume */ DEBUG(3,("%s queue entry %d\n", (function==82?"pausing":"resuming"),queue[i].job)); - status_printjob(cnum,snum,queue[i].job, + status_printjob(conn,snum,queue[i].job, (function==82?LPQ_PAUSED:LPQ_QUEUED)); break; } @@ -1824,7 +1825,7 @@ static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** Purge a print queue - or pause or resume it. ****************************************************************************/ -static BOOL api_WPrintQueuePurge(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1862,7 +1863,7 @@ static BOOL api_WPrintQueuePurge(int cnum,uint16 vuid, char *param,char *data, switch (function) { case 74: /* Pause queue */ case 75: /* Resume queue */ - status_printqueue(cnum,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK)); + status_printqueue(conn,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK)); DEBUG(3,("Print queue %s, queue=%s\n", (function==74?"pause":"resume"),QueueName)); break; @@ -1870,9 +1871,9 @@ static BOOL api_WPrintQueuePurge(int cnum,uint16 vuid, char *param,char *data, { print_queue_struct *queue=NULL; int i, count; - count = get_printqueue(snum,cnum,&queue,NULL); + count = get_printqueue(snum,conn,&queue,NULL); for (i = 0; i < count; i++) - del_printqueue(cnum,snum,queue[i].job); + del_printqueue(conn,snum,queue[i].job); if (queue) free(queue); DEBUG(3,("Print queue purge, queue=%s\n",QueueName)); @@ -1907,7 +1908,7 @@ static int check_printjob_info(struct pack_desc* desc, return True; } -static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, +static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -1941,7 +1942,7 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, int count; lpq_reset(snum); - count = get_printqueue(snum,cnum,&queue,NULL); + count = get_printqueue(snum,conn,&queue,NULL); for (i=0;i<count;i++) /* find job */ if ((queue[i].job&0xFF) == jobid) break; @@ -1987,16 +1988,17 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, if (Files[i].open && Files[i].print_file) { pstring wd; - int fcnum = Files[i].cnum; + connection_struct *fconn = Files[i].conn; GetWd(wd); unbecome_user(); - if (!become_user(&Connections[fcnum], fcnum,vuid) || - !become_service(fcnum,True)) + if (!become_user(fconn,vuid) || + !become_service(fconn,True)) break; - if (sys_rename(Files[i].name,name) == 0) - string_set(&Files[i].name,name); + if (sys_rename(Files[i].fsp_name,name) == 0) { + string_set(&Files[i].fsp_name,name); + } break; } @@ -2019,7 +2021,7 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, /**************************************************************************** get info about the server ****************************************************************************/ -static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2102,7 +2104,7 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data, SIVAL(p,6,0); } else { SIVAL(p,6,PTR_DIFF(p2,*rdata)); - standard_sub(cnum,comment); + standard_sub(conn,comment); StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0)); p2 = skip_string(p2,1); } @@ -2127,7 +2129,7 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** get info about the server ****************************************************************************/ -static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2364,7 +2366,7 @@ There is no auxiliary data in the response. #define AF_OP_ACCOUNTS 3 -static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2437,7 +2439,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, if (uLevel == 11) /* modelled after NTAS 3.51 reply */ { - SSVAL(p,usri11_priv,Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); + SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */ SIVALS(p,usri11_password_age,-1); /* password age */ SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */ @@ -2475,7 +2477,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, memset(p+22,' ',16); /* password */ SIVALS(p,38,-1); /* password age */ SSVAL(p,42, - Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); + conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */ pstrcpy(p2,lp_logon_path()); p2 = skip_string(p2,1); @@ -2523,7 +2525,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, /******************************************************************* get groups that a user is a member of ******************************************************************/ -static BOOL api_NetUserGetGroups(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2570,7 +2572,7 @@ static BOOL api_NetUserGetGroups(int cnum,uint16 vuid, char *param,char *data, } -static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2605,7 +2607,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, PACKS(&desc,"B21",name); /* eff. name */ PACKS(&desc,"B",""); /* pad */ PACKI(&desc,"W", - Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); + conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); PACKI(&desc,"D",0); /* auth flags XXX */ PACKI(&desc,"W",0); /* num logons */ PACKI(&desc,"W",0); /* bad pw count */ @@ -2628,7 +2630,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, /* JHT - By calling lp_logon_script() and standard_sub() we have */ /* made sure all macros are fully substituted and available */ logon_script = lp_logon_script(); - standard_sub( cnum, logon_script ); + standard_sub( conn, logon_script ); PACKS(&desc,"z", logon_script); /* script path */ /* End of JHT mods */ @@ -2650,7 +2652,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** api_WAccessGetUserPerms ****************************************************************************/ -static BOOL api_WAccessGetUserPerms(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2678,7 +2680,7 @@ static BOOL api_WAccessGetUserPerms(int cnum,uint16 vuid, char *param,char *data /**************************************************************************** api_WPrintJobEnumerate ****************************************************************************/ -static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2711,7 +2713,7 @@ static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data, if (snum < 0 || !VALID_SNUM(snum)) return(False); - count = get_printqueue(snum,cnum,&queue,&status); + count = get_printqueue(snum,conn,&queue,&status); for (i = 0; i < count; i++) { if ((queue[i].job & 0xFF) == job) break; } @@ -2721,7 +2723,7 @@ static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data, if (init_package(&desc,1,0)) { if (i < count) { - fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i); + fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i); *rdata_len = desc.usedlen; } else { @@ -2742,7 +2744,7 @@ static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data, return(True); } -static BOOL api_WPrintJobEnumerate(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2784,7 +2786,7 @@ static BOOL api_WPrintJobEnumerate(int cnum,uint16 vuid, char *param,char *data, if (snum < 0 || !VALID_SNUM(snum)) return(False); - count = get_printqueue(snum,cnum,&queue,&status); + count = get_printqueue(snum,conn,&queue,&status); if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt); desc.base = *rdata; desc.buflen = mdrcnt; @@ -2792,7 +2794,7 @@ static BOOL api_WPrintJobEnumerate(int cnum,uint16 vuid, char *param,char *data, if (init_package(&desc,count,0)) { succnt = 0; for (i = 0; i < count; i++) { - fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i); + fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i); if (desc.errcode == NERR_Success) succnt = i+1; } } @@ -2827,7 +2829,7 @@ static int check_printdest_info(struct pack_desc* desc, return True; } -static void fill_printdest_info(int cnum, int snum, int uLevel, +static void fill_printdest_info(connection_struct *conn, int snum, int uLevel, struct pack_desc* desc) { char buf[100]; @@ -2860,7 +2862,7 @@ static void fill_printdest_info(int cnum, int snum, int uLevel, } } -static BOOL api_WPrintDestGetInfo(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2904,7 +2906,7 @@ static BOOL api_WPrintDestGetInfo(int cnum,uint16 vuid, char *param,char *data, desc.base = *rdata; desc.buflen = mdrcnt; if (init_package(&desc,1,0)) { - fill_printdest_info(cnum,snum,uLevel,&desc); + fill_printdest_info(conn,snum,uLevel,&desc); } *rdata_len = desc.usedlen; } @@ -2919,7 +2921,7 @@ static BOOL api_WPrintDestGetInfo(int cnum,uint16 vuid, char *param,char *data, return(True); } -static BOOL api_WPrintDestEnum(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -2957,7 +2959,7 @@ static BOOL api_WPrintDestEnum(int cnum,uint16 vuid, char *param,char *data, n = 0; for (i = 0; i < services; i++) { if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) { - fill_printdest_info(cnum,i,uLevel,&desc); + fill_printdest_info(conn,i,uLevel,&desc); n++; if (desc.errcode == NERR_Success) succnt = n; } @@ -2977,7 +2979,7 @@ static BOOL api_WPrintDestEnum(int cnum,uint16 vuid, char *param,char *data, return(True); } -static BOOL api_WPrintDriverEnum(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -3022,7 +3024,7 @@ static BOOL api_WPrintDriverEnum(int cnum,uint16 vuid, char *param,char *data, return(True); } -static BOOL api_WPrintQProcEnum(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -3068,7 +3070,7 @@ static BOOL api_WPrintQProcEnum(int cnum,uint16 vuid, char *param,char *data, return(True); } -static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -3366,7 +3368,7 @@ static BOOL api_no_reply(char *outbuf, int max_rdata_len) /**************************************************************************** handle remote api calls delivered to a named pipe already opened. ****************************************************************************/ -static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, +static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf, uint16 *setup,char *data,char *params, int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt) { @@ -3407,8 +3409,6 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, { DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum)); - DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n", - tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid)); /* record maximum data length that can be transmitted in an SMBtrans */ p->file_offset = mdrcnt; @@ -3447,7 +3447,7 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, /**************************************************************************** the buffer was too small ****************************************************************************/ -static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -3468,7 +3468,7 @@ static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data, /**************************************************************************** the request is not supported ****************************************************************************/ -static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data, +static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len) @@ -3493,7 +3493,8 @@ struct { char *name; int id; - BOOL (*fn)(int,uint16,char *,char *,int,int,char **,char **,int *,int *); + BOOL (*fn)(connection_struct *,uint16,char *,char *, + int,int,char **,char **,int *,int *); int flags; } api_commands[] = { {"RNetShareEnum", 0, api_RNetShareEnum,0}, @@ -3531,7 +3532,7 @@ struct /**************************************************************************** handle remote api calls ****************************************************************************/ -static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params, +static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params, int tdscnt,int tpscnt,int mdrcnt,int mprcnt) { int api_command = SVAL(params,0); @@ -3558,21 +3559,21 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params, rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024); rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024); - reply = api_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt, + reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt, &rdata,&rparam,&rdata_len,&rparam_len); if (rdata_len > mdrcnt || rparam_len > mprcnt) { - reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt, + reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt, &rdata,&rparam,&rdata_len,&rparam_len); } /* if we get False back then it's actually unsupported */ if (!reply) - api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt, + api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt, &rdata,&rparam,&rdata_len,&rparam_len); @@ -3597,7 +3598,7 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params, /**************************************************************************** handle named pipe commands ****************************************************************************/ -static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name, +static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *name, uint16 *setup,char *data,char *params, int suwcnt,int tdscnt,int tpscnt, int msrcnt,int mdrcnt,int mprcnt) @@ -3606,12 +3607,12 @@ static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name, if (strequal(name,"LANMAN")) { - return api_reply(cnum,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt); + return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt); } if (strlen(name) < 1) { - return api_fd_reply(cnum,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); + return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); } if (setup) @@ -3626,141 +3627,132 @@ static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name, /**************************************************************************** reply to a SMBtrans ****************************************************************************/ -int reply_trans(char *inbuf,char *outbuf, int size, int bufsize) -{ - fstring name; - - char *data=NULL,*params=NULL; - uint16 *setup=NULL; - - int outsize = 0; - int cnum = SVAL(inbuf,smb_tid); - uint16 vuid = SVAL(inbuf,smb_uid); - - int tpscnt = SVAL(inbuf,smb_vwv0); - int tdscnt = SVAL(inbuf,smb_vwv1); - int mprcnt = SVAL(inbuf,smb_vwv2); - int mdrcnt = SVAL(inbuf,smb_vwv3); - int msrcnt = CVAL(inbuf,smb_vwv4); - BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0); - BOOL one_way = BITSETW(inbuf+smb_vwv5,1); - int pscnt = SVAL(inbuf,smb_vwv9); - int psoff = SVAL(inbuf,smb_vwv10); - int dscnt = SVAL(inbuf,smb_vwv11); - int dsoff = SVAL(inbuf,smb_vwv12); - int suwcnt = CVAL(inbuf,smb_vwv13); - - bzero(name, sizeof(name)); - fstrcpy(name,smb_buf(inbuf)); - - if (dscnt > tdscnt || pscnt > tpscnt) { - exit_server("invalid trans parameters\n"); - } +int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize) +{ + fstring name; + + char *data=NULL,*params=NULL; + uint16 *setup=NULL; + int outsize = 0; + uint16 vuid = SVAL(inbuf,smb_uid); + int tpscnt = SVAL(inbuf,smb_vwv0); + int tdscnt = SVAL(inbuf,smb_vwv1); + int mprcnt = SVAL(inbuf,smb_vwv2); + int mdrcnt = SVAL(inbuf,smb_vwv3); + int msrcnt = CVAL(inbuf,smb_vwv4); + BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0); + BOOL one_way = BITSETW(inbuf+smb_vwv5,1); + int pscnt = SVAL(inbuf,smb_vwv9); + int psoff = SVAL(inbuf,smb_vwv10); + int dscnt = SVAL(inbuf,smb_vwv11); + int dsoff = SVAL(inbuf,smb_vwv12); + int suwcnt = CVAL(inbuf,smb_vwv13); + + bzero(name, sizeof(name)); + fstrcpy(name,smb_buf(inbuf)); + + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } - if (tdscnt) - { - data = (char *)malloc(tdscnt); - memcpy(data,smb_base(inbuf)+dsoff,dscnt); - } - if (tpscnt) - { - params = (char *)malloc(tpscnt); - memcpy(params,smb_base(inbuf)+psoff,pscnt); - } + if (tdscnt) { + data = (char *)malloc(tdscnt); + memcpy(data,smb_base(inbuf)+dsoff,dscnt); + } - if (suwcnt) - { - int i; - setup = (uint16 *)malloc(suwcnt*sizeof(setup[0])); - for (i=0;i<suwcnt;i++) - setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD); - } + if (tpscnt) { + params = (char *)malloc(tpscnt); + memcpy(params,smb_base(inbuf)+psoff,pscnt); + } + if (suwcnt) { + int i; + setup = (uint16 *)malloc(suwcnt*sizeof(setup[0])); + for (i=0;i<suwcnt;i++) + setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD); + } - if (pscnt < tpscnt || dscnt < tdscnt) - { - /* We need to send an interim response then receive the rest - of the parameter/data bytes */ - outsize = set_message(outbuf,0,0,True); - show_msg(outbuf); - send_smb(Client,outbuf); - } - /* receive the rest of the trans packet */ - while (pscnt < tpscnt || dscnt < tdscnt) - { - BOOL ret; - int pcnt,poff,dcnt,doff,pdisp,ddisp; - - ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT); - - if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret) { - if(ret) { - DEBUG(0,("reply_trans: Invalid secondary trans packet\n")); - } else { - DEBUG(0,("reply_trans: %s in getting secondary trans response.\n", - (smb_read_error == READ_ERROR) ? "error" : "timeout" )); - } - if (params) free(params); - if (data) free(data); - if (setup) free(setup); - return(ERROR(ERRSRV,ERRerror)); - } + if (pscnt < tpscnt || dscnt < tdscnt) { + /* We need to send an interim response then receive the rest + of the parameter/data bytes */ + outsize = set_message(outbuf,0,0,True); + show_msg(outbuf); + send_smb(Client,outbuf); + } - show_msg(inbuf); + /* receive the rest of the trans packet */ + while (pscnt < tpscnt || dscnt < tdscnt) { + BOOL ret; + int pcnt,poff,dcnt,doff,pdisp,ddisp; - tpscnt = SVAL(inbuf,smb_vwv0); - tdscnt = SVAL(inbuf,smb_vwv1); + ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT); + + if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret) { + if(ret) { + DEBUG(0,("reply_trans: Invalid secondary trans packet\n")); + } else { + DEBUG(0,("reply_trans: %s in getting secondary trans response.\n", + (smb_read_error == READ_ERROR) ? "error" : "timeout" )); + } + if (params) free(params); + if (data) free(data); + if (setup) free(setup); + return(ERROR(ERRSRV,ERRerror)); + } - pcnt = SVAL(inbuf,smb_vwv2); - poff = SVAL(inbuf,smb_vwv3); - pdisp = SVAL(inbuf,smb_vwv4); - - dcnt = SVAL(inbuf,smb_vwv5); - doff = SVAL(inbuf,smb_vwv6); - ddisp = SVAL(inbuf,smb_vwv7); + show_msg(inbuf); - pscnt += pcnt; - dscnt += dcnt; - - if (dscnt > tdscnt || pscnt > tpscnt) { - exit_server("invalid trans parameters\n"); - } - - if (pcnt) - memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt); - if (dcnt) - memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt); - } - - - DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",name,tdscnt,tpscnt,suwcnt)); - - if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0) - { - DEBUG(5,("calling named_pipe\n")); - outsize = named_pipe(cnum,vuid,outbuf,name+strlen("\\PIPE\\"),setup,data,params, - suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt); - } - else - { - DEBUG(3,("invalid pipe name\n")); - outsize = 0; - } - - - if (data) free(data); - if (params) free(params); - if (setup) free(setup); - - if (close_on_completion) - close_cnum(cnum,vuid); + tpscnt = SVAL(inbuf,smb_vwv0); + tdscnt = SVAL(inbuf,smb_vwv1); + + pcnt = SVAL(inbuf,smb_vwv2); + poff = SVAL(inbuf,smb_vwv3); + pdisp = SVAL(inbuf,smb_vwv4); + + dcnt = SVAL(inbuf,smb_vwv5); + doff = SVAL(inbuf,smb_vwv6); + ddisp = SVAL(inbuf,smb_vwv7); + + pscnt += pcnt; + dscnt += dcnt; + + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } + + if (pcnt) + memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt); + if (dcnt) + memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt); + } + + + DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n", + name,tdscnt,tpscnt,suwcnt)); + + if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0) { + DEBUG(5,("calling named_pipe\n")); + outsize = named_pipe(conn,vuid,outbuf,name+strlen("\\PIPE\\"),setup,data,params, + suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt); + } else { + DEBUG(3,("invalid pipe name\n")); + outsize = 0; + } - if (one_way) - return(-1); - - if (outsize == 0) - return(ERROR(ERRSRV,ERRnosupport)); + + if (data) free(data); + if (params) free(params); + if (setup) free(setup); + + if (close_on_completion) + close_cnum(conn,vuid); - return(outsize); + if (one_way) + return(-1); + + if (outsize == 0) + return(ERROR(ERRSRV,ERRnosupport)); + + return(outsize); } diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index f33b8ac2e6..0703a4a74e 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -418,31 +418,6 @@ BOOL is_8_3( char *fname, BOOL check_case ) return( True ); } /* is_8_3 */ -/* ************************************************************************** ** - * Provide a checksum on a string - * - * Input: s - the nul-terminated character string for which the checksum - * will be calculated. - * - * Output: The checksum value calculated for s. - * - * ************************************************************************** ** - */ -int str_checksum( char *s ) - { - int res = 0; - int c; - int i=0; - - while( *s ) - { - c = *s; - res ^= (c << (i % 15)) ^ (c >> (15-(i%15))); - s++; - i++; - } - return(res); - } /* str_checksum */ /* ************************************************************************** ** * Compare two cache keys and return a value indicating their ordinal diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 44ae272bdd..001fc652b2 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -78,7 +78,7 @@ static void msg_deliver(void) string_sub(s,"%s",name); string_sub(s,"%f",msgfrom); string_sub(s,"%t",msgto); - standard_sub(-1,s); + standard_sub_basic(s); smbrun(s,NULL,False); } @@ -90,7 +90,8 @@ static void msg_deliver(void) /**************************************************************************** reply to a sends ****************************************************************************/ -int reply_sends(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_sends(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int len; char *orig,*dest,*msg; @@ -128,7 +129,8 @@ int reply_sends(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a sendstrt ****************************************************************************/ -int reply_sendstrt(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_sendstrt(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { char *orig,*dest; int outsize = 0; @@ -155,7 +157,8 @@ int reply_sendstrt(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a sendtxt ****************************************************************************/ -int reply_sendtxt(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_sendtxt(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int len; int outsize = 0; @@ -183,7 +186,8 @@ int reply_sendtxt(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a sendend ****************************************************************************/ -int reply_sendend(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_sendend(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -192,7 +196,7 @@ int reply_sendend(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "%s SMBsendend\n" ) ); + DEBUG(3,("SMBsendend\n")); msg_deliver(); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 8709b9c646..bff61b6736 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -25,7 +25,6 @@ extern int DEBUGLEVEL; extern int Protocol; extern int chain_fnum; -extern connection_struct Connections[]; extern files_struct Files[]; extern int Client; extern int oplock_sock; @@ -363,10 +362,9 @@ static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 fi /**************************************************************************** Reply to an NT create and X call on a pipe. ****************************************************************************/ - -static int nt_open_pipe(char *fname, char *inbuf, char *outbuf, int *ppnum) +static int nt_open_pipe(char *fname, connection_struct *conn, + char *inbuf, char *outbuf, int *ppnum) { - int cnum = SVAL(inbuf,smb_tid); int pnum = -1; uint16 vuid = SVAL(inbuf, smb_uid); int i; @@ -386,7 +384,7 @@ static int nt_open_pipe(char *fname, char *inbuf, char *outbuf, int *ppnum) DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); - pnum = open_rpc_pipe_hnd(fname, cnum, vuid); + pnum = open_rpc_pipe_hnd(fname, conn, vuid); if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); @@ -397,280 +395,291 @@ static int nt_open_pipe(char *fname, char *inbuf, char *outbuf, int *ppnum) /**************************************************************************** Reply to an NT create and X call. ****************************************************************************/ - -int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_ntcreate_and_X(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - pstring fname; - int cnum = SVAL(inbuf,smb_tid); - 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); - uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess); - uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition); - uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)), - ((uint32)sizeof(fname)-1)); - int smb_ofun; - int smb_open_mode; - int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK); - /* Breakout the oplock request bits so we can set the - reply bits separately. */ - int oplock_request = 0; - int unixmode; - int fmode=0,mtime=0,rmode=0; - off_t file_len = 0; - struct stat sbuf; - int smb_action = 0; - BOOL bad_path = False; - files_struct *fsp; - char *p = NULL; - - /* - * We need to construct the open_and_X ofun value from the - * NT values, as that's what our code is structured to accept. - */ - - if((smb_ofun = map_create_disposition( create_disposition )) == -1) - return(ERROR(ERRDOS,ERRbadaccess)); - - /* - * Now contruct the smb_open_mode value from the desired access - * and the share access. - */ - - if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1) - return(ERROR(ERRDOS,ERRbadaccess)); - - /* - * Get the file name. - */ - StrnCpy(fname,smb_buf(inbuf),fname_len); - fname[fname_len] = '\0'; - - /* If it's an IPC, use the pipe handler. */ - if (IS_IPC(cnum)) { - int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum); - if(ret != 0) - return ret; - smb_action = FILE_WAS_OPENED; - } else { - - /* - * Ordinary file or directory. - */ - - /* - * Check if POSIX semantics are wanted. - */ - - set_posix_case_semantics(file_attributes); - - unix_convert(fname,cnum,0,&bad_path); - - fnum = find_free_file(); - if (fnum < 0) { - restore_case_semantics(file_attributes); - return(ERROR(ERRSRV,ERRnofids)); - } - - fsp = &Files[fnum]; - - if (!check_name(fname,cnum)) { - if((errno == ENOENT) && bad_path) { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - fsp->reserved = False; - - restore_case_semantics(file_attributes); - - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - unixmode = unix_mode(cnum,smb_attr | aARCH); - - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; - oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; - - /* - * If it's a request for a directory open, deal with it separately. - */ - - if(flags & OPEN_DIRECTORY) { - oplock_request = 0; - - open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action); - - restore_case_semantics(file_attributes); - - if(!fsp->open) { - fsp->reserved = False; - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - } else { - - /* - * Ordinary file case. - */ - - /* - * NB. We have a potential bug here. If we cause an oplock - * break to ourselves, then we could end up processing filename - * related SMB requests whilst we await the oplock break - * response. As we may have changed the filename case - * semantics to be POSIX-like, this could mean a filename - * request could fail when it should succeed. This is a - * rare condition, but eventually we must arrange to restore - * the correct case semantics before issuing an oplock break - * request to our client. JRA. - */ - - open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode, - oplock_request,&rmode,&smb_action); - - if (!fsp->open) { - /* - * We cheat here. The only case we care about is a directory - * rename, where the NT client will attempt to open the source - * directory for DELETE access. Note that when the NT client - * does this it does *not* set the directory bit in the - * request packet. This is translated into a read/write open - * request. POSIX states that any open for write request on a directory - * will generate an EISDIR error, so we can catch this here and open - * a pseudo handle that is flagged as a directory. JRA. - */ - - if(errno == EISDIR) { - oplock_request = 0; - - open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action); - - if(!fsp->open) { - fsp->reserved = False; - restore_case_semantics(file_attributes); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - } else { - if((errno == ENOENT) && bad_path) { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - - fsp->reserved = False; - - restore_case_semantics(file_attributes); + 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); + uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess); + uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition); + uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)), + ((uint32)sizeof(fname)-1)); + int smb_ofun; + int smb_open_mode; + int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK); + /* Breakout the oplock request bits so we can set the + reply bits separately. */ + int oplock_request = 0; + int unixmode; + int fmode=0,mtime=0,rmode=0; + off_t file_len = 0; + struct stat sbuf; + int smb_action = 0; + BOOL bad_path = False; + files_struct *fsp=NULL; + char *p = NULL; + + /* + * We need to construct the open_and_X ofun value from the + * NT values, as that's what our code is structured to accept. + */ + + if((smb_ofun = map_create_disposition( create_disposition )) == -1) + return(ERROR(ERRDOS,ERRbadaccess)); + + /* + * Now contruct the smb_open_mode value from the desired access + * and the share access. + */ + + if((smb_open_mode = map_share_mode(desired_access, + share_access, + file_attributes)) == -1) { + return(ERROR(ERRDOS,ERRbadaccess)); + } - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - } - } - - if(fsp->is_directory) { - if(sys_stat(fsp->name, &sbuf) != 0) { - close_directory(fnum); - restore_case_semantics(file_attributes); - return(ERROR(ERRDOS,ERRnoaccess)); - } - } else { - if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum,False); - restore_case_semantics(file_attributes); - return(ERROR(ERRDOS,ERRnoaccess)); - } - } - - restore_case_semantics(file_attributes); - - file_len = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); - if(fmode == 0) - fmode = FILE_ATTRIBUTE_NORMAL; - mtime = sbuf.st_mtime; - if (!fsp->is_directory && (fmode & aDIR)) { - close_file(fnum,False); - return(ERROR(ERRDOS,ERRnoaccess)); - } - - /* - * If the caller set the extended oplock request bit - * and we granted one (by whatever means) - set the - * correct bit for extended oplock reply. - */ + /* + * Get the file name. + */ + StrnCpy(fname,smb_buf(inbuf),fname_len); + fname[fname_len] = '\0'; + + /* If it's an IPC, use the pipe handler. */ + if (IS_IPC(conn)) { + int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum); + if(ret != 0) + return ret; + smb_action = FILE_WAS_OPENED; + } else { + + /* + * Ordinary file or directory. + */ + + /* + * Check if POSIX semantics are wanted. + */ + + set_posix_case_semantics(file_attributes); + + unix_convert(fname,conn,0,&bad_path); + + fnum = find_free_file(); + if (fnum < 0) { + 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; + + restore_case_semantics(file_attributes); + + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + unixmode = unix_mode(conn,smb_attr | aARCH); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) - smb_action |= EXTENDED_OPLOCK_GRANTED; - - if(oplock_request && fsp->granted_oplock) - smb_action |= EXTENDED_OPLOCK_GRANTED; - } - - set_message(outbuf,34,0,True); - - p = outbuf + smb_vwv2; - - /* - * Currently as we don't support level II oplocks we just report - * exclusive & batch here. - */ - - SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0)); - p++; - SSVAL(p,0,fnum); - p += 2; - SIVAL(p,0,smb_action); - p += 4; - - if (IS_IPC(cnum)) { - /* - * Deal with pipe return. - */ - p += 32; - SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */ - p += 20; - /* File type. */ - SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE); - /* Device state. */ - SSVAL(p,2, 0x5FF); /* ? */ - } else { - /* - * Deal with file return. - */ - /* Create time. */ - put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); - p += 8; - put_long_date(p,sbuf.st_atime); /* access time */ - p += 8; - put_long_date(p,sbuf.st_mtime); /* write time */ - p += 8; - put_long_date(p,sbuf.st_mtime); /* change time */ - p += 8; - SIVAL(p,0,fmode); /* File Attributes. */ - p += 12; + oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; + oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; + + /* + * If it's a request for a directory open, deal with it separately. + */ + + if(flags & OPEN_DIRECTORY) { + oplock_request = 0; + + open_directory(fnum, conn, fname, smb_ofun, + unixmode, &smb_action); + + restore_case_semantics(file_attributes); + + if(!fsp->open) { + fsp->reserved = False; + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + } else { + /* + * Ordinary file case. + */ + + /* NB. We have a potential bug here. If we + * cause an oplock break to ourselves, then we + * could end up processing filename related + * SMB requests whilst we await the oplock + * break response. As we may have changed the + * filename case semantics to be POSIX-like, + * this could mean a filename request could + * fail when it should succeed. This is a rare + * condition, but eventually we must arrange + * to restore the correct case semantics + * before issuing an oplock break request to + * our client. JRA. */ + + open_file_shared(fnum,conn,fname,smb_open_mode, + smb_ofun,unixmode, + oplock_request,&rmode,&smb_action); + + if (!fsp->open) { + /* We cheat here. The only case we + * care about is a directory rename, + * where the NT client will attempt to + * open the source directory for + * DELETE access. Note that when the + * NT client does this it does *not* + * set the directory bit in the * + * request packet. This is translated + * into a read/write open * + * request. POSIX states that any open + * for write request on a directory * + * will generate an EISDIR error, so + * we can catch this here and open * a + * pseudo handle that is flagged as a + * directory. JRA. */ + + if(errno == EISDIR) { + oplock_request = 0; + + open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action); + + if(!fsp->open) { + fsp->reserved = False; + restore_case_semantics(file_attributes); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + } else { + if((errno == ENOENT) && bad_path) { + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadpath; + } + + fsp->reserved = False; + + restore_case_semantics(file_attributes); + + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + } + } + + if(fsp->is_directory) { + if(sys_stat(fsp->fsp_name, &sbuf) != 0) { + close_directory(fnum); + restore_case_semantics(file_attributes); + return(ERROR(ERRDOS,ERRnoaccess)); + } + } else { + if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + close_file(fnum,False); + restore_case_semantics(file_attributes); + return(ERROR(ERRDOS,ERRnoaccess)); + } + } + + restore_case_semantics(file_attributes); + + file_len = sbuf.st_size; + fmode = dos_mode(conn,fname,&sbuf); + if(fmode == 0) + fmode = FILE_ATTRIBUTE_NORMAL; + mtime = sbuf.st_mtime; + if (!fsp->is_directory && (fmode & aDIR)) { + close_file(fnum,False); + return(ERROR(ERRDOS,ERRnoaccess)); + } + + /* + * If the caller set the extended oplock request bit + * and we granted one (by whatever means) - set the + * correct bit for extended oplock reply. + */ + + if (oplock_request && lp_fake_oplocks(SNUM(conn))) + smb_action |= EXTENDED_OPLOCK_GRANTED; + + if(oplock_request && fsp->granted_oplock) + smb_action |= EXTENDED_OPLOCK_GRANTED; + } + + set_message(outbuf,34,0,True); + + p = outbuf + smb_vwv2; + + /* + * Currently as we don't support level II oplocks we just report + * exclusive & batch here. + */ + + SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0)); + p++; + SSVAL(p,0,fnum); + p += 2; + SIVAL(p,0,smb_action); + p += 4; + + if (IS_IPC(conn)) { + /* + * Deal with pipe return. + */ + p += 32; + SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */ + p += 20; + /* File type. */ + SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE); + /* Device state. */ + SSVAL(p,2, 0x5FF); /* ? */ + } else { + /* + * Deal with file return. + */ + /* Create time. */ + put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + p += 8; + put_long_date(p,sbuf.st_atime); /* access time */ + p += 8; + put_long_date(p,sbuf.st_mtime); /* write time */ + p += 8; + put_long_date(p,sbuf.st_mtime); /* change time */ + p += 8; + SIVAL(p,0,fmode); /* File Attributes. */ + p += 12; #if OFF_T_IS_64_BITS - SIVAL(p,0, file_len & 0xFFFFFFFF); - SIVAL(p,4, file_len >> 32); + SIVAL(p,0, file_len & 0xFFFFFFFF); + SIVAL(p,4, file_len >> 32); #else /* OFF_T_IS_64_BITS */ - SIVAL(p,0,file_len); + SIVAL(p,0,file_len); #endif /* OFF_T_IS_64_BITS */ - p += 12; - SCVAL(p,0,fsp->is_directory ? 1 : 0); - } - - chain_fnum = fnum; + p += 12; + SCVAL(p,0,fsp->is_directory ? 1 : 0); + } + + chain_fnum = fnum; - DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n", - fnum, fsp->name )); + + DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n", + fnum, fsp?fsp->fsp_name:"NULL")); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** Reply to a NT_TRANSACT_CREATE call (needs to process SD's). ****************************************************************************/ - -static int call_nt_transact_create(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, - char **ppsetup, char **ppparams, char **ppdata) +static int call_nt_transact_create(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, + char **ppsetup, char **ppparams, + char **ppdata) { pstring fname; int fnum = -1; @@ -721,8 +730,8 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, fname[fname_len] = '\0'; /* If it's an IPC, use the pipe handler. */ - if (IS_IPC(cnum)) { - int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum); + if (IS_IPC(conn)) { + int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum); if(ret != 0) return ret; smb_action = FILE_WAS_OPENED; @@ -733,7 +742,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, set_posix_case_semantics(file_attributes); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); fnum = find_free_file(); if (fnum < 0) { @@ -743,7 +752,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, fsp = &Files[fnum]; - if (!check_name(fname,cnum)) { + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; @@ -755,7 +764,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - unixmode = unix_mode(cnum,smb_attr | aARCH); + unixmode = unix_mode(conn,smb_attr | aARCH); oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; @@ -774,7 +783,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, * CreateDirectory() call. */ - open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action); + open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action); if(!fsp->open) { fsp->reserved = False; @@ -786,7 +795,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, * Ordinary file case. */ - open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode, + open_file_shared(fnum,conn,fname,smb_open_mode,smb_ofun,unixmode, oplock_request,&rmode,&smb_action); if (!fsp->open) { @@ -810,7 +819,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, } file_len = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); + fmode = dos_mode(conn,fname,&sbuf); if(fmode == 0) fmode = FILE_ATTRIBUTE_NORMAL; mtime = sbuf.st_mtime; @@ -827,7 +836,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, * correct bit for extended oplock reply. */ - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) + if (oplock_request && lp_fake_oplocks(SNUM(conn))) smb_action |= EXTENDED_OPLOCK_GRANTED; if(oplock_request && fsp->granted_oplock) @@ -850,7 +859,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, SIVAL(p,0,smb_action); p += 8; - if (IS_IPC(cnum)) { + if (IS_IPC(conn)) { /* * Deal with pipe return. */ @@ -866,7 +875,7 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, * Deal with file return. */ /* Create time. */ - put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); p += 8; put_long_date(p,sbuf.st_atime); /* access time */ p += 8; @@ -893,39 +902,39 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length, /**************************************************************************** Reply to a NT CANCEL request. ****************************************************************************/ - -int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize) +int reply_ntcancel(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - /* - * Go through and cancel any pending change notifies. - * TODO: When we add blocking locks we will add cancel - * for them here too. - */ - - int mid = SVAL(inbuf,smb_mid); - remove_pending_change_notify_requests_by_mid(mid); - - DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid)); - - return(-1); + /* + * Go through and cancel any pending change notifies. + * TODO: When we add blocking locks we will add cancel + * for them here too. + */ + + int mid = SVAL(inbuf,smb_mid); + remove_pending_change_notify_requests_by_mid(mid); + + DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid)); + + return(-1); } /**************************************************************************** Reply to an unsolicited SMBNTtranss - just ignore it! ****************************************************************************/ - -int reply_nttranss(char *inbuf,char *outbuf,int length,int bufsize) +int reply_nttranss(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - DEBUG(4,("Ignoring nttranss of length %d\n",length)); - return(-1); + DEBUG(4,("Ignoring nttranss of length %d\n",length)); + return(-1); } /**************************************************************************** Reply to an NT transact rename command. ****************************************************************************/ - -static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, +static int call_nt_transact_rename(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, char **ppsetup, char **ppparams, char **ppdata) { char *params = *ppparams; @@ -936,11 +945,11 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, ((uint32)sizeof(new_name)-1)); int outsize = 0; - CHECK_FNUM(fnum, cnum); + CHECK_FNUM(fnum, conn); StrnCpy(new_name,params+4,fname_len); new_name[fname_len] = '\0'; - outsize = rename_internals(inbuf, outbuf, Files[fnum].name, + outsize = rename_internals(conn, inbuf, outbuf, Files[fnum].fsp_name, new_name, replace_if_exists); if(outsize == 0) { /* @@ -949,7 +958,7 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0); DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", - Files[fnum].name, new_name)); + Files[fnum].fsp_name, new_name)); outsize = -1; } @@ -967,7 +976,7 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, typedef struct { ubi_slNode msg_next; int fnum; - int cnum; + connection_struct *conn; time_t next_check_time; time_t modify_time; /* Info from the directory we're monitoring. */ time_t status_time; /* Info from the directory we're monitoring. */ @@ -1076,12 +1085,12 @@ void process_pending_change_notify_queue(time_t t) while((cnbp != NULL) && (cnbp->next_check_time <= t)) { struct stat st; int fnum = cnbp->fnum; - int cnum = cnbp->cnum; + 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); - if(!become_user(&Connections[cnum],cnum,vuid)) { + if(!become_user(conn,vuid)) { DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n", vuid )); /* @@ -1093,9 +1102,8 @@ void process_pending_change_notify_queue(time_t t) continue; } - if(!become_service(cnum,True)) { - DEBUG(0,("process_pending_change_notify_queue: Unable to become service cnum=%d. \ -Error was %s.\n", cnum, strerror(errno) )); + if(!become_service(conn,True)) { + DEBUG(0,("process_pending_change_notify_queue: Unable to become service Error was %s.\n", strerror(errno) )); /* * Remove the entry and return an error to the client. */ @@ -1106,9 +1114,9 @@ Error was %s.\n", cnum, strerror(errno) )); continue; } - if(sys_stat(fsp->name, &st) < 0) { + if(sys_stat(fsp->fsp_name, &st) < 0) { DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \ -Error was %s.\n", fsp->name, strerror(errno) )); +Error was %s.\n", fsp->fsp_name, strerror(errno) )); /* * Remove the entry and return an error to the client. */ @@ -1125,7 +1133,7 @@ Error was %s.\n", 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->name )); + fnum, 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)); @@ -1147,10 +1155,11 @@ Error was %s.\n", fsp->name, strerror(errno) )); Reply to a notify change - queue the request and don't allow a directory to be opened. ****************************************************************************/ - -static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, - char **ppsetup, char **ppparams, char **ppdata) +static int call_nt_transact_notify_change(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, + char **ppsetup, + char **ppparams, char **ppdata) { char *setup = *ppsetup; files_struct *fsp; @@ -1167,7 +1176,7 @@ static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length, fsp = &Files[fnum]; - if((!fsp->open) || (!fsp->is_directory) || (cnum != fsp->cnum)) + if((!fsp->open) || (!fsp->is_directory) || (conn != fsp->conn)) return(ERROR(ERRDOS,ERRbadfid)); /* @@ -1187,16 +1196,16 @@ static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length, * Store the current timestamp on the directory we are monitoring. */ - if(sys_stat(fsp->name, &st) < 0) { + 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->name, strerror(errno) )); +Error was %s\n", fnum, fsp->fsp_name, strerror(errno) )); free((char *)cnbp); return(UNIXERROR(ERRDOS,ERRbadfid)); } memcpy(cnbp->request_buf, inbuf, smb_size); cnbp->fnum = fnum; - cnbp->cnum = cnum; + cnbp->conn = conn; cnbp->modify_time = st.st_mtime; cnbp->status_time = st.st_ctime; @@ -1211,7 +1220,7 @@ Error was %s\n", fnum, 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->name )); +fid=%d, name = %s\n", fnum, fsp->fsp_name )); return -1; } @@ -1220,9 +1229,10 @@ fid=%d, name = %s\n", fnum, fsp->name )); Reply to query a security descriptor - currently this is not implemented (it is planned to be though). ****************************************************************************/ - -static int call_nt_transact_query_security_desc(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, +static int call_nt_transact_query_security_desc(connection_struct *conn, + char *inbuf, char *outbuf, + int length, + int bufsize, char **ppsetup, char **ppparams, char **ppdata) { DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n")); @@ -1233,21 +1243,23 @@ static int call_nt_transact_query_security_desc(char *inbuf, char *outbuf, int l Reply to set a security descriptor - currently this is not implemented (it is planned to be though). ****************************************************************************/ - -static int call_nt_transact_set_security_desc(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, - char **ppsetup, char **ppparams, char **ppdata) +static int call_nt_transact_set_security_desc(connection_struct *conn, + char *inbuf, char *outbuf, + int length, + int bufsize, + char **ppsetup, + char **ppparams, char **ppdata) { - DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n")); - return(ERROR(ERRSRV,ERRnosupport)); + DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n")); + return(ERROR(ERRSRV,ERRnosupport)); } /**************************************************************************** Reply to IOCTL - not implemented - no plans. ****************************************************************************/ - -static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, +static int call_nt_transact_ioctl(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, char **ppsetup, char **ppparams, char **ppdata) { DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n")); @@ -1257,11 +1269,10 @@ static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int length, /**************************************************************************** Reply to a SMBNTtrans. ****************************************************************************/ - -int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize) +int reply_nttrans(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { int outsize = 0; - int cnum = SVAL(inbuf,smb_tid); #if 0 /* Not used. */ uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount); uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount); @@ -1394,39 +1405,45 @@ due to being in oplock break state.\n" )); /* Now we must call the relevant NT_TRANS function */ switch(function_code) { case NT_TRANSACT_CREATE: - outsize = call_nt_transact_create(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_create(conn, inbuf, outbuf, length, bufsize, &setup, ¶ms, &data); break; case NT_TRANSACT_IOCTL: - outsize = call_nt_transact_ioctl(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_ioctl(conn, + inbuf, outbuf, length, bufsize, &setup, ¶ms, &data); break; case NT_TRANSACT_SET_SECURITY_DESC: - outsize = call_nt_transact_set_security_desc(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, + length, bufsize, &setup, ¶ms, &data); break; case NT_TRANSACT_NOTIFY_CHANGE: - outsize = call_nt_transact_notify_change(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, + length, bufsize, &setup, ¶ms, &data); break; case NT_TRANSACT_RENAME: - outsize = call_nt_transact_rename(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_rename(conn, inbuf, outbuf, length, + bufsize, &setup, ¶ms, &data); break; + case NT_TRANSACT_QUERY_SECURITY_DESC: - outsize = call_nt_transact_query_security_desc(inbuf, outbuf, length, bufsize, cnum, + outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, + length, bufsize, &setup, ¶ms, &data); break; - default: - /* Error in request */ - DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code)); - if(setup) - free(setup); - if(params) - free(params); - if(data) - free(data); - return (ERROR(ERRSRV,ERRerror)); + default: + /* Error in request */ + DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code)); + if(setup) + free(setup); + if(params) + free(params); + if(data) + free(data); + return (ERROR(ERRSRV,ERRerror)); } /* As we do not know how many data packets will need to be diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 34884aa6d3..2a51e83946 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -58,10 +58,10 @@ extern struct pipe_id_info pipe_names[]; This code is basically stolen from reply_open_and_X with some wrinkles to handle pipes. ****************************************************************************/ -int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_open_pipe_and_X(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - uint16 cnum = SVAL(inbuf, smb_tid); uint16 vuid = SVAL(inbuf, smb_uid); int pnum = -1; int smb_ofun = SVAL(inbuf,smb_vwv8); @@ -95,7 +95,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(3,("Known pipe %s opening.\n",fname)); smb_ofun |= 0x10; /* Add Create it not exists flag */ - pnum = open_rpc_pipe_hnd(fname, cnum, vuid); + pnum = open_rpc_pipe_hnd(fname, conn, vuid); if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); /* Prepare the reply */ @@ -134,13 +134,10 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) uint32 smb_offs = IVAL(inbuf,smb_vwv3); int smb_maxcnt = SVAL(inbuf,smb_vwv5); int smb_mincnt = SVAL(inbuf,smb_vwv6); - int cnum; int nread = -1; char *data; BOOL ok = False; - cnum = SVAL(inbuf,smb_tid); - /* CHECK_FNUM(fnum,cnum); CHECK_READ(fnum); @@ -161,8 +158,8 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); SSVAL(smb_buf(outbuf),-2,nread); - DEBUG( 3, ( "readX pnum=%04x cnum=%d min=%d max=%d nread=%d\n", - pnum, cnum, smb_mincnt, smb_maxcnt, nread ) ); + DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", + pnum, smb_mincnt, smb_maxcnt, nread)); set_chain_pnum(pnum); @@ -171,15 +168,14 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a close ****************************************************************************/ -int reply_pipe_close(char *inbuf,char *outbuf) +int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); - int cnum = SVAL(inbuf,smb_tid); int outsize = set_message(outbuf,0,0,True); - DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum)); + DEBUG(5,("reply_pipe_close: pnum:%x\n", pnum)); - if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); + if (!close_rpc_pipe_hnd(pnum, conn)) return(ERROR(ERRDOS,ERRbadfid)); return(outsize); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b0509bf3d5..66d1dd2839 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -35,7 +35,6 @@ extern int max_send; extern int max_recv; extern int chain_fnum; extern char magic_char; -extern connection_struct Connections[]; extern files_struct Files[]; extern BOOL case_sensitive; extern BOOL case_preserve; @@ -82,7 +81,7 @@ int reply_special(char *inbuf,char *outbuf) *name1 = *name2 = 0; - bzero(outbuf,smb_size); + bzero(outbuf,smb_size); smb_setlen(outbuf,0); @@ -127,7 +126,7 @@ int reply_special(char *inbuf,char *outbuf) reopen_logs(); if (lp_status(-1)) { - claim_connection(-1,"STATUS.",MAXSTATUS,True); + claim_connection(NULL,"STATUS.",MAXSTATUS,True); } break; @@ -149,8 +148,8 @@ int reply_special(char *inbuf,char *outbuf) return(0); } - DEBUG( 5, ( "init msg_type=0x%x msg_flags=0x%x\n", - msg_type, msg_flags ) ); + DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n", + msg_type, msg_flags)); return(outsize); } @@ -159,26 +158,13 @@ int reply_special(char *inbuf,char *outbuf) /******************************************************************* work out what error to give to a failed connection ********************************************************************/ -static int connection_error(char *inbuf,char *outbuf,int connection_num) +static int connection_error(char *inbuf,char *outbuf,int ecode) { - switch (connection_num) - { - case -8: - return(ERROR(ERRSRV,ERRnoresource)); - case -7: - return(ERROR(ERRSRV,ERRbaduid)); - case -6: - return(ERROR(ERRSRV,ERRinvdevice)); - case -5: - return(ERROR(ERRSRV,ERRinvnetname)); - case -4: - return(ERROR(ERRSRV,ERRaccess)); - case -3: - return(ERROR(ERRDOS,ERRnoipc)); - case -2: - return(ERROR(ERRSRV,ERRinvnetname)); - } - return(ERROR(ERRSRV,ERRbadpw)); + if (ecode == ERRnoipc) { + return(ERROR(ERRDOS,ERRnoipc)); + } + + return(ERROR(ERRSRV,ecode)); } @@ -223,147 +209,145 @@ static void parse_connect(char *p,char *service,char *user, /**************************************************************************** reply to a tcon ****************************************************************************/ -int reply_tcon(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_tcon(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - pstring service; - pstring user; - pstring password; - pstring dev; - int connection_num; - int outsize = 0; - uint16 vuid = SVAL(inbuf,smb_uid); - int pwlen=0; - - *service = *user = *password = *dev = 0; - - parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev); - - /* - * Pass the user through the NT -> unix user mapping - * function. - */ + pstring service; + pstring user; + pstring password; + pstring dev; + int outsize = 0; + uint16 vuid = SVAL(inbuf,smb_uid); + int pwlen=0; + int ecode = -1; + + *service = *user = *password = *dev = 0; + + parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev); + + /* + * Pass the user through the NT -> unix user mapping + * function. + */ - (void)map_username(user); + (void)map_username(user); - /* - * Do any UNIX username case mangling. - */ - (void)Get_Pwnam( user, True); + /* + * Do any UNIX username case mangling. + */ + (void)Get_Pwnam( user, True); - connection_num = make_connection(service,user,password,pwlen,dev,vuid); + conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode); - if (connection_num < 0) - return(connection_error(inbuf,outbuf,connection_num)); + if (!conn) { + return(connection_error(inbuf,outbuf,ecode)); + } - outsize = set_message(outbuf,2,0,True); - SSVAL(outbuf,smb_vwv0,max_recv); - SSVAL(outbuf,smb_vwv1,connection_num); - SSVAL(outbuf,smb_tid,connection_num); + outsize = set_message(outbuf,2,0,True); + SSVAL(outbuf,smb_vwv0,max_recv); + SSVAL(outbuf,smb_vwv1,conn->cnum); + SSVAL(outbuf,smb_tid,conn->cnum); - DEBUG(3,("tcon service=%s user=%s cnum=%d\n", service, user, connection_num)); + DEBUG(3,("tcon service=%s user=%s cnum=%d\n", + service, user, conn->cnum)); - return(outsize); + return(outsize); } /**************************************************************************** reply to a tcon and X ****************************************************************************/ -int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - pstring service; - pstring user; - pstring password; - pstring devicename; - int connection_num; - uint16 vuid = SVAL(inbuf,smb_uid); - int passlen = SVAL(inbuf,smb_vwv3); - - *service = *user = *password = *devicename = 0; - - /* we might have to close an old one */ - if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0) - close_cnum(SVAL(inbuf,smb_tid),vuid); - - if (passlen > MAX_PASS_LEN) { - overflow_attack(passlen); - } - - { - char *path; - char *p; - memcpy(password,smb_buf(inbuf),passlen); - password[passlen]=0; - path = smb_buf(inbuf) + passlen; - - if (passlen != 24) { - if (strequal(password," ")) - *password = 0; - passlen = strlen(password); - } - - fstrcpy(service,path+2); - p = strchr(service,'\\'); - if (!p) - return(ERROR(ERRSRV,ERRinvnetname)); - *p = 0; - fstrcpy(service,p+1); - p = strchr(service,'%'); - if (p) - { - *p++ = 0; - fstrcpy(user,p); - } - StrnCpy(devicename,path + strlen(path) + 1,6); - DEBUG(4,("Got device type %s\n",devicename)); - } - - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - (void)map_username(user); + pstring service; + pstring user; + pstring password; + pstring devicename; + int ecode = -1; + uint16 vuid = SVAL(inbuf,smb_uid); + int passlen = SVAL(inbuf,smb_vwv3); + char *path; + char *p; + + *service = *user = *password = *devicename = 0; - /* - * Do any UNIX username case mangling. - */ - (void)Get_Pwnam( user, True); + /* we might have to close an old one */ + if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) { + close_cnum(conn,vuid); + } - connection_num = make_connection(service,user,password,passlen,devicename,vuid); + if (passlen > MAX_PASS_LEN) { + overflow_attack(passlen); + } - if (connection_num < 0) - return(connection_error(inbuf,outbuf,connection_num)); + memcpy(password,smb_buf(inbuf),passlen); + password[passlen]=0; + path = smb_buf(inbuf) + passlen; - if (Protocol < PROTOCOL_NT1) - { - set_message(outbuf,2,strlen(devicename)+1,True); - pstrcpy(smb_buf(outbuf),devicename); - } - else - { - char *fsname = FSTYPE_STRING; - char *p; + if (passlen != 24) { + if (strequal(password," ")) + *password = 0; + passlen = strlen(password); + } + + fstrcpy(service,path+2); + p = strchr(service,'\\'); + if (!p) + return(ERROR(ERRSRV,ERRinvnetname)); + *p = 0; + fstrcpy(service,p+1); + p = strchr(service,'%'); + if (p) { + *p++ = 0; + fstrcpy(user,p); + } + StrnCpy(devicename,path + strlen(path) + 1,6); + DEBUG(4,("Got device type %s\n",devicename)); - set_message(outbuf,3,3,True); + /* + * Pass the user through the NT -> unix user mapping + * function. + */ + + (void)map_username(user); + + /* + * Do any UNIX username case mangling. + */ + (void)Get_Pwnam(user, True); + + conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode); + + if (!conn) + return(connection_error(inbuf,outbuf,ecode)); - p = smb_buf(outbuf); - pstrcpy(p,devicename); p = skip_string(p,1); /* device name */ - pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */ + if (Protocol < PROTOCOL_NT1) { + set_message(outbuf,2,strlen(devicename)+1,True); + pstrcpy(smb_buf(outbuf),devicename); + } else { + char *fsname = FSTYPE_STRING; + char *p; - set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False); + set_message(outbuf,3,3,True); - SSVAL(outbuf, smb_vwv2, 0x0); /* optional support */ - } + p = smb_buf(outbuf); + pstrcpy(p,devicename); p = skip_string(p,1); /* device name */ + pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */ + + set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False); + + SSVAL(outbuf, smb_vwv2, 0x0); /* optional support */ + } - DEBUG( 3, ( "tconX service=%s user=%s cnum=%d\n", - service, user, connection_num ) ); + DEBUG(3,("tconX service=%s user=%s\n", + service, user)); - /* set the incoming and outgoing tid to the just created one */ - SSVAL(inbuf,smb_tid,connection_num); - SSVAL(outbuf,smb_tid,connection_num); + /* set the incoming and outgoing tid to the just created one */ + SSVAL(inbuf,smb_tid,conn->cnum); + SSVAL(outbuf,smb_tid,conn->cnum); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,outbuf,length,bufsize); } @@ -372,37 +356,36 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) ****************************************************************************/ int reply_unknown(char *inbuf,char *outbuf) { - int cnum; - int type; - cnum = SVAL(inbuf,smb_tid); - type = CVAL(inbuf,smb_com); + int type; + type = CVAL(inbuf,smb_com); - DEBUG(0,("unknown command type (%s): cnum=%d type=%d (0x%X)\n", - smb_fn_name(type), cnum, type, type)); + DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n", + smb_fn_name(type), type, type)); - return(ERROR(ERRSRV,ERRunknownsmb)); + return(ERROR(ERRSRV,ERRunknownsmb)); } /**************************************************************************** reply to an ioctl ****************************************************************************/ -int reply_ioctl(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_ioctl(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - DEBUG(3,("ignoring ioctl\n")); + DEBUG(3,("ignoring ioctl\n")); #if 0 - /* we just say it succeeds and hope its all OK. - some day it would be nice to interpret them individually */ - return set_message(outbuf,1,0,True); + /* we just say it succeeds and hope its all OK. + some day it would be nice to interpret them individually */ + return set_message(outbuf,1,0,True); #else - return(ERROR(ERRSRV,ERRnosupport)); + return(ERROR(ERRSRV,ERRnosupport)); #endif } /**************************************************************************** always return an error: it's just a matter of which one... ****************************************************************************/ -static int session_trust_account(char *inbuf, char *outbuf, char *user, +static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user, char *smb_passwd, int smb_passlen, char *smb_nt_passwd, int smb_nt_passlen) { @@ -472,7 +455,7 @@ static int session_trust_account(char *inbuf, char *outbuf, char *user, /**************************************************************************** reply to a session setup command ****************************************************************************/ -int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { uint16 sess_vuid; int gid; @@ -602,7 +585,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* say yes to everything ending in $. */ if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) { - return session_trust_account(inbuf, outbuf, user, + return session_trust_account(conn, inbuf, outbuf, user, smb_apasswd, smb_apasslen, smb_ntpasswd, smb_ntpasslen); } @@ -769,22 +752,20 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a chkpth ****************************************************************************/ -int reply_chkpth(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; - int cnum,mode; + int mode; pstring name; BOOL ok = False; BOOL bad_path = False; - cnum = SVAL(inbuf,smb_tid); - pstrcpy(name,smb_buf(inbuf) + 1); - unix_convert(name,cnum,0,&bad_path); + unix_convert(name,conn,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); - if (check_name(name,cnum)) + if (check_name(name,conn)) ok = directory_exist(name,NULL); if (!ok) @@ -815,7 +796,7 @@ int reply_chkpth(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "chkpth %s cnum=%d mode=%d\n", name, cnum, mode ) ); + DEBUG(3,("chkpth %s mode=%d\n", name, mode)); return(outsize); } @@ -824,10 +805,9 @@ int reply_chkpth(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a getatr ****************************************************************************/ -int reply_getatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - int cnum; int outsize = 0; struct stat sbuf; BOOL ok = False; @@ -836,27 +816,25 @@ int reply_getatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) time_t mtime=0; BOOL bad_path = False; - cnum = SVAL(inbuf,smb_tid); - pstrcpy(fname,smb_buf(inbuf) + 1); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); /* dos smetimes asks for a stat of "" - it returns a "hidden directory" under WfWg - weird! */ if (! (*fname)) { mode = aHIDDEN | aDIR; - if (!CAN_WRITE(cnum)) mode |= aRONLY; + if (!CAN_WRITE(conn)) mode |= aRONLY; size = 0; mtime = 0; ok = True; } else - if (check_name(fname,cnum)) + if (check_name(fname,conn)) { if (sys_stat(fname,&sbuf) == 0) { - mode = dos_mode(cnum,fname,&sbuf); + mode = dos_mode(conn,fname,&sbuf); size = sbuf.st_size; mtime = sbuf.st_mtime; if (mode & aDIR) @@ -881,7 +859,7 @@ int reply_getatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,10,0,True); SSVAL(outbuf,smb_vwv0,mode); - if(lp_dos_filetime_resolution(SNUM(cnum)) ) + if(lp_dos_filetime_resolution(SNUM(conn)) ) put_dos_date3(outbuf,smb_vwv1,mtime & ~1); else put_dos_date3(outbuf,smb_vwv1,mtime); @@ -904,30 +882,27 @@ int reply_getatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a setatr ****************************************************************************/ -int reply_setatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - int cnum; int outsize = 0; BOOL ok=False; int mode; time_t mtime; BOOL bad_path = False; - cnum = SVAL(inbuf,smb_tid); - pstrcpy(fname,smb_buf(inbuf) + 1); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); mtime = make_unix_date3(inbuf+smb_vwv1); if (directory_exist(fname,NULL)) mode |= aDIR; - if (check_name(fname,cnum)) - ok = (dos_chmod(cnum,fname,mode,NULL) == 0); + if (check_name(fname,conn)) + ok = (dos_chmod(conn,fname,mode,NULL) == 0); if (ok) - ok = set_filetime(cnum,fname,mtime); + ok = set_filetime(conn,fname,mtime); if (!ok) { @@ -951,14 +926,11 @@ int reply_setatr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a dskattr ****************************************************************************/ -int reply_dskattr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum; int outsize = 0; int dfree,dsize,bsize; - cnum = SVAL(inbuf,smb_tid); - sys_disk_free(".",&bsize,&dfree,&dsize); outsize = set_message(outbuf,5,0,True); @@ -968,7 +940,7 @@ int reply_dskattr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) SSVAL(outbuf,smb_vwv2,512); SSVAL(outbuf,smb_vwv3,dfree); - DEBUG( 3, ( "dskattr cnum=%d dfree=%d\n", cnum, dfree ) ); + DEBUG(3,("dskattr dfree=%d\n", dfree)); return(outsize); } @@ -978,7 +950,7 @@ int reply_dskattr(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) reply to a search Can be called from SMBsearch, SMBffirst or SMBfunique. ****************************************************************************/ -int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring mask; pstring directory; @@ -986,7 +958,6 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) int size,mode; time_t date; int dirtype; - int cnum; int outsize = 0; int numentries = 0; BOOL finished = False; @@ -1009,8 +980,6 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if(CVAL(inbuf,smb_com) == SMBffirst) expect_close = True; - cnum = SVAL(inbuf,smb_tid); - outsize = set_message(outbuf,1,3,True); maxentries = SVAL(inbuf,smb_vwv0); dirtype = SVAL(inbuf,smb_vwv1); @@ -1029,10 +998,10 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) pstrcpy(directory,smb_buf(inbuf)+1); pstrcpy(dir2,smb_buf(inbuf)+1); - unix_convert(directory,cnum,0,&bad_path); + unix_convert(directory,conn,0,&bad_path); unix_format(dir2); - if (!check_name(directory,cnum)) + if (!check_name(directory,conn)) can_open = False; p = strrchr(dir2,'/'); @@ -1064,10 +1033,10 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) memcpy(mask,status+1,11); mask[11] = 0; dirtype = CVAL(status,0) & 0x1F; - Connections[cnum].dirptr = dptr_fetch(status+12,&dptr_num); - if (!Connections[cnum].dirptr) + conn->dirptr = dptr_fetch(status+12,&dptr_num); + if (!conn->dirptr) goto SearchEmpty; - string_set(&Connections[cnum].dirpath,dptr_path(dptr_num)); + string_set(&conn->dirpath,dptr_path(dptr_num)); if (!case_sensitive) strnorm(mask); } @@ -1119,7 +1088,7 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if (status_len == 0) { - dptr_num = dptr_create(cnum,directory,expect_close,SVAL(inbuf,smb_pid)); + dptr_num = dptr_create(conn,directory,expect_close,SVAL(inbuf,smb_pid)); if (dptr_num < 0) { if(dptr_num == -2) @@ -1142,7 +1111,7 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if ((dirtype&0x1F) == aVOLID) { memcpy(p,status,21); - make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,aVOLID,0); + make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0); dptr_fill(p+12,dptr_num); if (dptr_zero(p+12) && (status_len==0)) numentries = 1; @@ -1152,15 +1121,16 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) } else { - DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)))); - if (in_list(Connections[cnum].dirpath, - lp_dontdescend(SNUM(cnum)),True)) + DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", + conn->dirpath,lp_dontdescend(SNUM(conn)))); + if (in_list(conn->dirpath, + lp_dontdescend(SNUM(conn)),True)) check_descend = True; for (i=numentries;(i<maxentries) && !finished;i++) { finished = - !get_dir_entry(cnum,mask,dirtype,fname,&size,&mode,&date,check_descend); + !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend); if (!finished) { memcpy(p,status,21); @@ -1215,9 +1185,9 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if ((! *directory) && dptr_path(dptr_num)) slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); - DEBUG( 4, ( "%s mask=%s path=%s cnum=%d dtype=%d nument=%d of %d\n", + DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n", smb_fn_name(CVAL(inbuf,smb_com)), - mask, directory, cnum, dirtype, numentries, maxentries ) ); + mask, directory, dirtype, numentries, maxentries ) ); return(outsize); } @@ -1226,17 +1196,14 @@ int reply_search(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a fclose (stop directory search) ****************************************************************************/ -int reply_fclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum; int outsize = 0; int status_len; char *path; char status[21]; int dptr_num= -1; - cnum = SVAL(inbuf,smb_tid); - outsize = set_message(outbuf,1,0,True); path = smb_buf(inbuf) + 1; status_len = SVAL(smb_buf(inbuf),3 + strlen(path)); @@ -1254,7 +1221,7 @@ int reply_fclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) SSVAL(outbuf,smb_vwv0,0); - DEBUG( 3, ( "%s search close cnum=%d\n", cnum ) ); + DEBUG(3,("search close\n")); return(outsize); } @@ -1263,10 +1230,9 @@ int reply_fclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to an open ****************************************************************************/ -int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - int cnum; int fnum = -1; int outsize = 0; int fmode=0; @@ -1280,12 +1246,10 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); - cnum = SVAL(inbuf,smb_tid); - share_mode = SVAL(inbuf,smb_vwv0); pstrcpy(fname,smb_buf(inbuf)+1); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); fnum = find_free_file(); if (fnum < 0) @@ -1293,7 +1257,7 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) fsp = &Files[fnum]; - if (!check_name(fname,cnum)) + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { @@ -1304,9 +1268,9 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) return(UNIXERROR(ERRDOS,ERRnoaccess)); } - unixmode = unix_mode(cnum,aARCH); + unixmode = unix_mode(conn,aARCH); - open_file_shared(fnum,cnum,fname,share_mode,3,unixmode, + open_file_shared(fnum,conn,fname,share_mode,3,unixmode, oplock_request,&rmode,NULL); if (!fsp->open) @@ -1326,7 +1290,7 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) } size = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); + fmode = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { @@ -1338,14 +1302,14 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,7,0,True); SSVAL(outbuf,smb_vwv0,fnum); SSVAL(outbuf,smb_vwv1,fmode); - if(lp_dos_filetime_resolution(SNUM(cnum)) ) + if(lp_dos_filetime_resolution(SNUM(conn)) ) put_dos_date3(outbuf,smb_vwv2,mtime & ~1); else put_dos_date3(outbuf,smb_vwv2,mtime); SIVAL(outbuf,smb_vwv4,size); SSVAL(outbuf,smb_vwv6,rmode); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; } @@ -1358,10 +1322,9 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to an open and X ****************************************************************************/ -int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; - int cnum = SVAL(inbuf,smb_tid); int fnum = -1; int smb_mode = SVAL(inbuf,smb_vwv3); int smb_attr = SVAL(inbuf,smb_vwv5); @@ -1384,13 +1347,13 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) files_struct *fsp; /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(cnum)) - return reply_open_pipe_and_X(inbuf,outbuf,length,bufsize); + if (IS_IPC(conn)) + return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize); /* XXXX we need to handle passed times, sattr and flags */ pstrcpy(fname,smb_buf(inbuf)); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); fnum = find_free_file(); if (fnum < 0) @@ -1398,7 +1361,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) fsp = &Files[fnum]; - if (!check_name(fname,cnum)) + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { @@ -1409,9 +1372,9 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) return(UNIXERROR(ERRDOS,ERRnoaccess)); } - unixmode = unix_mode(cnum,smb_attr | aARCH); + unixmode = unix_mode(conn,smb_attr | aARCH); - open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, + open_file_shared(fnum,conn,fname,smb_mode,smb_ofun,unixmode, oplock_request, &rmode,&smb_action); if (!fsp->open) @@ -1431,7 +1394,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) } size = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); + fmode = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { close_file(fnum,False); @@ -1443,7 +1406,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) correct bit for extended oplock reply. */ - if (ex_oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) { smb_action |= EXTENDED_OPLOCK_GRANTED; } @@ -1456,7 +1419,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) correct bit for core oplock reply. */ - if (core_oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; } @@ -1467,7 +1430,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) set_message(outbuf,15,0,True); SSVAL(outbuf,smb_vwv2,fnum); SSVAL(outbuf,smb_vwv3,fmode); - if(lp_dos_filetime_resolution(SNUM(cnum)) ) + if(lp_dos_filetime_resolution(SNUM(conn)) ) put_dos_date3(outbuf,smb_vwv4,mtime & ~1); else put_dos_date3(outbuf,smb_vwv4,mtime); @@ -1484,7 +1447,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a SMBulogoffX ****************************************************************************/ -int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) +int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { uint16 vuid = SVAL(inbuf,smb_uid); user_struct *vuser = get_valid_user_struct(vuid); @@ -1521,10 +1484,10 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a mknew or a create ****************************************************************************/ -int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - int cnum,com; + int com; int fnum = -1; int outsize = 0; int createmode; @@ -1535,18 +1498,17 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) int oplock_request = CORE_OPLOCK_REQUEST(inbuf); com = SVAL(inbuf,smb_com); - cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); pstrcpy(fname,smb_buf(inbuf)+1); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); if (createmode & aVOLID) { DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname)); } - unixmode = unix_mode(cnum,createmode); + unixmode = unix_mode(conn,createmode); fnum = find_free_file(); if (fnum < 0) @@ -1554,7 +1516,7 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) fsp = &Files[fnum]; - if (!check_name(fname,cnum)) + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { @@ -1577,7 +1539,7 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) } /* Open file in dos compatibility share mode. */ - open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, + open_file_shared(fnum,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, oplock_request, NULL, NULL); if (!fsp->open) @@ -1594,7 +1556,7 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,fnum); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; } @@ -1602,8 +1564,8 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; DEBUG( 2, ( "new file %s\n", fname ) ); - DEBUG( 3, ( "mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n", - fname, fsp->fd_ptr->fd, fnum, cnum, createmode, unixmode ) ); + DEBUG( 3, ( "mknew %s fd=%d fnum=%d dmode=%d umode=%o\n", + fname, fsp->fd_ptr->fd, fnum, createmode, unixmode ) ); return(outsize); } @@ -1612,11 +1574,10 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a create temporary file ****************************************************************************/ -int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; pstring fname2; - int cnum; int fnum = -1; int outsize = 0; int createmode; @@ -1625,13 +1586,12 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); - cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); pstrcpy(fname,smb_buf(inbuf)+1); pstrcat(fname,"/TMXXXXXX"); - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); - unixmode = unix_mode(cnum,createmode); + unixmode = unix_mode(conn,createmode); fnum = find_free_file(); if (fnum < 0) @@ -1639,7 +1599,7 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) fsp = &Files[fnum]; - if (!check_name(fname,cnum)) + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { @@ -1654,7 +1614,7 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /* Open file in dos compatibility share mode. */ /* We should fail if file exists. */ - open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, + open_file_shared(fnum,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, oplock_request, NULL, NULL); if (!fsp->open) @@ -1673,7 +1633,7 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(smb_buf(outbuf),0) = 4; pstrcpy(smb_buf(outbuf) + 1,fname2); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; } @@ -1681,8 +1641,8 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; DEBUG( 2, ( "created temp file %s\n", fname2 ) ); - DEBUG( 3, ( "ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n", - fname2, fsp->fd_ptr->fd, fnum, cnum, createmode, unixmode ) ); + DEBUG( 3, ( "ctemp %s fd=%d fnum=%d dmode=%d umode=%o\n", + fname2, fsp->fd_ptr->fd, fnum, createmode, unixmode ) ); return(outsize); } @@ -1691,33 +1651,32 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /******************************************************************* check if a user is allowed to delete a file ********************************************************************/ -static BOOL can_delete(char *fname,int cnum,int dirtype) +static BOOL can_delete(char *fname,connection_struct *conn, int dirtype) { struct stat sbuf; int fmode; - if (!CAN_WRITE(cnum)) return(False); + if (!CAN_WRITE(conn)) return(False); if (sys_lstat(fname,&sbuf) != 0) return(False); - fmode = dos_mode(cnum,fname,&sbuf); + fmode = dos_mode(conn,fname,&sbuf); if (fmode & aDIR) return(False); - if (!lp_delete_readonly(SNUM(cnum))) { + if (!lp_delete_readonly(SNUM(conn))) { if (fmode & aRONLY) return(False); } if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) return(False); - if (!check_file_sharing(cnum,fname,False)) return(False); + if (!check_file_sharing(conn,fname,False)) return(False); return(True); } /**************************************************************************** reply to a unlink ****************************************************************************/ -int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; pstring name; - int cnum; int dirtype; pstring directory; pstring mask; @@ -1730,14 +1689,13 @@ int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) *directory = *mask = 0; - cnum = SVAL(inbuf,smb_tid); dirtype = SVAL(inbuf,smb_vwv0); pstrcpy(name,smb_buf(inbuf) + 1); DEBUG(3,("reply_unlink : %s\n",name)); - unix_convert(name,cnum,0,&bad_path); + unix_convert(name,conn,0,&bad_path); p = strrchr(name,'/'); if (!p) { @@ -1757,14 +1715,14 @@ int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if (!has_wild) { pstrcat(directory,"/"); pstrcat(directory,mask); - if (can_delete(directory,cnum,dirtype) && !sys_unlink(directory)) count++; + if (can_delete(directory,conn,dirtype) && !sys_unlink(directory)) count++; if (!count) exists = file_exist(directory,NULL); } else { void *dirptr = NULL; char *dname; - if (check_name(directory,cnum)) - dirptr = OpenDir(cnum, directory, True); + if (check_name(directory,conn)) + dirptr = OpenDir(conn, directory, True); /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then the pattern matches against the long name, otherwise the short name @@ -1787,7 +1745,7 @@ int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) error = ERRnoaccess; slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); - if (!can_delete(fname,cnum,dirtype)) continue; + if (!can_delete(fname,conn,dirtype)) continue; if (!sys_unlink(fname)) count++; DEBUG(3,("reply_unlink : doing unlink on %s\n",fname)); } @@ -1818,9 +1776,9 @@ int reply_unlink(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a readbraw (core+ protocol) ****************************************************************************/ -int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) +int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) { - int cnum,maxcount,mincount,fnum; + int maxcount,mincount,fnum; int nread = 0; uint32 startpos; char *header = outbuf; @@ -1843,7 +1801,6 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) return -1; } - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); startpos = IVAL(inbuf,smb_vwv1); @@ -1854,7 +1811,7 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) maxcount = MIN(65535,maxcount); maxcount = MAX(mincount,maxcount); - if (!FNUM_OK(fnum,cnum) || !Files[fnum].can_read) + 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); @@ -1866,11 +1823,11 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) fsp = &Files[fnum]; fd = fsp->fd_ptr->fd; - fname = fsp->name; + fname = fsp->fsp_name; } - if (!is_locked(fnum,cnum,maxcount,startpos, F_RDLCK)) + if (!is_locked(fnum,conn,maxcount,startpos, F_RDLCK)) { int size = fsp->size; int sizeneeded = startpos + maxcount; @@ -1889,8 +1846,8 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) if (nread < mincount) nread = 0; - DEBUG( 3, ( "readbraw fnum=%d cnum=%d start=%d max=%d min=%d nread=%d\n", - fnum, cnum, startpos, + DEBUG( 3, ( "readbraw fnum=%d start=%d max=%d min=%d nread=%d\n", + fnum, startpos, maxcount, mincount, nread ) ); #if UNSAFE_READRAW @@ -1930,9 +1887,9 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a lockread (core+ protocol) ****************************************************************************/ -int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) +int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) { - int cnum,fnum; + int fnum; int nread = -1; char *data; int outsize = 0; @@ -1940,10 +1897,9 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) int eclass; uint32 ecode; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_READ(fnum); CHECK_ERROR(fnum); @@ -1954,7 +1910,7 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fnum, cnum, numtoread, startpos, F_RDLCK, &eclass, &ecode)) + if(!do_lock( fnum, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) return (ERROR(eclass,ecode)); nread = read_file(fnum,data,startpos,numtoread); @@ -1967,8 +1923,8 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) SSVAL(outbuf,smb_vwv5,nread+3); SSVAL(smb_buf(outbuf),1,nread); - DEBUG( 3, ( "lockread fnum=%d cnum=%d num=%d nread=%d\n", - fnum, cnum, numtoread, nread ) ); + DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n", + fnum, numtoread, nread ) ); return(outsize); } @@ -1977,18 +1933,17 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz) /**************************************************************************** reply to a read ****************************************************************************/ -int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,numtoread,fnum; + int numtoread,fnum; int nread = 0; char *data; uint32 startpos; int outsize = 0; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_READ(fnum); CHECK_ERROR(fnum); @@ -1999,7 +1954,7 @@ int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if (is_locked(fnum,cnum,numtoread,startpos, F_RDLCK)) + if (is_locked(fnum,conn,numtoread,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); if (numtoread > 0) @@ -2014,8 +1969,8 @@ int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(smb_buf(outbuf),0) = 1; SSVAL(smb_buf(outbuf),1,nread); - DEBUG( 3, ( "read fnum=%d cnum=%d num=%d nread=%d\n", - fnum, cnum, numtoread, nread ) ); + DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", + fnum, numtoread, nread ) ); return(outsize); } @@ -2024,31 +1979,28 @@ int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a read and X ****************************************************************************/ -int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { int fnum = GETFNUM(inbuf,smb_vwv2); uint32 smb_offs = IVAL(inbuf,smb_vwv3); int smb_maxcnt = SVAL(inbuf,smb_vwv5); int smb_mincnt = SVAL(inbuf,smb_vwv6); - int cnum; int nread = -1; char *data; BOOL ok = False; - cnum = SVAL(inbuf,smb_tid); - /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(cnum)) + if (IS_IPC(conn)) return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_READ(fnum); CHECK_ERROR(fnum); set_message(outbuf,12,0,True); data = smb_buf(outbuf); - if (is_locked(fnum,cnum,smb_maxcnt,smb_offs, F_RDLCK)) + if (is_locked(fnum,conn,smb_maxcnt,smb_offs, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); nread = read_file(fnum,data,smb_offs,smb_maxcnt); ok = True; @@ -2060,9 +2012,8 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); SSVAL(smb_buf(outbuf),-2,nread); - DEBUG( 3, ( "readX fnum=%d cnum=%d min=%d max=%d nread=%d\n", - fnum, cnum, - smb_mincnt, smb_maxcnt, nread ) ); + DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n", + fnum, smb_mincnt, smb_maxcnt, nread ) ); chain_fnum = fnum; @@ -2073,22 +2024,21 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a writebraw (core+ or LANMAN1.0 protocol) ****************************************************************************/ -int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int nwritten=0; int total_written=0; int numtowrite=0; - int cnum,fnum; + int fnum; int outsize = 0; long startpos; char *data=NULL; BOOL write_through; int tcount; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); @@ -2110,17 +2060,17 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) CVAL(inbuf,smb_com) = SMBwritec; CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,cnum,tcount,startpos, F_WRLCK)) + if (is_locked(fnum,conn,tcount,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); if (seek_file(fnum,startpos) != startpos) - DEBUG(0,("couldn't seek to %d in writebraw\n",startpos)); + DEBUG(0,("couldn't seek to %ld in writebraw\n",startpos)); if (numtowrite>0) nwritten = write_file(fnum,data,numtowrite); - DEBUG( 3, ( "writebraw1 fnum=%d cnum=%d start=%d num=%d wrote=%d sync=%d\n", - fnum, cnum, startpos, numtowrite, nwritten, write_through ) ); + DEBUG(3,("writebraw1 fnum=%d start=%ld num=%d wrote=%d sync=%d\n", + fnum, startpos, numtowrite, nwritten, write_through)); if (nwritten < numtowrite) return(UNIXERROR(ERRHRD,ERRdiskfull)); @@ -2162,11 +2112,11 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) SSVAL(outbuf,smb_err,ERRdiskfull); } - if (lp_syncalways(SNUM(cnum)) || write_through) - sync_file(cnum,fnum); + if (lp_syncalways(SNUM(conn)) || write_through) + sync_file(conn,fnum); - DEBUG( 3, ( "writebraw2 fnum=%d cnum=%d start=%d num=%d wrote=%d\n", - fnum, cnum, startpos, numtowrite, total_written ) ); + DEBUG(3,("writebraw2 fnum=%d start=%ld num=%d wrote=%d\n", + fnum, startpos, numtowrite, total_written)); /* we won't return a status if write through is not selected - this follows what WfWg does */ @@ -2180,9 +2130,9 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a writeunlock (core+) ****************************************************************************/ -int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,fnum; + int fnum; int nwritten = -1; int outsize = 0; char *data; @@ -2190,10 +2140,9 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) int eclass; uint32 ecode; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); @@ -2201,7 +2150,7 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK)) + if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); @@ -2214,21 +2163,21 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) else nwritten = write_file(fnum,data,numtowrite); - if (lp_syncalways(SNUM(cnum))) - sync_file(cnum,fnum); + if (lp_syncalways(SNUM(conn))) + sync_file(conn,fnum); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); - if(!do_unlock(fnum, cnum, numtowrite, startpos, &eclass, &ecode)) + if(!do_unlock(fnum, conn, numtowrite, startpos, &eclass, &ecode)) return(ERROR(eclass,ecode)); outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,nwritten); - DEBUG( 3, ( "writeunlock fnum=%d cnum=%d num=%d wrote=%d\n", - fnum, cnum, numtowrite, nwritten ) ); + DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n", + fnum, numtowrite, nwritten ) ); return(outsize); } @@ -2237,18 +2186,17 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a write ****************************************************************************/ -int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) +int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize) { - int cnum,numtowrite,fnum; + int numtowrite,fnum; int nwritten = -1; int outsize = 0; int startpos; char *data; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); @@ -2256,7 +2204,7 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK)) + if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); @@ -2269,8 +2217,8 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) else nwritten = write_file(fnum,data,numtowrite); - if (lp_syncalways(SNUM(cnum))) - sync_file(cnum,fnum); + if (lp_syncalways(SNUM(conn))) + sync_file(conn,fnum); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2284,8 +2232,8 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) SSVAL(outbuf,smb_err,ERRdiskfull); } - DEBUG( 3, ( "%s write fnum=%d cnum=%d num=%d wrote=%d\n", - fnum, cnum, numtowrite, nwritten ) ); + DEBUG(3,("write fnum=%d num=%d wrote=%d\n", + fnum, numtowrite, nwritten)); return(outsize); } @@ -2294,26 +2242,23 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize) /**************************************************************************** reply to a write and X ****************************************************************************/ -int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) +int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { int fnum = GETFNUM(inbuf,smb_vwv2); uint32 smb_offs = IVAL(inbuf,smb_vwv3); int smb_dsize = SVAL(inbuf,smb_vwv10); int smb_doff = SVAL(inbuf,smb_vwv11); BOOL write_through = BITSETW(inbuf+smb_vwv7,0); - int cnum; int nwritten = -1; char *data; - cnum = SVAL(inbuf,smb_tid); - - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); data = smb_base(inbuf) + smb_doff; - if (is_locked(fnum,cnum,smb_dsize,smb_offs, F_WRLCK)) + if (is_locked(fnum,conn,smb_dsize,smb_offs, F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,smb_offs); @@ -2339,13 +2284,13 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(outbuf,smb_err,ERRdiskfull); } - DEBUG( 3, ( "%s writeX fnum=%d cnum=%d num=%d wrote=%d\n", - fnum, cnum, smb_dsize, nwritten ) ); + DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", + fnum, smb_dsize, nwritten)); chain_fnum = fnum; - if (lp_syncalways(SNUM(cnum)) || write_through) - sync_file(cnum,fnum); + if (lp_syncalways(SNUM(conn)) || write_through) + sync_file(conn,fnum); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -2354,19 +2299,18 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a lseek ****************************************************************************/ -int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,fnum; + int fnum; uint32 startpos; int32 res= -1; int mode,umode; int outsize = 0; files_struct *fsp; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); mode = SVAL(inbuf,smb_vwv1) & 3; @@ -2389,8 +2333,8 @@ int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,2,0,True); SIVALS(outbuf,smb_vwv0,res); - DEBUG( 3, ( "lseek fnum=%d cnum=%d ofs=%d mode=%d\n", - fnum, cnum, startpos, mode ) ); + DEBUG(3,("lseek fnum=%d ofs=%d mode=%d\n", + fnum, startpos, mode)); return(outsize); } @@ -2399,28 +2343,28 @@ int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a flush ****************************************************************************/ -int reply_flush(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum, fnum; + int fnum; int outsize = set_message(outbuf,0,0,True); - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); if (fnum != 0xFFFF) { - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); } - if (fnum == 0xFFFF) - { - int i; - for (i=0;i<MAX_FNUMS;i++) - if (OPEN_FNUM(i)) - sync_file(cnum,i); - } - else - sync_file(cnum,fnum); + if (fnum == 0xFFFF) { + int i; + for (i=0;i<MAX_FNUMS;i++) { + if (OPEN_FNUM(i)) { + sync_file(conn,i); + } + } + } else { + sync_file(conn,fnum); + } DEBUG( 3, ( "flush fnum=%d\n", fnum ) ); return(outsize); @@ -2430,187 +2374,185 @@ int reply_flush(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a exit ****************************************************************************/ -int reply_exit(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_exit(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "exit\n" ) ); + int outsize = set_message(outbuf,0,0,True); + DEBUG(3,("exit\n")); - return(outsize); + return(outsize); } /**************************************************************************** Reply to a close - has to deal with closing a directory opened by NT SMB's. ****************************************************************************/ - -int reply_close(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_close(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum,cnum; - int outsize = 0; - time_t mtime; - int32 eclass = 0, err = 0; - files_struct *fsp = NULL; - - outsize = set_message(outbuf,0,0,True); + int fnum; + int outsize = 0; + time_t mtime; + int32 eclass = 0, err = 0; + files_struct *fsp = NULL; - cnum = SVAL(inbuf,smb_tid); + outsize = set_message(outbuf,0,0,True); - /* If it's an IPC, pass off to the pipe handler. */ - if (IS_IPC(cnum)) - return reply_pipe_close(inbuf,outbuf); + /* If it's an IPC, pass off to the pipe handler. */ + if (IS_IPC(conn)) { + return reply_pipe_close(conn, inbuf,outbuf); + } - fnum = GETFNUM(inbuf,smb_vwv0); + fnum = GETFNUM(inbuf,smb_vwv0); - /* - * We can only use CHECK_FNUM if we know it's not a directory. - */ + /* + * We can only use CHECK_FNUM if we know it's not a directory. + */ - if(!(VALID_FNUM(fnum) && Files[fnum].open && Files[fnum].is_directory)) - CHECK_FNUM(fnum,cnum); + if(!(VALID_FNUM(fnum) && Files[fnum].open && Files[fnum].is_directory)) + CHECK_FNUM(fnum,conn); - fsp = &Files[fnum]; + fsp = &Files[fnum]; - if(HAS_CACHED_ERROR(fnum)) { - eclass = fsp->wbmpx_ptr->wr_errclass; - err = fsp->wbmpx_ptr->wr_error; - } - - if(fsp->is_directory) { - /* - * Special case - close NT SMB directory - * handle. - */ - DEBUG( 3, ( "close directory fnum=%d cnum=%d\n", - fnum, cnum ) ); - close_directory( fnum ); - } else { - /* - * Close ordinary file. - */ - mtime = make_unix_date3(inbuf+smb_vwv1); + if(HAS_CACHED_ERROR(fnum)) { + eclass = fsp->wbmpx_ptr->wr_errclass; + err = fsp->wbmpx_ptr->wr_error; + } - /* try and set the date */ - set_filetime(cnum, fsp->name,mtime); + if(fsp->is_directory) { + /* + * Special case - close NT SMB directory + * handle. + */ + DEBUG(3,("close directory fnum=%d\n", fnum)); + close_directory(fnum); + } else { + /* + * Close ordinary file. + */ + mtime = make_unix_date3(inbuf+smb_vwv1); + + /* try and set the date */ + set_filetime(conn, fsp->fsp_name,mtime); - DEBUG( 3, ( "close fd=%d fnum=%d cnum=%d (numopen=%d)\n", - fsp->fd_ptr->fd, fnum, cnum, - Connections[cnum].num_files_open ) ); + DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n", + fsp->fd_ptr->fd, fnum, + conn->num_files_open)); - close_file(fnum,True); - } + close_file(fnum,True); + } - /* We have a cached error */ - if(eclass || err) - return(ERROR(eclass,err)); + /* We have a cached error */ + if(eclass || err) + return(ERROR(eclass,err)); - return(outsize); + return(outsize); } /**************************************************************************** reply to a writeclose (Core+ protocol) ****************************************************************************/ -int reply_writeclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_writeclose(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,numtowrite,fnum; - int nwritten = -1; - int outsize = 0; - int startpos; - char *data; - time_t mtime; - - cnum = SVAL(inbuf,smb_tid); - fnum = GETFNUM(inbuf,smb_vwv0); - - CHECK_FNUM(fnum,cnum); - CHECK_WRITE(fnum); - CHECK_ERROR(fnum); - - 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,cnum,numtowrite,startpos, F_WRLCK)) - return(ERROR(ERRDOS,ERRlock)); + int numtowrite,fnum; + int nwritten = -1; + int outsize = 0; + int startpos; + char *data; + time_t mtime; + + fnum = GETFNUM(inbuf,smb_vwv0); + + CHECK_FNUM(fnum,conn); + CHECK_WRITE(fnum); + CHECK_ERROR(fnum); + + 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)) + return(ERROR(ERRDOS,ERRlock)); - seek_file(fnum,startpos); + seek_file(fnum,startpos); - nwritten = write_file(fnum,data,numtowrite); + nwritten = write_file(fnum,data,numtowrite); - set_filetime(cnum, Files[fnum].name,mtime); + set_filetime(conn, Files[fnum].fsp_name,mtime); - close_file(fnum,True); + close_file(fnum,True); - DEBUG( 3, ( "writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n", - fnum, cnum, numtowrite, nwritten, - Connections[cnum].num_files_open ) ); + DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n", + fnum, numtowrite, nwritten, + conn->num_files_open)); - if (nwritten <= 0) - return(UNIXERROR(ERRDOS,ERRnoaccess)); + if (nwritten <= 0) + return(UNIXERROR(ERRDOS,ERRnoaccess)); - outsize = set_message(outbuf,1,0,True); + outsize = set_message(outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,nwritten); - return(outsize); + SSVAL(outbuf,smb_vwv0,nwritten); + return(outsize); } /**************************************************************************** reply to a lock ****************************************************************************/ -int reply_lock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_lock(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum,cnum; - int outsize = set_message(outbuf,0,0,True); - uint32 count,offset; - int eclass; - uint32 ecode; + int fnum; + int outsize = set_message(outbuf,0,0,True); + uint32 count,offset; + int eclass; + uint32 ecode; - cnum = SVAL(inbuf,smb_tid); - fnum = GETFNUM(inbuf,smb_vwv0); + fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); - CHECK_ERROR(fnum); + CHECK_FNUM(fnum,conn); + CHECK_ERROR(fnum); - count = IVAL(inbuf,smb_vwv1); - offset = IVAL(inbuf,smb_vwv3); + count = IVAL(inbuf,smb_vwv1); + offset = IVAL(inbuf,smb_vwv3); - DEBUG( 3, ("lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n", - Files[fnum].fd_ptr->fd, fnum, cnum, offset, count ) ); + DEBUG(3,("lock fd=%d fnum=%d ofs=%d cnt=%d\n", + Files[fnum].fd_ptr->fd, fnum, offset, count)); - if(!do_lock( fnum, cnum, count, offset, F_WRLCK, &eclass, &ecode)) - return (ERROR(eclass,ecode)); + if (!do_lock(fnum, conn, count, offset, F_WRLCK, &eclass, &ecode)) + return (ERROR(eclass,ecode)); - return(outsize); + return(outsize); } /**************************************************************************** reply to a unlock ****************************************************************************/ -int reply_unlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum,cnum; + int fnum; int outsize = set_message(outbuf,0,0,True); uint32 count,offset; int eclass; uint32 ecode; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); count = IVAL(inbuf,smb_vwv1); offset = IVAL(inbuf,smb_vwv3); - if(!do_unlock(fnum, cnum, count, offset, &eclass, &ecode)) + if(!do_unlock(fnum, conn, count, offset, &eclass, &ecode)) return (ERROR(eclass,ecode)); - DEBUG( 3, ( "unlock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n", - Files[fnum].fd_ptr->fd, fnum, cnum, offset, count ) ); + DEBUG( 3, ( "unlock fd=%d fnum=%d ofs=%d cnt=%d\n", + Files[fnum].fd_ptr->fd, fnum, offset, count ) ); return(outsize); } @@ -2619,27 +2561,24 @@ int reply_unlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a tdis ****************************************************************************/ -int reply_tdis(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_tdis(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum; - int outsize = set_message(outbuf,0,0,True); - uint16 vuid; + int outsize = set_message(outbuf,0,0,True); + uint16 vuid; - cnum = SVAL(inbuf,smb_tid); - vuid = SVAL(inbuf,smb_uid); + vuid = SVAL(inbuf,smb_uid); - if (!OPEN_CNUM(cnum)) { - DEBUG(4,("Invalid cnum in tdis (%d)\n",cnum)); - return(ERROR(ERRSRV,ERRinvnid)); - } + if (!conn) { + DEBUG(4,("Invalid connection in tdis\n")); + return(ERROR(ERRSRV,ERRinvnid)); + } - Connections[cnum].used = False; + conn->used = False; - close_cnum(cnum,vuid); + close_cnum(conn,vuid); - DEBUG( 3, ( "tdis cnum=%d\n", cnum ) ); - - return outsize; + return outsize; } @@ -2647,261 +2586,217 @@ int reply_tdis(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a echo ****************************************************************************/ -int reply_echo(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_echo(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum; - int smb_reverb = SVAL(inbuf,smb_vwv0); - int seq_num; - int data_len = smb_buflen(inbuf); - int outsize = set_message(outbuf,1,data_len,True); - - cnum = SVAL(inbuf,smb_tid); - - /* According to the latest CIFS spec we shouldn't - care what the TID is. - */ - -#if 0 - if (cnum != 0xFFFF && !OPEN_CNUM(cnum)) - { - DEBUG(4,("Invalid cnum in echo (%d)\n",cnum)); - return(ERROR(ERRSRV,ERRinvnid)); - } -#endif + int smb_reverb = SVAL(inbuf,smb_vwv0); + int seq_num; + int data_len = smb_buflen(inbuf); + int outsize = set_message(outbuf,1,data_len,True); + + /* copy any incoming data back out */ + if (data_len > 0) + memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len); - /* copy any incoming data back out */ - if (data_len > 0) - memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len); + if (smb_reverb > 100) { + DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb)); + smb_reverb = 100; + } - if (smb_reverb > 100) - { - DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb)); - smb_reverb = 100; - } + for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) { + SSVAL(outbuf,smb_vwv0,seq_num); - for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) - { - SSVAL(outbuf,smb_vwv0,seq_num); + smb_setlen(outbuf,outsize - 4); - smb_setlen(outbuf,outsize - 4); - - send_smb(Client,outbuf); - } + send_smb(Client,outbuf); + } - DEBUG( 3, ( "echo %d times cnum=%d\n", smb_reverb, cnum ) ); + DEBUG(3,("echo %d times\n", smb_reverb)); - return -1; + return -1; } /**************************************************************************** reply to a printopen ****************************************************************************/ -int reply_printopen(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_printopen(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - pstring fname; - pstring fname2; - int cnum; - int fnum = -1; - int outsize = 0; - files_struct *fsp; - - *fname = *fname2 = 0; - - cnum = SVAL(inbuf,smb_tid); - - if (!CAN_PRINT(cnum)) - return(ERROR(ERRDOS,ERRnoaccess)); - - { - pstring s; - char *p; - pstrcpy(s,smb_buf(inbuf)+1); - p = s; - while (*p) - { - if (!(isalnum(*p) || strchr("._-",*p))) - *p = 'X'; - p++; - } + pstring fname; + pstring fname2; + int fnum = -1; + int outsize = 0; + files_struct *fsp; + + *fname = *fname2 = 0; + + if (!CAN_PRINT(conn)) + return(ERROR(ERRDOS,ERRnoaccess)); - if (strlen(s) > 10) s[10] = 0; + { + pstring s; + char *p; + pstrcpy(s,smb_buf(inbuf)+1); + p = s; + while (*p) { + if (!(isalnum(*p) || strchr("._-",*p))) + *p = 'X'; + p++; + } - slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s); - } + if (strlen(s) > 10) s[10] = 0; - fnum = find_free_file(); - if (fnum < 0) - return(ERROR(ERRSRV,ERRnofids)); + slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s); + } - fsp = &Files[fnum]; + fnum = find_free_file(); + if (fnum < 0) + return(ERROR(ERRSRV,ERRnofids)); - pstrcpy(fname2,(char *)mktemp(fname)); + fsp = &Files[fnum]; + + pstrcpy(fname2,(char *)mktemp(fname)); - if (!check_name(fname2,cnum)) { - fsp->reserved = False; - return(ERROR(ERRDOS,ERRnoaccess)); - } + if (!check_name(fname2,conn)) { + fsp->reserved = False; + return(ERROR(ERRDOS,ERRnoaccess)); + } - /* Open for exclusive use, write only. */ - open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), - 0, NULL, NULL); + /* Open for exclusive use, write only. */ + open_file_shared(fnum,conn,fname2, + (DENY_ALL<<4)|1, 0x12, unix_mode(conn,0), + 0, NULL, NULL); - if (!fsp->open) { - fsp->reserved = False; - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } + if (!fsp->open) { + fsp->reserved = False; + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } - /* force it to be a print file */ - fsp->print_file = True; + /* force it to be a print file */ + fsp->print_file = True; - outsize = set_message(outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,fnum); + outsize = set_message(outbuf,1,0,True); + SSVAL(outbuf,smb_vwv0,fnum); - DEBUG( 3, ("openprint %s fd=%d fnum=%d cnum=%d\n", - fname2, fsp->fd_ptr->fd, fnum, cnum ) ); + DEBUG(3,("openprint %s fd=%d fnum=%d\n", + fname2, fsp->fd_ptr->fd, fnum)); - return(outsize); + return(outsize); } /**************************************************************************** reply to a printclose ****************************************************************************/ -int reply_printclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_printclose(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int fnum,cnum; - int outsize = set_message(outbuf,0,0,True); + int fnum; + int outsize = set_message(outbuf,0,0,True); - cnum = SVAL(inbuf,smb_tid); - fnum = GETFNUM(inbuf,smb_vwv0); + fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); - CHECK_ERROR(fnum); + CHECK_FNUM(fnum,conn); + CHECK_ERROR(fnum); - if (!CAN_PRINT(cnum)) - return(ERROR(ERRDOS,ERRnoaccess)); + if (!CAN_PRINT(conn)) + return(ERROR(ERRDOS,ERRnoaccess)); - DEBUG( 3, ( "printclose fd=%d fnum=%d cnum=%d\n", - Files[fnum].fd_ptr->fd,fnum,cnum)); + DEBUG(3,("printclose fd=%d fnum=%d\n", + Files[fnum].fd_ptr->fd,fnum)); - close_file(fnum,True); + close_file(fnum,True); - return(outsize); + return(outsize); } /**************************************************************************** reply to a printqueue ****************************************************************************/ -int reply_printqueue(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_printqueue(connection_struct *conn, + char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum; - int outsize = set_message(outbuf,2,3,True); - int max_count = SVAL(inbuf,smb_vwv0); - int start_index = SVAL(inbuf,smb_vwv1); - uint16 vuid; - - cnum = SVAL(inbuf,smb_tid); - vuid = SVAL(inbuf,smb_uid); - -/* allow checking the queue for anyone */ -#if 0 - if (!CAN_PRINT(cnum)) - return(ERROR(ERRDOS,ERRnoaccess)); -#endif - - SSVAL(outbuf,smb_vwv0,0); - SSVAL(outbuf,smb_vwv1,0); - CVAL(smb_buf(outbuf),0) = 1; - SSVAL(smb_buf(outbuf),1,0); + int outsize = set_message(outbuf,2,3,True); + int max_count = SVAL(inbuf,smb_vwv0); + int start_index = SVAL(inbuf,smb_vwv1); + uint16 vuid; + + vuid = SVAL(inbuf,smb_uid); + + /* we used to allow the client to get the cnum wrong, but that + is really quite gross and only worked when there was only + one printer - I think we should now only accept it if they + get it right (tridge) */ + if (!CAN_PRINT(conn)) + return(ERROR(ERRDOS,ERRnoaccess)); + + SSVAL(outbuf,smb_vwv0,0); + SSVAL(outbuf,smb_vwv1,0); + CVAL(smb_buf(outbuf),0) = 1; + SSVAL(smb_buf(outbuf),1,0); - DEBUG( 3, ( "printqueue cnum=%d start_index=%d max_count=%d\n", - cnum, start_index, max_count ) ); - - if (!OPEN_CNUM(cnum) || !Connections[cnum].printer) - { - int i; - cnum = -1; - - for (i=0;i<MAX_CONNECTIONS;i++) - if (CAN_PRINT(i) && Connections[i].printer) - cnum = i; - - if (cnum == -1) - for (i=0;i<MAX_CONNECTIONS;i++) - if (OPEN_CNUM(i)) - cnum = i; - - if (!OPEN_CNUM(cnum)) - return(ERROR(ERRSRV,ERRinvnid)); - - DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum)); - } - - if (!become_user(&Connections[cnum], cnum, vuid)) - return(ERROR(ERRSRV,ERRinvnid)); - - { - print_queue_struct *queue = NULL; - char *p = smb_buf(outbuf) + 3; - int count = get_printqueue(SNUM(cnum),cnum,&queue,NULL); - int num_to_get = ABS(max_count); - int first = (max_count>0?start_index:start_index+max_count+1); - int i; + DEBUG(3,("printqueue start_index=%d max_count=%d\n", + start_index, max_count)); - if (first >= count) - num_to_get = 0; - else - num_to_get = MIN(num_to_get,count-first); + { + print_queue_struct *queue = NULL; + char *p = smb_buf(outbuf) + 3; + int count = get_printqueue(SNUM(conn), conn,&queue,NULL); + int num_to_get = ABS(max_count); + int first = (max_count>0?start_index:start_index+max_count+1); + int i; + + if (first >= count) + num_to_get = 0; + else + num_to_get = MIN(num_to_get,count-first); - for (i=first;i<first+num_to_get;i++) - { - put_dos_date2(p,0,queue[i].time); - CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3); - SSVAL(p,5,printjob_encode(SNUM(cnum), queue[i].job)); - SIVAL(p,7,queue[i].size); - CVAL(p,11) = 0; - StrnCpy(p+12,queue[i].user,16); - p += 28; - } + for (i=first;i<first+num_to_get;i++) { + put_dos_date2(p,0,queue[i].time); + CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3); + SSVAL(p,5,printjob_encode(SNUM(conn), + queue[i].job)); + SIVAL(p,7,queue[i].size); + CVAL(p,11) = 0; + StrnCpy(p+12,queue[i].user,16); + p += 28; + } - if (count > 0) - { - outsize = set_message(outbuf,2,28*count+3,False); - SSVAL(outbuf,smb_vwv0,count); - SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1)); - CVAL(smb_buf(outbuf),0) = 1; - SSVAL(smb_buf(outbuf),1,28*count); - } + if (count > 0) { + outsize = set_message(outbuf,2,28*count+3,False); + SSVAL(outbuf,smb_vwv0,count); + SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1)); + CVAL(smb_buf(outbuf),0) = 1; + SSVAL(smb_buf(outbuf),1,28*count); + } - if (queue) free(queue); + if (queue) free(queue); - DEBUG(3,("%d entries returned in queue\n",count)); - } + DEBUG(3,("%d entries returned in queue\n",count)); + } - return(outsize); + return(outsize); } /**************************************************************************** reply to a printwrite ****************************************************************************/ -int reply_printwrite(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,numtowrite,fnum; + int numtowrite,fnum; int outsize = set_message(outbuf,0,0,True); char *data; - cnum = SVAL(inbuf,smb_tid); - - if (!CAN_PRINT(cnum)) + if (!CAN_PRINT(conn)) return(ERROR(ERRDOS,ERRnoaccess)); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); @@ -2911,7 +2806,7 @@ int reply_printwrite(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) if (write_file(fnum,data,numtowrite) != numtowrite) return(UNIXERROR(ERRDOS,ERRnoaccess)); - DEBUG( 3, ( "printwrite fnum=%d cnum=%d num=%d\n", fnum, cnum, numtowrite ) ); + DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fnum, numtowrite ) ); return(outsize); } @@ -2920,19 +2815,17 @@ int reply_printwrite(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a mkdir ****************************************************************************/ -int reply_mkdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring directory; - int cnum; int outsize,ret= -1; BOOL bad_path = False; pstrcpy(directory,smb_buf(inbuf) + 1); - cnum = SVAL(inbuf,smb_tid); - unix_convert(directory,cnum,0,&bad_path); + unix_convert(directory,conn,0,&bad_path); - if (check_name(directory,cnum)) - ret = sys_mkdir(directory,unix_mode(cnum,aDIR)); + if (check_name(directory, conn)) + ret = sys_mkdir(directory,unix_mode(conn,aDIR)); if (ret < 0) { @@ -2946,7 +2839,7 @@ int reply_mkdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "mkdir %s cnum=%d ret=%d\n", directory, cnum, ret ) ); + DEBUG( 3, ( "mkdir %s ret=%d\n", directory, ret ) ); return(outsize); } @@ -2959,7 +2852,7 @@ static BOOL recursive_rmdir(char *directory) { char *dname = NULL; BOOL ret = False; - void *dirptr = OpenDir(-1, directory, False); + void *dirptr = OpenDir(NULL, directory, False); if(dirptr == NULL) return True; @@ -3015,24 +2908,22 @@ static BOOL recursive_rmdir(char *directory) /**************************************************************************** reply to a rmdir ****************************************************************************/ -int reply_rmdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring directory; - int cnum; int outsize = 0; BOOL ok = False; BOOL bad_path = False; - cnum = SVAL(inbuf,smb_tid); pstrcpy(directory,smb_buf(inbuf) + 1); - unix_convert(directory,cnum,0,&bad_path); + unix_convert(directory,conn, NULL,&bad_path); - if (check_name(directory,cnum)) + if (check_name(directory,conn)) { dptr_closepath(directory,SVAL(inbuf,smb_pid)); ok = (sys_rmdir(directory) == 0); - if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(cnum))) + if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn))) { /* Check to see if the only thing in this directory are vetoed files/directories. If so then delete them and @@ -3040,7 +2931,7 @@ int reply_rmdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) do a recursive delete) then fail the rmdir. */ BOOL all_veto_files = True; char *dname; - void *dirptr = OpenDir(cnum, directory, False); + void *dirptr = OpenDir(conn, directory, False); if(dirptr != NULL) { @@ -3049,7 +2940,7 @@ int reply_rmdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) continue; - if(!IS_VETO_PATH(cnum, dname)) + if(!IS_VETO_PATH(conn, dname)) { all_veto_files = False; break; @@ -3080,7 +2971,7 @@ int reply_rmdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) break; if(st.st_mode & S_IFDIR) { - if(lp_recursive_veto_delete(SNUM(cnum))) + if(lp_recursive_veto_delete(SNUM(conn))) { if(recursive_rmdir(fullname) != 0) break; @@ -3192,14 +3083,14 @@ static BOOL resolve_wildcards(char *name1,char *name2) /******************************************************************* check if a user is allowed to rename a file ********************************************************************/ -static BOOL can_rename(char *fname,int cnum) +static BOOL can_rename(char *fname,connection_struct *conn) { struct stat sbuf; - if (!CAN_WRITE(cnum)) return(False); + if (!CAN_WRITE(conn)) return(False); if (sys_lstat(fname,&sbuf) != 0) return(False); - if (!check_file_sharing(cnum,fname,True)) return(False); + if (!check_file_sharing(conn,fname,True)) return(False); return(True); } @@ -3208,204 +3099,205 @@ static BOOL can_rename(char *fname,int cnum) The guts of the rename command, split out so it may be called by the NT SMB code. ****************************************************************************/ - -int rename_internals(char *inbuf, char *outbuf, char *name, char *newname, BOOL replace_if_exists) +int rename_internals(connection_struct *conn, + char *inbuf, char *outbuf, char *name, + char *newname, BOOL replace_if_exists) { - int cnum; - pstring directory; - pstring mask; - pstring newname_last_component; - char *p; - BOOL has_wild; - BOOL bad_path1 = False; - BOOL bad_path2 = False; - int count=0; - int error = ERRnoaccess; - BOOL exists=False; - - cnum = SVAL(inbuf,smb_tid); - - *directory = *mask = 0; - - unix_convert(name,cnum,0,&bad_path1); - unix_convert(newname,cnum,newname_last_component,&bad_path2); - - /* - * Split the old name into directory and last component - * strings. Note that unix_convert may have stripped off a - * leading ./ from both name and newname if the rename is - * at the root of the share. We need to make sure either both - * name and newname contain a / character or neither of them do - * as this is checked in resolve_wildcards(). - */ - - p = strrchr(name,'/'); - if (!p) { - pstrcpy(directory,"."); - pstrcpy(mask,name); - } else { - *p = 0; - pstrcpy(directory,name); - pstrcpy(mask,p+1); - *p = '/'; /* Replace needed for exceptional test below. */ - } - - if (is_mangled(mask)) - check_mangled_cache( mask ); - - has_wild = strchr(mask,'*') || strchr(mask,'?'); - - if (!has_wild) { - /* - * No wildcards - just process the one file. - */ - BOOL is_short_name = is_8_3(name, True); - - /* Add a terminating '/' to the directory name. */ - pstrcat(directory,"/"); - pstrcat(directory,mask); + pstring directory; + pstring mask; + pstring newname_last_component; + char *p; + BOOL has_wild; + BOOL bad_path1 = False; + BOOL bad_path2 = False; + int count=0; + int error = ERRnoaccess; + BOOL exists=False; + + *directory = *mask = 0; + + unix_convert(name,conn,0,&bad_path1); + unix_convert(newname,conn,newname_last_component,&bad_path2); + + /* + * Split the old name into directory and last component + * strings. Note that unix_convert may have stripped off a + * leading ./ from both name and newname if the rename is + * at the root of the share. We need to make sure either both + * name and newname contain a / character or neither of them do + * as this is checked in resolve_wildcards(). + */ + + p = strrchr(name,'/'); + if (!p) { + pstrcpy(directory,"."); + pstrcpy(mask,name); + } else { + *p = 0; + pstrcpy(directory,name); + pstrcpy(mask,p+1); + *p = '/'; /* Replace needed for exceptional test below. */ + } - /* Ensure newname contains a '/' also */ - if(strrchr(newname,'/') == 0) { - pstring tmpstr; + if (is_mangled(mask)) + check_mangled_cache( mask ); - pstrcpy(tmpstr, "./"); - pstrcat(tmpstr, newname); - pstrcpy(newname, tmpstr); - } - - DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", - case_sensitive, case_preserve, short_case_preserve, directory, - newname, newname_last_component, is_short_name)); + has_wild = strchr(mask,'*') || strchr(mask,'?'); - /* - * Check for special case with case preserving and not - * case sensitive, if directory and newname are identical, - * and the old last component differs from the original - * last component only by case, then we should allow - * the rename (user is trying to change the case of the - * filename). - */ - if((case_sensitive == False) && ( ((case_preserve == True) && (is_short_name == False)) || - ((short_case_preserve == True) && (is_short_name == True))) && - strcsequal(directory, newname)) { - pstring newname_modified_last_component; - - /* - * Get the last component of the modified name. - * Note that we guarantee that newname contains a '/' - * character above. - */ - p = strrchr(newname,'/'); - pstrcpy(newname_modified_last_component,p+1); + if (!has_wild) { + /* + * No wildcards - just process the one file. + */ + BOOL is_short_name = is_8_3(name, True); - if(strcsequal(newname_modified_last_component, - newname_last_component) == False) { - /* - * Replace the modified last component with - * the original. - */ - pstrcpy(p+1, newname_last_component); - } - } - - if(replace_if_exists) { - /* - * NT SMB specific flag - rename can overwrite - * file with the same name so don't check for - * file_exist(). - */ - if(resolve_wildcards(directory,newname) && - can_rename(directory,cnum) && - !sys_rename(directory,newname)) - count++; - } else { - if (resolve_wildcards(directory,newname) && - can_rename(directory,cnum) && - !file_exist(newname,NULL) && - !sys_rename(directory,newname)) - count++; - } + /* Add a terminating '/' to the directory name. */ + pstrcat(directory,"/"); + pstrcat(directory,mask); + + /* Ensure newname contains a '/' also */ + if(strrchr(newname,'/') == 0) { + pstring tmpstr; + + pstrcpy(tmpstr, "./"); + pstrcat(tmpstr, newname); + pstrcpy(newname, tmpstr); + } + + DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", + case_sensitive, case_preserve, short_case_preserve, directory, + newname, newname_last_component, is_short_name)); + + /* + * Check for special case with case preserving and not + * case sensitive, if directory and newname are identical, + * and the old last component differs from the original + * last component only by case, then we should allow + * the rename (user is trying to change the case of the + * filename). + */ + if((case_sensitive == False) && + (((case_preserve == True) && + (is_short_name == False)) || + ((short_case_preserve == True) && + (is_short_name == True))) && + strcsequal(directory, newname)) { + pstring newname_modified_last_component; + + /* + * Get the last component of the modified name. + * Note that we guarantee that newname contains a '/' + * character above. + */ + p = strrchr(newname,'/'); + pstrcpy(newname_modified_last_component,p+1); + + if(strcsequal(newname_modified_last_component, + newname_last_component) == False) { + /* + * Replace the modified last component with + * the original. + */ + pstrcpy(p+1, newname_last_component); + } + } + + if(replace_if_exists) { + /* + * NT SMB specific flag - rename can overwrite + * file with the same name so don't check for + * file_exist(). + */ + if(resolve_wildcards(directory,newname) && + can_rename(directory,conn) && + !sys_rename(directory,newname)) + count++; + } else { + if (resolve_wildcards(directory,newname) && + can_rename(directory,conn) && + !file_exist(newname,NULL) && + !sys_rename(directory,newname)) + count++; + } - DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed", + DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed", directory,newname)); - - if (!count) exists = file_exist(directory,NULL); - if (!count && exists && file_exist(newname,NULL)) { - exists = True; - error = 183; - } - } else { - /* - * Wildcards - process each file that matches. - */ - void *dirptr = NULL; - char *dname; - pstring destname; - - if (check_name(directory,cnum)) - dirptr = OpenDir(cnum, directory, True); - - if (dirptr) { - error = ERRbadfile; - - if (strequal(mask,"????????.???")) - pstrcpy(mask,"*"); - - while ((dname = ReadDirName(dirptr))) { - pstring fname; - pstrcpy(fname,dname); - - if(!mask_match(fname, mask, case_sensitive, False)) - continue; - - error = ERRnoaccess; - slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname); - if (!can_rename(fname,cnum)) { - DEBUG(6,("rename %s refused\n", fname)); - continue; - } - pstrcpy(destname,newname); - - if (!resolve_wildcards(fname,destname)) { - DEBUG(6,("resolve_wildcards %s %s failed\n", fname, destname)); - continue; - } - - if (!replace_if_exists && file_exist(destname,NULL)) { - DEBUG(6,("file_exist %s\n", destname)); - error = 183; - continue; - } - - if (!sys_rename(fname,destname)) - count++; - DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname)); - } - CloseDir(dirptr); - } - } - - if (count == 0) { - if (exists) - return(ERROR(ERRDOS,error)); - else { - if((errno == ENOENT) && (bad_path1 || bad_path2)) { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadpath; - } - return(UNIXERROR(ERRDOS,error)); - } - } - - return 0; + + if (!count) exists = file_exist(directory,NULL); + if (!count && exists && file_exist(newname,NULL)) { + exists = True; + error = 183; + } + } else { + /* + * Wildcards - process each file that matches. + */ + void *dirptr = NULL; + char *dname; + pstring destname; + + if (check_name(directory,conn)) + dirptr = OpenDir(conn, directory, True); + + if (dirptr) { + error = ERRbadfile; + + if (strequal(mask,"????????.???")) + pstrcpy(mask,"*"); + + while ((dname = ReadDirName(dirptr))) { + pstring fname; + pstrcpy(fname,dname); + + if(!mask_match(fname, mask, case_sensitive, False)) + continue; + + error = ERRnoaccess; + slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname); + if (!can_rename(fname,conn)) { + DEBUG(6,("rename %s refused\n", fname)); + continue; + } + pstrcpy(destname,newname); + + if (!resolve_wildcards(fname,destname)) { + DEBUG(6,("resolve_wildcards %s %s failed\n", fname, destname)); + continue; + } + + if (!replace_if_exists && file_exist(destname,NULL)) { + DEBUG(6,("file_exist %s\n", destname)); + error = 183; + continue; + } + + if (!sys_rename(fname,destname)) + count++; + DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname)); + } + CloseDir(dirptr); + } + } + + if (count == 0) { + if (exists) + return(ERROR(ERRDOS,error)); + else { + if((errno == ENOENT) && (bad_path1 || bad_path2)) { + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadpath; + } + return(UNIXERROR(ERRDOS,error)); + } + } + + return 0; } /**************************************************************************** Reply to a mv. ****************************************************************************/ -int reply_mv(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; pstring name; @@ -3416,7 +3308,7 @@ int reply_mv(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) DEBUG(3,("reply_mv : %s -> %s\n",name,newname)); - outsize = rename_internals(inbuf, outbuf, name, newname, False); + outsize = rename_internals(conn, inbuf, outbuf, name, newname, False); if(outsize == 0) outsize = set_message(outbuf,0,0,True); @@ -3426,7 +3318,7 @@ int reply_mv(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /******************************************************************* copy a file as part of a reply_copy ******************************************************************/ -static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, +static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, int count,BOOL target_is_directory) { int Access,action; @@ -3450,7 +3342,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, fnum1 = find_free_file(); if (fnum1<0) return(False); - open_file_shared(fnum1,cnum,src,(DENY_NONE<<4), + open_file_shared(fnum1,conn,src,(DENY_NONE<<4), 1,0,0,&Access,&action); if (!Files[fnum1].open) { @@ -3466,7 +3358,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, close_file(fnum1,False); return(False); } - open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1, + open_file_shared(fnum2,conn,dest,(DENY_NONE<<4)|1, ofun,st.st_mode,0,&Access,&action); if (!Files[fnum2].open) { @@ -3494,11 +3386,10 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, /**************************************************************************** reply to a file copy. ****************************************************************************/ -int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; pstring name; - int cnum; pstring directory; pstring mask,newname; char *p; @@ -3515,21 +3406,19 @@ int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) *directory = *mask = 0; - cnum = SVAL(inbuf,smb_tid); - pstrcpy(name,smb_buf(inbuf)); pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name)); DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); - if (tid2 != cnum) { + if (tid2 != conn->cnum) { /* can't currently handle inter share copies XXXX */ DEBUG(3,("Rejecting inter-share copy\n")); return(ERROR(ERRSRV,ERRinvdevice)); } - unix_convert(name,cnum,0,&bad_path1); - unix_convert(newname,cnum,0,&bad_path2); + unix_convert(name,conn,0,&bad_path1); + unix_convert(newname,conn,0,&bad_path2); target_is_directory = directory_exist(newname,NULL); @@ -3566,7 +3455,7 @@ int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) pstrcat(directory,"/"); pstrcat(directory,mask); if (resolve_wildcards(directory,newname) && - copy_file(directory,newname,cnum,ofun, + copy_file(directory,newname,conn,ofun, count,target_is_directory)) count++; if (!count) exists = file_exist(directory,NULL); } else { @@ -3574,8 +3463,8 @@ int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) char *dname; pstring destname; - if (check_name(directory,cnum)) - dirptr = OpenDir(cnum, directory, True); + if (check_name(directory,conn)) + dirptr = OpenDir(conn, directory, True); if (dirptr) { @@ -3595,7 +3484,7 @@ int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); pstrcpy(destname,newname); if (resolve_wildcards(fname,destname) && - copy_file(directory,newname,cnum,ofun, + copy_file(directory,newname,conn,ofun, count,target_is_directory)) count++; DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname)); } @@ -3628,38 +3517,36 @@ int reply_copy(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a setdir ****************************************************************************/ -int reply_setdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,snum; + int snum; int outsize = 0; BOOL ok = False; pstring newdir; - cnum = SVAL(inbuf,smb_tid); - - snum = Connections[cnum].service; + snum = SNUM(conn); if (!CAN_SETDIR(snum)) return(ERROR(ERRDOS,ERRnoaccess)); pstrcpy(newdir,smb_buf(inbuf) + 1); strlower(newdir); - if (strlen(newdir) == 0) - ok = True; - else - { - ok = directory_exist(newdir,NULL); - if (ok) - string_set(&Connections[cnum].connectpath,newdir); - } + if (strlen(newdir) == 0) { + ok = True; + } else { + ok = directory_exist(newdir,NULL); + if (ok) { + string_set(&conn->connectpath,newdir); + } + } if (!ok) - return(ERROR(ERRDOS,ERRbadpath)); + return(ERROR(ERRDOS,ERRbadpath)); outsize = set_message(outbuf,0,0,True); CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh); - - DEBUG( 3, ( "setdir %s cnum=%d\n", newdir, cnum ) ); + + DEBUG(3,("setdir %s\n", newdir)); return(outsize); } @@ -3668,7 +3555,7 @@ int reply_setdir(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a lockingX request ****************************************************************************/ -int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize) +int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { int fnum = GETFNUM(inbuf,smb_vwv2); unsigned char locktype = CVAL(inbuf,smb_vwv3); @@ -3679,15 +3566,12 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize) uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; int32 lock_timeout = IVAL(inbuf,smb_vwv4); - int cnum; int i; char *data; uint32 ecode=0, dummy2; int eclass=0, dummy1; - cnum = SVAL(inbuf,smb_tid); - - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); data = smb_buf(inbuf); @@ -3715,14 +3599,14 @@ no oplock granted on this file.\n", fnum)); } /* Remove the oplock flag from the sharemode. */ - lock_share_entry(fsp->cnum, dev, inode, &token); + lock_share_entry(fsp->conn, dev, inode, &token); if(remove_share_oplock( fnum, token)==False) { DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \ dev = %x, inode = %x\n", fnum, dev, inode)); - unlock_share_entry(fsp->cnum, dev, inode, token); + unlock_share_entry(fsp->conn, dev, inode, token); } else { - unlock_share_entry(fsp->cnum, dev, inode, token); + unlock_share_entry(fsp->conn, dev, inode, token); /* Clear the granted flag and return. */ fsp->granted_oplock = False; @@ -3745,7 +3629,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,cnum,count,offset,&eclass, &ecode)) + if(!do_unlock(fnum,conn,count,offset,&eclass, &ecode)) return ERROR(eclass,ecode); } @@ -3759,7 +3643,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,cnum,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) #if 0 /* JRATEST - blocking lock code. */ if((ecode == ERRlock) && (lock_timeout != 0)) { @@ -3780,15 +3664,15 @@ 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,cnum,count,offset,&dummy1,&dummy2); + do_unlock(fnum,conn,count,offset,&dummy1,&dummy2); } return ERROR(eclass,ecode); } set_message(outbuf,2,0,True); - DEBUG( 3, ( "lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n", - fnum, cnum, (unsigned int)locktype, num_locks, num_ulocks ) ); + DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", + fnum, (unsigned int)locktype, num_locks, num_ulocks ) ); chain_fnum = fnum; @@ -3799,9 +3683,9 @@ dev = %x, inode = %x\n", /**************************************************************************** reply to a SMBreadbmpx (read block multiplex) request ****************************************************************************/ -int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize) +int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - int cnum,fnum; + int fnum; int nread = -1; int total_read; char *data; @@ -3817,10 +3701,9 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize) outsize = set_message(outbuf,8,0,True); - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_READ(fnum); CHECK_ERROR(fnum); @@ -3837,7 +3720,7 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize) tcount = maxcount; total_read = 0; - if (is_locked(fnum,cnum,maxcount,startpos, F_RDLCK)) + if (is_locked(fnum,conn,maxcount,startpos, F_RDLCK)) return(ERROR(ERRDOS,ERRlock)); do @@ -3871,19 +3754,18 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** reply to a SMBwritebmpx (write block multiplex primary) request ****************************************************************************/ -int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,numtowrite,fnum; + int numtowrite,fnum; int nwritten = -1; int outsize = 0; uint32 startpos; int tcount, write_through, smb_doff; char *data; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); CHECK_ERROR(fnum); @@ -3899,14 +3781,14 @@ int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) not an SMBwritebmpx - set this up now so we don't forget */ CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fnum,cnum,tcount,startpos,F_WRLCK)) + if (is_locked(fnum,conn,tcount,startpos,F_WRLCK)) return(ERROR(ERRDOS,ERRlock)); seek_file(fnum,startpos); nwritten = write_file(fnum,data,numtowrite); - if(lp_syncalways(SNUM(cnum)) || write_through) - sync_file(cnum,fnum); + if(lp_syncalways(SNUM(conn)) || write_through) + sync_file(conn,fnum); if(nwritten < numtowrite) return(UNIXERROR(ERRHRD,ERRdiskfull)); @@ -3943,8 +3825,8 @@ int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */ - DEBUG( 3, ( "writebmpx fnum=%d cnum=%d num=%d wrote=%d\n", - fnum, cnum, numtowrite, nwritten ) ); + DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n", + fnum, numtowrite, nwritten ) ); if (write_through && tcount==nwritten) { /* we need to send both a primary and a secondary response */ @@ -3964,9 +3846,9 @@ int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a SMBwritebs (write block multiplex secondary) request ****************************************************************************/ -int reply_writebs(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,numtowrite,fnum; + int numtowrite,fnum; int nwritten = -1; int outsize = 0; int32 startpos; @@ -3975,9 +3857,8 @@ int reply_writebs(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) write_bmpx_struct *wbms; BOOL send_response = False; - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_WRITE(fnum); tcount = SVAL(inbuf,smb_vwv1); @@ -4006,8 +3887,8 @@ int reply_writebs(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) seek_file(fnum,startpos); nwritten = write_file(fnum,data,numtowrite); - if(lp_syncalways(SNUM(cnum)) || write_through) - sync_file(cnum,fnum); + if(lp_syncalways(SNUM(conn)) || write_through) + sync_file(conn,fnum); if (nwritten < numtowrite) { @@ -4045,18 +3926,17 @@ int reply_writebs(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a SMBsetattrE ****************************************************************************/ -int reply_setattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,fnum; + int fnum; struct utimbuf unix_times; int outsize = 0; outsize = set_message(outbuf,0,0,True); - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); /* Convert the DOS times into unix times. Ignore create @@ -4075,7 +3955,7 @@ int reply_setattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /* Ignore request */ if( DEBUGLVL( 3 ) ) { - dbgtext( "reply_setattrE fnum=%d cnum=%d ", fnum, cnum ); + dbgtext( "reply_setattrE fnum=%d ", fnum); dbgtext( "ignoring zero request - not setting timestamps of 0\n" ); } return(outsize); @@ -4087,11 +3967,11 @@ int reply_setattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) } /* Set the date on this file */ - if(file_utime(cnum, Files[fnum].name, &unix_times)) + if(file_utime(conn, Files[fnum].fsp_name, &unix_times)) return(ERROR(ERRDOS,ERRnoaccess)); - DEBUG( 3, ( "reply_setattrE fnum=%d cnum=%d actime=%d modtime=%d\n", - fnum, cnum, unix_times.actime, unix_times.modtime ) ); + DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n", + fnum, (int)unix_times.actime, (int)unix_times.modtime ) ); return(outsize); } @@ -4100,31 +3980,30 @@ int reply_setattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) /**************************************************************************** reply to a SMBgetattrE ****************************************************************************/ -int reply_getattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int cnum,fnum; + int fnum; struct stat sbuf; int outsize = 0; int mode; outsize = set_message(outbuf,11,0,True); - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); /* Do an fstat on this file */ if(fstat(Files[fnum].fd_ptr->fd, &sbuf)) return(UNIXERROR(ERRDOS,ERRnoaccess)); - mode = dos_mode(cnum,Files[fnum].name,&sbuf); + mode = dos_mode(conn,Files[fnum].fsp_name,&sbuf); /* Convert the times into dos times. Set create date to be last modify date as UNIX doesn't save this */ - put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime); put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime); if (mode & aDIR) @@ -4139,7 +4018,7 @@ int reply_getattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) } SSVAL(outbuf,smb_vwv10, mode); - DEBUG( 3, ( "reply_getattrE fnum=%d cnum=%d\n", fnum, cnum ) ); + DEBUG( 3, ( "reply_getattrE fnum=%d\n", fnum)); return(outsize); } 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 <David.Clerc@cui.unige.ch> 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;i<MAX_CONNECTIONS;i++) - if (OPEN_CNUM(i) && (SNUM(i) == snum)) - return(True); - return(False); + int i; + for (i=0;i<MAX_CONNECTIONS;i++) { + if (Connections[i].open && (Connections[i].service == snum)) { + return(True); + } + } + return(False); } /**************************************************************************** @@ -3377,50 +3367,50 @@ BOOL snum_used(int snum) **************************************************************************/ BOOL reload_services(BOOL test) { - BOOL ret; + BOOL ret; + + if (lp_loaded()) { + pstring fname; + pstrcpy(fname,lp_configfile()); + if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { + pstrcpy(servicesf,fname); + test = False; + } + } - if (lp_loaded()) - { - pstring fname; - pstrcpy(fname,lp_configfile()); - if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) - { - pstrcpy(servicesf,fname); - test = False; - } - } + reopen_logs(); - reopen_logs(); + if (test && !lp_file_list_changed()) + return(True); - if (test && !lp_file_list_changed()) - return(True); + lp_killunused(snum_used); - lp_killunused(snum_used); + ret = lp_load(servicesf,False,False,True); - ret = lp_load(servicesf,False,False,True); + load_printers(); - /* perhaps the config filename is now set */ - if (!test) - reload_services(True); + /* perhaps the config filename is now set */ + if (!test) + reload_services(True); - reopen_logs(); + reopen_logs(); - load_interfaces(); + load_interfaces(); - { - extern int Client; - if (Client != -1) { - set_socket_options(Client,"SO_KEEPALIVE"); - set_socket_options(Client,user_socket_options); - } - } + { + extern int Client; + if (Client != -1) { + set_socket_options(Client,"SO_KEEPALIVE"); + set_socket_options(Client,user_socket_options); + } + } - reset_mangled_cache(); + reset_mangled_cache(); - /* this forces service parameters to be flushed */ - become_service(-1,True); + /* this forces service parameters to be flushed */ + become_service(NULL,True); - return(ret); + return(ret); } @@ -3446,330 +3436,354 @@ static int sig_hup(void) return(0); } - /**************************************************************************** - make a connection to a service + 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. ****************************************************************************/ -int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid) +static connection_struct *find_free_connection(int hash) { - int cnum; - int snum; - struct passwd *pass = NULL; - connection_struct *pcon; - BOOL guest = False; - BOOL force = False; - extern int Client; + int i; + BOOL used=False; + hash = (hash % (MAX_CONNECTIONS-2))+1; - strlower(service); + again: - snum = find_service(service); - if (snum < 0) - { - extern int Client; - if (strequal(service,"IPC$")) - { - DEBUG( 3, ( "refusing IPC connection\n" ) ); - return( -3 ); + for (i=hash+1;i!=hash;) { + if (!Connections[i].open && Connections[i].used == used) { + DEBUG(3,("found free connection number %d\n",i)); + memset(&Connections[i], 0, sizeof(&Connections[i])); + Connections[i].cnum = i; + return &Connections[i]; + } + i++; + if (i == MAX_CONNECTIONS) { + i = 1; + } } - DEBUG( 0, ( "%s (%s) couldn't find service %s\n", - remote_machine, client_addr(Client), service ) ); - return(-2); - } - - if (strequal(service,HOMES_NAME)) - { - if (*user && Get_Pwnam(user,True)) - return(make_connection(user,user,password,pwlen,dev,vuid)); - - if(lp_security() != SEC_SHARE) - { - if (validated_username(vuid)) - { - pstrcpy(user,validated_username(vuid)); - return(make_connection(user,user,password,pwlen,dev,vuid)); - } - } - else - { - /* - * Security = share. Try with sesssetup_user as the username. - */ - if(*sesssetup_user) - { - pstrcpy(user,sesssetup_user); - return(make_connection(user,user,password,pwlen,dev,vuid)); - } - } - } + if (!used) { + used = !used; + goto again; + } - if (!lp_snum_ok(snum) || - !check_access(Client, lp_hostsallow(snum), lp_hostsdeny(snum))) { - return(-4); - } + DEBUG(1,("ERROR! Out of connection structures\n")); - /* you can only connect to the IPC$ service as an ipc device */ - if (strequal(service,"IPC$")) - pstrcpy(dev,"IPC"); + return NULL; +} - if (*dev == '?' || !*dev) - { - if (lp_print_ok(snum)) - pstrcpy(dev,"LPT1:"); - else - pstrcpy(dev,"A:"); - } - /* if the request is as a printer and you can't print then refuse */ - strupper(dev); - if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) { - DEBUG(1,("Attempt to connect to non-printer as a printer\n")); - return(-6); - } +/**************************************************************************** + make a connection to a service +****************************************************************************/ +connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode) +{ + int snum; + struct passwd *pass = NULL; + BOOL guest = False; + BOOL force = False; + extern int Client; + connection_struct *conn; + + strlower(service); + + snum = find_service(service); + if (snum < 0) { + extern int Client; + if (strequal(service,"IPC$")) { + DEBUG(3,("refusing IPC connection\n")); + *ecode = ERRnoipc; + return NULL; + } - /* lowercase the user name */ - strlower(user); + DEBUG(0,("%s (%s) couldn't find service %s\n", + remote_machine, client_addr(Client), service)); + *ecode = ERRinvnetname; + return NULL; + } - /* add it as a possible user name */ - add_session_user(service); + if (strequal(service,HOMES_NAME)) { + if (*user && Get_Pwnam(user,True)) + return(make_connection(user,user,password, + pwlen,dev,vuid,ecode)); + + if(lp_security() != SEC_SHARE) { + if (validated_username(vuid)) { + pstrcpy(user,validated_username(vuid)); + return(make_connection(user,user,password,pwlen,dev,vuid,ecode)); + } + } else { + /* Security = share. Try with sesssetup_user + * as the username. */ + if(*sesssetup_user) { + pstrcpy(user,sesssetup_user); + return(make_connection(user,user,password,pwlen,dev,vuid,ecode)); + } + } + } - /* shall we let them in? */ - if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) - { - DEBUG( 2, ( "Invalid username/password for %s\n", service ) ); - return(-1); - } - - cnum = find_free_connection( str_checksum(service) + str_checksum(user) ); - if (cnum < 0) - { - DEBUG( 0, ( "Couldn't find free connection.\n" ) ); - return(-1); - } + if (!lp_snum_ok(snum) || + !check_access(Client, + lp_hostsallow(snum), lp_hostsdeny(snum))) { + *ecode = ERRaccess; + return NULL; + } - pcon = &Connections[cnum]; - bzero((char *)pcon,sizeof(*pcon)); + /* you can only connect to the IPC$ service as an ipc device */ + if (strequal(service,"IPC$")) + pstrcpy(dev,"IPC"); + + if (*dev == '?' || !*dev) { + if (lp_print_ok(snum)) { + pstrcpy(dev,"LPT1:"); + } else { + pstrcpy(dev,"A:"); + } + } - /* find out some info about the user */ - pass = Get_Pwnam(user,True); + /* if the request is as a printer and you can't print then refuse */ + strupper(dev); + if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) { + DEBUG(1,("Attempt to connect to non-printer as a printer\n")); + *ecode = ERRinvdevice; + return NULL; + } - if (pass == NULL) - { - DEBUG( 0, ( "Couldn't find account %s\n", user ) ); - return(-7); - } + /* lowercase the user name */ + strlower(user); - pcon->read_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;i<MAX_FNUMS;i++) - if( Files[i].cnum == cnum && Files[i].open) { + if (Files[i].conn == conn && Files[i].open) { if(Files[i].is_directory) close_directory(i); else @@ -4307,69 +4288,66 @@ static void close_open_files(int cnum) /**************************************************************************** close a cnum ****************************************************************************/ -void close_cnum(int cnum, uint16 vuid) +void close_cnum(connection_struct *conn, uint16 vuid) { - extern int Client; - DirCacheFlush(SNUM(cnum)); + extern int Client; + DirCacheFlush(SNUM(conn)); - unbecome_user(); + unbecome_user(); - if (!OPEN_CNUM(cnum)) - { - DEBUG(0,("Can't close cnum %d\n",cnum)); - return; - } + if (!conn->open) { + 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;i<MAX_CONNECTIONS;i++) if (Connections[i].open) - close_cnum(i,(uint16)-1); + close_cnum(&Connections[i],(uint16)-1); #ifdef WITH_DFS if (dcelogin_atmost_once) { dfs_unlogin(); @@ -4450,42 +4429,6 @@ void exit_server(char *reason) exit(0); } -/**************************************************************************** -do some standard substitutions in a string -****************************************************************************/ -void standard_sub(int cnum,char *str) -{ - if (VALID_CNUM(cnum)) { - char *p, *s, *home; - - for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) { - switch (*(p+1)) { - case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL) - string_sub(p,"%H",home); - else - p += 2; - break; - case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break; - case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break; - case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break; - case 'u' : string_sub(p,"%u",Connections[cnum].user); break; - /* - * Patch from jkf@soton.ac.uk - * Left the %N (NIS server name) in standard_sub_basic as it - * is a feature for logon servers, hence uses the username. - * The %p (NIS server path) code is here as it is used - * instead of the default "path =" string in [homes] and so - * needs the service name, not the username. - */ - case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break; - case '\0' : p++; break; /* don't run off the end of the string */ - default : p+=2; break; - } - } - } - standard_sub_basic(str); -} - /* These flags determine some of the permissions required to do an operation @@ -4509,7 +4452,7 @@ struct smb_message_struct { int code; char *name; - int (*fn)(char *, char *, int, int); + int (*fn)(connection_struct *conn, char *, char *, int, int); int flags; #if PROFILING unsigned long time; @@ -4556,7 +4499,7 @@ struct smb_message_struct {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK }, {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK }, {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER}, - {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST}, + {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER}, {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER}, {SMBlock,"SMBlock",reply_lock,AS_USER}, {SMBunlock,"SMBunlock",reply_unlock,AS_USER}, @@ -4624,19 +4567,19 @@ return a string containing the function name of a SMB command ****************************************************************************/ char *smb_fn_name(int type) { - static char *unknown_name = "SMBunknown"; - static int num_smb_messages = - sizeof(smb_messages) / sizeof(struct smb_message_struct); - int match; + static char *unknown_name = "SMBunknown"; + static int num_smb_messages = + sizeof(smb_messages) / sizeof(struct smb_message_struct); + int match; - for (match=0;match<num_smb_messages;match++) - if (smb_messages[match].code == type) - break; + for (match=0;match<num_smb_messages;match++) + if (smb_messages[match].code == type) + break; - if (match == num_smb_messages) - return(unknown_name); + if (match == num_smb_messages) + return(unknown_name); - return(smb_messages[match].name); + return(smb_messages[match].name); } @@ -4706,6 +4649,12 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize static uint16 last_session_tag = UID_FIELD_INVALID; /* In share mode security we must ignore the vuid. */ uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); + connection_struct *conn = NULL; + + if (VALID_CNUM(cnum) && Connections[cnum].open) { + conn = &Connections[cnum]; + } + /* Ensure this value is replaced in the incoming packet. */ SSVAL(inbuf,smb_uid,session_tag); @@ -4718,7 +4667,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize * move it unless you know what you're doing... :-). * JRA. */ - if(session_tag != last_session_tag ) { + if (session_tag != last_session_tag) { user_struct *vuser = NULL; last_session_tag = session_tag; @@ -4733,7 +4682,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize unbecome_user(); /* does this protocol need to be run as the connected user? */ - if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) { + if ((flags & AS_USER) && !become_user(conn,session_tag)) { if (flags & AS_GUEST) flags &= ~AS_USER; else @@ -4746,16 +4695,19 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize flags &= ~AS_GUEST; /* does it need write permission? */ - if ((flags & NEED_WRITE) && !CAN_WRITE(cnum)) + if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) return(ERROR(ERRSRV,ERRaccess)); /* ipc services are limited */ - if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC)) + if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) { return(ERROR(ERRSRV,ERRaccess)); + } /* load service specific parameters */ - if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False)) + if (OPEN_CNUM(conn) && + !become_service(conn,(flags & AS_USER)?True:False)) { return(ERROR(ERRSRV,ERRaccess)); + } /* does this protocol need to be run as guest? */ if ((flags & AS_GUEST) && @@ -4766,7 +4718,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize last_inbuf = inbuf; - outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize); + outsize = smb_messages[match].fn(conn, inbuf,outbuf,size,bufsize); } else { @@ -5072,22 +5024,21 @@ static void process(void) } /* check for connection timeouts */ - for (i=0;i<MAX_CONNECTIONS;i++) - if (Connections[i].open) - { - /* close dirptrs on connections that are idle */ - if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT) - dptr_idlecnum(i); - - if (Connections[i].num_files_open > 0 || - (t-Connections[i].lastused)<deadtime) - allidle = False; - } + for (i=0;i<MAX_CONNECTIONS;i++) { + if (Connections[i].open) { + /* close dirptrs on connections that are idle */ + if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT) + dptr_idlecnum(&Connections[i]); + + if (Connections[i].num_files_open > 0 || + (t-Connections[i].lastused)<deadtime) + allidle = False; + } + } - if (allidle && num_connections_open>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<MAX_FNUMS;i++) { Files[i].open = False; - string_init(&Files[i].name,""); + string_init(&Files[i].fsp_name,""); } for (i=0;i<MAX_OPEN_FILES;i++) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index fc119307cd..07f0316c22 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -26,7 +26,6 @@ extern int DEBUGLEVEL; extern int Protocol; -extern connection_struct Connections[]; extern files_struct Files[]; extern BOOL case_sensitive; extern int Client; @@ -42,7 +41,7 @@ extern int global_oplock_break; HACK ! Always assumes smb_setup field is zero. ****************************************************************************/ static int send_trans2_replies(char *outbuf, int bufsize, char *params, - int paramsize, char *pdata, int datasize) + int paramsize, char *pdata, int datasize) { /* As we are using a protocol > LANMAN1 then the max_send variable must have been set in the sessetupX call. @@ -182,8 +181,9 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, /**************************************************************************** reply to a TRANSACT2_OPEN ****************************************************************************/ -static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, - char **pparams, char **ppdata) +static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, + int bufsize, + char **pparams, char **ppdata) { char *params = *pparams; int16 open_mode = SVAL(params, 2); @@ -211,12 +211,12 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, StrnCpy(fname,pname,namelen); - DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n", - fname,cnum,open_mode, open_attr, open_ofun, open_size)); + DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n", + fname,open_mode, open_attr, open_ofun, open_size)); /* XXXX we need to handle passed times, sattr and flags */ - unix_convert(fname,cnum,0,&bad_path); + unix_convert(fname,conn,0,&bad_path); fnum = find_free_file(); if (fnum < 0) @@ -224,7 +224,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, fsp = &Files[fnum]; - if (!check_name(fname,cnum)) + if (!check_name(fname,conn)) { if((errno == ENOENT) && bad_path) { @@ -235,9 +235,9 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - unixmode = unix_mode(cnum,open_attr | aARCH); + unixmode = unix_mode(conn,open_attr | aARCH); - open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode, + open_file_shared(fnum,conn,fname,open_mode,open_ofun,unixmode, oplock_request, &rmode,&smb_action); if (!fsp->open) @@ -257,7 +257,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, } size = sbuf.st_size; - fmode = dos_mode(cnum,fname,&sbuf); + fmode = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; inode = sbuf.st_ino; if (fmode & aDIR) { @@ -277,7 +277,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, SIVAL(params,8, size); SSVAL(params,12,rmode); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { + if (oplock_request && lp_fake_oplocks(SNUM(conn))) { smb_action |= EXTENDED_OPLOCK_GRANTED; } @@ -293,7 +293,8 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, /**************************************************************************** get a level dependent lanman2 dir entry. ****************************************************************************/ -static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level, +static int get_lanman2_dir_entry(connection_struct *conn, + char *path_mask,int dirtype,int info_level, int requires_resume_key, BOOL dont_descend,char **ppdata, char *base_data, int space_remaining, @@ -314,17 +315,17 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l uint32 size=0,len; uint32 mdate=0, adate=0, cdate=0; char *nameptr; - BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") || - strequal(Connections[cnum].dirpath,".") || - strequal(Connections[cnum].dirpath,"/")); + BOOL isrootdir = (strequal(conn->dirpath,"./") || + strequal(conn->dirpath,".") || + strequal(conn->dirpath,"/")); BOOL was_8_3; int nt_extmode; /* Used for NT connections instead of mode */ - BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/'); + BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); *fname = 0; *out_of_space = False; - if (!Connections[cnum].dirptr) + if (!conn->dirptr) return(False); p = strrchr(path_mask,'/'); @@ -341,8 +342,8 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l while (!found) { /* Needed if we run out of space */ - prev_dirpos = TellDir(Connections[cnum].dirptr); - dname = ReadDirName(Connections[cnum].dirptr); + prev_dirpos = TellDir(conn->dirptr); + dname = ReadDirName(conn->dirptr); /* * Due to bugs in NT client redirectors we are not using @@ -354,7 +355,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l reskey = 0; DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n", - Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr))); + (unsigned)conn->dirptr,TellDir(conn->dirptr))); if (!dname) return(False); @@ -372,7 +373,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if (isrootdir && isdots) continue; - pstrcpy(pathreal,Connections[cnum].dirpath); + pstrcpy(pathreal,conn->dirpath); if(needslash) pstrcat(pathreal,"/"); pstrcat(pathreal,dname); @@ -382,9 +383,9 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l continue; } - mode = dos_mode(cnum,pathreal,&sbuf); + mode = dos_mode(conn,pathreal,&sbuf); - if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) { + if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) { DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype)); continue; } @@ -392,7 +393,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l size = sbuf.st_size; mdate = sbuf.st_mtime; adate = sbuf.st_atime; - cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))); + cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); if(mode & aDIR) size = 0; @@ -402,7 +403,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l } } - name_map_mangle(fname,False,SNUM(cnum)); + name_map_mangle(fname,False,SNUM(conn)); p = pdata; nameptr = p; @@ -497,7 +498,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l SIVAL(p,0,0); p += 4; if (!was_8_3) { pstrcpy(p+2,fname); - if (!name_map_mangle(p+2,True,SNUM(cnum))) + if (!name_map_mangle(p+2,True,SNUM(conn))) (p+2)[12] = 0; } else *(p+2) = 0; @@ -562,7 +563,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if (PTR_DIFF(p,pdata) > space_remaining) { /* Move the dirptr back to prev_dirpos */ - SeekDir(Connections[cnum].dirptr, prev_dirpos); + SeekDir(conn->dirptr, prev_dirpos); *out_of_space = True; DEBUG(9,("get_lanman2_dir_entry: out of space\n")); return False; /* Not finished - just out of space */ @@ -605,8 +606,9 @@ void mask_convert( char *mask) /**************************************************************************** reply to a TRANS2_FINDFIRST ****************************************************************************/ -static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum, - char **pparams, char **ppdata) +static int call_trans2findfirst(connection_struct *conn, + char *inbuf, char *outbuf, int bufsize, + char **pparams, char **ppdata) { /* We must be careful here that we don't return more than the allowed number of data bytes. If this means returning fewer than @@ -661,8 +663,8 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum DEBUG(5,("path=%s\n",directory)); - unix_convert(directory,cnum,0,&bad_path); - if(!check_name(directory,cnum)) { + unix_convert(directory,conn,0,&bad_path); + if(!check_name(directory,conn)) { if((errno == ENOENT) && bad_path) { unix_ERR_class = ERRDOS; @@ -703,7 +705,7 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum if(params == NULL) return(ERROR(ERRDOS,ERRnomem)); - dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid)); + dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid)); if (dptr_num < 0) return(ERROR(ERRDOS,ERRbadfile)); @@ -742,8 +744,8 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum a different TRANS2 call. */ DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", - Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)))); - if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive)) + conn->dirpath,lp_dontdescend(SNUM(conn)))); + if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive)) dont_descend = True; p = pdata; @@ -763,7 +765,7 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum else { finished = - !get_lanman2_dir_entry(cnum,mask,dirtype,info_level, + !get_lanman2_dir_entry(conn,mask,dirtype,info_level, requires_resume_key,dont_descend, &p,pdata,space_remaining, &out_of_space, &last_name_off); @@ -807,9 +809,9 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum if ((! *directory) && dptr_path(dptr_num)) slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); - DEBUG( 4, ( "%s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n", + DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", smb_fn_name(CVAL(inbuf,smb_com)), - mask, directory, cnum, dirtype, numentries ) ); + mask, directory, dirtype, numentries ) ); return(-1); } @@ -818,8 +820,10 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum /**************************************************************************** reply to a TRANS2_FINDNEXT ****************************************************************************/ -static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2findnext(connection_struct *conn, + char *inbuf, char *outbuf, + int length, int bufsize, + char **pparams, char **ppdata) { /* We must be careful here that we don't return more than the allowed number of data bytes. If this means returning fewer than @@ -885,10 +889,10 @@ resume_key = %d resume name = %s continue=%d level = %d\n", return(ERROR(ERRDOS,ERRnomem)); /* Check that the dptr is valid */ - if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(dptr_num))) + if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) return(ERROR(ERRDOS,ERRnofiles)); - string_set(&Connections[cnum].dirpath,dptr_path(dptr_num)); + string_set(&conn->dirpath,dptr_path(dptr_num)); /* Get the wildcard mask from the dptr */ if((p = dptr_wcard(dptr_num))== NULL) { @@ -896,21 +900,21 @@ resume_key = %d resume name = %s continue=%d level = %d\n", return (ERROR(ERRDOS,ERRnofiles)); } pstrcpy(mask, p); - pstrcpy(directory,Connections[cnum].dirpath); + pstrcpy(directory,conn->dirpath); /* Get the attr mask from the dptr */ dirtype = dptr_attr(dptr_num); DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n", dptr_num, mask, dirtype, - Connections[cnum].dirptr, - TellDir(Connections[cnum].dirptr))); + (unsigned)conn->dirptr, + TellDir(conn->dirptr))); /* We don't need to check for VOL here as this is returned by a different TRANS2 call. */ - DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)))); - if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive)) + DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn)))); + if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive)) dont_descend = True; p = pdata; @@ -937,7 +941,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n", int current_pos, start_pos; char *dname; - void *dirptr = Connections[cnum].dirptr; + void *dirptr = conn->dirptr; start_pos = TellDir(dirptr); for(current_pos = start_pos; current_pos >= 0; current_pos--) { @@ -953,7 +957,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n", * here. */ - name_map_mangle( dname, False, SNUM(cnum)); + name_map_mangle( dname, False, SNUM(conn)); if(dname && strcsequal( resume_name, dname)) { @@ -980,7 +984,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n", * here. */ - name_map_mangle( dname, False, SNUM(cnum)); + name_map_mangle( dname, False, SNUM(conn)); if(strcsequal( resume_name, dname)) { @@ -1004,7 +1008,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n", else { finished = - !get_lanman2_dir_entry(cnum,mask,dirtype,info_level, + !get_lanman2_dir_entry(conn,mask,dirtype,info_level, requires_resume_key,dont_descend, &p,pdata,space_remaining, &out_of_space, &last_name_off); @@ -1038,9 +1042,9 @@ resume_key = %d resume name = %s continue=%d level = %d\n", if ((! *directory) && dptr_path(dptr_num)) slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); - DEBUG( 3, ( "%s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n", + DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", smb_fn_name(CVAL(inbuf,smb_com)), - mask, directory, cnum, dirtype, numentries ) ); + mask, directory, dirtype, numentries ) ); return(-1); } @@ -1048,18 +1052,20 @@ resume_key = %d resume name = %s continue=%d level = %d\n", /**************************************************************************** reply to a TRANS2_QFSINFO (query filesystem info) ****************************************************************************/ -static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2qfsinfo(connection_struct *conn, + char *inbuf, char *outbuf, + int length, int bufsize, + char **pparams, char **ppdata) { char *pdata = *ppdata; char *params = *pparams; uint16 info_level = SVAL(params,0); int data_len; struct stat st; - char *vname = volume_label(SNUM(cnum)); - int snum = SNUM(cnum); + char *vname = volume_label(SNUM(conn)); + int snum = SNUM(conn); - DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level)); + DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); if(sys_stat(".",&st)!=0) { DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); @@ -1081,7 +1087,7 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize SIVAL(pdata,l1_cUnitAvail,dfree); SSVAL(pdata,l1_cbSector,512); DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n", - bsize, st.st_dev, bsize/512, dsize, dfree, 512)); + bsize, (unsigned)st.st_dev, bsize/512, dsize, dfree, 512)); break; } case 2: @@ -1096,7 +1102,8 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); SCVAL(pdata,l2_vol_cch,volname_len); StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len); - DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len, + DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", + (unsigned)st.st_ctime, volname_len, pdata+l2_vol_szVolLabel)); break; } @@ -1159,15 +1166,17 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize /**************************************************************************** reply to a TRANS2_SETFSINFO (set filesystem info) ****************************************************************************/ -static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2setfsinfo(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, + char **pparams, char **ppdata) { /* Just say yes we did it - there is nothing that can be set here so it doesn't matter. */ int outsize; DEBUG(3,("call_trans2setfsinfo\n")); - if (!CAN_WRITE(cnum)) + if (!CAN_WRITE(conn)) return(ERROR(ERRSRV,ERRaccess)); outsize = set_message(outbuf,10,0,True); @@ -1180,8 +1189,9 @@ static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsi file name or file id). ****************************************************************************/ -static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, - int bufsize,int cnum, +static int call_trans2qfilepathinfo(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, char **pparams,char **ppdata, int total_data) { @@ -1203,10 +1213,10 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, int16 fnum = SVALS(params,0); info_level = SVAL(params,2); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); - fname = Files[fnum].name; + 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))); return(UNIXERROR(ERRDOS,ERRbadfid)); @@ -1217,8 +1227,8 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, info_level = SVAL(params,0); fname = &fname1[0]; pstrcpy(fname,¶ms[6]); - unix_convert(fname,cnum,0,&bad_path); - if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) { + unix_convert(fname,conn,0,&bad_path); + if (!check_name(fname,conn) || sys_stat(fname,&sbuf)) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); if((errno == ENOENT) && bad_path) { @@ -1240,7 +1250,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, else p++; l = strlen(p); - mode = dos_mode(cnum,fname,&sbuf); + mode = dos_mode(conn,fname,&sbuf); size = sbuf.st_size; if (mode & aDIR) size = 0; @@ -1261,7 +1271,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_INFO_STANDARD: case SMB_INFO_QUERY_EA_SIZE: data_size = (info_level==1?22:26); - put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ SIVAL(pdata,l1_cbFile,size); @@ -1272,7 +1282,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_INFO_QUERY_EAS_FROM_LIST: data_size = 24; - put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); put_dos_date2(pdata,4,sbuf.st_atime); put_dos_date2(pdata,8,sbuf.st_mtime); SIVAL(pdata,12,size); @@ -1290,7 +1300,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_QUERY_FILE_BASIC_INFO: data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ - put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ @@ -1298,7 +1308,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, DEBUG(5,("SMB_QFBI - ")); { - time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))); + time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); DEBUG(5,("create: %s ", ctime(&create_time))); } DEBUG(5,("access: %s ", ctime(&sbuf.st_atime))); @@ -1329,7 +1339,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, /* Mangle if not already 8.3 */ if(!is_8_3(short_name, True)) { - if(!name_map_mangle(short_name,True,SNUM(cnum))) + if(!name_map_mangle(short_name,True,SNUM(conn))) *short_name = '\0'; } strupper(short_name); @@ -1353,7 +1363,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, break; case SMB_QUERY_FILE_ALL_INFO: - put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum)))); + put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ @@ -1403,8 +1413,9 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, /**************************************************************************** reply to a TRANS2_SETFILEINFO (set file info by fileid) ****************************************************************************/ -static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, - int bufsize, int cnum, char **pparams, +static int call_trans2setfilepathinfo(connection_struct *conn, + char *inbuf, char *outbuf, int length, + int bufsize, char **pparams, char **ppdata, int total_data) { char *params = *pparams; @@ -1420,17 +1431,17 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, int fd = -1; BOOL bad_path = False; - if (!CAN_WRITE(cnum)) + if (!CAN_WRITE(conn)) return(ERROR(ERRSRV,ERRaccess)); if (tran_call == TRANSACT2_SETFILEINFO) { int16 fnum = SVALS(params,0); info_level = SVAL(params,2); - CHECK_FNUM(fnum,cnum); + CHECK_FNUM(fnum,conn); CHECK_ERROR(fnum); - fname = Files[fnum].name; + fname = Files[fnum].fsp_name; fd = Files[fnum].fd_ptr->fd; if(fstat(fd,&st)!=0) { @@ -1442,8 +1453,8 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, info_level = SVAL(params,0); fname = fname1; pstrcpy(fname,¶ms[6]); - unix_convert(fname,cnum,0,&bad_path); - if(!check_name(fname, cnum)) + unix_convert(fname,conn,0,&bad_path); + if(!check_name(fname, conn)) { if((errno == ENOENT) && bad_path) { @@ -1475,7 +1486,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, size = st.st_size; tvs.modtime = st.st_mtime; tvs.actime = st.st_atime; - mode = dos_mode(cnum,fname,&st); + mode = dos_mode(conn,fname,&st); if (total_data > 0 && IVAL(pdata,0) == total_data) { /* uggh, EAs for OS2 */ @@ -1572,14 +1583,14 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, */ if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) { - if(file_utime(cnum, fname, &tvs)!=0) + if(file_utime(conn, fname, &tvs)!=0) { return(ERROR(ERRDOS,ERRnoaccess)); } } /* check the mode isn't different, before changing it */ - if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL)) + if (mode != dos_mode(conn, fname, &st) && dos_chmod(conn, fname, mode, NULL)) { DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno))); return(ERROR(ERRDOS,ERRnoaccess)); @@ -1613,24 +1624,25 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, /**************************************************************************** reply to a TRANS2_MKDIR (make directory with extended attributes). ****************************************************************************/ -static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2mkdir(connection_struct *conn, + char *inbuf, char *outbuf, int length, int bufsize, + char **pparams, char **ppdata) { char *params = *pparams; pstring directory; int ret = -1; BOOL bad_path = False; - if (!CAN_WRITE(cnum)) + if (!CAN_WRITE(conn)) return(ERROR(ERRSRV,ERRaccess)); pstrcpy(directory, ¶ms[4]); DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); - unix_convert(directory,cnum,0,&bad_path); - if (check_name(directory,cnum)) - ret = sys_mkdir(directory,unix_mode(cnum,aDIR)); + unix_convert(directory,conn,0,&bad_path); + if (check_name(directory,conn)) + ret = sys_mkdir(directory,unix_mode(conn,aDIR)); if(ret < 0) { @@ -1659,8 +1671,10 @@ static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize, reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes) We don't actually do this - we just send a null response. ****************************************************************************/ -static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2findnotifyfirst(connection_struct *conn, + char *inbuf, char *outbuf, + int length, int bufsize, + char **pparams, char **ppdata) { static uint16 fnf_handle = 257; char *params = *pparams; @@ -1700,8 +1714,10 @@ static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for changes). Currently this does nothing. ****************************************************************************/ -static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize, - int cnum, char **pparams, char **ppdata) +static int call_trans2findnotifynext(connection_struct *conn, + char *inbuf, char *outbuf, + int length, int bufsize, + char **pparams, char **ppdata) { char *params = *pparams; @@ -1723,236 +1739,255 @@ static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int /**************************************************************************** reply to a SMBfindclose (stop trans2 directory search) ****************************************************************************/ -int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize) +int reply_findclose(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - int cnum; - int outsize = 0; - int16 dptr_num=SVALS(inbuf,smb_vwv0); + int outsize = 0; + int16 dptr_num=SVALS(inbuf,smb_vwv0); - cnum = SVAL(inbuf,smb_tid); + DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num)); - DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num)); + dptr_close(dptr_num); - dptr_close(dptr_num); + outsize = set_message(outbuf,0,0,True); - outsize = set_message(outbuf,0,0,True); + DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num)); - DEBUG( 3, ( "SMBfindclose cnum=%d, dptr_num = %d\n", cnum, dptr_num ) ); - - return(outsize); + return(outsize); } /**************************************************************************** reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search) ****************************************************************************/ -int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize) +int reply_findnclose(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - int cnum; - int outsize = 0; - int dptr_num= -1; - - cnum = SVAL(inbuf,smb_tid); - dptr_num = SVAL(inbuf,smb_vwv0); + int outsize = 0; + int dptr_num= -1; + + dptr_num = SVAL(inbuf,smb_vwv0); - DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num)); + DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num)); - /* We never give out valid handles for a - findnotifyfirst - so any dptr_num is ok here. - Just ignore it. */ + /* We never give out valid handles for a + findnotifyfirst - so any dptr_num is ok here. + Just ignore it. */ - outsize = set_message(outbuf,0,0,True); + outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "SMB_findnclose cnum=%d, dptr_num = %d\n", cnum, dptr_num ) ); + DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num)); - return(outsize); + return(outsize); } /**************************************************************************** reply to a SMBtranss2 - just ignore it! ****************************************************************************/ -int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize) +int reply_transs2(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - DEBUG(4,("Ignoring transs2 of length %d\n",length)); - return(-1); + DEBUG(4,("Ignoring transs2 of length %d\n",length)); + return(-1); } /**************************************************************************** reply to a SMBtrans2 ****************************************************************************/ -int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize) +int reply_trans2(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) { - int outsize = 0; - int cnum = SVAL(inbuf,smb_tid); - unsigned int total_params = SVAL(inbuf, smb_tpscnt); - unsigned int total_data =SVAL(inbuf, smb_tdscnt); + int outsize = 0; + unsigned int total_params = SVAL(inbuf, smb_tpscnt); + unsigned int total_data =SVAL(inbuf, smb_tdscnt); #if 0 - unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt); - unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt); - unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt); - BOOL close_tid = BITSETW(inbuf+smb_flags,0); - BOOL no_final_response = BITSETW(inbuf+smb_flags,1); - int32 timeout = IVALS(inbuf,smb_timeout); + unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt); + unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt); + unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt); + BOOL close_tid = BITSETW(inbuf+smb_flags,0); + BOOL no_final_response = BITSETW(inbuf+smb_flags,1); + int32 timeout = IVALS(inbuf,smb_timeout); #endif - unsigned int suwcnt = SVAL(inbuf, smb_suwcnt); - unsigned int tran_call = SVAL(inbuf, smb_setup0); - char *params = NULL, *data = NULL; - int num_params, num_params_sofar, num_data, num_data_sofar; - - if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) - { - /* - * Queue this open message as we are the process of an oplock break. - */ - - DEBUG( 2, ( "reply_trans2: queueing message trans2open due to being " ) ); - DEBUGADD( 2, ( "in oplock break state.\n" ) ); + unsigned int suwcnt = SVAL(inbuf, smb_suwcnt); + unsigned int tran_call = SVAL(inbuf, smb_setup0); + char *params = NULL, *data = NULL; + int num_params, num_params_sofar, num_data, num_data_sofar; - push_oplock_pending_smb_message( inbuf, length); - return -1; - } + if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) { + /* Queue this open message as we are the process of an + * oplock break. */ - outsize = set_message(outbuf,0,0,True); + DEBUG(2,("reply_trans2: queueing message trans2open due to being ")); + DEBUGADD(2,( "in oplock break state.\n")); - /* All trans2 messages we handle have smb_sucnt == 1 - ensure this - is so as a sanity check */ - if(suwcnt != 1 ) - { - DEBUG(2,("Invalid smb_sucnt in trans2 call\n")); - return(ERROR(ERRSRV,ERRerror)); - } + push_oplock_pending_smb_message(inbuf, length); + return -1; + } + + outsize = set_message(outbuf,0,0,True); + + /* All trans2 messages we handle have smb_sucnt == 1 - ensure this + is so as a sanity check */ + if (suwcnt != 1) { + DEBUG(2,("Invalid smb_sucnt in trans2 call\n")); + return(ERROR(ERRSRV,ERRerror)); + } - /* Allocate the space for the maximum needed parameters and data */ - if (total_params > 0) - params = (char *)malloc(total_params); - if (total_data > 0) - data = (char *)malloc(total_data); + /* Allocate the space for the maximum needed parameters and data */ + if (total_params > 0) + params = (char *)malloc(total_params); + if (total_data > 0) + data = (char *)malloc(total_data); - if ((total_params && !params) || (total_data && !data)) - { - DEBUG(2,("Out of memory in reply_trans2\n")); - return(ERROR(ERRDOS,ERRnomem)); - } - - /* Copy the param and data bytes sent with this request into - the params buffer */ - num_params = num_params_sofar = SVAL(inbuf,smb_pscnt); - num_data = num_data_sofar = SVAL(inbuf, smb_dscnt); - - if (num_params > total_params || num_data > total_data) - exit_server("invalid params in reply_trans2"); - - if(params) - memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params); - if(data) - memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data); - - if(num_data_sofar < total_data || num_params_sofar < total_params) - { - /* We need to send an interim response then receive the rest - of the parameter/data bytes */ - outsize = set_message(outbuf,0,0,True); - send_smb(Client,outbuf); - - while( num_data_sofar < total_data || num_params_sofar < total_params) - { - BOOL ret; - - ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize, - SMB_SECONDARY_WAIT); + if ((total_params && !params) || (total_data && !data)) { + DEBUG(2,("Out of memory in reply_trans2\n")); + return(ERROR(ERRDOS,ERRnomem)); + } - if((ret && (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) - { - outsize = set_message(outbuf,0,0,True); - if(ret) - DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n")); - else - DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n", - (smb_read_error == READ_ERROR) ? "error" : "timeout" )); - if(params) - free(params); - if(data) - free(data); - return(ERROR(ERRSRV,ERRerror)); - } + /* Copy the param and data bytes sent with this request into + the params buffer */ + num_params = num_params_sofar = SVAL(inbuf,smb_pscnt); + num_data = num_data_sofar = SVAL(inbuf, smb_dscnt); + + if (num_params > total_params || num_data > total_data) + exit_server("invalid params in reply_trans2"); + + if(params) + memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params); + if(data) + memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data); + + if(num_data_sofar < total_data || num_params_sofar < total_params) { + /* We need to send an interim response then receive the rest + of the parameter/data bytes */ + outsize = set_message(outbuf,0,0,True); + send_smb(Client,outbuf); + + while (num_data_sofar < total_data || + num_params_sofar < total_params) { + BOOL ret; + + ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize, + SMB_SECONDARY_WAIT); + + if ((ret && + (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) { + outsize = set_message(outbuf,0,0,True); + if(ret) + DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n")); + else + DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n", + (smb_read_error == READ_ERROR) ? "error" : "timeout" )); + if(params) + free(params); + if(data) + free(data); + return(ERROR(ERRSRV,ERRerror)); + } - /* Revise total_params and total_data in case they have changed downwards */ - total_params = SVAL(inbuf, smb_tpscnt); - total_data = SVAL(inbuf, smb_tdscnt); - num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt)); - num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt)); - if (num_params_sofar > total_params || num_data_sofar > total_data) - exit_server("data overflow in trans2"); - - memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)], - smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params); - memcpy( &data[SVAL(inbuf, smb_sdsdisp)], - smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data); + /* Revise total_params and total_data in case + they have changed downwards */ + total_params = SVAL(inbuf, smb_tpscnt); + total_data = SVAL(inbuf, smb_tdscnt); + num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt)); + num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt)); + if (num_params_sofar > total_params || num_data_sofar > total_data) + exit_server("data overflow in trans2"); + + memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)], + smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params); + memcpy( &data[SVAL(inbuf, smb_sdsdisp)], + smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data); + } + } + + if (Protocol >= PROTOCOL_NT1) { + uint16 flg2 = SVAL(outbuf,smb_flg2); + SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */ } - } - - if (Protocol >= PROTOCOL_NT1) { - uint16 flg2 = SVAL(outbuf,smb_flg2); - SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */ - } - - /* Now we must call the relevant TRANS2 function */ - switch(tran_call) - { - case TRANSACT2_OPEN: - outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_FINDFIRST: - outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_FINDNEXT: - outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_QFSINFO: - outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_SETFSINFO: - outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_QPATHINFO: - case TRANSACT2_QFILEINFO: - outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data); - break; - case TRANSACT2_SETPATHINFO: - case TRANSACT2_SETFILEINFO: - outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data); - break; - case TRANSACT2_FINDNOTIFYFIRST: - outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_FINDNOTIFYNEXT: - outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - case TRANSACT2_MKDIR: - outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data); - break; - default: - /* Error in request */ - DEBUG( 2, ( "Unknown request %d in trans2 call\n", tran_call ) ); - if(params) - free(params); - if(data) - free(data); - return (ERROR(ERRSRV,ERRerror)); - } - /* As we do not know how many data packets will need to be - returned here the various call_trans2xxxx calls - must send their own. Thus a call_trans2xxx routine only - returns a value other than -1 when it wants to send - an error packet. - */ - - if(params) - free(params); - if(data) - free(data); - return outsize; /* If a correct response was needed the call_trans2xxx - calls have already sent it. If outsize != -1 then it is - returning an error packet. */ + /* Now we must call the relevant TRANS2 function */ + switch(tran_call) { + case TRANSACT2_OPEN: + outsize = call_trans2open(conn, + inbuf, outbuf, bufsize, + ¶ms, &data); + break; + + case TRANSACT2_FINDFIRST: + outsize = call_trans2findfirst(conn, inbuf, outbuf, + bufsize, ¶ms, &data); + break; + + case TRANSACT2_FINDNEXT: + outsize = call_trans2findnext(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data); + break; + + case TRANSACT2_QFSINFO: + outsize = call_trans2qfsinfo(conn, inbuf, outbuf, + length, bufsize, ¶ms, + &data); + break; + + case TRANSACT2_SETFSINFO: + outsize = call_trans2setfsinfo(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data); + break; + + case TRANSACT2_QPATHINFO: + case TRANSACT2_QFILEINFO: + outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data, total_data); + break; + case TRANSACT2_SETPATHINFO: + case TRANSACT2_SETFILEINFO: + outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data, + total_data); + break; + + case TRANSACT2_FINDNOTIFYFIRST: + outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data); + break; + + case TRANSACT2_FINDNOTIFYNEXT: + outsize = call_trans2findnotifynext(conn, inbuf, outbuf, + length, bufsize, + ¶ms, &data); + break; + case TRANSACT2_MKDIR: + outsize = call_trans2mkdir(conn, inbuf, outbuf, length, + bufsize, ¶ms, &data); + break; + default: + /* Error in request */ + DEBUG(2,("Unknown request %d in trans2 call\n", tran_call)); + if(params) + free(params); + if(data) + free(data); + return (ERROR(ERRSRV,ERRerror)); + } + + /* As we do not know how many data packets will need to be + returned here the various call_trans2xxxx calls + must send their own. Thus a call_trans2xxx routine only + returns a value other than -1 when it wants to send + an error packet. + */ + + if(params) + free(params); + if(data) + free(data); + return outsize; /* If a correct response was needed the + call_trans2xxx calls have already sent + it. If outsize != -1 then it is returning */ } diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9e669c301b..1276eeaaac 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -27,7 +27,7 @@ static int initial_uid; static int initial_gid; /* what user is current? */ -struct current_user current_user; +extern struct current_user current_user; pstring OriginalDir; @@ -51,7 +51,7 @@ void init_uid(void) initial_uid = geteuid(); initial_gid = getegid(); - current_user.cnum = -1; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; ChDir(OriginalDir); @@ -180,7 +180,7 @@ BOOL become_guest(void) DEBUG(1,("Failed to become guest. Invalid guest account?\n")); } - current_user.cnum = -2; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; return(ret); @@ -210,90 +210,89 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) /**************************************************************************** become the user of a connection number ****************************************************************************/ -BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) +BOOL become_user(connection_struct *conn, uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); - int snum,gid; - int uid; - - /* - * We need a separate check in security=share mode due to vuid - * always being UID_FIELD_INVALID. If we don't do this then - * in share mode security we are *always* changing uid's between - * SMB's - this hurts performance - Badly. - */ - - if((lp_security() == SEC_SHARE) && (current_user.cnum == cnum) && - (current_user.uid == conn->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); - return(True); - } else if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.uid == vuser->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); - return(True); - } - - unbecome_user(); - - if (!(VALID_CNUM(cnum) && conn->open)) { - DEBUG(2,("Connection %d not open\n",cnum)); - return(False); - } - - snum = conn->service; + user_struct *vuser = get_valid_user_struct(vuid); + int snum,gid; + int uid; + + /* + * We need a separate check in security=share mode due to vuid + * always being UID_FIELD_INVALID. If we don't do this then + * in share mode security we are *always* changing uid's between + * SMB's - this hurts performance - Badly. + */ + + if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && + (current_user.uid == conn->uid)) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != 0) && (current_user.vuid == vuid) && + (current_user.uid == vuser->uid)) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } - if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) - return False; + unbecome_user(); - if (conn->force_user || - lp_security() == SEC_SHARE || - !(vuser) || (vuser->guest) - ) - { - uid = conn->uid; - gid = conn->gid; - current_user.groups = conn->groups; - current_user.ngroups = conn->ngroups; - } - else - { - if (!vuser) { - DEBUG(2,("Invalid vuid used %d\n",vuid)); - return(False); - } - uid = vuser->uid; - if(!*lp_force_group(snum)) - gid = vuser->gid; - else - gid = conn->gid; - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; - } + if (!(conn && conn->open)) { + DEBUG(2,("Connection not open\n")); + return(False); + } - if (initial_uid == 0) - { - if (!become_gid(gid)) return(False); + snum = SNUM(conn); + + if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) + return False; + + if (conn->force_user || + lp_security() == SEC_SHARE || + !(vuser) || (vuser->guest)) { + uid = conn->uid; + gid = conn->gid; + current_user.groups = conn->groups; + current_user.ngroups = conn->ngroups; + } else { + if (!vuser) { + DEBUG(2,("Invalid vuid used %d\n",vuid)); + return(False); + } + uid = vuser->uid; + if(!*lp_force_group(snum)) { + gid = vuser->gid; + } else { + gid = conn->gid; + } + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + } + + if (initial_uid == 0) { + if (!become_gid(gid)) return(False); #ifdef HAVE_SETGROUPS - if (!(VALID_CNUM(cnum) && conn->ipc)) { - /* groups stuff added by ih/wreu */ - if (current_user.ngroups > 0) - if (setgroups(current_user.ngroups,current_user.groups)<0) - DEBUG(0,("setgroups call failed!\n")); - } + if (!(conn && conn->ipc)) { + /* groups stuff added by ih/wreu */ + if (current_user.ngroups > 0) + if (setgroups(current_user.ngroups, + current_user.groups)<0) { + DEBUG(0,("setgroups call failed!\n")); + } + } #endif - if (!conn->admin_user && !become_uid(uid)) - return(False); - } - - current_user.cnum = cnum; - current_user.vuid = vuid; + if (!conn->admin_user && !become_uid(uid)) + return(False); + } + + current_user.conn = conn; + current_user.vuid = vuid; - DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", - getuid(),geteuid(),getgid(),getegid())); + DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", + getuid(),geteuid(),getgid(),getegid())); - return(True); + return(True); } /**************************************************************************** @@ -301,7 +300,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) ****************************************************************************/ BOOL unbecome_user(void ) { - if (current_user.cnum == -1) + if (!current_user.conn) return(False); ChDir(OriginalDir); @@ -343,158 +342,12 @@ BOOL unbecome_user(void ) DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); - current_user.cnum = -1; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; return(True); } - -/**************************************************************************** -This is a utility function of smbrun(). It must be called only from -the child as it may leave the caller in a privilaged state. -****************************************************************************/ -static BOOL setup_stdout_file(char *outfile,BOOL shared) -{ - int fd; - struct stat st; - mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH; - int flags = O_RDWR|O_CREAT|O_TRUNC|O_EXCL; - - close(1); - - if (shared) { - /* become root - unprivilaged users can't delete these files */ -#ifdef HAVE_SETRESUID - setresgid(0,0,0); - setresuid(0,0,0); -#else - setuid(0); - seteuid(0); -#endif - } - - if(stat(outfile, &st) == 0) { - /* Check we're not deleting a device file. */ - if(st.st_mode & S_IFREG) - unlink(outfile); - else - flags = O_RDWR; - } - /* now create the file */ - fd = open(outfile,flags,mode); - - if (fd == -1) return False; - - if (fd != 1) { - if (dup2(fd,1) != 0) { - DEBUG(2,("Failed to create stdout file descriptor\n")); - close(fd); - return False; - } - close(fd); - } - return True; -} - - -/**************************************************************************** -run a command being careful about uid/gid handling and putting the output in -outfile (or discard it if outfile is NULL). - -if shared is True then ensure the file will be writeable by all users -but created such that its owned by root. This overcomes a security hole. - -if shared is not set then open the file with O_EXCL set -****************************************************************************/ -int smbrun(char *cmd,char *outfile,BOOL shared) -{ - int fd,pid; - int uid = current_user.uid; - int gid = current_user.gid; - -#ifndef HAVE_EXECL - int ret; - pstring syscmd; - char *path = lp_smbrun(); - - /* in the old method we use system() to execute smbrun which then - executes the command (using system() again!). This involves lots - of shell launches and is very slow. It also suffers from a - potential security hole */ - if (!file_exist(path,NULL)) - { - DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path)); - return(1); - } - - slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"", - path,uid,gid,cmd, - outfile?outfile:"/dev/null"); - - DEBUG(5,("smbrun - running %s ",syscmd)); - ret = system(syscmd); - DEBUG(5,("gave %d\n",ret)); - return(ret); -#else - /* in this newer method we will exec /bin/sh with the correct - arguments, after first setting stdout to point at the file */ - - if ((pid=fork())) { - int status=0; - /* the parent just waits for the child to exit */ - if (sys_waitpid(pid,&status,0) != pid) { - DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno))); - return -1; - } - return status; - } - - - /* we are in the child. we exec /bin/sh to do the work for us. we - don't directly exec the command we want because it may be a - pipeline or anything else the config file specifies */ - - /* point our stdout at the file we want output to go into */ - if (outfile && !setup_stdout_file(outfile,shared)) { - exit(80); - } - - /* now completely lose our privilages. This is a fairly paranoid - way of doing it, but it does work on all systems that I know of */ -#ifdef HAVE_SETRESUID - setresgid(0,0,0); - setresuid(0,0,0); - setresgid(gid,gid,gid); - setresuid(uid,uid,uid); -#else - setuid(0); - seteuid(0); - setgid(gid); - setegid(gid); - setuid(uid); - seteuid(uid); -#endif - - if (getuid() != uid || geteuid() != uid || - getgid() != gid || getegid() != gid) { - /* we failed to lose our privilages - do not execute the command */ - exit(81); /* we can't print stuff at this stage, instead use exit codes - for debugging */ - } - - /* close all other file descriptors, leaving only 0, 1 and 2. 0 and - 2 point to /dev/null from the startup code */ - for (fd=3;fd<256;fd++) close(fd); - - execl("/bin/sh","sh","-c",cmd,NULL); - - /* not reached */ - exit(82); -#endif - return 1; -} - static struct current_user current_user_saved; static int become_root_depth; static pstring become_root_dir; |