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:
parent
eabe7d732e
commit
ba4467ca65
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user