Skip to content

Commit

Permalink
cd9660: Add support for mask,dirmask,uid,gid options
Browse files Browse the repository at this point in the history
Reviewed by:	jhb
Pull Request:	freebsd#982
  • Loading branch information
ricardobranco777 authored and bsdjhb committed Jan 12, 2024
1 parent bc1eea0 commit 82f2275
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 8 deletions.
37 changes: 36 additions & 1 deletion sbin/mount_cd9660/mount_cd9660.8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
79 changes: 76 additions & 3 deletions sbin/mount_cd9660/mount_cd9660.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
7 changes: 7 additions & 0 deletions sys/fs/cd9660/cd9660_mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */
23 changes: 23 additions & 0 deletions sys/fs/cd9660/cd9660_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -387,13 +394,29 @@ 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);
vfs_flagopt(mp->mnt_optnew, "extatt", &isomp->im_flags, ISOFSMNT_EXTATT);
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 +
Expand Down
24 changes: 20 additions & 4 deletions sys/fs/cd9660/cd9660_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions sys/fs/cd9660/iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 82f2275

Please sign in to comment.