BSD 4_4_Lite1 release
[unix-history] / usr / src / usr.sbin / vipw / pw_util.c
index ef8d9c4..9873f74 100644 (file)
@@ -1,12 +1,38 @@
 /*-
 /*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pw_util.c  8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)pw_util.c  8.3 (Berkeley) 4/2/94";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -15,21 +41,27 @@ static char sccsid[] = "@(#)pw_util.c       8.1 (Berkeley) %G%";
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
-#include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <fcntl.h>
+#include <paths.h>
 #include <pwd.h>
 #include <pwd.h>
-#include <errno.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <paths.h>
-#include <string.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pw_util.h"
 
 
-extern char *progname;
 extern char *tempname;
 
 extern char *tempname;
 
+void
 pw_init()
 {
        struct rlimit rlim;
 pw_init()
 {
        struct rlimit rlim;
@@ -61,75 +93,72 @@ pw_init()
 }
 
 static int lockfd;
 }
 
 static int lockfd;
+
+int
 pw_lock()
 {
        /* 
         * If the master password file doesn't exist, the system is hosed.
 pw_lock()
 {
        /* 
         * If the master password file doesn't exist, the system is hosed.
-        * Might as well try to build one.
+        * 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);
         * Open should allow flock'ing the file; see 4.4BSD.    XXX
         */
        lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
-       if (lockfd < 0) {
-               (void)fprintf(stderr, "%s: %s: %s\n",
-                   progname, _PATH_MASTERPASSWD, strerror(errno));
-               exit(1);
-       }
-       if (flock(lockfd, LOCK_EX|LOCK_NB)) {
-               (void)fprintf(stderr,
-                   "%s: the password db is busy.\n", progname);
-               exit(1);
-       }
-       return(lockfd);
+       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");
+       return (lockfd);
 }
 
 }
 
+int
 pw_tmp()
 {
        static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
        int fd;
        char *p;
 
 pw_tmp()
 {
        static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
        int fd;
        char *p;
 
-       if (p = rindex(path, '/'))
+       if (p = strrchr(path, '/'))
                ++p;
        else
                p = path;
                ++p;
        else
                p = path;
-       (void)sprintf(p, "%s.XXXXXX", progname);
-       if ((fd = mkstemp(path)) == -1) {
-               (void)fprintf(stderr,
-                   "%s: %s: %s\n", progname, path, strerror(errno));
-               exit(1);
-       }
+       strcpy(p, "pw.XXXXXX");
+       if ((fd = mkstemp(path)) == -1)
+               err(1, "%s", path);
        tempname = path;
        tempname = path;
-       return(fd);
+       return (fd);
 }
 
 }
 
+int
 pw_mkdb()
 {
 pw_mkdb()
 {
-       union wait pstat;
+       int pstat;
        pid_t pid;
 
        pid_t pid;
 
-       (void)printf("%s: rebuilding the database...\n", progname);
-       (void)fflush(stdout);
+       warnx("rebuilding the database...");
+       (void)fflush(stderr);
        if (!(pid = vfork())) {
                execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
                pw_error(_PATH_PWD_MKDB, 1, 1);
        }
        if (!(pid = vfork())) {
                execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
                pw_error(_PATH_PWD_MKDB, 1, 1);
        }
-       pid = waitpid(pid, (int *)&pstat, 0);
-       if (pid == -1 || pstat.w_status)
-               return(0);
-       (void)printf("%s: done\n", progname);
-       return(1);
+       pid = waitpid(pid, &pstat, 0);
+       if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+               return (0);
+       warnx("done");
+       return (1);
 }
 
 }
 
+void
 pw_edit(notsetuid)
        int notsetuid;
 {
 pw_edit(notsetuid)
        int notsetuid;
 {
-       union wait pstat;
+       int pstat;
        pid_t pid;
        char *p, *editor;
 
        if (!(editor = getenv("EDITOR")))
                editor = _PATH_VI;
        pid_t pid;
        char *p, *editor;
 
        if (!(editor = getenv("EDITOR")))
                editor = _PATH_VI;
-       if (p = rindex(editor, '/'))
+       if (p = strrchr(editor, '/'))
                ++p;
        else 
                p = editor;
                ++p;
        else 
                p = editor;
@@ -143,41 +172,33 @@ pw_edit(notsetuid)
                _exit(1);
        }
        pid = waitpid(pid, (int *)&pstat, 0);
                _exit(1);
        }
        pid = waitpid(pid, (int *)&pstat, 0);
-       if (pid == -1 || pstat.w_status)
+       if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
                pw_error(editor, 1, 1);
 }
 
                pw_error(editor, 1, 1);
 }
 
+void
 pw_prompt()
 {
 pw_prompt()
 {
-       register int c;
-
-       for (;;) {
-               (void)printf("re-edit the password file? [y]: ");
-               (void)fflush(stdout);
-               c = getchar();
-               if (c != EOF && c != (int)'\n')
-                       while (getchar() != (int)'\n');
-               if (c == (int)'n')
-                       pw_error((char *)NULL, 0, 0);
-               break;
-       }
+       int c;
+
+       (void)printf("re-edit the password file? [y]: ");
+       (void)fflush(stdout);
+       c = getchar();
+       if (c != EOF && c != '\n')
+               while (getchar() != '\n');
+       if (c == 'n')
+               pw_error(NULL, 0, 0);
 }
 
 }
 
+void
 pw_error(name, err, eval)
        char *name;
        int err, eval;
 {
 pw_error(name, err, eval)
        char *name;
        int err, eval;
 {
-       int sverrno;
-
-       if (err) {
-               sverrno = errno;
-               (void)fprintf(stderr, "%s: ", progname);
-               if (name)
-                       (void)fprintf(stderr, "%s: ", name);
-               (void)fprintf(stderr, "%s\n", strerror(sverrno));
-       }
-       (void)fprintf(stderr,
-           "%s: %s unchanged\n", progname, _PATH_MASTERPASSWD);
+       if (err)
+               warn(name);
+
+       warnx("%s: unchanged", _PATH_MASTERPASSWD);
        (void)unlink(tempname);
        exit(eval);
 }
        (void)unlink(tempname);
        exit(eval);
 }