CVE-2022-38023 s4:rpc_server/netlogon: Move schannel and credentials check functions...
authorSamuel Cabrero <scabrero@suse.de>
Thu, 22 Dec 2022 13:03:23 +0000 (14:03 +0100)
committerJule Anger <janger@samba.org>
Mon, 23 Jan 2023 09:06:16 +0000 (09:06 +0000)
Will be used later by s3 netlogon server.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 121e7b0e39478c5291100652ac92c263f406076b)

librpc/rpc/server/netlogon/schannel_util.c [new file with mode: 0644]
librpc/rpc/server/netlogon/schannel_util.h [new file with mode: 0644]
librpc/wscript_build
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/wscript_build

diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c
new file mode 100644 (file)
index 0000000..9b2a88a
--- /dev/null
@@ -0,0 +1,576 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   netlogon schannel utility functions
+
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
+   Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
+   Copyright (C) Matthias Dieter Wallnöfer            2009-2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "schannel_util.h"
+#include "param/param.h"
+#include "libcli/security/dom_sid.h"
+#include "libcli/auth/schannel.h"
+#include "librpc/rpc/dcesrv_core.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
+#include "lib/util/util_str_escape.h"
+
+struct dcesrv_netr_check_schannel_state {
+       struct dom_sid account_sid;
+       enum dcerpc_AuthType auth_type;
+       enum dcerpc_AuthLevel auth_level;
+
+       bool schannel_global_required;
+       bool schannel_required;
+       bool schannel_explicitly_set;
+
+       bool seal_global_required;
+       bool seal_required;
+       bool seal_explicitly_set;
+
+       NTSTATUS result;
+};
+
+static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *dce_call,
+                                                    const struct netlogon_creds_CredentialState *creds,
+                                                    enum dcerpc_AuthType auth_type,
+                                                    enum dcerpc_AuthLevel auth_level,
+                                                    struct dcesrv_netr_check_schannel_state **_s)
+{
+       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+       int schannel = lpcfg_server_schannel(lp_ctx);
+       bool schannel_global_required = (schannel == true);
+       bool schannel_required = schannel_global_required;
+       const char *explicit_opt = NULL;
+       bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
+       bool require_seal = global_require_seal;
+       const char *explicit_seal_opt = NULL;
+#define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
+       struct dcesrv_netr_check_schannel_state *s = NULL;
+       NTSTATUS status;
+
+       *_s = NULL;
+
+       s = dcesrv_iface_state_find_conn(dce_call,
+                       DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
+                       struct dcesrv_netr_check_schannel_state);
+       if (s != NULL) {
+               if (!dom_sid_equal(&s->account_sid, creds->sid)) {
+                       goto new_state;
+               }
+               if (s->auth_type != auth_type) {
+                       goto new_state;
+               }
+               if (s->auth_level != auth_level) {
+                       goto new_state;
+               }
+
+               *_s = s;
+               return NT_STATUS_OK;
+       }
+
+new_state:
+       TALLOC_FREE(s);
+       s = talloc_zero(dce_call,
+                       struct dcesrv_netr_check_schannel_state);
+       if (s == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       s->account_sid = *creds->sid;
+       s->auth_type = auth_type;
+       s->auth_level = auth_level;
+       s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
+
+       /*
+        * We don't use lpcfg_parm_bool(), as we
+        * need the explicit_opt pointer in order to
+        * adjust the debug messages.
+        */
+       explicit_seal_opt = lpcfg_get_parametric(lp_ctx,
+                                                NULL,
+                                                "server schannel require seal",
+                                                creds->account_name);
+       if (explicit_seal_opt != NULL) {
+               require_seal = lp_bool(explicit_seal_opt);
+       }
+
+       /*
+        * We don't use lpcfg_parm_bool(), as we
+        * need the explicit_opt pointer in order to
+        * adjust the debug messages.
+        */
+       explicit_opt = lpcfg_get_parametric(lp_ctx,
+                                           NULL,
+                                           "server require schannel",
+                                           creds->account_name);
+       if (explicit_opt != NULL) {
+               schannel_required = lp_bool(explicit_opt);
+       }
+
+       s->schannel_global_required = schannel_global_required;
+       s->schannel_required = schannel_required;
+       s->schannel_explicitly_set = explicit_opt != NULL;
+
+       s->seal_global_required = global_require_seal;
+       s->seal_required = require_seal;
+       s->seal_explicitly_set = explicit_seal_opt != NULL;
+
+       status = dcesrv_iface_state_store_conn(dce_call,
+                       DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
+                       s);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       *_s = s;
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_call,
+                                               struct dcesrv_netr_check_schannel_state *s,
+                                               const struct netlogon_creds_CredentialState *creds,
+                                               uint16_t opnum)
+{
+       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+       int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
+       int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
+       int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
+       int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
+               "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
+       TALLOC_CTX *frame = talloc_stackframe();
+       unsigned int dbg_lvl = DBGLVL_DEBUG;
+       const char *opname = "<unknown>";
+       const char *reason = "<unknown>";
+
+       if (opnum < ndr_table_netlogon.num_calls) {
+               opname = ndr_table_netlogon.calls[opnum].name;
+       }
+
+       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+               if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+                       reason = "WITH SEALED";
+               } else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+                       reason = "WITH SIGNED";
+               } else {
+                       reason = "WITH INVALID";
+                       dbg_lvl = DBGLVL_ERR;
+                       s->result = NT_STATUS_INTERNAL_ERROR;
+               }
+       } else {
+               reason = "WITHOUT";
+       }
+
+       if (!NT_STATUS_EQUAL(s->result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+               if (!NT_STATUS_IS_OK(s->result)) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(s->result)));
+               TALLOC_FREE(frame);
+               return s->result;
+       }
+
+       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
+           s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
+       {
+               s->result = NT_STATUS_OK;
+
+               if (s->schannel_explicitly_set && !s->schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
+               } else if (!s->schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+               }
+               if (s->seal_explicitly_set && !s->seal_required) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
+               } else if (!s->seal_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(s->result)));
+
+               if (s->schannel_explicitly_set && !s->schannel_required) {
+                       DEBUG(CVE_2020_1472_warn_level, (
+                             "CVE-2020-1472(ZeroLogon): "
+                             "Option 'server require schannel:%s = no' not needed for '%s'!\n",
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name)));
+               }
+
+               if (s->seal_explicitly_set && !s->seal_required) {
+                       DEBUG(CVE_2022_38023_warn_level, (
+                             "CVE-2022-38023: "
+                             "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name)));
+               }
+
+               TALLOC_FREE(frame);
+               return s->result;
+       }
+
+       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+               if (s->seal_required) {
+                       s->result = NT_STATUS_ACCESS_DENIED;
+
+                       if (s->seal_explicitly_set) {
+                               dbg_lvl = DBGLVL_NOTICE;
+                       } else {
+                               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+                       }
+                       if (s->schannel_explicitly_set && !s->schannel_required) {
+                               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
+                       }
+
+                       DEBUG(dbg_lvl, (
+                             "CVE-2022-38023: "
+                             "%s request (opnum[%u]) %s schannel from "
+                             "from client_account[%s] client_computer_name[%s] %s\n",
+                             opname, opnum, reason,
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name),
+                             nt_errstr(s->result)));
+                       if (s->seal_explicitly_set) {
+                               D_NOTICE("CVE-2022-38023: Option "
+                                        "'server schannel require seal:%s = yes' "
+                                        "rejects access for client.\n",
+                                        log_escape(frame, creds->account_name));
+                       } else {
+                               DEBUG(CVE_2020_1472_error_level, (
+                                     "CVE-2022-38023: Check if option "
+                                     "'server schannel require seal:%s = no' "
+                                     "might be needed for a legacy client.\n",
+                                     log_escape(frame, creds->account_name)));
+                       }
+                       if (s->schannel_explicitly_set && !s->schannel_required) {
+                               DEBUG(CVE_2020_1472_warn_level, (
+                                     "CVE-2020-1472(ZeroLogon): Option "
+                                     "'server require schannel:%s = no' "
+                                     "not needed for '%s'!\n",
+                                     log_escape(frame, creds->account_name),
+                                     log_escape(frame, creds->computer_name)));
+                       }
+                       TALLOC_FREE(frame);
+                       return s->result;
+               }
+
+               s->result = NT_STATUS_OK;
+
+               if (s->schannel_explicitly_set && !s->schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
+               } else if (!s->schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+               }
+               if (s->seal_explicitly_set && !s->seal_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+               } else if (!s->seal_required) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon): "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(s->result)));
+               if (s->schannel_explicitly_set && !s->schannel_required) {
+                       DEBUG(CVE_2020_1472_warn_level, (
+                             "CVE-2020-1472(ZeroLogon): "
+                             "Option 'server require schannel:%s = no' not needed for '%s'!\n",
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name)));
+               }
+               if (s->seal_explicitly_set && !s->seal_required) {
+                       D_INFO("CVE-2022-38023: "
+                              "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
+                              log_escape(frame, creds->account_name),
+                              log_escape(frame, creds->computer_name));
+               } else if (!s->seal_required) {
+                       /*
+                        * admins should set
+                        * server schannel require seal:COMPUTER$ = no
+                        * in order to avoid the level 0 messages.
+                        * Over time they can switch the global value
+                        * to be strict.
+                        */
+                       DEBUG(CVE_2022_38023_error_level, (
+                             "CVE-2022-38023: "
+                             "Please use 'server schannel require seal:%s = no' "
+                             "for '%s' to avoid this warning!\n",
+                             log_escape(frame, creds->account_name),
+                             log_escape(frame, creds->computer_name)));
+               }
+
+               TALLOC_FREE(frame);
+               return s->result;
+       }
+
+       if (s->seal_required) {
+               s->result = NT_STATUS_ACCESS_DENIED;
+
+               if (s->seal_explicitly_set) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+               } else {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+               }
+               if (!s->schannel_explicitly_set) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+               } else if (s->schannel_required) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "from client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(s->result)));
+               if (s->seal_explicitly_set) {
+                       D_NOTICE("CVE-2022-38023: Option "
+                                "'server schannel require seal:%s = yes' "
+                                "rejects access for client.\n",
+                                log_escape(frame, creds->account_name));
+               } else {
+                       DEBUG(CVE_2022_38023_error_level, (
+                             "CVE-2022-38023: Check if option "
+                             "'server schannel require seal:%s = no' "
+                             "might be needed for a legacy client.\n",
+                             log_escape(frame, creds->account_name)));
+               }
+               if (!s->schannel_explicitly_set) {
+                       DEBUG(CVE_2020_1472_error_level, (
+                             "CVE-2020-1472(ZeroLogon): Check if option "
+                             "'server require schannel:%s = no' "
+                             "might be needed for a legacy client.\n",
+                             log_escape(frame, creds->account_name)));
+               } else if (s->schannel_required) {
+                       D_NOTICE("CVE-2022-38023: Option "
+                                "'server require schannel:%s = yes' "
+                                "also rejects access for client.\n",
+                                log_escape(frame, creds->account_name));
+               }
+               TALLOC_FREE(frame);
+               return s->result;
+       }
+
+       if (s->schannel_required) {
+               s->result = NT_STATUS_ACCESS_DENIED;
+
+               if (s->schannel_explicitly_set) {
+                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+               } else {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+               }
+               if (!s->seal_explicitly_set) {
+                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+               }
+
+               DEBUG(dbg_lvl, (
+                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+                     "%s request (opnum[%u]) %s schannel from "
+                     "client_account[%s] client_computer_name[%s] %s\n",
+                     opname, opnum, reason,
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name),
+                     nt_errstr(s->result)));
+               if (s->schannel_explicitly_set) {
+                       D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
+                               "'server require schannel:%s = yes' "
+                               "rejects access for client.\n",
+                               log_escape(frame, creds->account_name));
+               } else {
+                       DEBUG(CVE_2020_1472_error_level, (
+                             "CVE-2020-1472(ZeroLogon): Check if option "
+                             "'server require schannel:%s = no' "
+                             "might be needed for a legacy client.\n",
+                             log_escape(frame, creds->account_name)));
+               }
+               if (!s->seal_explicitly_set) {
+                       DEBUG(CVE_2022_38023_error_level, (
+                             "CVE-2022-38023: Check if option "
+                             "'server schannel require seal:%s = no' "
+                             "might be needed for a legacy client.\n",
+                             log_escape(frame, creds->account_name)));
+               }
+               TALLOC_FREE(frame);
+               return s->result;
+       }
+
+       s->result = NT_STATUS_OK;
+
+       if (s->seal_explicitly_set) {
+               dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+       } else {
+               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+       }
+
+       if (s->schannel_explicitly_set) {
+               dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+       } else {
+               dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+       }
+
+       DEBUG(dbg_lvl, (
+             "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+             "%s request (opnum[%u]) %s schannel from "
+             "client_account[%s] client_computer_name[%s] %s\n",
+             opname, opnum, reason,
+             log_escape(frame, creds->account_name),
+             log_escape(frame, creds->computer_name),
+             nt_errstr(s->result)));
+
+       if (s->seal_explicitly_set) {
+               D_INFO("CVE-2022-38023: Option "
+                      "'server schannel require seal:%s = no' "
+                      "still needed for '%s'!\n",
+                      log_escape(frame, creds->account_name),
+                      log_escape(frame, creds->computer_name));
+       } else {
+               /*
+                * admins should set
+                * server schannel require seal:COMPUTER$ = no
+                * in order to avoid the level 0 messages.
+                * Over time they can switch the global value
+                * to be strict.
+                */
+               DEBUG(CVE_2022_38023_error_level, (
+                     "CVE-2022-38023: Please use "
+                      "'server schannel require seal:%s = no' "
+                     "for '%s' to avoid this warning!\n",
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name)));
+       }
+
+       if (s->schannel_explicitly_set) {
+               D_INFO("CVE-2020-1472(ZeroLogon): Option "
+                      "'server require schannel:%s = no' "
+                      "still needed for '%s'!\n",
+                      log_escape(frame, creds->account_name),
+                      log_escape(frame, creds->computer_name));
+       } else {
+               /*
+                * admins should set
+                * server require schannel:COMPUTER$ = no
+                * in order to avoid the level 0 messages.
+                * Over time they can switch the global value
+                * to be strict.
+                */
+               DEBUG(CVE_2020_1472_error_level, (
+                     "CVE-2020-1472(ZeroLogon): "
+                     "Please use 'server require schannel:%s = no' "
+                     "for '%s' to avoid this warning!\n",
+                     log_escape(frame, creds->account_name),
+                     log_escape(frame, creds->computer_name)));
+       }
+
+       TALLOC_FREE(frame);
+       return s->result;
+}
+
+NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
+                                   const struct netlogon_creds_CredentialState *creds,
+                                   enum dcerpc_AuthType auth_type,
+                                   enum dcerpc_AuthLevel auth_level,
+                                   uint16_t opnum)
+{
+       struct dcesrv_netr_check_schannel_state *s = NULL;
+       NTSTATUS status;
+
+       status = dcesrv_netr_check_schannel_get_state(dce_call,
+                                                     creds,
+                                                     auth_type,
+                                                     auth_level,
+                                                     &s);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = dcesrv_netr_check_schannel_once(dce_call, s, creds, opnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
+/*
+ * NOTE: The following functions are nearly identical to the ones available in
+ * source3/rpc_server/srv_nelog_nt.c
+ * The reason we keep 2 copies is that they use different structures to
+ * represent the auth_info and the decrpc pipes.
+ */
+NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
+                                                   TALLOC_CTX *mem_ctx,
+                                                   const char *computer_name,
+                                                   struct netr_Authenticator *received_authenticator,
+                                                   struct netr_Authenticator *return_authenticator,
+                                                   struct netlogon_creds_CredentialState **creds_out)
+{
+       NTSTATUS nt_status;
+       struct netlogon_creds_CredentialState *creds = NULL;
+       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+       enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+
+       dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+
+       nt_status = schannel_check_creds_state(mem_ctx,
+                                              dce_call->conn->dce_ctx->lp_ctx,
+                                              computer_name,
+                                              received_authenticator,
+                                              return_authenticator,
+                                              &creds);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               ZERO_STRUCTP(return_authenticator);
+               return nt_status;
+       }
+
+       nt_status = dcesrv_netr_check_schannel(dce_call,
+                                              creds,
+                                              auth_type,
+                                              auth_level,
+                                              dce_call->pkt.u.request.opnum);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(creds);
+               ZERO_STRUCTP(return_authenticator);
+               return nt_status;
+       }
+
+       *creds_out = creds;
+       return NT_STATUS_OK;
+}
diff --git a/librpc/rpc/server/netlogon/schannel_util.h b/librpc/rpc/server/netlogon/schannel_util.h
new file mode 100644 (file)
index 0000000..561e256
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   netlogon schannel utility functions
+
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
+   Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
+   Copyright (C) Matthias Dieter Wallnöfer            2009-2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__
+#define __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__
+
+#include "replace.h"
+#include <talloc.h>
+#include "libcli/util/ntstatus.h"
+
+#define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358
+
+struct dcesrv_call_state;
+struct netlogon_creds_CredentialState;
+struct netr_Authenticator;
+enum dcerpc_AuthType;
+enum dcerpc_AuthLevel;
+
+NTSTATUS dcesrv_netr_check_schannel(
+               struct dcesrv_call_state *dce_call,
+               const struct netlogon_creds_CredentialState *creds,
+               enum dcerpc_AuthType auth_type,
+               enum dcerpc_AuthLevel auth_level,
+               uint16_t opnum);
+
+NTSTATUS dcesrv_netr_creds_server_step_check(
+               struct dcesrv_call_state *dce_call,
+               TALLOC_CTX *mem_ctx,
+               const char *computer_name,
+               struct netr_Authenticator *received_authenticator,
+               struct netr_Authenticator *return_authenticator,
+               struct netlogon_creds_CredentialState **creds_out);
+
+#endif /* __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__ */
index b82209b429939d19cd8636e3b42ad9c464a13ef7..f22ab2eabae8f43a56a0e81e265f936ac5e1fed1 100644 (file)
@@ -678,6 +678,18 @@ bld.SAMBA_LIBRARY('dcerpc-pkt-auth',
                    ''',
                   deps='dcerpc-binding gensec')
 
+bld.SAMBA_SUBSYSTEM('DCERPC_SERVER_NETLOGON',
+                    source='''
+                           rpc/server/netlogon/schannel_util.c
+                           ''',
+                    deps='''
+                         talloc
+                         util_str_escape
+                         samba-hostconfig
+                         NDR_NETLOGON
+                         dcerpc-server-core
+                         ''')
+
 bld.SAMBA_LIBRARY('dcerpc-server-core',
     source='''
            rpc/dcesrv_core.c
index 2d4e6a2d4c705b59d9dac497f0ddb97a4a2016f6..37f6d94420da8fc28594aefb4e9262f5912ae5e6 100644 (file)
@@ -42,6 +42,7 @@
 #include "librpc/gen_ndr/ndr_irpc.h"
 #include "librpc/gen_ndr/ndr_winbind.h"
 #include "librpc/gen_ndr/ndr_winbind_c.h"
+#include "librpc/rpc/server/netlogon/schannel_util.h"
 #include "lib/socket/netif.h"
 #include "lib/util/util_str_escape.h"
 
@@ -855,551 +856,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
        return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
 }
 
