svn commit: samba r19271 - in branches/SAMBA_3_0/source/nsswitch: .

jra at samba.org jra at samba.org
Sat Oct 14 00:33:04 GMT 2006


Author: jra
Date: 2006-10-14 00:33:03 +0000 (Sat, 14 Oct 2006)
New Revision: 19271

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19271

Log:
Test the "hack" for "Domain Users" as agreed with
Jerry. 
If "enum users" is set to false, and the group being looked
up is the Domain Users SID: S-1-5-domain-513, then for the
list of members check if the querying user is in that group,
and if so only return that user as the gr_mem array.
We can change this to a different parameter than "enum users"
if neccessaey, or parameterize the group list we do this for.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/nsswitch/winbindd_group.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_group.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_group.c	2006-10-13 23:43:27 UTC (rev 19270)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_group.c	2006-10-14 00:33:03 UTC (rev 19271)
@@ -57,6 +57,7 @@
 /* Fill in the group membership field of a NT group given by group_sid */
 
 static BOOL fill_grent_mem(struct winbindd_domain *domain,
+			   struct winbindd_cli_state *state,
 			   DOM_SID *group_sid, 
 			   enum lsa_SidType group_name_type, 
 			   size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len)
@@ -64,11 +65,12 @@
 	DOM_SID *sid_mem = NULL;
 	uint32 num_names = 0;
 	uint32 *name_types = NULL;
-	unsigned int buf_len, buf_ndx, i;
-	char **names = NULL, *buf;
+	unsigned int buf_len = 0, buf_ndx = 0, i;
+	char **names = NULL, *buf = NULL;
 	BOOL result = False;
 	TALLOC_CTX *mem_ctx;
 	NTSTATUS status;
+	uint32 group_rid;
 	fstring sid_string;
 
 	if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name)))
@@ -98,13 +100,124 @@
                 goto done;
 	}
 
