Fixes for the %U and %G problems people have reported.
authorJeremy Allison <jra@samba.org>
Wed, 6 May 1998 00:22:08 +0000 (00:22 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 6 May 1998 00:22:08 +0000 (00:22 +0000)
Essentially, multiple session_setup_and_X's may be done
to an smbd. As there is only one global variable containing
the requested connection name (sessionsetup_user), then any
subsequent sessionsetups overwrite this name (causing %U
and %G to get the wrong name). This is particularly common
when an NT client does a null session setup to get a
browse list after the user has connected, but before
a share has been mounted.

These changes store the requested_name in the vuid structure
(so this only really works for user level and above security)
and copies this name back into the global variable before
the standard_sub call.

Jeremy.

source/include/proto.h
source/include/smb.h
source/printing/printing.c
source/smbd/ipc.c
source/smbd/message.c
source/smbd/password.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/uid.c

index 7a2289e7f4fe20ee6501ca116591e9efcd21fec2..c486c2077811bb0a9c12199b026bfe7b50628082 100644 (file)
@@ -843,7 +843,7 @@ BOOL last_challenge(char *challenge);
 user_struct *get_valid_user_struct(uint16 vuid);
 void invalidate_vuid(uint16 vuid);
 char *validated_username(uint16 vuid);
-uint16 register_vuid(int uid,int gid, char *name,BOOL guest);
+uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOOL guest);
 void add_session_user(char *user);
 BOOL update_smbpassword_file( struct passwd *pass, fstring password);
 void dfs_unlogin(void);
@@ -1286,10 +1286,10 @@ int reply_lanman1(char *outbuf);
 int reply_lanman2(char *outbuf);
 int reply_nt1(char *outbuf);
 void close_cnum(int cnum, uint16 vuid);
-BOOL yield_connection(int cnum,char *name,int max_connections);
-BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
+BOOL yield_connection(int cnum,char *name,int max_connections, uint16 vuid);
+BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear, uint16 vuid);
 void exit_server(char *reason);
-void standard_sub(int cnum,char *str);
+void standard_sub(int cnum,char *str,uint16 vuid);
 char *smb_fn_name(int type);
 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
index eb2477db0bc79b5772c4ebf31abda9bfdf8f4086..ef79e60f37b9ec5de5aeee561d0558d1895ead71 100644 (file)
@@ -465,7 +465,8 @@ typedef struct
   int uid; /* uid of a validated user */
   int gid; /* gid of a validated user */
 
-  fstring name; /* name of a validated user */
+  fstring requested_name; /* user name from the client */
+  fstring name; /* unix user name of a validated user */
   fstring real_name;   /* to store real name from password file - simeon */
   BOOL guest;
 
index c7db5744e266949bd7df420ea36a27fee8576089..bbc0ff6144bd4b65f53bdfe3b1eaca56b78212cb 100644 (file)
@@ -103,7 +103,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi
   
   string_sub(syscmd, "%p", tstr);
   
-  standard_sub(cnum,syscmd);
+  standard_sub(cnum,syscmd,UID_FIELD_INVALID);
   
   return (syscmd);
 }
@@ -1056,7 +1056,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue,
   pstrcpy(syscmd,lpq_command);
   string_sub(syscmd,"%p",printername);
 
-  standard_sub(cnum,syscmd);
+  standard_sub(cnum,syscmd,UID_FIELD_INVALID);
 
   sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
   
@@ -1147,7 +1147,7 @@ void del_printqueue(int cnum,int snum,int jobid)
   pstrcpy(syscmd,lprm_command);
   string_sub(syscmd,"%p",printername);
   string_sub(syscmd,"%j",jobstr);
-  standard_sub(cnum,syscmd);
+  standard_sub(cnum,syscmd,UID_FIELD_INVALID);
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
@@ -1185,7 +1185,7 @@ void status_printjob(int cnum,int snum,int jobid,int status)
   pstrcpy(syscmd,lpstatus_command);
   string_sub(syscmd,"%p",printername);
   string_sub(syscmd,"%j",jobstr);
-  standard_sub(cnum,syscmd);
+  standard_sub(cnum,syscmd,UID_FIELD_INVALID);
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
index cc8f9b9afd94e55c64baaf975f5f7e38172ea541..7f5eae0b4ae40c639be62d3629ca3c1c64f5dc45 100644 (file)
@@ -84,7 +84,7 @@ static int CopyExpanded(int cnum, int snum, char** dst, char* src, int* n)
 
   StrnCpy(buf,src,sizeof(buf)/2);
   string_sub(buf,"%S",lp_servicename(snum));
