cd9660: Add support for mask,dirmask,uid,gid options

Reviewed by:	jhb
Pull Request:	https://github.com/freebsd/freebsd-src/pull/982
This commit is contained in:
Ricardo Branco 2024-01-08 21:24:53 +01:00 committed by John Baldwin
parent bc1eea0c0b
commit 82f2275b73
6 changed files with 167 additions and 8 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 +

View File

@ -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;

View File

@ -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;