+	/* OPTIMIZATION / HACK. */
+	/* If "enum users" is set to false, and the group being looked
+	   up is the Domain Users SID: S-1-5-domain-513, then for the
+	   list of members check if the querying user is in that group,
+	   and if so only return that user as the gr_mem array.
+	   We can change this to a different parameter than "enum users"
+	   if neccessaey, or parameterize the group list we do this for. */
+
+	sid_peek_rid( group_sid, &group_rid );
+	if (!lp_winbind_enum_users() && group_rid == DOMAIN_GROUP_RID_USERS) {
+		DOM_SID querying_user_sid;
+		DOM_SID *pquerying_user_sid = NULL;
+		uint32 num_groups = 0;
+		DOM_SID *user_sids = NULL;
+		BOOL u_in_group = False;
+
+		DEBUG(10,("fill_grent_mem: optimized lookup for sid %s domain %s\n",
+			sid_to_string(sid_string, group_sid), domain->name ));
+
+		if (state) {
+			uid_t ret_uid = (uid_t)-1;
+			if (sys_getpeereid(state->sock, &ret_uid)==0) {
+				/* We know who's asking - look up their SID if
+				   it's one we've mapped before. */
+				status = idmap_uid_to_sid(&querying_user_sid,
+							ret_uid,
+							IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY);
+				if (NT_STATUS_IS_OK(status)) {
+					pquerying_user_sid = &querying_user_sid;
+					DEBUG(10,("fill_grent_mem: querying uid %u -> %s\n",
+						(unsigned int)ret_uid,
+						sid_to_string(sid_string, pquerying_user_sid) ));
+				}
+			}
+		}
+
+		/* Only look up if it was a winbindd user in this domain. */
+		if (pquerying_user_sid &&
+				(sid_compare_domain(pquerying_user_sid, &domain->sid) == 0)) {
+
+			DEBUG(10,("fill_grent_mem: querying user = %s\n",
+				sid_to_string(sid_string, pquerying_user_sid) ));
+
+			status = domain->methods->lookup_usergroups(domain,
+							mem_ctx,
+							pquerying_user_sid,
+							&num_groups,
+							&user_sids);
+			if (!NT_STATUS_IS_OK(status)) {
+				DEBUG(1, ("fill_grent_mem: lookup_usergroups failed "
+					"for sid %s in domain %s (error: %s)\n", 
+					sid_to_string(sid_string, pquerying_user_sid),
+					domain->name,
+					nt_errstr(status)));
+				goto done;
+			}
+
+			for (i = 0; i < num_groups; i++) {
+				if (sid_equal(group_sid, &user_sids[i])) {
+					/* User is in Domain Users, add their name
+					   as the only group member. */
+					u_in_group = True;
+					break;
+				}
+			}
+		}
+
+		if (u_in_group) {
+			size_t len = 0;
+			char *domainname = NULL;
+			char *username = NULL;
+			fstring name;
+			enum lsa_SidType type;
+
+			DEBUG(10,("fill_grent_mem: sid %s in 'Domain Users' in domain %s\n",
+				sid_to_string(sid_string, pquerying_user_sid), domain->name ));
+
+			status = domain->methods->sid_to_name(domain, mem_ctx,
+								pquerying_user_sid,
+								&domainname,
+								&username,
+								&type);
+			if (!NT_STATUS_IS_OK(status)) {
+				DEBUG(1, ("could not lookup username for user "
+					"sid %s in domain %s (error: %s)\n", 
+					sid_to_string(sid_string, pquerying_user_sid),
+					domain->name,
+					nt_errstr(status)));
+				goto done;
+			}
+			fill_domain_username(name, domain->name, username, True);
+			len = strlen(name);
+			buf_len = len + 1;
+			if (!(buf = (char *)SMB_MALLOC(buf_len))) {
+				DEBUG(1, ("out of memory\n"));
+				goto done;
+			}
+			memcpy(buf, name, buf_len);
+
+			DEBUG(10,("fill_grent_mem: user %s in 'Domain Users' in domain %s\n",
+				name, domain->name ));
+		}
+		
+		*gr_mem = buf;
+		*gr_mem_len = buf_len;
+
+		DEBUG(10, ("num_mem = %u, len = %u, mem = %s\n", (unsigned int)*num_gr_mem, 
+		   (unsigned int)buf_len, *num_gr_mem ? buf : "NULL")); 
+		result = True;
+		goto done;
+	}
+
 	/* Lookup group members */
 	status = domain->methods->lookup_groupmem(domain, mem_ctx, group_sid, &num_names, 
 						  &sid_mem, &names, &name_types);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("could not lookup membership for group rid %s in domain %s (error: %s)\n", 
+		DEBUG(1, ("could not lookup membership for group sid %s in domain %s (error: %s)\n", 
 			  sid_to_string(sid_string, group_sid), domain->name, nt_errstr(status)));
-
 		goto done;
 	}
 
@@ -119,9 +232,6 @@
 
 	/* Add members to list */
 
-	buf = NULL;
-	buf_len = buf_ndx = 0;
-
  again:
 
 	for (i = 0; i < num_names; i++) {
@@ -311,7 +421,7 @@
 
 	if (!fill_grent(&state->response.data.gr, name_domain,
 			name_group, gid) ||
-	    !fill_grent_mem(domain, &group_sid, name_type,
+	    !fill_grent_mem(domain, state, &group_sid, name_type,
 			    &num_gr_mem,
 			    &gr_mem, &gr_mem_len)) {
 		request_error(state);
@@ -370,7 +480,7 @@
 
 	if (!fill_grent(&state->response.data.gr, dom_name, group_name, 
 			state->request.data.gid) ||
-	    !fill_grent_mem(domain, &group_sid, name_type,
+	    !fill_grent_mem(domain, state, &group_sid, name_type,
 			    &num_gr_mem,
 			    &gr_mem, &gr_mem_len)) {
 		request_error(state);
@@ -802,6 +912,7 @@
 				sid_append_rid(&member_sid, name_list[ent->sam_entry_index].rid);
 				result = fill_grent_mem(
 					domain,
+					NULL,
 					&member_sid,
 					SID_NAME_DOM_GRP,
 					&num_gr_mem,



More information about the samba-cvs mailing list