diff options
author | Günther Deschner <gd@samba.org> | 2007-11-02 12:54:19 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2007-12-21 05:44:06 +0100 |
commit | f2002541ced97da3658348fe9ac9e212dd50c55b (patch) | |
tree | e9e0b7df2f65fff9b3ef48167e5b631edfb712c2 | |
parent | ffc3ff734ee46c1c5837545114bbbc57ffcf6c9b (diff) | |
download | samba-f2002541ced97da3658348fe9ac9e212dd50c55b.tar.gz samba-f2002541ced97da3658348fe9ac9e212dd50c55b.tar.bz2 samba-f2002541ced97da3658348fe9ac9e212dd50c55b.zip |
r25803: Make our security descriptor acl manipulation methods more generic so that we
can add and delete ACEs for SACLs as well as for DACLs.
Guenther
(This used to be commit 947fff994181f0ae50ac76d09621ddd684873112)
-rw-r--r-- | source4/lib/registry/tests/registry.c | 2 | ||||
-rw-r--r-- | source4/libcli/security/security_descriptor.c | 247 | ||||
-rw-r--r-- | source4/libnet/libnet_become_dc.c | 2 | ||||
-rw-r--r-- | source4/torture/raw/acls.c | 40 | ||||
-rw-r--r-- | source4/torture/rpc/samba3rpc.c | 4 | ||||
-rw-r--r-- | source4/torture/rpc/winreg.c | 2 |
6 files changed, 199 insertions, 98 deletions
diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index d2838e363f..155e891c40 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -399,7 +399,7 @@ static bool test_security(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey)) return false; - osd = security_descriptor_create(tctx, + osd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, SID_NT_AUTHENTICATED_USERS, diff --git a/source4/libcli/security/security_descriptor.c b/source4/libcli/security/security_descriptor.c index 34ccab593d..6a124d7371 100644 --- a/source4/libcli/security/security_descriptor.c +++ b/source4/libcli/security/security_descriptor.c @@ -142,78 +142,123 @@ struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx, } /* - add an ACE to the DACL of a security_descriptor + add an ACE to an ACL of a security_descriptor */ -NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, - const struct security_ace *ace) + +static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd, + bool add_to_sacl, + const struct security_ace *ace) { - if (sd->dacl == NULL) { - sd->dacl = talloc(sd, struct security_acl); - if (sd->dacl == NULL) { + struct security_acl *acl = NULL; + + if (add_to_sacl) { + acl = sd->sacl; + } else { + acl = sd->dacl; + } + + if (acl == NULL) { + acl = talloc(sd, struct security_acl); + if (acl == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->revision = SECURITY_ACL_REVISION_NT4; - sd->dacl->size = 0; - sd->dacl->num_aces = 0; - sd->dacl->aces = NULL; + acl->revision = SECURITY_ACL_REVISION_NT4; + acl->size = 0; + acl->num_aces = 0; + acl->aces = NULL; } - sd->dacl->aces = talloc_realloc(sd->dacl, sd->dacl->aces, - struct security_ace, sd->dacl->num_aces+1); - if (sd->dacl->aces == NULL) { + acl->aces = talloc_realloc(acl, acl->aces, + struct security_ace, acl->num_aces+1); + if (acl->aces == NULL) { return NT_STATUS_NO_MEMORY; } - sd->dacl->aces[sd->dacl->num_aces] = *ace; - sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths = - (uint32_t *)talloc_memdup(sd->dacl->aces, - sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths, - sizeof(uint32_t) * - sd->dacl->aces[sd->dacl->num_aces].trustee.num_auths); - if (sd->dacl->aces[sd->dacl->num_aces].trustee.sub_auths == NULL) { + acl->aces[acl->num_aces] = *ace; + acl->aces[acl->num_aces].trustee.sub_auths = + (uint32_t *)talloc_memdup(acl->aces, + acl->aces[acl->num_aces].trustee.sub_auths, + sizeof(uint32_t) * + acl->aces[acl->num_aces].trustee.num_auths); + if (acl->aces[acl->num_aces].trustee.sub_auths == NULL) { return NT_STATUS_NO_MEMORY; } - switch (sd->dacl->aces[sd->dacl->num_aces].type) { + switch (acl->aces[acl->num_aces].type) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - sd->dacl->revision = SECURITY_ACL_REVISION_ADS; + acl->revision = SECURITY_ACL_REVISION_ADS; break; default: break; } - sd->dacl->num_aces++; + acl->num_aces++; - sd->type |= SEC_DESC_DACL_PRESENT; + if (add_to_sacl) { + sd->sacl = acl; + sd->type |= SEC_DESC_SACL_PRESENT; + } else { + sd->dacl = acl; + sd->type |= SEC_DESC_DACL_PRESENT; + } return NT_STATUS_OK; } +/* + add an ACE to the SACL of a security_descriptor +*/ + +NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd, + const struct security_ace *ace) +{ + return security_descriptor_acl_add(sd, true, ace); +} /* - delete the ACE corresponding to the given trustee in the DACL of a security_descriptor + add an ACE to the DACL of a security_descriptor */ -NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, - struct dom_sid *trustee) + +NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd, + const struct security_ace *ace) +{ + return security_descriptor_acl_add(sd, false, ace); +} + +/* + delete the ACE corresponding to the given trustee in an ACL of a + security_descriptor +*/ + +static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd, + bool sacl_del, + struct dom_sid *trustee) { int i; bool found = false; + struct security_acl *acl = NULL; - if (sd->dacl == NULL) { + if (sacl_del) { + acl = sd->sacl; + } else { + acl = sd->dacl; + } + + if (acl == NULL) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } /* there can be multiple ace's for one trustee */ - for (i=0;i<sd->dacl->num_aces;i++) { - if (dom_sid_equal(trustee, &sd->dacl->aces[i].trustee)) { - memmove(&sd->dacl->aces[i], &sd->dacl->aces[i+1], - sizeof(sd->dacl->aces[i]) * (sd->dacl->num_aces - (i+1))); - sd->dacl->num_aces--; - if (sd->dacl->num_aces == 0) { - sd->dacl->aces = NULL; + for (i=0;i<acl->num_aces;i++) { + if (dom_sid_equal(trustee, &acl->aces[i].trustee)) { + memmove(&acl->aces[i], &acl->aces[i+1], + sizeof(acl->aces[i]) * (acl->num_aces - (i+1))); + acl->num_aces--; + if (acl->num_aces == 0) { + acl->aces = NULL; } found = true; } @@ -223,15 +268,15 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - sd->dacl->revision = SECURITY_ACL_REVISION_NT4; + acl->revision = SECURITY_ACL_REVISION_NT4; - for (i=0;i<sd->dacl->num_aces;i++) { - switch (sd->dacl->aces[i].type) { + for (i=0;i<acl->num_aces;i++) { + switch (acl->aces[i].type) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - sd->dacl->revision = SECURITY_ACL_REVISION_ADS; + acl->revision = SECURITY_ACL_REVISION_ADS; return NT_STATUS_OK; default: break; /* only for the switch statement */ @@ -241,6 +286,27 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, return NT_STATUS_OK; } +/* + delete the ACE corresponding to the given trustee in the DACL of a + security_descriptor +*/ + +NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd, + struct dom_sid *trustee) +{ + return security_descriptor_acl_del(sd, false, trustee); +} + +/* + delete the ACE corresponding to the given trustee in the SACL of a + security_descriptor +*/ + +NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd, + struct dom_sid *trustee) +{ + return security_descriptor_acl_del(sd, true, trustee); +} /* compare two security ace structures @@ -319,30 +385,9 @@ bool security_descriptor_mask_equal(const struct security_descriptor *sd1, } -/* - create a security descriptor using string SIDs. This is used by the - torture code to allow the easy creation of complex ACLs - This is a varargs function. The list of DACL ACEs ends with a NULL sid. - - Each ACE contains a set of 4 parameters: - SID, ACCESS_TYPE, MASK, FLAGS - - a typical call would be: - - sd = security_descriptor_create(mem_ctx, - sd_type_flags, - mysid, - mygroup, - SID_NT_AUTHENTICATED_USERS, - SEC_ACE_TYPE_ACCESS_ALLOWED, - SEC_FILE_ALL, - SEC_ACE_FLAG_OBJECT_INHERIT, - NULL); - that would create a sd with one DACL ACE -*/ - -struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd, - va_list ap) +static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd, + bool add_ace_to_sacl, + va_list ap) { const char *sidstr; @@ -364,7 +409,11 @@ struct security_descriptor *security_descriptor_appendv(struct security_descript return NULL; } ace->trustee = *sid; - status = security_descriptor_dacl_add(sd, ace); + if (add_ace_to_sacl) { + status = security_descriptor_sacl_add(sd, ace); + } else { + status = security_descriptor_dacl_add(sd, ace); + } /* TODO: check: would talloc_free(ace) here be correct? */ if (!NT_STATUS_IS_OK(status)) { talloc_free(sd); @@ -381,23 +430,25 @@ struct security_descriptor *security_descriptor_append(struct security_descripto va_list ap; va_start(ap, sd); - sd = security_descriptor_appendv(sd, ap); + sd = security_descriptor_appendv(sd, false, ap); va_end(ap); return sd; } -struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, - uint16_t sd_type, - const char *owner_sid, - const char *group_sid, - ...) +static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + bool add_ace_to_sacl, + va_list ap) { - va_list ap; struct security_descriptor *sd; sd = security_descriptor_initialise(mem_ctx); - if (sd == NULL) return NULL; + if (sd == NULL) { + return NULL; + } sd->type |= sd_type; @@ -416,8 +467,58 @@ struct security_descriptor *security_descriptor_create(TALLOC_CTX *mem_ctx, } } + return security_descriptor_appendv(sd, add_ace_to_sacl, ap); +} + +/* + create a security descriptor using string SIDs. This is used by the + torture code to allow the easy creation of complex ACLs + This is a varargs function. The list of DACL ACEs ends with a NULL sid. + + Each ACE contains a set of 4 parameters: + SID, ACCESS_TYPE, MASK, FLAGS + + a typical call would be: + + sd = security_descriptor_dacl_create(mem_ctx, + sd_type_flags, + mysid, + mygroup, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_FILE_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + that would create a sd with one DACL ACE +*/ + +struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + ...) +{ + struct security_descriptor *sd = NULL; + va_list ap; + va_start(ap, group_sid); + sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid, + group_sid, false, ap); + va_end(ap); + + return sd; +} + +struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx, + uint16_t sd_type, + const char *owner_sid, + const char *group_sid, + ...) +{ + struct security_descriptor *sd = NULL; + va_list ap; va_start(ap, group_sid); - sd = security_descriptor_appendv(sd, ap); + sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid, + group_sid, true, ap); va_end(ap); return sd; diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index a6ca3551ce..ade2d340b8 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -1736,7 +1736,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s) domain_admins_sid_str = dom_sid_string(domain_admins_sid, domain_admins_sid); if (composite_nomem(domain_admins_sid_str, c)) return; - v = security_descriptor_create(vd, + v = security_descriptor_dacl_create(vd, 0, /* owner: domain admins */ domain_admins_sid_str, diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c index 0136056bdf..95e7282895 100644 --- a/source4/torture/raw/acls.c +++ b/source4/torture/raw/acls.c @@ -297,7 +297,7 @@ static bool test_creator_sid(struct torture_context *tctx, owner_sid = dom_sid_string(tctx, sd_orig->owner_sid); printf("set a sec desc allowing no write by CREATOR_OWNER\n"); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, SID_CREATOR_OWNER, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -334,7 +334,7 @@ static bool test_creator_sid(struct torture_context *tctx, CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); printf("set a sec desc allowing no write by owner\n"); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -389,7 +389,7 @@ static bool test_creator_sid(struct torture_context *tctx, smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); printf("set a sec desc allowing generic read by owner\n"); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -402,7 +402,7 @@ static bool test_creator_sid(struct torture_context *tctx, CHECK_STATUS(status, NT_STATUS_OK); printf("check that generic read has been mapped correctly\n"); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -567,7 +567,7 @@ static bool test_generic_bits(struct torture_context *tctx, printf("testing generic bits 0x%08x\n", file_mappings[i].gen_bits); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -583,7 +583,7 @@ static bool test_generic_bits(struct torture_context *tctx, status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -615,7 +615,7 @@ static bool test_generic_bits(struct torture_context *tctx, printf("testing generic bits 0x%08x (anonymous)\n", file_mappings[i].gen_bits); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -631,7 +631,7 @@ static bool test_generic_bits(struct torture_context *tctx, status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -732,7 +732,7 @@ static bool test_generic_bits(struct torture_context *tctx, printf("testing generic bits 0x%08x\n", file_mappings[i].gen_bits); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -748,7 +748,7 @@ static bool test_generic_bits(struct torture_context *tctx, status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -780,7 +780,7 @@ static bool test_generic_bits(struct torture_context *tctx, printf("testing generic bits 0x%08x (anonymous)\n", file_mappings[i].gen_bits); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -796,7 +796,7 @@ static bool test_generic_bits(struct torture_context *tctx, status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -907,7 +907,7 @@ static bool test_owner_bits(struct torture_context *tctx, } printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No"); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1114,7 +1114,7 @@ static bool test_inheritance(struct torture_context *tctx, printf("owner_sid is %s\n", owner_sid); - sd_def = security_descriptor_create(tctx, + sd_def = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1129,7 +1129,7 @@ static bool test_inheritance(struct torture_context *tctx, creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER); for (i=0;i<ARRAY_SIZE(test_flags);i++) { - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, SID_CREATOR_OWNER, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1262,7 +1262,7 @@ static bool test_inheritance(struct torture_context *tctx, } printf("testing access checks on inherited create with %s\n", fname1); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1295,7 +1295,7 @@ static bool test_inheritance(struct torture_context *tctx, CHECK_STATUS(status, NT_STATUS_OK); smbcli_close(cli->tree, fnum2); - sd2 = security_descriptor_create(tctx, + sd2 = security_descriptor_dacl_create(tctx, 0, owner_sid, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1431,7 +1431,7 @@ static bool test_inheritance_dynamic(struct torture_context *tctx, printf("owner_sid is %s\n", owner_sid); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1471,7 +1471,7 @@ static bool test_inheritance_dynamic(struct torture_context *tctx, CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); printf("update parent sd\n"); - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, @@ -1586,7 +1586,7 @@ static bool test_sd_get_set(struct torture_context *tctx, printf("TESTING ACCESS MASKS FOR SD GET/SET\n"); /* first create a file with full access for everyone */ - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS, SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index c8d58bf620..d91f935f7f 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -2117,14 +2117,14 @@ bool try_tcon(TALLOC_CTX *mem_ctx, return false; } - sd = security_descriptor_create( + sd = security_descriptor_dacl_create( tmp_ctx, 0, "S-1-5-32-544", dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid, DOMAIN_RID_USERS)), dom_sid_string(mem_ctx, user_sid), SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL); if (sd == NULL) { - d_printf("security_descriptor_create failed\n"); + d_printf("security_descriptor_dacl_create failed\n"); talloc_free(tmp_ctx); return false; } diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index 4c765f72a2..733d7f2958 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -139,7 +139,7 @@ static bool test_CreateKey_sd(struct dcerpc_pipe *p, DATA_BLOB sdblob; struct winreg_SecBuf secbuf; - sd = security_descriptor_create(tctx, + sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, SID_NT_AUTHENTICATED_USERS, |