svn commit: samba r23255 - in branches/SAMBA_3_0_26/source/nsswitch: .

obnox at samba.org obnox at samba.org
Wed May 30 22:57:47 GMT 2007


Author: obnox
Date: 2007-05-30 22:57:46 +0000 (Wed, 30 May 2007)
New Revision: 23255

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

Log:
Merge the reworking of winbindd_ads lookup_groupmem function
from 3_0: Call lsa_lookup_sids on the list of sids that
can not be resolved from cache, instead of passing each
single sid to dn_lookup (which becomes obsoleten and is
removed). Weed out the sids that could not be resolved.

This merges r23072, r23078, r23252, r23253.

Michael


Modified:
   branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c


Changeset:
Modified: branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c
===================================================================
--- branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c	2007-05-30 22:43:11 UTC (rev 23254)
+++ branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c	2007-05-30 22:57:46 UTC (rev 23255)
@@ -402,50 +402,11 @@
 	return NT_STATUS_OK;
 }
 
-/* convert a DN to a name, SID and name type 
-   this might become a major speed bottleneck if groups have
-   lots of users, in which case we could cache the results
-*/
-static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
-		      const char *dn,
-		      char **name, uint32 *name_type, DOM_SID *sid)
-{
-	LDAPMessage *res = NULL;
-	const char *attrs[] = {"userPrincipalName", "sAMAccountName",
-			       "objectSid", "sAMAccountType", NULL};
-	ADS_STATUS rc;
-	uint32 atype;
-	DEBUG(3,("ads: dn_lookup\n"));
+/* If you are looking for "dn_lookup": Yes, it used to be here!
+ * It has gone now since it was a major speed bottleneck in
+ * lookup_groupmem (its only use). It has been replaced by
+ * an rpc lookup sids call... R.I.P. */
 
-	rc = ads_search_retry_dn(ads, &res, dn, attrs);
-
-	if (!ADS_ERR_OK(rc) || !res) {
-		goto failed;
-	}
-
-	(*name) = ads_pull_username(ads, mem_ctx, res);
-
-	if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) {
-		goto failed;
-	}
-	(*name_type) = ads_atype_map(atype);
-
-	if (!ads_pull_sid(ads, res, "objectSid", sid)) {
-		goto failed;
-	}
-
-	if (res) 
-		ads_msgfree(ads, res);
-
-	return True;
-
-failed:
-	if (res) 
-		ads_msgfree(ads, res);
-
-	return False;
-}
-
 /* Lookup user information from a rid */
 static NTSTATUS query_user(struct winbindd_domain *domain, 
 			   TALLOC_CTX *mem_ctx, 
@@ -942,12 +903,19 @@
 	char *ldap_exp;
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 	char *sidstr;
-	char **members;
+	char **members = NULL;
 	int i;
-	size_t num_members;
-	fstring sid_string;
+	size_t num_members = 0;
 	ads_control args;
+        struct rpc_pipe_client *cli;
+        POLICY_HND lsa_policy;
+	DOM_SID *sid_mem_nocache = NULL;
+	char **names_nocache = NULL;
+	uint32 *name_types_nocache = NULL;
+	char **domains_nocache = NULL;     /* only needed for rpccli_lsa_lookup_sids */
+	uint32 num_nocache = 0;
 
+
 	DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, 
 		  sid_string_static(group_sid)));
 
@@ -980,9 +948,6 @@
 	}
 	SAFE_FREE(sidstr);
 
-	members = NULL;
-	num_members = 0;
-
 	args.control = ADS_EXTENDED_DN_OID;
 	args.val = ADS_EXTENDED_DN_HEX_STRING;
 	args.critical = True;
@@ -996,74 +961,135 @@
 		goto done;
 	} 
 	
