diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-07-16 11:27:29 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:01:08 -0500 |
commit | c86e98aa8070137834f0587b613e215db8802f27 (patch) | |
tree | 1782cf9a4d8aefb40bc962adbb337da90b48682e /source4/winbind | |
parent | 3ccf9ff2ab468d91b9843139df2dfdccbe24c7a1 (diff) | |
download | samba-c86e98aa8070137834f0587b613e215db8802f27.tar.gz samba-c86e98aa8070137834f0587b613e215db8802f27.tar.bz2 samba-c86e98aa8070137834f0587b613e215db8802f27.zip |
r23890: Allow wbinfo -a to work against Samba4's winbind.
Add a test for wbinfo -a to test_member.sh
Reimplement the server-side 'pam_auth' and 'pam_auth_crap' calls to
use the same SamLogon code as auth_winbind uses.
In my previous code, we did not bind to the LSA and SAMR pipes, before
attempting operations. We now do this (how we passed any tests before
is beyond me).
This required some rework, particularly to make it easier to setup
secondary connections. The new rpc_secondary_auth_connection()
function also performs the bind.
The dcerpc_connect.c file was getting to big, so things have been
merged into dcerpc_secondary.c.
Andrew Bartlett
(This used to be commit 365778a993b7d76af6d53ba2a598b7e271741dc5)
Diffstat (limited to 'source4/winbind')
-rw-r--r-- | source4/winbind/wb_connect_sam.c | 10 | ||||
-rw-r--r-- | source4/winbind/wb_dom_info.c | 14 | ||||
-rw-r--r-- | source4/winbind/wb_init_domain.c | 22 | ||||
-rw-r--r-- | source4/winbind/wb_pam_auth.c | 176 |
4 files changed, 76 insertions, 146 deletions
diff --git a/source4/winbind/wb_connect_sam.c b/source4/winbind/wb_connect_sam.c index 3ca4734ae9..935ba266d3 100644 --- a/source4/winbind/wb_connect_sam.c +++ b/source4/winbind/wb_connect_sam.c @@ -67,8 +67,10 @@ struct composite_context *wb_connect_samr_send(TALLOC_CTX *mem_ctx, /* this will make the secondary connection on the same IPC$ share, secured with SPNEGO, NTLMSSP or SCHANNEL */ - ctx = dcerpc_secondary_connection_send(domain->netlogon_pipe, - domain->samr_binding); + ctx = dcerpc_secondary_auth_connection_send(domain->netlogon_pipe, + domain->samr_binding, + &dcerpc_table_samr, + domain->schannel_creds); composite_continue(state->ctx, ctx, connect_samr_recv_pipe, state); return result; @@ -84,8 +86,8 @@ static void connect_samr_recv_pipe(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct connect_samr_state); - state->ctx->status = dcerpc_secondary_connection_recv(ctx, - &state->samr_pipe); + state->ctx->status = dcerpc_secondary_auth_connection_recv(ctx, state, + &state->samr_pipe); if (!composite_is_ok(state->ctx)) return; state->connect_handle = talloc(state, struct policy_handle); diff --git a/source4/winbind/wb_dom_info.c b/source4/winbind/wb_dom_info.c index 571ecb39b2..5ec8f1a159 100644 --- a/source4/winbind/wb_dom_info.c +++ b/source4/winbind/wb_dom_info.c @@ -45,7 +45,7 @@ struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx, { struct composite_context *result, *ctx; struct get_dom_info_state *state; - struct dom_sid *dup_sid; + struct dom_sid *dom_sid; result = composite_create(mem_ctx, service->task->event_ctx); if (result == NULL) goto failed; @@ -57,11 +57,17 @@ struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx, state->info = talloc_zero(state, struct wb_dom_info); if (state->info == NULL) goto failed; - dup_sid = dom_sid_dup(state, sid); - if (dup_sid == NULL) goto failed; + state->info->name = talloc_strdup(state->info, domain_name); + if (state->info->name == NULL) goto failed; + + state->info->sid = dom_sid_dup(state->info, sid); + if (state->info->sid == NULL) goto failed; + + dom_sid = dom_sid_dup(mem_ctx, sid); + if (dom_sid == NULL) goto failed; ctx = finddcs_send(mem_ctx, domain_name, NBT_NAME_LOGON, - dup_sid, lp_name_resolve_order(), service->task->event_ctx, + dom_sid, lp_name_resolve_order(), service->task->event_ctx, service->task->msg_ctx); if (ctx == NULL) goto failed; diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index 69ea9c7533..cdc1491f2b 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -202,7 +202,7 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct init_domain_state); - state->ctx->status = dcerpc_pipe_connect_b_recv(ctx, state, + state->ctx->status = dcerpc_pipe_connect_b_recv(ctx, state->domain, &state->domain->netlogon_pipe); if (!composite_is_ok(state->ctx)) { @@ -224,13 +224,17 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) /* this will make the secondary connection on the same IPC$ share, secured with SPNEGO or NTLMSSP */ - ctx = dcerpc_secondary_connection_send(state->domain->netlogon_pipe, - state->domain->lsa_binding); + ctx = dcerpc_secondary_auth_connection_send(state->domain->netlogon_pipe, + state->domain->lsa_binding, + &dcerpc_table_lsarpc, + state->domain->schannel_creds + ); composite_continue(state->ctx, ctx, init_domain_recv_lsa_pipe, state); } static bool retry_with_schannel(struct init_domain_state *state, struct dcerpc_binding *binding, + const struct dcerpc_interface_table *table, void (*continuation)(struct composite_context *)) { struct composite_context *ctx; @@ -246,8 +250,10 @@ static bool retry_with_schannel(struct init_domain_state *state, /* Try again, likewise on the same IPC$ share, secured with SCHANNEL */ - ctx = dcerpc_secondary_connection_send(state->domain->netlogon_pipe, - binding); + ctx = dcerpc_secondary_auth_connection_send(state->domain->netlogon_pipe, + binding, + table, + state->domain->schannel_creds); composite_continue(state->ctx, ctx, continuation, state); return true; } else { @@ -264,10 +270,11 @@ static void init_domain_recv_lsa_pipe(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct init_domain_state); - state->ctx->status = dcerpc_secondary_connection_recv(ctx, - &state->domain->lsa_pipe); + state->ctx->status = dcerpc_secondary_auth_connection_recv(ctx, state->domain, + &state->domain->lsa_pipe); if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_LOGON_FAILURE)) { if (retry_with_schannel(state, state->domain->lsa_binding, + &dcerpc_table_lsarpc, init_domain_recv_lsa_pipe)) { return; } @@ -307,6 +314,7 @@ static void init_domain_recv_lsa_policy(struct rpc_request *req) if ((!NT_STATUS_IS_OK(state->ctx->status) || !NT_STATUS_IS_OK(state->lsa_openpolicy.out.result))) { if (retry_with_schannel(state, state->domain->lsa_binding, + &dcerpc_table_lsarpc, init_domain_recv_lsa_pipe)) { return; } diff --git a/source4/winbind/wb_pam_auth.c b/source4/winbind/wb_pam_auth.c index fffb7c408c..4874254eff 100644 --- a/source4/winbind/wb_pam_auth.c +++ b/source4/winbind/wb_pam_auth.c @@ -28,23 +28,22 @@ #include "libcli/auth/libcli_auth.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" +#include "librpc/gen_ndr/winbind.h" /* Oh, there is so much to keep an eye on when authenticating a user. Oh my! */ struct pam_auth_crap_state { struct composite_context *ctx; struct event_context *event_ctx; - uint32_t logon_parameters; - const char *domain_name; - const char *user_name; + + struct winbind_SamLogon *req; char *unix_username; - const char *workstation; - DATA_BLOB chal, nt_resp, lm_resp; - struct creds_CredentialState *creds_state; - struct netr_Authenticator auth, auth2; struct netr_NetworkInfo ninfo; struct netr_LogonSamLogon r; + const char *user_name; + const char *domain_name; + struct netr_UserSessionKey user_session_key; struct netr_LMSessionKey lm_key; DATA_BLOB info3; @@ -54,8 +53,7 @@ struct pam_auth_crap_state { * NTLM authentication. */ -static void pam_auth_crap_recv_domain(struct composite_context *ctx); -static void pam_auth_crap_recv_samlogon(struct rpc_request *req); +static void pam_auth_crap_recv_logon(struct composite_context *ctx); struct composite_context *wb_cmd_pam_auth_crap_send(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, @@ -69,6 +67,8 @@ struct composite_context *wb_cmd_pam_auth_crap_send(TALLOC_CTX *mem_ctx, { struct composite_context *result, *ctx; struct pam_auth_crap_state *state; + struct netr_NetworkInfo *ninfo; + DATA_BLOB tmp_nt_resp, tmp_lm_resp; result = composite_create(mem_ctx, service->task->event_ctx); if (result == NULL) goto failed; @@ -78,35 +78,43 @@ struct composite_context *wb_cmd_pam_auth_crap_send(TALLOC_CTX *mem_ctx, state->ctx = result; result->private_data = state; - state->logon_parameters = logon_parameters; + state->req = talloc(state, struct winbind_SamLogon); + + state->req->in.logon_level = 2; + state->req->in.validation_level = 3; + ninfo = state->req->in.logon.network = talloc(state, struct netr_NetworkInfo); + if (ninfo == NULL) goto failed; + + ninfo->identity_info.account_name.string = talloc_strdup(state, user); + ninfo->identity_info.domain_name.string = talloc_strdup(state, domain); + ninfo->identity_info.parameter_control = logon_parameters; + ninfo->identity_info.logon_id_low = 0; + ninfo->identity_info.logon_id_high = 0; + ninfo->identity_info.workstation.string = talloc_strdup(state, workstation); + + SMB_ASSERT(chal.length == sizeof(ninfo->challenge)); + memcpy(ninfo->challenge, chal.data, + sizeof(ninfo->challenge)); + + tmp_nt_resp = data_blob_talloc(ninfo, nt_resp.data, nt_resp.length); + if ((nt_resp.data != NULL) && + (tmp_nt_resp.data == NULL)) goto failed; - state->domain_name = talloc_strdup(state, domain); - if (state->domain_name == NULL) goto failed; + tmp_lm_resp = data_blob_talloc(ninfo, lm_resp.data, lm_resp.length); + if ((lm_resp.data != NULL) && + (tmp_lm_resp.data == NULL)) goto failed; - state->user_name = talloc_strdup(state, user); - if (state->user_name == NULL) goto failed; + ninfo->nt.length = tmp_nt_resp.length; + ninfo->nt.data = tmp_nt_resp.data; + ninfo->lm.length = tmp_lm_resp.length; + ninfo->lm.data = tmp_lm_resp.data; state->unix_username = NULL; - state->workstation = talloc_strdup(state, workstation); - if (state->workstation == NULL) goto failed; - - state->chal = data_blob_talloc(state, chal.data, chal.length); - if ((chal.data != NULL) && (state->chal.data == NULL)) goto failed; - - state->nt_resp = data_blob_talloc(state, nt_resp.data, nt_resp.length); - if ((nt_resp.data != NULL) && - (state->nt_resp.data == NULL)) goto failed; - - state->lm_resp = data_blob_talloc(state, lm_resp.data, lm_resp.length); - if ((lm_resp.data != NULL) && - (state->lm_resp.data == NULL)) goto failed; - - ctx = wb_sid2domain_send(state, service, service->primary_sid); + ctx = wb_sam_logon_send(mem_ctx, service, state->req); if (ctx == NULL) goto failed; - ctx->async.fn = pam_auth_crap_recv_domain; - ctx->async.private_data = state; + composite_continue(result, ctx, pam_auth_crap_recv_logon, state); return result; failed: @@ -119,95 +127,19 @@ struct composite_context *wb_cmd_pam_auth_crap_send(TALLOC_CTX *mem_ctx, Send of a SamLogon request to authenticate a user. */ -static void pam_auth_crap_recv_domain(struct composite_context *ctx) +static void pam_auth_crap_recv_logon(struct composite_context *ctx) { + DATA_BLOB tmp_blob; + struct netr_SamBaseInfo *base; struct pam_auth_crap_state *state = talloc_get_type(ctx->async.private_data, struct pam_auth_crap_state); - struct rpc_request *req; - struct wbsrv_domain *domain; - - state->ctx->status = wb_sid2domain_recv(ctx, &domain); - if (!composite_is_ok(state->ctx)) return; - state->creds_state = - cli_credentials_get_netlogon_creds(domain->schannel_creds); - - creds_client_authenticator(state->creds_state, &state->auth); - - state->ninfo.identity_info.account_name.string = state->user_name; - state->ninfo.identity_info.domain_name.string = state->domain_name; - state->ninfo.identity_info.parameter_control = state->logon_parameters; - state->ninfo.identity_info.logon_id_low = 0; - state->ninfo.identity_info.logon_id_high = 0; - state->ninfo.identity_info.workstation.string = state->workstation; - - SMB_ASSERT(state->chal.length == sizeof(state->ninfo.challenge)); - memcpy(state->ninfo.challenge, state->chal.data, - sizeof(state->ninfo.challenge)); - - state->ninfo.nt.length = state->nt_resp.length; - state->ninfo.nt.data = state->nt_resp.data; - state->ninfo.lm.length = state->lm_resp.length; - state->ninfo.lm.data = state->lm_resp.data; - - state->r.in.server_name = talloc_asprintf( - state, "\\\\%s", dcerpc_server_name(domain->netlogon_pipe)); - if (composite_nomem(state->r.in.server_name, state->ctx)) return; - - ZERO_STRUCT(state->auth2); - - state->r.in.computer_name = - cli_credentials_get_workstation(domain->schannel_creds); - state->r.in.credential = &state->auth; - state->r.in.return_authenticator = &state->auth2; - state->r.in.logon_level = 2; - state->r.in.validation_level = 3; - state->r.in.logon.network = &state->ninfo; - state->r.out.return_authenticator = NULL; - - req = dcerpc_netr_LogonSamLogon_send(domain->netlogon_pipe, state, - &state->r); - composite_continue_rpc(state->ctx, req, pam_auth_crap_recv_samlogon, - state); -} - -/* - NTLM Authentication - - Check the SamLogon reply, decrypt and parse out the session keys and the - info3 structure. -*/ -static void pam_auth_crap_recv_samlogon(struct rpc_request *req) -{ - struct pam_auth_crap_state *state = - talloc_get_type(req->async.private_data, - struct pam_auth_crap_state); - struct netr_SamBaseInfo *base; - DATA_BLOB tmp_blob; - state->ctx->status = dcerpc_ndr_request_recv(req); + state->ctx->status = wb_sam_logon_recv(ctx, state, state->req); if (!composite_is_ok(state->ctx)) return; - if ((state->r.out.return_authenticator == NULL) || - (!creds_client_check(state->creds_state, - &state->r.out.return_authenticator->cred))) { - DEBUG(0, ("Credentials check failed!\n")); - composite_error(state->ctx, NT_STATUS_ACCESS_DENIED); - return; - } - - state->ctx->status = state->r.out.result; - if (!composite_is_ok(state->ctx)) return; - - /* Decrypt the session keys before we reform the info3, so the - * person on the other end of winbindd pipe doesn't have to. - * They won't have the encryption key anyway */ - creds_decrypt_samlogon(state->creds_state, - state->r.in.validation_level, - &state->r.out.validation); - state->ctx->status = ndr_push_struct_blob( - &tmp_blob, state, state->r.out.validation.sam3, + &tmp_blob, state, state->req->out.validation.sam3, (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); if (!composite_is_ok(state->ctx)) return; @@ -220,25 +152,7 @@ static void pam_auth_crap_recv_samlogon(struct rpc_request *req) SIVAL(state->info3.data, 0, 1); memcpy(state->info3.data+4, tmp_blob.data, tmp_blob.length); - /* We actually only ask for level 3, and assume it above, but - * anyway... */ - - base = NULL; - switch(state->r.in.validation_level) { - case 2: - base = &state->r.out.validation.sam2->base; - break; - case 3: - base = &state->r.out.validation.sam3->base; - break; - case 6: - base = &state->r.out.validation.sam6->base; - break; - } - if (base == NULL) { - composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); - return; - } + base = &state->req->out.validation.sam3->base; state->user_session_key = base->key; state->lm_key = base->LMSessKey; |