diff options
-rw-r--r-- | source4/libcli/security/security_descriptor.c | 21 | ||||
-rw-r--r-- | source4/librpc/idl/lsa.idl | 5 | ||||
-rw-r--r-- | source4/librpc/idl/samr.idl | 9 | ||||
-rw-r--r-- | source4/librpc/idl/security.idl | 5 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 4 | ||||
-rw-r--r-- | source4/torture/rpc/samsync.c | 46 |
6 files changed, 76 insertions, 14 deletions
diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 5ed5ef5c76..a4056e5e71 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -224,3 +224,24 @@ BOOL security_descriptor_equal(const struct security_descriptor *sd1, return True; } + +/* + compare two security descriptors, but allow certain (missing) parts + to be masked out of the comparison +*/ +BOOL security_descriptor_mask_equal(const struct security_descriptor *sd1, + const struct security_descriptor *sd2, + uint32 mask) +{ + if (sd1 == sd2) return True; + if (!sd1 || !sd2) return False; + if (sd1->revision != sd2->revision) return False; + if ((sd1->type & mask) != (sd2->type & mask)) return False; + + if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return False; + if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return False; + if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl)) return False; + if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl)) return False; + + return True; +} diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index d0bf2ad3e1..225979da18 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -56,11 +56,6 @@ /******************/ /* Function: 0x03 */ - typedef [public] struct { - uint32 size; - [subcontext(4)] security_descriptor *sd; - } sec_desc_buf; - NTSTATUS lsa_QuerySecObj ( [in,ref] policy_handle *handle, [in] uint32 sec_info, diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index 358218c2a0..58e0601606 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -48,15 +48,10 @@ /******************/ /* Function: 0x02 */ - typedef struct { - [range(0,0x40000),value(ndr_size_security_descriptor(r->sd))] uint32 sd_size; - [subcontext(4)] security_descriptor *sd; - } samr_SdBuf; - NTSTATUS samr_SetSecurity ( [in,ref] policy_handle *handle, [in] uint32 sec_info, - [in,ref] samr_SdBuf *sdbuf + [in,ref] sec_desc_buf *sdbuf ); /******************/ @@ -65,7 +60,7 @@ NTSTATUS samr_QuerySecurity ( [in,ref] policy_handle *handle, [in] uint32 sec_info, - [out] samr_SdBuf *sdbuf + [out] sec_desc_buf *sdbuf ); /******************/ diff --git a/source4/librpc/idl/security.idl b/source4/librpc/idl/security.idl index 201868e531..9625153ec1 100644 --- a/source4/librpc/idl/security.idl +++ b/source4/librpc/idl/security.idl @@ -120,6 +120,11 @@ interface security [relative] security_acl *dacl; /* user (discretionary) ACL */ } security_descriptor; + typedef [public] struct { + [range(0,0x40000),value(ndr_size_security_descriptor(r->sd))] uint32 sd_size; + [subcontext(4)] security_descriptor *sd; + } sec_desc_buf; + typedef [public,printonly] struct { /* TODO */ uint32 flags; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index ef6e45cb1e..05031bdfcb 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -118,13 +118,13 @@ static NTSTATUS samr_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CT struct samr_QuerySecurity *r) { struct dcesrv_handle *h; - struct samr_SdBuf *sd; + struct sec_desc_buf *sd; r->out.sdbuf = NULL; DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); - sd = talloc_p(mem_ctx, struct samr_SdBuf); + sd = talloc_p(mem_ctx, struct sec_desc_buf); if (sd == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 7f9cf321dc..be56e4593e 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -164,6 +164,24 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, return domain_handle; } +static struct sec_desc_buf *samsync_query_sec_desc(TALLOC_CTX *mem_ctx, + struct samsync_state *samsync_state, + struct policy_handle *handle) +{ + struct samr_QuerySecurity r; + NTSTATUS status; + + r.in.handle = handle; + r.in.sec_info = 0x7; + + status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("QuerySecurity failed - %s\n", nt_errstr(status)); + return NULL; + } + + return r.out.sdbuf; +} #define TEST_UINT64_EQUAL(i1, i2) do {\ if (i1 != i2) {\ @@ -187,6 +205,7 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, ret = False;\ } \ } while (0) + #define TEST_STRING_EQUAL(s1, s2) do {\ if (!((!s1.string || s1.string[0]=='\0') && (!s2.string || s2.string[0]=='\0')) \ && strcmp_safe(s1.string, s2.string) != 0) {\ @@ -196,6 +215,25 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, } \ } while (0) +/* The ~SEC_DESC_SACL_PRESENT is because we don't, as administrator, + * get back the SACL part of the SD when we ask over SAMR */ + +#define TEST_SEC_DESC_EQUAL(sd1, handle) do {\ + struct sec_desc_buf *sdbuf = samsync_query_sec_desc(mem_ctx, samsync_state, \ + handle); \ + if (!sdbuf || !sdbuf->sd) { \ + ret = False; \ + } else {\ + if (!security_descriptor_mask_equal(sd1.sd, sdbuf->sd, \ + ~SEC_DESC_SACL_PRESENT)) {\ + printf("Security Descriptor Mismatch for %s:\n", #sd1);\ + ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "SamSync", sd1.sd);\ + ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "SamR", sdbuf->sd);\ + ret = False;\ + }\ + }\ +} while (0) + static BOOL samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state, int database_id, struct netr_DELTA_ENUM *delta) { @@ -279,6 +317,8 @@ static BOOL samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time, domain->domain_create_time); + TEST_SEC_DESC_EQUAL(domain->sdbuf, samsync_state->domain_handle[database_id]); + return ret; } @@ -351,6 +391,8 @@ static BOOL samsync_handle_user(TALLOC_CTX *mem_ctx, struct samsync_state *samsy q.in.user_handle = &user_handle; q.in.level = 21; + TEST_SEC_DESC_EQUAL(user->sdbuf, &user_handle); + nt_status = dcerpc_samr_QueryUserInfo(samsync_state->p_samr, mem_ctx, &q); if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &user_handle)) { return False; @@ -546,6 +588,8 @@ static BOOL samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.alias_handle = &alias_handle; q.in.level = 1; + TEST_SEC_DESC_EQUAL(alias->sdbuf, &alias_handle); + nt_status = dcerpc_samr_QueryAliasInfo(samsync_state->p_samr, mem_ctx, &q); if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &alias_handle)) { return False; @@ -593,6 +637,8 @@ static BOOL samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.group_handle = &group_handle; q.in.level = 1; + TEST_SEC_DESC_EQUAL(group->sdbuf, &group_handle); + nt_status = dcerpc_samr_QueryGroupInfo(samsync_state->p_samr, mem_ctx, &q); if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &group_handle)) { return False; |