summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/security/security_descriptor.c21
-rw-r--r--source4/librpc/idl/lsa.idl5
-rw-r--r--source4/librpc/idl/samr.idl9
-rw-r--r--source4/librpc/idl/security.idl5
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c4
-rw-r--r--source4/torture/rpc/samsync.c46
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;