Skip to content

Commit

Permalink
Windows: Support idmapped mount
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Innes <[email protected]>
  • Loading branch information
andrewc12 committed Nov 9, 2022
1 parent 35a5f83 commit b2d4c6e
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 54 deletions.
1 change: 1 addition & 0 deletions include/os/windows/spl/sys/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef uint64_t ino64_t;

typedef unsigned char uuid_t[16];

typedef void zuserns_t;

// clang spits out "atomics are disabled" - change code to use atomic() calls.
// #define _Atomic
Expand Down
13 changes: 8 additions & 5 deletions include/os/windows/zfs/sys/zfs_vnops_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,23 @@ extern "C" {

extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags);
extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp,
zuserns_t *mnt_ns);
extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
cred_t *cr, int flags);
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
zuserns_t *mnt_ns);
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
char *tnm, cred_t *cr, int flags);
char *tnm, cred_t *cr, int flags, zuserns_t *mnt_ns);
extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
char *link, znode_t **zpp, cred_t *cr, int flags);
char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
extern int zfs_link(znode_t *tdzp, znode_t *sp,
char *name, cred_t *cr, int flags);
extern int zfs_space(znode_t *zp, int cmd, struct flock *bfp, int flag,
offset_t offset, cred_t *cr);
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
zuserns_t *mnt_ns);
extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag,
cred_t *cr);
extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
Expand Down
30 changes: 17 additions & 13 deletions module/os/windows/zfs/zfs_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1663,7 +1663,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, zfs_acl_t *paclp,
*/
int
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
{
int error;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
Expand Down Expand Up @@ -2126,7 +2126,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if (zp->z_pflags & ZFS_IMMUTABLE)
return (SET_ERROR(EPERM));

if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL)))
return (error);

error = zfs_vsec_2_aclp(zfsvfs, vnode_vtype(ZTOV(zp)), vsecp, cr,
Expand Down Expand Up @@ -2547,7 +2547,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
DTRACE_PROBE(zfs__fastpath__execute__access__miss);
if ((error = zfs_enter(zdp->z_zfsvfs, FTAG)) != 0)
return (error);
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL);
zfs_exit(zdp->z_zfsvfs, FTAG);
return (error);
}
Expand All @@ -2559,7 +2559,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
* can define any form of access.
*/
int
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
zuserns_t *mnt_ns)
{
uint32_t working_mode;
int error;
Expand Down Expand Up @@ -2737,9 +2738,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
* native ACL format and call zfs_zaccess()
*/
int
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
zuserns_t *mnt_ns)
{
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
NULL));
}

/*
Expand All @@ -2750,7 +2753,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
{
int v4_mode = zfs_unix_to_v4(mode >> 6);

return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL));
}

/* See zfs_zaccess_delete() */
Expand Down Expand Up @@ -2827,7 +2830,7 @@ uint64_t zfs_write_implies_delete_child = 1;
* zfs_write_implies_delete_child
*/
int
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
{
uint32_t wanted_dirperms;
uint32_t dzp_working_mode = 0;
Expand Down Expand Up @@ -2955,7 +2958,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)

int
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
znode_t *tzp, cred_t *cr)
znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
{
int add_perm;
int error;
Expand All @@ -2975,7 +2978,8 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
* to another.
*/
if (vnode_isdir(ZTOV(szp)) && ZTOV(sdzp) != ZTOV(tdzp)) {
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr)))
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr,
NULL)))
return (error);
}

Expand All @@ -2985,21 +2989,21 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
* If that succeeds then check for add_file/add_subdir permissions
*/

if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
return (error);

/*
* If we have a tzp, see if we can delete it?
*/
if (tzp) {
if ((error = zfs_zaccess_delete(tdzp, tzp, cr)))
if ((error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
return (error);
}

/*
* Now check for add permissions
*/
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, NULL);

return (error);
}
7 changes: 4 additions & 3 deletions module/os/windows/zfs/zfs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,11 +1044,12 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)

*xzpp = NULL;

if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr,
NULL)))
return (error);

if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
&acl_ids)) != 0)
&acl_ids, NULL)) != 0)
return (error);
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zp->z_projid)) {
zfs_acl_ids_free(&acl_ids);
Expand Down Expand Up @@ -1200,7 +1201,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)

