vipw.c revision 96201
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 * 3. All advertising materials mentioning features or use of this software
211553Srgrimes *    must display the following acknowledgement:
221553Srgrimes *	This product includes software developed by the University of
231553Srgrimes *	California, Berkeley and its contributors.
241553Srgrimes * 4. Neither the name of the University nor the names of its contributors
251553Srgrimes *    may be used to endorse or promote products derived from this software
261553Srgrimes *    without specific prior written permission.
271553Srgrimes *
281553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
291553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
301553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
311553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
321553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
331553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
341553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
351553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
361553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
371553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
381553Srgrimes * SUCH DAMAGE.
391553Srgrimes */
401553Srgrimes
411553Srgrimes#ifndef lint
4230765Scharnierstatic const char copyright[] =
431553Srgrimes"@(#) Copyright (c) 1987, 1993, 1994\n\
441553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
451553Srgrimes#endif /* not lint */
461553Srgrimes
471553Srgrimes#ifndef lint
4830765Scharnier#if 0
491553Srgrimesstatic char sccsid[] = "@(#)vipw.c	8.3 (Berkeley) 4/2/94";
5030765Scharnier#endif
5130765Scharnierstatic const char rcsid[] =
5250479Speter  "$FreeBSD: head/usr.sbin/vipw/vipw.c 96201 2002-05-08 00:54:29Z des $";
531553Srgrimes#endif /* not lint */
541553Srgrimes
551553Srgrimes#include <sys/types.h>
561553Srgrimes#include <sys/stat.h>
571553Srgrimes
581553Srgrimes#include <err.h>
591553Srgrimes#include <pwd.h>
601553Srgrimes#include <stdio.h>
611553Srgrimes#include <stdlib.h>
621553Srgrimes#include <string.h>
631553Srgrimes#include <unistd.h>
641553Srgrimes
6596201Sdes#include <libutil.h>		/* must be after pwd.h */
661553Srgrimes
6790233Sdesstatic void	usage(void);
681553Srgrimes
691553Srgrimesint
7090233Sdesmain(int argc, char *argv[])
711553Srgrimes{
7296201Sdes	const char *passwd_dir = NULL;
7396201Sdes	int ch, pfd, tfd;
7496201Sdes	char *line;
7596201Sdes	size_t len;
761553Srgrimes
7748232Ssheldonh	while ((ch = getopt(argc, argv, "d:")) != -1)
781553Srgrimes		switch (ch) {
7948232Ssheldonh		case 'd':
8096201Sdes			passwd_dir = optarg;
8148232Ssheldonh			break;
821553Srgrimes		case '?':
831553Srgrimes		default:
841553Srgrimes			usage();
851553Srgrimes		}
868857Srgrimes
871553Srgrimes	argc -= optind;
881553Srgrimes	argv += optind;
891553Srgrimes
901553Srgrimes	if (argc != 0)
911553Srgrimes		usage();
921553Srgrimes
9396201Sdes	if (pw_init(passwd_dir, NULL) == -1)
9496201Sdes		err(1, "pw_init()");
9596201Sdes	if ((pfd = pw_lock()) == -1) {
9696201Sdes		pw_fini();
9796201Sdes		err(1, "pw_lock()");
9896201Sdes	}
9996201Sdes	if ((tfd = pw_tmp(pfd)) == -1) {
10096201Sdes		pw_fini();
10196201Sdes		err(1, "pw_tmp()");
10296201Sdes	}
1031553Srgrimes	(void)close(tfd);
10448241Spb	/* Force umask for partial writes made in the edit phase */
10548241Spb	(void)umask(077);
1061553Srgrimes
1071553Srgrimes	for (;;) {
10896201Sdes		switch (pw_edit(NULL)) {
10996201Sdes		case -1:
11096201Sdes			pw_fini();
11196201Sdes			err(1, "pw_edit()");
11296201Sdes		case 0:
11396201Sdes			pw_fini();
11496201Sdes			errx(0, "no changes made");
11596201Sdes		default:
11696201Sdes			break;
1171553Srgrimes		}
11896201Sdes		if (pw_mkdb(NULL) == 0) {
11996201Sdes			pw_fini();
12096201Sdes			errx(0, "password list updated");
12196201Sdes		}
12296201Sdes		printf("re-edit the password file? ");
12396201Sdes		fflush(stdout);
12496201Sdes		if ((line = fgetln(stdin, &len)) == NULL) {
12596201Sdes			pw_fini();
12696201Sdes			err(1, "fgetln()");
12796201Sdes		}
12896201Sdes		if (len > 0 && (*line == 'N' || *line == 'n'))
1291553Srgrimes			break;
1301553Srgrimes	}
13196201Sdes	pw_fini();
1321553Srgrimes	exit(0);
1331553Srgrimes}
1341553Srgrimes
13590233Sdesstatic void
13690233Sdesusage(void)
1371553Srgrimes{
1381553Srgrimes
13996201Sdes	(void)fprintf(stderr, "usage: vipw [-d directory]\n");
1401553Srgrimes	exit(1);
1411553Srgrimes}
142