return status;
}
-
-static NTSTATUS map_validation_levels(uint16_t level_in,
- uint16_t level_out,
- union netr_Validation *inout)
-{
- uint32_t level_in_out;
- union netr_Validation out;
-
- if (inout == NULL) {
- return NT_STATUS_OK;
- }
-
- if (level_in == level_out) {
- return NT_STATUS_OK;
- }
-
- level_in_out = level_in;
- level_in_out <<= 16;
- level_in_out |= level_out;
-
- ZERO_STRUCT(out);
-
- switch (level_out) {
- case 0x0002:
- out.sam2 = talloc_zero(inout, struct netr_SamInfo2);
- if (out.sam2 == NULL) {
- return NT_STATUS_NO_MEMORY;
- };
- break;
-
- case 0x0003:
- out.sam3 = talloc_zero(inout, struct netr_SamInfo3);
- if (out.sam3 == NULL) {
- return NT_STATUS_NO_MEMORY;
- };
- break;
-
- case 0x0006:
- out.sam6 = talloc_zero(inout, struct netr_SamInfo6);
- if (out.sam6 == NULL) {
- return NT_STATUS_NO_MEMORY;
- };
- break;
-
- default:
- DBG_ERR("mapping from in[%u] to out[%u] not implemented\n",
- (unsigned)level_in, (unsigned)level_out);
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- switch (level_in_out) {
- case 0x00020003:
- out.sam3->base = inout->sam2->base;
- break;
-
- case 0x00020006:
- out.sam6->base = inout->sam2->base;
- break;
-
- case 0x00030002:
- out.sam2->base = inout->sam3->base;
- break;
-
- case 0x00030006:
- out.sam6->base = inout->sam3->base;
- out.sam6->sidcount = inout->sam3->sidcount;
- out.sam6->sids = inout->sam3->sids;
- break;
-
- case 0x00060002:
- out.sam2->base = inout->sam6->base;
- break;
-
- case 0x00060003:
- out.sam3->base = inout->sam6->base;
- out.sam3->sidcount = inout->sam6->sidcount;
- out.sam3->sids = inout->sam6->sids;
- break;
-
- default:
- DBG_ERR("mapping from in[%u] to out[%u] not implemented\n",
- (unsigned)level_in, (unsigned)level_out);
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- *inout = out;
- return NT_STATUS_OK;
-}
-
-NTSTATUS _winbind_LogonSamLogon(struct pipes_struct *p,
- struct winbind_LogonSamLogon *r)
-{
- NTSTATUS status;
- struct winbindd_domain *domain;
- struct rpc_pipe_client *netlogon_pipe;
- enum netr_LogonInfoClass logon_level = 0;
- uint16_t validation_level = 0;
- union netr_Validation *validation = NULL;
- struct dcerpc_binding_handle *b;
- bool retry = false;
-
- domain = wb_child_domain();
- if (domain == NULL) {
- return NT_STATUS_REQUEST_NOT_ACCEPTED;
- }
-
- if (domain->internal) {
- /*
- * This only called from the NETLOGON server
- * and should not access the local SAM.
- */
- return NT_STATUS_REQUEST_NOT_ACCEPTED;
- }
-
- switch (r->in.logon_level) {
- case NetlogonInteractiveInformation:
- case NetlogonInteractiveTransitiveInformation:
- /*
- * TODO: Map the Transitive levels
- * based on the trust attributes.
- */
- logon_level = r->in.logon_level;
- break;
-
- case NetlogonServiceInformation:
- case NetlogonServiceTransitiveInformation:
- /*
- * TODO: Map the Transitive levels
- * based on the trust attributes.
- */
- logon_level = r->in.logon_level;
- break;
-
- case NetlogonNetworkInformation:
- case NetlogonNetworkTransitiveInformation:
- /*
- * TODO: Map the Transitive levels
- * based on the trust attributes.
- */
- logon_level = r->in.logon_level;
- break;
-
- case NetlogonGenericInformation:
- /*
- * We don't support NetlogonGenericInformation
- * here (yet).
- */
- logon_level = r->in.logon_level;
- return NT_STATUS_REQUEST_NOT_ACCEPTED;
-
- default:
- /*
- */
- return NT_STATUS_REQUEST_NOT_ACCEPTED;
- }
-
-reconnect:
- status = cm_connect_netlogon(domain, &netlogon_pipe);
- reset_cm_connection_on_error(domain, status);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- b = netlogon_pipe->binding_handle;
-
- status = netlogon_creds_cli_LogonSamLogon(domain->conn.netlogon_creds,
- netlogon_pipe->binding_handle,
- logon_level,
- r->in.logon,
- p->mem_ctx,
- &validation_level,
- &validation,
- r->out.authoritative,
- r->out.flags);
-
- if (!dcerpc_binding_handle_is_connected(b) && !retry) {
- DEBUG(10, ("Session might have expired. "
- "Reconnect and retry once.\n"));
- invalidate_cm_connection(domain);
- retry = true;
- goto reconnect;
- }
-
- reset_cm_connection_on_error(domain, status);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- status = map_validation_levels(validation_level,
- r->in.validation_level,
- validation);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- *r->out.validation = *validation;
- DBG_INFO("succeeded\n");
- return NT_STATUS_OK;
-}
irpc_send_reply(state->msg, NT_STATUS_OK);
}
-static NTSTATUS wb_irpc_LogonSamLogon(struct irpc_message *msg,
- struct winbind_LogonSamLogon *req)
-{
- struct winbindd_domain *domain;
- const struct netr_IdentityInfo *identity_info;
- const char *target_domain_name;
-
- if (req->in.logon == NULL) {
- /*
- * the caller should have checked
- */
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- switch (req->in.logon_level) {
- case NetlogonInteractiveInformation:
- case NetlogonServiceInformation:
- case NetlogonInteractiveTransitiveInformation:
- case NetlogonServiceTransitiveInformation:
-
- if (req->in.logon->password == NULL) {
- /*
- * the caller should have checked
- */
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- identity_info = &req->in.logon->password->identity_info;
-
- break;
-
- case NetlogonNetworkInformation:
- case NetlogonNetworkTransitiveInformation:
-
- if (req->in.logon->network == NULL) {
- /*
- * the caller should have checked
- */
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- identity_info = &req->in.logon->network->identity_info;
- break;
-
- case NetlogonGenericInformation:
- if (req->in.logon->generic == NULL) {
- /*
- * the caller should have checked
- */
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- identity_info = &req->in.logon->generic->identity_info;
- break;
-
- default:
- /*
- * This should not be passed to us
- */
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- /*
- * TODO: fetch the domain name from a possible
- * UPN in identity_info->account_name, when we're
- * an AD-DC.
- */
- target_domain_name = identity_info->domain_name.string;
-
- domain = find_auth_domain(0, target_domain_name);
- if (domain == NULL) {
- *req->out.authoritative = 0;
- req->out.result = NT_STATUS_NO_SUCH_USER;
- return NT_STATUS_OK;
- }
-
- DEBUG(5, ("wb_irpc_LogonSamLogon called\n"));
-
- return wb_irpc_forward_rpc_call(msg, msg,
- winbind_event_context(),
- req, NDR_WINBIND_LOGONSAMLOGON,
- "winbind_LogonSamLogon",
- domain, 45 /* timeout */);
-}
-
NTSTATUS wb_irpc_register(void)
{
NTSTATUS status;
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = IRPC_REGISTER(winbind_imessaging_context(),
- winbind, WINBIND_LOGONSAMLOGON,
- wb_irpc_LogonSamLogon, NULL);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
return NT_STATUS_OK;
}