mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
r3885: Add security descriptor comparison to our RPC-SAMSYNC test. We now
verify that the security descriptor found in the SamSync is the same as what is available over SAMR. Unfortunately, the administrator seems unable to retrieve the SACL on the security descriptor, so I've added a new function to compare with a mask. Andrew Bartlett
This commit is contained in:
parent
16d905f6b0
commit
39ae5e1dac
@ -224,3 +224,24 @@ BOOL security_descriptor_equal(const struct security_descriptor *sd1,
|
|||||||
|
|
||||||
return True;
|
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;
|
||||||
|
}
|
||||||
|
@ -56,11 +56,6 @@
|
|||||||
/******************/
|
/******************/
|
||||||
/* Function: 0x03 */
|
/* Function: 0x03 */
|
||||||
|
|
||||||
typedef [public] struct {
|
|
||||||
uint32 size;
|
|
||||||
[subcontext(4)] security_descriptor *sd;
|
|
||||||
} sec_desc_buf;
|
|
||||||
|
|
||||||
NTSTATUS lsa_QuerySecObj (
|
NTSTATUS lsa_QuerySecObj (
|
||||||
[in,ref] policy_handle *handle,
|
[in,ref] policy_handle *handle,
|
||||||
[in] uint32 sec_info,
|
[in] uint32 sec_info,
|
||||||
|
@ -48,15 +48,10 @@
|
|||||||
/******************/
|
/******************/
|
||||||
/* Function: 0x02 */
|
/* 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 (
|
NTSTATUS samr_SetSecurity (
|
||||||
[in,ref] policy_handle *handle,
|
[in,ref] policy_handle *handle,
|
||||||
[in] uint32 sec_info,
|
[in] uint32 sec_info,
|
||||||
[in,ref] samr_SdBuf *sdbuf
|
[in,ref] sec_desc_buf *sdbuf
|
||||||
);
|
);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
@ -65,7 +60,7 @@
|
|||||||
NTSTATUS samr_QuerySecurity (
|
NTSTATUS samr_QuerySecurity (
|
||||||
[in,ref] policy_handle *handle,
|
[in,ref] policy_handle *handle,
|
||||||
[in] uint32 sec_info,
|
[in] uint32 sec_info,
|
||||||
[out] samr_SdBuf *sdbuf
|
[out] sec_desc_buf *sdbuf
|
||||||
);
|
);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
|
@ -120,6 +120,11 @@ interface security
|
|||||||
[relative] security_acl *dacl; /* user (discretionary) ACL */
|
[relative] security_acl *dacl; /* user (discretionary) ACL */
|
||||||
} security_descriptor;
|
} 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 {
|
typedef [public,printonly] struct {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
@ -118,13 +118,13 @@ static NTSTATUS samr_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CT
|
|||||||
struct samr_QuerySecurity *r)
|
struct samr_QuerySecurity *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h;
|
struct dcesrv_handle *h;
|
||||||
struct samr_SdBuf *sd;
|
struct sec_desc_buf *sd;
|
||||||
|
|
||||||
r->out.sdbuf = NULL;
|
r->out.sdbuf = NULL;
|
||||||
|
|
||||||
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
|
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) {
|
if (sd == NULL) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,24 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
|
|||||||
return domain_handle;
|
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 {\
|
#define TEST_UINT64_EQUAL(i1, i2) do {\
|
||||||
if (i1 != i2) {\
|
if (i1 != i2) {\
|
||||||
@ -187,6 +205,7 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
|
|||||||
ret = False;\
|
ret = False;\
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_STRING_EQUAL(s1, s2) do {\
|
#define TEST_STRING_EQUAL(s1, s2) do {\
|
||||||
if (!((!s1.string || s1.string[0]=='\0') && (!s2.string || s2.string[0]=='\0')) \
|
if (!((!s1.string || s1.string[0]=='\0') && (!s2.string || s2.string[0]=='\0')) \
|
||||||
&& strcmp_safe(s1.string, s2.string) != 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)
|
} 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,
|
static BOOL samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state,
|
||||||
int database_id, struct netr_DELTA_ENUM *delta)
|
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,
|
TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time,
|
||||||
domain->domain_create_time);
|
domain->domain_create_time);
|
||||||
|
|
||||||
|
TEST_SEC_DESC_EQUAL(domain->sdbuf, samsync_state->domain_handle[database_id]);
|
||||||
|
|
||||||
return ret;
|
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.user_handle = &user_handle;
|
||||||
q.in.level = 21;
|
q.in.level = 21;
|
||||||
|
|
||||||
|
TEST_SEC_DESC_EQUAL(user->sdbuf, &user_handle);
|
||||||
|
|
||||||
nt_status = dcerpc_samr_QueryUserInfo(samsync_state->p_samr, mem_ctx, &q);
|
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)) {
|
if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &user_handle)) {
|
||||||
return False;
|
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.alias_handle = &alias_handle;
|
||||||
q.in.level = 1;
|
q.in.level = 1;
|
||||||
|
|
||||||
|
TEST_SEC_DESC_EQUAL(alias->sdbuf, &alias_handle);
|
||||||
|
|
||||||
nt_status = dcerpc_samr_QueryAliasInfo(samsync_state->p_samr, mem_ctx, &q);
|
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)) {
|
if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &alias_handle)) {
|
||||||
return False;
|
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.group_handle = &group_handle;
|
||||||
q.in.level = 1;
|
q.in.level = 1;
|
||||||
|
|
||||||
|
TEST_SEC_DESC_EQUAL(group->sdbuf, &group_handle);
|
||||||
|
|
||||||
nt_status = dcerpc_samr_QueryGroupInfo(samsync_state->p_samr, mem_ctx, &q);
|
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)) {
|
if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, &group_handle)) {
|
||||||
return False;
|
return False;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user