kern/114847: [PATCH]: dirmask support for NTFS ala MSDOSFS
Ighighi
ighighi at gmail.com
Tue Jul 24 04:20:02 UTC 2007
>Number: 114847
>Category: kern
>Synopsis: [PATCH]: dirmask support for NTFS ala MSDOSFS
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Jul 24 04:20:01 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Ighighi
>Release: 6.2-STABLE
>Organization:
>Environment:
FreeBSD orion 6.2-STABLE FreeBSD 6.2-STABLE #0: Thu Jul 19 17:44:47 VET 2007 root at orion:/usr/obj/usr/src/sys/CUSTOM i386
>Description:
The "-m mask" option alone is useless since we are forced to add the
executable bits to browse directories, but these bits make no sense on
regular files in NTFS volumes most of the time.
Example code taken from src/sys/fs/msdosfs/* and src/sbin/mount_msdosfs/*
It was successfully built and tested on 6.2-STABLE and known to patch correctly
on -CURRENT.
It changes the ABI of the kernel module so any applications that use
<fs/ntfs/ntfs.h> & <fs/ntfs/ntfsmount.h> may need to be recompiled.
I'm not aware of none (other than mount_ntfs(8), of course).
An alternative patch will be posted later that just adds executable bits
to every directory, that preserves ABI compatibility.
>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/ntfs
make clean && make && make install clean
cp -f /sys/fs/ntfs/ntfs.h /usr/include/fs/ntfs/
cp -f /sys/fs/ntfs/ntfsmount.h /usr/include/fs/ntfs/
cd /usr/src/sbin/mount_ntfs
make clean && make && make install clean
kldunload -v ntfs
kldload -v ntfs
Enjoy, you may use a line like this in /etc/fstab:
/dev/ad0s1 /mnt/win ntfs ro,noexec,noatime,-m644,-M755 0 0
Patch attached with submission follows:
#
# (!c) 2007 by Ighighi
#
# This patch adds dirmask support to NTFS ala MSDOSFS.
# The "-m mask" option alone is useless since we are forced to add the
# executable bits to browse directories, but these bits make no sense
# on regular files in NTFS volumes most of the time.
#
# 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/ntfs
# make clean && make && make install clean
# cp -f /sys/fs/ntfs/ntfs.h /usr/include/fs/ntfs/
# cp -f /sys/fs/ntfs/ntfsmount.h /usr/include/fs/ntfs/
# cd /usr/src/sbin/mount_ntfs
# make clean && make && make install clean
# kldunload -v ntfs
# kldload -v ntfs
#
# Enjoy, you may use a line like this in /etc/fstab:
# /dev/ad0s1 /mnt/win ntfs ro,noexec,noatime,-m644,-M755 0 0
#
--- src/sbin/mount_ntfs/mount_ntfs.c.orig 2005-06-10 05:51:42.000000000 -0400
+++ src/sbin/mount_ntfs/mount_ntfs.c 2007-07-23 20:51:08.000000000 -0400
@@ -75,18 +75,18 @@
{
struct ntfs_args args;
struct stat sb;
- int c, mntflags, set_gid, set_uid, set_mask;
+ int c, mntflags, set_gid, set_uid, set_mask, set_dirmask;
char *dev, *dir, mntpath[MAXPATHLEN];
- mntflags = set_gid = set_uid = set_mask = 0;
+ mntflags = set_gid = set_uid = set_mask = set_dirmask = 0;
(void)memset(&args, '\0', sizeof(args));
args.cs_ntfs = NULL;
args.cs_local = NULL;
#ifdef TRANSITION_PERIOD_HACK
- while ((c = getopt(argc, argv, "aiu:g:m:o:C:W:")) != -1) {
+ while ((c = getopt(argc, argv, "aiu:g:m:M:o:C:W:")) != -1) {
#else
- while ((c = getopt(argc, argv, "aiu:g:m:o:C:")) != -1) {
+ while ((c = getopt(argc, argv, "aiu:g:m:M:o:C:")) != -1) {
#endif
switch (c) {
case 'u':
@@ -101,6 +101,10 @@
args.mode = a_mask(optarg);
set_mask = 1;
break;
+ case 'M':
+ args.dirmode = a_mask(optarg);
+ set_dirmask = 1;
+ break;
case 'i':
args.flag |= NTFS_MFLAG_CASEINS;
break;
@@ -146,6 +150,15 @@
if (optind + 2 != argc)
usage();
+ if (set_mask && !set_dirmask) {
+ args.dirmode = args.mode;
+ set_dirmask = 1;
+ }
+ else if (set_dirmask && !set_mask) {
+ args.mode = args.dirmode;
+ set_mask = 1;
+ }
+
dev = argv[optind];
dir = argv[optind + 1];
@@ -183,7 +196,8 @@
if (!set_gid)
args.gid = sb.st_gid;
if (!set_mask)
- args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ args.mode = args.dirmode =
+ sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}
if (mount("ntfs", mntpath, mntflags, &args) < 0)
@@ -254,10 +268,10 @@
{
#ifdef TRANSITION_PERIOD_HACK
fprintf(stderr, "%s\n%s\n",
- "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask]",
+ "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-M mask] [-m mask]",
" [-C charset] [-W u2wtable] special node");
#else
- fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-C charset] special node\n");
+ fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-M mask] [-m mask] [-C charset] special node\n");
#endif
exit(EX_USAGE);
}
--- src/sbin/mount_ntfs/mount_ntfs.8.orig 2005-02-10 05:19:31.000000000 -0400
+++ src/sbin/mount_ntfs/mount_ntfs.8 2007-07-23 20:34:21.000000000 -0400
@@ -42,6 +42,7 @@
.Op Fl i
.Op Fl u Ar user
.Op Fl g Ar group
+.Op Fl M Ar mask
.Op Fl m Ar mask
.Op Fl C Ar charset
.Op Fl W Ar u2wtable
@@ -82,6 +83,37 @@
.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 value of
+.Ar -M
+is used if it is supplied and
+.Ar -m
+is omitted.
+The default
+.Ar mask
+is taken from the
+directory on which the file system is being mounted.
+.It Fl M Ar mask
+Specify the maximum file permissions for directories
+in the file system.
+The value of
+.Ar -m
+is used if it is supplied and
+.Ar -M
+is omitted.
+See the previous option's description for details.
.It Fl C Ar charset
Specify local
.Ar charset
--- src/sys/fs/ntfs/ntfs.h.orig 2004-12-06 16:22:16.000000000 -0400
+++ src/sys/fs/ntfs/ntfs.h 2007-07-23 20:19:22.000000000 -0400
@@ -249,6 +249,7 @@
uid_t ntm_uid;
gid_t ntm_gid;
mode_t ntm_mode;
+ mode_t ntm_dirmode;
u_int ntm_flag;
cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
--- src/sys/fs/ntfs/ntfsmount.h.orig 2003-09-26 16:26:23.000000000 -0400
+++ src/sys/fs/ntfs/ntfsmount.h 2007-07-23 20:19:02.000000000 -0400
@@ -38,6 +38,7 @@
uid_t uid; /* uid that owns ntfs files */
gid_t gid; /* gid that owns ntfs files */
mode_t mode; /* mask to be applied for ntfs perms */
+ mode_t dirmode; /* mask to be applied for directories */
u_long flag; /* additional flags */
char *cs_ntfs; /* NTFS Charset */
char *cs_local; /* Local Charset */
--- src/sys/fs/ntfs/ntfs_vfsops.c.orig 2006-10-10 05:43:20.000000000 -0400
+++ src/sys/fs/ntfs/ntfs_vfsops.c 2007-07-23 20:21:50.000000000 -0400
@@ -131,6 +131,7 @@
ma = mount_argf(ma, "uid", "%d", args.uid);
ma = mount_argf(ma, "gid", "%d", args.gid);
ma = mount_argf(ma, "mode", "%d", args.mode);
+ ma = mount_argf(ma, "dirmode", "%d", args.dirmode);
ma = mount_argb(ma, args.flag & NTFS_MFLAG_CASEINS, "nocaseins");
ma = mount_argb(ma, args.flag & NTFS_MFLAG_ALLNAMES, "noallnames");
if (args.flag & NTFS_MFLAG_KICONV) {
@@ -144,7 +145,7 @@
}
static const char *ntfs_opts[] = {
- "from", "export", "uid", "gid", "mode", "caseins", "allnames",
+ "from", "export", "uid", "gid", "mode", "dirmode", "caseins", "allnames",
"kiconv", "cs_ntfs", "cs_local", NULL
};
@@ -319,6 +320,8 @@
ntmp->ntm_gid = v;
if (1 == vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v))
ntmp->ntm_mode = v;
+ if (1 == vfs_scanopt(mp->mnt_optnew, "dirmode", "%d", &v))
+ ntmp->ntm_dirmode = v;
vfs_flagopt(mp->mnt_optnew,
"caseins", &ntmp->ntm_flag, NTFS_MFLAG_CASEINS);
vfs_flagopt(mp->mnt_optnew,
@@ -342,10 +345,10 @@
mp->mnt_data = (qaddr_t)ntmp;
- dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
+ dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o, dirmode: %o\n",
(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
(ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
- ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
+ ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode, ntmp->ntm_dirmode));
/*
* We read in some system nodes to do not allow
--- src/sys/fs/ntfs/ntfs_vnops.c.orig 2006-11-15 21:47:02.000000000 -0400
+++ src/sys/fs/ntfs/ntfs_vnops.c 2007-07-23 20:25:41.000000000 -0400
@@ -186,7 +186,8 @@
vap->va_fsid = dev2udev(ip->i_dev);
vap->va_fileid = ip->i_number;
- vap->va_mode = ip->i_mp->ntm_mode;
+ vap->va_mode = (vp->v_type == VDIR) ?
+ ip->i_mp->ntm_dirmode : ip->i_mp->ntm_mode;
vap->va_nlink = (ip->i_nlink || ip->i_flag & IN_LOADED ? ip->i_nlink : 1);
vap->va_uid = ip->i_mp->ntm_uid;
vap->va_gid = ip->i_mp->ntm_gid;
@@ -392,13 +393,16 @@
{
struct vnode *vp = ap->a_vp;
struct ntnode *ip = VTONT(vp);
- mode_t mode = ap->a_mode;
+ mode_t file_mode, mode = ap->a_mode;
#ifdef QUOTA
int error;
#endif
dprintf(("ntfs_access: %d\n",ip->i_number));
+ file_mode = (vp->v_type == VDIR) ?
+ ip->i_mp->ntm_dirmode : ip->i_mp->ntm_mode;
+
/*
* Disallow write attempts on read-only filesystems;
* unless the file is a socket, fifo, or a block or
@@ -419,7 +423,7 @@
}
}
- return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid,
+ return (vaccess(vp->v_type, file_mode, ip->i_mp->ntm_uid,
ip->i_mp->ntm_gid, ap->a_mode, ap->a_cred, NULL));
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list