Skip to content

Commit

Permalink
Honor setgit bit on directories
Browse files Browse the repository at this point in the history
Newly created files were always being created with the fsuid/fsgid
in the current users credentials.  This is correct except in the
case when the parent directory sets the 'setgit' bit.  In this
case according to posix the newly created file/directory should
inherit the gid of the parent directory.  Additionally, in the
case of a subdirectory it should also inherit the 'setgit' bit.

Finally, this commit performs a little cleanup of the vattr_t
initialization by moving it to a common helper function.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #262
  • Loading branch information
behlendorf committed Jul 20, 2011
1 parent fe0ed8f commit 9fd91da
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions module/zfs/zpl_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
return d_splice_alias(ip, dentry);
}

static void
zpl_vap_init(vattr_t *vap, struct inode *dir, struct dentry *dentry,
mode_t mode, cred_t *cr)
{
vap->va_mask = ATTR_MODE;
vap->va_mode = mode;
vap->va_dentry = dentry;
vap->va_uid = crgetfsuid(cr);

if (dir && dir->i_mode & S_ISGID) {
vap->va_gid = dir->i_gid;
if (S_ISDIR(mode))
vap->va_mode |= S_ISGID;
} else {
vap->va_gid = crgetfsgid(cr);
}
}

static int
zpl_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
Expand All @@ -62,11 +80,7 @@ zpl_create(struct inode *dir, struct dentry *dentry, int mode,

crhold(cr);
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
vap->va_mode = mode;
vap->va_mask = ATTR_MODE;
vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr);
vap->va_dentry = dentry;
zpl_vap_init(vap, dir, dentry, mode, cr);

error = -zfs_create(dir, (char *)dentry->d_name.name,
vap, 0, mode, &ip, cr, 0, NULL);
Expand Down Expand Up @@ -94,12 +108,8 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)

crhold(cr);
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
vap->va_mode = mode;
vap->va_mask = ATTR_MODE;
zpl_vap_init(vap, dir, dentry, mode, cr);
vap->va_rdev = rdev;
vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr);
vap->va_dentry = dentry;

error = -zfs_create(dir, (char *)dentry->d_name.name,
vap, 0, mode, &ip, cr, 0, NULL);
Expand Down Expand Up @@ -134,11 +144,7 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode)

crhold(cr);
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
vap->va_mode = S_IFDIR | mode;
vap->va_mask = ATTR_MODE;
vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr);
vap->va_dentry = dentry;
zpl_vap_init(vap, dir, dentry, mode | S_IFDIR, cr);

error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
kmem_free(vap, sizeof(vattr_t));
Expand Down Expand Up @@ -229,11 +235,7 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)

crhold(cr);
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
vap->va_mode = S_IFLNK | S_IRWXUGO;
vap->va_mask = ATTR_MODE;
vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr);
vap->va_dentry = dentry;
zpl_vap_init(vap, dir, dentry, S_IFLNK | S_IRWXUGO, cr);

error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
kmem_free(vap, sizeof(vattr_t));
Expand Down

0 comments on commit 9fd91da

Please sign in to comment.