diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd.h | 11 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 39 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 25 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 48 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 129 |
5 files changed, 143 insertions, 109 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index a4c0dd970d..26181326bb 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -137,6 +137,17 @@ struct winbindd_methods { /* return the current global sequence number */ NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32 *seq); + + /* enumerate trusted domains */ + NTSTATUS (*trusted_domains)(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_domains, + char ***names, + DOM_SID **dom_sids); + + /* find the domain sid */ + NTSTATUS (*domain_sid)(struct winbindd_domain *domain, + DOM_SID *sid); }; /* Structures to hold per domain information */ diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index e009f9a9ab..198e6ca92b 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -657,6 +657,41 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) return NT_STATUS_OK; } +/* get a list of trusted domains */ +static NTSTATUS trusted_domains(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_domains, + char ***names, + DOM_SID **dom_sids) +{ + *num_domains = 0; + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* find the domain sid for a domain */ +static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + const char *attrs[] = {"objectSid", NULL}; + ADS_STRUCT *ads = NULL; + void *res; + int rc; + + ads = ads_cached_connection(domain); + if (!ads) goto done; + + rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, &res); + if (rc) goto done; + if (ads_pull_sid(ads, res, "objectSid", sid)) { + status = NT_STATUS_OK; + } + ads_msgfree(ads, res); + +done: + return status; +} + /* the ADS backend methods are exposed via this structure */ struct winbindd_methods ads_methods = { query_user_list, @@ -666,7 +701,9 @@ struct winbindd_methods ads_methods = { query_user, lookup_usergroups, lookup_groupmem, - sequence_number + sequence_number, + trusted_domains, + domain_sid }; #endif diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 912ac162b5..9f87f8377f 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -706,6 +706,27 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) return NT_STATUS_OK; } +/* enumerate trusted domains */ +static NTSTATUS trusted_domains(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_domains, + char ***names, + DOM_SID **dom_sids) +{ + struct winbind_cache *cache = get_cache(domain); + + return cache->backend->trusted_domains(domain, mem_ctx, num_domains, + names, dom_sids); +} + +/* find the domain sid */ +static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) +{ + struct winbind_cache *cache = get_cache(domain); + + return cache->backend->domain_sid(domain, sid); +} + /* the ADS backend methods are exposed via this structure */ struct winbindd_methods cache_methods = { query_user_list, @@ -715,7 +736,9 @@ struct winbindd_methods cache_methods = { query_user, lookup_usergroups, lookup_groupmem, - sequence_number + sequence_number, + trusted_domains, + domain_sid }; diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 8a98a2626d..e0d1b69c60 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -460,6 +460,49 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) return result; } +/* get a list of trusted domains */ +static NTSTATUS trusted_domains(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_domains, + char ***names, + DOM_SID **dom_sids) +{ + CLI_POLICY_HND *hnd; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 enum_ctx = 0; + + if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) + goto done; + + result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, + &hnd->pol, &enum_ctx, num_domains, + names, dom_sids); +done: + return result; +} + +/* find the domain sid for a domain */ +static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *mem_ctx; + CLI_POLICY_HND *hnd; + fstring level5_dom; + + if (!(mem_ctx = talloc_init())) + return NT_STATUS_NO_MEMORY; + + /* Get sam handle */ + if (!(hnd = cm_get_lsa_handle(domain->name))) + goto done; + + status = cli_lsa_query_info_policy(hnd->cli, mem_ctx, + &hnd->pol, 0x05, level5_dom, sid); + +done: + talloc_destroy(mem_ctx); + return status; +} /* the rpc backend methods are exposed via this structure */ struct winbindd_methods msrpc_methods = { @@ -470,6 +513,7 @@ struct winbindd_methods msrpc_methods = { query_user, lookup_usergroups, lookup_groupmem, - sequence_number + sequence_number, + trusted_domains, + domain_sid }; - diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 5add3c9ac7..608749b39d 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -87,7 +87,6 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) /* Add a trusted domain to our list of domains */ static struct winbindd_domain *add_trusted_domain(char *domain_name, - DOM_SID *domain_sid, struct winbindd_methods *methods) { struct winbindd_domain *domain, *tmp; @@ -110,7 +109,6 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name, ZERO_STRUCTP(domain); fstrcpy(domain->name, domain_name); - sid_copy(&domain->sid, domain_sid); domain->methods = methods; domain->sequence_number = DOM_SEQUENCE_NONE; domain->last_seq_check = 0; @@ -126,130 +124,51 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name, BOOL get_domain_info(void) { - uint32 enum_ctx = 0, num_doms = 0; - char **domains = NULL; - DOM_SID *sids = NULL, domain_sid; NTSTATUS result; - CLI_POLICY_HND *hnd; - int i; - fstring level5_dom; - BOOL rv = False; TALLOC_CTX *mem_ctx; extern struct winbindd_methods cache_methods; - - DEBUG(1, ("getting trusted domain list\n")); + struct winbindd_domain *domain; + DOM_SID *dom_sids; + char **names; + int num_domains = 0; if (!(mem_ctx = talloc_init())) return False; - /* Add our workgroup - keep handle to look up trusted domains */ - - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; - - result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, - &hnd->pol, 0x05, level5_dom, &domain_sid); + domain = add_trusted_domain(lp_workgroup(), &cache_methods); - if (!NT_STATUS_IS_OK(result)) - goto done; + /* now we *must* get the domain sid for our primary domain. Go into a holding + pattern until that is available */ + result = cache_methods.domain_sid(domain, &domain->sid); + while (!NT_STATUS_IS_OK(result)) { + sleep(10); + DEBUG(1,("Retrying startup domain sid fetch for %s\n", + domain->name)); + result = cache_methods.domain_sid(domain, &domain->sid); + } - add_trusted_domain(lp_workgroup(), &domain_sid, &cache_methods); - - /* Enumerate list of trusted domains */ + DEBUG(1, ("getting trusted domain list\n")); - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; + result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains, + &names, &dom_sids); - result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, - &hnd->pol, &enum_ctx, &num_doms, &domains, &sids); - - if (!NT_STATUS_IS_OK(result)) - goto done; - /* Add each domain to the trusted domain list */ - - for(i = 0; i < num_doms; i++) - add_trusted_domain(domains[i], &sids[i], &cache_methods); - - rv = True; - - done: - - talloc_destroy(mem_ctx); - - return rv; -} - - -/* Connect to a domain controller using get_any_dc_name() to discover - the domain name and sid */ - -BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) -{ - fstring level5_dom; - uint32 enum_ctx = 0, num_doms = 0; - char **domains = NULL; - DOM_SID *sids = NULL; - CLI_POLICY_HND *hnd; - NTSTATUS result; - BOOL rv = False; - TALLOC_CTX *mem_ctx; - - DEBUG(1, ("looking up sid for domain %s\n", domain_name)); - - if (!(mem_ctx = talloc_init())) - return False; - - if (!(hnd = cm_get_lsa_handle(domain_name))) - goto done; - - /* Do a level 5 query info policy if we are looking up the SID for - our own domain. */ - - if (strequal(domain_name, lp_workgroup())) { - - result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, - &hnd->pol, 0x05, level5_dom, - &domain->sid); - - rv = NT_STATUS_IS_OK(result); - goto done; - } - - /* Use lsaenumdomains to get sid for this domain */ - - result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, &hnd->pol, - &enum_ctx, &num_doms, &domains, &sids); - - /* Look for domain name */ - - if (NT_STATUS_IS_OK(result) && domains && sids) { - BOOL found = False; + if (NT_STATUS_IS_OK(result)) { int i; - - for(i = 0; i < num_doms; i++) { - if (strequal(domain_name, domains[i])) { - sid_copy(&domain->sid, &sids[i]); - found = True; - break; + for(i = 0; i < num_domains; i++) { + domain = add_trusted_domain(names[i], &cache_methods); + if (domain) { + sid_copy(&domain->sid, &dom_sids[i]); } } - - rv = found; - goto done; } - - rv = False; /* An error occured with a trusted domain */ - - done: talloc_destroy(mem_ctx); - - return rv; + return True; } -/* Lookup a sid in a domain from a name */ +/* Lookup a sid in a domain from a name */ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, const char *name, DOM_SID *sid, enum SID_NAME_USE *type) { |