CVE-2022-38023 s3:rpc_server/netlogon: make sure all _netr_LogonSamLogon*() calls...
authorSamuel Cabrero <scabrero@suse.de>
Thu, 22 Dec 2022 08:29:04 +0000 (09:29 +0100)
committerJule Anger <janger@samba.org>
Mon, 23 Jan 2023 10:01:59 +0000 (10:01 +0000)
Some checks are also required for _netr_LogonSamLogonEx().

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 ca07f4340ce58a7e940a1123888b7409176412f7)

source3/rpc_server/netlogon/srv_netlog_nt.c

index 8e0ea522b6d010961c5943e2f996f840d05e1e5c..ba2680668ede0efc221a0801b64883e912487955 100644 (file)
@@ -1632,6 +1632,11 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
        struct auth_serversupplied_info *server_info = NULL;
        struct auth_context *auth_context = NULL;
        const char *fn;
+       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+       enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+       uint16_t opnum = dce_call->pkt.u.request.opnum;
+
+       dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
 
 #ifdef DEBUG_PASSWORD
        logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
@@ -1642,15 +1647,37 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
        }
 #endif
 
-       switch (dce_call->pkt.u.request.opnum) {
+       switch (opnum) {
                case NDR_NETR_LOGONSAMLOGON:
                        fn = "_netr_LogonSamLogon";
+                       /*
+                        * Already called netr_check_schannel() via
+                        * netr_creds_server_step_check()
+                        */
                        break;
                case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
                        fn = "_netr_LogonSamLogonWithFlags";
+                       /*
+                        * Already called netr_check_schannel() via
+                        * netr_creds_server_step_check()
+                        */
                        break;
                case NDR_NETR_LOGONSAMLOGONEX:
                        fn = "_netr_LogonSamLogonEx";
+
+                       if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
+                               return NT_STATUS_ACCESS_DENIED;
+                       }
+
+                       status = dcesrv_netr_check_schannel(p->dce_call,
+                                                           creds,
+                                                           auth_type,
+                                                           auth_level,
+                                                           opnum);
+                       if (NT_STATUS_IS_ERR(status)) {
+                               return status;
+                       }
+
                        break;
                default:
                        return NT_STATUS_INTERNAL_ERROR;
@@ -1881,10 +1908,6 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
                                                r->out.validation->sam3);
                break;
        case 6: {
-               enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
-
-               dcesrv_call_auth_info(dce_call, NULL, &auth_level);
-
                /* Only allow this if the pipe is protected. */
                if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
                        DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
@@ -1997,8 +2020,6 @@ NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
 NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
                               struct netr_LogonSamLogonEx *r)
 {
-       struct dcesrv_call_state *dce_call = p->dce_call;
-       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
        NTSTATUS status;
        struct netlogon_creds_CredentialState *creds = NULL;
        struct loadparm_context *lp_ctx;
@@ -2010,16 +2031,6 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
                return status;
        }
 
-       /* Only allow this if the pipe is protected. */
-
-       dcesrv_call_auth_info(dce_call, &auth_type, NULL);
-
-       if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
-               DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
-                       get_remote_machine_name() ));
-               return NT_STATUS_INVALID_PARAMETER;
-        }
-
        lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
        if (lp_ctx == NULL) {
                DEBUG(0, ("loadparm_init_s3 failed\n"));