From 0f8ef123ea06360476876852c3d0ec8d63254912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 18 Jun 2012 12:53:25 +0200 Subject: [PATCH] Added inheritance of the set-group-id flag So far the set-group-id flag could be set in a chmod. This patch enables the inheritance of the group to files and subdirectories, and the inheritance of the set-group-id flag to subdirectories. --- include/ntfs-3g/security.h | 2 ++ libntfs-3g/security.c | 54 ++++++++++++++++++++++++++++++++++++-- src/lowntfs-3g.c | 18 ++++++++----- src/ntfs-3g.c | 18 ++++++++----- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/include/ntfs-3g/security.h b/include/ntfs-3g/security.h index 9d7dd331..8875c9c1 100644 --- a/include/ntfs-3g/security.h +++ b/include/ntfs-3g/security.h @@ -255,6 +255,8 @@ int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode); BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni); int ntfs_allowed_access(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, int accesstype); +int ntfs_allowed_create(struct SECURITY_CONTEXT *scx, + ntfs_inode *ni, gid_t *pgid, mode_t *pdsetgid); BOOL old_ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx, const char *path, int accesstype); diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index a78663ba..4f2865b7 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -1876,7 +1876,7 @@ static int access_check_posix(struct SECURITY_CONTEXT *scx, if (!scx->uid) { /* root access if owner or other execution */ if (perms & 0101) - perms = 07777; + perms |= 01777; else { /* root access if some group execution */ groupperms = 0; @@ -2292,7 +2292,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx, if (!scx->uid) { /* root access and execution */ if (perm & 0111) - perm = 07777; + perm |= 01777; else perm = 0; } else @@ -3395,6 +3395,56 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx, return (allow); } +/* + * Check whether user can create a file (or directory) + * + * Returns TRUE if access is allowed, + * Also returns the gid and dsetgid applicable to the created file + */ + +int ntfs_allowed_create(struct SECURITY_CONTEXT *scx, + ntfs_inode *dir_ni, gid_t *pgid, mode_t *pdsetgid) +{ + int perm; + int res; + int allow; + struct stat stbuf; + + /* + * Always allow for root. + * Also always allow if no mapping has been defined + */ + if (!scx->mapping[MAPUSERS]) + perm = 0777; + else + perm = ntfs_get_perm(scx, dir_ni, S_IWRITE + S_IEXEC); + if (!scx->mapping[MAPUSERS] + || !scx->uid) { + allow = 1; + } else { + perm = ntfs_get_perm(scx, dir_ni, S_IWRITE + S_IEXEC); + if (perm >= 0) { + res = EACCES; + allow = ((perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) + && ((perm & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0); + if (!allow) + errno = res; + } else + allow = 0; + } + *pgid = scx->gid; + *pdsetgid = 0; + /* return directory group if S_ISGID is set */ + if (allow && (perm & S_ISGID)) { + if (ntfs_get_owner_mode(scx, dir_ni, &stbuf) >= 0) { + *pdsetgid = stbuf.st_mode & S_ISGID; + if (perm & S_ISGID) + *pgid = stbuf.st_gid; + } + } + return (allow); +} + #if 0 /* not needed any more */ /* diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 7a80e36b..0c9af18c 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -1820,6 +1820,8 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name, struct open_file *of; int state = 0; le32 securid; + gid_t gid; + mode_t dsetgid; mode_t type = typemode & ~07777; mode_t perm; struct SECURITY_CONTEXT security; @@ -1842,13 +1844,15 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name, #if !KERNELPERMS | (POSIXACLS & !KERNELACLS) /* make sure parent directory is writeable and executable */ if (!ntfs_fuse_fill_security_context(req, &security) - || ntfs_allowed_access(&security, - dir_ni,S_IWRITE + S_IEXEC)) { + || ntfs_allowed_create(&security, + dir_ni, &gid, &dsetgid)) { #else ntfs_fuse_fill_security_context(req, &security); + ntfs_allowed_create(&security, dir_ni, &gid, &dsetgid); #endif if (S_ISDIR(type)) - perm = typemode & ~ctx->dmask & 0777; + perm = (typemode & ~ctx->dmask & 0777) + | (dsetgid & S_ISGID); else perm = typemode & ~ctx->fmask & 0777; /* @@ -1866,11 +1870,11 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name, else #if POSIXACLS securid = ntfs_alloc_securid(&security, - security.uid, security.gid, + security.uid, gid, dir_ni, perm, S_ISDIR(type)); #else securid = ntfs_alloc_securid(&security, - security.uid, security.gid, + security.uid, gid, perm & ~security.umask, S_ISDIR(type)); #endif /* Create object specified in @type. */ @@ -1904,13 +1908,13 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name, #if POSIXACLS if (!securid && ntfs_set_inherited_posix(&security, ni, - security.uid, security.gid, + security.uid, gid, dir_ni, perm) < 0) set_fuse_error(&res); #else if (!securid && ntfs_set_owner_mode(&security, ni, - security.uid, security.gid, + security.uid, gid, perm & ~security.umask) < 0) set_fuse_error(&res); #endif diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 1418bb83..d6974a96 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -1598,6 +1598,8 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev, char *dir_path; le32 securid; char *path; + gid_t gid; + mode_t dsetgid; ntfschar *stream_name; int stream_name_len; mode_t type = typemode & ~07777; @@ -1636,13 +1638,15 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev, #if !KERNELPERMS | (POSIXACLS & !KERNELACLS) /* make sure parent directory is writeable and executable */ if (!ntfs_fuse_fill_security_context(&security) - || ntfs_allowed_access(&security, - dir_ni,S_IWRITE + S_IEXEC)) { + || ntfs_allowed_create(&security, + dir_ni, &gid, &dsetgid)) { #else ntfs_fuse_fill_security_context(&security); + ntfs_allowed_create(&security, dir_ni, &gid, &dsetgid); #endif if (S_ISDIR(type)) - perm = typemode & ~ctx->dmask & 0777; + perm = (typemode & ~ctx->dmask & 0777) + | (dsetgid & S_ISGID); else perm = typemode & ~ctx->fmask & 0777; /* @@ -1660,11 +1664,11 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev, else #if POSIXACLS securid = ntfs_alloc_securid(&security, - security.uid, security.gid, + security.uid, gid, dir_ni, perm, S_ISDIR(type)); #else securid = ntfs_alloc_securid(&security, - security.uid, security.gid, + security.uid, gid, perm & ~security.umask, S_ISDIR(type)); #endif /* Create object specified in @type. */ @@ -1698,13 +1702,13 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev, #if POSIXACLS if (!securid && ntfs_set_inherited_posix(&security, ni, - security.uid, security.gid, + security.uid, gid, dir_ni, perm) < 0) set_fuse_error(&res); #else if (!securid && ntfs_set_owner_mode(&security, ni, - security.uid, security.gid, + security.uid, gid, perm & ~security.umask) < 0) set_fuse_error(&res); #endif