s3:rpc_server: check verification trailer
authorGregor Beck <gbeck@sernet.de>
Fri, 10 Jan 2014 12:56:06 +0000 (13:56 +0100)
committerGünther Deschner <gd@samba.org>
Tue, 11 Feb 2014 15:02:14 +0000 (16:02 +0100)
Signed-off-by: Gregor Beck <gbeck@sernet.de>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
source3/rpc_server/srv_pipe.c

index f58eba49f8be80356f0ce8b685877537c949f7cd..36864d26045f189ce6dffb20b95fa2b1219adecf 100644 (file)
@@ -43,6 +43,7 @@
 #include "lib/param/param.h"
 #include "librpc/ndr/ndr_table.h"
 #include "auth/gensec/gensec.h"
+#include "librpc/ndr/ndr_dcerpc.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -1204,6 +1205,41 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
                       const struct api_struct *api_rpc_cmds, int n_cmds,
                       const struct ndr_syntax_id *syntax);
 
+static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
+                                               struct ncacn_packet *pkt,
+                                               struct pipe_rpc_fns *pipe_fns)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct dcerpc_sec_verification_trailer *vt = NULL;
+       const uint32_t bitmask1 =
+               p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
+       const struct dcerpc_sec_vt_pcontext pcontext = {
+               .abstract_syntax = pipe_fns->syntax,
+               .transfer_syntax = ndr_transfer_syntax_ndr,
+       };
+       const struct dcerpc_sec_vt_header2 header2 =
+              dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
+       struct ndr_pull *ndr;
+       enum ndr_err_code ndr_err;
+       bool ret = false;
+
+       ndr = ndr_pull_init_blob(&p->in_data.data, frame);
+       if (ndr == NULL) {
+               goto done;
+       }
+
+       ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               goto done;
+       }
+
+       ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
+                                                   &pcontext, &header2);
+done:
+       TALLOC_FREE(frame);
+       return ret;
+}
+
 /****************************************************************************
  Find the correct RPC function to call for this request.
  If the pipe is authenticated then become the correct UNIX user
@@ -1236,6 +1272,14 @@ static bool api_pipe_request(struct pipes_struct *p,
                return false;
        }
 
+       if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
+               DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
+               setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
+               data_blob_free(&p->out_data.rdata);
+               TALLOC_FREE(frame);
+               return true;
+       }
+
        if (!become_authenticated_pipe_user(p->session_info)) {
                DEBUG(1, ("Failed to become pipe user!\n"));
                data_blob_free(&p->out_data.rdata);