s3: pass DCE RPC handle type to create_policy_hnd
authorAlexander Bokovoy <ab@samba.org>
Tue, 28 Apr 2020 18:59:46 +0000 (21:59 +0300)
committerJeremy Allison <jra@samba.org>
Tue, 28 Apr 2020 22:55:29 +0000 (22:55 +0000)
Various RPC services expect policy handles of a specific type.

s3 RPC server did not allow to create policy handles with a specific
type while actually requiring that policy handle type itself in some
places.

Make sure we are able to specify the policy on-wire handle type when
creating the policy handle. The changes follow s4 DCE RPC server
implementation.

The original logic to always set on-wire handle type to 0 can be tracked
down to commit fdeea341ed1bae670382e45eb731db1b5838ad21 when we didn't
really know about differences in on-wire handle types.

All but LSA trusted domain RPC calls do not check the on-wire handle
type in s3 RPC server.

Fixes trusted domain operations when Samba RPC client attempts to call
s3 RPC server to perform lsa_lsaRSetForestTrustInformation in FreeIPA.
This fix is a pre-requisite for FreeIPA-FreeIPA forest trust.

Signed-off-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Apr 28 22:55:29 UTC 2020 on sn-devel-184

source3/rpc_server/epmapper/srv_epmapper.c
source3/rpc_server/eventlog/srv_eventlog_nt.c
source3/rpc_server/lsa/srv_lsa_nt.c
source3/rpc_server/mdssvc/srv_mdssvc_nt.c
source3/rpc_server/rpc_handles.c
source3/rpc_server/rpc_pipes.h
source3/rpc_server/samr/srv_samr_nt.c
source3/rpc_server/spoolss/srv_spoolss_nt.c
source3/rpc_server/svcctl/srv_svcctl_nt.c
source3/rpc_server/winreg/srv_winreg_nt.c

index 58af887e7f4a9651527f39fd966d32519a93f39f..a95803c62a2bfb5eaa48c6f645948ba6b7b3c9bc 100644 (file)
@@ -31,6 +31,9 @@
 #include "librpc/gen_ndr/ndr_epmapper_scompat.h"
 #include "rpc_server/rpc_server.h"
 
+/* handle types for this module */
+enum handle_types {HTYPE_LOOKUP};
+
 typedef uint32_t error_status_t;
 
 /* An endpoint combined with an interface description */
@@ -704,7 +707,7 @@ error_status_t _epm_Lookup(struct pipes_struct *p,
                        goto done;
                }
 
