diff options
| -rw-r--r-- | source3/Makefile.in | 7 | ||||
| -rw-r--r-- | source3/include/util_getent.h | 24 | ||||
| -rw-r--r-- | source3/lib/username.c | 28 | ||||
| -rw-r--r-- | source3/lib/util_getent.c | 81 | ||||
| -rw-r--r-- | source3/nsswitch/winbindd_proto.h | 1 | 
5 files changed, 118 insertions, 23 deletions
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);  | 
