Remove Get_Pwnam and its associated static variable
authorVolker Lendecke <vl@samba.org>
Wed, 19 Dec 2007 14:02:59 +0000 (15:02 +0100)
committerVolker Lendecke <vl@samba.org>
Wed, 19 Dec 2007 20:09:10 +0000 (21:09 +0100)
All callers are replaced by Get_Pwnam_alloc
(This used to be commit 735f59315497113aebadcf9ad387e3dbfffa284a)

12 files changed:
source3/auth/auth_unix.c
source3/lib/substitute.c
source3/lib/username.c
source3/param/loadparm.c
source3/passdb/pdb_interface.c
source3/rpc_server/srv_samr_nt.c
source3/smbd/chgpasswd.c
source3/smbd/map_username.c
source3/smbd/password.c
source3/smbd/service.c
source3/utils/net_rpc_samsync.c
source3/winbindd/idmap_nss.c

index 4fca5bcbe4c79b819e499179b01e3c2c989fe578..58c765226d633c707d05a9923e6588eb987da44b 100644 (file)
@@ -92,7 +92,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context,
        struct passwd *pass = NULL;
 
        become_root();
-       pass = Get_Pwnam(user_info->internal_username);
+       pass = Get_Pwnam_alloc(talloc_tos(), user_info->internal_username);
 
        
        /** @todo This call assumes a ASCII password, no charset transformation is 
@@ -123,6 +123,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context,
                }
        }
 
+       TALLOC_FREE(pass);
        return nt_status;
 }
 
index e06917c8fbe24d3140526236503a04dd18c67e33..80feee95790d4323d418d3d263837827fa8b6cf8 100644 (file)
@@ -408,7 +408,7 @@ static const char *automount_path(const char *user_name)
        /* use the passwd entry as the default */
        /* this will be the default if WITH_AUTOMOUNT is not used or fails */
 
-       server_path = talloc_strdup(ctx, get_user_home_dir(user_name));
+       server_path = talloc_strdup(ctx, get_user_home_dir(ctx, user_name));
        if (!server_path) {
                return "";
        }
@@ -541,7 +541,6 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name,
 {
        char *b, *p, *s, *r, *a_string;
        fstring pidstr, vnnstr;
-       struct passwd *pass;
        char addr[INET6_ADDRSTRLEN];
        const char *local_machine_name = get_local_machine_name();
 
@@ -571,15 +570,21 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name,
                        }
                        a_string = realloc_string_sub(a_string, "%U", r);
                        break;
