r5174: ensure that we consistently use the current_user_info.smb_name vs. smb_name...
[ira/wip.git] / source / lib / substitute.c
index 6d96a1820f1484fcd997ff5774c313936bab0e5d..615a8d73b0a36016381705b8a7fa99fdf026bb8a 100644 (file)
@@ -25,8 +25,126 @@ fstring local_machine="";
 fstring remote_arch="UNKNOWN";
 userdom_struct current_user_info;
 fstring remote_proto="UNKNOWN";
-fstring remote_machine="";
-extern pstring global_myname;
+
+static fstring remote_machine;
+static fstring smb_user_name;
+
+/** 
+ * Set the 'local' machine name
+ * @param local_name the name we are being called
+ * @param if this is the 'final' name for us, not be be changed again
+ */
+
+void set_local_machine_name(const char* local_name, BOOL perm)
+{
+       static BOOL already_perm = False;
+       fstring tmp_local_machine;
+
+       fstrcpy(tmp_local_machine,local_name);
+       trim_char(tmp_local_machine,' ',' ');
+
+       /*
+        * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
+        * arrggg!!! 
+        */
+
+       if ( strequal(tmp_local_machine, "*SMBSERVER") || strequal(tmp_local_machine, "*SMBSERV") )  {
+               fstrcpy( local_machine, client_socket_addr() );
+               return;
+       }
+
+       if (already_perm)
+               return;
+
+       already_perm = perm;
+
+       alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
+       strlower_m(local_machine);
+}
+
+/** 
+ * Set the 'remote' machine name
+ * @param remote_name the name our client wants to be called by
+ * @param if this is the 'final' name for them, not be be changed again
+ */
+
+void set_remote_machine_name(const char* remote_name, BOOL perm)
+{
+       static BOOL already_perm = False;
+       fstring tmp_remote_machine;
+
+       if (already_perm)
+               return;
+
+       already_perm = perm;
+
+       fstrcpy(tmp_remote_machine,remote_name);
+       trim_char(tmp_remote_machine,' ',' ');
+       alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
+       strlower_m(remote_machine);
+}
+
+const char* get_remote_machine_name(void) 
+{
+       return remote_machine;
+}
+
+const char* get_local_machine_name(void) 
+{
+       if (!*local_machine) {
+               return global_myname();
+       }
+
+       return local_machine;
+}
+
+/*******************************************************************
+ Setup the string used by %U substitution.
+********************************************************************/
+
+void sub_set_smb_name(const char *name)
+{
+       fstring tmp;
+
+       /* don't let anonymous logins override the name */
+       if (! *name)
+               return;
+
+       fstrcpy(tmp,name);
+       trim_char(tmp,' ',' ');
+       strlower_m(tmp);
+       alpha_strcpy(smb_user_name,tmp,SAFE_NETBIOS_CHARS,sizeof(smb_user_name)-1);
+}
+
+char* sub_get_smb_name( void )
+{
+       return smb_user_name;
+}
+
+/*******************************************************************
+ Setup the strings used by substitutions. Called per packet. Ensure
+ %U name is set correctly also.
+********************************************************************/
+
+void set_current_user_info(const userdom_struct *pcui)
+{
+       current_user_info = *pcui;
+       /* The following is safe as current_user_info.smb_name
+        * has already been sanitised in register_vuid. */
+       fstrcpy(smb_user_name, current_user_info.smb_name);
+}
+
+/*******************************************************************
+ return the current active user name
+*******************************************************************/
+
+const char* get_current_username( void )
+{
+       if ( current_user_info.smb_name[0] == '\0' )
+               return smb_user_name;
+
+       return current_user_info.smb_name; 
+}
 
 /*******************************************************************
  Given a pointer to a %$(NAME) expand it as an environment variable.
@@ -118,7 +236,7 @@ static char * realloc_expand_env_var(char *str, char *p)
 
        r = p + 3;
        copylen = q - r;
-       envname = (char *)malloc(copylen + 1 + 4); /* reserve space for use later add %$() chars */
+       envname = (char *)SMB_MALLOC(copylen + 1 + 4); /* reserve space for use later add %$() chars */
        if (envname == NULL) return NULL;
        strncpy(envname,r,copylen);
        envname[copylen] = '\0';
