1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

security: Fixed bugs in expansion of generic information ACEs

When an ACE gontaining GA, GE, GR, GW, CO or CG is provided by a user or inherited
the final SD actually has to have 2 ACEs, one is an effective expanded one, and the
original one with IO flag added.
This commit is contained in:
Nadezhda Ivanova 2011-01-11 12:20:43 +02:00
parent d7c2eb1be3
commit 980f68a6f2

View File

@ -55,12 +55,12 @@ uint32_t map_generic_rights_ds(uint32_t access_mask)
{
if (access_mask & SEC_GENERIC_ALL) {
access_mask |= SEC_ADS_GENERIC_ALL;
access_mask = ~SEC_GENERIC_ALL;
access_mask &= ~SEC_GENERIC_ALL;
}
if (access_mask & SEC_GENERIC_EXECUTE) {
access_mask |= SEC_ADS_GENERIC_EXECUTE;
access_mask = ~SEC_GENERIC_EXECUTE;
access_mask &= ~SEC_GENERIC_EXECUTE;
}
if (access_mask & SEC_GENERIC_WRITE) {
@ -82,6 +82,45 @@ static bool object_in_list(struct GUID *object_list, struct GUID *object)
{
return true;
}
/* returns true if the ACE gontains generic information
* that needs to be processed additionally */
static bool desc_ace_has_generic(TALLOC_CTX *mem_ctx,
struct security_ace *ace)
{
struct dom_sid *co, *cg;
co = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER);
cg = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_GROUP);
if (ace->access_mask & SEC_GENERIC_ALL || ace->access_mask & SEC_GENERIC_READ ||
ace->access_mask & SEC_GENERIC_WRITE || ace->access_mask & SEC_GENERIC_EXECUTE) {
return true;
}
if (dom_sid_equal(&ace->trustee, co) || dom_sid_equal(&ace->trustee, cg)) {
return true;
}
return false;
}
/* creates an ace in which the generic information is expanded */
static void desc_expand_generic(TALLOC_CTX *mem_ctx,
struct security_ace *new_ace,
struct dom_sid *owner,
struct dom_sid *group)
{
struct dom_sid *co, *cg;
co = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER);
cg = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_GROUP);
new_ace->access_mask = map_generic_rights_ds(new_ace->access_mask);
if (dom_sid_equal(&new_ace->trustee, co)) {
new_ace->trustee = *owner;
}
if (dom_sid_equal(&new_ace->trustee, cg)) {
new_ace->trustee = *group;
}
new_ace->flags = 0x0;
}
static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx,
struct security_acl *acl,
@ -108,7 +147,8 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx,
struct security_ace *ace = &acl->aces[i];
if ((ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) ||
(ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace,
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces,
struct security_ace,
tmp_acl->num_aces+1);
if (tmp_acl->aces == NULL) {
talloc_free(tmp_ctx);
@ -128,30 +168,24 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx,
}
}
tmp_acl->aces[tmp_acl->num_aces].access_mask =
map_generic_rights_ds(ace->access_mask);
tmp_acl->num_aces++;
if (is_container) {
if (!(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) &&
((dom_sid_equal(&ace->trustee, co) || dom_sid_equal(&ace->trustee, cg)))) {
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace,
(desc_ace_has_generic(tmp_ctx, ace))) {
tmp_acl->aces = talloc_realloc(tmp_acl,
tmp_acl->aces,
struct security_ace,
tmp_acl->num_aces+1);
if (tmp_acl->aces == NULL) {
talloc_free(tmp_ctx);
return NULL;
}
tmp_acl->aces[tmp_acl->num_aces] = *ace;
tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERITED_ACE;
if (dom_sid_equal(&tmp_acl->aces[tmp_acl->num_aces].trustee, co)) {
tmp_acl->aces[tmp_acl->num_aces].trustee = *owner;
}
if (dom_sid_equal(&tmp_acl->aces[tmp_acl->num_aces].trustee, cg)) {
tmp_acl->aces[tmp_acl->num_aces].trustee = *group;
}
tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT;
tmp_acl->aces[tmp_acl->num_aces].access_mask =
map_generic_rights_ds(ace->access_mask);
desc_expand_generic(tmp_ctx,
&tmp_acl->aces[tmp_acl->num_aces],
owner,
group);
tmp_acl->aces[tmp_acl->num_aces].flags = SEC_ACE_FLAG_INHERITED_ACE;
tmp_acl->num_aces++;
}
}
@ -200,29 +234,39 @@ static struct security_acl *process_user_acl(TALLOC_CTX *mem_ctx,
ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT))
continue;
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace,
tmp_acl->num_aces+1);
tmp_acl->aces[tmp_acl->num_aces] = *ace;
if (dom_sid_equal(&(tmp_acl->aces[tmp_acl->num_aces].trustee), co)) {
tmp_acl->aces[tmp_acl->num_aces].trustee = *owner;
tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT;
}
if (dom_sid_equal(&(tmp_acl->aces[tmp_acl->num_aces].trustee), cg)) {
tmp_acl->aces[tmp_acl->num_aces].trustee = *group;
tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT;
}
tmp_acl->aces[tmp_acl->num_aces].access_mask =
map_generic_rights_ds(tmp_acl->aces[tmp_acl->num_aces].access_mask);
tmp_acl->num_aces++;
if (!dom_sid_equal(&ace->trustee, co) && !dom_sid_equal(&ace->trustee, cg))
continue;
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace,
tmp_acl->aces = talloc_realloc(tmp_acl,
tmp_acl->aces,
struct security_ace,
tmp_acl->num_aces+1);
tmp_acl->aces[tmp_acl->num_aces] = *ace;
tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERIT_ONLY;
tmp_acl->num_aces++;
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
continue;
}
/* if the ACE contains CO, CG, GA, GE, GR or GW, and is inheritable
* it has to be expanded to two aces, the original as IO,
* and another one where these are translated */
if (desc_ace_has_generic(tmp_ctx, ace)) {
if (!(ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
desc_expand_generic(tmp_ctx,
&tmp_acl->aces[tmp_acl->num_aces-1],
owner,
group);
} else {
/*The original ACE becomes read only */
tmp_acl->aces[tmp_acl->num_aces-1].flags |= SEC_ACE_FLAG_INHERIT_ONLY;
tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces,
struct security_ace,
tmp_acl->num_aces+1);
/* add a new ACE with expanded generic info */
tmp_acl->aces[tmp_acl->num_aces] = *ace;
desc_expand_generic(tmp_ctx,
&tmp_acl->aces[tmp_acl->num_aces],
owner,
group);
tmp_acl->num_aces++;
}
}
}
new_acl = security_acl_dup(mem_ctx,tmp_acl);