From: Stefan Metzmacher Date: Wed, 16 Oct 2024 15:55:41 +0000 (+0200) Subject: s4:rpc_server/netlogon: split out dcesrv_netr_ServerAuthenticateGeneric() X-Git-Tag: samba-4.21.2~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=30d744d0a6a44cf70a95fb60dc5f52b46260dc26;p=thirdparty%2Fsamba.git s4:rpc_server/netlogon: split out dcesrv_netr_ServerAuthenticateGeneric() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit e4132c492ded7cadc60371b524e72e41f71f75e9) --- diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index f0b01297f96..61c214af7e2 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -388,14 +388,23 @@ return_downgrade: return orig_status; } -/* - * Do the actual processing of a netr_ServerAuthenticate3 message. - * called from dcesrv_netr_ServerAuthenticate3, which handles the logging. - */ -static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( +typedef NTSTATUS (*dcesrv_netr_ServerAuthenticateGenericCallback_fn)( + struct dcesrv_call_state *dce_call, + const struct netlogon_server_pipe_state *challenge, + const struct netr_ServerAuthenticate3 *r, + uint32_t client_flags, + const struct dom_sid *client_sid, + uint32_t negotiate_flags, + const struct ldb_message *sam_msg, + const struct ldb_message *tdo_msg, + TALLOC_CTX *mem_ctx, + struct netlogon_creds_CredentialState **_creds); + +static NTSTATUS dcesrv_netr_ServerAuthenticateGeneric( struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate3 *r, + dcesrv_netr_ServerAuthenticateGenericCallback_fn auth_fn, const char **trust_account_for_search, const char **trust_account_in_db, struct dom_sid **sid) @@ -405,10 +414,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( struct netlogon_server_pipe_state challenge; struct netlogon_creds_CredentialState *creds; struct ldb_context *sam_ctx; - struct samr_Password *curNtHash = NULL; - struct samr_Password *prevNtHash = NULL; uint32_t user_account_control; struct ldb_message **msgs; + struct ldb_message *tdo_msg = NULL; NTSTATUS nt_status; static const char *attrs[] = { "unicodePwd", @@ -551,7 +559,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { - struct ldb_message *tdo_msg = NULL; static const char *const tdo_attrs[] = {"trustAuthIncoming", "trustAttributes", "flatName", @@ -620,22 +627,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( nt_status); } - nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx, - &curNtHash, - &prevNtHash); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) { - return dcesrv_netr_ServerAuthenticate3_check_downgrade( - dce_call, r, pipe_state, negotiate_flags, - NULL, /* trust_account_in_db */ - NT_STATUS_NO_TRUST_SAM_ACCOUNT); - } - if (!NT_STATUS_IS_OK(nt_status)) { - return dcesrv_netr_ServerAuthenticate3_check_downgrade( - dce_call, r, pipe_state, negotiate_flags, - NULL, /* trust_account_in_db */ - nt_status); - } - flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL); if (flatname == NULL) { return dcesrv_netr_ServerAuthenticate3_check_downgrade( @@ -760,28 +751,92 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( } if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { - nt_status = samdb_result_passwords_no_lockout(mem_ctx, - dce_call->conn->dce_ctx->lp_ctx, - msgs[0], &curNtHash); - if (!NT_STATUS_IS_OK(nt_status)) { - return NT_STATUS_ACCESS_DENIED; - } + tdo_msg = NULL; } - if (curNtHash == NULL) { + *sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid"); + if (*sid == NULL) { return NT_STATUS_ACCESS_DENIED; } - if (!challenge_valid) { - DEBUG(1, ("No challenge requested by client [%s/%s], " - "cannot authenticate\n", - log_escape(mem_ctx, r->in.computer_name), - log_escape(mem_ctx, r->in.account_name))); + nt_status = auth_fn(dce_call, + challenge_valid ? &challenge : NULL, + r, + client_flags, + *sid, + negotiate_flags, + msgs[0], + tdo_msg, + mem_ctx, + &creds); + if (!NT_STATUS_IS_OK(nt_status)) { + ZERO_STRUCTP(r->out.return_credentials); + return nt_status; + } + + nt_status = schannel_save_creds_state(mem_ctx, + dce_call->conn->dce_ctx->lp_ctx, + creds); + if (!NT_STATUS_IS_OK(nt_status)) { + ZERO_STRUCTP(r->out.return_credentials); + return nt_status; + } + + *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], + "objectSid", 0); + + return NT_STATUS_OK; +} + +static NTSTATUS dcesrv_netr_ServerAuthenticateNTHash_cb( + struct dcesrv_call_state *dce_call, + const struct netlogon_server_pipe_state *challenge, + const struct netr_ServerAuthenticate3 *r, + uint32_t client_flags, + const struct dom_sid *client_sid, + uint32_t negotiate_flags, + const struct ldb_message *sam_msg, + const struct ldb_message *tdo_msg, + TALLOC_CTX *mem_ctx, + struct netlogon_creds_CredentialState **_creds) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + struct netlogon_creds_CredentialState *creds = NULL; + struct samr_Password *curNtHash = NULL; + struct samr_Password *prevNtHash = NULL; + NTSTATUS status; + + if (tdo_msg != NULL) { + status = dsdb_trust_get_incoming_passwords(tdo_msg, + frame, + &curNtHash, + &prevNtHash); + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_DISABLED)) { + status = NT_STATUS_NO_TRUST_SAM_ACCOUNT; + } + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + } else { + status = samdb_result_passwords_no_lockout(frame, + lp_ctx, + sam_msg, + &curNtHash); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return NT_STATUS_ACCESS_DENIED; + } + } + + if (curNtHash == NULL) { + TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; } - *sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid"); - if (*sid == NULL) { + if (challenge == NULL) { + TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; } @@ -789,13 +844,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( r->in.account_name, r->in.computer_name, r->in.secure_channel_type, - &challenge.client_challenge, - &challenge.server_challenge, + &challenge->client_challenge, + &challenge->server_challenge, curNtHash, r->in.credentials, r->out.return_credentials, client_flags, - *sid, + client_sid, negotiate_flags); if (creds == NULL && prevNtHash != NULL) { /* @@ -808,32 +863,48 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( r->in.account_name, r->in.computer_name, r->in.secure_channel_type, - &challenge.client_challenge, - &challenge.server_challenge, + &challenge->client_challenge, + &challenge->server_challenge, prevNtHash, r->in.credentials, r->out.return_credentials, client_flags, - *sid, + client_sid, negotiate_flags); } if (creds == NULL) { + TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; } - nt_status = schannel_save_creds_state(mem_ctx, - dce_call->conn->dce_ctx->lp_ctx, - creds); - if (!NT_STATUS_IS_OK(nt_status)) { - ZERO_STRUCTP(r->out.return_credentials); - return nt_status; - } + *_creds = creds; + TALLOC_FREE(frame); + return NT_STATUS_OK; +} - *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], - "objectSid", 0); +/* + * Do the actual processing of a netr_ServerAuthenticate3 message. + * called from dcesrv_netr_ServerAuthenticate3, which handles the logging. + */ +static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( + struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct netr_ServerAuthenticate3 *r, + const char **trust_account_for_search, + const char **trust_account_in_db, + struct dom_sid **sid) +{ + dcesrv_netr_ServerAuthenticateGenericCallback_fn auth_fn = + dcesrv_netr_ServerAuthenticateNTHash_cb; - return NT_STATUS_OK; + return dcesrv_netr_ServerAuthenticateGeneric(dce_call, + mem_ctx, + r, + auth_fn, + trust_account_for_search, + trust_account_in_db, + sid); } /*