From owner-freebsd-bugs@FreeBSD.ORG Tue Jul 24 04:20:02 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 155F716A419 for ; Tue, 24 Jul 2007 04:20:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id E711413C46B for ; Tue, 24 Jul 2007 04:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l6O4K1oN047464 for ; Tue, 24 Jul 2007 04:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l6O4K1oJ047463; Tue, 24 Jul 2007 04:20:01 GMT (envelope-from gnats) Resent-Date: Tue, 24 Jul 2007 04:20:01 GMT Resent-Message-Id: <200707240420.l6O4K1oJ047463@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ighighi Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5BE1516A417 for ; Tue, 24 Jul 2007 04:18:08 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (unknown [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 3D82B13C46C for ; Tue, 24 Jul 2007 04:18:08 +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 l6O4I77F008584 for ; Tue, 24 Jul 2007 04:18:07 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.1/8.14.1/Submit) id l6O4I7hs008583; Tue, 24 Jul 2007 04:18:07 GMT (envelope-from nobody) Message-Id: <200707240418.l6O4I7hs008583@www.freebsd.org> Date: Tue, 24 Jul 2007 04:18:07 GMT From: Ighighi To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: kern/114847: [PATCH]: dirmask support for NTFS ala MSDOSFS X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Jul 2007 04:20:02 -0000 >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@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 & 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: