1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

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
This commit is contained in:
Andrew Bartlett 2014-05-08 16:49:13 +12:00
parent eabe7d732e
commit ba4467ca65
4 changed files with 150 additions and 51 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);