s3:mdssvc: failing the RPC request if the mdssvc policy handle is not found
authorRalph Boehme <slow@samba.org>
Mon, 6 May 2019 12:14:26 +0000 (14:14 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 8 Aug 2019 20:24:33 +0000 (20:24 +0000)
Turns out macOS mdssvc doesn't fail the RPC request if the policy handle is all
zero. Also, if it fails with a non-all-zero handle, it returns a different RPC
error, namely DCERPC_NCA_S_PROTO_ERROR, not DCERPC_FAULT_CONTEXT_MISMATCH (or
rather their mapped NT_STATUS codes).

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
selftest/knownfail.d/samba3.rpc
source3/rpc_server/mdssvc/srv_mdssvc_nt.c

index 2b9179863c8a75f47fb63c77e677f562b382e06d..bafc9c3ece0b21c8adca6c2644fc0c017b308ba3 100644 (file)
@@ -1,6 +1,2 @@
 ^samba3.rpc.mdssvc.rpccmd.close\(fileserver\)
-^samba3.rpc.mdssvc.rpccmd.null_ph\(fileserver\)
-^samba3.rpc.mdssvc.disconnect1.invalid_ph_unknown1\(fileserver\)
-^samba3.rpc.mdssvc.disconnect2.invalid_ph_cmd\(fileserver\)
-^samba3.rpc.mdssvc.disconnect3.invalid_ph_close\(fileserver\)
 ^samba3.rpc.mdssvc.mdscmd.fetch_unknown_cnid\(fileserver\)
index a4df2f136b7a23cb31f224a4f5916c1bfc464024..9e869dd3427edd8e9e74b98abf9ff5c48831bbd3 100644 (file)
@@ -187,12 +187,32 @@ void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r)
        return;
 }
 
+static bool is_zero_policy_handle(const struct policy_handle *h)
+{
+       struct GUID zero_uuid = {0};
+
+       if (h->handle_type != 0) {
+               return false;
+       }
+       if (!GUID_equal(&h->uuid, &zero_uuid)) {
+               return false;
+       }
+       return true;
+}
+
 void _mdssvc_unknown1(struct pipes_struct *p, struct mdssvc_unknown1 *r)
 {
        struct mds_ctx *mds_ctx;
 
        if (!find_policy_by_hnd(p, &r->in.handle, (void **)(void *)&mds_ctx)) {
-               DEBUG(1, ("%s: invalid handle\n", __func__));
+               if (is_zero_policy_handle(&r->in.handle)) {
+                       p->fault_state = 0;
+               } else {
+                       p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
+               }
+               *r->out.status = 0;
+               *r->out.flags = 0;
+               *r->out.unkn7 = 0;
                return;
        }
 
@@ -212,7 +232,14 @@ void _mdssvc_cmd(struct pipes_struct *p, struct mdssvc_cmd *r)
        struct mds_ctx *mds_ctx;
 
        if (!find_policy_by_hnd(p, &r->in.handle, (void **)(void *)&mds_ctx)) {
-               DEBUG(1, ("%s: invalid handle\n", __func__));
+               if (is_zero_policy_handle(&r->in.handle)) {
+                       p->fault_state = 0;
+               } else {
+                       p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
+               }
+               r->out.response_blob->size = 0;
+               *r->out.fragment = 0;
+               *r->out.unkn9 = 0;
                return;
        }
 
@@ -280,6 +307,11 @@ void _mdssvc_close(struct pipes_struct *p, struct mdssvc_close *r)
 
        if (!find_policy_by_hnd(p, &r->in.in_handle, (void **)(void *)&mds_ctx)) {
                DEBUG(1, ("%s: invalid handle\n", __func__));
+               if (is_zero_policy_handle(&r->in.in_handle)) {
+                       p->fault_state = 0;
+               } else {
+                       p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
+               }
                return;
        }