From 14e6be49756eeef2486e6e305cdf051b743e023e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 11 Feb 2002 01:29:07 +0000 Subject: A few small winbind updates: Add a connection cache to the netlogon pipe. This makes a *massive* difference to the time-per-auth. Also fix up *some* of the memory leaks in other connection caches. Add some debugging messages for the is_connected() code. I'm thinking we should get a client implementation of SMBecho and call it here - as it would allow us to always know the DC is around before we start. Down the debug level for some of the pam_winbind code - I'll probably down it further when I'm finished debugging. Andrew Bartlett (This used to be commit 49d3e476662220775ef8da7db01ea17e77e11b0b) --- source3/nsswitch/wbinfo.c | 1 - source3/nsswitch/winbindd_cm.c | 69 ++++++++++++++++++++++++++++++++--------- source3/nsswitch/winbindd_pam.c | 15 +++------ 3 files changed, 60 insertions(+), 25 deletions(-) (limited to 'source3/nsswitch') diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 635af6064f..f39381e507 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -162,7 +162,6 @@ static BOOL wbinfo_list_domains(void) static BOOL wbinfo_show_sequence(void) { struct winbindd_response response; - fstring name; ZERO_STRUCT(response); diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index c1b5b27af8..4b23327ffe 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -352,11 +352,17 @@ static BOOL cm_open_connection(char *domain, char *pipe_name, static BOOL connection_ok(struct winbindd_cm_conn *conn) { - if (!conn->cli->initialised) + if (!conn->cli->initialised) { + DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n", + conn->controller, conn->domain, conn->pipe_name)); return False; + } - if (conn->cli->fd == -1) + if (conn->cli->fd == -1) { + DEBUG(3, ("Connection to %s for domain %s (pipe %s) has died or was never started (fd == -1)\n", + conn->controller, conn->domain, conn->pipe_name)); return False; + } return True; } @@ -377,8 +383,9 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain) strequal(conn->pipe_name, PIPE_LSARPC)) { if (!connection_ok(conn)) { + cli_shutdown(conn->cli); DLIST_REMOVE(cm_conns, conn); - return NULL; + SAFE_FREE(conn); } goto ok; @@ -429,8 +436,9 @@ CLI_POLICY_HND *cm_get_sam_handle(char *domain) if (strequal(conn->domain, domain) && strequal(conn->pipe_name, PIPE_SAMR)) { if (!connection_ok(conn)) { + cli_shutdown(conn->cli); DLIST_REMOVE(cm_conns, conn); - return NULL; + SAFE_FREE(conn); } goto ok; @@ -486,6 +494,7 @@ CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid) conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) { if (!connection_ok(conn)) { + /* Shutdown cli? Free conn? Allow retry of DC? */ DLIST_REMOVE(cm_conns, conn); return NULL; } @@ -556,6 +565,7 @@ CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, conn->pipe_data.samr.rid == user_rid) { if (!connection_ok(conn)) { + /* Shutdown cli? Free conn? Allow retry of DC? */ DLIST_REMOVE(cm_conns, conn); return NULL; } @@ -632,6 +642,7 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid, conn->pipe_data.samr.rid == group_rid) { if (!connection_ok(conn)) { + /* Shutdown cli? Free conn? Allow retry of DC? */ DLIST_REMOVE(cm_conns, conn); return NULL; } @@ -697,29 +708,59 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid, NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, struct cli_state **cli) { - struct winbindd_cm_conn conn; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct winbindd_cm_conn *conn; + NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + BOOL new_conn = False; /* Is this a new connection, to add to the list? */ /* Open an initial conection */ - ZERO_STRUCT(conn); - - if (!cm_open_connection(domain, PIPE_NETLOGON, &conn)) { - DEBUG(3, ("Could not open a connection to %s\n", domain)); - return result; + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_NETLOGON)) { + if (!connection_ok(conn)) { + cli_shutdown(conn->cli); + DLIST_REMOVE(cm_conns, conn); + SAFE_FREE(conn); + } else { + break; + } + } } - result = new_cli_nt_setup_creds(conn.cli, trust_passwd); + if (!conn) { + if (!(conn = (struct winbindd_cm_conn *) malloc(sizeof(struct winbindd_cm_conn)))) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(conn); + + if (!cm_open_connection(domain, PIPE_NETLOGON, conn)) { + DEBUG(3, ("Could not open a connection to %s\n", domain)); + free(conn); + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + + new_conn = True; + } + + result = new_cli_nt_setup_creds(conn->cli, trust_passwd); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("error connecting to domain password server: %s\n", get_nt_error_msg(result))); - cli_shutdown(conn.cli); + cli_shutdown(conn->cli); + DLIST_REMOVE(cm_conns, conn); + SAFE_FREE(conn); return result; } + /* Add to list */ + + if (new_conn) { + DLIST_ADD(cm_conns, conn); + } + if (cli) - *cli = conn.cli; + *cli = conn->cli; return result; } diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 3325917353..5e3cb149dd 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -93,12 +93,12 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); ZERO_STRUCT(info3); - + + /* Don't shut this down - it belongs to the connection cache code */ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); - result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; goto done; } @@ -111,15 +111,12 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) uni_group_cache_store_netlogon(mem_ctx, &info3); done: - if (cli) - cli_shutdown(cli); - state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, get_nt_error_msg(result)); fstrcpy(state->response.data.auth.error_string, get_nt_error_msg(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); - DEBUG(2, ("Plain-text authenticaion for user %s returned %s (PAM: %d)\n", + DEBUG(3, ("Plain-text authenticaion for user %s returned %s (PAM: %d)\n", state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); @@ -188,6 +185,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ZERO_STRUCT(info3); + /* Don't shut this down - it belongs to the connection cache code */ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli); if (!NT_STATUS_IS_OK(result)) { @@ -207,15 +205,12 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) done: - if (cli) - cli_shutdown(cli); - state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, get_nt_error_msg(result)); fstrcpy(state->response.data.auth.error_string, get_nt_error_msg(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); - DEBUG(2, ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(3, ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n", state->request.data.auth_crap.domain, state->request.data.auth_crap.user, state->response.data.auth.nt_status_string, -- cgit