From owner-svn-src-stable-10@FreeBSD.ORG Mon Jun 1 09:05:00 2015 Return-Path: Delivered-To: svn-src-stable-10@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 59BE689F; Mon, 1 Jun 2015 09:05:00 +0000 (UTC) (envelope-from smh@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 458231453; Mon, 1 Jun 2015 09:05:00 +0000 (UTC) (envelope-from smh@FreeBSD.org) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t51950As047321; Mon, 1 Jun 2015 09:05:00 GMT (envelope-from smh@FreeBSD.org) Received: (from smh@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t5194wLM047286; Mon, 1 Jun 2015 09:04:58 GMT (envelope-from smh@FreeBSD.org) Message-Id: <201506010904.t5194wLM047286@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: smh set sender to smh@FreeBSD.org using -f From: Steven Hartland Date: Mon, 1 Jun 2015 09:04:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r283875 - in stable/10: . bin/chflags bin/chmod usr.sbin/chown X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jun 2015 09:05:00 -0000 Author: smh Date: Mon Jun 1 09:04:57 2015 New Revision: 283875 URL: https://svnweb.freebsd.org/changeset/base/283875 Log: MFC r282208: Standardise chmod, chflags, chown and chgrp recursive symlink processing Relnotes: Yes Sponsored by: Multiplay Modified: stable/10/UPDATING stable/10/bin/chflags/chflags.1 stable/10/bin/chflags/chflags.c stable/10/bin/chmod/chmod.1 stable/10/bin/chmod/chmod.c stable/10/usr.sbin/chown/chgrp.1 stable/10/usr.sbin/chown/chown.8 stable/10/usr.sbin/chown/chown.c Directory Properties: stable/10/ (props changed) Modified: stable/10/UPDATING ============================================================================== --- stable/10/UPDATING Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/UPDATING Mon Jun 1 09:04:57 2015 (r283875) @@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITH stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20150601: + chmod, chflags, chown and chgrp now affect symlinks in -R mode as + defined in symlink(7); previously symlinks were silently ignored. + 20150430: The const qualifier has been removed from iconv(3) to comply with POSIX. The ports tree is aware of this from r384038 onwards. Modified: stable/10/bin/chflags/chflags.1 ============================================================================== --- stable/10/bin/chflags/chflags.1 Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/bin/chflags/chflags.1 Mon Jun 1 09:04:57 2015 (r283875) @@ -32,7 +32,7 @@ .\" @(#)chflags.1 8.4 (Berkeley) 5/2/95 .\" $FreeBSD$ .\" -.Dd April 8, 2013 +.Dd April 20, 2015 .Dt CHFLAGS 1 .Os .Sh NAME @@ -66,8 +66,9 @@ nor modify the exit status to reflect su .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during traversal are not followed.) .It Fl h If the .Ar file @@ -83,8 +84,12 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the file flags for the file hierarchies rooted -in the files instead of just the files themselves. +Change the file flags of the file hierarchies rooted in the files, +instead of just the files themselves. +Beware of unintentionally matching the +.Dq Pa ".." +hard link to the parent directory when using wildcards like +.Dq Li ".*" . .It Fl v Cause .Nm Modified: stable/10/bin/chflags/chflags.c ============================================================================== --- stable/10/bin/chflags/chflags.c Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/bin/chflags/chflags.c Mon Jun 1 09:04:57 2015 (r283875) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -65,7 +66,6 @@ main(int argc, char *argv[]) int Hflag, Lflag, Rflag, fflag, hflag, vflag; int ch, fts_options, oct, rval; char *flags, *ep; - int (*change_flags)(const char *, unsigned long); Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; while ((ch = getopt(argc, argv, "HLPRfhv")) != -1) @@ -104,20 +104,23 @@ main(int argc, char *argv[]) usage(); if (Rflag) { - fts_options = FTS_PHYSICAL; if (hflag) - errx(1, "the -R and -h options " - "may not be specified together"); - if (Hflag) - fts_options |= FTS_COMFOLLOW; + errx(1, "the -R and -h options may not be " + "specified together."); if (Lflag) { - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; + fts_options = FTS_LOGICAL; + } else { + fts_options = FTS_PHYSICAL; + + if (Hflag) { + fts_options |= FTS_COMFOLLOW; + } } - } else - fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; - - change_flags = hflag ? lchflags : chflags; + } else if (hflag) { + fts_options = FTS_PHYSICAL; + } else { + fts_options = FTS_LOGICAL; + } flags = *argv; if (*flags >= '0' && *flags <= '7') { @@ -142,12 +145,21 @@ main(int argc, char *argv[]) err(1, NULL); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + int atflag; + + if ((fts_options & FTS_LOGICAL) || + ((fts_options & FTS_COMFOLLOW) && + p->fts_level == FTS_ROOTLEVEL)) + atflag = 0; + else + atflag = AT_SYMLINK_NOFOLLOW; + switch (p->fts_info) { case FTS_D: /* Change it at FTS_DP if we're recursive. */ if (!Rflag) fts_set(ftsp, p, FTS_SKIP); continue; - case FTS_DNR: /* Warn, chflag, continue. */ + case FTS_DNR: /* Warn, chflags. */ warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; @@ -156,16 +168,6 @@ main(int argc, char *argv[]) warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; continue; - case FTS_SL: /* Ignore. */ - case FTS_SLNONE: - /* - * The only symlinks that end up here are ones that - * don't point to anything and ones that we found - * doing a physical walk. - */ - if (!hflag) - continue; - /* FALLTHROUGH */ default: break; } @@ -175,7 +177,8 @@ main(int argc, char *argv[]) newflags = (p->fts_statp->st_flags | set) & clear; if (newflags == p->fts_statp->st_flags) continue; - if ((*change_flags)(p->fts_accpath, newflags) && !fflag) { + if (chflagsat(AT_FDCWD, p->fts_accpath, newflags, + atflag) == -1 && !fflag) { warn("%s", p->fts_path); rval = 1; } else if (vflag) { Modified: stable/10/bin/chmod/chmod.1 ============================================================================== --- stable/10/bin/chmod/chmod.1 Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/bin/chmod/chmod.1 Mon Jun 1 09:04:57 2015 (r283875) @@ -32,7 +32,7 @@ .\" @(#)chmod.1 8.4 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd January 26, 2009 +.Dd April 20, 2015 .Dt CHMOD 1 .Os .Sh NAME @@ -63,9 +63,9 @@ nor modify the exit status to reflect su .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed by -default.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during tree traversal are not followed.) .It Fl h If the file is a symbolic link, change the mode of the link itself rather than the file that the link points to. @@ -79,8 +79,12 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the modes of the file hierarchies rooted in the files +Change the modes of the file hierarchies rooted in the files, instead of just the files themselves. +Beware of unintentionally matching the +.Dq Pa ".." +hard link to the parent directory when using wildcards like +.Dq Li ".*" . .It Fl v Cause .Nm Modified: stable/10/bin/chmod/chmod.c ============================================================================== --- stable/10/bin/chmod/chmod.c Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/bin/chmod/chmod.c Mon Jun 1 09:04:57 2015 (r283875) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -62,7 +63,7 @@ main(int argc, char *argv[]) FTS *ftsp; FTSENT *p; mode_t *set; - int Hflag, Lflag, Rflag, ch, error, fflag, fts_options, hflag, rval; + int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval; int vflag; char *mode; mode_t newmode; @@ -126,18 +127,23 @@ done: argv += optind; usage(); if (Rflag) { - fts_options = FTS_PHYSICAL; if (hflag) - errx(1, - "the -R and -h options may not be specified together."); - if (Hflag) - fts_options |= FTS_COMFOLLOW; + errx(1, "the -R and -h options may not be " + "specified together."); if (Lflag) { - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; + fts_options = FTS_LOGICAL; + } else { + fts_options = FTS_PHYSICAL; + + if (Hflag) { + fts_options |= FTS_COMFOLLOW; + } } - } else - fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + } else if (hflag) { + fts_options = FTS_PHYSICAL; + } else { + fts_options = FTS_LOGICAL; + } mode = *argv; if ((set = setmode(mode)) == NULL) @@ -146,12 +152,21 @@ done: argv += optind; if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) err(1, "fts_open"); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + int atflag; + + if ((fts_options & FTS_LOGICAL) || + ((fts_options & FTS_COMFOLLOW) && + p->fts_level == FTS_ROOTLEVEL)) + atflag = 0; + else + atflag = AT_SYMLINK_NOFOLLOW; + switch (p->fts_info) { case FTS_D: /* Change it at FTS_DP. */ if (!Rflag) fts_set(ftsp, p, FTS_SKIP); continue; - case FTS_DNR: /* Warn, chmod, continue. */ + case FTS_DNR: /* Warn, chmod. */ warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; @@ -160,16 +175,6 @@ done: argv += optind; warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; continue; - case FTS_SL: /* Ignore. */ - case FTS_SLNONE: - /* - * The only symlinks that end up here are ones that - * don't point to anything and ones that we found - * doing a physical walk. - */ - if (!hflag) - continue; - /* FALLTHROUGH */ default: break; } @@ -182,32 +187,25 @@ done: argv += optind; if (may_have_nfs4acl(p, hflag) == 0 && (newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS)) continue; - if (hflag) - error = lchmod(p->fts_accpath, newmode); - else - error = chmod(p->fts_accpath, newmode); - if (error) { - if (!fflag) { - warn("%s", p->fts_path); - rval = 1; - } - } else { - if (vflag) { - (void)printf("%s", p->fts_path); + if (fchmodat(AT_FDCWD, p->fts_accpath, newmode, atflag) == -1 + && !fflag) { + warn("%s", p->fts_path); + rval = 1; + } else if (vflag) { + (void)printf("%s", p->fts_path); - if (vflag > 1) { - char m1[12], m2[12]; + if (vflag > 1) { + char m1[12], m2[12]; - strmode(p->fts_statp->st_mode, m1); - strmode((p->fts_statp->st_mode & - S_IFMT) | newmode, m2); - (void)printf(": 0%o [%s] -> 0%o [%s]", - p->fts_statp->st_mode, m1, - (p->fts_statp->st_mode & S_IFMT) | - newmode, m2); - } - (void)printf("\n"); + strmode(p->fts_statp->st_mode, m1); + strmode((p->fts_statp->st_mode & + S_IFMT) | newmode, m2); + (void)printf(": 0%o [%s] -> 0%o [%s]", + p->fts_statp->st_mode, m1, + (p->fts_statp->st_mode & S_IFMT) | + newmode, m2); } + (void)printf("\n"); } } if (errno) Modified: stable/10/usr.sbin/chown/chgrp.1 ============================================================================== --- stable/10/usr.sbin/chown/chgrp.1 Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/usr.sbin/chown/chgrp.1 Mon Jun 1 09:04:57 2015 (r283875) @@ -31,7 +31,7 @@ .\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd February 21, 2010 +.Dd April 20, 2015 .Dt CHGRP 1 .Os .Sh NAME @@ -60,8 +60,9 @@ The following options are available: .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during traversal are not followed.) .It Fl L If the .Fl R @@ -72,8 +73,12 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the group ID for the file hierarchies rooted -in the files instead of just the files themselves. +Change the group ID of the file hierarchies rooted in the files, +instead of just the files themselves. +Beware of unintentionally matching the +.Dq Pa ".." +hard link to the parent directory when using wildcards like +.Dq Li ".*" . .It Fl f The force option ignores errors, except for usage errors and does not query about strange modes (unless the user does not have proper permissions). Modified: stable/10/usr.sbin/chown/chown.8 ============================================================================== --- stable/10/usr.sbin/chown/chown.8 Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/usr.sbin/chown/chown.8 Mon Jun 1 09:04:57 2015 (r283875) @@ -28,7 +28,7 @@ .\" @(#)chown.8 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd February 21, 2010 +.Dd April 20, 2015 .Dt CHOWN 8 .Os .Sh NAME @@ -64,8 +64,9 @@ The options are as follows: .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during traversal are not followed.) .It Fl L If the .Fl R @@ -76,8 +77,8 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the user ID and/or the group ID of the specified directory trees -(recursively, including their contents) and files. +Change the user ID and/or the group ID of the file hierarchies rooted +in the files, instead of just the files themselves. Beware of unintentionally matching the .Dq Pa ".." hard link to the parent directory when using wildcards like Modified: stable/10/usr.sbin/chown/chown.c ============================================================================== --- stable/10/usr.sbin/chown/chown.c Mon Jun 1 08:52:11 2015 (r283874) +++ stable/10/usr.sbin/chown/chown.c Mon Jun 1 09:04:57 2015 (r283875) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -119,18 +120,24 @@ main(int argc, char **argv) usage(); 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; - else if (Lflag) { - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; + if (Lflag) { + fts_options = FTS_LOGICAL; + } else { + fts_options = FTS_PHYSICAL; + + if (Hflag) { + fts_options |= FTS_COMFOLLOW; + } } - } else - fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + } else if (hflag) { + fts_options = FTS_PHYSICAL; + } else { + fts_options = FTS_LOGICAL; + } + if (xflag) fts_options |= FTS_XDEV; @@ -156,6 +163,15 @@ main(int argc, char **argv) err(1, NULL); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + int atflag; + + if ((fts_options & FTS_LOGICAL) || + ((fts_options & FTS_COMFOLLOW) && + p->fts_level == FTS_ROOTLEVEL)) + atflag = 0; + else + atflag = AT_SYMLINK_NOFOLLOW; + switch (p->fts_info) { case FTS_D: /* Change it at FTS_DP. */ if (!Rflag) @@ -170,58 +186,44 @@ main(int argc, char **argv) warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; continue; - case FTS_SL: - case FTS_SLNONE: - /* - * The only symlinks that end up here are ones that - * don't point to anything and ones that we found - * doing a physical walk. - */ - if (hflag) - break; - else - continue; default: break; } if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) && (gid == (gid_t)-1 || gid == p->fts_statp->st_gid)) continue; - if ((hflag ? lchown : chown)(p->fts_accpath, uid, gid) == -1) { - if (!fflag) { - chownerr(p->fts_path); - rval = 1; - } - } else { - if (vflag) { - printf("%s", p->fts_path); - if (vflag > 1) { - if (ischown) { - printf(": %ju:%ju -> %ju:%ju", - (uintmax_t) - p->fts_statp->st_uid, - (uintmax_t) - p->fts_statp->st_gid, - (uid == (uid_t)-1) ? - (uintmax_t) - p->fts_statp->st_uid : - (uintmax_t)uid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } else { - printf(": %ju -> %ju", - (uintmax_t) - p->fts_statp->st_gid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } + if (fchownat(AT_FDCWD, p->fts_accpath, uid, gid, atflag) + == -1 && !fflag) { + chownerr(p->fts_path); + rval = 1; + } else if (vflag) { + printf("%s", p->fts_path); + if (vflag > 1) { + if (ischown) { + printf(": %ju:%ju -> %ju:%ju", + (uintmax_t) + p->fts_statp->st_uid, + (uintmax_t) + p->fts_statp->st_gid, + (uid == (uid_t)-1) ? + (uintmax_t) + p->fts_statp->st_uid : + (uintmax_t)uid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); + } else { + printf(": %ju -> %ju", + (uintmax_t) + p->fts_statp->st_gid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); } - printf("\n"); } + printf("\n"); } } if (errno)