kern/114955: [cd9660] [patch] support for mask, dirmask, uid,
gid for mount_cd9660(8) / CD9660
Ighighi
ighighi at gmail.com
Thu Aug 2 03:10:09 UTC 2007
The following reply was made to PR kern/114955; it has been noted by GNATS.
From: Ighighi <ighighi at gmail.com>
To: bug-followup at freebsd.org
Cc:
Subject: Re: kern/114955: [cd9660] [patch] support for mask,dirmask,uid,gid
for mount_cd9660(8) / CD9660
Date: Wed, 01 Aug 2007 23:06:17 -0400
This is a multi-part message in MIME format.
--------------080803050503080308030403
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
This new version (for RELENG_6) allows overriding Rockridge uid/gid,
file and directory permissions ala MSDOS.
To apply this patch, run:
patch -d /usr < /path/do/patch
Now, either rebuild the world and the kernel or run:
cd /usr/src/sys/modules/cd9660
make clean obj depend && make && make install clean
cp -f /sys/isofs/cd9660/iso.h /usr/include/isofs/cd9660/
cp -f /sys/isofs/cd9660/cd9660_mount.h /usr/include/isofs/cd9660/
cd /usr/src/sbin/mount_cd9660
make clean obj depend && make && make install clean
umount -a -t cd9660
kldunload -v cd9660
kldload -v cd9660
You may now add the following line to /etc/fstab:
/dev/acd0 /media/cdrom ro,noauto,nosuid,nodev,-m640,-M750,-Uuser,-Ggroup 0 0
Or run mount_cd9660(8) as:
mount_cd9660 -o ro,nosuid,nodev -m640 -M750 -U`whoami` -G`id -g`
Enjoy ;)
--------------080803050503080308030403
Content-Type: text/x-patch;
name="cd9660.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="cd9660.patch"
#
# (!c) 2007 by Ighighi
#
# This patch adds arbitrary mask, dirmask, uid & gid support to ISO9660
# ala MSDOSFS. It is necessary because legitimate data in CD-ROM and ISO
# images may be inaccessible when ownership is assigned to root/wheel.
# The mask/dirmask options let the user override the ugly 0555 permissions
# of files where the executable bit makes no sense.
#
# Successfully built & tested on 6.2-STABLE
#
# To apply this patch, run:
# patch -d /usr < /path/do/patch
# Now, either rebuild the world and the kernel or run:
# cd /usr/src/sys/modules/cd9660
# make clean obj depend && make && make install clean
# cp -f /sys/isofs/cd9660/iso.h /usr/include/isofs/cd9660/
# cp -f /sys/isofs/cd9660/cd9660_mount.h /usr/include/isofs/cd9660/
# cd /usr/src/sbin/mount_cd9660
# make clean obj depend && make && make install clean
# umount -a -t cd9660
# kldunload -v cd9660
# kldload -v cd9660
#
# Enjoy, you may use a line like this in /etc/fstab:
# /dev/cdrom /media/cdrom cd9660 ro,noauto,nosuid,-m644,-M755 0 0
# From the command line:
# mount_cd9660 -o ro -m 660 -M 750 -U `whoami` -G staff /dev/cdrom ~/cdrom
#
--- src/sbin/mount_cd9660/mount_cd9660.c.orig 2005-06-10 05:51:41.000000000 -0400
+++ src/sbin/mount_cd9660/mount_cd9660.c 2007-07-25 01:19:30.000000000 -0400
@@ -59,8 +59,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>
@@ -80,6 +83,10 @@
MOPT_END
};
+static gid_t a_gid(const char *);
+static uid_t a_uid(const char *);
+static mode_t a_mask(const char *);
+
int get_ssector(const char *dev);
int set_charset(struct iso_args *, const char *);
void usage(void);
@@ -97,7 +104,7 @@
args.ssector = -1;
args.cs_disk = NULL;
args.cs_local = NULL;
- 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':
opts |= ISOFSMNT_BROKENJOLIET;
@@ -108,9 +115,21 @@
case 'g':
opts |= ISOFSMNT_GENS;
break;
+ case 'G':
+ args.gid = a_gid(optarg);
+ opts |= ISOFSMNT_GID;
+ break;
case 'j':
opts |= ISOFSMNT_NOJOLIET;
break;
+ case 'm':
+ args.fmask = a_mask(optarg);
+ opts |= ISOFSMNT_FMASK;
+ break;
+ case 'M':
+ args.dmask = a_mask(optarg);
+ opts |= ISOFSMNT_DMASK;
+ break;
case 'o':
getmntopts(optarg, mopts, &mntflags, &opts);
break;
@@ -120,6 +139,10 @@
case 's':
args.ssector = atoi(optarg);
break;
+ case 'U':
+ args.uid = a_uid(optarg);
+ opts |= ISOFSMNT_UID;
+ break;
case 'v':
verbose++;
break;
@@ -187,8 +210,8 @@
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);
}
@@ -258,3 +281,58 @@
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);
+}
--- src/sbin/mount_cd9660/mount_cd9660.8.orig 2005-02-13 18:25:16.000000000 -0400
+++ src/sbin/mount_cd9660/mount_cd9660.8 2007-07-25 01:17:27.000000000 -0400
@@ -42,8 +42,13 @@
.Nm
.Op Fl begjrv
.Op Fl C Ar charset
+.Op Fl G Ar gid
+.Op Fl L Ar locale
+.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
@@ -69,6 +74,37 @@
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
--- src/sys/isofs/cd9660/cd9660_mount.h.orig 2005-01-06 18:18:23.000000000 -0400
+++ src/sys/isofs/cd9660/cd9660_mount.h 2007-07-24 02:03:11.000000000 -0400
@@ -41,6 +41,10 @@
struct iso_args {
char *fspec; /* block special device to mount */
struct export_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 */
@@ -52,3 +56,8 @@
#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 */
+#define ISOFSMNT_FMASK 0x00000400 /* override mode for files */
+#define ISOFSMNT_DMASK 0x00000800 /* override mode for directories */
--- src/sys/isofs/cd9660/cd9660_vfsops.c.orig 2007-02-07 00:02:05.000000000 -0400
+++ src/sys/isofs/cd9660/cd9660_vfsops.c 2007-07-29 02:08:40.012651627 -0400
@@ -108,6 +108,14 @@
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);
+ if (args.flags & ISOFSMNT_FMASK)
+ ma = mount_argf(ma, "mask", "%d", args.fmask);
+ if (args.flags & ISOFSMNT_DMASK)
+ 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);
@@ -220,6 +228,7 @@
struct g_consumer *cp;
struct bufobj *bo;
char *cs_local, *cs_disk;
+ int v;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
DROP_GIANT();
@@ -389,6 +398,23 @@
vfs_flagopt(mp->mnt_optnew, "nojoliet", &isomp->im_flags, ISOFSMNT_NOJOLIET);
vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV);
+ if (1 == vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v)) {
+ isomp->im_flags |= ISOFSMNT_UID;
+ isomp->im_uid = v;
+ }
+ if (1 == vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v)) {
+ isomp->im_flags |= ISOFSMNT_GID;
+ isomp->im_gid = v;
+ }
+ if (1 == vfs_scanopt(mp->mnt_optnew, "mask", "%d", &v)) {
+ isomp->im_flags |= ISOFSMNT_FMASK;
+ isomp->im_fmask = v & ACCESSPERMS;
+ }
+ if (1 == vfs_scanopt(mp->mnt_optnew, "dirmask", "%d", &v)) {
+ isomp->im_flags |= ISOFSMNT_DMASK;
+ isomp->im_dmask = v & ACCESSPERMS;
+ }
+
/* Check the Rock Ridge Extension support */
if (!(isomp->im_flags & ISOFSMNT_NORRIP)) {
if ((error = bread(isomp->im_devvp,
--- src/sys/isofs/cd9660/cd9660_vnops.c.orig 2006-02-19 20:53:14.000000000 -0400
+++ src/sys/isofs/cd9660/cd9660_vnops.c 2007-08-01 20:54:23.000000000 -0400
@@ -58,6 +58,7 @@
#include <vm/uma.h>
#include <isofs/cd9660/iso.h>
+#include <isofs/cd9660/cd9660_mount.h>
#include <isofs/cd9660/cd9660_node.h>
#include <isofs/cd9660/iso_rrip.h>
@@ -132,7 +133,9 @@
{
struct vnode *vp = ap->a_vp;
struct iso_node *ip = VTOI(vp);
- mode_t mode = ap->a_mode;
+ mode_t file_mode, mode = ap->a_mode;
+ uid_t uid;
+ gid_t gid;
if (vp->v_type == VCHR || vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -154,8 +157,27 @@
}
}
- return (vaccess(vp->v_type, ip->inode.iso_mode, ip->inode.iso_uid,
- ip->inode.iso_gid, ap->a_mode, ap->a_cred, NULL));
+ file_mode = ip->inode.iso_mode;
+ switch (vp->v_type) {
+ case VDIR:
+ if (ip->i_mnt->im_flags & ISOFSMNT_DMASK)
+ file_mode = ip->i_mnt->im_dmask;
+ break;
+ case VREG:
+ if (ip->i_mnt->im_flags & ISOFSMNT_FMASK)
+ file_mode = ip->i_mnt->im_fmask;
+ break;
+ default:
+ break;
+ }
+
+ 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_mode, ap->a_cred, NULL));
}
static int
@@ -193,9 +215,26 @@
vap->va_fileid = ip->i_number;
vap->va_mode = ip->inode.iso_mode;
+ switch (vp->v_type) {
+ case VDIR:
+ if (ip->i_mnt->im_flags & ISOFSMNT_DMASK)
+ vap->va_mode =
+ (vap->va_mode & ~ACCESSPERMS) | ip->i_mnt->im_dmask;
+ break;
+ case VREG:
+ if (ip->i_mnt->im_flags & ISOFSMNT_FMASK)
+ vap->va_mode =
+ (vap->va_mode & ~ACCESSPERMS) | ip->i_mnt->im_fmask;
+ break;
+ default:
+ break;
+ }
+
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;
--- src/sys/isofs/cd9660/iso.h.orig 2005-12-14 05:20:30.000000000 -0400
+++ src/sys/isofs/cd9660/iso.h 2007-07-24 02:06:21.000000000 -0400
@@ -229,6 +229,11 @@
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;
--------------080803050503080308030403--
More information about the freebsd-bugs
mailing list