if ((uid = crgetuid(cr)) == downer || uid == fowner ||
(vnode_isreg(ZTOV(zp)) &&
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0))
return (0);
else
return (secpolicy_vnode_remove(ZTOV(zp), cr));
Expand Down
49 changes: 27 additions & 22 deletions module/os/windows/zfs/zfs_vnops_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags,
* Check accessibility of directory.
*/

if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand Down Expand Up @@ -419,7 +419,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags,

int
zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
zuserns_t *mnt_ns)
{
znode_t *zp = NULL;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
Expand Down Expand Up @@ -506,7 +507,8 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
* Create a new file object and update the directory
* to reference it.
*/
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr,
NULL))) {
if (have_acl)
zfs_acl_ids_free(&acl_ids);
goto out;
Expand All @@ -525,7 +527,7 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
}

if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
cr, vsecp, &acl_ids)) != 0)
cr, vsecp, &acl_ids, NULL)) != 0)
goto out;
have_acl = B_TRUE;

Expand Down Expand Up @@ -637,7 +639,8 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
/*
* Verify requested access to file.
*/
if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr))) {
if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr,
NULL))) {
goto out;
}

Expand Down Expand Up @@ -746,7 +749,7 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags)
return (error);
}

if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
goto out;
}

Expand Down Expand Up @@ -932,7 +935,7 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags)
*/
int
zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
cred_t *cr, int flags, vsecattr_t *vsecp)
cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns)
{
znode_t *zp;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
Expand Down Expand Up @@ -989,7 +992,7 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
}

if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
vsecp, &acl_ids)) != 0) {
vsecp, &acl_ids, NULL)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand All @@ -1010,7 +1013,8 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
return (error);
}

if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
NULL))) {
zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl);
zfs_exit(zfsvfs, FTAG);
Expand Down Expand Up @@ -1153,7 +1157,7 @@ zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr,
return (error);
}

if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
goto out;
}

Expand Down Expand Up @@ -2065,7 +2069,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) &&
(vap->va_uid != crgetuid(cr))) {
if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0,
skipaclchk, cr))) {
skipaclchk, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand Down Expand Up @@ -2229,7 +2233,7 @@ void kx_qsort(void* array, size_t nm, size_t member_size,
* vp - ctime updated, mtime updated if size changed.
*/
int
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns)
{
vnode_t *vp = ZTOV(zp);
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
Expand Down Expand Up @@ -2401,7 +2405,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
skipaclchk, cr);
skipaclchk, cr, NULL);
}

if (mask & (ATTR_UID|ATTR_GID)) {
Expand Down Expand Up @@ -2439,7 +2443,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
((idmask == ATTR_UID) && take_owner) ||
((idmask == ATTR_GID) && take_group)) {
if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
skipaclchk, cr) == 0) {
skipaclchk, cr, NULL) == 0) {
/*
* Remove setuid/setgid for non-privileged users
*/
Expand Down Expand Up @@ -2548,7 +2552,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
}

if (mask & ATTR_MODE) {
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
NULL) == 0) {
err = secpolicy_setid_setsticky_clear(vp, vap,
&oldva, cr);
if (err) {
Expand Down Expand Up @@ -3062,7 +3067,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
*/
int
zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
cred_t *cr, int flags)
cred_t *cr, int flags, zuserns_t *mnt_ns)
{
znode_t *szp, *tzp;
zfsvfs_t *zfsvfs = ZTOZSB(sdzp);
Expand Down Expand Up @@ -3257,7 +3262,7 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
* done in a single check.
*/

if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, NULL)))
goto out;

if (S_ISDIR(szp->z_mode)) {
Expand Down Expand Up @@ -3440,7 +3445,7 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
*/
int
zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
znode_t **zpp, cred_t *cr, int flags)
znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns)
{
znode_t *zp;
zfs_dirlock_t *dl;
Expand Down Expand Up @@ -3478,7 +3483,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
}

if ((error = zfs_acl_ids_create(dzp, 0,
vap, cr, NULL, &acl_ids)) != 0) {
vap, cr, NULL, &acl_ids, NULL)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand All @@ -3495,7 +3500,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
return (error);
}

if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) {
zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl);
zfs_exit(zfsvfs, FTAG);
Expand Down Expand Up @@ -3742,7 +3747,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
return (SET_ERROR(EPERM));
}

if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand Down Expand Up @@ -3907,7 +3912,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
* On Linux we can get here through truncate_range() which
* operates directly on inodes, so we need to check access rights.
*/
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
Expand Down
Loading

0 comments on commit b2d4c6e

Please sign in to comment.