[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-4399-gc9b3bbd

Steven Danneman sdanneman at samba.org
Tue Nov 18 22:37:10 GMT 2008


The branch, v3-3-test has been updated
       via  c9b3bbdc3c36580dcb18a99ac58ae143b1926d8e (commit)
       via  f778c89592b5884c2d572c31dac3ccc14ac10dfb (commit)
      from  39f47db6f93132ebeef185f064652944aec11d99 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit c9b3bbdc3c36580dcb18a99ac58ae143b1926d8e
Author: Steven Danneman <steven.danneman at isilon.com>
Date:   Sat Nov 15 13:07:15 2008 -0800

    Fix extended DN parse error when AD object does not have a SID.
    
    Some AD objects, like Exchange Public Folders, can be members of Security
    Groups but do not have a SID attribute.  This patch adds more granular return
    errors to ads_get_sid_from_extended_dn().  Callers can now determine if a parse
    error occured because of bad input, or the DN was valid but contained no SID.
    
    I updated all callers to ignore SIDless objects when appropriate.
    
    Also did some cleanup to the out paths of lookup_usergroups_memberof()

commit f778c89592b5884c2d572c31dac3ccc14ac10dfb
Author: Steven Danneman <steven.danneman at isilon.com>
Date:   Fri Nov 14 19:16:12 2008 -0800

    Whitespace and >80 column cleanups.

-----------------------------------------------------------------------

Summary of changes:
 source/include/proto.h           |    8 +-
 source/libads/ldap.c             |   78 ++++++++++++++----------
 source/winbindd/winbindd_ads.c   |  125 ++++++++++++++++++++++----------------
 source/winbindd/winbindd_group.c |    4 +-
 4 files changed, 125 insertions(+), 90 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/include/proto.h b/source/include/proto.h
index 7f0c1f0..2e46bca 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -2102,10 +2102,10 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
 				TALLOC_CTX *mem_ctx,
 				char ***ous,
 				size_t *num_ous);
-bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, 
-				  const char *extended_dn, 
-				  enum ads_extended_dn_flags flags, 
-				  DOM_SID *sid);
+ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
+					const char *extended_dn,
+					enum ads_extended_dn_flags flags,
+					DOM_SID *sid);
 char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
 char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
 char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 03d02fc..97e802a 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -3111,60 +3111,66 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
 
 /**
  * pull a DOM_SID from an extended dn string
- * @param mem_ctx TALLOC_CTX 
+ * @param mem_ctx TALLOC_CTX
  * @param extended_dn string
  * @param flags string type of extended_dn
  * @param sid pointer to a DOM_SID
- * @return boolean inidicating success
+ * @return NT_STATUS_OK on success,
+ *	   NT_INVALID_PARAMETER on error,
+ *	   NT_STATUS_NOT_FOUND if no SID present
  **/
-bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, 
-				  const char *extended_dn, 
-				  enum ads_extended_dn_flags flags, 
-				  DOM_SID *sid)
+ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
+					const char *extended_dn,
+					enum ads_extended_dn_flags flags,
+					DOM_SID *sid)
 {
 	char *p, *q, *dn;
 
 	if (!extended_dn) {
-		return False;
+		return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 	}
 
 	/* otherwise extended_dn gets stripped off */
 	if ((dn = talloc_strdup(mem_ctx, extended_dn)) == NULL) {
-		return False;
+		return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 	}
-	/* 
+	/*
 	 * ADS_EXTENDED_DN_HEX_STRING:
 	 * <GUID=238e1963cb390f4bb032ba0105525a29>;<SID=010500000000000515000000bb68c8fd6b61b427572eb04556040000>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
 	 *
 	 * ADS_EXTENDED_DN_STRING (only with w2k3):
-	<GUID=63198e23-39cb-4b0f-b032-ba0105525a29>;<SID=S-1-5-21-4257769659-666132843-1169174103-1110>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
+	 * <GUID=63198e23-39cb-4b0f-b032-ba0105525a29>;<SID=S-1-5-21-4257769659-666132843-1169174103-1110>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
+	 *
+	 * Object with no SID, such as an Exchange Public Folder
+	 * <GUID=28907fb4bdf6854993e7f0a10b504e7c>;CN=public,CN=Microsoft Exchange System Objects,DC=sd2k3ms,DC=west,DC=isilon,DC=com
 	 */
 
 	p = strchr(dn, ';');
 	if (!p) {
-		return False;
+		return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 	}
 
 	if (strncmp(p, ";<SID=", strlen(";<SID=")) != 0) {
-		return False;
+		DEBUG(5,("No SID present in extended dn\n"));
+		return ADS_ERROR_NT(NT_STATUS_NOT_FOUND);
 	}
 
 	p += strlen(";<SID=");
 
 	q = strchr(p, '>');
 	if (!q) {
-		return False;
+		return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 	}
-	
+
 	*q = '\0';
 
 	DEBUG(100,("ads_get_sid_from_extended_dn: sid string is %s\n", p));
 
 	switch (flags) {
-	
+
 	case ADS_EXTENDED_DN_STRING:
 		if (!string_to_sid(sid, p)) {
-			return False;
+			return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 		}
 		break;
 	case ADS_EXTENDED_DN_HEX_STRING: {
@@ -3173,21 +3179,21 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
 
 		buf_len = strhex_to_str(buf, sizeof(buf), p, strlen(p));
 		if (buf_len == 0) {
-			return False;
+			return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 		}
 
 		if (!sid_parse(buf, buf_len, sid)) {
 			DEBUG(10,("failed to parse sid\n"));
-			return False;
+			return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 		}
 		break;
 		}
 	default:
 		DEBUG(10,("unknown extended dn format\n"));
-		return False;
+		return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 	}
 
-	return True;
+	return ADS_ERROR_NT(NT_STATUS_OK);
 }
 
 /**
@@ -3200,18 +3206,19 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
  * @param sids pointer to sid array to allocate
  * @return the count of SIDs pulled
  **/
- int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, 
-				   TALLOC_CTX *mem_ctx, 
-				   LDAPMessage *msg, 
+ int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads,
+				   TALLOC_CTX *mem_ctx,
+				   LDAPMessage *msg,
 				   const char *field,
 				   enum ads_extended_dn_flags flags,
 				   DOM_SID **sids)
 {
 	int i;
-	size_t dn_count;
+	ADS_STATUS rc;
+	size_t dn_count, ret_count = 0;
 	char **dn_strings;
 
-	if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field, 
+	if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field,
 					   &dn_count)) == NULL) {
 		return 0;
 	}
@@ -3223,18 +3230,25 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
 	}
 
 	for (i=0; i<dn_count; i++) {
-
-		if (!ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i], 
-						  flags, &(*sids)[i])) {
-			TALLOC_FREE(*sids);
-			TALLOC_FREE(dn_strings);
-			return 0;
+		rc = ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i],
+						  flags, &(*sids)[i]);
+		if (!ADS_ERR_OK(rc)) {
+			if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+			    NT_STATUS_NOT_FOUND)) {
+				continue;
+			}
+			else {
+				TALLOC_FREE(*sids);
+				TALLOC_FREE(dn_strings);
+				return 0;
+			}
 		}
+		ret_count++;
 	}
 
 	TALLOC_FREE(dn_strings);
 
-	return dn_count;
+	return ret_count;
 }
 
 /********************************************************************
diff --git a/source/winbindd/winbindd_ads.c b/source/winbindd/winbindd_ads.c
index 894e786..5f59ef3 100644
--- a/source/winbindd/winbindd_ads.c
+++ b/source/winbindd/winbindd_ads.c
@@ -641,9 +641,10 @@ done:
    tokenGroups are not available. */
 static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 					   TALLOC_CTX *mem_ctx,
-					   const char *user_dn, 
+					   const char *user_dn,
 					   DOM_SID *primary_group,
