From 207a6bf3976d516e40c1ffa7312243e6ff92c791 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 14 Oct 2005 21:05:45 +0000 Subject: r11068: Fix pam_auth_crap, remove the sync code. I don't know what it was when I tested it, but I can not reproduce the problem I had with abartlett's initial implementation anymore. Fix a bug found using valgrind. Volker (This used to be commit 0c6c71ae3cd0a2f97eab2cc24a752976c32a39fc) --- source4/winbind/wb_async_helpers.c | 6 +- source4/winbind/wb_pam_auth.c | 48 ++++---- source4/winbind/wb_samba3_cmd.c | 222 +++++++++++++++---------------------- 3 files changed, 113 insertions(+), 163 deletions(-) diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c index d7cbd702ea..4850ec0d57 100644 --- a/source4/winbind/wb_async_helpers.c +++ b/source4/winbind/wb_async_helpers.c @@ -533,7 +533,7 @@ struct composite_context *wb_cmd_lookupname_send(struct wbsrv_call *call, if (state->domain->initialized) { ctx = wb_lsa_lookupnames_send(state->domain->lsa_pipe, state->domain->lsa_policy, - 1, &name); + 1, &state->name); if (ctx == NULL) goto failed; ctx->async.fn = cmd_lookupname_recv_sid; ctx->async.private_data = state; @@ -576,10 +576,8 @@ static void cmd_lookupname_recv_sid(struct composite_context *ctx) struct wb_sid_object **sids; state->ctx->status = wb_lsa_lookupnames_recv(ctx, state, &sids); - state->result = sids[0]; - if (!composite_is_ok(state->ctx)) return; - + state->result = sids[0]; composite_done(state->ctx); } diff --git a/source4/winbind/wb_pam_auth.c b/source4/winbind/wb_pam_auth.c index bd295e476b..f35ff4703d 100644 --- a/source4/winbind/wb_pam_auth.c +++ b/source4/winbind/wb_pam_auth.c @@ -49,13 +49,13 @@ static struct rpc_request *send_samlogon(struct pam_auth_crap_state *state); static void pam_auth_crap_recv_init(struct composite_context *ctx); static void pam_auth_crap_recv_samlogon(struct rpc_request *req); -struct composite_context *wb_pam_auth_crap_send(struct wbsrv_call *call, - const char *domain, - const char *user, - const char *workstation, - DATA_BLOB chal, - DATA_BLOB nt_resp, - DATA_BLOB lm_resp) +struct composite_context *wb_cmd_pam_auth_crap_send(struct wbsrv_call *call, + const char *domain, + const char *user, + const char *workstation, + DATA_BLOB chal, + DATA_BLOB nt_resp, + DATA_BLOB lm_resp) { struct composite_context *result, *ctx; struct pam_auth_crap_state *state; @@ -228,11 +228,11 @@ static void pam_auth_crap_recv_samlogon(struct rpc_request *req) composite_done(state->ctx); } -NTSTATUS wb_pam_auth_crap_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx, - DATA_BLOB *info3, - struct netr_UserSessionKey *user_session_key, - struct netr_LMSessionKey *lm_key) +NTSTATUS wb_cmd_pam_auth_crap_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + DATA_BLOB *info3, + struct netr_UserSessionKey *user_session_key, + struct netr_LMSessionKey *lm_key) { NTSTATUS status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { @@ -248,18 +248,18 @@ NTSTATUS wb_pam_auth_crap_recv(struct composite_context *c, return status; } -NTSTATUS wb_pam_auth_crap(struct wbsrv_call *call, - const char *domain, const char *user, - const char *workstation, - DATA_BLOB chal, DATA_BLOB nt_resp, - DATA_BLOB lm_resp, TALLOC_CTX *mem_ctx, - DATA_BLOB *info3, - struct netr_UserSessionKey *user_session_key, - struct netr_LMSessionKey *lm_key) +NTSTATUS wb_cmd_pam_auth_crap(struct wbsrv_call *call, + const char *domain, const char *user, + const char *workstation, + DATA_BLOB chal, DATA_BLOB nt_resp, + DATA_BLOB lm_resp, TALLOC_CTX *mem_ctx, + DATA_BLOB *info3, + struct netr_UserSessionKey *user_session_key, + struct netr_LMSessionKey *lm_key) { struct composite_context *c = - wb_pam_auth_crap_send(call, domain, user, workstation, - chal, nt_resp, lm_resp); - return wb_pam_auth_crap_recv(c, mem_ctx, info3, user_session_key, - lm_key); + wb_cmd_pam_auth_crap_send(call, domain, user, workstation, + chal, nt_resp, lm_resp); + return wb_cmd_pam_auth_crap_recv(c, mem_ctx, info3, user_session_key, + lm_key); } diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c index 37415e4993..9bd752ace8 100644 --- a/source4/winbind/wb_samba3_cmd.c +++ b/source4/winbind/wb_samba3_cmd.c @@ -183,140 +183,32 @@ NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call) return NT_STATUS_OK; } -NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) +static BOOL samba3_parse_domuser(TALLOC_CTX *mem_ctx, const char *domuser, + char **domain, char **user) { -#if 0 - struct wbsrv_service *service = - s3call->call->wbconn->listen_socket->service; - struct wbsrv_domain *domain; - struct creds_CredentialState *creds_state; - struct netr_Authenticator auth, auth2; - struct netr_NetworkInfo ninfo; - struct netr_LogonSamLogon r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; + char *p = strchr(domuser, *lp_winbind_separator()); - DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n")); - - mem_ctx = talloc_new(s3call); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; + if (p == NULL) { + *domain = talloc_strdup(mem_ctx, lp_workgroup()); + } else { + *domain = talloc_strndup(mem_ctx, domuser, + PTR_DIFF(p, domuser)); + domuser = p+1; } - domain = service->domains; + *user = talloc_strdup(mem_ctx, domuser); + + return ((*domain != NULL) && (*user != NULL)); +} + +static void pam_auth_crap_recv(struct composite_context *ctx); + +NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) +{ + struct composite_context *ctx; - ZERO_STRUCT(auth2); - creds_state = - cli_credentials_get_netlogon_creds(domain->schannel_creds); - - creds_client_authenticator(creds_state, &auth); - - ninfo.identity_info.account_name.string = - s3call->request.data.auth_crap.user; - ninfo.identity_info.domain_name.string = - s3call->request.data.auth_crap.domain; - ninfo.identity_info.parameter_control = 0; - ninfo.identity_info.logon_id_low = 0; - ninfo.identity_info.logon_id_high = 0; - ninfo.identity_info.workstation.string = - s3call->request.data.auth_crap.workstation; - memcpy(ninfo.challenge, s3call->request.data.auth_crap.chal, - sizeof(ninfo.challenge)); - ninfo.nt.length = s3call->request.data.auth_crap.nt_resp_len; - ninfo.nt.data = s3call->request.data.auth_crap.nt_resp; - ninfo.lm.length = s3call->request.data.auth_crap.lm_resp_len; - ninfo.lm.data = s3call->request.data.auth_crap.lm_resp; - - r.in.server_name = - talloc_asprintf(mem_ctx, "\\\\%s", - dcerpc_server_name(domain->netlogon_pipe)); - r.in.workstation = - cli_credentials_get_workstation(domain->schannel_creds); - r.in.credential = &auth; - r.in.return_authenticator = &auth2; - r.in.logon_level = 2; - r.in.validation_level = 3; - r.in.logon.network = &ninfo; - - r.out.return_authenticator = NULL; - status = dcerpc_netr_LogonSamLogon(domain->netlogon_pipe, mem_ctx, &r); - if (!r.out.return_authenticator || - !creds_client_check(creds_state, - &r.out.return_authenticator->cred)) { - DEBUG(0, ("Credentials check failed!\n")); - status = NT_STATUS_ACCESS_DENIED; - } - if (NT_STATUS_IS_OK(status)) { - struct netr_SamBaseInfo *base = NULL; - switch (r.in.validation_level) { - case 2: - base = &r.out.validation.sam2->base; - break; - case 3: - base = &r.out.validation.sam3->base; - break; - case 6: - base = &r.out.validation.sam6->base; - break; - } - - creds_decrypt_samlogon(creds_state, - r.in.validation_level, - &r.out.validation); - - if ((s3call->request.flags & WBFLAG_PAM_INFO3_NDR) - && (r.in.validation_level == 3)) { - DATA_BLOB tmp_blob, tmp_blob2; - status = ndr_push_struct_blob( - &tmp_blob, mem_ctx, r.out.validation.sam3, - (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); - if (NT_STATUS_IS_OK(status)) { - tmp_blob2 = data_blob_talloc( - mem_ctx, NULL, tmp_blob.length + 4); - if (!tmp_blob2.data) { - status = NT_STATUS_NO_MEMORY; - } - } - /* Ugly Samba3 winbind pipe compatability */ - if (NT_STATUS_IS_OK(status)) { - SIVAL(tmp_blob2.data, 0, 1); - memcpy(tmp_blob2.data + 4, tmp_blob.data, - tmp_blob.length); - } - s3call->response.extra_data = - talloc_steal(s3call, tmp_blob2.data); - s3call->response.length += tmp_blob2.length; - } - if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) { - memcpy(s3call->response.data.auth.user_session_key, - base->key.key, sizeof(s3call->response.data.auth.user_session_key) /* 16 */); - } - if (s3call->request.flags & WBFLAG_PAM_LMKEY) { - memcpy(s3call->response.data.auth.first_8_lm_hash, - base->LMSessKey.key, - sizeof(s3call->response.data.auth.first_8_lm_hash) /* 8 */); - } - } - - if (!NT_STATUS_IS_OK(status)) { - struct winbindd_response *resp = &s3call->response; - resp->result = WINBINDD_ERROR; - } else { - struct winbindd_response *resp = &s3call->response; - resp->result = WINBINDD_OK; - } - - WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.nt_status_string, - nt_errstr(status)); - WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.error_string, - nt_errstr(status)); - s3call->response.data.auth.pam_error = nt_status_to_pam(status); - return NT_STATUS_OK; -#else DATA_BLOB chal, nt_resp, lm_resp; - DATA_BLOB info3; - struct netr_UserSessionKey user_session_key; - struct netr_LMSessionKey lm_key; + char *domain, *user; DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n")); @@ -327,11 +219,71 @@ NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) lm_resp.data = s3call->request.data.auth_crap.lm_resp; lm_resp.length = s3call->request.data.auth_crap.lm_resp_len; - return wb_pam_auth_crap(s3call->call, - s3call->request.data.auth_crap.user, - s3call->request.data.auth_crap.domain, - s3call->request.data.auth_crap.workstation, - chal, nt_resp, lm_resp, - s3call, &info3, &user_session_key, &lm_key); -#endif + if (!samba3_parse_domuser(s3call, s3call->request.data.auth_crap.user, + &domain, &user)) { + return NT_STATUS_NO_MEMORY; + } + + ctx = wb_cmd_pam_auth_crap_send( + s3call->call, domain, user, + s3call->request.data.auth_crap.workstation, + chal, nt_resp, lm_resp); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + ctx->async.fn = pam_auth_crap_recv; + ctx->async.private_data = s3call; + s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC; + return NT_STATUS_OK; +} + +static void pam_auth_crap_recv(struct composite_context *ctx) +{ + struct wbsrv_samba3_call *s3call = + talloc_get_type(ctx->async.private_data, + struct wbsrv_samba3_call); + struct winbindd_response *resp = &s3call->response; + NTSTATUS status; + DATA_BLOB info3; + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lm_key; + + status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3, + &user_session_key, &lm_key); + if (!NT_STATUS_IS_OK(status)) goto done; + + if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) { + memcpy(s3call->response.data.auth.user_session_key, + &user_session_key.key, + sizeof(s3call->response.data.auth.user_session_key)); + } + + if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) { + s3call->response.extra_data = info3.data; + s3call->response.length += info3.length; + } + + if (s3call->request.flags & WBFLAG_PAM_LMKEY) { + memcpy(s3call->response.data.auth.first_8_lm_hash, + lm_key.key, + sizeof(s3call->response.data.auth.first_8_lm_hash)); + } + + resp->result = WINBINDD_OK; + + done: + if (!NT_STATUS_IS_OK(status)) { + resp->result = WINBINDD_ERROR; + WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string, + nt_errstr(status)); + WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string, + nt_errstr(status)); + resp->data.auth.pam_error = nt_status_to_pam(status); + } + + status = wbsrv_send_reply(s3call->call); + if (!NT_STATUS_IS_OK(status)) { + wbsrv_terminate_connection(s3call->call->wbconn, + "wbsrv_queue_reply() failed"); + return; + } } -- cgit