diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-10-09 12:13:05 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:39:35 -0500 |
commit | bc42531213f9223a823d303cf307dfce3e8e99f1 (patch) | |
tree | 18be42c3c45bc236739f9e10e36a74733f699b73 /source4 | |
parent | 5952157ad293c923ff14f07bfbbfa8b45e4d0bf2 (diff) | |
download | samba-bc42531213f9223a823d303cf307dfce3e8e99f1.tar.gz samba-bc42531213f9223a823d303cf307dfce3e8e99f1.tar.bz2 samba-bc42531213f9223a823d303cf307dfce3e8e99f1.zip |
r10844: Add challenge-response authentication to Samba4's winbindd for VL.
Plaintext should be simple, but I'm going to do some infrustructure
work first.
Andrew Bartlett
(This used to be commit c9273729e4db4adc0061087fe7e0332e2bc24384)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/nsswitch/winbindd_nss.h | 3 | ||||
-rw-r--r-- | source4/winbind/wb_samba3_cmd.c | 120 | ||||
-rw-r--r-- | source4/winbind/wb_samba3_protocol.c | 6 |
3 files changed, 128 insertions, 1 deletions
diff --git a/source4/nsswitch/winbindd_nss.h b/source4/nsswitch/winbindd_nss.h index 34a6dc4a42..a8830a2379 100644 --- a/source4/nsswitch/winbindd_nss.h +++ b/source4/nsswitch/winbindd_nss.h @@ -186,7 +186,6 @@ struct winbindd_request { pid_t pid; /* pid of calling process */ uint32_t flags; /* flags relavant to a given request */ winbind_string domain_name; /* name of domain for which the request applies */ - int msgid; union { winbind_string winsreq; /* WINS request */ @@ -247,6 +246,8 @@ struct winbindd_request { winbind_string cache_key; } dual_sidaliases; } data; + char *extra_data; + size_t extra_len; char null_term; }; diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c index 6687c861af..525ed06e30 100644 --- a/source4/winbind/wb_samba3_cmd.c +++ b/source4/winbind/wb_samba3_cmd.c @@ -33,6 +33,7 @@ #include "libcli/smb_composite/smb_composite.h" #include "include/version.h" #include "lib/events/events.h" +#include "librpc/gen_ndr/ndr_netlogon.h" NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call) { @@ -175,3 +176,122 @@ static void lookupname_recv_sid(struct composite_context *ctx) return; } } + +NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call) +{ + struct wbsrv_service *service = + s3call->call->wbconn->listen_socket->service; + + s3call->response.result = WINBINDD_ERROR; + return NT_STATUS_OK; +} + +NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) +{ + struct wbsrv_service *service = + s3call->call->wbconn->listen_socket->service; + struct creds_CredentialState *creds_state; + struct netr_Authenticator auth, auth2; + struct netr_NetworkInfo ninfo; + struct netr_LogonSamLogon r; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(s3call); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCT(auth2); + creds_state = cli_credentials_get_netlogon_creds(service->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(service->netlogon_pipe)); + r.in.workstation = cli_credentials_get_workstation(service->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(service->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; + 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; +} diff --git a/source4/winbind/wb_samba3_protocol.c b/source4/winbind/wb_samba3_protocol.c index f5e6fb71cf..e99952be96 100644 --- a/source4/winbind/wb_samba3_protocol.c +++ b/source4/winbind/wb_samba3_protocol.c @@ -93,6 +93,12 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call) case WINBINDD_LOOKUPNAME: return wbsrv_samba3_lookupname(s3call); + + case WINBINDD_PAM_AUTH: + return wbsrv_samba3_pam_auth(s3call); + + case WINBINDD_PAM_AUTH_CRAP: + return wbsrv_samba3_pam_auth_crap(s3call); } s3call->response.result = WINBINDD_ERROR; |