s3-iremotewinspool: check for correct object_uuid in dispatch fn.
[gd/samba-autobuild/.git] / source3 / rpc_server / spoolss / srv_iremotewinspool.c
index 014fa6cab9b98a75b26259e4a1065c44d7cf7a5c..5bc4228f83f629fe0e886df6f1d3c1761a919a3b 100644 (file)
@@ -12,6 +12,7 @@
 #include "librpc/gen_ndr/ndr_spoolss_scompat.h"
 #include "rpc_server/rpc_config.h"
 #include "rpc_server/rpc_server.h"
+#include "rpc_server/spoolss/iremotewinspool_util.h"
 
 static bool forward_opnum_to_spoolss(uint16_t opnum) {
        switch (opnum) {
@@ -33,11 +34,6 @@ static bool forward_opnum_to_spoolss(uint16_t opnum) {
 /* iremotewinspool - dcerpc server boilerplate generated by pidl */
 static NTSTATUS iremotewinspool__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
 {
-       struct pipes_struct *p = NULL;
-
-       /* Retrieve pipes struct */
-       p = dcesrv_get_pipes_struct(context->conn);
-       p->pipe_bound = true;
 #ifdef DCESRV_INTERFACE_IREMOTEWINSPOOL_BIND
        return DCESRV_INTERFACE_IREMOTEWINSPOOL_BIND(context,iface);
 #else
@@ -58,10 +54,16 @@ NTSTATUS iremotewinspool__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC
 {
        enum ndr_err_code ndr_err;
        uint16_t opnum = dce_call->pkt.u.request.opnum;
+       uint16_t mapped_opnum;
 
        dce_call->fault_code = 0;
 
        if (forward_opnum_to_spoolss(opnum)) {
+               bool ok;
+               ok = iremotewinspool_map_opcode(opnum, &mapped_opnum);
+               if (ok) {
+                       dce_call->pkt.u.request.opnum = mapped_opnum;
+               }
                return spoolss__op_ndr_pull(dce_call, mem_ctx, pull, r);
        }
 
@@ -87,9 +89,27 @@ static NTSTATUS iremotewinspool__op_dispatch_internal(struct dcesrv_call_state *
 {
        uint16_t opnum = dce_call->pkt.u.request.opnum;
        struct pipes_struct *p = NULL;
-       struct auth_session_info *pipe_session_info = NULL;
        NTSTATUS status = NT_STATUS_OK;
        bool impersonated = false;
+       bool ok;
+       struct GUID object_uuid;
+
+       ok = dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID;
+       if (!ok) {
+               dce_call->fault_code = DCERPC_NCA_S_UNSUPPORTED_TYPE;
+               return NT_STATUS_NET_WRITE_FAULT;
+       }
+
+       status = GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &object_uuid);
+       if (!NT_STATUS_IS_OK(status)) {
+               dce_call->fault_code = DCERPC_NCA_S_UNSUPPORTED_TYPE;
+               return NT_STATUS_NET_WRITE_FAULT;
+       }
+
+       if (!GUID_equal(&dce_call->pkt.u.request.object.object, &object_uuid)) {
+               dce_call->fault_code = DCERPC_NCA_S_UNSUPPORTED_TYPE;
+               return NT_STATUS_NET_WRITE_FAULT;
+       }
 
        if (forward_opnum_to_spoolss(opnum)) {
                return spoolss__op_dispatch(dce_call, mem_ctx, r);
@@ -99,18 +119,13 @@ static NTSTATUS iremotewinspool__op_dispatch_internal(struct dcesrv_call_state *
        p = dcesrv_get_pipes_struct(dce_call->conn);
        p->dce_call = dce_call;
        p->mem_ctx = mem_ctx;
-       /* Update pipes struct session info */
-       pipe_session_info = p->session_info;
-       p->session_info = dce_call->auth_state->session_info;
-       p->auth.auth_type = dce_call->auth_state->auth_type;
-       p->auth.auth_level = dce_call->auth_state->auth_level;
-       p->auth.auth_context_id = dce_call->auth_state->auth_context_id;
        /* Reset pipes struct fault state */
        p->fault_state = 0;
 
        /* Impersonate */
        if (!rpcint_call) {
-               impersonated = become_authenticated_pipe_user(p->session_info);
+               impersonated = become_authenticated_pipe_user(
+                       dce_call->auth_state->session_info);
                if (!impersonated) {
                        dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
                        status = NT_STATUS_NET_WRITE_FAULT;
@@ -1238,11 +1253,6 @@ fail:
 
        p->dce_call = NULL;
        p->mem_ctx = NULL;
-       /* Restore session info */
-       p->session_info = pipe_session_info;
-       p->auth.auth_type = 0;
-       p->auth.auth_level = 0;
-       p->auth.auth_context_id = 0;
        /* Check pipes struct fault state */
        if (p->fault_state != 0) {
                dce_call->fault_code = p->fault_state;
@@ -2295,25 +2305,10 @@ static const struct dcesrv_interface dcesrv_iremotewinspool_interface = {
 #endif
 };
 
-static NTSTATUS iremotewinspool__check_register_in_endpoint(const char *name, struct dcerpc_binding *binding) {
-       enum dcerpc_transport_t transport = dcerpc_binding_get_transport(binding);
-
-       /* If service is embedded, register only for ncacn_np
-        * see 8466b3c85e4b835e57e41776853093f4a0edc8b8
-        */
-       if (rpc_service_mode(name) == RPC_SERVICE_MODE_EMBEDDED && (transport != NCACN_NP && transport != NCALRPC)) {
-               DBG_INFO("Interface 'iremotewinspool' not registered in endpoint '%s' as service is embedded\n", name);
-               return NT_STATUS_NOT_SUPPORTED;
-       }
-
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS iremotewinspool__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
 {
        int i;
        NTSTATUS ret;
-       struct dcerpc_binding *binding;
 
 #ifdef DCESRV_INTERFACE_IREMOTEWINSPOOL_NCACN_NP_SECONDARY_ENDPOINT
        const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_IREMOTEWINSPOOL_NCACN_NP_SECONDARY_ENDPOINT;
@@ -2324,19 +2319,6 @@ static NTSTATUS iremotewinspool__op_init_server(struct dcesrv_context *dce_ctx,
        for (i=0;i<ndr_table_iremotewinspool.endpoints->count;i++) {
                const char *name = ndr_table_iremotewinspool.endpoints->names[i];
 
-               ret = dcerpc_parse_binding(dce_ctx, name, &binding);
-               if (NT_STATUS_IS_ERR(ret)) {
-                       DBG_ERR("Failed to parse binding string '%s'\n", name);
-                       return ret;
-               }
-
-               ret = iremotewinspool__check_register_in_endpoint("iremotewinspool", binding);
-               if (NT_STATUS_IS_ERR(ret)) {
-                       talloc_free(binding);
-                       continue;
-               }
-               talloc_free(binding);
-
                ret = dcesrv_interface_register(dce_ctx, name, ncacn_np_secondary_endpoint, &dcesrv_iremotewinspool_interface, NULL);
                if (!NT_STATUS_IS_OK(ret)) {
                        DBG_ERR("Failed to register endpoint '%s'\n",name);