X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/3870d9c3a764b9d7a92f5910f57d30b8ee8d0987..345ce45fb269249e53a4c90cce43f5057a478515:/libutil/pw_util.c diff --git a/libutil/pw_util.c b/libutil/pw_util.c index 9873f74..ce9eba2 100644 --- a/libutil/pw_util.c +++ b/libutil/pw_util.c @@ -32,7 +32,11 @@ */ #ifndef lint -static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; +#if 0 +static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; +#endif +static const char rcsid[] = + "$FreeBSD$"; #endif /* not lint */ /* @@ -41,13 +45,13 @@ static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; */ #include +#include #include #include #include #include #include -#include #include #include #include @@ -60,6 +64,19 @@ static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; #include "pw_util.h" extern char *tempname; +static pid_t editpid = -1; +static int lockfd; +char *mppath = _PATH_PWD; +char *masterpasswd = _PATH_MASTERPASSWD; + +void +pw_cont(sig) + int sig; +{ + + if (editpid != -1) + kill(editpid, sig); +} void pw_init() @@ -85,40 +102,56 @@ pw_init() (void)signal(SIGPIPE, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, SIG_IGN); - (void)signal(SIGTSTP, SIG_IGN); - (void)signal(SIGTTOU, SIG_IGN); + (void)signal(SIGCONT, pw_cont); /* Create with exact permissions. */ (void)umask(0); } -static int lockfd; - int pw_lock() { - /* + /* * If the master password file doesn't exist, the system is hosed. * Might as well try to build one. Set the close-on-exec bit so * that users can't get at the encrypted passwords while editing. * Open should allow flock'ing the file; see 4.4BSD. XXX */ - lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0); - if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) - err(1, "%s", _PATH_MASTERPASSWD); - if (flock(lockfd, LOCK_EX|LOCK_NB)) - errx(1, "the password db file is busy"); + for (;;) { + struct stat st; + + lockfd = open(masterpasswd, O_RDONLY, 0); + if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) + err(1, "%s", masterpasswd); + if (flock(lockfd, LOCK_EX|LOCK_NB)) + errx(1, "the password db file is busy"); + + /* + * If the password file was replaced while we were trying to + * get the lock, our hardlink count will be 0 and we have to + * close and retry. + */ + if (fstat(lockfd, &st) < 0) + errx(1, "fstat() failed"); + if (st.st_nlink != 0) + break; + close(lockfd); + lockfd = -1; + } return (lockfd); } int pw_tmp() { - static char path[MAXPATHLEN] = _PATH_MASTERPASSWD; + static char path[MAXPATHLEN]; int fd; char *p; - if (p = strrchr(path, '/')) + strncpy(path, masterpasswd, MAXPATHLEN - 1); + path[MAXPATHLEN] = '\0'; + + if ((p = strrchr(path, '/'))) ++p; else p = path; @@ -130,15 +163,23 @@ pw_tmp() } int -pw_mkdb() +pw_mkdb(username) +char *username; { int pstat; pid_t pid; - warnx("rebuilding the database..."); (void)fflush(stderr); - if (!(pid = vfork())) { - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL); + if (!(pid = fork())) { + if(!username) { + warnx("rebuilding the database..."); + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, + tempname, (char *)NULL); + } else { + warnx("updating the database..."); + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, + "-u", username, tempname, (char *)NULL); + } pw_error(_PATH_PWD_MKDB, 1, 1); } pid = waitpid(pid, &pstat, 0); @@ -153,40 +194,50 @@ pw_edit(notsetuid) int notsetuid; { int pstat; - pid_t pid; char *p, *editor; if (!(editor = getenv("EDITOR"))) editor = _PATH_VI; - if (p = strrchr(editor, '/')) + if ((p = strrchr(editor, '/'))) ++p; - else + else p = editor; - if (!(pid = vfork())) { + if (!(editpid = fork())) { if (notsetuid) { (void)setgid(getgid()); (void)setuid(getuid()); } - execlp(editor, p, tempname, NULL); - _exit(1); + errno = 0; + execlp(editor, p, tempname, (char *)NULL); + _exit(errno); } - pid = waitpid(pid, (int *)&pstat, 0); - if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) - pw_error(editor, 1, 1); + for (;;) { + editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); + errno = WEXITSTATUS(pstat); + if (editpid == -1) + pw_error(editor, 1, 1); + else if (WIFSTOPPED(pstat)) + raise(WSTOPSIG(pstat)); + else if (WIFEXITED(pstat) && errno == 0) + break; + else + pw_error(editor, 1, 1); + } + editpid = -1; } void pw_prompt() { - int c; + int c, first; (void)printf("re-edit the password file? [y]: "); (void)fflush(stdout); - c = getchar(); - if (c != EOF && c != '\n') - while (getchar() != '\n'); - if (c == 'n') + first = c = getchar(); + while (c != '\n' && c != EOF) + c = getchar(); + if (first == 'n') pw_error(NULL, 0, 0); } @@ -195,10 +246,21 @@ pw_error(name, err, eval) char *name; int err, eval; { - if (err) - warn(name); - - warnx("%s: unchanged", _PATH_MASTERPASSWD); +#ifdef YP + extern int _use_yp; +#endif /* YP */ + if (err) { + if (name != NULL) + warn("%s", name); + else + warn(NULL); + } +#ifdef YP + if (_use_yp) + warnx("NIS information unchanged"); + else +#endif /* YP */ + warnx("%s: unchanged", masterpasswd); (void)unlink(tempname); exit(eval); }