From: Steven Danneman Date: Sat, 15 Nov 2008 21:07:15 +0000 (-0800) Subject: Fix extended DN parse error when AD object does not have a SID. X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=6d59be1e6d83d4faf145c9b6d574bab9f2acb36a 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() --- diff --git a/source3/include/proto.h b/source3/include/proto.h index 33425849d1fc..1cdf6c9cbc85 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1920,10 +1920,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/source3/libads/ldap.c b/source3/libads/ldap.c index c651b33efe91..f55cfa784a35 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3115,45 +3115,51 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, * @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: * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de * * ADS_EXTENDED_DN_STRING (only with w2k3): - ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + * + * Object with no SID, such as an Exchange Public Folder + * ;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, ";'); if (!q) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } *q = '\0'; @@ -3164,7 +3170,7 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, 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); } /** @@ -3208,7 +3214,8 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, 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, @@ -3223,18 +3230,25 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, } for (i=0; ilast_status = NT_STATUS_SERVER_DISABLED; - goto done; + return NT_STATUS_UNSUCCESSFUL; } rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs, @@ -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