Let the carnage begin....
[metze/old/v3-2-winbind-ndr.git] / source / lib / username.c
index 7d66b320adf8d61abd2aefdddd2b056bc1ba8ffe..c04dfd05da10ba05fca94ff264f190b6be1d3234 100644 (file)
 #include "includes.h"
 
 /* internal functions */
-static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (const char *), int N);
-static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (const char *), int N);
+static struct passwd *uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
+                                               struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
+                                               int N);
+static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset,
+                                                struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
+                                                int N);
 
 /*****************************************************************
  Check if a user or group name is local (this is a *local* name for
@@ -108,7 +112,7 @@ BOOL map_username(fstring user)
                }
 
                numlines = 0;
-               qlines = fd_lines_load(fd, &numlines);
+               qlines = fd_lines_load(fd, &numlines,0);
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
                close(fd);
 
@@ -180,7 +184,8 @@ BOOL map_username(fstring user)
                        return False;
                }
 
-               if (strchr_m(dosname,'*') || user_in_list(user, (const char **)dosuserlist, NULL, 0)) {
+               if (strchr_m(dosname,'*') ||
+                   user_in_list(user, (const char **)dosuserlist)) {
                        DEBUG(3,("Mapped user %s to %s\n",user,unixname));
                        mapped_user = True;
                        fstrcpy( last_from,user );
@@ -218,7 +223,8 @@ BOOL map_username(fstring user)
 
 static struct passwd *Get_Pwnam_ret = NULL;
 
-static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
+static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
+                                         const char *user, char *user2)
 {
        struct passwd *ret = NULL;
 
@@ -232,7 +238,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
           common case on UNIX systems */
        strlower_m(user2);
        DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
-       ret = getpwnam_alloc(user2);
+       ret = getpwnam_alloc(mem_ctx, user2);
        if(ret)
                goto done;
 
@@ -240,7 +246,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
        if(strcmp(user, user2) != 0) {
                DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",
                         user));
-               ret = getpwnam_alloc(user);
+               ret = getpwnam_alloc(mem_ctx, user);
                if(ret)
                        goto done;
        }
@@ -250,7 +256,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
        if(strcmp(user, user2) != 0) {
                DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
                         user2));
-               ret = getpwnam_alloc(user2);
+               ret = getpwnam_alloc(mem_ctx, user2);
                if(ret)
                        goto done;
        }
@@ -259,7 +265,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
        strlower_m(user2);
        DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",
                 lp_usernamelevel(), user2));
-       ret = uname_string_combinations(user2, getpwnam_alloc,
+       ret = uname_string_combinations(user2, mem_ctx, getpwnam_alloc,
                                        lp_usernamelevel());
 
 done:
@@ -275,7 +281,7 @@ done:
   This will return an allocated structure
 ****************************************************************************/
 
-struct passwd *Get_Pwnam_alloc(const char *user)
+struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
 {
        fstring user2;
        struct passwd *ret;
@@ -289,7 +295,7 @@ struct passwd *Get_Pwnam_alloc(const char *user)
 
        DEBUG(5,("Finding user %s\n", user));
 
-       ret = Get_Pwnam_internals(user, user2);
+       ret = Get_Pwnam_internals(mem_ctx, user, user2);
        
        return ret;  
 }
@@ -303,7 +309,7 @@ struct passwd *Get_Pwnam(const char *user)
 {
        struct passwd *ret;
 
-       ret = Get_Pwnam_alloc(user);
+       ret = Get_Pwnam_alloc(NULL, user);
        
        /* This call used to just return the 'passwd' static buffer.
           This could then have accidental reuse implications, so 
@@ -320,7 +326,7 @@ struct passwd *Get_Pwnam(const char *user)
        */
 
        if (Get_Pwnam_ret) {
-               passwd_free(&Get_Pwnam_ret);
+               talloc_free(Get_Pwnam_ret);
        }
        
        Get_Pwnam_ret = ret;
@@ -333,7 +339,7 @@ struct passwd *Get_Pwnam(const char *user)
  try lower case.
 ****************************************************************************/
 
-static BOOL user_in_netgroup_list(const char *user, const char *ngname)
+BOOL user_in_netgroup(const char *user, const char *ngname)
 {
 #ifdef HAVE_NETGROUP
        static char *mydomain = NULL;
@@ -351,7 +357,7 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
                user, mydomain, ngname));
 
        if (innetgr(ngname, NULL, user, mydomain)) {
-               DEBUG(5,("user_in_netgroup_list: Found\n"));
+               DEBUG(5,("user_in_netgroup: Found\n"));
                return (True);
        } else {
 
@@ -367,7 +373,7 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
                        lowercase_user, mydomain, ngname));
 
                if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
