Importing sbin/chown

Change-Id: I49950ec241985a8a8f1fc29e01c0212278fbeaa9
This commit is contained in:
Lionel Sambuc 2014-03-26 18:35:18 +01:00
parent 6a309697f4
commit e39e890e08
12 changed files with 671 additions and 238 deletions

View file

@ -4,7 +4,7 @@
SUBDIR= add_route arp ash at backup btrace \ SUBDIR= add_route arp ash at backup btrace \
cawf cd cdprobe cpp \ cawf cd cdprobe cpp \
chmod chown ci cleantmp cmp co \ chmod ci cleantmp cmp co \
compress cp crc cron crontab \ compress cp crc cron crontab \
dd decomp16 DESCRIBE devmand devsize dhcpd \ dd decomp16 DESCRIBE devmand devsize dhcpd \
dhrystone diff diskctl \ dhrystone diff diskctl \

View file

@ -1,8 +0,0 @@
# LSC For Now
NOGCCERROR:= yes
PROG= chown
MAN=
LINKS+= ${BINDIR}/chown ${BINDIR}/chgrp
.include <bsd.prog.mk>

View file

@ -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 <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <minix/minlib.h>
#include <stdio.h>
#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);
}

View file

@ -11,6 +11,7 @@
./bin/[ minix-sys ./bin/[ minix-sys
./bin/cat minix-sys ./bin/cat minix-sys
./bin/cd minix-sys ./bin/cd minix-sys
./bin/chgrp minix-sys
./bin/chmod minix-sys ./bin/chmod minix-sys
./bin/clone minix-sys ./bin/clone minix-sys
./bin/command minix-sys ./bin/command minix-sys
@ -135,6 +136,7 @@
./root/.exrc minix-sys ./root/.exrc minix-sys
./root/.profile minix-sys ./root/.profile minix-sys
./sbin minix-sys ./sbin minix-sys
./sbin/chown minix-sys
./sbin/devman minix-sys ./sbin/devman minix-sys
./sbin/ext2 minix-sys ./sbin/ext2 minix-sys
./sbin/fsck minix-sys ./sbin/fsck minix-sys
@ -242,7 +244,6 @@
./usr/bin/chfn minix-sys ./usr/bin/chfn minix-sys
./usr/bin/chgrp minix-sys ./usr/bin/chgrp minix-sys
./usr/bin/chmod minix-sys ./usr/bin/chmod minix-sys
./usr/bin/chown minix-sys
./usr/bin/chpass minix-sys ./usr/bin/chpass minix-sys
./usr/bin/chsh minix-sys ./usr/bin/chsh minix-sys
./usr/bin/ci minix-sys ./usr/bin/ci minix-sys
@ -4897,6 +4898,7 @@
./usr/preserve minix-sys ./usr/preserve minix-sys
./usr/run minix-sys ./usr/run minix-sys
./usr/sbin minix-sys ./usr/sbin minix-sys
./usr/sbin/chown minix-sys
./usr/sbin/chroot minix-sys ./usr/sbin/chroot minix-sys
./usr/sbin/ds minix-sys ./usr/sbin/ds minix-sys
./usr/sbin/group minix-sys ./usr/sbin/group minix-sys
@ -5025,23 +5027,23 @@
./usr/share/games/fortune/farber minix-sys ./usr/share/games/fortune/farber minix-sys
./usr/share/games/fortune/farber.dat minix-sys ./usr/share/games/fortune/farber.dat minix-sys
./usr/share/games/fortune/fortunes 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 minix-sys
./usr/share/games/fortune/fortunes2.dat minix-sys
./usr/share/games/fortune/fortunes2-o minix-sys ./usr/share/games/fortune/fortunes2-o minix-sys
./usr/share/games/fortune/fortunes2-o.dat 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 minix-sys
./usr/share/games/fortune/limerick.dat minix-sys
./usr/share/games/fortune/limerick-o minix-sys ./usr/share/games/fortune/limerick-o minix-sys
./usr/share/games/fortune/limerick-o.dat 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 minix-sys
./usr/share/games/fortune/netbsd.dat minix-sys
./usr/share/games/fortune/netbsd-o minix-sys ./usr/share/games/fortune/netbsd-o minix-sys
./usr/share/games/fortune/netbsd-o.dat 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 minix-sys
./usr/share/games/fortune/netbsd-tips.dat 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 minix-sys
./usr/share/games/fortune/startrek.dat minix-sys ./usr/share/games/fortune/startrek.dat minix-sys
./usr/share/games/fortune/unamerican-o minix-sys ./usr/share/games/fortune/unamerican-o minix-sys

View file

@ -1,5 +1,5 @@
MAN= add_route.8 backup.8 boot.8 btrace.8 \ 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 \ dhcpd.8 diskctl.8 fbdctl.8 fdisk.8 \
getty.8 halt.8 hgfs.8 httpd.8 ifconfig.8 inet.8 init.8 \ getty.8 halt.8 hgfs.8 httpd.8 ifconfig.8 inet.8 init.8 \
intr.8 irdpd.8 loadramdisk.8 \ intr.8 irdpd.8 loadramdisk.8 \

View file

@ -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).

View file

@ -7,7 +7,7 @@
.include <bsd.own.mk> .include <bsd.own.mk>
SUBDIR= \ SUBDIR= \
\ chown \
fsck init \ fsck init \
mknod nologin \ mknod nologin \
reboot \ reboot \

12
sbin/chown/Makefile Normal file
View file

@ -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 <bsd.prog.mk>

168
sbin/chown/chgrp.1 Normal file
View file

@ -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 .

175
sbin/chown/chown.8 Normal file
View file

@ -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 .

302
sbin/chown/chown.c Normal file
View file

@ -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 <sys/cdefs.h>
#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 <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <locale.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
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);
}

View file

@ -35,8 +35,8 @@ tests_no=`expr 0`
# If root, make sure the setuid tests have the correct permissions # If root, make sure the setuid tests have the correct permissions
# and make the dir bin-owned. # and make the dir bin-owned.
if [ "$ROOT" ] if [ "$ROOT" ]
then chown bin . then /usr/sbin/chown bin .
chown root ${setuids} /usr/sbin/chown root ${setuids}
chmod 4755 ${setuids} chmod 4755 ${setuids}
fi fi