From owner-freebsd-bugs@FreeBSD.ORG Mon Nov 29 04:50:22 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 10DF416A4CE for ; Mon, 29 Nov 2004 04:50:22 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id DA6CC43D5C for ; Mon, 29 Nov 2004 04:50:21 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.1/8.13.1) with ESMTP id iAT4oL7V020156 for ; Mon, 29 Nov 2004 04:50:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.1/8.13.1/Submit) id iAT4oLNp020155; Mon, 29 Nov 2004 04:50:21 GMT (envelope-from gnats) Resent-Date: Mon, 29 Nov 2004 04:50:21 GMT Resent-Message-Id: <200411290450.iAT4oLNp020155@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, Dan Nelson Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3007616A4CE for ; Mon, 29 Nov 2004 04:44:43 +0000 (GMT) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by mx1.FreeBSD.org (Postfix) with ESMTP id C617543D31 for ; Mon, 29 Nov 2004 04:44:42 +0000 (GMT) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.13.1/8.13.1) id iAT4ig0Q045278; Sun, 28 Nov 2004 22:44:42 -0600 (CST) (envelope-from dan) Message-Id: <200411290444.iAT4ig0Q045278@dan.emsphone.com> Date: Sun, 28 Nov 2004 22:44:42 -0600 (CST) From: Dan Nelson To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/74500: [PATCH] allow chflags to set flags on symlinks X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Nov 2004 04:50:22 -0000 >Number: 74500 >Category: bin >Synopsis: [PATCH] allow chflags to set flags on symlinks >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: Mon Nov 29 04:50:21 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Dan Nelson >Release: FreeBSD 5.3-STABLE i386 >Organization: The Allant Group >Environment: System: FreeBSD dan.emsphone.com 5.3-STABLE FreeBSD 5.3-STABLE #373: Fri Nov 26 21:49:32 CST 2004 zsh@dan.emsphone.com:/usr/src/sys/i386/compile/DANSMP i386 >Description: /bin/chflags always calls chflags(2), which means that it drills through symlinks and changes attricutes on the underlying files. This may not be what is intended if the user wants to prevent the symlink itself from being changed (to point to a different location, for example). The prototypes for chflags and fchflags are also incorrect; they take an int argument, not an unsigned long. >How-To-Repeat: >Fix: Apply the following patch which adds the -h switch, copied from the chown code. A newer version may be at http://dan.allantgroup.com/FreeBSD/ . Index: /usr/src/sys/sys/stat.h =================================================================== RCS file: /home/ncvs/src/sys/sys/stat.h,v retrieving revision 1.40 diff -u -r1.40 stat.h --- /usr/src/sys/sys/stat.h 17 Jun 2004 17:16:52 -0000 1.40 +++ /usr/src/sys/sys/stat.h 11 Nov 2004 20:06:24 -0000 @@ -299,11 +299,11 @@ #ifndef _KERNEL __BEGIN_DECLS #if __BSD_VISIBLE -int chflags(const char *, unsigned long); +int chflags(const char *, int); #endif int chmod(const char *, mode_t); #if __BSD_VISIBLE -int fchflags(int, unsigned long); +int fchflags(int, int); int fchmod(int, mode_t); #endif int fstat(int, struct stat *); Index: /usr/src/bin/chflags/chflags.1 =================================================================== RCS file: /home/ncvs/src/bin/chflags/chflags.1,v retrieving revision 1.18 diff -u -r1.18 chflags.1 --- /usr/src/bin/chflags/chflags.1 6 Apr 2004 20:06:44 -0000 1.18 +++ /usr/src/bin/chflags/chflags.1 11 Nov 2004 20:01:49 -0000 @@ -39,6 +39,7 @@ .Nd change file flags .Sh SYNOPSIS .Nm +.Op Fl h .Oo .Fl R .Op Fl H | Fl L | Fl P @@ -72,6 +73,9 @@ .It Fl R Change the file flags for the file hierarchies rooted in the files instead of just the files themselves. +.It Fl h +If the file is a symbolic link, change the user ID and/or the +group ID of the link itself. .El .Pp The flags are specified as an octal number or a comma separated list Index: /usr/src/bin/chflags/chflags.c =================================================================== RCS file: /home/ncvs/src/bin/chflags/chflags.c,v retrieving revision 1.20 diff -u -r1.20 chflags.c --- /usr/src/bin/chflags/chflags.c 6 Apr 2004 20:06:44 -0000 1.20 +++ /usr/src/bin/chflags/chflags.c 11 Nov 2004 20:04:01 -0000 @@ -62,11 +62,11 @@ FTSENT *p; u_long clear, set; long val; - int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval; + int Hflag, Lflag, Pflag, Rflag, hflag, ch, fts_options, oct, rval; char *flags, *ep; - Hflag = Lflag = Pflag = Rflag = 0; - while ((ch = getopt(argc, argv, "HLPR")) != -1) + Hflag = Lflag = Pflag = Rflag = hflag = 0; + while ((ch = getopt(argc, argv, "HLPRh")) != -1) switch (ch) { case 'H': Hflag = 1; @@ -83,6 +83,9 @@ case 'R': Rflag = 1; break; + case 'h': + hflag = 1; + break; case '?': default: usage(); @@ -95,6 +98,9 @@ if (Rflag) { fts_options = FTS_PHYSICAL; + if (hflag && (Hflag || Lflag)) + errx(1, "the -R%c and -h options may not be " + "specified together", Hflag ? 'H' : 'L'); if (Hflag) fts_options |= FTS_COMFOLLOW; if (Lflag) { @@ -102,7 +108,7 @@ fts_options |= FTS_LOGICAL; } } else - fts_options = FTS_LOGICAL; + fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; flags = *argv; if (*flags >= '0' && *flags <= '7') { @@ -148,17 +154,20 @@ * don't point to anything and ones that we found * doing a physical walk. */ - continue; + if (hflag) + break; + else + continue; default: break; } if (oct) { - if (!chflags(p->fts_accpath, set)) + if (!(hflag ? lchflags : chflags)(p->fts_accpath, set)) continue; } else { p->fts_statp->st_flags |= set; p->fts_statp->st_flags &= clear; - if (!chflags(p->fts_accpath, (u_long)p->fts_statp->st_flags)) + if (!(hflag ? lchflags : chflags)(p->fts_accpath, (u_long)p->fts_statp->st_flags)) continue; } warn("%s", p->fts_path); @@ -173,6 +182,6 @@ usage(void) { (void)fprintf(stderr, - "usage: chflags [-R [-H | -L | -P]] flags file ...\n"); + "usage: chflags [-h] [-R [-H | -L | -P]] flags file ...\n"); exit(1); } >Release-Note: >Audit-Trail: >Unformatted: