From nobody@FreeBSD.org  Fri Jul 27 08:11:22 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3601E16A41F
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 27 Jul 2007 08:11:22 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 1C1DA13C4A3
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 27 Jul 2007 08:11:22 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l6R8BLMm024292
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 27 Jul 2007 08:11:21 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.1/8.14.1/Submit) id l6R8BLX3024291;
	Fri, 27 Jul 2007 08:11:21 GMT
	(envelope-from nobody)
Message-Id: <200707270811.l6R8BLX3024291@www.freebsd.org>
Date: Fri, 27 Jul 2007 08:11:21 GMT
From: Ighighi <ighighi@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH]: support for mask,dirmask,uid,gid for mount_cd9660(8) / CD9660
X-Send-Pr-Version: www-3.0

>Number:         114955
>Category:       kern
>Synopsis:       [cd9660] [patch] [request] support for mask,dirmask,uid,gid for mount_cd9660(8) / CD9660
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-fs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 27 08:20:01 GMT 2007
>Closed-Date:    
>Last-Modified:  Sun Mar 09 12:59:18 UTC 2008
>Originator:     Ighighi
>Release:        6.2-STABLE
>Organization:
>Environment:
FreeBSD orion 6.2-STABLE FreeBSD 6.2-STABLE #0: Thu Jul 26 01:07:13 VET 2007     root@orion:/usr/obj/usr/src/sys/CUSTOM  i386

>Description:
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 with patch to -CURRENT pending.
The mount_cd9660(8) in -CURRENT that uses nmount() instead of the old mount()
ran successfully too.

>How-To-Repeat:

>Fix:
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
  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


Patch attached with submission follows:

#
# (!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
#  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/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;
--- src/sys/isofs/cd9660/cd9660_node.c.orig	2006-03-12 17:50:02.000000000 -0400
+++ src/sys/isofs/cd9660/cd9660_node.c	2007-07-27 00:37:35.806317377 -0400
@@ -129,6 +129,7 @@
 	struct buf *bp2 = NULL;
 	struct iso_mnt *imp;
 	struct iso_extended_attributes *ap = NULL;
+	mode_t mode;
 	int off;
 
 	/* high sierra does not have timezone data, flag is one byte ahead */
@@ -179,6 +180,23 @@
 	}
 	if (bp2)
 		brelse(bp2);
