summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd.h1
-rw-r--r--source3/nsswitch/winbindd_cache.c5
-rw-r--r--source3/nsswitch/winbindd_cm.c61
-rw-r--r--source3/nsswitch/winbindd_util.c9
4 files changed, 59 insertions, 17 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index c18848ac52..4063e6b66b 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -203,6 +203,7 @@ struct winbindd_domain {
/* Callback we use to try put us back online. */
+ uint32 check_online_timeout;
struct timed_event *check_online_event;
/* Linked list info */
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 799eb5855c..7990068ee4 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -87,10 +87,11 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
struct winbindd_domain *our_domain = domain;
#endif
- /* we have to know what type of domain we are dealing with first */
+ /* We have to know what type of domain we are dealing with first. */
- if ( !domain->initialized )
+ if ( !domain->initialized ) {
init_dc_connection( domain );
+ }
/*
OK. listen up becasue I'm only going to say this once.
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 3f392c4825..4044bb71ee 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -7,6 +7,7 @@
Copyright (C) Andrew Bartlett 2002
Copyright (C) Gerald (Jerry) Carter 2003-2005.
Copyright (C) Volker Lendecke 2004-2005
+ Copyright (C) Jeremy Allison 2006
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
@@ -64,9 +65,29 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
static void set_dc_type_and_flags( struct winbindd_domain *domain );
/****************************************************************
+ If we're still offline, exponentially increase the timeout check.
+****************************************************************/
+
+static void calc_new_online_timeout(struct winbindd_domain *domain)
+{
+ if (domain->startup) {
+ domain->check_online_timeout = 10;
+ } else if (domain->check_online_timeout == 0) {
+ domain->check_online_timeout = lp_winbind_cache_time();
+ } else {
+ uint32 new_to = (domain->check_online_timeout * domain->check_online_timeout);
+ if (new_to < domain->check_online_timeout) {
+ new_to = 0x7FFFFFFF;
+ }
+ domain->check_online_timeout = new_to;
+ }
+}
+
+/****************************************************************
Handler triggered if we're offline to try and detect a DC.
****************************************************************/
@@ -104,8 +125,10 @@ static void check_domain_online_handler(struct timed_event *te,
/* This call takes care of setting the online
flag to true if we connected, or re-adding
- the offline handler if false. */
- init_dc_connection(domain);
+ the offline handler if false. Bypasses online
+ check so always does network calls. */
+
+ init_dc_connection_network(domain);
}
/****************************************************************
@@ -130,6 +153,11 @@ void set_domain_offline(struct winbindd_domain *domain)
domain->online = False;
+ /* Offline domains are always initialized. They're
+ re-initialized when they go back online. */
+
+ domain->initialized = True;
+
/* We only add the timeout handler that checks and
allows us to go back online when we've not
been told to remain offline. */
@@ -143,10 +171,12 @@ void set_domain_offline(struct winbindd_domain *domain)
/* If we're in statup mode, check again in 10 seconds, not in
lp_winbind_cache_time() seconds (which is 5 mins by default). */
+ if (domain->check_online_timeout == 0) {
+ calc_new_online_timeout(domain);
+ }
+
domain->check_online_event = add_timed_event( NULL,
- domain->startup ?
- timeval_current_ofs(10,0) :
- timeval_current_ofs(lp_winbind_cache_time(), 0),
+ timeval_current_ofs(domain->check_online_timeout,0),
"check_domain_online_handler",
check_domain_online_handler,
domain);
@@ -207,6 +237,12 @@ static void set_domain_online(struct winbindd_domain *domain)
}
}
+ /* Ensure we have no online timeout checks. */
+ domain->check_online_timeout = 0;
+ if (domain->check_online_event) {
+ TALLOC_FREE(domain->check_online_event);
+ }
+
domain->online = True;
}
@@ -1203,9 +1239,10 @@ static BOOL connection_ok(struct winbindd_domain *domain)
return True;
}
-/* Initialize a new connection up to the RPC BIND. */
+/* Initialize a new connection up to the RPC BIND.
+ Bypass online status check so always does network calls. */
-NTSTATUS init_dc_connection(struct winbindd_domain *domain)
+static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
{
NTSTATUS result;
@@ -1233,6 +1270,16 @@ NTSTATUS init_dc_connection(struct winbindd_domain *domain)
return result;
}
+NTSTATUS init_dc_connection(struct winbindd_domain *domain)
+{
+ if (domain->initialized && !domain->online) {
+ /* We check for online status elsewhere. */
+ return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ }
+
+ return init_dc_connection_network(domain);
+}
+
/******************************************************************************
We can 'sense' certain things about the DC by it's replies to certain
questions.
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index cdffc28087..98990664e3 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -163,6 +163,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
domain->last_seq_check = 0;
domain->initialized = False;
domain->online = is_internal_domain(sid);
+ domain->check_online_timeout = 0;
if (sid) {
sid_copy(&domain->sid, sid);
}
@@ -462,7 +463,6 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai
init_dc_connection(domain);
-#if 1
if (!domain->initialized) {
/* If we return error here we can't do any cached authentication,
but we may be in disconnected mode and can't initialize correctly.
@@ -472,13 +472,6 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai
DEBUG(5, ("winbindd_dual_init_connection: %s returning without initialization "
"online = %d\n", domain->name, (int)domain->online ));
}
-#else
- if (!domain->initialized) {
- DEBUG(1, ("Could not initialize domain %s\n",
- state->request.domain_name));
- return WINBINDD_ERROR;
- }
-#endif
fstrcpy(state->response.data.domain_info.name, domain->name);
fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name);