diff --git a/fuse-overlayfs.1 b/fuse-overlayfs.1 index 8c11fb1..cbf55e2 100644 --- a/fuse-overlayfs.1 +++ b/fuse-overlayfs.1 @@ -42,6 +42,11 @@ done to the file system will be written. A directory used internally by fuse\-overlays, must be on the same file system as the upper dir. +.PP +\fB\-o workdir=workdir\fP +A directory used internally by fuse\-overlays, must be on the same file +system as the upper dir. + .PP \fB\-o uidmapping=UID:MAPPED\-UID:LEN[,UID2:MAPPED\-UID2:LEN2]\fP \fB\-o gidmapping=GID:MAPPED\-GID:LEN[,GID2:MAPPED\-GID2:LEN2]\fP @@ -99,6 +104,18 @@ $ stat \-c %u:%g merged/a merged/b .PP Those are the same IDs visible from outside the user namespace. +.PP +\fB\-o squash\_to\_root\fP +Every file and directory is owned by the root user (0:0). + +.PP +\fB\-o squash\_to\_uid=uid\fP +\fB\-o squash\_to\_gid=gid\fP +Every file and directory is owned by the specified uid or gid. + +.PP +It has higher precedence over \fBsquash\_to\_root\fP\&. + .SH SEE ALSO .PP diff --git a/fuse-overlayfs.1.md b/fuse-overlayfs.1.md index b418de8..61b8418 100644 --- a/fuse-overlayfs.1.md +++ b/fuse-overlayfs.1.md @@ -84,6 +84,15 @@ $ stat -c %u:%g merged/a merged/b Those are the same IDs visible from outside the user namespace. +**-o squash_to_root** +Every file and directory is owned by the root user (0:0). + +**-o squash_to_uid=uid** +**-o squash_to_gid=gid** +Every file and directory is owned by the specified uid or gid. + +It has higher precedence over **squash_to_root**. + # SEE ALSO **fuse**(8), **mount**(8), **user_namespaces**(7) diff --git a/fuse-overlayfs.h b/fuse-overlayfs.h index f43dfc0..83d5697 100644 --- a/fuse-overlayfs.h +++ b/fuse-overlayfs.h @@ -97,6 +97,8 @@ struct ovl_data int disable_xattrs; int xattr_permissions; int squash_to_root; + int squash_to_uid; + int squash_to_gid; /* current uid/gid*/ uid_t uid; diff --git a/main.c b/main.c index 03f57c9..cca4516 100644 --- a/main.c +++ b/main.c @@ -221,6 +221,10 @@ static const struct fuse_opt ovl_opts[] = { offsetof (struct ovl_data, xattr_permissions), 0}, {"squash_to_root", offsetof (struct ovl_data, squash_to_root), 1}, + {"squash_to_uid=%d", + offsetof (struct ovl_data, squash_to_uid), 1}, + {"squash_to_gid=%d", + offsetof (struct ovl_data, squash_to_gid), 1}, {"volatile", /* native overlay supports "volatile" to mean fsync=0. */ offsetof (struct ovl_data, fsync), 0}, FUSE_OPT_END @@ -535,7 +539,7 @@ do_fchown (struct ovl_data *lo, int fd, uid_t uid, gid_t gid, mode_t mode) ret = write_permission_xattr (lo, fd, NULL, uid, gid, mode); else ret = fchown (fd, uid, gid); - return (lo->squash_to_root ? 0 : ret); + return (lo->squash_to_root || lo->squash_to_uid != -1 || lo->squash_to_gid != -1) ? 0 : ret; } /* Make sure it is not used anymore. */ #define fchown ERROR @@ -548,7 +552,7 @@ do_chown (struct ovl_data *lo, const char *path, uid_t uid, gid_t gid, mode_t mo ret = write_permission_xattr (lo, -1, path, uid, gid, mode); else ret = chown (path, uid, gid); - return (lo->squash_to_root ? 0 : ret); + return (lo->squash_to_root || lo->squash_to_uid != -1 || lo->squash_to_gid != -1) ? 0 : ret; } /* Make sure it is not used anymore. */ #define chown ERROR @@ -569,7 +573,7 @@ do_fchownat (struct ovl_data *lo, int dfd, const char *path, uid_t uid, gid_t gi } else ret = fchownat (dfd, path, uid, gid, flags); - return (lo->squash_to_root ? 0 : ret); + return (lo->squash_to_root || lo->squash_to_uid != -1 || lo->squash_to_gid != -1) ? 0 : ret; } /* Make sure it is not used anymore. */ #define fchownat ERROR @@ -812,6 +816,10 @@ find_mapping (unsigned int id, const struct ovl_data *data, const struct ovl_mapping *mapping = (uid ? data->uid_mappings : data->gid_mappings); + if (direct && uid && data->squash_to_uid != -1) + return data->squash_to_uid; + if (direct && !uid && data->squash_to_gid != -1) + return data->squash_to_gid; if (direct && data->squash_to_root) return 0; @@ -5424,6 +5432,8 @@ main (int argc, char *argv[]) .redirect_dir = NULL, .mountpoint = NULL, .fsync = 1, + .squash_to_uid = -1, + .squash_to_gid = -1, .xattr_permissions = 0, .timeout = 1000000000.0, .timeout_str = NULL,