-					   size_t *p_num_groups, DOM_SID **user_sids)
+					   size_t *p_num_groups,
+					   DOM_SID **user_sids)
 {
 	ADS_STATUS rc;
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -652,15 +653,15 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 	size_t num_groups = 0;
 	DOM_SID *group_sids = NULL;
 	int i;
-	char **strings;
-	size_t num_strings = 0;
+	char **strings = NULL;
+	size_t num_strings = 0, num_sids = 0;
 
 
 	DEBUG(3,("ads: lookup_usergroups_memberof\n"));
 
 	if ( !winbindd_can_contact_domain( domain ) ) {
-		DEBUG(10,("lookup_usergroups_memberof: No incoming trust for domain %s\n",
-			  domain->name));		
+		DEBUG(10,("lookup_usergroups_memberof: No incoming trust for "
+			  "domain %s\n", domain->name));
 		return NT_STATUS_OK;
 	}
 
@@ -668,19 +669,19 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 
 	if (!ads) {
 		domain->last_status = NT_STATUS_SERVER_DISABLED;
-		goto done;
+		return NT_STATUS_UNSUCCESSFUL;
 	}
 
-	rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs, 
-						 ADS_EXTENDED_DN_HEX_STRING, 
+	rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
+						 ADS_EXTENDED_DN_HEX_STRING,
 						 &strings, &num_strings);
 
 	if (!ADS_ERR_OK(rc)) {
-		DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n", 
-			user_dn, ads_errstr(rc)));
+		DEBUG(1,("lookup_usergroups_memberof ads_search "
+			"member=%s: %s\n", user_dn, ads_errstr(rc)));
 		return ads_ntstatus(rc);
 	}
-	
+
 	*user_sids = NULL;
 	num_groups = 0;
 
@@ -693,21 +694,26 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 
 	group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);
 	if (!group_sids) {
-		TALLOC_FREE(strings);
 		status = NT_STATUS_NO_MEMORY;
 		goto done;
 	}
 
 	for (i=0; i<num_strings; i++) {
-
-		if (!ads_get_sid_from_extended_dn(mem_ctx, strings[i], 
-						  ADS_EXTENDED_DN_HEX_STRING, 
-						  &(group_sids)[i])) {
-			TALLOC_FREE(group_sids);
-			TALLOC_FREE(strings);
-			status = NT_STATUS_NO_MEMORY;
-			goto done;
+		rc = ads_get_sid_from_extended_dn(mem_ctx, strings[i],
+						  ADS_EXTENDED_DN_HEX_STRING,
+						  &(group_sids)[i]);
+		if (!ADS_ERR_OK(rc)) {
+			/* ignore members without SIDs */
+			if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+			    NT_STATUS_NOT_FOUND)) {
+				continue;
+			}
+			else {
+				status = ads_ntstatus(rc);
+				goto done;
+			}
 		}
+		num_sids++;
 	}
 
 	if (i == 0) {
@@ -716,7 +722,7 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 		goto done;
 	}
 
-	for (i=0; i<num_strings; i++) {
+	for (i=0; i<num_sids; i++) {
 
 		/* ignore Builtin groups from ADS - Guenther */
 		if (sid_check_is_in_builtin(&group_sids[i])) {
@@ -728,14 +734,17 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
 		if (!NT_STATUS_IS_OK(status)) {
 			goto done;
 		}
-	
+
 	}
 
 	*p_num_groups = num_groups;
 	status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
 
-	DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n", user_dn));
+	DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n",
+		user_dn));
+
 done:
+	TALLOC_FREE(strings);
 	TALLOC_FREE(group_sids);
 
 	return status;
@@ -899,8 +908,8 @@ done:
  */
 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 				TALLOC_CTX *mem_ctx,
-				const DOM_SID *group_sid, uint32 *num_names, 
-				DOM_SID **sid_mem, char ***names, 
+				const DOM_SID *group_sid, uint32 *num_names,
+				DOM_SID **sid_mem, char ***names,
 				uint32 **name_types)
 {
 	ADS_STATUS rc;
@@ -921,7 +930,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 	uint32 num_nocache = 0;
 	TALLOC_CTX *tmp_ctx = NULL;
 
-	DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, 
+	DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
 		  sid_string_dbg(group_sid)));
 
 	*num_names = 0;
