]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
dcesrv_core: better fault codes dcesrv_auth_prepare_auth3()
authorStefan Metzmacher <metze@samba.org>
Fri, 13 Nov 2020 01:47:51 +0000 (02:47 +0100)
committerJule Anger <janger@samba.org>
Thu, 7 Nov 2024 08:18:17 +0000 (08:18 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Thu Oct 10 15:17:46 UTC 2024 on atb-devel-224

(cherry picked from commit 9263ce5752063235836d5f77220b0151df6c9408)

librpc/rpc/dcesrv_auth.c
librpc/rpc/dcesrv_core.c
selftest/knownfail.d/dcerpc-auth-pad [deleted file]

index c5dbec973d12ab976b9b524eb3a85f8f7358e025..b2f6e607a24d0ac06ed7e5d5450ded9f7d1596f6 100644 (file)
@@ -445,11 +445,38 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
        struct dcesrv_auth *auth = call->auth_state;
        NTSTATUS status;
 
-       if (pkt->auth_length == 0) {
+       if (pkt->frag_length > call->conn->transport_max_recv_frag) {
+               /*
+                * Note that we don't check against the negotiated
+                * max_recv_frag, but a hard coded value from
+                * the transport.
+                */
+               call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               return false;
+       }
+
+       if (pkt->auth_length > 4096) {
+               call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
                return false;
        }
 
        if (auth->auth_finished) {
+               call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               return false;
+       }
+
+       if (!auth->auth_started) {
+               call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               return false;
+       }
+
+       if (auth->auth_invalid) {
+               call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               return false;
+       }
+
+       if (pkt->auth_length == 0) {
+               call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
                return false;
        }
 
@@ -465,23 +492,36 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
        status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info,
                                          &call->in_auth_info, NULL, true);
        if (!NT_STATUS_IS_OK(status)) {
+               struct dcerpc_auth *auth_info = &call->in_auth_info;
+               uint32_t nr = auth_info->auth_context_id;
+
                /*
                 * Windows returns DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY
-                * instead of DCERPC_NCA_S_PROTO_ERROR.
+                * instead of DCERPC_NCA_S_PROTO_ERROR in most cases.
                 */
                call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
+
+               if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR) &&
+                   nr != DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED)
+               {
+                       call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               }
+
                return false;
        }
 
        if (call->in_auth_info.auth_type != auth->auth_type) {
+               call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
                return false;
        }
 
        if (call->in_auth_info.auth_level != auth->auth_level) {
+               call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
                return false;
        }
 
        if (call->in_auth_info.auth_context_id != auth->auth_context_id) {
+               call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
                return false;
        }
 
index ebe6e662202ec90f8a13d9b5bab5cd5e2febba9c..66478001640d039bfbf856c4148139d8f8a68efb 100644 (file)
@@ -1419,14 +1419,6 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
        struct tevent_req *subreq = NULL;
        NTSTATUS status;
 
-       if (!auth->auth_started) {
-               return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
-       }
-
-       if (auth->auth_finished) {
-               return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
-       }
-
        status = dcerpc_verify_ncacn_packet_header(&call->pkt,
                        DCERPC_PKT_AUTH3,
                        call->pkt.u.auth3.auth_info.length,
diff --git a/selftest/knownfail.d/dcerpc-auth-pad b/selftest/knownfail.d/dcerpc-auth-pad
deleted file mode 100644 (file)
index 4c77d62..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_pad_auth3_align2_ntlm
-^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_pad_auth3_align2_spnego
-^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_spnego_auth3