From 56b4aa326626128c178c838977ef9e3d564b7bc7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Apr 2010 14:14:43 +0200 Subject: s3: Move the in-memory ccache to the parent None of this blocks, so there is no reason to keep this in a winbind child process --- source3/winbindd/winbindd_ccache_access.c | 65 +++++++++++-------------------- source3/winbindd/winbindd_domain.c | 8 ---- source3/winbindd/winbindd_pam.c | 48 ++++------------------- source3/winbindd/winbindd_pam_auth.c | 22 ++++++++++- source3/winbindd/winbindd_pam_chauthtok.c | 31 ++++++++++++++- source3/winbindd/winbindd_pam_logoff.c | 10 ++++- source3/winbindd/winbindd_proto.h | 1 + 7 files changed, 90 insertions(+), 95 deletions(-) diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index ac08f6879f..935d9fe121 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -168,6 +168,10 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring name_domain, name_user; + NTSTATUS result = NT_STATUS_NOT_SUPPORTED; + struct WINBINDD_MEMORY_CREDS *entry; + DATA_BLOB initial, challenge, auth; + uint32 initial_blob_len, challenge_blob_len, extra_len; /* Ensure null termination */ state->request->data.ccache_ntlm_auth.user[ @@ -200,26 +204,6 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) return; } - sendto_domain(state, domain); -} - -enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - NTSTATUS result = NT_STATUS_NOT_SUPPORTED; - struct WINBINDD_MEMORY_CREDS *entry; - DATA_BLOB initial, challenge, auth; - fstring name_domain, name_user; - uint32 initial_blob_len, challenge_blob_len, extra_len; - - /* Ensure null termination */ - state->request->data.ccache_ntlm_auth.user[ - sizeof(state->request->data.ccache_ntlm_auth.user)-1]='\0'; - - DEBUG(3, ("winbindd_dual_ccache_ntlm_auth: [%5lu]: perform NTLM auth on " - "behalf of user %s (dual)\n", (unsigned long)state->pid, - state->request->data.ccache_ntlm_auth.user)); - /* validate blob lengths */ initial_blob_len = state->request->data.ccache_ntlm_auth.initial_blob_len; challenge_blob_len = state->request->data.ccache_ntlm_auth.challenge_blob_len; @@ -294,13 +278,18 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma data_blob_free(&auth); process_result: - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; + if (!NT_STATUS_IS_OK(result)) { + request_error(state); + return; + } + request_ok(state); } void winbindd_ccache_save(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring name_domain, name_user; + NTSTATUS status; /* Ensure null termination */ state->request->data.ccache_save.user[ @@ -323,8 +312,16 @@ void winbindd_ccache_save(struct winbindd_cli_state *state) return; } - domain = find_auth_domain(state->request->flags, name_domain); + /* + * The domain is checked here only for compatibility + * reasons. We used to do the winbindd memory ccache for + * ntlm_auth in the domain child. With that code, we had to + * make sure that we do have a domain around to send this + * to. Now we do the memory cache in the parent winbindd, + * where it would not matter if we have a domain or not. + */ + domain = find_auth_domain(state->request->flags, name_domain); if (domain == NULL) { DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n", name_domain)); @@ -337,24 +334,6 @@ void winbindd_ccache_save(struct winbindd_cli_state *state) return; } - sendto_domain(state, domain); -} - -enum winbindd_result winbindd_dual_ccache_save( - struct winbindd_domain *domain, struct winbindd_cli_state *state) -{ - NTSTATUS status = NT_STATUS_NOT_SUPPORTED; - - /* Ensure null termination */ - state->request->data.ccache_save.user[ - sizeof(state->request->data.ccache_save.user)-1]='\0'; - state->request->data.ccache_save.pass[ - sizeof(state->request->data.ccache_save.pass)-1]='\0'; - - DEBUG(3, ("winbindd_dual_ccache_save: [%5lu]: save password of user " - "%s\n", (unsigned long)state->pid, - state->request->data.ccache_save.user)); - status = winbindd_add_memory_creds( state->request->data.ccache_save.user, state->request->data.ccache_save.uid, @@ -363,8 +342,8 @@ enum winbindd_result winbindd_dual_ccache_save( if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("winbindd_add_memory_creds failed %s\n", nt_errstr(status))); - return WINBINDD_ERROR; + request_error(state); + return; } - - return WINBINDD_OK; + request_ok(state); } diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index 4689b5f5db..d82db19adc 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -62,14 +62,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .name = "PAM_CHAUTHTOK", .struct_cmd = WINBINDD_PAM_CHAUTHTOK, .struct_fn = winbindd_dual_pam_chauthtok, - },{ - .name = "CCACHE_NTLM_AUTH", - .struct_cmd = WINBINDD_CCACHE_NTLMAUTH, - .struct_fn = winbindd_dual_ccache_ntlm_auth, - },{ - .name = "CCACHE_SAVE", - .struct_cmd = WINBINDD_CCACHE_SAVE, - .struct_fn = winbindd_dual_ccache_save, },{ .name = "NDRCMD", .struct_cmd = WINBINDD_DUAL_NDRCMD, diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index d8643a6158..3f350e3fb2 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -522,11 +522,11 @@ static void setup_return_cc_name(struct winbindd_cli_state *state, const char *c #endif -static uid_t get_uid_from_state(struct winbindd_cli_state *state) +uid_t get_uid_from_request(struct winbindd_request *request) { uid_t uid; - uid = state->request->data.auth.uid; + uid = request->data.auth.uid; if (uid < 0) { DEBUG(1,("invalid uid: '%u'\n", (unsigned int)uid)); @@ -535,6 +535,11 @@ static uid_t get_uid_from_state(struct winbindd_cli_state *state) return uid; } +static uid_t get_uid_from_state(struct winbindd_cli_state *state) +{ + return get_uid_from_request(state->request); +} + /********************************************************************** Authenticate a user with a clear text password using Kerberos and fill up ccache if required @@ -1623,30 +1628,12 @@ process_result: if ((state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) { - /* Store in-memory creds for single-signon using ntlm_auth. */ - result = winbindd_add_memory_creds(state->request->data.auth.user, - get_uid_from_state(state), - state->request->data.auth.pass); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10,("Failed to store memory creds: %s\n", nt_errstr(result))); - goto done; - } - if (lp_winbind_offline_logon()) { result = winbindd_store_creds(domain, state->mem_ctx, state->request->data.auth.user, state->request->data.auth.pass, info3, NULL); - if (!NT_STATUS_IS_OK(result)) { - - /* Release refcount. */ - winbindd_delete_memory_creds(state->request->data.auth.user); - - DEBUG(10,("Failed to store creds: %s\n", nt_errstr(result))); - goto done; - } } } @@ -2026,26 +2013,6 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact done: if (NT_STATUS_IS_OK(result) && (state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) { - - /* Update the single sign-on memory creds. */ - result = winbindd_replace_memory_creds(state->request->data.chauthtok.user, - newpass); - - /* When we login from gdm or xdm and password expires, - * we change password, but there are no memory crendentials - * So, winbindd_replace_memory_creds() returns - * NT_STATUS_OBJECT_NAME_NOT_FOUND. This is not a failure. - * --- BoYang - * */ - if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - result = NT_STATUS_OK; - } - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10,("Failed to replace memory creds: %s\n", nt_errstr(result))); - goto process_result; - } - if (lp_winbind_offline_logon()) { result = winbindd_update_creds_by_name(contact_domain, state->mem_ctx, user, @@ -2152,7 +2119,6 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, process_result: - winbindd_delete_memory_creds(state->request->data.logoff.user); set_auth_errors(state->response, result); diff --git a/source3/winbindd/winbindd_pam_auth.c b/source3/winbindd/winbindd_pam_auth.c index b32d882827..94d98ec55b 100644 --- a/source3/winbindd/winbindd_pam_auth.c +++ b/source3/winbindd/winbindd_pam_auth.c @@ -21,6 +21,7 @@ #include "winbindd.h" struct winbindd_pam_auth_state { + struct winbindd_request *request; struct winbindd_response *response; }; @@ -43,6 +44,7 @@ struct tevent_req *winbindd_pam_auth_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + state->request = request; /* Ensure null termination */ request->data.auth.user[sizeof(request->data.auth.user)-1] = '\0'; @@ -121,5 +123,23 @@ NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req, *response = *state->response; response->result = WINBINDD_PENDING; state->response = talloc_move(response, &state->response); - return NT_STATUS(response->data.auth.nt_status); + + status = NT_STATUS(response->data.auth.nt_status); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (state->request->flags & WBFLAG_PAM_CACHED_LOGIN) { + + /* Store in-memory creds for single-signon using ntlm_auth. */ + + status = winbindd_add_memory_creds( + state->request->data.auth.user, + get_uid_from_request(state->request), + state->request->data.auth.pass); + DEBUG(10, ("winbindd_add_memory_creds returned: %s\n", + nt_errstr(status))); + } + + return status; } diff --git a/source3/winbindd/winbindd_pam_chauthtok.c b/source3/winbindd/winbindd_pam_chauthtok.c index 9f231e00ce..8ffbc29b97 100644 --- a/source3/winbindd/winbindd_pam_chauthtok.c +++ b/source3/winbindd/winbindd_pam_chauthtok.c @@ -21,6 +21,7 @@ #include "winbindd.h" struct winbindd_pam_chauthtok_state { + struct winbindd_request *request; struct winbindd_response *response; }; @@ -44,6 +45,7 @@ struct tevent_req *winbindd_pam_chauthtok_send( if (req == NULL) { return NULL; } + state->request = request; /* Ensure null termination */ request->data.chauthtok.user[ @@ -117,5 +119,32 @@ NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req, *response = *state->response; response->result = WINBINDD_PENDING; state->response = talloc_move(response, &state->response); - return NT_STATUS(response->data.auth.nt_status); + + status = NT_STATUS(response->data.auth.nt_status); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (state->request->flags & WBFLAG_PAM_CACHED_LOGIN) { + + /* Update the single sign-on memory creds. */ + status = winbindd_replace_memory_creds( + state->request->data.chauthtok.user, + state->request->data.chauthtok.newpass); + + DEBUG(10, ("winbindd_replace_memory_creds returned %s\n", + nt_errstr(status))); + + /* + * When we login from gdm or xdm and password expires, + * we change password, but there are no memory + * crendentials So, winbindd_replace_memory_creds() + * returns NT_STATUS_OBJECT_NAME_NOT_FOUND. This is + * not a failure. --- BoYang + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + status = NT_STATUS_OK; + } + } + return status; } diff --git a/source3/winbindd/winbindd_pam_logoff.c b/source3/winbindd/winbindd_pam_logoff.c index 9cf7f17d13..c32a63e146 100644 --- a/source3/winbindd/winbindd_pam_logoff.c +++ b/source3/winbindd/winbindd_pam_logoff.c @@ -21,6 +21,7 @@ #include "winbindd.h" struct winbindd_pam_logoff_state { + struct winbindd_request *request; struct winbindd_response *response; }; @@ -43,6 +44,7 @@ struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + state->request = request; /* Ensure null termination */ /* Ensure null termination */ @@ -135,5 +137,11 @@ NTSTATUS winbindd_pam_logoff_recv(struct tevent_req *req, *response = *state->response; response->result = WINBINDD_PENDING; state->response = talloc_move(response, &state->response); - return NT_STATUS(response->data.auth.nt_status); + + status = NT_STATUS(response->data.auth.nt_status); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + winbindd_delete_memory_creds(state->request->data.logoff.user); + return status; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index e47f300ab7..221c51ed85 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -380,6 +380,7 @@ void ndr_print_winbindd_domain(struct ndr_print *ndr, /* The following definitions come from winbindd/winbindd_pam.c */ bool check_request_flags(uint32_t flags); +uid_t get_uid_from_request(struct winbindd_request *request); struct winbindd_domain *find_auth_domain(uint8_t flags, const char *domain_name); enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, -- cgit