From 43e325d99167179cb7000451e252dcde7f0eb1a0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Dec 2001 21:51:09 +0000 Subject: Added the group enum code from 2.2 Jeremy. (This used to be commit 59e01a22c5cb1046758c8cd6b09333c19d6cd26e) --- source3/Makefile.in | 7 ++-- source3/include/util_getent.h | 24 +++++++++--- source3/lib/username.c | 28 +++++++------- source3/lib/util_getent.c | 81 +++++++++++++++++++++++++++++++++++++++ source3/nsswitch/winbindd_proto.h | 1 + 5 files changed, 118 insertions(+), 23 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index a2f92180cc..d345cdf8a6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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 \ diff --git a/source3/include/util_getent.h b/source3/include/util_getent.h index 877d272ceb..5d4674ddef 100644 --- a/source3/include/util_getent.h +++ b/source3/include/util_getent.h @@ -22,9 +22,10 @@ #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 */ diff --git a/source3/lib/username.c b/source3/lib/username.c index 3562ab3b95..e65f133812 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -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; } diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c index 4393debaba..81b36effcb 100644 --- a/source3/lib/util_getent.c +++ b/source3/lib/util_getent.c @@ -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); + } +} diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index 9de38a3543..d50469d978 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -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); -- cgit