diff options
-rw-r--r-- | source3/nsswitch/winbindd.h | 1 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_dual.c | 13 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 12 |
4 files changed, 27 insertions, 3 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 98c0e12349..1437343965 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -169,6 +169,7 @@ struct winbindd_domain { BOOL primary; /* is this our primary domain ? */ BOOL internal; /* BUILTIN and member SAM */ BOOL online; /* is this domain available ? */ + BOOL startup; /* are we in the first 30 seconds after fork ? */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 36748b0b11..7a1768354d 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -912,8 +912,8 @@ static BOOL find_new_dc(TALLOC_CTX *mem_ctx, { for (i=0; i<num_dcs; i++) { DEBUG(10, ("find_new_dc: open_any_socket_out failed for " - "domain %s address %s\n", - domain->name, inet_ntoa(dcs[i].ip) )); + "domain %s address %s. Error was %s\n", + domain->name, inet_ntoa(dcs[i].ip), strerror(errno) )); winbind_add_failed_connection_entry(domain, dcs[i].name, NT_STATUS_UNSUCCESSFUL); } diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c index 659242e918..e2e0db8570 100644 --- a/source3/nsswitch/winbindd_dual.c +++ b/source3/nsswitch/winbindd_dual.c @@ -582,7 +582,7 @@ static void child_msg_offline(int msg_type, struct process_id src, void *buf, si /* Ensure any negative cache entries with the netbios or realm names are removed. */ -static void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain) +void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain) { flush_negative_conn_cache_for_domain(domain->name); if (*domain->alt_name) { @@ -681,6 +681,7 @@ static BOOL fork_domain_child(struct winbindd_child *child) int fdpair[2]; struct winbindd_cli_state state; extern BOOL override_logfile; + time_t startup_time; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { DEBUG(0, ("Could not open child pipe: %s\n", @@ -764,6 +765,9 @@ static BOOL fork_domain_child(struct winbindd_child *child) message_register(MSG_WINBIND_ONLINE,child_msg_online); message_register(MSG_WINBIND_ONLINESTATUS,child_msg_onlinestatus); + child->domain->startup = True; + startup_time = time(NULL); + while (1) { int ret; @@ -780,6 +784,13 @@ static BOOL fork_domain_child(struct winbindd_child *child) GetTimeOfDay(&now); + if (child->domain->startup && (now.tv_sec > startup_time + 30)) { + /* No longer in "startup" mode. */ + DEBUG(10,("fork_domain_child: domain %s no longer in 'startup' mode.\n", + child->domain->name )); + child->domain->startup = False; + } + tp = get_timed_events_timeout(&t); if (tp) { DEBUG(11,("select will use timeout of %u.%u seconds\n", diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index f27fc610a6..df12ceb3f1 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -1208,6 +1208,18 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, parse_domain_user(state->request.data.auth.user, name_domain, name_user); + if (domain->online == False && domain->startup) { + /* Logons are very important to users. If we're offline and + we get a request within the first 30 seconds of startup, + try very hard to find a DC and go online. */ + + DEBUG(10,("winbindd_dual_pam_auth: domain: %s offline and auth " + "request in startup mode.\n", domain->name )); + + winbindd_flush_negative_conn_cache(domain); + set_dc_type_and_flags(domain); + } + DEBUG(10,("winbindd_dual_pam_auth: domain: %s last was %s\n", domain->name, domain->online ? "online":"offline")); /* Check for Kerberos authentication */ |