]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:rpc_server/netlogon: split out dcesrv_netr_ServerAuthenticateGeneric()
authorStefan Metzmacher <metze@samba.org>
Wed, 16 Oct 2024 15:55:41 +0000 (17:55 +0200)
committerJule Anger <janger@samba.org>
Wed, 13 Nov 2024 08:41:12 +0000 (08:41 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e4132c492ded7cadc60371b524e72e41f71f75e9)

source4/rpc_server/netlogon/dcerpc_netlogon.c

index f0b01297f96ea8226ee2649a0d0bb4b0d2d9ffbd..61c214af7e264ebf9a2c52d671e91031351fd624 100644 (file)
@@ -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);
 }
 
 /*