CVE-2015-5370: s4:rpc_server: fix the order of error checking in dcesrv_alter()
authorStefan Metzmacher <metze@samba.org>
Fri, 26 Jun 2015 06:10:46 +0000 (08:10 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:30 +0000 (19:25 +0200)
The basically matches Windows 2012R2, it's not 100%
but it's enough for our raw protocol tests to pass.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source4/rpc_server/dcerpc_server.c

index aaf1d478c10b6d10dfa483b339c349db73fbd098..26e52a28cb66b3066942ce9025b71acc2f4d6e47 100644 (file)
@@ -1106,6 +1106,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
 {
        NTSTATUS status;
        const struct dcerpc_ctx_list *ctx = NULL;
+       bool auth_ok = false;
 
        if (!call->conn->allow_alter) {
                return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
@@ -1127,12 +1128,12 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
                return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
        }
 
-       /* handle any authentication that is being requested */
-       if (!dcesrv_auth_alter(call)) {
-               /* TODO: work out the right reject code */
-               return dcesrv_alter_resp(call,
-                               DCERPC_BIND_PROVIDER_REJECT,
-                               DCERPC_BIND_REASON_ASYNTAX);
+       auth_ok = dcesrv_auth_alter(call);
+       if (!auth_ok) {
+               if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) {
+                       return dcesrv_fault_disconnect(call,
+                                       DCERPC_FAULT_ACCESS_DENIED);
+               }
        }
 
        if (call->pkt.u.alter.num_contexts < 1) {
@@ -1186,6 +1187,17 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
                                DCERPC_BIND_REASON_ASYNTAX);
        }
 
+       /* handle any authentication that is being requested */
+       if (!auth_ok) {
+               if (call->in_auth_info.auth_type !=
+                   call->conn->auth_state.auth_type)
+               {
+                       return dcesrv_fault_disconnect(call,
+                                       DCERPC_FAULT_SEC_PKG_ERROR);
+               }
+               return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
+       }
+
        return dcesrv_alter_resp(call,
                                DCERPC_BIND_ACK_RESULT_ACCEPTANCE,
                                DCERPC_BIND_ACK_REASON_NOT_SPECIFIED);