diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-05-08 00:54:29 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-05-08 00:54:29 +0000 |
commit | f1d0592537b0b2774b66b00abcfc194c8a9bd915 (patch) | |
tree | f9c07c171e36b0d81df99eba09235047c8f8015b /usr.sbin/vipw | |
parent | 492da65ed7cf182fa0f8b324a307d3cc85a9a2a9 (diff) | |
download | src-test2-f1d0592537b0b2774b66b00abcfc194c8a9bd915.tar.gz src-test2-f1d0592537b0b2774b66b00abcfc194c8a9bd915.zip |
Notes
Diffstat (limited to 'usr.sbin/vipw')
-rw-r--r-- | usr.sbin/vipw/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/vipw/pw_util.c | 258 | ||||
-rw-r--r-- | usr.sbin/vipw/pw_util.h | 44 | ||||
-rw-r--r-- | usr.sbin/vipw/vipw.c | 95 |
4 files changed, 47 insertions, 353 deletions
diff --git a/usr.sbin/vipw/Makefile b/usr.sbin/vipw/Makefile index ca9f2f5ce787..1dd091a5ce88 100644 --- a/usr.sbin/vipw/Makefile +++ b/usr.sbin/vipw/Makefile @@ -3,7 +3,8 @@ PROG= vipw MAN= vipw.8 -SRCS= pw_util.c vipw.c +DPADD= ${LIBUTIL} +LDADD= -lutil WARNS?= 4 .include <bsd.prog.mk> diff --git a/usr.sbin/vipw/pw_util.c b/usr.sbin/vipw/pw_util.c deleted file mode 100644 index 1c163d2d57ed..000000000000 --- a/usr.sbin/vipw/pw_util.c +++ /dev/null @@ -1,258 +0,0 @@ -/*- - * Copyright (c) 1990, 1993, 1994 - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* - * This file is used by all the "password" programs; vipw(8), chpass(1), - * and passwd(1). - */ - -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#include <err.h> -#include <fcntl.h> -#include <paths.h> -#include <pwd.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "pw_util.h" - -extern char *tempname; -static pid_t editpid = -1; -static int lockfd; -static char _default_editor[] = _PATH_VI; -static char _default_mppath[] = _PATH_PWD; -static char _default_masterpasswd[] = _PATH_MASTERPASSWD; -char *mppath = _default_mppath; -char *masterpasswd = _default_masterpasswd; - -void pw_cont(int); - -void -pw_cont(int sig) -{ - - if (editpid != -1) - kill(editpid, sig); -} - -void -pw_init(void) -{ - struct rlimit rlim; - - /* Unlimited resource limits. */ - rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; - (void)setrlimit(RLIMIT_CPU, &rlim); - (void)setrlimit(RLIMIT_FSIZE, &rlim); - (void)setrlimit(RLIMIT_STACK, &rlim); - (void)setrlimit(RLIMIT_DATA, &rlim); - (void)setrlimit(RLIMIT_RSS, &rlim); - - /* Don't drop core (not really necessary, but GP's). */ - rlim.rlim_cur = rlim.rlim_max = 0; - (void)setrlimit(RLIMIT_CORE, &rlim); - - /* Turn off signals. */ - (void)signal(SIGALRM, SIG_IGN); - (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGINT, SIG_IGN); - (void)signal(SIGPIPE, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGTERM, SIG_IGN); - (void)signal(SIGCONT, pw_cont); - - /* Create with exact permissions. */ - (void)umask(0); -} - -int -pw_lock(void) -{ - /* - * If the master password file doesn't exist, the system is hosed. - * Might as well try to build one. Set the close-on-exec bit so - * that users can't get at the encrypted passwords while editing. - * Open should allow flock'ing the file; see 4.4BSD. XXX - */ - for (;;) { - struct stat st; - - lockfd = open(masterpasswd, O_RDONLY, 0); - if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) - err(1, "%s", masterpasswd); - if (flock(lockfd, LOCK_EX|LOCK_NB)) - errx(1, "the password db file is busy"); - - /* - * If the password file was replaced while we were trying to - * get the lock, our hardlink count will be 0 and we have to - * close and retry. - */ - if (fstat(lockfd, &st) < 0) - errx(1, "fstat() failed"); - if (st.st_nlink != 0) - break; - close(lockfd); - lockfd = -1; - } - return (lockfd); -} - -int -pw_tmp(void) -{ - static char path[MAXPATHLEN]; - int fd; - char *p; - - strncpy(path, masterpasswd, MAXPATHLEN - 1); - path[MAXPATHLEN] = '\0'; - - if ((p = strrchr(path, '/'))) - ++p; - else - p = path; - strcpy(p, "pw.XXXXXX"); - if ((fd = mkstemp(path)) == -1) - err(1, "%s", path); - tempname = path; - return (fd); -} - -int -pw_mkdb(const char *username) -{ - int pstat; - pid_t pid; - - (void)fflush(stderr); - if (!(pid = fork())) { - if(!username) { - warnx("rebuilding the database..."); - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, - tempname, (char *)NULL); - } else { - warnx("updating the database..."); - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, - "-u", username, tempname, (char *)NULL); - } - pw_error(_PATH_PWD_MKDB, 1, 1); - } - pid = waitpid(pid, &pstat, 0); - if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) - return (0); - warnx("done"); - return (1); -} - -void -pw_edit(int notsetuid) -{ - int pstat; - char *p, *editor; - - if (!(editor = getenv("EDITOR"))) - editor = _default_editor; - if ((p = strrchr(editor, '/'))) - ++p; - else - p = editor; - - if (!(editpid = fork())) { - if (notsetuid) { - (void)setgid(getgid()); - (void)setuid(getuid()); - } - errno = 0; - execlp(editor, p, tempname, (char *)NULL); - _exit(errno); - } - for (;;) { - editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); - errno = WEXITSTATUS(pstat); - if (editpid == -1) - pw_error(editor, 1, 1); - else if (WIFSTOPPED(pstat)) - raise(WSTOPSIG(pstat)); - else if (WIFEXITED(pstat) && errno == 0) - break; - else - pw_error(editor, 1, 1); - } - editpid = -1; -} - -void -pw_prompt(void) -{ - int c, first; - - (void)printf("re-edit the password file? [y]: "); - (void)fflush(stdout); - first = c = getchar(); - while (c != '\n' && c != EOF) - c = getchar(); - if (first == 'n') - pw_error(NULL, 0, 0); -} - -void -pw_error(const char *name, int error, int eval) -{ - if (error) { - if (name != NULL) - warn("%s", name); - else - warn(NULL); - } - warnx("password information unchanged"); - (void)unlink(tempname); - exit(eval); -} diff --git a/usr.sbin/vipw/pw_util.h b/usr.sbin/vipw/pw_util.h deleted file mode 100644 index 1000a9abdc7f..000000000000 --- a/usr.sbin/vipw/pw_util.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 1994 - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - * - * @(#)pw_util.h 8.2 (Berkeley) 4/1/94 - * - * $FreeBSD$ - */ - -void pw_edit(int); -void pw_error(const char *, int, int); -void pw_init(void); -int pw_lock(void); -int pw_mkdb(const char *); -void pw_prompt(void); -int pw_tmp(void); diff --git a/usr.sbin/vipw/vipw.c b/usr.sbin/vipw/vipw.c index 6d84990ead1c..5914b62a792f 100644 --- a/usr.sbin/vipw/vipw.c +++ b/usr.sbin/vipw/vipw.c @@ -1,6 +1,13 @@ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -55,37 +62,22 @@ static const char rcsid[] = #include <string.h> #include <unistd.h> -#include "pw_util.h" - -extern char *mppath; -extern char *masterpasswd; -char *tempname; +#include <libutil.h> /* must be after pwd.h */ -static void copyfile(int, int); static void usage(void); int main(int argc, char *argv[]) { - int pfd, tfd; - struct stat begin, end; - int ch; + const char *passwd_dir = NULL; + int ch, pfd, tfd; + char *line; + size_t len; while ((ch = getopt(argc, argv, "d:")) != -1) switch (ch) { case 'd': - if ((masterpasswd = malloc(strlen(optarg) + - strlen(_MASTERPASSWD) + 2)) == NULL) - err(1, NULL); - strcpy(masterpasswd, optarg); - if (masterpasswd[strlen(masterpasswd) - 1] != '/') - strcat(masterpasswd, "/" _MASTERPASSWD); - else - strcat(masterpasswd, _MASTERPASSWD); - if ((mppath = strdup(optarg)) == NULL) - err(1, NULL); - if (mppath[strlen(mppath) - 1] == '/') - mppath[strlen(mppath) - 1] = '\0'; + passwd_dir = optarg; break; case '?': default: @@ -98,49 +90,52 @@ main(int argc, char *argv[]) if (argc != 0) usage(); - pw_init(); - pfd = pw_lock(); - tfd = pw_tmp(); - copyfile(pfd, tfd); + if (pw_init(passwd_dir, NULL) == -1) + err(1, "pw_init()"); + if ((pfd = pw_lock()) == -1) { + pw_fini(); + err(1, "pw_lock()"); + } + if ((tfd = pw_tmp(pfd)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } (void)close(tfd); /* Force umask for partial writes made in the edit phase */ (void)umask(077); for (;;) { - if (stat(tempname, &begin)) - pw_error(tempname, 1, 1); - pw_edit(0); - if (stat(tempname, &end)) - pw_error(tempname, 1, 1); - if (begin.st_mtime == end.st_mtime) { - warnx("no changes made"); - pw_error((char *)NULL, 0, 0); + switch (pw_edit(NULL)) { + case -1: + pw_fini(); + err(1, "pw_edit()"); + case 0: + pw_fini(); + errx(0, "no changes made"); + default: + break; + } + if (pw_mkdb(NULL) == 0) { + pw_fini(); + errx(0, "password list updated"); } - if (pw_mkdb((char *)NULL)) + printf("re-edit the password file? "); + fflush(stdout); + if ((line = fgetln(stdin, &len)) == NULL) { + pw_fini(); + err(1, "fgetln()"); + } + if (len > 0 && (*line == 'N' || *line == 'n')) break; - pw_prompt(); } + pw_fini(); exit(0); } static void -copyfile(int from, int to) -{ - int nr, nw, off; - char buf[8*1024]; - - while ((nr = read(from, buf, sizeof(buf))) > 0) - for (off = 0; off < nr; nr -= nw, off += nw) - if ((nw = write(to, buf + off, nr)) < 0) - pw_error(tempname, 1, 1); - if (nr < 0) - pw_error(masterpasswd, 1, 1); -} - -static void usage(void) { - (void)fprintf(stderr, "usage: vipw [ -d directory ]\n"); + (void)fprintf(stderr, "usage: vipw [-d directory]\n"); exit(1); } |