From ab8f021861ead31afaf376abb5ac7b466c3537ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 23 Jun 2014 11:26:00 +0200 Subject: [PATCH] Fixed checking permissions when Posix ACLs are compiled in but not enabled When the Posix ACLs are not enabled in the mount options, the permission checks should not take into account the extra owners and groups of the file. --- libntfs-3g/acls.c | 10 +++- libntfs-3g/security.c | 104 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c index 422e75b9..dad91420 100644 --- a/libntfs-3g/acls.c +++ b/libntfs-3g/acls.c @@ -4478,7 +4478,15 @@ struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem) if (mapping) { mapping->sid = sid; mapping->xid = gid; - mapping->grcnt = 0; + /* special groups point to themselves */ + if (ntfs_known_group_sid(sid)) { + mapping->groups = + (gid_t*)&mapping->xid; + mapping->grcnt = 1; + } else + mapping->grcnt = 0; + + mapping->next = (struct MAPPING*)NULL; if (lastmapping) lastmapping->next = mapping; diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index 11b74601..f431a017 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -1340,6 +1340,48 @@ static BOOL groupmember(struct SECURITY_CONTEXT *scx, uid_t uid, gid_t gid) #endif /* defined(__sun) && defined (__SVR4) */ +#if POSIXACLS + +/* + * Extract the basic permissions from a Posix ACL + * + * This is only to be used when Posix ACLs are compiled in, + * but not enabled in the mount options. + * + * it replaces the permission mask by the group permissions. + * If special groups are mapped, they are also considered as world. + */ + +static int ntfs_basic_perms(const struct SECURITY_CONTEXT *scx, + const struct POSIX_SECURITY *pxdesc) +{ + int k; + int perms; + const struct POSIX_ACE *pace; + const struct MAPPING* group; + + k = 0; + perms = pxdesc->mode; + for (k=0; k < pxdesc->acccnt; k++) { + pace = &pxdesc->acl.ace[k]; + if (pace->tag == POSIX_ACL_GROUP_OBJ) + perms = (perms & 07707) + | ((pace->perms & 7) << 3); + else + if (pace->tag == POSIX_ACL_GROUP) { + group = scx->mapping[MAPGROUPS]; + while (group && (group->xid != pace->id)) + group = group->next; + if (group && group->grcnt + && (*(group->groups) == (gid_t)pace->id)) + perms |= pace->perms & 7; + } + } + return (perms); +} + +#endif /* POSIXACLS */ + /* * Cacheing is done two-way : * - from uid, gid and perm to securid (CACHED_SECURID) @@ -1883,7 +1925,9 @@ static char *getsecurityattr(ntfs_volume *vol, ntfs_inode *ni) * Determine which access types to a file are allowed * according to the relation of current process to the file * - * Do not call if default_permissions is set + * When Posix ACLs are compiled in but not enabled in the mount + * options POSIX_ACL_USER, POSIX_ACL_GROUP and POSIX_ACL_MASK + * are ignored. */ static int access_check_posix(struct SECURITY_CONTEXT *scx, @@ -1896,10 +1940,15 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, int mask; BOOL somegroup; BOOL needgroups; + BOOL noacl; mode_t perms; int i; - perms = pxdesc->mode; + noacl = !(scx->vol->secure_flags & (1 << SECURITY_ACL)); + if (noacl) + perms = ntfs_basic_perms(scx, pxdesc); + else + perms = pxdesc->mode; /* owner and root access */ if (!scx->uid || (uid == scx->uid)) { if (!scx->uid) { @@ -1915,11 +1964,16 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, switch (pxace->tag) { case POSIX_ACL_USER_OBJ : case POSIX_ACL_GROUP_OBJ : - case POSIX_ACL_GROUP : groupperms |= pxace->perms; break; + case POSIX_ACL_GROUP : + if (!noacl) + groupperms + |= pxace->perms; + break; case POSIX_ACL_MASK : - mask = pxace->perms & 7; + if (!noacl) + mask = pxace->perms & 7; break; default : break; @@ -1946,18 +2000,25 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, pxace = &pxdesc->acl.ace[i]; switch (pxace->tag) { case POSIX_ACL_USER : - if ((uid_t)pxace->id == scx->uid) + if (!noacl + && ((uid_t)pxace->id == scx->uid)) userperms = pxace->perms; break; case POSIX_ACL_MASK : - mask = pxace->perms & 7; + if (!noacl) + mask = pxace->perms & 7; break; case POSIX_ACL_GROUP_OBJ : - case POSIX_ACL_GROUP : if (((pxace->perms & mask) ^ perms) & (request >> 6) & 7) needgroups = TRUE; break; + case POSIX_ACL_GROUP : + if (!noacl + && (((pxace->perms & mask) ^ perms) + & (request >> 6) & 7)) + needgroups = TRUE; + break; default : break; } @@ -1973,7 +2034,7 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, && ((gid == scx->gid) || groupmember(scx, scx->uid, gid))) perms &= 07070; - else { + else if (!noacl) { /* other groups */ groupperms = -1; somegroup = FALSE; @@ -1993,7 +2054,8 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, perms = 0; else perms &= 07007; - } + } else + perms &= 07007; } } return (perms); @@ -2398,7 +2460,13 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx, /* check whether available in cache */ cached = fetch_cache(scx,ni); if (cached) { - perm = cached->mode; +#if POSIXACLS + if (!(scx->vol->secure_flags & (1 << SECURITY_ACL)) + && cached->pxdesc) + perm = ntfs_basic_perms(scx,cached->pxdesc); + else +#endif + perm = cached->mode; stbuf->st_uid = cached->uid; stbuf->st_gid = cached->gid; stbuf->st_mode = (stbuf->st_mode & ~07777) + perm; @@ -2420,11 +2488,17 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx, securattr[le32_to_cpu(phead->owner)]; #endif #if POSIXACLS - pxdesc = ntfs_build_permissions_posix(scx->mapping, securattr, - usid, gsid, isdir); - if (pxdesc) - perm = pxdesc->mode & 07777; - else + pxdesc = ntfs_build_permissions_posix( + scx->mapping, securattr, + usid, gsid, isdir); + if (pxdesc) { + if (!(scx->vol->secure_flags + & (1 << SECURITY_ACL))) + perm = ntfs_basic_perms(scx, + pxdesc); + else + perm = pxdesc->mode & 07777; + } else perm = -1; #else perm = ntfs_build_permissions(securattr,