From 10ada62bedd6edaaf1311ce03bf9695f927de7b9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2006 17:33:57 +0000 Subject: r19148: Finish last nights patch - make offline work again. Still under test. Jeremy. (This used to be commit 40a455db78f805daa6bfeb9e78fb78dcc12fd9a7) --- source3/nsswitch/winbindd_cache.c | 2 +- source3/nsswitch/winbindd_cm.c | 105 ++++++++++++++++++++++---------------- source3/nsswitch/winbindd_pam.c | 4 +- source3/nsswitch/winbindd_util.c | 18 +++++-- 4 files changed, 78 insertions(+), 51 deletions(-) (limited to 'source3/nsswitch') diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 43bb33bea9..745a9e262a 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -90,7 +90,7 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) /* we have to know what type of domain we are dealing with first */ if ( !domain->initialized ) - set_dc_type_and_flags( domain ); + 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 8f82f97d88..b947ce75ec 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -64,7 +64,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -static NTSTATUS init_dc_connection(struct winbindd_domain *domain); +static void set_dc_type_and_flags( struct winbindd_domain *domain ); /**************************************************************** Handler triggered if we're offline to try and detect a DC. @@ -175,24 +175,27 @@ static void set_domain_online(struct winbindd_domain *domain) /* If we are waiting to get a krb5 ticket, trigger immediately. */ GetTimeOfDay(&now); set_event_dispatch_time("krb5_ticket_gain_handler", now); - domain->online = True; /* Ok, we're out of any startup mode now... */ domain->startup = False; - /* We were offline - now we're online. We default to - using the MS-RPC backend if we started offline, - and if we're going online for the first time we - should really re-initialize the backends and the - checks to see if we're talking to an AD or NT domain. - */ - - domain->initialized = False; - - /* 'reconnect_methods' is the MS-RPC backend. */ - if (domain->backend == &reconnect_methods) { - domain->backend = NULL; + if (domain->online == False) { + /* We were offline - now we're online. We default to + using the MS-RPC backend if we started offline, + and if we're going online for the first time we + should really re-initialize the backends and the + checks to see if we're talking to an AD or NT domain. + */ + + domain->initialized = False; + + /* 'reconnect_methods' is the MS-RPC backend. */ + if (domain->backend == &reconnect_methods) { + domain->backend = NULL; + } } + + domain->online = True; } /**************************************************************** @@ -1179,17 +1182,29 @@ static BOOL connection_ok(struct winbindd_domain *domain) return True; } - + /* Initialize a new connection up to the RPC BIND. */ -static NTSTATUS init_dc_connection(struct winbindd_domain *domain) +NTSTATUS init_dc_connection(struct winbindd_domain *domain) { - if (connection_ok(domain)) + NTSTATUS result; + + if (connection_ok(domain)) { + if (!domain->initialized) { + set_dc_type_and_flags(domain); + } return NT_STATUS_OK; + } invalidate_cm_connection(&domain->conn); - return cm_open_connection(domain, &domain->conn); + result = cm_open_connection(domain, &domain->conn); + + if (NT_STATUS_IS_OK(result) && !domain->initialized) { + set_dc_type_and_flags(domain); + } + + return result; } /****************************************************************************** @@ -1200,7 +1215,7 @@ static NTSTATUS init_dc_connection(struct winbindd_domain *domain) is native mode. ******************************************************************************/ -void set_dc_type_and_flags( struct winbindd_domain *domain ) +static void set_dc_type_and_flags( struct winbindd_domain *domain ) { NTSTATUS result; DS_DOMINFO_CTR ctr; @@ -1211,28 +1226,20 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) char *domain_name = NULL; char *dns_name = NULL; DOM_SID *dom_sid = NULL; - int try_count = 0; ZERO_STRUCT( ctr ); - domain->native_mode = False; - domain->active_directory = False; - if (domain->internal) { domain->initialized = True; return; } - try_again: - - result = init_dc_connection(domain); - if (!NT_STATUS_IS_OK(result) || try_count > 2) { - DEBUG(5, ("set_dc_type_and_flags: Could not open a connection " - "to %s: (%s)\n", domain->name, nt_errstr(result))); - domain->initialized = True; + if (!connection_ok(domain)) { return; } + DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name )); + cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS, &result); @@ -1240,10 +1247,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) DEBUG(5, ("set_dc_type_and_flags: Could not bind to " "PI_LSARPC_DS on domain %s: (%s)\n", domain->name, nt_errstr(result))); - domain->initialized = True; - /* We want to detect network failures asap to try another dc. */ - try_count++; - goto try_again; + return; } result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx, @@ -1252,21 +1256,27 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) cli_rpc_pipe_close(cli); if (!NT_STATUS_IS_OK(result)) { - domain->initialized = True; + DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo " + "on domain %s failed: (%s)\n", + domain->name, nt_errstr(result))); return; } if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) && - !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) ) + !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) { domain->native_mode = True; + } else { + domain->native_mode = False; + } cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result); if (cli == NULL) { - domain->initialized = True; - /* We want to detect network failures asap to try another dc. */ - try_count++; - goto try_again; + DEBUG(5, ("set_dc_type_and_flags: Could not bind to " + "PI_LSARPC on domain %s: (%s)\n", + domain->name, nt_errstr(result))); + cli_rpc_pipe_close(cli); + return; } mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n", @@ -1290,6 +1300,8 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) } if (NT_STATUS_IS_OK(result)) { + domain->active_directory = True; + if (domain_name) fstrcpy(domain->name, domain_name); @@ -1298,10 +1310,9 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) if (dom_sid) sid_copy(&domain->sid, dom_sid); - - domain->active_directory = True; } else { - + domain->active_directory = False; + result = rpccli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -1323,13 +1334,17 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) } done: + DEBUG(5, ("set_dc_type_and_flags: domain %s is %snative mode.\n", + domain->name, domain->native_mode ? "" : "NOT ")); + + DEBUG(5,("set_dc_type_and_flags: domain %s is %sactive directory.\n", + domain->name, domain->active_directory ? "" : "NOT ")); + cli_rpc_pipe_close(cli); talloc_destroy(mem_ctx); domain->initialized = True; - - return; } static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain, diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 35c062163f..1a38b979b9 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -1006,7 +1006,7 @@ NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, } if (!contact_domain->initialized) { - set_dc_type_and_flags(contact_domain); + init_dc_connection(contact_domain); } if (!contact_domain->active_directory) { @@ -1217,7 +1217,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, "request in startup mode.\n", domain->name )); winbindd_flush_negative_conn_cache(domain); - set_dc_type_and_flags(domain); + init_dc_connection(domain); } DEBUG(10,("winbindd_dual_pam_auth: domain: %s last was %s\n", domain->name, domain->online ? "online":"offline")); diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index f26ec9232b..a6d6959446 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -474,13 +474,25 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai domain->dcaddr.sin_port = 0; } - set_dc_type_and_flags(domain); + 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. + Do what the previous code did and just return without initialization, + once we go online we'll re-initialize. + */ + 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); @@ -585,7 +597,7 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name) return NULL; if (!domain->initialized) - set_dc_type_and_flags(domain); + init_dc_connection(domain); return domain; } @@ -620,7 +632,7 @@ struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid) return NULL; if (!domain->initialized) - set_dc_type_and_flags(domain); + init_dc_connection(domain); return domain; } -- cgit