vipw.c revision 256281
1132451Sroberto/*
2132451Sroberto * Copyright (c) 1987, 1993, 1994
3290001Sglebius *	The Regents of the University of California.  All rights reserved.
4290001Sglebius * Copyright (c) 2002 Networks Associates Technology, Inc.
5290001Sglebius * All rights reserved.
6290001Sglebius *
7290001Sglebius * Portions of this software were developed for the FreeBSD Project by
8290001Sglebius * ThinkSec AS and NAI Labs, the Security Research Division of Network
9290001Sglebius * Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
10290001Sglebius * ("CBOSS"), as part of the DARPA CHATS research program.
11290001Sglebius *
12290001Sglebius * Redistribution and use in source and binary forms, with or without
13290001Sglebius * modification, are permitted provided that the following conditions
14290001Sglebius * are met:
15290001Sglebius * 1. Redistributions of source code must retain the above copyright
16290001Sglebius *    notice, this list of conditions and the following disclaimer.
17290001Sglebius * 2. Redistributions in binary form must reproduce the above copyright
18290001Sglebius *    notice, this list of conditions and the following disclaimer in the
19290001Sglebius *    documentation and/or other materials provided with the distribution.
20290001Sglebius * 4. Neither the name of the University nor the names of its contributors
21290001Sglebius *    may be used to endorse or promote products derived from this software
22290001Sglebius *    without specific prior written permission.
23290001Sglebius *
24290001Sglebius * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25290001Sglebius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26290001Sglebius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27290001Sglebius * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28290001Sglebius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29290001Sglebius * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30290001Sglebius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31290001Sglebius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32290001Sglebius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33290001Sglebius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34290001Sglebius * SUCH DAMAGE.
35290001Sglebius */
36290001Sglebius
37290001Sglebius#if 0
38290001Sglebius#ifndef lint
39290001Sglebiusstatic const char copyright[] =
40290001Sglebius"@(#) Copyright (c) 1987, 1993, 1994\n\
41290001Sglebius	The Regents of the University of California.  All rights reserved.\n";
42290001Sglebius#endif /* not lint */
43290001Sglebius
44290001Sglebius#ifndef lint
45290001Sglebiusstatic char sccsid[] = "@(#)vipw.c	8.3 (Berkeley) 4/2/94";
46290001Sglebius#endif /* not lint */
47290001Sglebius#endif
48290001Sglebius#include <sys/cdefs.h>
49290001Sglebius__FBSDID("$FreeBSD: stable/10/usr.sbin/vipw/vipw.c 133249 2004-08-07 04:28:56Z imp $");
50290001Sglebius
51290001Sglebius#include <sys/types.h>
52290001Sglebius#include <sys/stat.h>
53290001Sglebius
54290001Sglebius#include <err.h>
55290001Sglebius#include <pwd.h>
56290001Sglebius#include <stdio.h>
57290001Sglebius#include <stdlib.h>
58290001Sglebius#include <string.h>
59290001Sglebius#include <unistd.h>
60290001Sglebius
61290001Sglebius#include <libutil.h>		/* must be after pwd.h */
62290001Sglebius
63290001Sglebiusstatic void	usage(void);
64290001Sglebius
65290001Sglebiusint
66290001Sglebiusmain(int argc, char *argv[])
67290001Sglebius{
68290001Sglebius	const char *passwd_dir = NULL;
69290001Sglebius	int ch, pfd, tfd;
70290001Sglebius	char *line;
71290001Sglebius	size_t len;
72290001Sglebius
73290001Sglebius	while ((ch = getopt(argc, argv, "d:")) != -1)
74290001Sglebius		switch (ch) {
75290001Sglebius		case 'd':
76290001Sglebius			passwd_dir = optarg;
77290001Sglebius			break;
78290001Sglebius		case '?':
79290001Sglebius		default:
80290001Sglebius			usage();
81290001Sglebius		}
82290001Sglebius
83290001Sglebius	argc -= optind;
84290001Sglebius	argv += optind;
85290001Sglebius
86290001Sglebius	if (argc != 0)
87290001Sglebius		usage();
88290001Sglebius
89290001Sglebius	if (pw_init(passwd_dir, NULL) == -1)
90290001Sglebius		err(1, "pw_init()");
91290001Sglebius	if ((pfd = pw_lock()) == -1) {
92290001Sglebius		pw_fini();
93290001Sglebius		err(1, "pw_lock()");
94290001Sglebius	}
95290001Sglebius	if ((tfd = pw_tmp(pfd)) == -1) {
96290001Sglebius		pw_fini();
97290001Sglebius		err(1, "pw_tmp()");
98290001Sglebius	}
99290001Sglebius	(void)close(tfd);
100290001Sglebius	/* Force umask for partial writes made in the edit phase */
101290001Sglebius	(void)umask(077);
102290001Sglebius
103290001Sglebius	for (;;) {
104290001Sglebius		switch (pw_edit(0)) {
105290001Sglebius		case -1:
106290001Sglebius			pw_fini();
107290001Sglebius			err(1, "pw_edit()");
108290001Sglebius		case 0:
109290001Sglebius			pw_fini();
110290001Sglebius			errx(0, "no changes made");
111290001Sglebius		default:
112290001Sglebius			break;
113290001Sglebius		}
114290001Sglebius		if (pw_mkdb(NULL) == 0) {
115290001Sglebius			pw_fini();
116290001Sglebius			errx(0, "password list updated");
117290001Sglebius		}
118290001Sglebius		printf("re-edit the password file? ");
119290001Sglebius		fflush(stdout);
120290001Sglebius		if ((line = fgetln(stdin, &len)) == NULL) {
121290001Sglebius			pw_fini();
122290001Sglebius			err(1, "fgetln()");
123290001Sglebius		}
124290001Sglebius		if (len > 0 && (*line == 'N' || *line == 'n'))
125290001Sglebius			break;
126290001Sglebius	}
127290001Sglebius	pw_fini();
128290001Sglebius	exit(0);
129290001Sglebius}
130290001Sglebius
131290001Sglebiusstatic void
132290001Sglebiususage(void)
133290001Sglebius{
134290001Sglebius
135290001Sglebius	(void)fprintf(stderr, "usage: vipw [-d directory]\n");
136290001Sglebius	exit(1);
137290001Sglebius}
138290001Sglebius