summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid O'Neill <dmo@samba.org>2001-01-19 16:56:58 +0000
committerDavid O'Neill <dmo@samba.org>2001-01-19 16:56:58 +0000
commita4c22506eff954ceacfb8d2405dae358b5b4c964 (patch)
tree561c612d1bf935456c740ec0cce2574f04e1fcd0
parent1a0d64a4254ae769e147699f0dc2b40429e43f23 (diff)
downloadsamba-a4c22506eff954ceacfb8d2405dae358b5b4c964.tar.gz
samba-a4c22506eff954ceacfb8d2405dae358b5b4c964.tar.bz2
samba-a4c22506eff954ceacfb8d2405dae358b5b4c964.zip
Changes from APPLIANCE_HEAD:
source/lib/util_seaccess.c - added se_create_child_secdesc() function which takes a parent (container) security descriptor and creates a security descriptor which has the inheritance flags for each ACE applied. In NT a print job is a child object of a printer so deleting and pausing/resuming jobs requires a check against the child security descriptor, not the parent. The values seen in NT printer security descriptors now all fit together in a natural and elegant way which is always nice. - Removed #ifdef'ed out portion of check_ace() when the INHERIT_ONLY flag is set as the se_create_child_secdesc() function now creates a security descriptor which can be used without this hack. (This used to be commit f125b9a94413fd481ae9f05ec5096ef79f0d49e4)
-rw-r--r--source3/lib/util_seaccess.c147
1 files changed, 119 insertions, 28 deletions
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 68f900b34d..6cfcd065aa 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -51,32 +51,6 @@ static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
{
uint32 mask = ace->info.mask;
-#if 0
-
- /* I think there is some aspect of inheritable ACEs that we don't
- understand. A 'Manage Documents' permission has the following
- ACE entries (after generic mapping has been applied):
-
- S-1-5-21-1067277791-1719175008-3000797951-1033 0 9 0x000f000c
- S-1-5-21-1067277791-1719175008-3000797951-1033 0 2 0x00020000
-
- Now a user wanting to print calls se_access_check() with desired
- access PRINTER_ACCESS_USE (0x00000008). This is only allowed if
- the inherit only ACE, flags & SEC_ACE_FLAG_INHERIT_ONLY (0x8) is
- checked. A similar argument is used to explain how a user with
- 'Full Control' permission can print.
-
- Having both the flags SEC_ACE_FLAG_INHERIT_ONLY and
- SEC_ACE_FLAG_OBJECT_INHERIT set in an ACE doesn't seem to make
- sense. According to the MSDN, an inherit only ACE "indicates an
- [...] ACE which does not control access to the object to which
- it is attached" and an object inherit ACE for "non-container
- child objects [they] inherit the ACE as an effective ACE".
- These two flags don't seem to make sense when combined. Does
- the object inherit override the inherit only flag? We are also
- talking about access to a printer object, not a printer job so
- inheritance shouldn't even be involved. -tpot */
-
/*
* Inherit only is ignored.
*/
@@ -85,8 +59,6 @@ static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
return acc_desired;
}
-#endif
-
/*
* If this ACE has no SID in common with the token,
* ignore it as it cannot be used to make an access
@@ -328,3 +300,122 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
DEBUG(5,("se_access_check: access (%x) denied.\n", (unsigned int)acc_desired ));
return False;
}
+
+/* Create a child security descriptor using another security descriptor as
+ the parent container. This child object can either be a container or
+ non-container object. */
+
+SEC_DESC_BUF *se_create_child_secdesc(SEC_DESC *parent_ctr,
+ BOOL child_container)
+{
+ SEC_DESC_BUF *sdb;
+ SEC_DESC *sd;
+ SEC_ACL *new_dacl, *acl;
+ SEC_ACE *new_ace_list = NULL;
+ int new_ace_list_ndx = 0, i;
+ size_t size;
+
+ /* Currently we only process the dacl when creating the child. The
+ sacl should also be processed but this is left out as sacls are
+ not implemented in Samba at the moment.*/
+
+ acl = parent_ctr->dacl;
+
+ if (!(new_ace_list = malloc(sizeof(SEC_ACE) * acl->num_aces)))
+ return NULL;
+
+ for (i = 0; acl && i < acl->num_aces; i++) {
+ SEC_ACE *ace = &acl->ace[i];
+ SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
+ uint8 new_flags = 0;
+ BOOL inherit = False;
+ fstring sid_str;
+
+ /* The OBJECT_INHERIT_ACE flag causes the ACE to be
+ inherited by non-container children objects. Container
+ children objects will inherit it as an INHERIT_ONLY
+ ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
+
+ if (!child_container) {
+ new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
+ } else {
+ new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ inherit = True;
+ }
+
+ /* The CONAINER_INHERIT_ACE flag means all child container
+ objects will inherit and use the ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
+ if (!child_container) {
+ inherit = False;
+ } else {
+ new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
+ }
+ }
+
+ /* The INHERIT_ONLY_ACE is not used by the se_access_check()
+ function for the parent container, but is inherited by
+ all child objects as a normal ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ /* Move along, nothing to see here */
+ }
+
+ /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
+ is inherited by child objects but not grandchildren
+ objects. We clear the object inherit and container
+ inherit flags in the inherited ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
+ SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+
+ /* Add ACE to ACE list */
+
+ if (!inherit)
+ continue;
+
+ init_sec_access(&new_ace->info, ace->info.mask);
+ init_sec_ace(new_ace, &ace->sid, ace->type,
+ new_ace->info, new_flags);
+
+ sid_to_string(sid_str, &ace->sid);
+
+ DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
+ " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
+ ace->type, ace->flags, ace->info.mask,
+ sid_str, new_ace->type, new_ace->flags,
+ new_ace->info.mask));
+
+ new_ace_list_ndx++;
+ }
+
+ /* Create child security descriptor to return */
+
+ new_dacl = make_sec_acl(ACL_REVISION, new_ace_list_ndx, new_ace_list);
+ safe_free(new_ace_list);
+
+ /* Use the existing user and group sids. I don't think this is
+ correct. Perhaps the user and group should be passed in as
+ parameters by the caller? */
+
+ sd = make_sec_desc(SEC_DESC_REVISION,
+ parent_ctr->owner_sid,
+ parent_ctr->grp_sid,
+ parent_ctr->sacl,
+ new_dacl, &size);
+
+ free_sec_acl(&new_dacl);
+
+ sdb = make_sec_desc_buf(size, sd);
+
+ free_sec_desc(&sd);
+
+ return sdb;
+}