xref: /csrg-svn/usr.sbin/vipw/pw_util.c (revision 46377)
1*46377Sbostic /*-
2*46377Sbostic  * Copyright (c) 1990 The Regents of the University of California.
3*46377Sbostic  * All rights reserved.
4*46377Sbostic  *
5*46377Sbostic  * %sccs.include.redist.c%
6*46377Sbostic  */
7*46377Sbostic 
8*46377Sbostic #ifndef lint
9*46377Sbostic static char sccsid[] = "@(#)pw_util.c	5.1 (Berkeley) 02/12/91";
10*46377Sbostic #endif /* not lint */
11*46377Sbostic 
12*46377Sbostic /*
13*46377Sbostic  * This file is used by all the "password" programs; vipw(8), chpass(1),
14*46377Sbostic  * and passwd(1).
15*46377Sbostic  */
16*46377Sbostic 
17*46377Sbostic #include <sys/param.h>
18*46377Sbostic #include <sys/wait.h>
19*46377Sbostic #include <sys/time.h>
20*46377Sbostic #include <sys/resource.h>
21*46377Sbostic #include <signal.h>
22*46377Sbostic #include <fcntl.h>
23*46377Sbostic #include <pwd.h>
24*46377Sbostic #include <errno.h>
25*46377Sbostic #include <stdio.h>
26*46377Sbostic #include <paths.h>
27*46377Sbostic #include <string.h>
28*46377Sbostic #include <stdlib.h>
29*46377Sbostic 
30*46377Sbostic extern char *progname;
31*46377Sbostic extern char *tempname;
32*46377Sbostic 
33*46377Sbostic pw_init()
34*46377Sbostic {
35*46377Sbostic 	struct rlimit rlim;
36*46377Sbostic 	sigset_t set;
37*46377Sbostic 
38*46377Sbostic 	/* Unlimited cpu, file size. */
39*46377Sbostic 	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
40*46377Sbostic 	(void)setrlimit(RLIMIT_CPU, &rlim);
41*46377Sbostic 	(void)setrlimit(RLIMIT_FSIZE, &rlim);
42*46377Sbostic 
43*46377Sbostic 	/* Don't drop core (not really necessary, but GP's). */
44*46377Sbostic 	rlim.rlim_cur = rlim.rlim_max = 0;
45*46377Sbostic 	(void)setrlimit(RLIMIT_CORE, &rlim);
46*46377Sbostic 
47*46377Sbostic 	/* Turn off usual signals. */
48*46377Sbostic 	sigemptyset(&set);
49*46377Sbostic 	(void)sigaddset(&set, SIGTSTP);
50*46377Sbostic 	(void)sigaddset(&set, SIGHUP);
51*46377Sbostic 	(void)sigaddset(&set, SIGINT);
52*46377Sbostic 	(void)sigaddset(&set, SIGQUIT);
53*46377Sbostic 	(void)sigaddset(&set, SIGTERM);
54*46377Sbostic 	(void)sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL);
55*46377Sbostic 
56*46377Sbostic 	/* Create with exact permissions. */
57*46377Sbostic 	(void)umask(0);
58*46377Sbostic }
59*46377Sbostic 
60*46377Sbostic static int lockfd;
61*46377Sbostic pw_lock()
62*46377Sbostic {
63*46377Sbostic 	/*
64*46377Sbostic 	 * If the master password file doesn't exist, the system is hosed.
65*46377Sbostic 	 * Might as well try to build one.
66*46377Sbostic 	 * Open should allow flock'ing the file; see 4.4BSD.	XXX
67*46377Sbostic 	 */
68*46377Sbostic 	lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
69*46377Sbostic 	if (lockfd < 0) {
70*46377Sbostic 		(void)fprintf(stderr, "%s: %s: %s\n",
71*46377Sbostic 		    progname, _PATH_MASTERPASSWD, strerror(errno));
72*46377Sbostic 		exit(1);
73*46377Sbostic 	}
74*46377Sbostic 	if (flock(lockfd, LOCK_EX)) {
75*46377Sbostic 		(void)fprintf(stderr,
76*46377Sbostic 		    "%s: the password db is busy.\n", progname);
77*46377Sbostic 		exit(1);
78*46377Sbostic 	}
79*46377Sbostic 	return(lockfd);
80*46377Sbostic }
81*46377Sbostic 
82*46377Sbostic pw_tmp()
83*46377Sbostic {
84*46377Sbostic 	static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
85*46377Sbostic 	int fd;
86*46377Sbostic 	char *p;
87*46377Sbostic 
88*46377Sbostic 	if (p = rindex(path, '/'))
89*46377Sbostic 		++p;
90*46377Sbostic 	else
91*46377Sbostic 		p = path;
92*46377Sbostic 	(void)sprintf(p, "%s.XXXXXX", progname);
93*46377Sbostic 	if ((fd = mkstemp(path)) == -1) {
94*46377Sbostic 		(void)fprintf(stderr,
95*46377Sbostic 		    "%s: %s: %s\n", progname, path, strerror(errno));
96*46377Sbostic 		exit(1);
97*46377Sbostic 	}
98*46377Sbostic 	tempname = path;
99*46377Sbostic 	return(fd);
100*46377Sbostic }
101*46377Sbostic 
102*46377Sbostic pw_mkdb()
103*46377Sbostic {
104*46377Sbostic 	union wait pstat;
105*46377Sbostic 	pid_t pid;
106*46377Sbostic 
107*46377Sbostic 	(void)printf("%s: rebuilding the database...\n", progname);
108*46377Sbostic 	(void)fflush(stdout);
109*46377Sbostic 	if (!(pid = vfork())) {
110*46377Sbostic 		execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
111*46377Sbostic 		pw_error(_PATH_PWD_MKDB, 1, 1);
112*46377Sbostic 	}
113*46377Sbostic 	pid = waitpid(pid, (int *)&pstat, 0);
114*46377Sbostic 	if (pid == -1 || pstat.w_status)
115*46377Sbostic 		return(0);
116*46377Sbostic 	(void)printf("%s: done\n", progname);
117*46377Sbostic 	return(1);
118*46377Sbostic }
119*46377Sbostic 
120*46377Sbostic pw_edit(notsetuid)
121*46377Sbostic 	int notsetuid;
122*46377Sbostic {
123*46377Sbostic 	union wait pstat;
124*46377Sbostic 	pid_t pid;
125*46377Sbostic 	char *p, *editor;
126*46377Sbostic 
127*46377Sbostic 	if (!(editor = getenv("EDITOR")))
128*46377Sbostic 		editor = _PATH_VI;
129*46377Sbostic 	if (p = rindex(editor, '/'))
130*46377Sbostic 		++p;
131*46377Sbostic 	else
132*46377Sbostic 		p = editor;
133*46377Sbostic 
134*46377Sbostic 	if (!(pid = vfork())) {
135*46377Sbostic 		if (notsetuid) {
136*46377Sbostic 			(void)setgid(getgid());
137*46377Sbostic 			(void)setuid(getuid());
138*46377Sbostic 		}
139*46377Sbostic 		execlp(editor, p, tempname, NULL);
140*46377Sbostic 		pw_error(editor, 1, 1);
141*46377Sbostic 	}
142*46377Sbostic 	pid = waitpid(pid, (int *)&pstat, 0);
143*46377Sbostic 	return (pid == -1 ? 1 : pstat.w_status);
144*46377Sbostic }
145*46377Sbostic 
146*46377Sbostic pw_prompt()
147*46377Sbostic {
148*46377Sbostic 	register int c;
149*46377Sbostic 
150*46377Sbostic 	for (;;) {
151*46377Sbostic 		(void)printf("re-edit the password file? [y]: ");
152*46377Sbostic 		(void)fflush(stdout);
153*46377Sbostic 		c = getchar();
154*46377Sbostic 		if (c != EOF && c != (int)'\n')
155*46377Sbostic 			while (getchar() != (int)'\n');
156*46377Sbostic 		if (c == (int)'n')
157*46377Sbostic 			pw_error((char *)NULL, 0, 0);
158*46377Sbostic 		break;
159*46377Sbostic 	}
160*46377Sbostic }
161*46377Sbostic 
162*46377Sbostic pw_error(name, err, eval)
163*46377Sbostic 	char *name;
164*46377Sbostic 	int err, eval;
165*46377Sbostic {
166*46377Sbostic 	int sverrno;
167*46377Sbostic 
168*46377Sbostic 	if (err) {
169*46377Sbostic 		sverrno = errno;
170*46377Sbostic 		(void)fprintf(stderr, "%s: ", progname);
171*46377Sbostic 		if (name)
172*46377Sbostic 			(void)fprintf(stderr, "%s: ", name);
173*46377Sbostic 		(void)fprintf(stderr, "%s\n", strerror(sverrno));
174*46377Sbostic 	}
175*46377Sbostic 	(void)fprintf(stderr,
176*46377Sbostic 	    "%s: %s unchanged\n", progname, _PATH_MASTERPASSWD);
177*46377Sbostic 	(void)unlink(tempname);
178*46377Sbostic 	exit(eval);
179*46377Sbostic }
180