-                       DEBUG(5,("user_in_netgroup_list: Found\n"));
+                       DEBUG(5,("user_in_netgroup: Found\n"));
                        return (True);
                }
        }
@@ -379,8 +385,8 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
  Check if a user is in a winbind group.
 ****************************************************************************/
   
-static BOOL user_in_winbind_group_list(const char *user, const char *gname,
-                                      BOOL *winbind_answered)
+static BOOL user_in_winbind_group(const char *user, const char *gname,
+                                 BOOL *winbind_answered)
 {
        int i;
        gid_t gid, gid_low, gid_high;
@@ -392,7 +398,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
        *winbind_answered = False;
  
        if ((gid = nametogid(gname)) == (gid_t)-1) {
-               DEBUG(0,("user_in_winbind_group_list: nametogid for group %s "
+               DEBUG(0,("user_in_winbind_group: nametogid for group %s "
                         "failed.\n", gname ));
                goto err;
        }
@@ -439,11 +445,11 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
                
        }
        else 
-               DEBUG(10,("user_in_winbind_group_list: using cached user "
+               DEBUG(10,("user_in_winbind_group: using cached user "
                          "groups for [%s]\n", user));
  
        if ( DEBUGLEVEL >= 10 ) {
-               DEBUG(10,("user_in_winbind_group_list: using groups -- "));
+               DEBUG(10,("user_in_winbind_group: using groups -- "));
                for ( i=0; i<num_groups; i++ )
                        DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
                DEBUGADD(10,("\n"));    
@@ -477,13 +483,13 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
  Check if a user is in a UNIX group.
 ****************************************************************************/
 
-BOOL user_in_unix_group_list(const char *user,const char *gname)
+BOOL user_in_unix_group(const char *user,const char *gname)
 {
        struct passwd *pass = Get_Pwnam(user);
        struct sys_userlist *user_list;
        struct sys_userlist *member;
 
-       DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n",
+       DEBUG(10,("user_in_unix_group: checking user %s in group %s\n",
                  user, gname));
 
        /*
@@ -493,7 +499,7 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
  
        if (pass) {
                if (strequal(gname,gidtoname(pass->pw_gid))) {
-                       DEBUG(10,("user_in_unix_group_list: group %s is "
+                       DEBUG(10,("user_in_unix_group: group %s is "
                                  "primary group.\n", gname ));
                        return True;
                }
@@ -501,13 +507,13 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
  
        user_list = get_users_in_group(gname);
        if (user_list == NULL) {
-               DEBUG(10,("user_in_unix_group_list: no such group %s\n",
+               DEBUG(10,("user_in_unix_group: no such group %s\n",
                          gname ));
                return False;
        }
 
        for (member = user_list; member; member = member->next) {
-               DEBUG(10,("user_in_unix_group_list: checking user %s against "
+               DEBUG(10,("user_in_unix_group: checking user %s against "
                          "member %s\n", user, member->unix_name ));
                if (strequal(member->unix_name,user)) {
                        free_userlist(user_list);
@@ -523,35 +529,17 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
  Check if a user is in a group list. Ask winbind first, then use UNIX.
 ****************************************************************************/
 
-BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups,
-                       size_t n_groups)
+BOOL user_in_group(const char *user, const char *gname)
 {
        BOOL winbind_answered = False;
        BOOL ret;
-       gid_t gid;
-       unsigned i;
 
-       gid = nametogid(gname);
-       if (gid == (gid_t)-1) 
-               return False;
-
-       if (groups && n_groups > 0) {
-               for (i=0; i < n_groups; i++) {
-                       if (groups[i] == gid) {
-                               return True;
-                       }
-               }
-               return False;
-       }
-
-       /* fallback if we don't yet have the group list */
-
-       ret = user_in_winbind_group_list(user, gname, &winbind_answered);
+       ret = user_in_winbind_group(user, gname, &winbind_answered);
        if (!winbind_answered)
-               ret = user_in_unix_group_list(user, gname);
+               ret = user_in_unix_group(user, gname);
 
        if (ret)
-               DEBUG(10,("user_in_group_list: user |%s| is in group |%s|\n",
+               DEBUG(10,("user_in_group: user |%s| is in group |%s|\n",
                          user, gname));
        return ret;
 }
@@ -561,8 +549,7 @@ BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups,
  and netgroup lists.
 ****************************************************************************/
 
-BOOL user_in_list(const char *user,const char **list, gid_t *groups,
-                 size_t n_groups)
+BOOL user_in_list(const char *user,const char **list)
 {
        if (!list || !*list)
                return False;
@@ -590,10 +577,9 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
                         * Old behaviour. Check netgroup list
                         * followed by UNIX list.
                         */
-                       if(user_in_netgroup_list(user, *list +1))
+                       if(user_in_netgroup(user, *list +1))
                                return True;
-                       if(user_in_group_list(user, *list +1, groups,
-                                             n_groups))
+                       if(user_in_group(user, *list +1))
                                return True;
                } else if (**list == '+') {
 
@@ -601,10 +587,9 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
                                /*
                                 * Search UNIX list followed by netgroup.
                                 */
-                               if(user_in_group_list(user, *list +2, groups,
-                                                     n_groups))
+                               if(user_in_group(user, *list +2))
                                        return True;
-                               if(user_in_netgroup_list(user, *list +2))
+                               if(user_in_netgroup(user, *list +2))
                                        return True;
 
                        } else {
@@ -613,8 +598,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
                                 * Just search UNIX list.
                                 */
 
-                               if(user_in_group_list(user, *list +1, groups,
-                                                     n_groups))
+                               if(user_in_group(user, *list +1))
                                        return True;
                        }
 
@@ -624,16 +608,15 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
                                /*
                                 * Search netgroup list followed by UNIX list.
                                 */
-                               if(user_in_netgroup_list(user, *list +2))
+                               if(user_in_netgroup(user, *list +2))
                                        return True;
-                               if(user_in_group_list(user, *list +2, groups,
-                                                     n_groups))
+                               if(user_in_group(user, *list +2))
                                        return True;
                        } else {
                                /*
                                 * Just search netgroup list.
                                 */
-                               if(user_in_netgroup_list(user, *list +1))
+                               if(user_in_netgroup(user, *list +1))
                                        return True;
                        }
                } else if (!name_is_local(*list)) {
@@ -676,7 +659,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
                                        
                                        /* Check if user name is in the
                                         * Windows group */
-                                       ret = user_in_winbind_group_list(
+                                       ret = user_in_winbind_group(
                                                user, *list,
                                                &winbind_answered);
                                        
@@ -705,21 +688,24 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
  it assumes the string starts lowercased
 ****************************************************************************/
 
-static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(const char *),int N)
+static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
+                                                int offset,
+                                                struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
+                                                int N)
 {
        ssize_t len = (ssize_t)strlen(s);
        int i;
        struct passwd *ret;
 
        if (N <= 0 || offset >= len)
-               return(fn(s));
+               return(fn(mem_ctx, s));
 
        for (i=offset;i<(len-(N-1));i++) {
                char c = s[i];
                if (!islower_ascii((int)c))
                        continue;
                s[i] = toupper_ascii(c);
-               ret = uname_string_combinations2(s,i+1,fn,N-1);
+               ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
                if(ret)
                        return(ret);
                s[i] = c;
@@ -735,13 +721,15 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
  it assumes the string starts lowercased
 ****************************************************************************/
 
-static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(const char *),int N)
+static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
+                                                struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
+                                                int N)
 {
        int n;
        struct passwd *ret;
 
        for (n=1;n<=N;n++) {
-               ret = uname_string_combinations2(s,0,fn,n);
+               ret = uname_string_combinations2(s,mem_ctx,0,fn,n);
                if(ret)
                        return(ret);
        }