Honor setgit bit on directories
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
This commit is contained in:
parent
fe0ed8f910
commit
9fd91daeef
|
@ -51,6 +51,24 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||||
return d_splice_alias(ip, dentry);
|
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
|
static int
|
||||||
zpl_create(struct inode *dir, struct dentry *dentry, int mode,
|
zpl_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||||
struct nameidata *nd)
|
struct nameidata *nd)
|
||||||
|
@ -62,11 +80,7 @@ zpl_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
||||||
vap->va_mode = mode;
|
zpl_vap_init(vap, dir, dentry, mode, cr);
|
||||||
vap->va_mask = ATTR_MODE;
|
|
||||||
vap->va_uid = crgetfsuid(cr);
|
|
||||||
vap->va_gid = crgetfsgid(cr);
|
|
||||||
vap->va_dentry = dentry;
|
|
||||||
|
|
||||||
error = -zfs_create(dir, (char *)dentry->d_name.name,
|
error = -zfs_create(dir, (char *)dentry->d_name.name,
|
||||||
vap, 0, mode, &ip, cr, 0, NULL);
|
vap, 0, mode, &ip, cr, 0, NULL);
|
||||||
|
@ -94,12 +108,8 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
||||||
vap->va_mode = mode;
|
zpl_vap_init(vap, dir, dentry, mode, cr);
|
||||||
vap->va_mask = ATTR_MODE;
|
|
||||||
vap->va_rdev = rdev;
|
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,
|
error = -zfs_create(dir, (char *)dentry->d_name.name,
|
||||||
vap, 0, mode, &ip, cr, 0, NULL);
|
vap, 0, mode, &ip, cr, 0, NULL);
|
||||||
|
@ -134,11 +144,7 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
||||||
vap->va_mode = S_IFDIR | mode;
|
zpl_vap_init(vap, dir, dentry, mode | S_IFDIR, cr);
|
||||||
vap->va_mask = ATTR_MODE;
|
|
||||||
vap->va_uid = crgetfsuid(cr);
|
|
||||||
vap->va_gid = crgetfsgid(cr);
|
|
||||||
vap->va_dentry = dentry;
|
|
||||||
|
|
||||||
error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
|
error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
|
||||||
kmem_free(vap, sizeof(vattr_t));
|
kmem_free(vap, sizeof(vattr_t));
|
||||||
|
@ -229,11 +235,7 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
|
||||||
vap->va_mode = S_IFLNK | S_IRWXUGO;
|
zpl_vap_init(vap, dir, dentry, S_IFLNK | S_IRWXUGO, cr);
|
||||||
vap->va_mask = ATTR_MODE;
|
|
||||||
vap->va_uid = crgetfsuid(cr);
|
|
||||||
vap->va_gid = crgetfsgid(cr);
|
|
||||||
vap->va_dentry = dentry;
|
|
||||||
|
|
||||||
error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
|
error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
|
||||||
kmem_free(vap, sizeof(vattr_t));
|
kmem_free(vap, sizeof(vattr_t));
|
||||||
|
|
Loading…
Reference in New Issue