* sec_acl.cc (search_ace): Use id == -1, instead of < 0, as wildcard.
(setacl): Start the search for a matching default at the next entry. Invalidate the type of merged entries instead of clearing it. Use well_known_creator for default owner and owning group and do not try to merge non-default and default entries in these cases. (getacl): Recognize well_known_creator for default owner and group. (acl_worker): Improve errno settings and streamline the nontsec case. * security.cc (write_sd): Remove the call to set_process_privilege. (alloc_sd): If the owner changes, call set_process_privilege and return immediately on failure. Change inheritance rules: on new directories add inherit only allow ACEs for creator_owner, creator_group and everyone. Preserve all inheritances through chmod and chown calls. Introduce isownergroup to implement the uid == gid case, to keep the inheritance code simple. Do not initialize owner_sid and group_sid and stop using the variable psd.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* secacl.cc: Sun compatible ACL functions.
|
||||
/* sec_acl.cc: Sun compatible ACL functions.
|
||||
|
||||
Copyright 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
Written by Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
@@ -41,7 +41,7 @@ searchace (__aclent16_t *aclp, int nentries, int type, int id = -1)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nentries; ++i)
|
||||
if ((aclp[i].a_type == type && (id < 0 || aclp[i].a_id == id))
|
||||
if ((aclp[i].a_type == type && (id == -1 || aclp[i].a_id == id))
|
||||
|| !aclp[i].a_type)
|
||||
return i;
|
||||
return -1;
|
||||
@@ -137,26 +137,31 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp)
|
||||
* inheritance bits is created.
|
||||
*/
|
||||
if (!(aclbufp[i].a_type & ACL_DEFAULT)
|
||||
&& (pos = searchace (aclbufp, nentries,
|
||||
&& aclbufp[i].a_type & (USER|GROUP|OTHER_OBJ)
|
||||
&& (pos = searchace (aclbufp + i + 1, nentries - i - 1,
|
||||
aclbufp[i].a_type | ACL_DEFAULT,
|
||||
(aclbufp[i].a_type & (USER|GROUP))
|
||||
? aclbufp[i].a_id : -1)) >= 0
|
||||
&& aclbufp[pos].a_type
|
||||
&& aclbufp[i].a_perm == aclbufp[pos].a_perm)
|
||||
{
|
||||
inheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||||
/* This eliminates the corresponding default entry. */
|
||||
aclbufp[pos].a_type = 0;
|
||||
/* This invalidates the corresponding default entry. */
|
||||
aclbufp[pos].a_type = USER|GROUP|ACL_DEFAULT;
|
||||
}
|
||||
switch (aclbufp[i].a_type)
|
||||
{
|
||||
case USER_OBJ:
|
||||
case DEF_USER_OBJ:
|
||||
allow |= STANDARD_RIGHTS_ALL & ~DELETE;
|
||||
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
||||
owner, acl_len, inheritance))
|
||||
return -1;
|
||||
break;
|
||||
case DEF_USER_OBJ:
|
||||
allow |= STANDARD_RIGHTS_ALL & ~DELETE;
|
||||
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
||||
well_known_creator_owner_sid, acl_len, inheritance))
|
||||
return -1;
|
||||
break;
|
||||
case USER:
|
||||
case DEF_USER:
|
||||
if (!(pw = internal_getpwuid (aclbufp[i].a_id))
|
||||
@@ -166,11 +171,15 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp)
|
||||
return -1;
|
||||
break;
|
||||
case GROUP_OBJ:
|
||||
case DEF_GROUP_OBJ:
|
||||
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
||||
group, acl_len, inheritance))
|
||||
return -1;
|
||||
break;
|
||||
case DEF_GROUP_OBJ:
|
||||
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
||||
well_known_creator_group_sid, acl_len, inheritance))
|
||||
return -1;
|
||||
break;
|
||||
case GROUP:
|
||||
case DEF_GROUP:
|
||||
if (!(gr = internal_getgrgid (aclbufp[i].a_id))
|
||||
@@ -336,6 +345,16 @@ getacl (const char *file, DWORD attr, int nentries, __aclent16_t *aclbufp)
|
||||
type = USER_OBJ;
|
||||
id = uid;
|
||||
}
|
||||
else if (ace_sid == well_known_creator_group_sid)
|
||||
{
|
||||
type = GROUP_OBJ | ACL_DEFAULT;
|
||||
id = ILLEGAL_GID;
|
||||
}
|
||||
else if (ace_sid == well_known_creator_owner_sid)
|
||||
{
|
||||
type = USER_OBJ | ACL_DEFAULT;
|
||||
id = ILLEGAL_GID;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = ace_sid.get_id (FALSE, &type);
|
||||
@@ -352,7 +371,7 @@ getacl (const char *file, DWORD attr, int nentries, __aclent16_t *aclbufp)
|
||||
}
|
||||
if (!type)
|
||||
continue;
|
||||
if (!(ace->Header.AceFlags & INHERIT_ONLY))
|
||||
if (!(ace->Header.AceFlags & INHERIT_ONLY || type & ACL_DEFAULT))
|
||||
{
|
||||
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
|
||||
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
|
||||
@@ -360,6 +379,10 @@ getacl (const char *file, DWORD attr, int nentries, __aclent16_t *aclbufp)
|
||||
if ((ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
|
||||
&& (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
if (type == USER_OBJ)
|
||||
type = USER;
|
||||
else if (type == GROUP_OBJ)
|
||||
type = GROUP;
|
||||
type |= ACL_DEFAULT;
|
||||
types_def |= type;
|
||||
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
|
||||
@@ -475,45 +498,30 @@ acl_worker (const char *path, int cmd, int nentries, __aclent16_t *aclbufp,
|
||||
set_errno (ENOSYS);
|
||||
break;
|
||||
case GETACL:
|
||||
if (nentries < 1)
|
||||
set_errno (EINVAL);
|
||||
if (!aclbufp)
|
||||
set_errno(EFAULT);
|
||||
else if (nentries < MIN_ACL_ENTRIES)
|
||||
set_errno (ENOSPC);
|
||||
else if ((nofollow && !lstat64 (path, &st))
|
||||
|| (!nofollow && !stat64 (path, &st)))
|
||||
{
|
||||
__aclent16_t lacl[4];
|
||||
if (nentries > 0)
|
||||
{
|
||||
lacl[0].a_type = USER_OBJ;
|
||||
lacl[0].a_id = st.st_uid;
|
||||
lacl[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
|
||||
}
|
||||
if (nentries > 1)
|
||||
{
|
||||
lacl[1].a_type = GROUP_OBJ;
|
||||
lacl[1].a_id = st.st_gid;
|
||||
lacl[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
|
||||
}
|
||||
if (nentries > 2)
|
||||
{
|
||||
lacl[2].a_type = OTHER_OBJ;
|
||||
lacl[2].a_id = ILLEGAL_GID;
|
||||
lacl[2].a_perm = st.st_mode & S_IRWXO;
|
||||
}
|
||||
if (nentries > 3)
|
||||
{
|
||||
lacl[3].a_type = CLASS_OBJ;
|
||||
lacl[3].a_id = ILLEGAL_GID;
|
||||
lacl[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
}
|
||||
if (nentries > 4)
|
||||
nentries = 4;
|
||||
if (aclbufp)
|
||||
memcpy (aclbufp, lacl, nentries * sizeof (__aclent16_t));
|
||||
ret = nentries;
|
||||
aclbufp[0].a_type = USER_OBJ;
|
||||
aclbufp[0].a_id = st.st_uid;
|
||||
aclbufp[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
|
||||
aclbufp[1].a_type = GROUP_OBJ;
|
||||
aclbufp[1].a_id = st.st_gid;
|
||||
aclbufp[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
|
||||
aclbufp[2].a_type = OTHER_OBJ;
|
||||
aclbufp[2].a_id = ILLEGAL_GID;
|
||||
aclbufp[2].a_perm = st.st_mode & S_IRWXO;
|
||||
aclbufp[3].a_type = CLASS_OBJ;
|
||||
aclbufp[3].a_id = ILLEGAL_GID;
|
||||
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
ret = MIN_ACL_ENTRIES;
|
||||
}
|
||||
break;
|
||||
case GETACLCNT:
|
||||
ret = 4;
|
||||
ret = MIN_ACL_ENTRIES;
|
||||
break;
|
||||
}
|
||||
syscall_printf ("%d = acl (%s)", ret, path);
|
||||
@@ -527,19 +535,21 @@ acl_worker (const char *path, int cmd, int nentries, __aclent16_t *aclbufp,
|
||||
nentries, aclbufp);
|
||||
break;
|
||||
case GETACL:
|
||||
if (nentries < 1)
|
||||
break;
|
||||
return getacl (real_path.get_win32 (),
|
||||
real_path.file_attributes (),
|
||||
nentries, aclbufp);
|
||||
if (!aclbufp)
|
||||
set_errno(EFAULT);
|
||||
else
|
||||
return getacl (real_path.get_win32 (),
|
||||
real_path.file_attributes (),
|
||||
nentries, aclbufp);
|
||||
break;
|
||||
case GETACLCNT:
|
||||
return getacl (real_path.get_win32 (),
|
||||
real_path.file_attributes (),
|
||||
0, NULL);
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
break;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
syscall_printf ("-1 = acl (%s)", path);
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user