@@ -188,16 +306,17 @@ static char *automount_path(const char *user_name)
  moved out to a separate function.
 *******************************************************************/
 
-static char *automount_server(const char *user_name)
+static const char *automount_server(const char *user_name)
 {
        static pstring server_name;
+       const char *local_machine_name = get_local_machine_name(); 
 
        /* use the local machine name as the default */
        /* this will be the default if WITH_AUTOMOUNT is not used or fails */
-       if (*local_machine)
-               pstrcpy(server_name, local_machine);
+       if (local_machine_name && *local_machine_name)
+               pstrcpy(server_name, local_machine_name);
        else
-               pstrcpy(server_name, global_myname);
+               pstrcpy(server_name, global_myname());
        
 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
 
@@ -229,6 +348,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
        char *p, *s;
        fstring pidstr;
        struct passwd *pass;
+       const char *local_machine_name = get_local_machine_name();
 
        for (s=str; (p=strchr_m(s, '%'));s=p) {
                fstring tmp_str;
@@ -241,7 +361,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
                switch (*(p+1)) {
                case 'U' : 
                        fstrcpy(tmp_str, smb_name);
-                       strlower(tmp_str);
+                       strlower_m(tmp_str);
                        string_sub(p,"%U",tmp_str,l);
                        break;
                case 'G' :
@@ -254,17 +374,25 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
                        break;
                case 'D' :
                        fstrcpy(tmp_str, current_user_info.domain);
-                       strupper(tmp_str);
+                       strupper_m(tmp_str);
                        string_sub(p,"%D", tmp_str,l);
                        break;
                case 'I' :
                        string_sub(p,"%I", client_addr(),l);
                        break;
+               case 'i' :
+                       string_sub(p,"%i", client_socket_addr(),l);
+                       break;
                case 'L' : 
-                       if (*local_machine)
-                               string_sub(p,"%L", local_machine,l); 
-                       else
-                               string_sub(p,"%L", global_myname,l); 
+                       if (local_machine_name && *local_machine_name)
+                               string_sub(p,"%L", local_machine_name,l); 
+                       else {
+                               pstring temp_name;
+
+                               pstrcpy(temp_name, global_myname());
+                               strlower_m(temp_name);
+                               string_sub(p,"%L", temp_name,l); 
+                       }
                        break;
                case 'M' :
                        string_sub(p,"%M", client_name(),l);
@@ -286,10 +414,10 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
                        string_sub(p,"%h", myhostname(),l);
                        break;
                case 'm' :
-                       string_sub(p,"%m", remote_machine,l);
+                       string_sub(p,"%m", get_remote_machine_name(),l);
                        break;
                case 'v' :
-                       string_sub(p,"%v", VERSION,l);
+                       string_sub(p,"%v", SAMBA_VERSION_STRING,l);
                        break;
                case '$' :
                        p += expand_env_var(p,l);
@@ -330,7 +458,8 @@ static void standard_sub_advanced(int snum, const char *user,
                        string_sub(p,"%P", connectpath, l); 
                        break;
                case 'S': 
-                       string_sub(p,"%S", lp_servicename(snum), l); 
+                       if ( snum != -1 )
+                               string_sub(p,"%S", lp_servicename(snum), l); 
                        break;
                case 'g': 
                        string_sub(p,"%g", gidtoname(gid), l); 
@@ -347,7 +476,8 @@ static void standard_sub_advanced(int snum, const char *user,
                         * "path =" string in [homes] and so needs the
                         * service name, not the username.  */
                case 'p': 
-                       string_sub(p,"%p", automount_path(lp_servicename(snum)), l); 
+                       if ( snum != -1 )
+                               string_sub(p,"%p", automount_path(lp_servicename(snum)), l); 
                        break;
                case '\0': 
                        p++; 
@@ -381,8 +511,16 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
        char *b, *p, *s, *t, *r, *a_string;
        fstring pidstr;
        struct passwd *pass;
+       const char *local_machine_name = get_local_machine_name();
 
-       a_string = strdup(str);
+       /* workaround to prevent a crash while lookinf at bug #687 */
+       
+       if ( !str ) {
+               DEBUG(0,("alloc_sub_basic: NULL source string!  This should not happen\n"));
+               return NULL;
+       }
+       
+       a_string = SMB_STRDUP(str);
        if (a_string == NULL) {
                DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
                return NULL;
@@ -400,7 +538,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
                        t = realloc_string_sub(t, "%U", r);
                        break;
                case 'G' :
-                       r = strdup(smb_name);
+                       r = SMB_STRDUP(smb_name);
                        if (r == NULL) goto error;
                        if ((pass = Get_Pwnam(r))!=NULL) {
                                t = realloc_string_sub(t, "%G", gidtoname(pass->pw_gid));
@@ -415,10 +553,13 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
                        t = realloc_string_sub(t, "%I", client_addr());
                        break;
                case 'L' : 
-                       if (*local_machine)
-                               t = realloc_string_sub(t, "%L", local_machine); 
+                       if (local_machine_name && *local_machine_name)
+                               t = realloc_string_sub(t, "%L", local_machine_name); 
                        else
-                               t = realloc_string_sub(t, "%L", global_myname); 
+                               t = realloc_string_sub(t, "%L", global_myname()); 
+                       break;
+               case 'N':
+                       t = realloc_string_sub(t, "%N", automount_server(smb_name));
                        break;
                case 'M' :
                        t = realloc_string_sub(t, "%M", client_name());
@@ -443,7 +584,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
                        t = realloc_string_sub(t, "%m", remote_machine);
                        break;
                case 'v' :
-                       t = realloc_string_sub(t, "%v", VERSION);
+                       t = realloc_string_sub(t, "%v", SAMBA_VERSION_STRING);
                        break;
                case '$' :
                        t = realloc_expand_env_var(t, p); /* Expand environment variables */
@@ -494,7 +635,7 @@ char *alloc_sub_specified(const char *input_string,
        char *a_string, *ret_string;
        char *b, *p, *s, *t;
 
-       a_string = strdup(input_string);
+       a_string = SMB_STRDUP(input_string);
        if (a_string == NULL) {
                DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
                return NULL;
@@ -554,7 +695,7 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
                        const char *connectpath,
                        gid_t gid,
                        const char *smb_name,
-                       char *str)
+                       const char *str)
 {
        char *a, *t;
                a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str);
@@ -566,12 +707,12 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
 
 char *alloc_sub_advanced(int snum, const char *user, 
                                  const char *connectpath, gid_t gid, 
-                                 const char *smb_name, char *str)
+                                 const char *smb_name, const char *str)
 {
        char *a_string, *ret_string;
        char *b, *p, *s, *t, *h;
 
-       a_string = strdup(str);
+       a_string = SMB_STRDUP(str);
        if (a_string == NULL) {
                DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
                return NULL;
@@ -637,7 +778,20 @@ char *alloc_sub_advanced(int snum, const char *user,
 void standard_sub_conn(connection_struct *conn, char *str, size_t len)
 {
        standard_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
-                       conn->gid, current_user_info.smb_name, str, len);
+                       conn->gid, smb_user_name, str, len);
+}
+
+char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
+{
+       return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
+                       conn->connectpath, conn->gid,
+                       smb_user_name, str);
+}
+
+char *alloc_sub_conn(connection_struct *conn, const char *str)
+{
+       return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
+                       conn->gid, smb_user_name, str);
 }
 
 /****************************************************************************
@@ -657,6 +811,6 @@ void standard_sub_snum(int snum, char *str, size_t len)
                cached_uid = current_user.uid;
        }
 
-       standard_sub_advanced(snum, cached_user, "", -1,
-               current_user_info.smb_name, str, len);
+       standard_sub_advanced(snum, cached_user, "", current_user.gid,
+                             smb_user_name, str, len);
 }