summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2020-04-28 21:59:46 +0300
committerKarolin Seeger <kseeger@samba.org>2020-05-04 11:35:51 +0000
commit24e21906a339488d84a740783eb1d47e15ffc195 (patch)
treecafc266f51f1a5c2237f7674ac393a5a8171bb75
parent08c012642f710c9005d2d89d5e5d3d89deb6d8e1 (diff)
downloadsamba-24e21906a339488d84a740783eb1d47e15ffc195.tar.gz
s3: pass DCE RPC handle type to create_policy_hnd
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 (cherry picked from commit c7a4578d06427a82ead287f0c5248c1a54cc9336) Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> Autobuild-Date(v4-11-test): Mon May 4 11:35:51 UTC 2020 on sn-devel-184
-rw-r--r--source3/rpc_server/epmapper/srv_epmapper.c7
-rw-r--r--source3/rpc_server/eventlog/srv_eventlog_nt.c2
-rw-r--r--source3/rpc_server/lsa/srv_lsa_nt.c2
-rw-r--r--source3/rpc_server/mdssvc/srv_mdssvc_nt.c2
-rw-r--r--source3/rpc_server/rpc_handles.c30
-rw-r--r--source3/rpc_server/rpc_pipes.h19
-rw-r--r--source3/rpc_server/samr/srv_samr_nt.c84
-rw-r--r--source3/rpc_server/spoolss/srv_spoolss_nt.c2
-rw-r--r--source3/rpc_server/svcctl/srv_svcctl_nt.c2
-rw-r--r--source3/rpc_server/winreg/srv_winreg_nt.c6
10 files changed, 108 insertions, 48 deletions
diff --git a/source3/rpc_server/epmapper/srv_epmapper.c b/source3/rpc_server/epmapper/srv_epmapper.c
index d0e2d546c47..6fab4652aa9 100644
--- a/source3/rpc_server/epmapper/srv_epmapper.c
+++ b/source3/rpc_server/epmapper/srv_epmapper.c
@@ -27,6 +27,9 @@
#include "srv_epmapper.h"
#include "auth.h"
+/* handle types for this module */
+enum handle_types {HTYPE_LOOKUP};
+
typedef uint32_t error_status_t;
/* An endpoint combined with an interface description */
@@ -681,7 +684,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;
@@ -1073,7 +1076,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;
diff --git a/source3/rpc_server/eventlog/srv_eventlog_nt.c b/source3/rpc_server/eventlog/srv_eventlog_nt.c
index 5093125a6f6..1435403351c 100644
--- a/source3/rpc_server/eventlog/srv_eventlog_nt.c
+++ b/source3/rpc_server/eventlog/srv_eventlog_nt.c
@@ -267,7 +267,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;
}
diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index 4adb3b2bf6c..614cc06261a 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -371,7 +371,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;
diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c
index c4bf995ce14..28a5a8c6860 100644
--- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c
+++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c
@@ -124,7 +124,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;
diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c
index cf5bc2770ea..99fc2490dd0 100644
--- a/source3/rpc_server/rpc_handles.c
+++ b/source3/rpc_server/rpc_handles.c
@@ -250,8 +250,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 *create_rpc_handle_internal(struct pipes_struct *p,
- struct policy_handle *hnd, void *data_ptr)
+static struct dcesrv_handle *create_rpc_handle_internal(
+ struct pipes_struct *p,
+ struct policy_handle *hnd,
+ uint8_t handle_type,
+ void *data_ptr)
{
struct dcesrv_handle *rpc_hnd;
static uint32_t pol_hnd_low = 0;
@@ -279,8 +282,7 @@ static struct dcesrv_handle *create_rpc_handle_internal(struct pipes_struct *p,
pol_hnd_high++;
}
- /* first bit must be null */
- SIVAL(&rpc_hnd->wire_handle.handle_type, 0 , 0);
+ rpc_hnd->wire_handle.handle_type = handle_type;
/* second bit is incrementing */
SIVAL(&rpc_hnd->wire_handle.uuid.time_low, 0 , pol_hnd_low);
@@ -307,12 +309,14 @@ static struct dcesrv_handle *create_rpc_handle_internal(struct pipes_struct *p,
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 *rpc_hnd;
- 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;
}
@@ -448,9 +452,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 *rpc_hnd;
void *data;
@@ -472,7 +480,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;
diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h
index 8a8f8e58169..5cdf2fdf6a2 100644
--- a/source3/rpc_server/rpc_pipes.h
+++ b/source3/rpc_server/rpc_pipes.h
@@ -199,18 +199,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,
diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
index 124d6d38cd7..7b8c42271bb 100644
--- a/source3/rpc_server/samr/srv_samr_nt.c
+++ b/source3/rpc_server/samr/srv_samr_nt.c
@@ -62,6 +62,14 @@
#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;
};
@@ -495,8 +503,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;
}
@@ -2214,8 +2226,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;
}
@@ -3776,8 +3792,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;
}
@@ -3845,9 +3865,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;
}
@@ -3909,8 +3932,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;
}
@@ -4146,8 +4173,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;
}
@@ -5818,9 +5849,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;
}
@@ -5892,9 +5926,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;
}
@@ -6296,9 +6333,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;
}
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index f32b465afb6..a00fc032a03 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -713,7 +713,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;
}
diff --git a/source3/rpc_server/svcctl/srv_svcctl_nt.c b/source3/rpc_server/svcctl/srv_svcctl_nt.c
index ae787066873..9ba6fbb1fce 100644
--- a/source3/rpc_server/svcctl/srv_svcctl_nt.c
+++ b/source3/rpc_server/svcctl/srv_svcctl_nt.c
@@ -257,7 +257,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;
}
diff --git a/source3/rpc_server/winreg/srv_winreg_nt.c b/source3/rpc_server/winreg/srv_winreg_nt.c
index e42f0ba203e..93f7804a9f5 100644
--- a/source3/rpc_server/winreg/srv_winreg_nt.c
+++ b/source3/rpc_server/winreg/srv_winreg_nt.c
@@ -34,6 +34,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 *
*****************************************************************/
@@ -81,7 +83,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;
}
@@ -705,7 +707,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;
}