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