-  standard_sub(cnum,buf);
+  standard_sub(cnum,buf,UID_FIELD_INVALID);
   StrnCpy(*dst,buf,*n);
   l = strlen(*dst) + 1;
   (*dst) += l;
@@ -109,7 +109,7 @@ static int StrlenExpanded(int cnum, int snum, char* s)
   if (!s) return(0);
   StrnCpy(buf,s,sizeof(buf)/2);
   string_sub(buf,"%S",lp_servicename(snum));
-  standard_sub(cnum,buf);
+  standard_sub(cnum,buf,UID_FIELD_INVALID);
   return strlen(buf) + 1;
 }
 
@@ -119,7 +119,7 @@ static char* Expand(int cnum, int snum, char* s)
   if (!s) return(NULL);
   StrnCpy(buf,s,sizeof(buf)/2);
   string_sub(buf,"%S",lp_servicename(snum));
-  standard_sub(cnum,buf);
+  standard_sub(cnum,buf,UID_FIELD_INVALID);
   return &buf[0];
 }
 
@@ -1974,7 +1974,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(cnum,comment,vuid);
        StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
        p2 = skip_string(p2,1);
       }
@@ -2500,7 +2500,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( cnum, logon_script, vuid );
     PACKS(&desc,"z", logon_script);            /* script path */
 /* End of JHT mods */
 
index 24477f31ff6b7fe3204a86e751c2ba04bc5a2f5d..9fb506edd016560e60a07c9a7539d9c32fdaced8 100644 (file)
@@ -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(-1,s,UID_FIELD_INVALID);
       smbrun(s,NULL,False);
     }
 
index 77cbf6723ccce4812ce23d065f0872c975c7918a..154543bcf532f6fee5bc94521c7f03238a7afba3 100644 (file)
@@ -152,7 +152,7 @@ register a uid/name pair as being valid and that a valid password
 has been given. vuid is biased by an offset. This allows us to
 tell random client vuid's (normally zero) from valid vuids.
 ****************************************************************************/
-uint16 register_vuid(int uid,int gid, char *name,BOOL guest)
+uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOOL guest)
 {
   user_struct *vuser;
   struct passwd *pwfile; /* for getting real name from passwd file */
@@ -199,7 +199,8 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest)
   vuser->uid = uid;
   vuser->gid = gid;
   vuser->guest = guest;
-  strcpy(vuser->name,name);
+  fstrcpy(vuser->name,unix_name);
+  fstrcpy(vuser->requested_name,requested_name);
 
   vuser->n_sids = 0;
   vuser->sids   = NULL;
@@ -211,13 +212,13 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest)
 
   /* Find all the groups this uid is in and store them. 
      Used by become_user() */
-  setup_groups(name,uid,gid,
+  setup_groups(unix_name,uid,gid,
               &vuser->n_groups,
               &vuser->igroups,
               &vuser->groups,
               &vuser->attrs);
 
-  DEBUG(3,("uid %d registered to name %s\n",uid,name));
+  DEBUG(3,("uid %d registered to name %s\n",uid,unix_name));
 
   DEBUG(3, ("Clearing default real name\n"));
   fstrcpy(vuser->real_name, "<Full Name>\0");
index 38a7879abd13331a25b65701abb15d500c2c5363..63cb608db4ab612327216dc62dc0c2008cccf865 100644 (file)
@@ -648,7 +648,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 
   /* register the name and uid as being validated, so further connections
      to a uid can get through without a password, on the same VC */
-  sess_vuid = register_vuid(uid,gid,user,guest);
+  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
  
   SSVAL(outbuf,smb_uid,sess_vuid);
   SSVAL(inbuf,smb_uid,sess_vuid);
index d9f2efc64c8d3ff0f7ff4bce0ba54d120c1e01be..ee6726506ae51d042837de53b26c17ac0ddb160a 100644 (file)
@@ -3603,7 +3603,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
   {
     pstring s;
     pstrcpy(s,lp_pathname(snum));
-    standard_sub(cnum,s);
+    standard_sub(cnum,s,vuid);
     string_set(&pcon->connectpath,s);
     DEBUG(3,("Connect path is %s\n",s));
   }
@@ -3623,14 +3623,14 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
       /* check number of connections */
       if (!claim_connection(cnum,
                            lp_servicename(SNUM(cnum)),
-                           lp_max_connections(SNUM(cnum)),False))
+                           lp_max_connections(SNUM(cnum)),False,vuid))
        {
          DEBUG(1,("too many connections - rejected\n"));
          return(-8);
        }  
 
       if (lp_status(SNUM(cnum)))
-       claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
+       claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection,vuid);
 
       first_connection = False;
     } /* IS_IPC */
