# 2.11BSD#431 - /usr/src/usr.sbin/vipw/vipw.c

##### Functions

    check             X
    edit              X
    main              X
    makedb            X
    prompt            X
    stop              X

##### Variables

    copyright         X
    passwd            X
    temp              X

       1: /*
       2:  * Copyright (c) 1987 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that the above copyright notice and this paragraph are
       7:  * duplicated in all such forms and that any documentation,
       8:  * advertising materials, and other materials related to such
       9:  * distribution and use acknowledge that the software was developed
      10:  * by the University of California, Berkeley.  The name of the
      11:  * University may not be used to endorse or promote products derived
      12:  * from this software without specific prior written permission.
      13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
      14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      16:  */
      17:
      18: #if !defined(lint) && defined(DOSCCS)
      19: char copyright[] =
      20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
      21:  All rights reserved.\n";
      22:
      23: static char sccsid[] = "@(#)vipw.c	5.9.1 (2.11BSD) 1996/1/12";
      24: #endif /* not lint */
      25:
      26: #include <sys/param.h>
      27: #include <sys/stat.h>
      28: #include <sys/signal.h>
      29: #include <sys/file.h>
      30: #include <sys/time.h>
      31: #include <sys/resource.h>
      32: #include <errno.h>
      33: #include <pwd.h>
      34: #include <stdio.h>
      35: #include <strings.h>
      36: #include <stdlib.h>
      37:
      38: char *passwd, *temp;
      39:
      40: main()
      41: {
      42:     register int n, fd_passwd, fd;
      43:     struct rlimit rlim;
      44:     struct stat s1, s2;
      45:     FILE *tfp;
      46:     char *fend, *tend;
      47:     char buf[1024], from[MAXPATHLEN], to[MAXPATHLEN];
      48:
      49:     (void)signal(SIGHUP, SIG_IGN);
      50:     (void)signal(SIGINT, SIG_IGN);
      51:     (void)signal(SIGQUIT, SIG_IGN);
      52:     (void)signal(SIGTSTP, SIG_IGN);
      53:
      54:     rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
      55:     (void)setrlimit(RLIMIT_CPU, &rlim);
      56:     (void)setrlimit(RLIMIT_FSIZE, &rlim);
      57:
      58:     (void)umask(0);
      59:
      60:     temp = _PATH_PTMP;
      61:     if ((fd = open(temp, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0) {
      62:         if (errno == EEXIST)
      63:             (void)fprintf(stderr, "vipw: password file busy.\n");
      64:         else
      65:             (void)fprintf(stderr,
      66:                 "vipw: %s: %s\n", temp, strerror(errno));
      67:         exit(1);
      68:     }
      69:     passwd = _PATH_MASTERPASSWD;
      70:     if ((fd_passwd = open(passwd, O_RDONLY, 0)) < 0) {
      71:         (void)fprintf(stderr, "vipw: %s: %s\n", passwd,
      72:             strerror(errno));
      73:         exit(1);
      74:     }
      75:     while ((n = read(fd_passwd, buf, sizeof(buf))) > 0)
      76:         if (write(fd, buf, n) != n)
      77:             goto syserr;
      78:
      79:     if (n == -1 || close(fd_passwd)) {
      80: syserr:     (void)fprintf(stderr, "vipw: %s: %s; ",
      81:             passwd, strerror(errno));
      82:         stop(1);
      83:     }
      84:     if (!(tfp = fdopen(fd, "r"))) {
      85:         (void)fprintf(stderr, "vipw: %s: %s; ",
      86:             temp, strerror(errno));
      87:         stop(1);
      88:     }
      89:
      90:     for (;;) {
      91:         (void)fstat(fd, &s1);
      92:         if (edit()) {
      93:             (void)fprintf(stderr, "vipw: edit failed; ");
      94:             stop(1);
      95:         }
      96:         (void)fstat(fd, &s2);
      97:         if (s1.st_mtime == s2.st_mtime) {
      98:             (void)fprintf(stderr, "vipw: no changes made; ");
      99:             stop(0);
     100:         }
     101:         rewind(tfp);
     102:         if (!check(tfp))
     103:             break;
     104:         if (prompt())
     105:             stop(0);
     106:     }
     107:
     108:     switch(fork()) {
     109:     case 0:
     110:         break;
     111:     case -1:
     112:         (void)fprintf(stderr, "vipw: can't fork; ");
     113:         stop(1);
     114:         /* NOTREACHED */
     115:     default:
     116:         exit(0);
     117:         /* NOTREACHED */
     118:     }
     119:
     120:     if (makedb(temp)) {
     121:         (void)fprintf(stderr, "vipw: mkpasswd failed; ");
     122:         stop(1);
     123:     }
     124:
     125:     /*
     126: 	 * possible race; have to rename four files, and someone could slip
     127: 	 * in between them.  LOCK_EX and rename the ``passwd.dir'' file first
     128: 	 * so that getpwent(3) can't slip in; the lock should never fail and
     129: 	 * it's unclear what to do if it does.  Rename ``ptmp'' last so that
     130: 	 * passwd/vipw/chpass can't slip in.
     131: 	 */
     132:     (void)setpriority(PRIO_PROCESS, 0, -20);
     133:     fend = strcpy(from, temp) + strlen(temp);
     134:     tend = strcpy(to, _PATH_PASSWD) + strlen(_PATH_PASSWD);
     135:     bcopy(".dir", fend, 5);
     136:     bcopy(".dir", tend, 5);
     137:     if ((fd = open(from, O_RDONLY, 0)) >= 0)
     138:         (void)flock(fd, LOCK_EX);
     139:     /* here we go... */
     140:     (void)rename(from, to);
     141:     bcopy(".pag", fend, 5);
     142:     bcopy(".pag", tend, 5);
     143:     (void)rename(from, to);
     144:     bcopy(".orig", fend, 6);
     145:     (void)rename(from, _PATH_PASSWD);
     146:     (void)rename(temp, passwd);
     147:     /* done! */
     148:     exit(0);
     149: }
     150:
     151: check(tfp)
     152:     FILE *tfp;
     153: {
     154:     long id;
     155:     int root;
     156:     register int lcnt;
     157:     register char *p, *sh;
     158:     char buf[256], *getusershell();
     159:     char *bp;
     160:
     161:     for (lcnt = 1; fgets(buf, sizeof(buf), tfp); ++lcnt) {
     162:         bp = buf;
     163:         /* skip lines that are too big */
     164:         if (!(p = index(buf, '\n'))) {
     165:             (void)fprintf(stderr, "vipw: line too long");
     166:             goto bad;
     167:         }
     168:         *p = '\0';
     169:         if (!(p = strsep(&bp, ":")))    /* login */
     170:             goto general;
     171:         root = !strcmp(p, "root");
     172:         (void)strsep(&bp, ":");     /* passwd */
     173:         if (!(p = strsep(&bp, ":")))    /* uid */
     174:             goto general;
     175:         id = atol(p);
     176:         if (root && id) {
     177:             (void)fprintf(stderr, "vipw: root uid should be 0");
     178:             goto bad;
     179:         }
     180:         if (id > USHRT_MAX) {
     181:             (void)fprintf(stderr, "vipw: %s > max uid value (%u)",
     182:                 p, USHRT_MAX);
     183:             goto bad;
     184:         }
     185:         if (!(p = strsep(&bp, ":")))    /* gid */
     186:             goto general;
     187:         id = atol(p);
     188:         if (id > USHRT_MAX) {
     189:             (void)fprintf(stderr, "vipw: %s > max gid value (%u)",
     190:                 p, USHRT_MAX);
     191:             goto bad;
     192:         }
     193:         (void)strsep(&bp, ":");     /* class */
     194:         (void)strsep(&bp, ":");     /* change */
     195:         (void)strsep(&bp, ":");     /* expire */
     196:         (void)strsep(&bp, ":");     /* gecos */
     197:         (void)strsep(&bp, ":");     /* directory */
     198:         if (!(p = strsep(&bp, ":")))    /* shell */
     199:             goto general;
     200:         if (root && *p)             /* empty == /bin/sh */
     201:             for (setusershell();;)
     202:                 if (!(sh = getusershell())) {
     203:                     (void)fprintf(stderr,
     204:                         "vipw: warning, unknown root shell.\n");
     205:                     break;
     206:                 }
     207:                 else if (!strcmp(p, sh))
     208:                     break;
     209:         if (strsep(&bp, ":")) { /* too many */
     210: general:        (void)fprintf(stderr, "vipw: corrupted entry");
     211: bad:            (void)fprintf(stderr, "; line #%d.\n", lcnt);
     212:             (void)fflush(stderr);
     213:             return(1);
     214:         }
     215:     }
     216:     return(0);
     217: }
     218:
     219: makedb(file)
     220:     char *file;
     221: {
     222:     int status, pid, w;
     223:
     224:     if (!(pid = vfork())) {
     225:         execl(_PATH_MKPASSWD, "mkpasswd", "-p", file, NULL);
     226:         _exit(127);
     227:     }
     228:     while ((w = wait(&status)) != pid && w != -1);
     229:     return(w == -1 || status);
     230: }
     231:
     232: edit()
     233: {
     234:     int status, pid, w;
     235:     char *p, *editor;
     236:
     237:     if (editor = getenv("EDITOR")) {
     238:         if (p = rindex(editor, '/'))
     239:             ++p;
     240:         else
     241:             p = editor;
     242:     }
     243:     else
     244:         p = editor = "vi";
     245:     if (!(pid = vfork())) {
     246:         execlp(editor, p, temp, NULL);
     247:         (void)fprintf(stderr, "vipw: %s: %s\n", editor,
     248:             strerror(errno));
     249:         _exit(127);
     250:     }
     251:     while ((w = wait(&status)) != pid && w != -1);
     252:     return(w == -1 || status);
     253: }
     254:
     255: prompt()
     256: {
     257:     register int c;
     258:
     259:     for (;;) {
     260:         (void)printf("re-edit the password file? [y]: ");
     261:         (void)fflush(stdout);
     262:         c = getchar();
     263:         if (c != EOF && c != (int)'\n')
     264:             while (getchar() != (int)'\n');
     265:         return(c == (int)'n');
     266:     }
     267:     /* NOTREACHED */
     268: }
     269:
     270: stop(val)
     271:     int val;
     272: {
     273:     (void)fprintf(stderr, "%s unchanged.\n", passwd);
     274:     (void)unlink(temp);
     275:     exit(val);
     276: }

#### Defined functions

check defined in line 151; used 1 times

- in line 102

edit defined in line 232; used 1 times

- in line 92

main defined in line 40; never used
makedb defined in line 219; used 1 times

- in line 120

prompt defined in line 255; used 1 times

- in line 104

stop defined in line 270; used 7 times

- in line 82-87(2), 94-99(2), 105, 113, 122

#### Defined variables

copyright defined in line 19; never used
passwd defined in line 38; used 6 times

- in line 69-71(3), 81, 146, 273

sccsid defined in line 23; never used
temp defined in line 38; used 10 times

- in line 60-66(3), 86, 120, 133(2), 146, 246, 274

Last modified: 1996-01-13 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1836 |