-               ok = create_policy_hnd(p, r->out.entry_handle, eps);
+               ok = create_policy_hnd(p, r->out.entry_handle, HTYPE_LOOKUP, eps);
                if (!ok) {
                        rc = EPMAPPER_STATUS_NO_MEMORY;
                        goto done;
@@ -1096,7 +1099,7 @@ error_status_t _epm_Map(struct pipes_struct *p,
                }
                /* end of "some algorithm" */
 
-               ok = create_policy_hnd(p, r->out.entry_handle, eps);
+               ok = create_policy_hnd(p, r->out.entry_handle, HTYPE_LOOKUP, eps);
                if (!ok) {
                        rc = EPMAPPER_STATUS_NO_MEMORY;
                        goto done;
index db8b42d5e468194993abce503c0c737769276f82..a444967586bd66d01ec54c02b690136588d2031b 100644 (file)
@@ -274,7 +274,7 @@ static NTSTATUS elog_open( struct pipes_struct * p, const char *logname, struct
 
        /* create the policy handle */
 
-       if ( !create_policy_hnd( p, hnd, elog ) ) {
+       if ( !create_policy_hnd( p, hnd, 0, elog ) ) {
                TALLOC_FREE(elog);
                return NT_STATUS_NO_MEMORY;
        }
index 8ce7f05365bf840492461117c6f90854697d6951..8892299ca772ddf60483f973ae614a04cc2fe94d 100644 (file)
@@ -372,7 +372,7 @@ static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
                }
        }
 
-       if (!create_policy_hnd(p, handle, info)) {
+       if (!create_policy_hnd(p, handle, type, info)) {
                talloc_free(info);
                ZERO_STRUCTP(handle);
                return NT_STATUS_NO_MEMORY;
index c09d430a6104e411b116d66ce32d4e611cd5f6a5..2b0357e7145a958f501fcb6ec44745c58d8d92b5 100644 (file)
@@ -104,7 +104,7 @@ static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (!create_policy_hnd(p, handle, mds_ctx)) {
+       if (!create_policy_hnd(p, handle, 0, mds_ctx)) {
                talloc_free(mds_ctx);
                ZERO_STRUCTP(handle);
                return NT_STATUS_NO_MEMORY;
index e6e69045b28b70b62ddc74b7c5a0491c8780c591..d215a6a6d8812a8c7c10e6918dc4f98623f8fa97 100644 (file)
@@ -249,8 +249,11 @@ bool init_pipe_handles(struct pipes_struct *p, const struct ndr_syntax_id *synta
   data_ptr is TALLOC_FREE()'ed
 ****************************************************************************/
 
-static struct dcesrv_handle_old *create_rpc_handle_internal(struct pipes_struct *p,
-                               struct policy_handle *hnd, void *data_ptr)
+static struct dcesrv_handle_old *create_rpc_handle_internal(
+                               struct pipes_struct *p,
+                               struct policy_handle *hnd,
+                               uint8_t handle_type,
+                               void *data_ptr)
 {
        struct dcesrv_handle_old *rpc_hnd = NULL;
        static uint32_t pol_hnd_low  = 0;
@@ -278,8 +281,7 @@ static struct dcesrv_handle_old *create_rpc_handle_internal(struct pipes_struct
                pol_hnd_high++;
        }
 
-       /* first bit must be null */
-       SIVAL(&rpc_hnd->wire_handle.handle_type, 0 , 0);
+       SIVAL(&rpc_hnd->wire_handle.handle_type, 0 , handle_type);
 
        /* second bit is incrementing */
        SIVAL(&rpc_hnd->wire_handle.uuid.time_low, 0 , pol_hnd_low);
@@ -306,12 +308,14 @@ static struct dcesrv_handle_old *create_rpc_handle_internal(struct pipes_struct
        return rpc_hnd;
 }
 
-bool create_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd,
-                      void *data_ptr)
+bool create_policy_hnd(struct pipes_struct *p,
+                       struct policy_handle *hnd,
+                       uint8_t handle_type,
+                       void *data_ptr)
 {
        struct dcesrv_handle_old *rpc_hnd = NULL;
 
-       rpc_hnd = create_rpc_handle_internal(p, hnd, data_ptr);
+       rpc_hnd = create_rpc_handle_internal(p, hnd, handle_type, data_ptr);
        if (rpc_hnd == NULL) {
                return false;
        }
@@ -449,9 +453,13 @@ bool pipe_access_check(struct pipes_struct *p)
        return True;
 }
 
-void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
-                           uint32_t access_granted, size_t data_size,
-                           const char *type, NTSTATUS *pstatus)
+void *_policy_handle_create(struct pipes_struct *p,
+                       struct policy_handle *hnd,
+                       uint8_t handle_type,
+                       uint32_t access_granted,
+                       size_t data_size,
+                       const char *type,
+                       NTSTATUS *pstatus)
 {
        struct dcesrv_handle_old *rpc_hnd = NULL;
        void *data;
@@ -473,7 +481,7 @@ void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
        }
        talloc_set_name_const(data, type);
 
-       rpc_hnd = create_rpc_handle_internal(p, hnd, data);
+       rpc_hnd = create_rpc_handle_internal(p, hnd, handle_type, data);
        if (rpc_hnd == NULL) {
                TALLOC_FREE(data);
                *pstatus = NT_STATUS_NO_MEMORY;
index e9a0ca6589d890d80f1a4308ee3986e1a56060f3..5c4ded2c6c46010fa144db1bb7248bdb4f317517 100644 (file)
@@ -121,18 +121,25 @@ int close_internal_rpc_pipe_hnd(struct pipes_struct *p);
 
 size_t num_pipe_handles(struct pipes_struct *p);
 bool init_pipe_handles(struct pipes_struct *p, const struct ndr_syntax_id *syntax);
-bool create_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd, void *data_ptr);
+bool create_policy_hnd(struct pipes_struct *p,
+                       struct policy_handle *hnd,
+                       uint8_t handle_type,
+                       void *data_ptr);
 bool find_policy_by_hnd(struct pipes_struct *p, const struct policy_handle *hnd,
                        void **data_p);
 bool close_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd);
 void close_policy_by_pipe(struct pipes_struct *p);
 bool pipe_access_check(struct pipes_struct *p);
 
-void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
-                           uint32_t access_granted, size_t data_size,
-                           const char *type, NTSTATUS *pstatus);
-#define policy_handle_create(_p, _hnd, _access, _type, _pstatus) \
-       (_type *)_policy_handle_create((_p), (_hnd), (_access), sizeof(_type), #_type, \
+void *_policy_handle_create(struct pipes_struct *p,
+                       struct policy_handle *hnd,
+                       uint8_t handle_type,
+                       uint32_t access_granted,
+                       size_t data_size,
+                       const char *type,
+                       NTSTATUS *pstatus);
+#define policy_handle_create(_p, _hnd, _hnd_type, _access, _type, _pstatus) \
+       (_type *)_policy_handle_create((_p), (_hnd), (_hnd_type), (_access), sizeof(_type), #_type, \
                                       (_pstatus))
 
 void *_policy_handle_find(struct pipes_struct *p,
index 77cbf276ff0508cc1f9579fc5310b792a641f440..62796dbe5407634911d1fdc8651b1addb8952dda 100644 (file)
 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
 #define MAX_SAM_ENTRIES_W95 50
 
+enum samr_handle {
+       SAMR_HANDLE_CONNECT,
+       SAMR_HANDLE_DOMAIN,
+       SAMR_HANDLE_USER,
+       SAMR_HANDLE_GROUP,
+       SAMR_HANDLE_ALIAS
+};
+
 struct samr_connect_info {
        uint8_t dummy;
 };
@@ -499,8 +507,12 @@ NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
                return NT_STATUS_NO_SUCH_DOMAIN;
        }
 
-       dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
-                                    struct samr_domain_info, &status);
+       dinfo = policy_handle_create(p,
+                               r->out.domain_handle,
+                               SAMR_HANDLE_DOMAIN,
+                               acc_granted,
+                               struct samr_domain_info,
+                               &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -2222,8 +2234,12 @@ NTSTATUS _samr_OpenUser(struct pipes_struct *p,
        /* If we did the rid admins hack above, allow access. */
        acc_granted |= extra_access;
 
-       uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
-                                    struct samr_user_info, &nt_status);
+       uinfo = policy_handle_create(p,
+                               r->out.user_handle,
+                               SAMR_HANDLE_USER,
+                               acc_granted,
+                               struct samr_user_info,
+                               &nt_status);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -3791,8 +3807,12 @@ NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
                return nt_status;
        }
 
-       uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
-                                    struct samr_user_info, &nt_status);
+       uinfo = policy_handle_create(p,
+                               r->out.user_handle,
+                               SAMR_HANDLE_USER,
+                               acc_granted,
+                               struct samr_user_info,
+                               &nt_status);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -3860,9 +3880,12 @@ NTSTATUS _samr_Connect(struct pipes_struct *p,
 
        /* set up the SAMR connect_anon response */
 
-       (void)policy_handle_create(p, &hnd, acc_granted,
-                                   struct samr_connect_info,
-                                   &status);
+       (void)policy_handle_create(p,
+                               &hnd,
+                               SAMR_HANDLE_CONNECT,
+                               acc_granted,
+                               struct samr_connect_info,
+                               &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -3924,8 +3947,12 @@ NTSTATUS _samr_Connect2(struct pipes_struct *p,
        if ( !NT_STATUS_IS_OK(nt_status) )
                return nt_status;
 
-       (void)policy_handle_create(p, &hnd, acc_granted,
-                                   struct samr_connect_info, &nt_status);
+       (void)policy_handle_create(p,
+                               &hnd,
+                               SAMR_HANDLE_CONNECT,
+                               acc_granted,
+                               struct samr_connect_info,
+                               &nt_status);
         if (!NT_STATUS_IS_OK(nt_status)) {
                 return nt_status;
         }
@@ -4161,8 +4188,12 @@ NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
 
        }
 
-       ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
-                                    struct samr_alias_info, &status);
+       ainfo = policy_handle_create(p,
+                               r->out.alias_handle,
+                               SAMR_HANDLE_ALIAS,
+                               acc_granted,
+                               struct samr_alias_info,
+                               &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -5907,9 +5938,12 @@ NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
        if ( !NT_STATUS_IS_OK(status) )
                return status;
 
-       ginfo = policy_handle_create(p, r->out.group_handle,
-                                    GENERIC_RIGHTS_GROUP_ALL_ACCESS,
-                                    struct samr_group_info, &status);
+       ginfo = policy_handle_create(p,
+                               r->out.group_handle,
+                               SAMR_HANDLE_GROUP,
+                               GENERIC_RIGHTS_GROUP_ALL_ACCESS,
+                               struct samr_group_info,
+                               &status);
         if (!NT_STATUS_IS_OK(status)) {
                 return status;
         }
@@ -5981,9 +6015,12 @@ NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       ainfo = policy_handle_create(p, r->out.alias_handle,
-                                    GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
-                                    struct samr_alias_info, &result);
+       ainfo = policy_handle_create(p,
+                               r->out.alias_handle,
+                               SAMR_HANDLE_ALIAS,
+                               GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
+                               struct samr_alias_info,
+                               &result);
         if (!NT_STATUS_IS_OK(result)) {
                 return result;
         }
@@ -6387,9 +6424,12 @@ NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
 
        TALLOC_FREE(map);
 
-       ginfo = policy_handle_create(p, r->out.group_handle,
-                                    acc_granted,
-                                    struct samr_group_info, &status);
+       ginfo = policy_handle_create(p,
+                               r->out.group_handle,
+                               SAMR_HANDLE_GROUP,
+                               acc_granted,
+                               struct samr_group_info,
+                               &status);
         if (!NT_STATUS_IS_OK(status)) {
                 return status;
         }
index 3ba94ee7affd3410ee5dbffb15812f567bf5fce5..02c9f8d431873c798c786670892b0099d9c5d6ed 100644 (file)
@@ -719,7 +719,7 @@ static WERROR open_printer_hnd(struct pipes_struct *p,
        talloc_set_destructor(new_printer, printer_entry_destructor);
 
        /* This also steals the printer_handle on the policy_handle */
-       if (!create_policy_hnd(p, hnd, new_printer)) {
+       if (!create_policy_hnd(p, hnd, 0, new_printer)) {
                TALLOC_FREE(new_printer);
                return WERR_INVALID_HANDLE;
        }
index b2b0fec0fa218e416787925aa9b619eb845aa0c5..1431591916963cced52b4c3da335790bb6223b08 100644 (file)
@@ -262,7 +262,7 @@ static WERROR create_open_service_handle(struct pipes_struct *p,
 
        /* store the SERVICE_INFO and create an open handle */
 
-       if ( !create_policy_hnd( p, handle, info ) ) {
+       if ( !create_policy_hnd( p, handle, 0, info ) ) {
                result = WERR_ACCESS_DENIED;
                goto done;
        }
index 98af44114d7edf91812d3987ec1c252798cda809..c59413d92e60f074019528352a9f945667c30394 100644 (file)
@@ -35,6 +35,8 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
+enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
+
 /******************************************************************
  Find a registry key handle and return a struct registry_key *
  *****************************************************************/
@@ -82,7 +84,7 @@ static WERROR open_registry_key(struct pipes_struct *p,
                return result;
        }
 
-       if ( !create_policy_hnd( p, hnd, key ) ) {
+       if ( !create_policy_hnd( p, hnd, HTYPE_REGKEY, key ) ) {
                return WERR_FILE_NOT_FOUND;
        }
 
@@ -708,7 +710,7 @@ WERROR _winreg_CreateKey(struct pipes_struct *p,
                return result;
        }
 
-       if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
+       if (!create_policy_hnd(p, r->out.new_handle, HTYPE_REGKEY, new_key)) {
                TALLOC_FREE(new_key);
                return WERR_FILE_NOT_FOUND;
        }