summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/winbindd/winbindd_cache.c163
1 files changed, 139 insertions, 24 deletions
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 8e1eb7ac34..68972dd18d 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -1380,6 +1380,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
struct cache_entry *centry = NULL;
NTSTATUS status;
unsigned int i, retry;
+ bool old_status = domain->online;
if (!cache->tdb)
goto do_query;
@@ -1451,7 +1452,7 @@ do_query:
}
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
/* store partial response. */
@@ -1466,7 +1467,7 @@ do_query:
* domain is offline now, and there is no user entries,
* try to fetch from cache again.
*/
- if (cache->tdb && !domain->online && !domain->internal) {
+ if (cache->tdb && !domain->online && !domain->internal && old_status) {
centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
/* partial response... */
if (!centry) {
@@ -1530,7 +1531,9 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
struct cache_entry *centry = NULL;
NTSTATUS status;
unsigned int i;
+ bool old_status;
+ old_status = domain->online;
if (!cache->tdb)
goto do_query;
@@ -1579,12 +1582,13 @@ do_query:
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (cache->tdb &&
!domain->online &&
- !domain->internal) {
+ !domain->internal &&
+ old_status) {
centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
if (centry) {
goto do_fetch_cache;
@@ -1622,7 +1626,9 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
struct cache_entry *centry = NULL;
NTSTATUS status;
unsigned int i;
+ bool old_status;
+ old_status = domain->online;
if (!cache->tdb)
goto do_query;
@@ -1681,12 +1687,13 @@ do_query:
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (cache->tdb &&
!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
if (centry) {
goto do_fetch_cache;
@@ -1763,6 +1770,9 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
enum lsa_SidType *type)
{
NTSTATUS status;
+ bool old_status;
+
+ old_status = domain->online;
status = wcache_name_to_sid(domain, domain_name, name, sid, type);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -1790,11 +1800,12 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_name_to_sid(domain, domain_name, name, sid, type);
return cache_status;
@@ -1870,7 +1881,9 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
enum lsa_SidType *type)
{
NTSTATUS status;
+ bool old_status;
+ old_status = domain->online;
status = wcache_sid_to_name(domain, sid, mem_ctx, domain_name, name,
type);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -1898,11 +1911,12 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_sid_to_name(domain, sid, mem_ctx,
domain_name, name, type);
@@ -1936,7 +1950,9 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
bool have_mapped;
bool have_unmapped;
+ bool old_status;
+ old_status = domain->online;
*domain_name = NULL;
*names = NULL;
*types = NULL;
@@ -2023,12 +2039,13 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (cache->tdb &&
!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
have_mapped = have_unmapped = false;
for (i=0; i<num_rids; i++) {
@@ -2209,7 +2226,9 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
struct wbint_userinfo *info)
{
NTSTATUS status;
+ bool old_status;
+ old_status = domain->online;
status = wcache_query_user(domain, mem_ctx, user_sid, info);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
return status;
@@ -2229,11 +2248,12 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_query_user(domain, mem_ctx, user_sid, info);
return cache_status;
@@ -2318,7 +2338,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
NTSTATUS status;
unsigned int i;
fstring sid_string;
+ bool old_status;
+ old_status = domain->online;
status = wcache_lookup_usergroups(domain, mem_ctx, user_sid,
num_groups, user_gids);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -2340,11 +2362,12 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_lookup_usergroups(domain, mem_ctx, user_sid,
num_groups, user_gids);
@@ -2466,7 +2489,9 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
NTSTATUS status;
char *sidlist;
int i;
+ bool old_status;
+ old_status = domain->online;
status = wcache_lookup_useraliases(domain, mem_ctx, num_sids, sids,
num_aliases, alias_rids);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -2493,11 +2518,12 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_lookup_useraliases(domain, mem_ctx, num_sids,
sids, num_aliases, alias_rids);
@@ -2599,7 +2625,9 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
NTSTATUS status;
unsigned int i;
fstring sid_string;
+ bool old_status;
+ old_status = domain->online;
status = wcache_lookup_groupmem(domain, mem_ctx, group_sid, num_names,
sid_mem, names, name_types);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -2625,11 +2653,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
NTSTATUS cache_status;
cache_status = wcache_lookup_groupmem(domain, mem_ctx, group_sid,
num_names, sid_mem, names,
@@ -2676,7 +2705,71 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
struct netr_DomainTrustList *trusts)
{
NTSTATUS status;
+ struct winbind_cache *cache;
+ struct winbindd_tdc_domain *dom_list = NULL;
+ size_t num_domains = 0;
+ bool retval = false;
+ int i;
+ bool old_status;
+
+ old_status = domain->online;
+ trusts->count = 0;
+ trusts->array = NULL;
+ if (domain->online) {
+ goto do_query;
+ }
+ cache = get_cache(domain);
+ if (!cache || !cache->tdb) {
+ goto do_query;
+ }
+
+ retval = wcache_tdc_fetch_list(&dom_list, &num_domains);
+ if (!retval || !num_domains || !dom_list) {
+ TALLOC_FREE(dom_list);
+ goto do_query;
+ }
+
+do_fetch_cache:
+ trusts->array = TALLOC_ZERO_ARRAY(mem_ctx, struct netr_DomainTrust, num_domains);
+ if (!trusts->array) {
+ TALLOC_FREE(dom_list);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < num_domains; i++) {
+ struct netr_DomainTrust *trust;
+ struct dom_sid *sid;
+ struct winbindd_domain *dom;
+
+ dom = find_domain_from_name_noinit(dom_list[i].domain_name);
+ if (dom && dom->internal) {
+ continue;
+ }
+
+ trust = &trusts->array[trusts->count];
+ trust->netbios_name = talloc_strdup(trusts->array, dom_list[i].domain_name);
+ trust->dns_name = talloc_strdup(trusts->array, dom_list[i].dns_name);
+ sid = talloc(trusts->array, struct dom_sid);
+ if (!trust->netbios_name || !trust->dns_name ||
+ !sid) {
+ TALLOC_FREE(dom_list);
+ TALLOC_FREE(trusts->array);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ trust->trust_flags = dom_list[i].trust_flags;
+ trust->trust_attributes = dom_list[i].trust_attribs;
+ trust->trust_type = dom_list[i].trust_type;
+ sid_copy(sid, &dom_list[i].sid);
+ trust->sid = sid;
+ trusts->count++;
+ }
+
+ TALLOC_FREE(dom_list);
+ return NT_STATUS_OK;
+
+do_query:
/* Return status value returned by seq number check */
if (!NT_STATUS_IS_OK(domain->last_status))
@@ -2687,6 +2780,22 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
status = domain->backend->trusted_domains(domain, mem_ctx, trusts);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
+ if (!domain->internal && old_status) {
+ set_domain_offline(domain);
+ }
+ if (!domain->internal &&
+ !domain->online &&
+ old_status) {
+ retval = wcache_tdc_fetch_list(&dom_list, &num_domains);
+ if (retval && num_domains && dom_list) {
+ TALLOC_FREE(trusts->array);
+ trusts->count = 0;
+ goto do_fetch_cache;
+ }
+ }
+ }
/* no trusts gives NT_STATUS_NO_MORE_ENTRIES resetting to NT_STATUS_OK
* so that the generic centry handling still applies correctly -
* Guenther*/
@@ -2705,7 +2814,9 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
+ bool old_status;
+ old_status = domain->online;
if (!cache->tdb)
goto do_query;
@@ -2742,12 +2853,13 @@ do_query:
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (cache->tdb &&
!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
centry = wcache_fetch(cache, domain, "LOC_POL/%s", domain->name);
if (centry) {
goto do_fetch_cache;
@@ -2772,7 +2884,9 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
+ bool old_status;
+ old_status = domain->online;
if (!cache->tdb)
goto do_query;
@@ -2811,12 +2925,13 @@ do_query:
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- if (!domain->internal) {
+ if (!domain->internal && old_status) {
set_domain_offline(domain);
}
if (cache->tdb &&
!domain->internal &&
- !domain->online) {
+ !domain->online &&
+ old_status) {
centry = wcache_fetch(cache, domain, "PWD_POL/%s", domain->name);
if (centry) {
goto do_fetch_cache;