xref: /csrg-svn/usr.sbin/vipw/pw_util.c (revision 66576)
146377Sbostic /*-
264008Sbostic  * Copyright (c) 1990, 1993
364008Sbostic  *	The Regents of the University of California.  All rights reserved.
446377Sbostic  *
546377Sbostic  * %sccs.include.redist.c%
646377Sbostic  */
746377Sbostic 
846377Sbostic #ifndef lint
9*66576Spendry static char sccsid[] = "@(#)pw_util.c	8.2 (Berkeley) 04/01/94";
1046377Sbostic #endif /* not lint */
1146377Sbostic 
1246377Sbostic /*
1346377Sbostic  * This file is used by all the "password" programs; vipw(8), chpass(1),
1446377Sbostic  * and passwd(1).
1546377Sbostic  */
1646377Sbostic 
1746377Sbostic #include <sys/param.h>
1846377Sbostic #include <sys/time.h>
1946377Sbostic #include <sys/resource.h>
20*66576Spendry #include <sys/stat.h>
21*66576Spendry #include <sys/wait.h>
2264007Sbostic 
23*66576Spendry #include <err.h>
2464007Sbostic #include <errno.h>
2546377Sbostic #include <fcntl.h>
2664007Sbostic #include <paths.h>
2746377Sbostic #include <pwd.h>
2864007Sbostic #include <signal.h>
2946377Sbostic #include <stdio.h>
3064007Sbostic #include <stdlib.h>
3146377Sbostic #include <string.h>
32*66576Spendry #include <unistd.h>
3346377Sbostic 
34*66576Spendry #include "pw_util.h"
35*66576Spendry 
3646377Sbostic extern char *tempname;
3746377Sbostic 
38*66576Spendry void
3946377Sbostic pw_init()
4046377Sbostic {
4146377Sbostic 	struct rlimit rlim;
4246377Sbostic 
4349830Sbostic 	/* Unlimited resource limits. */
4446377Sbostic 	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
4546377Sbostic 	(void)setrlimit(RLIMIT_CPU, &rlim);
4646377Sbostic 	(void)setrlimit(RLIMIT_FSIZE, &rlim);
4749830Sbostic 	(void)setrlimit(RLIMIT_STACK, &rlim);
4849830Sbostic 	(void)setrlimit(RLIMIT_DATA, &rlim);
4949830Sbostic 	(void)setrlimit(RLIMIT_RSS, &rlim);
5046377Sbostic 
5146377Sbostic 	/* Don't drop core (not really necessary, but GP's). */
5246377Sbostic 	rlim.rlim_cur = rlim.rlim_max = 0;
5346377Sbostic 	(void)setrlimit(RLIMIT_CORE, &rlim);
5446377Sbostic 
5549830Sbostic 	/* Turn off signals. */
5649830Sbostic 	(void)signal(SIGALRM, SIG_IGN);
5747287Sbostic 	(void)signal(SIGHUP, SIG_IGN);
5847287Sbostic 	(void)signal(SIGINT, SIG_IGN);
5949830Sbostic 	(void)signal(SIGPIPE, SIG_IGN);
6047287Sbostic 	(void)signal(SIGQUIT, SIG_IGN);
6147287Sbostic 	(void)signal(SIGTERM, SIG_IGN);
6247287Sbostic 	(void)signal(SIGTSTP, SIG_IGN);
6349830Sbostic 	(void)signal(SIGTTOU, SIG_IGN);
6446377Sbostic 
6546377Sbostic 	/* Create with exact permissions. */
6646377Sbostic 	(void)umask(0);
6746377Sbostic }
6846377Sbostic 
6946377Sbostic static int lockfd;
70*66576Spendry 
71*66576Spendry int
7246377Sbostic pw_lock()
7346377Sbostic {
7446377Sbostic 	/*
7546377Sbostic 	 * If the master password file doesn't exist, the system is hosed.
7664007Sbostic 	 * Might as well try to build one.  Set the close-on-exec bit so
7764007Sbostic 	 * that users can't get at the encrypted passwords while editing.
7846377Sbostic 	 * Open should allow flock'ing the file; see 4.4BSD.	XXX
7946377Sbostic 	 */
8046377Sbostic 	lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
81*66576Spendry 	if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
82*66576Spendry 		err(1, "%s", _PATH_MASTERPASSWD);
83*66576Spendry 	if (flock(lockfd, LOCK_EX|LOCK_NB))
84*66576Spendry 		errx(1, "the password db file is busy");
85*66576Spendry 	return (lockfd);
8646377Sbostic }
8746377Sbostic 
88*66576Spendry int
8946377Sbostic pw_tmp()
9046377Sbostic {
9146377Sbostic 	static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
9246377Sbostic 	int fd;
9346377Sbostic 	char *p;
9446377Sbostic 
95*66576Spendry 	if (p = strrchr(path, '/'))
9646377Sbostic 		++p;
9746377Sbostic 	else
9846377Sbostic 		p = path;
99*66576Spendry 	strcpy(p, "pw.XXXXXX");
100*66576Spendry 	if ((fd = mkstemp(path)) == -1)
101*66576Spendry 		err(1, "%s", path);
10246377Sbostic 	tempname = path;
103*66576Spendry 	return (fd);
10446377Sbostic }
10546377Sbostic 
106*66576Spendry int
10746377Sbostic pw_mkdb()
10846377Sbostic {
109*66576Spendry 	int pstat;
11046377Sbostic 	pid_t pid;
11146377Sbostic 
112*66576Spendry 	warnx("rebuilding the database...");
113*66576Spendry 	(void)fflush(stderr);
11446377Sbostic 	if (!(pid = vfork())) {
11546377Sbostic 		execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
11646377Sbostic 		pw_error(_PATH_PWD_MKDB, 1, 1);
11746377Sbostic 	}
118*66576Spendry 	pid = waitpid(pid, &pstat, 0);
119*66576Spendry 	if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
120*66576Spendry 		return (0);
121*66576Spendry 	warnx("done");
122*66576Spendry 	return (1);
12346377Sbostic }
12446377Sbostic 
125*66576Spendry void
12646377Sbostic pw_edit(notsetuid)
12746377Sbostic 	int notsetuid;
12846377Sbostic {
129*66576Spendry 	int pstat;
13046377Sbostic 	pid_t pid;
13146377Sbostic 	char *p, *editor;
13246377Sbostic 
13346377Sbostic 	if (!(editor = getenv("EDITOR")))
13446377Sbostic 		editor = _PATH_VI;
135*66576Spendry 	if (p = strrchr(editor, '/'))
13646377Sbostic 		++p;
13746377Sbostic 	else
13846377Sbostic 		p = editor;
13946377Sbostic 
14046377Sbostic 	if (!(pid = vfork())) {
14146377Sbostic 		if (notsetuid) {
14246377Sbostic 			(void)setgid(getgid());
14346377Sbostic 			(void)setuid(getuid());
14446377Sbostic 		}
14546377Sbostic 		execlp(editor, p, tempname, NULL);
14646955Sbostic 		_exit(1);
14746377Sbostic 	}
14846377Sbostic 	pid = waitpid(pid, (int *)&pstat, 0);
149*66576Spendry 	if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
15046955Sbostic 		pw_error(editor, 1, 1);
15146377Sbostic }
15246377Sbostic 
153*66576Spendry void
15446377Sbostic pw_prompt()
15546377Sbostic {
156*66576Spendry 	int c;
15746377Sbostic 
158*66576Spendry 	(void)printf("re-edit the password file? [y]: ");
159*66576Spendry 	(void)fflush(stdout);
160*66576Spendry 	c = getchar();
161*66576Spendry 	if (c != EOF && c != '\n')
162*66576Spendry 		while (getchar() != '\n');
163*66576Spendry 	if (c == 'n')
164*66576Spendry 		pw_error(NULL, 0, 0);
16546377Sbostic }
16646377Sbostic 
167*66576Spendry void
16846377Sbostic pw_error(name, err, eval)
16946377Sbostic 	char *name;
17046377Sbostic 	int err, eval;
17146377Sbostic {
172*66576Spendry 	if (err)
173*66576Spendry 		warn(name);
17446377Sbostic 
175*66576Spendry 	warnx("%s: unchanged", _PATH_MASTERPASSWD);
17646377Sbostic 	(void)unlink(tempname);
17746377Sbostic 	exit(eval);
17846377Sbostic }
179