@@ -935,12 +944,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
 	if ( !winbindd_can_contact_domain( domain ) ) {
 		DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
-			  domain->name));		
+			  domain->name));
 		return NT_STATUS_OK;
 	}
 
 	ads = ads_cached_connection(domain);
-	
+
 	if (!ads) {
 		domain->last_status = NT_STATUS_SERVER_DISABLED;
 		goto done;
@@ -952,8 +961,8 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 	}
 
 	/* search for all members of the group */
-	if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", 
-					 sidbinstr))) 
+	if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)",
+					 sidbinstr)))
 	{
 		SAFE_FREE(sidbinstr);
 		DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n"));
@@ -966,21 +975,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 	args.val = ADS_EXTENDED_DN_HEX_STRING;
 	args.critical = True;
 
-	rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path, 
+	rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
 			       ldap_exp, &args, "member", &members, &num_members);
 
 	if (!ADS_ERR_OK(rc)) {
 		DEBUG(0,("ads_ranged_search failed with: %s\n", ads_errstr(rc)));
 		status = NT_STATUS_UNSUCCESSFUL;
 		goto done;
-	} 
-	
+	}
+
 	DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)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 
+	 * 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
@@ -988,7 +997,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 	 * 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_members) {
 		(*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
 		(*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
@@ -1015,11 +1024,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 		char *name, *domain_name;
 		DOM_SID sid;
 
-	        if (!ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, &sid)) {
-			status = NT_STATUS_INVALID_PARAMETER;
-	                goto done;
+	        rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val,
+		    &sid);
+		if (!ADS_ERR_OK(rc)) {
+			if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+			    NT_STATUS_NOT_FOUND)) {
+				/* Group members can be objects, like Exchange
+				 * Public Folders, that don't have a SID.  Skip
+				 * them. */
+				continue;
+			}
+			else {
+				status = ads_ntstatus(rc);
+				goto done;
+			}
 		}
-		if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
+		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_dbg(&sid)));
 			sid_copy(&(*sid_mem)[*num_names], &sid);
@@ -1051,23 +1072,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 			goto done;
 		}
 
-		status = rpccli_lsa_lookup_sids(cli, tmp_ctx, 
+		status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
 						&lsa_policy,
-						num_nocache, 
-						sid_mem_nocache, 
-						&domains_nocache, 
-						&names_nocache, 
+						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)) 
+		    NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
 		{
-			/* Copy the entries over from the "_nocache" arrays 
-			 * to the result arrays, skipping the gaps the 
+			/* Copy the entries over from the "_nocache" arrays
+			 * to the result arrays, skipping the gaps the
 			 * lookup_sids call left. */
 			for (i=0; i < num_nocache; i++) {
-				if (((names_nocache)[i] != NULL) && 
-				    ((name_types_nocache)[i] != SID_NAME_UNKNOWN)) 
+				if (((names_nocache)[i] != NULL) &&
+				    ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
 				{
 					sid_copy(&(*sid_mem)[*num_names],
 						 &sid_mem_nocache[i]);
diff --git a/source/winbindd/winbindd_group.c b/source/winbindd/winbindd_group.c
index 8fa6712..25461d6 100644
--- a/source/winbindd/winbindd_group.c
+++ b/source/winbindd/winbindd_group.c
@@ -581,7 +581,7 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
 	}
 
 	/* Real work goes here.  Create a list of group names to
-	   expand startign with the initial one.  Pass that to
+	   expand starting with the initial one.  Pass that to
 	   expand_groups() which returns a list of more group names
 	   to expand.  Do this up to the max search depth. */
 
@@ -918,7 +918,7 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
 	nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
 					 &mapped_name);
 
-	/* basiuc whitespace reversal */
+	/* basic whitespace reversal */
 	if (NT_STATUS_IS_OK(nt_status)) {
 		s->group_name = talloc_asprintf(s->state->mem_ctx,
 						"%s%c%s",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list