-               case 'G' :
+               case 'G' : {
+                       struct passwd *pass;
                        r = SMB_STRDUP(smb_name);
                        if (r == NULL) {
                                goto error;
                        }
-                       if ((pass = Get_Pwnam(r))!=NULL) {
-                               a_string = realloc_string_sub(a_string, "%G", gidtoname(pass->pw_gid));
-                       } 
+                       pass = Get_Pwnam_alloc(talloc_tos(), r);
+                       if (pass != NULL) {
+                               a_string = realloc_string_sub(
+                                       a_string, "%G",
+                                       gidtoname(pass->pw_gid));
+                       }
+                       TALLOC_FREE(pass);
                        break;
+               }
                case 'D' :
                        r = strdup_upper(domain_name);
                        if (r == NULL) {
@@ -766,7 +771,7 @@ static char *alloc_sub_advanced(const char *servicename, const char *user,
                         const char *str)
 {
        char *a_string, *ret_string;
-       char *b, *p, *s, *h;
+       char *b, *p, *s;
 
        a_string = SMB_STRDUP(str);
        if (a_string == NULL) {
@@ -782,10 +787,13 @@ static char *alloc_sub_advanced(const char *servicename, const char *user,
                case 'N' :
                        a_string = realloc_string_sub(a_string, "%N", automount_server(user));
                        break;
-               case 'H':
-                       if ((h = get_user_home_dir(user)))
+               case 'H': {
+                       char *h;
+                       if ((h = get_user_home_dir(talloc_tos(), user)))
                                a_string = realloc_string_sub(a_string, "%H", h);
+                       TALLOC_FREE(h);
                        break;
+               }
                case 'P': 
                        a_string = realloc_string_sub(a_string, "%P", connectpath); 
                        break;
index 21eed9f5fc3cd2c5e7be5fe0e0846e155d34eb46..3087bac0f4b1ec50d188a3bc6467959e69d0da01 100644 (file)
@@ -32,19 +32,24 @@ static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, i
  Get a users home directory.
 ****************************************************************************/
 
-char *get_user_home_dir(const char *user)
+char *get_user_home_dir(TALLOC_CTX *mem_ctx, const char *user)
 {
-       static struct passwd *pass;
+       struct passwd *pass;
+       char *result;
 
        /* Ensure the user exists. */
 
-       pass = Get_Pwnam(user);
+       pass = Get_Pwnam_alloc(mem_ctx, user);
 
        if (!pass)
                return(NULL);
+
        /* Return home directory from struct passwd. */
 
-       return(pass->pw_dir);      
+       result = talloc_move(mem_ctx, &pass->pw_dir);
+
+       TALLOC_FREE(pass);
+       return result;
 }
 
 /****************************************************************************
@@ -55,8 +60,6 @@ char *get_user_home_dir(const char *user)
  *   - using lp_usernamelevel() for permutations.
 ****************************************************************************/
 
-static struct passwd *Get_Pwnam_ret = NULL;
-
 static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
                                          const char *user, char *user2)
 {
@@ -134,40 +137,6 @@ struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
        return ret;  
 }
 
-/****************************************************************************
- Get_Pwnam wrapper without modification.
-  NOTE: This with NOT modify 'user'! 
-****************************************************************************/
-
-struct passwd *Get_Pwnam(const char *user)
-{
-       struct passwd *ret;
-
-       ret = Get_Pwnam_alloc(NULL, user);
-       
-       /* This call used to just return the 'passwd' static buffer.
-          This could then have accidental reuse implications, so 
-          we now malloc a copy, and free it in the next use.
-
-          This should cause the (ab)user to segfault if it 
-          uses an old struct. 
-          
-          This is better than useing the wrong data in security
-          critical operations.
-
-          The real fix is to make the callers free the returned 
-          malloc'ed data.
-       */
-
-       if (Get_Pwnam_ret) {
-               TALLOC_FREE(Get_Pwnam_ret);
-       }
-       
-       Get_Pwnam_ret = ret;
-
-       return ret;  
-}
-
 /* The functions below have been taken from password.c and slightly modified */
 /****************************************************************************
  Apply a function to upper/lower case combinations
index eea3ecec2b592deb899d60ae1b7d6e74575900b1..4eb8a1ce655b050eeecf64692517586e39d15d65 100644 (file)
@@ -4702,13 +4702,17 @@ static void lp_add_auto_services(char *str)
        homes = lp_servicenumber(HOMES_NAME);
 
        for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
-               char *home = get_user_home_dir(p);
+               char *home;
 
                if (lp_servicenumber(p) >= 0)
                        continue;
 
+               home = get_user_home_dir(talloc_tos(), p);
+
                if (home && homes >= 0)
                        lp_add_home(p, homes, p, home);
+
+               TALLOC_FREE(home);
        }
        SAFE_FREE(s);
 }
index ed6a91cb2b53312ae38bb7f0861d0cb61179536c..198960550be8d9f7dcaa70c298eb3d1c40296120 100644 (file)
@@ -1570,11 +1570,12 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
                        return True;
                }
 
-               pw = Get_Pwnam(*name);
+               pw = Get_Pwnam_alloc(talloc_tos(), *name);
                if (pw == NULL) {
                        return False;
                }
                unix_id->uid = pw->pw_uid;
+               TALLOC_FREE(pw);
                return True;
        }
        TALLOC_FREE(sam_account);
index cc4b4f330f29f08fdca1e855753269206c7732af..1d69cb320e67b38ca84a4ebcb33feb25f383c374 100644 (file)
@@ -3325,7 +3325,8 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
                                return NT_STATUS_ACCESS_DENIED;
                        }
 
-                       if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
+                       passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
+                       if (passwd == NULL) {
                                DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
                        }
 
@@ -3333,6 +3334,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
                                TALLOC_FREE(pwd);
                                return NT_STATUS_ACCESS_DENIED;
                        }
+                       TALLOC_FREE(passwd);
                }
        }
 
@@ -3406,7 +3408,8 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
                                return False;
                        }
 
-                       if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
+                       passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
+                       if (passwd == NULL) {
                                DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
                        }
 
@@ -3414,6 +3417,7 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
                                TALLOC_FREE(pwd);
                                return False;
                        }
+                       TALLOC_FREE(passwd);
                }
        }
 
index e478122e9b701a518419e8a60705f42e1098c1f3..fb228f9e2a682c518aaeaf8a9c63f8b86853584a 100644 (file)
@@ -1142,7 +1142,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
                return NT_STATUS_PASSWORD_RESTRICTION;
        }
 
-       pass = Get_Pwnam(username);
+       pass = Get_Pwnam_alloc(talloc_tos(), username);
        if (!pass) {
                DEBUG(1, ("change_oem_password: Username %s does not exist in system !?!\n", username));
                return NT_STATUS_ACCESS_DENIED;
@@ -1160,6 +1160,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
                        if (samr_reject_reason) {
                                *samr_reject_reason = REJECT_REASON_NOT_COMPLEX;
                        }
+                       TALLOC_FREE(pass);
                        return NT_STATUS_PASSWORD_RESTRICTION;
                }
        }
@@ -1178,9 +1179,12 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
        
        if(lp_unix_password_sync() &&
                !chgpasswd(username, pass, old_passwd, new_passwd, as_root)) {
+               TALLOC_FREE(pass);
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       TALLOC_FREE(pass);
+
        if (!pdb_set_plaintext_passwd (hnd, new_passwd)) {
                return NT_STATUS_ACCESS_DENIED;
        }
index bde755eff6a40a4f20407f00d183837d209ad3dd..7290f7054722c4a40b80de193a0c29c435e0a987 100644 (file)
@@ -28,7 +28,7 @@
  any incoming or new username - in order to canonicalize the name.
  This is being done to de-couple the case conversions from the user mapping
  function. Previously, the map_username was being called
- every time Get_Pwnam was called.
+ every time Get_Pwnam_alloc was called.
  Returns True if username was changed, false otherwise.
 ********************************************************************/
 
index b3005ba0824b4bdab83ebdca4305f098ab48191b..6b517c3d862cc15be2191e844bb9d47888c129bc 100644 (file)
@@ -837,9 +837,11 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,
 
        /* check for a normal guest connection */
        if (!ok && GUEST_OK(snum)) {
+               struct passwd *guest_pw;
                fstring guestname;
                fstrcpy(guestname,lp_guestaccount());
-               if (Get_Pwnam(guestname)) {
+               guest_pw = Get_Pwnam_alloc(talloc_tos(), guestname);
+               if (guest_pw != NULL) {
                        fstrcpy(user,guestname);
                        ok = True;
                        DEBUG(3,("authorise_login: ACCEPTED: guest account "
@@ -848,6 +850,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,
                        DEBUG(0,("authorise_login: Invalid guest account "
                                 "%s??\n",guestname));
                }
+               TALLOC_FREE(guest_pw);
                *guest = True;
        }
 
index 88ab9f0048c30e800650d4e3489b497ecae5d965..ed43528c76d011446fc66cd727f963f86eee0de7 100644 (file)
@@ -357,6 +357,7 @@ void load_registry_shares(void)
 int find_service(fstring service)
 {
        int iService;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        all_string_sub(service,"\\","/",0);
 
@@ -364,7 +365,7 @@ int find_service(fstring service)
 
        /* now handle the special case of a home directory */
        if (iService < 0) {
-               char *phome_dir = get_user_home_dir(service);
+               char *phome_dir = get_user_home_dir(talloc_tos(), service);
 
                if(!phome_dir) {
                        /*
@@ -372,7 +373,8 @@ int find_service(fstring service)
                         * be a Windows to unix mapped user name.
                         */
                        if(map_username(service))
-                               phome_dir = get_user_home_dir(service);
+                               phome_dir = get_user_home_dir(
+                                       talloc_tos(), service);
                }
 
                DEBUG(3,("checking for home directory %s gave %s\n",service,
@@ -461,6 +463,8 @@ int find_service(fstring service)
        if (iService < 0)
                DEBUG(3,("find_service() failed to find service %s\n", service));
 
+       TALLOC_FREE(frame);
+
        return (iService);
 }
 
@@ -744,11 +748,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                        *status = NT_STATUS_WRONG_PASSWORD;
                        return NULL;
                }
-               pass = Get_Pwnam(user);
+               pass = Get_Pwnam_alloc(talloc_tos(), user);
                status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
                                                     &conn->uid, &conn->gid,
                                                     &found_username,
                                                     &conn->nt_user_token);
+               TALLOC_FREE(pass);
                if (!NT_STATUS_IS_OK(status2)) {
                        conn_free(conn);
                        *status = status2;
index ca3279ee3acc6274aea2976fbb69f980baf23714..779006884d0e1d968519b491dd1a0e0cbebb9547 100644 (file)
@@ -486,7 +486,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!(passwd = Get_Pwnam(account))) {
+       if (!(passwd = Get_Pwnam_alloc(sam_account, account))) {
                /* Create appropriate user */
                if (delta->acb_info & ACB_NORMAL) {
                        add_script = talloc_strdup(sam_account,
@@ -525,7 +525,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                }
 
                /* try and find the possible unix account again */
-               if ( !(passwd = Get_Pwnam(account)) ) {
+               if ( !(passwd = Get_Pwnam_alloc(sam_account, account)) ) {
                        d_fprintf(stderr, "Could not create posix account info for '%s'\n", account);
                        nt_ret = NT_STATUS_NO_SUCH_USER;
                        goto done;
index fa9f2c96812c320c35fc8a6734af21050d31ee5c..46c24d7fcb95629436f4976c0d5de617bb95d383 100644 (file)
@@ -145,7 +145,6 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        }
 
        for (i = 0; ids[i]; i++) {
-               struct passwd *pw;
                struct group *gr;
                enum lsa_SidType type;
                const char *dom_name = NULL;
@@ -166,17 +165,20 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
                }
 
                switch (type) {
-               case SID_NAME_USER:
+               case SID_NAME_USER: {
+                       struct passwd *pw;
 
                        /* this will find also all lower case name and use username level */
-                       
-                       pw = Get_Pwnam(name);
+
+                       pw = Get_Pwnam_alloc(talloc_tos(), name);
                        if (pw) {
                                ids[i]->xid.id = pw->pw_uid;
                                ids[i]->xid.type = ID_TYPE_UID;
                                ids[i]->status = ID_MAPPED;
                        }
+                       TALLOC_FREE(pw);
                        break;
+               }
 
                case SID_NAME_DOM_GRP:
                case SID_NAME_ALIAS: