summaryrefslogtreecommitdiff
path: root/source4/winbind
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-10-09 12:13:05 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:35 -0500
commitbc42531213f9223a823d303cf307dfce3e8e99f1 (patch)
tree18be42c3c45bc236739f9e10e36a74733f699b73 /source4/winbind
parent5952157ad293c923ff14f07bfbbfa8b45e4d0bf2 (diff)
downloadsamba-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/winbind')
-rw-r--r--source4/winbind/wb_samba3_cmd.c120
-rw-r--r--source4/winbind/wb_samba3_protocol.c6
2 files changed, 126 insertions, 0 deletions
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;