X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fwinbindd%2Fwinbindd_ads.c;h=4a9bd3577db4e9f7461f4a45b14f028fdd7b20b8;hb=d63a8bd52709835ea063b8f0230f973540965397;hp=1febddf110b422bcc29e959847130bb4eca30ab7;hpb=49145bfefae54672c5d4cccdbb9dd33e1cd89b88;p=samba.git diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 1febddf110b..4a9bd3577db 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -6,23 +6,24 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2003 Copyright (C) Gerald (Jerry) Carter 2004 - + 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 the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "includes.h" #include "winbindd.h" +#include "../librpc/gen_ndr/cli_netlogon.h" #ifdef HAVE_ADS @@ -84,10 +85,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) SAFE_FREE(ads->auth.realm); if ( IS_DC ) { - DOM_SID sid; - time_t last_set_time; - if ( !pdb_get_trusteddom_pw( domain->name, &ads->auth.password, &sid, &last_set_time ) ) { + if ( !pdb_get_trusteddom_pw( domain->name, &ads->auth.password, NULL, NULL ) ) { ads_destroy( &ads ); return NULL; } @@ -153,7 +152,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 *num_entries, - WINBIND_USERINFO **info) + struct wbint_userinfo **info) { ADS_STRUCT *ads = NULL; const char *attrs[] = { "*", NULL }; @@ -174,15 +173,19 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, } ads = ads_cached_connection(domain); - + if (!ads) { domain->last_status = NT_STATUS_SERVER_DISABLED; goto done; } rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs); - if (!ADS_ERR_OK(rc) || !res) { + if (!ADS_ERR_OK(rc)) { DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); + status = ads_ntstatus(rc); + } else if (!res) { + DEBUG(1,("query_user_list ads_search returned NULL res\n")); + goto done; } @@ -192,7 +195,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, goto done; } - (*info) = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, count); + (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count); if (!*info) { status = NT_STATUS_NO_MEMORY; goto done; @@ -201,16 +204,17 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, i = 0; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *name, *gecos = NULL; - char *homedir = NULL; - char *shell = NULL; + const char *name; + const char *gecos = NULL; + const char *homedir = NULL; + const char *shell = NULL; uint32 group; uint32 atype; DOM_SID user_sid; gid_t primary_gid = (gid_t)-1; if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || - ads_atype_map(atype) != SID_NAME_USER) { + ds_atype_map(atype) != SID_NAME_USER) { DEBUG(1,("Not a user account? atype=0x%x\n", atype)); continue; } @@ -226,7 +230,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, if (gecos == NULL) { gecos = ads_pull_string(ads, mem_ctx, msg, "name"); } - + if (!ads_pull_sid(ads, msg, "objectSid", &(*info)[i].user_sid)) { DEBUG(1,("No sid for %s !?\n", name)); @@ -325,9 +329,13 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, } rc = ads_search_retry(ads, &res, filter, attrs); - if (!ADS_ERR_OK(rc) || !res) { + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); DEBUG(1,("enum_dom_groups ads_search: %s\n", ads_errstr(rc))); goto done; + } else if (!res) { + DEBUG(1,("enum_dom_groups ads_search returned NULL res\n")); + goto done; } count = ads_count_replies(ads, res); @@ -343,7 +351,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, } i = 0; - + for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { char *name, *gecos; DOM_SID sid; @@ -397,10 +405,51 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, * to be split out */ *num_entries = 0; - + return NT_STATUS_OK; } +/* convert a single name to a sid in a domain - use rpc methods */ +static NTSTATUS name_to_sid(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const char *domain_name, + const char *name, + uint32_t flags, + DOM_SID *sid, + enum lsa_SidType *type) +{ + return reconnect_methods.name_to_sid(domain, mem_ctx, + domain_name, name, flags, + sid, type); +} + +/* convert a domain SID to a user or group name - use rpc methods */ +static NTSTATUS sid_to_name(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + char **domain_name, + char **name, + enum lsa_SidType *type) +{ + return reconnect_methods.sid_to_name(domain, mem_ctx, sid, + domain_name, name, type); +} + +/* convert a list of rids to names - use rpc methods */ +static NTSTATUS rids_to_names(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum lsa_SidType **types) +{ + return reconnect_methods.rids_to_names(domain, mem_ctx, sid, + rids, num_rids, + domain_name, names, types); +} + /* 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 @@ -410,7 +459,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *sid, - WINBIND_USERINFO *info) + struct wbint_userinfo *info) { ADS_STRUCT *ads = NULL; const char *attrs[] = { "*", NULL }; @@ -422,6 +471,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, uint32 group_rid; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; struct netr_SamInfo3 *user = NULL; + gid_t gid; DEBUG(3,("ads: query_user\n")); @@ -430,25 +480,25 @@ static NTSTATUS query_user(struct winbindd_domain *domain, info->primary_gid = (gid_t)-1; /* try netsamlogon cache first */ - + if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL ) { - DEBUG(5,("query_user: Cache lookup succeeded for %s\n", sid_string_dbg(sid))); sid_compose(&info->user_sid, &domain->sid, user->base.rid); sid_compose(&info->group_sid, &domain->sid, user->base.primary_gid); - + info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string); info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string); - + nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, &info->homedir, &info->shell, &info->full_name, - &info->primary_gid ); + &gid ); + info->primary_gid = gid; TALLOC_FREE(user); - + return NT_STATUS_OK; } @@ -470,7 +520,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, &info->homedir, &info->shell, &info->full_name, - &info->primary_gid ); + &gid); + info->primary_gid = gid; status = NT_STATUS_OK; goto done; @@ -483,15 +534,22 @@ static NTSTATUS query_user(struct winbindd_domain *domain, goto done; } - sidstr = sid_binstring(sid); - asprintf(&ldap_exp, "(objectSid=%s)", sidstr); + sidstr = sid_binstring(talloc_tos(), sid); + if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { + status = NT_STATUS_NO_MEMORY; + goto done; + } rc = ads_search_retry(ads, &msg, ldap_exp, attrs); - free(ldap_exp); - free(sidstr); - if (!ADS_ERR_OK(rc) || !msg) { + SAFE_FREE(ldap_exp); + TALLOC_FREE(sidstr); + if (!ADS_ERR_OK(rc)) { DEBUG(1,("query_user(sid=%s) ads_search: %s\n", sid_string_dbg(sid), ads_errstr(rc))); - goto done; + return ads_ntstatus(rc); + } else if (!msg) { + DEBUG(1,("query_user(sid=%s) ads_search returned NULL res\n", + sid_string_dbg(sid))); + return NT_STATUS_INTERNAL_ERROR; } count = ads_count_replies(ads, msg); @@ -505,7 +563,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, nss_get_info_cached( domain, sid, mem_ctx, ads, msg, &info->homedir, &info->shell, &info->full_name, - &info->primary_gid ); + &gid); + info->primary_gid = gid; if (info->full_name == NULL) { info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); @@ -564,7 +623,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, goto done; } - if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) { + if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) { status = NT_STATUS_NO_MEMORY; goto done; } @@ -576,22 +635,26 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, GROUP_TYPE_SECURITY_ENABLED); if (!ldap_exp) { DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn)); - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); status = NT_STATUS_NO_MEMORY; goto done; } - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); rc = ads_search_retry(ads, &res, ldap_exp, group_attrs); - - if (!ADS_ERR_OK(rc) || !res) { + + if (!ADS_ERR_OK(rc)) { DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc))); return ads_ntstatus(rc); + } else if (!res) { + DEBUG(1,("lookup_usergroups ads_search returned NULL res\n")); + return NT_STATUS_INTERNAL_ERROR; } - + + count = ads_count_replies(ads, res); - + *user_sids = NULL; num_groups = 0; @@ -606,12 +669,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { DOM_SID group_sid; - + if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { DEBUG(1,("No sid for this group ?!?\n")); continue; } - + /* ignore Builtin groups from ADS - Guenther */ if (sid_check_is_in_builtin(&group_sid)) { continue; @@ -641,9 +704,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 +716,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 +732,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 +757,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; ilast_status = NT_STATUS_SERVER_DISABLED; status = NT_STATUS_SERVER_DISABLED; @@ -795,7 +867,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, "%s\n", sid_string_dbg(sid), ads_errstr(rc))); goto done; } - + count = ads_count_replies(ads, msg); if (count != 1) { status = NT_STATUS_UNSUCCESSFUL; @@ -812,7 +884,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, goto done; } - user_dn = ads_get_dn(ads, msg); + user_dn = ads_get_dn(ads, mem_ctx, msg); if (user_dn == NULL) { status = NT_STATUS_NO_MEMORY; goto done; @@ -838,7 +910,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, if (count == 0) { /* no tokenGroups */ - + /* lookup what groups this user is a member of by DN search on * "memberOf" */ @@ -868,7 +940,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(status)) { goto done; } - + for (i=0;iname, + DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_dbg(group_sid))); *num_names = 0; @@ -935,52 +1019,50 @@ 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; } - if ((sidbinstr = sid_binstring(group_sid)) == NULL) { + if ((sidbinstr = sid_binstring(talloc_tos(), group_sid)) == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } /* search for all members of the group */ - if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", - sidbinstr))) - { - SAFE_FREE(sidbinstr); + ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", sidbinstr); + TALLOC_FREE(sidbinstr); + if (ldap_exp == NULL) { DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; } - SAFE_FREE(sidbinstr); args.control = ADS_EXTENDED_DN_OID; 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 +1070,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 +1097,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); @@ -1046,29 +1140,39 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, /* handle sids not resolved from cache by lsa_lookup_sids */ if (num_nocache > 0) { - status = cm_connect_lsa(domain, tmp_ctx, &cli, &lsa_policy); - - if (!NT_STATUS_IS_OK(status)) { - goto done; + status = winbindd_lookup_sids(tmp_ctx, + domain, + 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, NT_STATUS_NONE_MAPPED))) + { + DEBUG(1, ("lsa_lookupsids call failed with %s " + "- retrying...\n", nt_errstr(status))); + + status = winbindd_lookup_sids(tmp_ctx, + domain, + num_nocache, + sid_mem_nocache, + &domains_nocache, + &names_nocache, + &name_types_nocache); } - status = rpccli_lsa_lookup_sids(cli, tmp_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)) + 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]); @@ -1127,16 +1231,16 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) *seq = DOM_SEQUENCE_NONE; ads = ads_cached_connection(domain); - + if (!ads) { domain->last_status = NT_STATUS_SERVER_DISABLED; return NT_STATUS_UNSUCCESSFUL; } rc = ads_USN(ads, seq); - + if (!ADS_ERR_OK(rc)) { - + /* its a dead connection, destroy it */ if (domain->private_data) { @@ -1150,28 +1254,37 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) return ads_ntstatus(rc); } +/* find the lockout policy of a domain - use rpc methods */ +static NTSTATUS lockout_policy(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + struct samr_DomInfo12 *policy) +{ + return reconnect_methods.lockout_policy(domain, mem_ctx, policy); +} + +/* find the password policy of a domain - use rpc methods */ +static NTSTATUS password_policy(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + struct samr_DomInfo1 *policy) +{ + return reconnect_methods.password_policy(domain, mem_ctx, policy); +} + /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct netr_DomainTrustList trusts; int i; uint32 flags; struct rpc_pipe_client *cli; uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT); int ret_count; - + DEBUG(3,("ads: trusted_domains\n")); - *num_domains = 0; - *alt_names = NULL; - *names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); /* If this is our primary domain or a root in our forest, query for all trusts. If not, then just look for domain @@ -1199,138 +1312,121 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx, cli->desthost, flags, - &trusts, + trusts, NULL); - if ( NT_STATUS_IS_OK(result) && trusts.count) { - - /* Allocate memory for trusted domain names and sids */ - - if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } + if (!NT_STATUS_IS_OK(result)) { + return result; + } + if (trusts->count == 0) { + return NT_STATUS_OK; + } - /* Copy across names and sids */ + /* Copy across names and sids */ + ret_count = 0; + for (i = 0; i < trusts->count; i++) { + struct netr_DomainTrust *trust = &trusts->array[i]; + struct winbindd_domain d; - ret_count = 0; - for (i = 0; i < trusts.count; i++) { - struct winbindd_domain d; - - ZERO_STRUCT(d); + ZERO_STRUCT(d); - /* drop external trusts if this is not our primary - domain. This means that the returned number of - domains may be less that the ones actually trusted - by the DC. */ + /* + * drop external trusts if this is not our primary + * domain. This means that the returned number of + * domains may be less that the ones actually trusted + * by the DC. + */ - if ( (trusts.array[i].trust_attributes == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && - !domain->primary ) - { - DEBUG(10,("trusted_domains: Skipping external trusted domain " - "%s because it is outside of our primary domain\n", - trusts.array[i].netbios_name)); - continue; - } - - (*names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].netbios_name); - (*alt_names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy(&(*dom_sids)[ret_count], trusts.array[i].sid); - } else { - sid_copy(&(*dom_sids)[ret_count], &global_sid_NULL); - } + if ((trust->trust_attributes + == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && + !domain->primary ) + { + DEBUG(10,("trusted_domains: Skipping external trusted " + "domain %s because it is outside of our " + "primary domain\n", + trust->netbios_name)); + continue; + } - /* add to the trusted domain cache */ + /* add to the trusted domain cache */ - fstrcpy( d.name, trusts.array[i].netbios_name); - fstrcpy( d.alt_name, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy( &d.sid, trusts.array[i].sid); - } else { - sid_copy(&d.sid, &global_sid_NULL); - } + fstrcpy(d.name, trust->netbios_name); + fstrcpy(d.alt_name, trust->dns_name); + if (trust->sid) { + sid_copy(&d.sid, trust->sid); + } else { + sid_copy(&d.sid, &global_sid_NULL); + } - if ( domain->primary ) { + if ( domain->primary ) { + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and storing " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = trust->trust_attributes; + + wcache_tdc_add_domain( &d ); + ret_count++; + } else if ( (domain->domain_flags&fr_flags) == fr_flags ) { + /* Check if we already have this record. If + * we are following our forest root that is not + * our primary domain, we want to keep trust + * flags from the perspective of our primary + * domain not our forest root. */ + struct winbindd_tdc_domain *exist = NULL; + + exist = wcache_tdc_fetch_domain( + talloc_tos(), trust->netbios_name); + if (!exist) { DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; + "trusted domain list of %s and " + "storing trust flags for domain " + "%s\n", domain->name, d.alt_name)); + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = + trust->trust_attributes; wcache_tdc_add_domain( &d ); ret_count++; - } else if ( (domain->domain_flags&fr_flags) == fr_flags ) { - /* Check if we already have this record. If - * we are following our forest root that is not - * our primary domain, we want to keep trust - * flags from the perspective of our primary - * domain not our forest root. */ - struct winbindd_tdc_domain *exist = NULL; - - exist = - wcache_tdc_fetch_domain(NULL, trusts.array[i].netbios_name); - if (!exist) { - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; - - wcache_tdc_add_domain( &d ); - ret_count++; - } - TALLOC_FREE(exist); + } + TALLOC_FREE(exist); + } else { + /* This gets a little tricky. If we are + following a transitive forest trust, then + innerit the flags, type, and attribs from + the domain we queried to make sure we don't + record the view of the trust from the wrong + side. Always view it from the side of our + primary domain. --jerry */ + struct winbindd_tdc_domain *parent = NULL; + + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and inheriting " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + parent = wcache_tdc_fetch_domain(talloc_tos(), + domain->name); + if (parent) { + d.domain_flags = parent->trust_flags; + d.domain_type = parent->trust_type; + d.domain_trust_attribs = parent->trust_attribs; } else { - /* This gets a little tricky. If we are - following a transitive forest trust, then - innerit the flags, type, and attribs from - the domain we queried to make sure we don't - record the view of the trust from the wrong - side. Always view it from the side of our - primary domain. --jerry */ - struct winbindd_tdc_domain *parent = NULL; - - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and inheriting " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - parent = wcache_tdc_fetch_domain(NULL, domain->name); - if (parent) { - d.domain_flags = parent->trust_flags; - d.domain_type = parent->trust_type; - d.domain_trust_attribs = parent->trust_attribs; - } else { - d.domain_flags = domain->domain_flags; - d.domain_type = domain->domain_type; - d.domain_trust_attribs = domain->domain_trust_attribs; - } - TALLOC_FREE(parent); - - wcache_tdc_add_domain( &d ); - ret_count++; + d.domain_flags = domain->domain_flags; + d.domain_type = domain->domain_type; + d.domain_trust_attribs = + domain->domain_trust_attribs; } - } + TALLOC_FREE(parent); - *num_domains = ret_count; + wcache_tdc_add_domain( &d ); + ret_count++; + } } - return result; } @@ -1340,16 +1436,16 @@ struct winbindd_methods ads_methods = { query_user_list, enum_dom_groups, enum_local_groups, - msrpc_name_to_sid, - msrpc_sid_to_name, - msrpc_rids_to_names, + name_to_sid, + sid_to_name, + rids_to_names, query_user, lookup_usergroups, - msrpc_lookup_useraliases, + lookup_useraliases, lookup_groupmem, sequence_number, - msrpc_lockout_policy, - msrpc_password_policy, + lockout_policy, + password_policy, trusted_domains, };