-	/* now we need to turn a list of members into rids, names and name types 
-	   the problem is that the members are in the form of distinguised names
-	*/
-
-	if (num_members) {
+	DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", num_members));
+	
+	/* Now that we have a list of sids, we need to get the
+	 * lists of names and name_types belonging to these sids.
+	 * even though conceptually not quite clean,  we use the 
+	 * RPC call lsa_lookup_sids for this since it can handle a 
+	 * list of sids. ldap calls can just resolve one sid at a time.
+	 *
+	 * At this stage, the sids are still hidden in the exetended dn
+	 * member output format. We actually do a little better than
+	 * stated above: In extracting the sids from the member strings,
+	 * we try to resolve as many sids as possible from the
+	 * cache. Only the rest is passed to the lsa_lookup_sids call. */
+	
+	if (num_names) {
 		(*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
+		(*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
 		(*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
-		(*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
+		(sid_mem_nocache) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
 
 		if ((members == NULL) || (*sid_mem == NULL) ||
-		     (*name_types == NULL) || (*names == NULL)) {
+		    (*names == NULL) || (*name_types == NULL) ||
+		    (sid_mem_nocache == NULL))
+		{
 			DEBUG(1, ("talloc failed\n"));
 			status = NT_STATUS_NO_MEMORY;
 			goto done;
 		}
-	} else {
+	}
+	else {
 		(*sid_mem) = NULL;
+		(*names) = NULL;
 		(*name_types) = NULL;
-		(*names) = NULL;
 	}
- 
-	for (i=0;i<num_members;i++) {
+
+	for (i=0; i<num_members; i++) {
 		uint32 name_type;
-		char *name, *domain_name, *dn;
+		char *name, *domain_name;
 		DOM_SID sid;
 
-		if ((!ads_get_sid_from_extended_dn(mem_ctx, members[i], ADS_EXTENDED_DN_HEX_STRING, &sid)) ||
-		    (!ads_get_dn_from_extended_dn(mem_ctx, members[i], &dn)))
-		{
+	        if (!ads_get_sid_from_extended_dn(mem_ctx, members[i], args.val, &sid)) {
 			status = NT_STATUS_INVALID_PARAMETER;
-			goto done;
+	                goto done;
 		}
-
 		if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
-
-			DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n", 
-				sid_string_static(&sid)));
-
+			DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n",
+				 sid_string_static(&sid)));
+			sid_copy(&(*sid_mem)[*num_names], &sid);
 			(*names)[*num_names] = CONST_DISCARD(char *,name);
 			(*name_types)[*num_names] = name_type;
-			sid_copy(&(*sid_mem)[*num_names], &sid);
-
 			(*num_names)++;
-
-			continue;
 		}
+		else {
+			DEBUG(10, ("ads: lookup_groupmem: sid %s not found in cache\n",
+				  sid_string_static(&sid)));
+			sid_copy(&(sid_mem_nocache)[num_nocache], &sid);
+			num_nocache++;
+		}
+	}
 
-		if (dn_lookup(ads, mem_ctx, dn, &name, &name_type, &sid)) {
+	DEBUG(10, ("ads: lookup_groupmem: %d sids found in cache, "
+		  "%d left for lsa_lookupsids\n", *num_names, num_nocache));
 
-			DEBUG(10,("ads: lookup_groupmem: got sid %s from dn_lookup\n", 
-				sid_string_static(&sid)));
-			
-			(*names)[*num_names] = name;
-			(*name_types)[*num_names] = name_type;
-			sid_copy(&(*sid_mem)[*num_names], &sid);
-			
-			(*num_names)++;
+	/* handle sids not resolved from cache by lsa_lookup_sids */
+	if (num_nocache > 0) {
 
+		status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
 		}
-	}	
 
+		status = rpccli_lsa_lookup_sids_all(cli, mem_ctx, 
+						    &lsa_policy,
+						    num_nocache, 
+						    sid_mem_nocache, 
+						    &domains_nocache, 
+						    &names_nocache, 
+						    &name_types_nocache);
+
+		if (NT_STATUS_IS_OK(status) ||
+		    NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) 
+		{
+			/* Copy the entries over from the "_nocache" arrays 
+			 * to the result arrays, skipping the gaps the 
+			 * lookup_sids call left. */
+			*num_names = 0;
+			for (i=0; i < num_nocache; i++) {
+				if (((names_nocache)[i] != NULL) && 
+				    ((name_types_nocache)[i] != SID_NAME_UNKNOWN)) 
+				{
+					sid_copy(&(*sid_mem)[*num_names],
+						 &sid_mem_nocache[i]);
+					(*names)[*num_names] = names_nocache[i];
+					(*name_types)[*num_names] = name_types_nocache[i];
+					(*num_names)++;
+				}
+			}
+		}
+		else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+			DEBUG(10, ("lookup_groupmem: lsa_lookup_sids could "
+				   "not map any SIDs at all.\n"));
+			/* Don't handle this as an error here.
+			 * There is nothing left to do with respect to the 
+			 * overall result... */
+		}
+		else if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(10, ("lookup_groupmem: Error looking up %d "
+				   "sids via rpc_lsa_lookup_sids: %s\n",
+				   num_members, nt_errstr(status)));
+			goto done;
+		}
+	}
+
 	status = NT_STATUS_OK;
-	DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n", sid_to_string(sid_string, group_sid)));
+	DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n",
+		 sid_string_static(group_sid)));
+
 done:
 
 	if (res) 
 		ads_msgfree(ads, res);
 
+	/* free intermediate lists. - a temp talloc ctx might be better. */
+	TALLOC_FREE(sid_mem_nocache);
+	TALLOC_FREE(names_nocache);
+	TALLOC_FREE(name_types_nocache);
+	TALLOC_FREE(domains_nocache);
+
 	return status;
 }
 



More information about the samba-cvs mailing list