+
+	mode = inop->inode.iso_mode & S_IFMT;
+	switch (mode) {
+	case S_IFDIR:
+		if (inop->i_mnt->im_flags & ISOFSMNT_DMASK)
+			inop->inode.iso_mode = mode | inop->i_mnt->im_dmask;
+		break;
+	case S_IFREG:
+		if (inop->i_mnt->im_flags & ISOFSMNT_FMASK)
+			inop->inode.iso_mode = mode | inop->i_mnt->im_fmask;
+		break;
+	}
+
+	if (inop->i_mnt->im_flags & ISOFSMNT_UID)
+		inop->inode.iso_uid = inop->i_mnt->im_uid;
+	if (inop->i_mnt->im_flags & ISOFSMNT_GID)
+		inop->inode.iso_gid = inop->i_mnt->im_gid;
 }
 
 /*
--- 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-27 01:36:02.206613258 -0400
@@ -108,6 +108,10 @@
 
 	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
 	ma = mount_arg(ma, "export", &args.export, sizeof args.export);
+	ma = mount_argf(ma, "uid", "%d", args.uid);
+	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);
@@ -220,6 +224,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 +394,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,


>Release-Note:
>Audit-Trail:

From: Ighighi <ighighi@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/114955: [PATCH]: support for mask, dirmask, uid, gid for
 mount_cd9660(8)
Date: Fri, 27 Jul 2007 04:29:13 -0400

 This is a multi-part message in MIME format.
 --------------030003060409070908020005
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 NOTE: This version applies to -CURRENT
 
 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.
 
 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/fs/cd9660/iso.h /usr/include/fs/cd9660/
    cp -f /sys/fs/cd9660/cd9660_mount.h /usr/include/fs/cd9660/
    cd /usr/src/sbin/mount_cd9660
    make clean obj depend && make && make install clean
    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
 
 --------------030003060409070908020005
 Content-Type: text/x-patch;
  name="cd9660-head.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="cd9660-head.patch"
 
 --- src/sbin/mount_cd9660/mount_cd9660.c.orig	2007-07-25 01:29:31.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.c	2007-07-27 02:48:51.445670177 -0400
 @@ -58,8 +58,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>
 @@ -74,6 +77,9 @@
  	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);
 @@ -94,7 +100,7 @@
  	mntflags = opts = 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);
 @@ -105,6 +111,15 @@
  		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;
 @@ -124,6 +139,9 @@
  		case 's':
  			ssector = atoi(optarg);
  			break;
 +		case 'U':
 +		        build_iovec_argf(&iov, &iovlen, "uid", "%d", a_uid(optarg));
 +			break;
  		case 'v':
  			verbose++;
  			break;
 @@ -186,8 +204,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);
  }
  
 @@ -265,3 +283,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	2007-07-25 01:29:29.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.8	2007-07-25 01:32:13.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/fs/cd9660/cd9660_mount.h.orig	2007-02-11 09:54:25.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_mount.h	2007-07-27 04:15:04.109015099 -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/fs/cd9660/iso.h.orig	2007-02-15 18:08:34.000000000 -0400
 +++ src/sys/fs/cd9660/iso.h	2007-07-27 04:15:04.111016471 -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;
 --- src/sys/fs/cd9660/cd9660_node.c.orig	2007-02-11 09:54:25.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_node.c	2007-07-27 04:15:04.112016598 -0400
 @@ -129,6 +129,7 @@
  	struct buf *bp2 = NULL;
  	struct iso_mnt *imp;
  	struct iso_extended_attributes *ap = NULL;
 +	mode_t mode;
  	int off;
  
  	/* high sierra does not have timezone data, flag is one byte ahead */
 @@ -179,6 +180,23 @@
  	}
  	if (bp2)
  		brelse(bp2);
 +
 +	mode = inop->inode.iso_mode & S_IFMT;
 +	switch (mode) {
 +	case S_IFDIR:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_DMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_dmask;
 +		break;
 +	case S_IFREG:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_FMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_fmask;
 +		break;
 +	}
 +
 +	if (inop->i_mnt->im_flags & ISOFSMNT_UID)
 +		inop->inode.iso_uid = inop->i_mnt->im_uid;
 +	if (inop->i_mnt->im_flags & ISOFSMNT_GID)
 +		inop->inode.iso_gid = inop->i_mnt->im_gid;
  }
  
  /*
 --- src/sys/fs/cd9660/cd9660_vfsops.c.orig	2007-03-12 21:50:22.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_vfsops.c	2007-07-27 04:15:04.114016573 -0400
 @@ -107,6 +107,10 @@
  
  	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
  	ma = mount_arg(ma, "export", &args.export, sizeof args.export);
 +	ma = mount_argf(ma, "uid", "%d", args.uid);
 +	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);
 @@ -223,6 +227,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();
 @@ -392,6 +397,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,
 
 --------------030003060409070908020005--

From: Ighighi <ighighi@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/114955: [cd9660] [patch] support for mask,dirmask,uid,gid
 for mount_cd9660(8) / CD9660
Date: Sun, 29 Jul 2007 02:50:04 -0400

 This is a multi-part message in MIME format.
 --------------030905040004010907090909
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 This patch addresses a bug in the previous commit for RELENG_6 that made 
 the newly added options mandatory.
 
 Also, an "umount -a -t cd9660" was missing from the following instructions:
 
 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
 
 
 --------------030905040004010907090909
 Content-Type: text/x-patch;
  name="cd9660_dirmask.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="cd9660_dirmask.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/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;
 --- src/sys/isofs/cd9660/cd9660_node.c.orig	2006-03-12 17:50:02.000000000 -0400
 +++ src/sys/isofs/cd9660/cd9660_node.c	2007-07-27 00:37:35.806317377 -0400
 @@ -129,6 +129,7 @@
  	struct buf *bp2 = NULL;
  	struct iso_mnt *imp;
  	struct iso_extended_attributes *ap = NULL;
 +	mode_t mode;
  	int off;
  
  	/* high sierra does not have timezone data, flag is one byte ahead */
 @@ -179,6 +180,23 @@
  	}
  	if (bp2)
  		brelse(bp2);
 +
 +	mode = inop->inode.iso_mode & S_IFMT;
 +	switch (mode) {
 +	case S_IFDIR:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_DMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_dmask;
 +		break;
 +	case S_IFREG:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_FMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_fmask;
 +		break;
 +	}
 +
 +	if (inop->i_mnt->im_flags & ISOFSMNT_UID)
 +		inop->inode.iso_uid = inop->i_mnt->im_uid;
 +	if (inop->i_mnt->im_flags & ISOFSMNT_GID)
 +		inop->inode.iso_gid = inop->i_mnt->im_gid;
  }
  
  /*
 --- 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,
 
 --------------030905040004010907090909--

From: Ighighi <ighighi@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/114955: [cd9660] [patch] support for mask,dirmask,uid,gid
 for mount_cd9660(8) / CD9660
Date: Sun, 29 Jul 2007 03:00:05 -0400

 This is a multi-part message in MIME format.
 --------------030307030605050000020100
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 This patch addresses a bug in the previous commit for -CURRENT that made
 the newly added options mandatory (though the new nmount() call made it
 a non-issue with mount_cd9660(8)
 
 Also, an "umount -a -t cd9660" was missing from the following instructions:
 
 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
 
 
 
 --------------030307030605050000020100
 Content-Type: text/x-patch;
  name="cd9660-head.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="cd9660-head.patch"
 
 --- src/sbin/mount_cd9660/mount_cd9660.c.orig	2007-07-25 01:29:31.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.c	2007-07-27 02:48:51.445670177 -0400
 @@ -58,8 +58,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>
 @@ -74,6 +77,9 @@
  	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);
 @@ -94,7 +100,7 @@
  	mntflags = opts = 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);
 @@ -105,6 +111,15 @@
  		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;
 @@ -124,6 +139,9 @@
  		case 's':
  			ssector = atoi(optarg);
  			break;
 +		case 'U':
 +		        build_iovec_argf(&iov, &iovlen, "uid", "%d", a_uid(optarg));
 +			break;
  		case 'v':
  			verbose++;
  			break;
 @@ -186,8 +204,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);
  }
  
 @@ -265,3 +283,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	2007-07-25 01:29:29.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.8	2007-07-25 01:32:13.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/fs/cd9660/cd9660_mount.h.orig	2007-02-11 09:54:25.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_mount.h	2007-07-27 04:15:04.109015099 -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/fs/cd9660/iso.h.orig	2007-02-15 18:08:34.000000000 -0400
 +++ src/sys/fs/cd9660/iso.h	2007-07-27 04:15:04.111016471 -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;
 --- src/sys/fs/cd9660/cd9660_node.c.orig	2007-02-11 09:54:25.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_node.c	2007-07-27 04:15:04.112016598 -0400
 @@ -129,6 +129,7 @@
  	struct buf *bp2 = NULL;
  	struct iso_mnt *imp;
  	struct iso_extended_attributes *ap = NULL;
 +	mode_t mode;
  	int off;
  
  	/* high sierra does not have timezone data, flag is one byte ahead */
 @@ -179,6 +180,23 @@
  	}
  	if (bp2)
  		brelse(bp2);
 +
 +	mode = inop->inode.iso_mode & S_IFMT;
 +	switch (mode) {
 +	case S_IFDIR:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_DMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_dmask;
 +		break;
 +	case S_IFREG:
 +		if (inop->i_mnt->im_flags & ISOFSMNT_FMASK)
 +			inop->inode.iso_mode = mode | inop->i_mnt->im_fmask;
 +		break;
 +	}
 +
 +	if (inop->i_mnt->im_flags & ISOFSMNT_UID)
 +		inop->inode.iso_uid = inop->i_mnt->im_uid;
 +	if (inop->i_mnt->im_flags & ISOFSMNT_GID)
 +		inop->inode.iso_gid = inop->i_mnt->im_gid;
  }
  
  /*
 --- src/sys/fs/cd9660/cd9660_vfsops.c.orig	2007-03-12 21:50:22.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_vfsops.c	2007-07-29 02:51:10.106173569 -0400
 @@ -107,6 +107,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);
 @@ -223,6 +231,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();
 @@ -392,6 +401,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,
 
 --------------030307030605050000020100--

From: Ighighi <ighighi@gmail.com>
To: bug-followup@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--

From: Ighighi <ighighi@gmail.com>
To: bug-followup@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:15:14 -0400

 This is a multi-part message in MIME format.
 --------------090503080406010209010801
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 This new version (for -CURRENT) 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 ;)
 
 
 --------------090503080406010209010801
 Content-Type: text/x-patch;
  name="cd9660-head.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="cd9660-head.patch"
 
 --- src/sbin/mount_cd9660/mount_cd9660.c.orig	2007-07-25 01:29:31.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.c	2007-07-27 02:48:51.445670177 -0400
 @@ -58,8 +58,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>
 @@ -74,6 +77,9 @@
  	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);
 @@ -94,7 +100,7 @@
  	mntflags = opts = 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);
 @@ -105,6 +111,15 @@
  		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;
 @@ -124,6 +139,9 @@
  		case 's':
  			ssector = atoi(optarg);
  			break;
 +		case 'U':
 +		        build_iovec_argf(&iov, &iovlen, "uid", "%d", a_uid(optarg));
 +			break;
  		case 'v':
  			verbose++;
  			break;
 @@ -186,8 +204,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);
  }
  
 @@ -265,3 +283,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	2007-07-25 01:29:29.000000000 -0400
 +++ src/sbin/mount_cd9660/mount_cd9660.8	2007-07-25 01:32:13.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/fs/cd9660/cd9660_mount.h.orig	2007-02-11 09:54:25.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_mount.h	2007-08-01 23:09:43.154973768 -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/fs/cd9660/cd9660_vfsops.c.orig	2007-03-12 21:50:22.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_vfsops.c	2007-08-01 23:09:43.156972625 -0400
 @@ -107,6 +107,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);
 @@ -223,6 +231,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();
 @@ -392,6 +401,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/fs/cd9660/cd9660_vnops.c.orig	2007-02-15 18:08:34.000000000 -0400
 +++ src/sys/fs/cd9660/cd9660_vnops.c	2007-08-01 23:09:43.159973845 -0400
 @@ -133,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);
 @@ -155,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
 @@ -194,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/fs/cd9660/iso.h.orig	2007-02-15 18:08:34.000000000 -0400
 +++ src/sys/fs/cd9660/iso.h	2007-08-01 23:09:43.161973540 -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;
 
 --------------090503080406010209010801--
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Sun Mar 9 12:59:00 UTC 2008 
Responsible-Changed-Why:  
Over to maintainers. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=114955 
>Unformatted:
