summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-12-10 02:25:19 +0000
committerAndrew Tridgell <tridge@samba.org>2001-12-10 02:25:19 +0000
commit7c60ae59378be1b2af2e57ee3927966a29a797a5 (patch)
treec7ed51e51c595e58532ae9644bf91e99130c8772
parent5ab2c8b8214236b4cd028f791e9ddb76a9973d74 (diff)
downloadsamba-7c60ae59378be1b2af2e57ee3927966a29a797a5.tar.gz
moved the domain sid lookup and enumeration of trusted domains into
the backends at startup, loop until we get the domain sid for our primary domain, trying every 10 seconds. This makes winbindd handle a room-wide power failure better
-rw-r--r--source/nsswitch/winbindd.h11
-rw-r--r--source/nsswitch/winbindd_ads.c39
-rw-r--r--source/nsswitch/winbindd_cache.c25
-rw-r--r--source/nsswitch/winbindd_rpc.c48
-rw-r--r--source/nsswitch/winbindd_util.c129
5 files changed, 143 insertions, 109 deletions
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index a4c0dd970d8..26181326bb2 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/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/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index e009f9a9aba..198e6ca92b2 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/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/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 912ac162b57..9f87f8377f9 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/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/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 8a98a2626de..e0d1b69c605 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/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/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 5add3c9ac74..608749b39db 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/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)
{