aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicardo Branco <rbranco@suse.de>2024-01-08 20:24:53 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-01-12 22:51:31 +0000
commit82f2275b73e556580b155ea9bbf7f7e364458fa1 (patch)
treeab58d288b07924706d281dbd0d2f109c0717ecb7
parentbc1eea0c0b0ad0a39b5b22b89341b4af1f0cd21f (diff)
downloadsrc-82f2275b73e556580b155ea9bbf7f7e364458fa1.tar.gz
src-82f2275b73e556580b155ea9bbf7f7e364458fa1.zip
cd9660: Add support for mask,dirmask,uid,gid options
Reviewed by: jhb Pull Request: https://github.com/freebsd/freebsd-src/pull/982
-rw-r--r--sbin/mount_cd9660/mount_cd9660.837
-rw-r--r--sbin/mount_cd9660/mount_cd9660.c79
-rw-r--r--sys/fs/cd9660/cd9660_mount.h7
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c23
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c24
-rw-r--r--sys/fs/cd9660/iso.h5
6 files changed, 167 insertions, 8 deletions
diff --git a/sbin/mount_cd9660/mount_cd9660.8 b/sbin/mount_cd9660/mount_cd9660.8
index cd6f7a19f6eb..d2cdd2f3ef20 100644
--- a/sbin/mount_cd9660/mount_cd9660.8
+++ b/sbin/mount_cd9660/mount_cd9660.8
@@ -29,7 +29,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 11, 2018
+.Dd January 2, 2024
.Dt MOUNT_CD9660 8
.Os
.Sh NAME
@@ -39,8 +39,12 @@
.Nm
.Op Fl begjrv
.Op Fl C Ar charset
+.Op Fl G Ar gid
+.Op Fl m Ar mask
+.Op Fl M Ar mask
.Op Fl o Ar options
.Op Fl s Ar startsector
+.Op Fl U Ar uid
.Ar special node
.Sh DESCRIPTION
The
@@ -66,6 +70,37 @@ Do not strip version numbers on files.
only the last one will be listed.)
In either case, files may be opened without explicitly stating a
version number.
+.It Fl G Ar group
+Set the group of the files in the file system to
+.Ar group .
+The default gid on non-Rockridge volumes is zero.
+.It Fl U Ar user
+Set the owner of the files in the file system to
+.Ar user .
+The default uid on non-Rockridge volumes is zero.
+.It Fl m Ar mask
+Specify the maximum file permissions for files
+in the file system.
+(For example, a
+.Ar mask
+of
+.Li 755
+specifies that, by default, the owner should have
+read, write, and execute permissions for files, but
+others should only have read and execute permissions).
+See
+.Xr chmod 1
+for more information about octal file modes.
+Only the nine low-order bits of
+.Ar mask
+are used.
+The default
+.Ar mask
+on non-Rockridge volumes is 755.
+.It Fl M Ar mask
+Specify the maximum file permissions for directories
+in the file system.
+See the previous option's description for details.
.It Fl j
Do not use any Joliet extensions included in the file system.
.It Fl o
diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c
index ab6da7271c17..d8d64eb5a656 100644
--- a/sbin/mount_cd9660/mount_cd9660.c
+++ b/sbin/mount_cd9660/mount_cd9660.c
@@ -44,8 +44,11 @@
#include <arpa/inet.h>
+#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -60,6 +63,9 @@ static struct mntopt mopts[] = {
MOPT_END
};
+static gid_t a_gid(const char *);
+static uid_t a_uid(const char *);
+static mode_t a_mask(const char *);
static int get_ssector(const char *dev);
static int set_charset(struct iovec **, int *iovlen, const char *);
void usage(void);
@@ -80,7 +86,7 @@ main(int argc, char **argv)
mntflags = verbose = 0;
ssector = -1;
- while ((ch = getopt(argc, argv, "begjo:rs:vC:")) != -1)
+ while ((ch = getopt(argc, argv, "begG:jm:M:o:rs:U:vC:")) != -1)
switch (ch) {
case 'b':
build_iovec(&iov, &iovlen, "brokenjoliet", NULL, (size_t)-1);
@@ -91,6 +97,15 @@ main(int argc, char **argv)
case 'g':
build_iovec(&iov, &iovlen, "gens", NULL, (size_t)-1);
break;
+ case 'G':
+ build_iovec_argf(&iov, &iovlen, "gid", "%d", a_gid(optarg));
+ break;
+ case 'm':
+ build_iovec_argf(&iov, &iovlen, "mask", "%u", a_mask(optarg));
+ break;
+ case 'M':
+ build_iovec_argf(&iov, &iovlen, "dirmask", "%u", a_mask(optarg));
+ break;
case 'j':
build_iovec(&iov, &iovlen, "nojoliet", NULL, (size_t)-1);
break;
@@ -110,6 +125,9 @@ main(int argc, char **argv)
case 's':
ssector = atoi(optarg);
break;
+ case 'U':
+ build_iovec_argf(&iov, &iovlen, "uid", "%d", a_uid(optarg));
+ break;
case 'v':
verbose++;
break;
@@ -173,8 +191,8 @@ void
usage(void)
{
(void)fprintf(stderr,
-"usage: mount_cd9660 [-begjrv] [-C charset] [-o options] [-s startsector]\n"
-" special node\n");
+"usage: mount_cd9660 [-begjrv] [-C charset] [-G gid] [-m mask] [-M mask]\n"
+" [-o options] [-U uid] [-s startsector] special node\n");
exit(EX_USAGE);
}
@@ -254,3 +272,58 @@ set_charset(struct iovec **iov, int *iovlen, const char *localcs)
return (0);
}
+
+static gid_t
+a_gid(const char *s)
+{
+ struct group *gr;
+ const char *gname;
+ gid_t gid;
+
+ if ((gr = getgrnam(s)) != NULL)
+ gid = gr->gr_gid;
+ else {
+ for (gname = s; *s && isdigit(*s); ++s);
+ if (!*s)
+ gid = atoi(gname);
+ else
+ errx(EX_NOUSER, "unknown group id: %s", gname);
+ }
+ return (gid);
+}
+
+static uid_t
+a_uid(const char *s)
+{
+ struct passwd *pw;
+ const char *uname;
+ uid_t uid;
+
+ if ((pw = getpwnam(s)) != NULL)
+ uid = pw->pw_uid;
+ else {
+ for (uname = s; *s && isdigit(*s); ++s);
+ if (!*s)
+ uid = atoi(uname);
+ else
+ errx(EX_NOUSER, "unknown user id: %s", uname);
+ }
+ return (uid);
+}
+
+static mode_t
+a_mask(const char *s)
+{
+ int done, rv;
+ char *ep;
+
+ done = 0;
+ rv = -1;
+ if (*s >= '0' && *s <= '7') {
+ done = 1;
+ rv = strtol(optarg, &ep, 8);
+ }
+ if (!done || rv < 0 || *ep)
+ errx(EX_USAGE, "invalid file mode: %s", s);
+ return (rv);
+}
diff --git a/sys/fs/cd9660/cd9660_mount.h b/sys/fs/cd9660/cd9660_mount.h
index 88075dc2788b..4f2d9538a10a 100644
--- a/sys/fs/cd9660/cd9660_mount.h
+++ b/sys/fs/cd9660/cd9660_mount.h
@@ -40,6 +40,10 @@
struct iso_args {
char *fspec; /* block special device to mount */
struct oexport_args export; /* network export info */
+ uid_t uid; /* uid that owns ISO-9660 files */
+ gid_t gid; /* gid that owns ISO-9660 files */
+ mode_t fmask; /* file mask to be applied for files */
+ mode_t dmask; /* file mask to be applied for directories */
int flags; /* mounting flags, see below */
int ssector; /* starting sector, 0 for 1st session */
char *cs_disk; /* disk charset for Joliet cs conversion */
@@ -51,3 +55,6 @@ struct iso_args {
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext.*/
#define ISOFSMNT_BROKENJOLIET 0x00000010/* allow broken Joliet disks */
#define ISOFSMNT_KICONV 0x00000020 /* Use libiconv to convert chars */
+
+#define ISOFSMNT_UID 0x00000100 /* override uid */
+#define ISOFSMNT_GID 0x00000200 /* override gid */
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index ee0b68714c2a..f067453d3458 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -104,6 +104,12 @@ cd9660_cmount(struct mntarg *ma, void *data, uint64_t flags)
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
ma = mount_arg(ma, "export", &args.export, sizeof(args.export));
+ if (args.flags & ISOFSMNT_UID)
+ ma = mount_argf(ma, "uid", "%d", args.uid);
+ if (args.flags & ISOFSMNT_GID)
+ ma = mount_argf(ma, "gid", "%d", args.gid);
+ ma = mount_argf(ma, "mask", "%d", args.fmask);
+ ma = mount_argf(ma, "dirmask", "%d", args.dmask);
ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
ma = mount_argf(ma, "ssector", "%u", args.ssector);
@@ -218,6 +224,7 @@ iso_mountfs(struct vnode *devvp, struct mount *mp)
struct g_consumer *cp;
struct bufobj *bo;
char *cs_local, *cs_disk;
+ int v;
dev = devvp->v_rdev;
dev_ref(dev);
@@ -387,6 +394,7 @@ iso_mountfs(struct vnode *devvp, struct mount *mp)
isomp->im_mountp = mp;
isomp->im_dev = dev;
isomp->im_devvp = devvp;
+ isomp->im_fmask = isomp->im_dmask = ACCESSPERMS;
vfs_flagopt(mp->mnt_optnew, "norrip", &isomp->im_flags, ISOFSMNT_NORRIP);
vfs_flagopt(mp->mnt_optnew, "gens", &isomp->im_flags, ISOFSMNT_GENS);
@@ -394,6 +402,21 @@ iso_mountfs(struct vnode *devvp, struct mount *mp)
vfs_flagopt(mp->mnt_optnew, "nojoliet", &isomp->im_flags, ISOFSMNT_NOJOLIET);
vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV);
+ if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v) == 1) {
+ isomp->im_flags |= ISOFSMNT_UID;
+ isomp->im_uid = v;
+ }
+ if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v) == 1) {
+ isomp->im_flags |= ISOFSMNT_GID;
+ isomp->im_gid = v;
+ }
+ if (vfs_scanopt(mp->mnt_optnew, "mask", "%d", &v) == 1) {
+ isomp->im_fmask &= v;
+ }
+ if (vfs_scanopt(mp->mnt_optnew, "dirmask", "%d", &v) == 1) {
+ isomp->im_dmask &= v;
+ }
+
/* Check the Rock Ridge Extension support */
if (!(isomp->im_flags & ISOFSMNT_NORRIP)) {
if ((error = bread(isomp->im_devvp, (isomp->root_extent +
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index 1b11da80431b..33ca58472490 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/cd9660/cd9660_vnops.c
@@ -56,6 +56,7 @@
#include <fs/cd9660/iso.h>
#include <fs/cd9660/cd9660_node.h>
+#include <fs/cd9660/cd9660_mount.h>
#include <fs/cd9660/iso_rrip.h>
static vop_setattr_t cd9660_setattr;
@@ -119,6 +120,9 @@ cd9660_access(struct vop_access_args *ap)
struct vnode *vp = ap->a_vp;
struct iso_node *ip = VTOI(vp);
accmode_t accmode = ap->a_accmode;
+ accmode_t file_mode;
+ uid_t uid;
+ gid_t gid;
if (vp->v_type == VCHR || vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -140,8 +144,16 @@ cd9660_access(struct vop_access_args *ap)
}
}
- return (vaccess(vp->v_type, ip->inode.iso_mode, ip->inode.iso_uid,
- ip->inode.iso_gid, ap->a_accmode, ap->a_cred));
+ file_mode = ip->inode.iso_mode;
+ file_mode &= (vp->v_type == VDIR) ? ip->i_mnt->im_dmask : ip->i_mnt->im_fmask;
+
+ uid = (ip->i_mnt->im_flags & ISOFSMNT_UID) ?
+ ip->i_mnt->im_uid : ip->inode.iso_uid;
+ gid = (ip->i_mnt->im_flags & ISOFSMNT_GID) ?
+ ip->i_mnt->im_gid : ip->inode.iso_gid;
+
+ return (vaccess(vp->v_type, file_mode, uid,
+ gid, ap->a_accmode, ap->a_cred));
}
static int
@@ -169,9 +181,13 @@ cd9660_getattr(struct vop_getattr_args *ap)
vap->va_fileid = ip->i_number;
vap->va_mode = ip->inode.iso_mode;
+ vap->va_mode &= (vp->v_type == VDIR) ? ip->i_mnt->im_dmask : ip->i_mnt->im_fmask;
+
vap->va_nlink = ip->inode.iso_links;
- vap->va_uid = ip->inode.iso_uid;
- vap->va_gid = ip->inode.iso_gid;
+ vap->va_uid = (ip->i_mnt->im_flags & ISOFSMNT_UID) ?
+ ip->i_mnt->im_uid : ip->inode.iso_uid;
+ vap->va_gid = (ip->i_mnt->im_flags & ISOFSMNT_GID) ?
+ ip->i_mnt->im_gid : ip->inode.iso_gid;
vap->va_atime = ip->inode.iso_atime;
vap->va_mtime = ip->inode.iso_mtime;
vap->va_ctime = ip->inode.iso_ctime;
diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h
index 2d9e2e8b682a..a9733f62c077 100644
--- a/sys/fs/cd9660/iso.h
+++ b/sys/fs/cd9660/iso.h
@@ -237,6 +237,11 @@ struct iso_mnt {
struct g_consumer *im_cp;
struct bufobj *im_bo;
+ uid_t im_uid;
+ gid_t im_gid;
+ mode_t im_fmask;
+ mode_t im_dmask;
+
int logical_block_size;
int im_bshift;
int im_bmask;