summaryrefslogtreecommitdiff
path: root/source4/winbind/wb_samba3_cmd.c
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/wb_samba3_cmd.c
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/wb_samba3_cmd.c')
-rw-r--r--source4/winbind/wb_samba3_cmd.c120
1 files changed, 120 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;
+}