From e39e890e081e80fafba29a21d53b6984038a7aaa Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Wed, 26 Mar 2014 18:35:18 +0100 Subject: [PATCH] Importing sbin/chown Change-Id: I49950ec241985a8a8f1fc29e01c0212278fbeaa9 --- commands/Makefile | 2 +- commands/chown/Makefile | 8 - commands/chown/chown.c | 177 --------------------- distrib/sets/lists/minix/mi | 16 +- man/man8/Makefile | 2 +- man/man8/chown.8 | 41 ----- sbin/Makefile | 2 +- sbin/chown/Makefile | 12 ++ sbin/chown/chgrp.1 | 168 ++++++++++++++++++++ sbin/chown/chown.8 | 175 +++++++++++++++++++++ sbin/chown/chown.c | 302 ++++++++++++++++++++++++++++++++++++ test/run | 4 +- 12 files changed, 671 insertions(+), 238 deletions(-) delete mode 100644 commands/chown/Makefile delete mode 100644 commands/chown/chown.c delete mode 100644 man/man8/chown.8 create mode 100644 sbin/chown/Makefile create mode 100644 sbin/chown/chgrp.1 create mode 100644 sbin/chown/chown.8 create mode 100644 sbin/chown/chown.c diff --git a/commands/Makefile b/commands/Makefile index 04f9c536e..632586a99 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -4,7 +4,7 @@ SUBDIR= add_route arp ash at backup btrace \ cawf cd cdprobe cpp \ - chmod chown ci cleantmp cmp co \ + chmod ci cleantmp cmp co \ compress cp crc cron crontab \ dd decomp16 DESCRIBE devmand devsize dhcpd \ dhrystone diff diskctl \ diff --git a/commands/chown/Makefile b/commands/chown/Makefile deleted file mode 100644 index 2c728982b..000000000 --- a/commands/chown/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# LSC For Now -NOGCCERROR:= yes -PROG= chown -MAN= - -LINKS+= ${BINDIR}/chown ${BINDIR}/chgrp - -.include diff --git a/commands/chown/chown.c b/commands/chown/chown.c deleted file mode 100644 index 1ea90f8c5..000000000 --- a/commands/chown/chown.c +++ /dev/null @@ -1,177 +0,0 @@ -/* chown/chgrp - Change file ownership Author: V. Archer */ - -/* Copyright 1991 by Vincent Archer - * You may freely redistribute this software, in source or binary - * form, provided that you do not alter this copyright mention in any - * way. - */ - -/* Changed 3 Feb 93 by Kees J. Bot: setuid execution nonsense removed. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef S_ISLNK -#define S_ISLNK(mode) 0 -#define lstat stat -#endif - -#define S_IUGID (S_ISUID|S_ISGID) - -/* Global variables, such as flags and path names */ -int gflag, oflag, rflag, error, hflag = 0; -char *pgmname, path[PATH_MAX + 1]; -uid_t nuid; -gid_t ngid; - -int main(int argc, char *argv[]); -void do_chown(char *file); -void usage(void); - -/* Main module. If chown(1) is invoked as chgrp(1), the behaviour is nearly - * identical, except that the default when a single name is given as an - * argument is to take a group id rather than an user id. This allow the - * non-Posix "chgrp user:group file". - */ -int main(int argc, char *argv[]) -{ - char *id, *id2; - struct group *grp; - struct passwd *pwp; - int ch; - - if (pgmname = strrchr(*argv, '/')) - pgmname++; - else - pgmname = *argv; - gflag = strcmp(pgmname, "chgrp"); - - while((ch = getopt(argc, argv, "Rh")) != -1) { - switch(ch) { - case 'R': - rflag = 1; - break; - case 'h': - hflag = 1; - break; - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc < 2) usage(); - - id = *argv++; - argc--; - if (id2 = strchr(id, ':')) *id2++ = '\0'; - if (!id2 && !gflag) { - id2 = id; - id = 0; - } - if (id) { - if (isdigit(*id)) - nuid = atoi(id); - else { - if (!(pwp = getpwnam(id))) { - std_err(id); - std_err(": unknown user name\n"); - exit(1); - } - nuid = pwp->pw_uid; - } - oflag = 1; - } else - oflag = 0; - - if (id2) { - if (isdigit(*id2)) - ngid = atoi(id2); - else { - if (!(grp = getgrnam(id2))) { - std_err(id2); - std_err(": unknown group name\n"); - exit(1); - } - ngid = grp->gr_gid; - } - gflag = 1; - } else - gflag = 0; - - error = 0; - while (argc--) do_chown(*argv++); - return(error); -} - -/* Apply the user/group modification here. - */ -void do_chown(char *file) -{ - DIR *dirp; - struct dirent *entp; - char *namp; - struct stat st; - - if (lstat(file, &st)) { - perror(file); - error = 1; - return; - } - - if (S_ISLNK(st.st_mode) && rflag) return; /* Note: violates POSIX. */ - - if (S_ISLNK(st.st_mode) && hflag) { - fprintf(stderr, "chown: cannot lchown %s\n", file); - error = 1; - } - - if (chown(file, oflag ? nuid : st.st_uid, gflag ? ngid : st.st_gid)) { - perror(file); - error = 1; - } - - if (S_ISDIR(st.st_mode) && rflag) { - if (!(dirp = opendir(file))) { - perror(file); - error = 1; - return; - } - if (path != file) strcpy(path, file); - namp = path + strlen(path); - *namp++ = '/'; - while (entp = readdir(dirp)) - if (entp->d_name[0] != '.' || - (entp->d_name[1] && - (entp->d_name[1] != '.' || entp->d_name[2]))) { - strcpy(namp, entp->d_name); - do_chown(path); - } - closedir(dirp); - *--namp = '\0'; - } -} - -/* Posix prototype of the chown/chgrp function */ -void usage() -{ - std_err("Usage: "); - std_err(pgmname); - std_err(gflag ? " owner[:group]" : " [owner:]group"); - std_err(" file...\n"); - exit(1); -} diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 1faf7d093..bdc320528 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -11,6 +11,7 @@ ./bin/[ minix-sys ./bin/cat minix-sys ./bin/cd minix-sys +./bin/chgrp minix-sys ./bin/chmod minix-sys ./bin/clone minix-sys ./bin/command minix-sys @@ -135,6 +136,7 @@ ./root/.exrc minix-sys ./root/.profile minix-sys ./sbin minix-sys +./sbin/chown minix-sys ./sbin/devman minix-sys ./sbin/ext2 minix-sys ./sbin/fsck minix-sys @@ -242,7 +244,6 @@ ./usr/bin/chfn minix-sys ./usr/bin/chgrp minix-sys ./usr/bin/chmod minix-sys -./usr/bin/chown minix-sys ./usr/bin/chpass minix-sys ./usr/bin/chsh minix-sys ./usr/bin/ci minix-sys @@ -4897,6 +4898,7 @@ ./usr/preserve minix-sys ./usr/run minix-sys ./usr/sbin minix-sys +./usr/sbin/chown minix-sys ./usr/sbin/chroot minix-sys ./usr/sbin/ds minix-sys ./usr/sbin/group minix-sys @@ -5025,23 +5027,23 @@ ./usr/share/games/fortune/farber minix-sys ./usr/share/games/fortune/farber.dat minix-sys ./usr/share/games/fortune/fortunes minix-sys -./usr/share/games/fortune/fortunes-o minix-sys -./usr/share/games/fortune/fortunes-o.dat minix-sys -./usr/share/games/fortune/fortunes.dat minix-sys ./usr/share/games/fortune/fortunes2 minix-sys +./usr/share/games/fortune/fortunes2.dat minix-sys ./usr/share/games/fortune/fortunes2-o minix-sys ./usr/share/games/fortune/fortunes2-o.dat minix-sys -./usr/share/games/fortune/fortunes2.dat minix-sys +./usr/share/games/fortune/fortunes.dat minix-sys +./usr/share/games/fortune/fortunes-o minix-sys +./usr/share/games/fortune/fortunes-o.dat minix-sys ./usr/share/games/fortune/limerick minix-sys +./usr/share/games/fortune/limerick.dat minix-sys ./usr/share/games/fortune/limerick-o minix-sys ./usr/share/games/fortune/limerick-o.dat minix-sys -./usr/share/games/fortune/limerick.dat minix-sys ./usr/share/games/fortune/netbsd minix-sys +./usr/share/games/fortune/netbsd.dat minix-sys ./usr/share/games/fortune/netbsd-o minix-sys ./usr/share/games/fortune/netbsd-o.dat minix-sys ./usr/share/games/fortune/netbsd-tips minix-sys ./usr/share/games/fortune/netbsd-tips.dat minix-sys -./usr/share/games/fortune/netbsd.dat minix-sys ./usr/share/games/fortune/startrek minix-sys ./usr/share/games/fortune/startrek.dat minix-sys ./usr/share/games/fortune/unamerican-o minix-sys diff --git a/man/man8/Makefile b/man/man8/Makefile index 4f7ec5d12..b8ca9ead2 100644 --- a/man/man8/Makefile +++ b/man/man8/Makefile @@ -1,5 +1,5 @@ MAN= add_route.8 backup.8 boot.8 btrace.8 \ - cdprobe.8 chown.8 cleantmp.8 config.8 cron.8 \ + cdprobe.8 cleantmp.8 config.8 cron.8 \ dhcpd.8 diskctl.8 fbdctl.8 fdisk.8 \ getty.8 halt.8 hgfs.8 httpd.8 ifconfig.8 inet.8 init.8 \ intr.8 irdpd.8 loadramdisk.8 \ diff --git a/man/man8/chown.8 b/man/man8/chown.8 deleted file mode 100644 index 5fe9770d4..000000000 --- a/man/man8/chown.8 +++ /dev/null @@ -1,41 +0,0 @@ -.TH CHOWN 8 -.SH NAME -chown \- change owner -.SH SYNOPSIS -\fBchown [\fB\-R\fR] \fIowner\fR[:\fIgroup\fR] \fIfile\fR ...\fR -.br -.de FL -.TP -\\fB\\$1\\fR -\\$2 -.. -.de EX -.TP 20 -\\fB\\$1\\fR -# \\$2 -.. -.SH OPTIONS -.TP 5 -.B \-R -# Change directory hierarchies -.SH EXAMPLES -.TP 20 -.B chown ast file1 file2 -# Make \fIast\fR the owner of the files -.TP 20 -.B chown \-R ast:other dir -# Change the owner and group of all files in dir -.SH DESCRIPTION -.PP -The owner field (and optionally group field) of the named files is changed -to -.I owner -(i.e., login name specified) and -.I group . -Alternatively, a decimal uid(gid) may be specified instead of a user name. -Only the superuser may execute this command. -.SH "SEE ALSO" -.BR chgrp (1), -.BR chmod (1), -.BR ls (1), -.BR chown (2). diff --git a/sbin/Makefile b/sbin/Makefile index fe348f0a3..ee3735542 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -7,7 +7,7 @@ .include SUBDIR= \ - \ + chown \ fsck init \ mknod nologin \ reboot \ diff --git a/sbin/chown/Makefile b/sbin/chown/Makefile new file mode 100644 index 000000000..e3a535757 --- /dev/null +++ b/sbin/chown/Makefile @@ -0,0 +1,12 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $NetBSD: Makefile,v 1.6 2011/01/13 23:44:11 haad Exp $ + +PROG= chown +CPPFLAGS+=-DSUPPORT_DOT +MAN= chgrp.1 chown.8 +SYMLINKS+= ${BINDIR}/chown /bin/chgrp + +SYMLINKS+= ${BINDIR}/chown /usr/bin/chgrp +SYMLINKS+= ${BINDIR}/chown /usr/sbin/chown + +.include diff --git a/sbin/chown/chgrp.1 b/sbin/chown/chgrp.1 new file mode 100644 index 000000000..c7b492d6a --- /dev/null +++ b/sbin/chown/chgrp.1 @@ -0,0 +1,168 @@ +.\" Copyright (c) 1983, 1990, 1993, 1994, 2003 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the Institute of Electrical and Electronics Engineers, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" from: @(#)chgrp.1 8.3 (Berkeley) 3/31/94 +.\" $NetBSD: chgrp.1,v 1.5 2012/10/22 18:02:26 christos Exp $ +.\" +.Dd October 22, 2012 +.Dt CHGRP 1 +.Os +.Sh NAME +.Nm chgrp +.Nd change group +.Sh SYNOPSIS +.Nm +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl fhv +.Ar group +.Ar +.Nm +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl fhv +.Fl Fl reference=rfile +.Ar +.Sh DESCRIPTION +The +.Nm +utility sets the group ID of the file named by each +.Ar file +operand to the +.Ar group +ID specified by the group operand, +or to the group of the given +.Ar rfile , +specified by the +.Fl Fl reference +argument. +.Pp +Options: +.Bl -tag -width Ds +.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.) +.It Fl L +If the +.Fl R +option is specified, all symbolic links are followed. +.It Fl P +If the +.Fl R +option is specified, no symbolic links are followed. +.It Fl R +Change the group ID for the file hierarchies rooted +in the files instead of just the files themselves. +.It Fl f +The force option ignores errors, except for usage errors and doesn't +query about strange modes (unless the user does not have proper permissions). +.It Fl h +If +.Ar file +is a symbolic link, the group of the link is changed. +.It Fl v +Cause +.Nm +to be verbose, showing files as they are processed. +.El +.Pp +If +.Fl h +is not given, unless the +.Fl H +or +.Fl L +option is set, +.Nm +on a symbolic link always succeeds and has no effect. +The +.Fl H , +.Fl L +and +.Fl P +options are ignored unless the +.Fl R +option is specified. +In addition, these options override each other and the +command's actions are determined by the last one specified. +.Pp +The +.Ar group +operand can be either a group name from the group database, +or a numeric group ID. +Since it is valid to have a group name that is numeric (and +doesn't have the numeric ID that matches its name) the name lookup +is always done first. +Preceding the ID with a ``#'' character will force it to be taken +as a number. +.Pp +The user invoking +.Nm +must belong to the specified group and be the owner of the file, +or be the super-user. +.Pp +Unless invoked by the super-user, +.Nm +clears the set-user-id and set-group-id bits on a file to prevent +accidental or mischievous creation of set-user-id or set-group-id +programs. +.Pp +The +.Nm +utility exits 0 on success, and \*[Gt]0 if an error occurs. +.Sh FILES +.Bl -tag -width /etc/group -compact +.It Pa /etc/group +Group ID file +.El +.Sh SEE ALSO +.Xr chown 2 , +.Xr lchown 2 , +.Xr fts 3 , +.Xr group 5 , +.Xr passwd 5 , +.Xr symlink 7 , +.Xr chown 8 +.Sh STANDARDS +The +.Nm +utility is expected to be POSIX 1003.2 compatible. +.Pp +The +.Fl v +option and the use of ``#'' to force a numeric group ID +are extensions to +.St -p1003.2 . diff --git a/sbin/chown/chown.8 b/sbin/chown/chown.8 new file mode 100644 index 000000000..eafec7d57 --- /dev/null +++ b/sbin/chown/chown.8 @@ -0,0 +1,175 @@ +.\" Copyright (c) 1990, 1991, 1993, 1994, 2003 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" from: @(#)chown.8 8.3 (Berkeley) 3/31/94 +.\" $NetBSD: chown.8,v 1.6 2012/10/23 17:30:59 wiz Exp $ +.\" +.Dd October 22, 2012 +.Dt CHOWN 8 +.Os +.Sh NAME +.Nm chown +.Nd change file owner and group +.Sh SYNOPSIS +.Nm +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl fhv +.Ar owner Ns Op Ar :group +.Ar +.Nm +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl fhv +.Ar :group +.Ar +.Nm +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl fhv +.Fl Fl reference=rfile +.Ar +.Sh DESCRIPTION +.Nm +sets the user ID and/or the group ID of the specified files. +.Pp +The options are as follows: +.Bl -tag -width Ds +.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.) +.It Fl L +If the +.Fl R +option is specified, all symbolic links are followed. +.It Fl P +If the +.Fl R +option is specified, no symbolic links are followed. +.It Fl R +Change the user ID and/or the group ID for the file hierarchies rooted +in the files instead of just the files themselves. +.It Fl f +Don't report any failure to change file owner or group, nor modify +the exit status to reflect such failures. +.It Fl h +If +.Ar file +is a symbolic link, the owner and/or group of the link is changed. +.It Fl v +Cause +.Nm +to be verbose, showing files as they are processed. +.El +.Pp +The +.Fl H , +.Fl L +and +.Fl P +options are ignored unless the +.Fl R +option is specified. +In addition, these options override each other and the +command's actions are determined by the last one specified. +.Pp +The +.Fl L +option cannot be used together with the +.Fl h +option. +.Pp +The +.Ar owner +and +.Ar group +operands are both optional, however, one must be specified; alternatively, +both the owner and group may be specified using a reference +.Ar rfile +specified using the +.Fl Fl reference +argument. +If the +.Ar group +operand is specified, it must be preceded by a colon (``:'') character. +.Pp +The +.Ar owner +may be either a user name or a numeric user ID. +The +.Ar group +may be either a group name or a numeric group ID. +Since it is valid to have a user or group name that is numeric (and +doesn't have the numeric ID that matches its name) the name lookup +is always done first. +Preceding an ID with a ``#'' character will force it to be taken +as a number. +.Pp +The ownership of a file may only be altered by a super-user for +obvious security reasons. +.Pp +Unless invoked by the super-user, +.Nm +clears the set-user-id and set-group-id bits on a file to prevent +accidental or mischievous creation of set-user-id and set-group-id +programs. +.Pp +The +.Nm +utility exits 0 on success, and \*[Gt]0 if an error occurs. +.Sh COMPATIBILITY +Previous versions of the +.Nm +utility used the dot (``.'') character to distinguish the group name. +This has been changed to be a colon (``:'') character so that user and +group names may contain the dot character. +.Sh SEE ALSO +.Xr chflags 1 , +.Xr chgrp 1 , +.Xr find 1 , +.Xr chown 2 , +.Xr lchown 2 , +.Xr fts 3 , +.Xr symlink 7 +.Sh STANDARDS +The +.Nm +command is expected to be POSIX 1003.2 compliant. +.Pp +The +.Fl v +option and the use of ``#'' to force a numeric lookup +are extensions to +.St -p1003.2 . diff --git a/sbin/chown/chown.c b/sbin/chown/chown.c new file mode 100644 index 000000000..ee46eee35 --- /dev/null +++ b/sbin/chown/chown.c @@ -0,0 +1,302 @@ +/* $NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $ */ + +/* + * Copyright (c) 1988, 1993, 1994, 2003 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94"; +#else +__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $"); +#endif +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void a_gid(const char *); +static void a_uid(const char *); +static id_t id(const char *, const char *); +__dead static void usage(void); + +static uid_t uid; +static gid_t gid; +static int ischown; +static const char *myname; + +struct option chown_longopts[] = { + { "reference", required_argument, 0, + 1 }, + { NULL, 0, 0, + 0 }, +}; + +int +main(int argc, char **argv) +{ + FTS *ftsp; + FTSENT *p; + int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag; + char *cp, *reference; + int (*change_owner)(const char *, uid_t, gid_t); + + setprogname(*argv); + + (void)setlocale(LC_ALL, ""); + + myname = getprogname(); + ischown = (myname[2] == 'o'); + reference = NULL; + + Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; + while ((ch = getopt_long(argc, argv, "HLPRfhv", + chown_longopts, NULL)) != -1) + switch (ch) { + case 1: + reference = optarg; + break; + case 'H': + Hflag = 1; + Lflag = 0; + break; + case 'L': + Lflag = 1; + Hflag = 0; + break; + case 'P': + Hflag = Lflag = 0; + break; + case 'R': + Rflag = 1; + break; + case 'f': + fflag = 1; + break; + case 'h': + /* + * In System V the -h option causes chown/chgrp to + * change the owner/group of the symbolic link. + * 4.4BSD's symbolic links didn't have owners/groups, + * so it was an undocumented noop. + * In NetBSD 1.3, lchown(2) is introduced. + */ + hflag = 1; + break; + case 'v': + vflag = 1; + break; + case '?': + default: + usage(); + } + argv += optind; + argc -= optind; + + if (argc == 0 || (argc == 1 && reference == NULL)) + usage(); + + fts_options = FTS_PHYSICAL; + if (Rflag) { + if (Hflag) + fts_options |= FTS_COMFOLLOW; + if (Lflag) { + if (hflag) + errx(EXIT_FAILURE, + "the -L and -h options " + "may not be specified together."); + fts_options &= ~FTS_PHYSICAL; + fts_options |= FTS_LOGICAL; + } + } else if (!hflag) + fts_options |= FTS_COMFOLLOW; + + uid = (uid_t)-1; + gid = (gid_t)-1; + if (reference == NULL) { + if (ischown) { + if ((cp = strchr(*argv, ':')) != NULL) { + *cp++ = '\0'; + a_gid(cp); + } +#ifdef SUPPORT_DOT + else if ((cp = strrchr(*argv, '.')) != NULL) { + if (uid_from_user(*argv, &uid) == -1) { + *cp++ = '\0'; + a_gid(cp); + } + } +#endif + a_uid(*argv); + } else + a_gid(*argv); + argv++; + } else { + struct stat st; + + if (stat(reference, &st) == -1) + err(EXIT_FAILURE, "Cannot stat `%s'", reference); + if (ischown) + uid = st.st_uid; + gid = st.st_gid; + } + + if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) + err(EXIT_FAILURE, "fts_open"); + + for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) { + change_owner = chown; + switch (p->fts_info) { + case FTS_D: + if (!Rflag) /* Change it at FTS_DP. */ + fts_set(ftsp, p, FTS_SKIP); + continue; + case FTS_DNR: /* Warn, chown, continue. */ + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = EXIT_FAILURE; + break; + case FTS_ERR: /* Warn, continue. */ + case FTS_NS: + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = EXIT_FAILURE; + continue; + case FTS_SL: /* Ignore unless -h. */ + /* + * All symlinks we found while doing a physical + * walk end up here. + */ + if (!hflag) + continue; + /* + * Note that if we follow a symlink, fts_info is + * not FTS_SL but FTS_F or whatever. And we should + * use lchown only for FTS_SL and should use chown + * for others. + */ + change_owner = lchown; + break; + case FTS_SLNONE: /* Ignore. */ + /* + * The only symlinks that end up here are ones that + * don't point to anything. Note that if we are + * doing a phisycal walk, we never reach here unless + * we asked to follow explicitly. + */ + continue; + default: + break; + } + + if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) { + warn("%s", p->fts_path); + rval = EXIT_FAILURE; + } else { + if (vflag) + printf("%s\n", p->fts_path); + } + } + if (errno) + err(EXIT_FAILURE, "fts_read"); + exit(rval); + /* NOTREACHED */ +} + +static void +a_gid(const char *s) +{ + struct group *gr; + + if (*s == '\0') /* Argument was "uid[:.]". */ + return; + gr = *s == '#' ? NULL : getgrnam(s); + if (gr == NULL) + gid = id(s, "group"); + else + gid = gr->gr_gid; + return; +} + +static void +a_uid(const char *s) +{ + if (*s == '\0') /* Argument was "[:.]gid". */ + return; + if (*s == '#' || uid_from_user(s, &uid) == -1) { + uid = id(s, "user"); + } + return; +} + +static id_t +id(const char *name, const char *type) +{ + id_t val; + char *ep; + + errno = 0; + if (*name == '#') + name++; + val = (id_t)strtoul(name, &ep, 10); + if (errno) + err(EXIT_FAILURE, "%s", name); + if (*ep != '\0') + errx(EXIT_FAILURE, "%s: invalid %s name", name, type); + return (val); +} + +static void +usage(void) +{ + + (void)fprintf(stderr, + "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n" + "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n", + myname, ischown ? "owner:group|owner|:group" : "group", + myname); + exit(EXIT_FAILURE); +} diff --git a/test/run b/test/run index 223652033..80d07c16e 100755 --- a/test/run +++ b/test/run @@ -35,8 +35,8 @@ tests_no=`expr 0` # If root, make sure the setuid tests have the correct permissions # and make the dir bin-owned. if [ "$ROOT" ] -then chown bin . - chown root ${setuids} +then /usr/sbin/chown bin . + /usr/sbin/chown root ${setuids} chmod 4755 ${setuids} fi