diff options
Diffstat (limited to 'source4/winbind/wb_samba3_cmd.c')
-rw-r--r-- | source4/winbind/wb_samba3_cmd.c | 222 |
1 files changed, 87 insertions, 135 deletions
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; + } } |