-struct dcesrv_netr_check_schannel_state {
-       struct dom_sid account_sid;
-       enum dcerpc_AuthType auth_type;
-       enum dcerpc_AuthLevel auth_level;
-
-       bool schannel_global_required;
-       bool schannel_required;
-       bool schannel_explicitly_set;
-
-       bool seal_global_required;
-       bool seal_required;
-       bool seal_explicitly_set;
-
-       NTSTATUS result;
-};
-
-static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *dce_call,
-                                                    const struct netlogon_creds_CredentialState *creds,
-                                                    enum dcerpc_AuthType auth_type,
-                                                    enum dcerpc_AuthLevel auth_level,
-                                                    struct dcesrv_netr_check_schannel_state **_s)
-{
-       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
-       int schannel = lpcfg_server_schannel(lp_ctx);
-       bool schannel_global_required = (schannel == true);
-       bool schannel_required = schannel_global_required;
-       const char *explicit_opt = NULL;
-       bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
-       bool require_seal = global_require_seal;
-       const char *explicit_seal_opt = NULL;
-#define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
-       struct dcesrv_netr_check_schannel_state *s = NULL;
-       NTSTATUS status;
-
-       *_s = NULL;
-
-       s = dcesrv_iface_state_find_conn(dce_call,
-                       DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
-                       struct dcesrv_netr_check_schannel_state);
-       if (s != NULL) {
-               if (!dom_sid_equal(&s->account_sid, creds->sid)) {
-                       goto new_state;
-               }
-               if (s->auth_type != auth_type) {
-                       goto new_state;
-               }
-               if (s->auth_level != auth_level) {
-                       goto new_state;
-               }
-
-               *_s = s;
-               return NT_STATUS_OK;
-       }
-
-new_state:
-       TALLOC_FREE(s);
-       s = talloc_zero(dce_call,
-                       struct dcesrv_netr_check_schannel_state);
-       if (s == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       s->account_sid = *creds->sid;
-       s->auth_type = auth_type;
-       s->auth_level = auth_level;
-       s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
-
-       /*
-        * We don't use lpcfg_parm_bool(), as we
-        * need the explicit_opt pointer in order to
-        * adjust the debug messages.
-        */
-       explicit_seal_opt = lpcfg_get_parametric(lp_ctx,
-                                                NULL,
-                                                "server schannel require seal",
-                                                creds->account_name);
-       if (explicit_seal_opt != NULL) {
-               require_seal = lp_bool(explicit_seal_opt);
-       }
-
-       /*
-        * We don't use lpcfg_parm_bool(), as we
-        * need the explicit_opt pointer in order to
-        * adjust the debug messages.
-        */
-       explicit_opt = lpcfg_get_parametric(lp_ctx,
-                                           NULL,
-                                           "server require schannel",
-                                           creds->account_name);
-       if (explicit_opt != NULL) {
-               schannel_required = lp_bool(explicit_opt);
-       }
-
-       s->schannel_global_required = schannel_global_required;
-       s->schannel_required = schannel_required;
-       s->schannel_explicitly_set = explicit_opt != NULL;
-
-       s->seal_global_required = global_require_seal;
-       s->seal_required = require_seal;
-       s->seal_explicitly_set = explicit_seal_opt != NULL;
-
-       status = dcesrv_iface_state_store_conn(dce_call,
-                       DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
-                       s);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       *_s = s;
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_call,
-                                               struct dcesrv_netr_check_schannel_state *s,
-                                               const struct netlogon_creds_CredentialState *creds,
-                                               uint16_t opnum)
-{
-       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
-       int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
-               "CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
-       int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
-               "CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
-       int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
-               "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
-       int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
-               "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
-       TALLOC_CTX *frame = talloc_stackframe();
-       unsigned int dbg_lvl = DBGLVL_DEBUG;
-       const char *opname = "<unknown>";
-       const char *reason = "<unknown>";
-
-       if (opnum < ndr_table_netlogon.num_calls) {
-               opname = ndr_table_netlogon.calls[opnum].name;
-       }
-
-       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-               if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
-                       reason = "WITH SEALED";
-               } else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
-                       reason = "WITH SIGNED";
-               } else {
-                       reason = "WITH INVALID";
-                       dbg_lvl = DBGLVL_ERR;
-                       s->result = NT_STATUS_INTERNAL_ERROR;
-               }
-       } else {
-               reason = "WITHOUT";
-       }
-
-       if (!NT_STATUS_EQUAL(s->result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               if (!NT_STATUS_IS_OK(s->result)) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-               }
-
-               DEBUG(dbg_lvl, (
-                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
-                     "%s request (opnum[%u]) %s schannel from "
-                     "client_account[%s] client_computer_name[%s] %s\n",
-                     opname, opnum, reason,
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name),
-                     nt_errstr(s->result)));
-               TALLOC_FREE(frame);
-               return s->result;
-       }
-
-       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
-           s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
-       {
-               s->result = NT_STATUS_OK;
-
-               if (s->schannel_explicitly_set && !s->schannel_required) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
-               } else if (!s->schannel_required) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-               }
-               if (s->seal_explicitly_set && !s->seal_required) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
-               } else if (!s->seal_required) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-               }
-
-               DEBUG(dbg_lvl, (
-                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
-                     "%s request (opnum[%u]) %s schannel from "
-                     "client_account[%s] client_computer_name[%s] %s\n",
-                     opname, opnum, reason,
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name),
-                     nt_errstr(s->result)));
-
-               if (s->schannel_explicitly_set && !s->schannel_required) {
-                       DEBUG(CVE_2020_1472_warn_level, (
-                             "CVE-2020-1472(ZeroLogon): "
-                             "Option 'server require schannel:%s = no' not needed for '%s'!\n",
-                             log_escape(frame, creds->account_name),
-                             log_escape(frame, creds->computer_name)));
-               }
-
-               if (s->seal_explicitly_set && !s->seal_required) {
-                       DEBUG(CVE_2022_38023_warn_level, (
-                             "CVE-2022-38023: "
-                             "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
-                             log_escape(frame, creds->account_name),
-                             log_escape(frame, creds->computer_name)));
-               }
-
-               TALLOC_FREE(frame);
-               return s->result;
-       }
-
-       if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-               if (s->seal_required) {
-                       s->result = NT_STATUS_ACCESS_DENIED;
-
-                       if (s->seal_explicitly_set) {
-                               dbg_lvl = DBGLVL_NOTICE;
-                       } else {
-                               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
-                       }
-                       if (s->schannel_explicitly_set && !s->schannel_required) {
-                               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
-                       }
-
-                       DEBUG(dbg_lvl, (
-                             "CVE-2022-38023: "
-                             "%s request (opnum[%u]) %s schannel from "
-                             "from client_account[%s] client_computer_name[%s] %s\n",
-                             opname, opnum, reason,
-                             log_escape(frame, creds->account_name),
-                             log_escape(frame, creds->computer_name),
-                             nt_errstr(s->result)));
-                       if (s->seal_explicitly_set) {
-                               D_NOTICE("CVE-2022-38023: Option "
-                                        "'server schannel require seal:%s = yes' "
-                                        "rejects access for client.\n",
-                                        log_escape(frame, creds->account_name));
-                       } else {
-                               DEBUG(CVE_2020_1472_error_level, (
-                                     "CVE-2022-38023: Check if option "
-                                     "'server schannel require seal:%s = no' "
-                                     "might be needed for a legacy client.\n",
-                                     log_escape(frame, creds->account_name)));
-                       }
-                       if (s->schannel_explicitly_set && !s->schannel_required) {
-                               DEBUG(CVE_2020_1472_warn_level, (
-                                     "CVE-2020-1472(ZeroLogon): Option "
-                                     "'server require schannel:%s = no' "
-                                     "not needed for '%s'!\n",
-                                     log_escape(frame, creds->account_name),
-                                     log_escape(frame, creds->computer_name)));
-                       }
-                       TALLOC_FREE(frame);
-                       return s->result;
-               }
-
-               s->result = NT_STATUS_OK;
-
-               if (s->schannel_explicitly_set && !s->schannel_required) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
-               } else if (!s->schannel_required) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-               }
-               if (s->seal_explicitly_set && !s->seal_required) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-               } else if (!s->seal_required) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
-               }
-
-               DEBUG(dbg_lvl, (
-                     "CVE-2020-1472(ZeroLogon): "
-                     "%s request (opnum[%u]) %s schannel from "
-                     "client_account[%s] client_computer_name[%s] %s\n",
-                     opname, opnum, reason,
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name),
-                     nt_errstr(s->result)));
-               if (s->schannel_explicitly_set && !s->schannel_required) {
-                       DEBUG(CVE_2020_1472_warn_level, (
-                             "CVE-2020-1472(ZeroLogon): "
-                             "Option 'server require schannel:%s = no' not needed for '%s'!\n",
-                             log_escape(frame, creds->account_name),
-                             log_escape(frame, creds->computer_name)));
-               }
-               if (s->seal_explicitly_set && !s->seal_required) {
-                       D_INFO("CVE-2022-38023: "
-                              "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
-                              log_escape(frame, creds->account_name),
-                              log_escape(frame, creds->computer_name));
-               } else if (!s->seal_required) {
-                       /*
-                        * admins should set
-                        * server schannel require seal:COMPUTER$ = no
-                        * in order to avoid the level 0 messages.
-                        * Over time they can switch the global value
-                        * to be strict.
-                        */
-                       DEBUG(CVE_2022_38023_error_level, (
-                             "CVE-2022-38023: "
-                             "Please use 'server schannel require seal:%s = no' "
-                             "for '%s' to avoid this warning!\n",
-                             log_escape(frame, creds->account_name),
-                             log_escape(frame, creds->computer_name)));
-               }
-
-               TALLOC_FREE(frame);
-               return s->result;
-       }
-
-       if (s->seal_required) {
-               s->result = NT_STATUS_ACCESS_DENIED;
-
-               if (s->seal_explicitly_set) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
-               } else {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
-               }
-               if (!s->schannel_explicitly_set) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
-               } else if (s->schannel_required) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
-               }
-
-               DEBUG(dbg_lvl, (
-                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
-                     "%s request (opnum[%u]) %s schannel from "
-                     "from client_account[%s] client_computer_name[%s] %s\n",
-                     opname, opnum, reason,
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name),
-                     nt_errstr(s->result)));
-               if (s->seal_explicitly_set) {
-                       D_NOTICE("CVE-2022-38023: Option "
-                                "'server schannel require seal:%s = yes' "
-                                "rejects access for client.\n",
-                                log_escape(frame, creds->account_name));
-               } else {
-                       DEBUG(CVE_2022_38023_error_level, (
-                             "CVE-2022-38023: Check if option "
-                             "'server schannel require seal:%s = no' "
-                             "might be needed for a legacy client.\n",
-                             log_escape(frame, creds->account_name)));
-               }
-               if (!s->schannel_explicitly_set) {
-                       DEBUG(CVE_2020_1472_error_level, (
-                             "CVE-2020-1472(ZeroLogon): Check if option "
-                             "'server require schannel:%s = no' "
-                             "might be needed for a legacy client.\n",
-                             log_escape(frame, creds->account_name)));
-               } else if (s->schannel_required) {
-                       D_NOTICE("CVE-2022-38023: Option "
-                                "'server require schannel:%s = yes' "
-                                "also rejects access for client.\n",
-                                log_escape(frame, creds->account_name));
-               }
-               TALLOC_FREE(frame);
-               return s->result;
-       }
-
-       if (s->schannel_required) {
-               s->result = NT_STATUS_ACCESS_DENIED;
-
-               if (s->schannel_explicitly_set) {
-                       dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
-               } else {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
-               }
-               if (!s->seal_explicitly_set) {
-                       dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
-               }
-
-               DEBUG(dbg_lvl, (
-                     "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
-                     "%s request (opnum[%u]) %s schannel from "
-                     "client_account[%s] client_computer_name[%s] %s\n",
-                     opname, opnum, reason,
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name),
-                     nt_errstr(s->result)));
-               if (s->schannel_explicitly_set) {
-                       D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
-                               "'server require schannel:%s = yes' "
-                               "rejects access for client.\n",
-                               log_escape(frame, creds->account_name));
-               } else {
-                       DEBUG(CVE_2020_1472_error_level, (
-                             "CVE-2020-1472(ZeroLogon): Check if option "
-                             "'server require schannel:%s = no' "
-                             "might be needed for a legacy client.\n",
-                             log_escape(frame, creds->account_name)));
-               }
-               if (!s->seal_explicitly_set) {
-                       DEBUG(CVE_2022_38023_error_level, (
-                             "CVE-2022-38023: Check if option "
-                             "'server schannel require seal:%s = no' "
-                             "might be needed for a legacy client.\n",
-                             log_escape(frame, creds->account_name)));
-               }
-               TALLOC_FREE(frame);
-               return s->result;
-       }
-
-       s->result = NT_STATUS_OK;
-
-       if (s->seal_explicitly_set) {
-               dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-       } else {
-               dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
-       }
-
-       if (s->schannel_explicitly_set) {
-               dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
-       } else {
-               dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
-       }
-
-       DEBUG(dbg_lvl, (
-             "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
-             "%s request (opnum[%u]) %s schannel from "
-             "client_account[%s] client_computer_name[%s] %s\n",
-             opname, opnum, reason,
-             log_escape(frame, creds->account_name),
-             log_escape(frame, creds->computer_name),
-             nt_errstr(s->result)));
-
-       if (s->seal_explicitly_set) {
-               D_INFO("CVE-2022-38023: Option "
-                      "'server schannel require seal:%s = no' "
-                      "still needed for '%s'!\n",
-                      log_escape(frame, creds->account_name),
-                      log_escape(frame, creds->computer_name));
-       } else {
-               /*
-                * admins should set
-                * server schannel require seal:COMPUTER$ = no
-                * in order to avoid the level 0 messages.
-                * Over time they can switch the global value
-                * to be strict.
-                */
-               DEBUG(CVE_2022_38023_error_level, (
-                     "CVE-2022-38023: Please use "
-                      "'server schannel require seal:%s = no' "
-                     "for '%s' to avoid this warning!\n",
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name)));
-       }
-
-       if (s->schannel_explicitly_set) {
-               D_INFO("CVE-2020-1472(ZeroLogon): Option "
-                      "'server require schannel:%s = no' "
-                      "still needed for '%s'!\n",
-                      log_escape(frame, creds->account_name),
-                      log_escape(frame, creds->computer_name));
-       } else {
-               /*
-                * admins should set
-                * server require schannel:COMPUTER$ = no
-                * in order to avoid the level 0 messages.
-                * Over time they can switch the global value
-                * to be strict.
-                */
-               DEBUG(CVE_2020_1472_error_level, (
-                     "CVE-2020-1472(ZeroLogon): "
-                     "Please use 'server require schannel:%s = no' "
-                     "for '%s' to avoid this warning!\n",
-                     log_escape(frame, creds->account_name),
-                     log_escape(frame, creds->computer_name)));
-       }
-
-       TALLOC_FREE(frame);
-       return s->result;
-}
-
-static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
-                                          const struct netlogon_creds_CredentialState *creds,
-                                          enum dcerpc_AuthType auth_type,
-                                          enum dcerpc_AuthLevel auth_level,
-                                          uint16_t opnum)
-{
-       struct dcesrv_netr_check_schannel_state *s = NULL;
-       NTSTATUS status;
-
-       status = dcesrv_netr_check_schannel_get_state(dce_call,
-                                                     creds,
-                                                     auth_type,
-                                                     auth_level,
-                                                     &s);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = dcesrv_netr_check_schannel_once(dce_call, s, creds, opnum);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/*
- * NOTE: The following functions are nearly identical to the ones available in
- * source3/rpc_server/srv_nelog_nt.c
- * The reason we keep 2 copies is that they use different structures to
- * represent the auth_info and the decrpc pipes.
- */
-static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
-                                                   TALLOC_CTX *mem_ctx,
-                                                   const char *computer_name,
-                                                   struct netr_Authenticator *received_authenticator,
-                                                   struct netr_Authenticator *return_authenticator,
-                                                   struct netlogon_creds_CredentialState **creds_out)
-{
-       NTSTATUS nt_status;
-       struct netlogon_creds_CredentialState *creds = NULL;
-       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
-       enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
-
-       dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
-
-       nt_status = schannel_check_creds_state(mem_ctx,
-                                              dce_call->conn->dce_ctx->lp_ctx,
-                                              computer_name,
-                                              received_authenticator,
-                                              return_authenticator,
-                                              &creds);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               ZERO_STRUCTP(return_authenticator);
-               return nt_status;
-       }
-
-       nt_status = dcesrv_netr_check_schannel(dce_call,
-                                              creds,
-                                              auth_type,
-                                              auth_level,
-                                              dce_call->pkt.u.request.opnum);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               TALLOC_FREE(creds);
-               ZERO_STRUCTP(return_authenticator);
-               return nt_status;
-       }
-
-       *creds_out = creds;
-       return NT_STATUS_OK;
-}
-
 /*
   Change the machine account password for the currently connected
   client.  Supplies only the NT#.
index e7bb773d719131eab50c5bd2c27c86c7af5f4141..0e44a3c2baed8e78faeaabf35302ae9eb3e2fb30 100644 (file)
@@ -118,10 +118,10 @@ bld.SAMBA_MODULE('dcerpc_netlogon',
                       samba-hostconfig
                       DSDB_MODULE_HELPERS
                       util_str_escape
+                      DCERPC_SERVER_NETLOGON
                       '''
                  )
 
-
 bld.SAMBA_MODULE('dcerpc_lsarpc',
                  source='lsa/dcesrv_lsa.c lsa/lsa_init.c lsa/lsa_lookup.c',
                  autoproto='lsa/proto.h',