Added the group enum code from 2.2
authorJeremy Allison <jra@samba.org>
Fri, 14 Dec 2001 21:51:09 +0000 (21:51 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 14 Dec 2001 21:51:09 +0000 (21:51 +0000)
Jeremy.

source/Makefile.in
source/include/util_getent.h
source/lib/username.c
source/lib/util_getent.c
source/nsswitch/winbindd_proto.h

index a2f92180cc03a9579cbd5014f6dac9efbef5fb21..d345cdf8a61a91f9eb84b9aedcf443a9a7212709 100644 (file)
@@ -114,7 +114,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
           lib/getsmbpass.o lib/interface.o lib/md4.o \
           lib/interfaces.o lib/pidfile.o lib/replace.o \
           lib/signal.o lib/system.o lib/time.o \
-         lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
+         lib/ufc.o lib/genrand.o lib/username.o lib/util_getent.o lib/access.o lib/smbrun.o \
          lib/bitmap.o lib/crc32.o lib/snprintf.o lib/dprintf.o lib/xfile.o lib/wins_srv.o \
          lib/util_str.o lib/util_sid.o \
          lib/util_unistr.o lib/util_file.o lib/sysacls.o \
@@ -160,8 +160,7 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
                  rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \
                  rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \
                  rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \
-                 rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o \
-                lib/util_getent.o
+                 rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
 
 # this includes only the low level parse code, not stuff
 # that requires knowledge of security contexts
@@ -403,7 +402,7 @@ PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
                lib/wins_srv.o lib/substitute.o lib/select.o lib/util.o \
                nsswitch/wb_client.o nsswitch/wb_common.o \
                lib/system.o lib/util_file.o \
-               lib/genrand.o lib/username.o lib/charcnv.o lib/time.o \
+               lib/genrand.o lib/username.o lib/util_getent.o lib/charcnv.o lib/time.o \
                lib/md4.o lib/util_unistr.o lib/signal.o lib/talloc.o \
                lib/ms_fnmatch.o lib/util_sock.o lib/smbrun.o \
                lib/util_sec.o \
index 877d272cebeb7fb734f8887b08db7ba53788f555..5d4674ddefafdfbff91fab2227196b4255971399 100644 (file)
 #ifndef _UTIL_GETENT_H
 #define _UTIL_GETENT_H
 
-/* element for a single linked list of group entries */
-/* replace the use of struct group in some cases */
-/* used by getgrent_list() */
+/* Element for a single linked list of group entries */
+/* Replace the use of struct group in some cases */
+/* Used by getgrent_list() */
+
 struct sys_grent {
        char *gr_name;
        char *gr_passwd;
@@ -33,9 +34,10 @@ struct sys_grent {
        struct sys_grent *next;
 };
 
-/* element for a single linked list of passwd entries */
-/* replace the use of struct passwd in some cases */
-/* used by getpwent_list() */
+/* Element for a single linked list of passwd entries */
+/* Replace the use of struct passwd in some cases */
+/* Used by getpwent_list() */
+
 struct sys_pwent {
        char *pw_name;
        char *pw_passwd;
@@ -47,4 +49,14 @@ struct sys_pwent {
        struct sys_pwent *next;
 };
 
+/* Element for a single linked list of user names in a group. */
+/* Used to return group lists that may span multiple lines in 
+   /etc/group file. */
+/* Used by get_users_in_group() */
+
+struct sys_userlist {
+       struct sys_userlist *next, *prev;
+       char *unix_name;
+};
+
 #endif /* _UTIL_GETENT_H */
index 3562ab3b958a68f57a114c83b645f488fe10bfc3..e65f1338123ece34d83fa5d0687a2b335c153914 100644 (file)
@@ -344,10 +344,10 @@ failed with error %s\n", strerror(errno) ));
                goto err;
        }
  
-       /*
-        * Now we have the gid list for this user - convert the gname
-        * to a gid_t via either winbind or the local UNIX lookup and do the comparison.
-        */
+       /*
+        * Now we have the gid list for this user - convert the gname
+        * to a gid_t via either winbind or the local UNIX lookup and do the comparison.
+        */
  
        if ((gid = nametogid(gname)) == (gid_t)-1) {
                DEBUG(0,("user_in_winbind_group_list: winbind_lookup_name for group %s failed.\n",
@@ -379,9 +379,9 @@ failed with error %s\n", strerror(errno) ));
 
 static BOOL user_in_unix_group_list(const char *user,const char *gname)
 {
-       struct group *gptr;
-       char **member;  
        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", user, gname));
 
@@ -397,20 +397,22 @@ static BOOL user_in_unix_group_list(const char *user,const char *gname)
                }
        }
  
-       if ((gptr = (struct group *)getgrnam(gname)) == NULL) {
+       user_list = get_users_in_group(gname);
+       if (user_list == NULL) {
                DEBUG(10,("user_in_unix_group_list: no such group %s\n", gname ));
                return False;
        }
-       member = gptr->gr_mem;
-       while (member && *member) {
-               DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n", user, *member ));
-               if (strequal(*member,user)) {
+
+       for (member = user_list; member; member = member->next) {
+               DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n",
+                       user, member->unix_name ));
+               if (strequal(member->unix_name,user)) {
+                       free_userlist(user_list);
                        return(True);
                }
-               member++;
        }
 
+       free_userlist(user_list);
        return False;
 }            
 
index 4393debabaec3bbe82eb82dc38267c82006527e5..81b36effcb48143055308c7844e1d5cd7951d0b8 100644 (file)
@@ -3,6 +3,7 @@
    Version 3.0
    Samba utility functions
    Copyright (C) Simo Sorce 2001
+   Copyright (C) Jeremy Allison 2001
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -230,3 +231,83 @@ void pwent_free (struct sys_pwent *plist)
                SAFE_FREE(prev);
        }
 }
+
+/****************************************************************
+ Add the individual group users onto the list.
+****************************************************************/
+
+static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp)
+{
+       size_t num_users, i;
+
+       /* Count the number of users. */
+       for (num_users = 0; grp->gr_mem[num_users]; num_users++)
+               ;
+
+       for (i = 0; i < num_users; i++) {
+               struct sys_userlist *entry = (struct sys_userlist *)malloc(sizeof(*entry));
+               size_t len = strlen(grp->gr_mem[i])+1;
+               if (entry == NULL) {
+                       free_userlist(list_head);
+                       return NULL;
+               }
+               entry->unix_name = (char *)malloc(len);
+               if (entry->unix_name == NULL) {
+                       SAFE_FREE(entry);
+                       free_userlist(list_head);
+                       return NULL;
+               }
+               safe_strcpy(entry->unix_name, grp->gr_mem[i],len);
+               DLIST_ADD(list_head, entry);
+       }
+       return list_head;
+}
+
+/****************************************************************
+ Get the list of UNIX users in a group.
+ We have to enumerate the /etc/group file as some UNIX getgrnam()
+ calls won't do that for us (notably Tru64 UNIX).
+****************************************************************/
+
+struct sys_userlist *get_users_in_group(const char *gname)
+{
+       struct sys_userlist *list_head = NULL;
+       struct group *gptr;
+
+       /*
+        * If we're doing this via winbindd, don't do the
+        * entire group list enumeration as we know this is
+        * pointless (and slow).
+        */
+
+       if (strchr(gname,*lp_winbind_separator())) {
+               if ((gptr = (struct group *)getgrnam(gname)) == NULL)
+                       return NULL;
+               return add_members_to_userlist(list_head, gptr);
+       }
+
+       setgrent();
+       while((gptr = getgrent()) != NULL) {
+               if (strequal(gname, gptr->gr_name)) {
+                       list_head = add_members_to_userlist(list_head, gptr);
+                       if (list_head == NULL)
+                               return NULL;
+               }
+       }
+       endgrent();
+       return list_head;
+}
+
+/****************************************************************
+ Free list allocated above.
+****************************************************************/
+
+void free_userlist(struct sys_userlist *list_head)
+{
+       while (list_head) {
+               struct sys_userlist *old_head = list_head;
+               DLIST_REMOVE(list_head, list_head);
+               SAFE_FREE(old_head->unix_name);
+               SAFE_FREE(old_head);
+       }
+}
index 9de38a35436cc40970c9daf8b7e4496e44844315..d50469d978eae2943bfed60df7fe019eef9522a2 100644 (file)
@@ -26,6 +26,7 @@ struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status
 
 /* The following definitions come from nsswitch/winbindd_cm.c  */
 
+void cm_init_creds(struct ntuser_creds *creds);
 CLI_POLICY_HND *cm_get_lsa_handle(char *domain);
 CLI_POLICY_HND *cm_get_sam_handle(char *domain);
 CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid);