summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/wbinfo.c1
-rw-r--r--source3/nsswitch/winbindd_cm.c69
-rw-r--r--source3/nsswitch/winbindd_pam.c15
3 files changed, 60 insertions, 25 deletions
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,