@@ -3642,7 +3642,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
     {
       pstring cmd;
       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
-      standard_sub(cnum,cmd);
+      standard_sub(cnum,cmd,vuid);
       DEBUG(5,("cmd=%s\n",cmd));
       smbrun(cmd,NULL,False);
     }
@@ -3654,8 +3654,8 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
       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);
+                        lp_max_connections(SNUM(cnum)), vuid);
+       if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS, vuid);
       }
       return(-1);
     }
@@ -3669,8 +3669,8 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
       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);
+                        lp_max_connections(SNUM(cnum)), vuid);
+       if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS, vuid);
       }
       return(-5);      
     }
@@ -3696,7 +3696,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
     {
       pstring cmd;
       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
-      standard_sub(cnum,cmd);
+      standard_sub(cnum,cmd,vuid);
       smbrun(cmd,NULL,False);
     }
   
@@ -4275,10 +4275,10 @@ void close_cnum(int cnum, uint16 vuid)
 
   yield_connection(cnum,
                   lp_servicename(SNUM(cnum)),
-                  lp_max_connections(SNUM(cnum)));
+                  lp_max_connections(SNUM(cnum)), vuid);
 
   if (lp_status(SNUM(cnum)))
-    yield_connection(cnum,"STATUS.",MAXSTATUS);
+    yield_connection(cnum,"STATUS.",MAXSTATUS, vuid);
 
   close_open_files(cnum);
   dptr_closecnum(cnum);
@@ -4288,7 +4288,7 @@ void close_cnum(int cnum, uint16 vuid)
     {
       pstring cmd;
       strcpy(cmd,lp_postexec(SNUM(cnum)));
-      standard_sub(cnum,cmd);
+      standard_sub(cnum,cmd,vuid);
       smbrun(cmd,NULL,False);
       unbecome_user();
     }
@@ -4299,7 +4299,7 @@ void close_cnum(int cnum, uint16 vuid)
     {
       pstring cmd;
       strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
-      standard_sub(cnum,cmd);
+      standard_sub(cnum,cmd,vuid);
       smbrun(cmd,NULL,False);
     }
 
@@ -4328,7 +4328,7 @@ void close_cnum(int cnum, uint16 vuid)
 /****************************************************************************
 simple routines to do connection counting
 ****************************************************************************/
-BOOL yield_connection(int cnum,char *name,int max_connections)
+BOOL yield_connection(int cnum,char *name,int max_connections, uint16 vuid)
 {
   struct connect_record crec;
   pstring fname;
@@ -4344,7 +4344,7 @@ BOOL yield_connection(int cnum,char *name,int max_connections)
   bzero(&crec,sizeof(crec));
 
   pstrcpy(fname,lp_lockdir());
-  standard_sub(cnum,fname);
+  standard_sub(cnum,fname,vuid);
   trim_string(fname,"","/");
 
   strcat(fname,"/");
@@ -4401,7 +4401,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(int cnum,char *name,int max_connections,BOOL Clear, uint16 vuid)
 {
   struct connect_record crec;
   pstring fname;
@@ -4416,7 +4416,7 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
   DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
 
   pstrcpy(fname,lp_lockdir());
-  standard_sub(cnum,fname);
+  standard_sub(cnum,fname,vuid);
   trim_string(fname,"","/");
 
   if (!directory_exist(fname,NULL))
@@ -4581,8 +4581,10 @@ void exit_server(char *reason)
 /****************************************************************************
 do some standard substitutions in a string
 ****************************************************************************/
-void standard_sub(int cnum,char *str)
+void standard_sub(int cnum,char *str,uint16 vuid)
 {
+  user_struct *vuser = get_valid_user_struct(vuid);
+
   if (VALID_CNUM(cnum)) {
     char *p, *s, *home;
 
@@ -4611,6 +4613,9 @@ void standard_sub(int cnum,char *str)
       }
     }
   }
+  if(vuser != NULL)
+    pstrcpy( sesssetup_user, vuser->requested_name);
+
   standard_sub_basic(str);
 }
 
index 14b0000f59401685052b0d4df34f8a44f90c1e9c..f9da121ddaa57899da00881985f4d6c9723f189e 100644 (file)
@@ -28,6 +28,7 @@ static int initial_gid;
 
 /* what user is current? */
 struct current_user current_user;
+extern pstring sesssetup_user;
 
 pstring OriginalDir;
 
@@ -277,6 +278,11 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid)
   current_user.cnum = cnum;
   current_user.vuid = vuid;
   
+  /* Ensure sesssetup_user is set correctly if we are using
+     user security. */
+  if(vuser != NULL)
+    pstrcpy( sesssetup_user, vuser->requested_name);
+
   DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
           getuid(),geteuid(),getgid(),getegid()));