summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2014-05-08 16:49:13 +1200
committerAndrew Bartlett <abartlet@samba.org>2014-06-11 12:43:58 +0200
commitba4467ca65d5f85a2732da27d88760b684c6e30d (patch)
treec7c8ad4191091424d0071f1fe92bce8cc0d61461
parenteabe7d732e6d9b64004bbb477384a1eae999815f (diff)
downloadsamba-ba4467ca65d5f85a2732da27d88760b684c6e30d.tar.gz
samba-ba4467ca65d5f85a2732da27d88760b684c6e30d.tar.xz
samba-ba4467ca65d5f85a2732da27d88760b684c6e30d.zip
s3-winbindd: Implement SamLogon IRPC call
We do this by lifting parts of the winbindd_dual_pam_auth_crap() code into a new helper function winbind_dual_SamLogon(). This allows us to implement the semantics we need for IRPC, without the artifacts of the winbindd pipe protocol. Change-Id: Idb169217e6d68d387c99765d0af7ed394cb5b93a Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Kamen Mazdrashki <kamenim@samba.org> Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Wed Jun 11 12:43:58 CEST 2014 on sn-devel-104
-rw-r--r--source3/winbindd/winbindd_dual_srv.c32
-rw-r--r--source3/winbindd/winbindd_irpc.c29
-rw-r--r--source3/winbindd/winbindd_pam.c129
-rw-r--r--source3/winbindd/winbindd_proto.h11
4 files changed, 150 insertions, 51 deletions
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 985f0a92097..5e33787bd34 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -758,8 +758,34 @@ NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
}
NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
- struct winbind_SamLogon *r)
+ struct winbind_SamLogon *r)
{
- p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct winbindd_domain *domain;
+ NTSTATUS status;
+ DATA_BLOB lm_response, nt_response;
+ domain = wb_child_domain();
+ if (domain == NULL) {
+ return NT_STATUS_REQUEST_NOT_ACCEPTED;
+ }
+
+ /* TODO: Handle interactive logons here */
+ if (r->in.validation_level != 3 ||
+ r->in.logon.network == NULL ||
+ (r->in.logon_level != NetlogonNetworkInformation
+ && r->in.logon_level != NetlogonNetworkTransitiveInformation)) {
+ return NT_STATUS_REQUEST_NOT_ACCEPTED;
+ }
+
+
+ lm_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
+ nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
+
+ status = winbind_dual_SamLogon(domain, p->mem_ctx,
+ r->in.logon.network->identity_info.parameter_control,
+ r->in.logon.network->identity_info.account_name.string,
+ r->in.logon.network->identity_info.domain_name.string,
+ r->in.logon.network->identity_info.workstation.string,
+ r->in.logon.network->challenge,
+ lm_response, nt_response, &r->out.validation.sam3);
+ return status;
}
diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
index 3c33076d615..cf58a088eb4 100644
--- a/source3/winbindd/winbindd_irpc.c
+++ b/source3/winbindd/winbindd_irpc.c
@@ -128,10 +128,39 @@ static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *m
domain, IRPC_CALL_TIMEOUT);
}
+static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
+ struct winbind_SamLogon *req)
+{
+ struct winbindd_domain *domain;
+ const char *target_domain_name;
+ if (req->in.logon.network == NULL) {
+ return NT_STATUS_REQUEST_NOT_ACCEPTED;
+ }
+ target_domain_name = req->in.logon.network->identity_info.domain_name.string;
+
+ domain = find_auth_domain(0, target_domain_name);
+ if (domain == NULL) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ DEBUG(5, ("wb_irpc_SamLogon called\n"));
+
+ return wb_irpc_forward_rpc_call(msg, msg,
+ winbind_event_context(),
+ req, NDR_WINBIND_SAMLOGON,
+ "winbind_SamLogon",
+ domain, IRPC_CALL_TIMEOUT);
+}
+
NTSTATUS wb_irpc_register(void)
{
NTSTATUS status;
status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
wb_irpc_DsrUpdateReadOnlyServerDnsRecords, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SAMLOGON,
+ wb_irpc_SamLogon, NULL);
return status;
}
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index c432afac1a2..1fb4360e351 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1866,6 +1866,76 @@ done:
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32_t logon_parameters,
+ const char *name_user,
+ const char *name_domain,
+ const char *workstation,
+ const uint8_t chal[8],
+ DATA_BLOB lm_response,
+ DATA_BLOB nt_response,
+ struct netr_SamInfo3 **info3)
+{
+ NTSTATUS result;
+
+ if (strequal(name_domain, get_global_sam_name())) {
+ DATA_BLOB chal_blob = data_blob_const(
+ chal, 8);
+
+ result = winbindd_dual_auth_passdb(
+ mem_ctx,
+ logon_parameters,
+ name_domain, name_user,
+ &chal_blob, &lm_response, &nt_response, info3);
+ goto process_result;
+ }
+
+ result = winbind_samlogon_retry_loop(domain,
+ mem_ctx,
+ logon_parameters,
+ domain->dcname,
+ name_user,
+ name_domain,
+ /* Bug #3248 - found by Stefan Burkei. */
+ workstation, /* We carefully set this above so use it... */
+ chal,
+ lm_response,
+ nt_response,
+ info3);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+process_result:
+
+ if (NT_STATUS_IS_OK(result)) {
+ struct dom_sid user_sid;
+
+ sid_compose(&user_sid, (*info3)->base.domain_sid,
+ (*info3)->base.rid);
+ wcache_invalidate_samlogon(find_domain_from_name(name_domain),
+ &user_sid);
+ netsamlogon_cache_store(name_user, *info3);
+ }
+
+done:
+
+ /* give us a more useful (more correct?) error code */
+ if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
+ (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
+ result = NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("NTLM CRAP authentication for user [%s]\\[%s] returned %s\n",
+ name_domain,
+ name_user,
+ nt_errstr(result)));
+
+ return result;
+}
+
enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
@@ -1916,46 +1986,22 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
state->request->data.auth_crap.nt_resp_len);
}
- if (strequal(name_domain, get_global_sam_name())) {
- DATA_BLOB chal_blob = data_blob_const(
- state->request->data.auth_crap.chal,
- sizeof(state->request->data.auth_crap.chal));
-
- result = winbindd_dual_auth_passdb(
- state->mem_ctx,
- state->request->data.auth_crap.logon_parameters,
- name_domain, name_user,
- &chal_blob, &lm_resp, &nt_resp, &info3);
- goto process_result;
- }
-
- result = winbind_samlogon_retry_loop(domain,
- state->mem_ctx,
- state->request->data.auth_crap.logon_parameters,
- domain->dcname,
- name_user,
- name_domain,
- /* Bug #3248 - found by Stefan Burkei. */
- workstation, /* We carefully set this above so use it... */
- state->request->data.auth_crap.chal,
- lm_resp,
- nt_resp,
- &info3);
+ result = winbind_dual_SamLogon(domain,
+ state->mem_ctx,
+ state->request->data.auth_crap.logon_parameters,
+ name_user,
+ name_domain,
+ /* Bug #3248 - found by Stefan Burkei. */
+ workstation, /* We carefully set this above so use it... */
+ state->request->data.auth_crap.chal,
+ lm_resp,
+ nt_resp,
+ &info3);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
-process_result:
-
if (NT_STATUS_IS_OK(result)) {
- struct dom_sid user_sid;
-
- sid_compose(&user_sid, info3->base.domain_sid,
- info3->base.rid);
- wcache_invalidate_samlogon(find_domain_from_name(name_domain),
- &user_sid);
- netsamlogon_cache_store(name_user, info3);
-
/* Check if the user is in the right group */
result = check_info3_in_group(
@@ -1979,25 +2025,12 @@ process_result:
done:
- /* give us a more useful (more correct?) error code */
- if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
- (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
- result = NT_STATUS_NO_LOGON_SERVERS;
- }
-
if (state->request->flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
result = nt_status_squash(result);
}
set_auth_errors(state->response, result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
- name_domain,
- name_user,
- state->response->data.auth.nt_status_string,
- state->response->data.auth.pam_error));
-
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 540a99ab43a..dfd61621c6a 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -394,6 +394,17 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state,
struct netr_SamInfo3 **info3);
+NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32_t logon_parameters,
+ const char *name_user,
+ const char *name_domain,
+ const char *workstation,
+ const uint8_t chal[8],
+ DATA_BLOB lm_response,
+ DATA_BLOB nt_response,
+ struct netr_SamInfo3 **info3);
+
/* The following definitions come from winbindd/winbindd_util.c */
struct winbindd_domain *domain_list(void);