11553Srgrimes/*
21553Srgrimes * Copyright (c) 1987, 1993, 1994
31553Srgrimes *	The Regents of the University of California.  All rights reserved.
496201Sdes * Copyright (c) 2002 Networks Associates Technology, Inc.
596201Sdes * All rights reserved.
61553Srgrimes *
796201Sdes * Portions of this software were developed for the FreeBSD Project by
896201Sdes * ThinkSec AS and NAI Labs, the Security Research Division of Network
996201Sdes * Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
1096201Sdes * ("CBOSS"), as part of the DARPA CHATS research program.
1196201Sdes *
121553Srgrimes * Redistribution and use in source and binary forms, with or without
131553Srgrimes * modification, are permitted provided that the following conditions
141553Srgrimes * are met:
151553Srgrimes * 1. Redistributions of source code must retain the above copyright
161553Srgrimes *    notice, this list of conditions and the following disclaimer.
171553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
181553Srgrimes *    notice, this list of conditions and the following disclaimer in the
191553Srgrimes *    documentation and/or other materials provided with the distribution.
201553Srgrimes * 4. Neither the name of the University nor the names of its contributors
211553Srgrimes *    may be used to endorse or promote products derived from this software
221553Srgrimes *    without specific prior written permission.
231553Srgrimes *
241553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341553Srgrimes * SUCH DAMAGE.
351553Srgrimes */
361553Srgrimes
37114601Sobrien#if 0
381553Srgrimes#ifndef lint
3930765Scharnierstatic const char copyright[] =
401553Srgrimes"@(#) Copyright (c) 1987, 1993, 1994\n\
411553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
421553Srgrimes#endif /* not lint */
431553Srgrimes
441553Srgrimes#ifndef lint
451553Srgrimesstatic char sccsid[] = "@(#)vipw.c	8.3 (Berkeley) 4/2/94";
46114601Sobrien#endif /* not lint */
4730765Scharnier#endif
48114601Sobrien#include <sys/cdefs.h>
49114601Sobrien__FBSDID("$FreeBSD$");
501553Srgrimes
511553Srgrimes#include <sys/types.h>
521553Srgrimes#include <sys/stat.h>
531553Srgrimes
541553Srgrimes#include <err.h>
551553Srgrimes#include <pwd.h>
561553Srgrimes#include <stdio.h>
571553Srgrimes#include <stdlib.h>
581553Srgrimes#include <string.h>
591553Srgrimes#include <unistd.h>
601553Srgrimes
6196201Sdes#include <libutil.h>		/* must be after pwd.h */
621553Srgrimes
6390233Sdesstatic void	usage(void);
641553Srgrimes
651553Srgrimesint
6690233Sdesmain(int argc, char *argv[])
671553Srgrimes{
6896201Sdes	const char *passwd_dir = NULL;
6996201Sdes	int ch, pfd, tfd;
7096201Sdes	char *line;
7196201Sdes	size_t len;
721553Srgrimes
7348232Ssheldonh	while ((ch = getopt(argc, argv, "d:")) != -1)
741553Srgrimes		switch (ch) {
7548232Ssheldonh		case 'd':
7696201Sdes			passwd_dir = optarg;
7748232Ssheldonh			break;
781553Srgrimes		case '?':
791553Srgrimes		default:
801553Srgrimes			usage();
811553Srgrimes		}
828857Srgrimes
831553Srgrimes	argc -= optind;
841553Srgrimes	argv += optind;
851553Srgrimes
861553Srgrimes	if (argc != 0)
871553Srgrimes		usage();
881553Srgrimes
8996201Sdes	if (pw_init(passwd_dir, NULL) == -1)
9096201Sdes		err(1, "pw_init()");
9196201Sdes	if ((pfd = pw_lock()) == -1) {
9296201Sdes		pw_fini();
9396201Sdes		err(1, "pw_lock()");
9496201Sdes	}
9596201Sdes	if ((tfd = pw_tmp(pfd)) == -1) {
9696201Sdes		pw_fini();
9796201Sdes		err(1, "pw_tmp()");
9896201Sdes	}
991553Srgrimes	(void)close(tfd);
10048241Spb	/* Force umask for partial writes made in the edit phase */
10148241Spb	(void)umask(077);
1021553Srgrimes
1031553Srgrimes	for (;;) {
104102234Simp		switch (pw_edit(0)) {
10596201Sdes		case -1:
10696201Sdes			pw_fini();
10796201Sdes			err(1, "pw_edit()");
10896201Sdes		case 0:
10996201Sdes			pw_fini();
11096201Sdes			errx(0, "no changes made");
11196201Sdes		default:
11296201Sdes			break;
1131553Srgrimes		}
11496201Sdes		if (pw_mkdb(NULL) == 0) {
11596201Sdes			pw_fini();
11696201Sdes			errx(0, "password list updated");
11796201Sdes		}
11896201Sdes		printf("re-edit the password file? ");
11996201Sdes		fflush(stdout);
12096201Sdes		if ((line = fgetln(stdin, &len)) == NULL) {
12196201Sdes			pw_fini();
12296201Sdes			err(1, "fgetln()");
12396201Sdes		}
12496201Sdes		if (len > 0 && (*line == 'N' || *line == 'n'))
1251553Srgrimes			break;
1261553Srgrimes	}
12796201Sdes	pw_fini();
1281553Srgrimes	exit(0);
1291553Srgrimes}
1301553Srgrimes
13190233Sdesstatic void
13290233Sdesusage(void)
1331553Srgrimes{
1341553Srgrimes
13596201Sdes	(void)fprintf(stderr, "usage: vipw [-d directory]\n");
1361553Srgrimes	exit(1);
1371553Srgrimes}
138