# 2.11BSD#431 - /usr/src/bin/passwd/passwd.c

##### Functions

    copy              X
    getnewpasswd      X
    main              X
    makedb            X

##### Variables

    copyright         X
    uid               X

       1: /*
       2:  * Copyright (c) 1988 The 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      16:  */
      17:
      18: #ifndef lint
      19: char copyright[] =
      20: "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
      21:  All rights reserved.\n";
      22: #endif /* not lint */
      23:
      24: #ifndef lint
      25: static char sccsid[] = "@(#)passwd.c	4.35 (Berkeley) 3/16/89";
      26: #endif /* not lint */
      27:
      28: #include <sys/param.h>
      29: #include <sys/file.h>
      30: #include <sys/signal.h>
      31: #include <sys/time.h>
      32: #include <sys/resource.h>
      33: #include <errno.h>
      34: #include <pwd.h>
      35: #include <stdio.h>
      36: #include <ctype.h>
      37: #include <strings.h>
      38:
      39: uid_t uid;
      40:
      41: main(argc, argv)
      42:     int argc;
      43:     char **argv;
      44: {
      45:     extern int errno;
      46:     struct passwd *pw;
      47:     struct rlimit rlim;
      48:     FILE *temp_fp;
      49:     int fd;
      50:     char *fend, *np, *passwd, *temp, *tend;
      51:     char from[MAXPATHLEN], to[MAXPATHLEN];
      52:     char *getnewpasswd();
      53:
      54:     uid = getuid();
      55:     switch(--argc) {
      56:     case 0:
      57:         if (!(pw = getpwuid(uid))) {
      58:             fprintf(stderr, "passwd: unknown user: uid %u\n", uid);
      59:             exit(1);
      60:         }
      61:         break;
      62:     case 1:
      63:         if (!(pw = getpwnam(argv[1]))) {
      64:             fprintf(stderr, "passwd: unknown user %s.\n", argv[1]);
      65:             exit(1);
      66:         }
      67:         if (uid && uid != pw->pw_uid) {
      68:             fprintf(stderr, "passwd: %s\n", strerror(EACCES));
      69:             exit(1);
      70:         }
      71:         break;
      72:     default:
      73:         fprintf(stderr, "usage: passwd [user]\n");
      74:         exit(1);
      75:     }
      76:
      77:     (void)signal(SIGHUP, SIG_IGN);
      78:     (void)signal(SIGINT, SIG_IGN);
      79:     (void)signal(SIGQUIT, SIG_IGN);
      80:     (void)signal(SIGTSTP, SIG_IGN);
      81:
      82:     rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
      83:     (void)setrlimit(RLIMIT_CPU, &rlim);
      84:     (void)setrlimit(RLIMIT_FSIZE, &rlim);
      85:
      86:     (void)umask(0);
      87:
      88:     temp = _PATH_PTMP;
      89:     if ((fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0) {
      90:         if (errno == EEXIST) {
      91:             fprintf(stderr,
      92:                 "passwd: password file busy -- try again later.\n");
      93:             exit(0);
      94:         }
      95:         fprintf(stderr, "passwd: %s: %s", temp, strerror(errno));
      96:         goto bad;
      97:     }
      98:     if (!(temp_fp = fdopen(fd, "w"))) {
      99:         fprintf(stderr, "passwd: can't write %s\n", temp);
     100:         goto bad;
     101:     }
     102:     passwd = _PATH_MASTERPASSWD;
     103:     if (!freopen(passwd, "r", stdin)) {
     104:         fprintf(stderr, "passwd: can't read %s\n", passwd);
     105:         goto bad;
     106:     }
     107:
     108:     printf("Changing password for %s.\n", pw->pw_name);
     109:     np = getnewpasswd(pw, temp);
     110:
     111:     if (!copy(pw->pw_name, np, temp_fp, pw))
     112:         goto bad;
     113:
     114:     (void)fclose(temp_fp);
     115:     (void)fclose(stdin);
     116:
     117:     switch(fork()) {
     118:     case 0:
     119:         break;
     120:     case -1:
     121:         fprintf(stderr, "passwd: can't fork");
     122:         goto bad;
     123:         /* NOTREACHED */
     124:     default:
     125:         exit(0);
     126:         /* NOTREACHED */
     127:     }
     128:
     129:     if (makedb(temp)) {
     130:         fprintf(stderr, "passwd: mkpasswd failed");
     131: bad:        fprintf(stderr, "; password unchanged.\n");
     132:         (void)unlink(temp);
     133:         exit(1);
     134:     }
     135:
     136:     /*
     137: 	 * possible race; have to rename four files, and someone could slip
     138: 	 * in between them.  LOCK_EX and rename the ``passwd.dir'' file first
     139: 	 * so that getpwent(3) can't slip in; the lock should never fail and
     140: 	 * it's unclear what to do if it does.  Rename ``ptmp'' last so that
     141: 	 * passwd/vipw/chpass can't slip in.
     142: 	 */
     143:     (void)setpriority(PRIO_PROCESS, 0, -20);
     144:     fend = strcpy(from, temp) + strlen(temp);
     145:     tend = strcpy(to, _PATH_PASSWD) + strlen(_PATH_PASSWD);
     146:     bcopy(".dir", fend, 5);
     147:     bcopy(".dir", tend, 5);
     148:     if ((fd = open(from, O_RDONLY, 0)) >= 0)
     149:         (void)flock(fd, LOCK_EX);
     150:     /* here we go... */
     151:     (void)rename(from, to);
     152:     bcopy(".pag", fend, 5);
     153:     bcopy(".pag", tend, 5);
     154:     (void)rename(from, to);
     155:     bcopy(".orig", fend, 6);
     156:     (void)rename(from, _PATH_PASSWD);
     157:     (void)rename(temp, passwd);
     158:     /* done! */
     159:     exit(0);
     160: }
     161:
     162: copy(name, np, fp, pw)
     163:     char *name, *np;
     164:     FILE *fp;
     165:     struct passwd *pw;
     166: {
     167:     register int done;
     168:     register char *p;
     169:     char buf[256];
     170:
     171:     for (done = 0; fgets(buf, sizeof(buf), stdin);) {
     172:         /* skip lines that are too big */
     173:         if (!index(buf, '\n')) {
     174:             fprintf(stderr, "passwd: line too long.\n");
     175:             return(0);
     176:         }
     177:         if (done) {
     178:             fprintf(fp, "%s", buf);
     179:             continue;
     180:         }
     181:         if (!(p = index(buf, ':'))) {
     182:             fprintf(stderr, "passwd: corrupted entry.\n");
     183:             return(0);
     184:         }
     185:         *p = '\0';
     186:         if (strcmp(buf, name)) {
     187:             *p = ':';
     188:             fprintf(fp, "%s", buf);
     189:             continue;
     190:         }
     191:         if (!(p = index(++p, ':'))) {
     192:             fprintf(stderr, "passwd: corrupted entry.\n");
     193:             return(0);
     194:         }
     195:         /*
     196: 		 * reset change time to zero; when classes are implemented,
     197: 		 * go and get the "offset" value for this class and reset
     198: 		 * the timer.
     199: 		 */
     200:         fprintf(fp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
     201:             pw->pw_name, np, pw->pw_uid, pw->pw_gid,
     202:             pw->pw_class, 0L, pw->pw_expire, pw->pw_gecos,
     203:             pw->pw_dir, pw->pw_shell);
     204:         done = 1;
     205:     }
     206:     return(1);
     207: }
     208:
     209: char *
     210: getnewpasswd(pw, temp)
     211:     register struct passwd *pw;
     212:     char *temp;
     213: {
     214:     register char *p, *t;
     215:     char buf[10], salt[2], *crypt(), *getpass();
     216:     time_t time();
     217:
     218:     if (uid && pw->pw_passwd &&
     219:         strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
     220:         pw->pw_passwd)) {
     221:         (void)printf("passwd: %s.\n", strerror(EACCES));
     222:         (void)unlink(temp);
     223:         exit(1);
     224:     }
     225:
     226:     for (buf[0] = '\0';;) {
     227:         p = getpass("New password:");
     228:         if (!*p) {
     229:             (void)printf("Password unchanged.\n");
     230:             (void)unlink(temp);
     231:             exit(0);
     232:         }
     233:         if (strlen(p) <= 5) {
     234:             printf("Please enter a longer password.\n");
     235:             continue;
     236:         }
     237:         for (t = p; *t && islower(*t); ++t);
     238:         if (!*t) {
     239:             printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n");
     240:             continue;
     241:         }
     242:         (void)strcpy(buf, p);
     243:         if (!strcmp(buf, getpass("Retype new password:")))
     244:             break;
     245:         printf("Mismatch; try again, EOF to quit.\n");
     246:     }
     247:     /* grab a random printable character that isn't a colon */
     248:     (void)srandom((int)time((time_t *)NULL));
     249:     while ((salt[0] = random() % 93 + 33) == ':');
     250:     while ((salt[1] = random() % 93 + 33) == ':');
     251:     return(crypt(buf, salt));
     252: }
     253:
     254: makedb(file)
     255:     char *file;
     256: {
     257:     int status, pid, w;
     258:
     259:     if (!(pid = vfork())) {
     260:         execl(_PATH_MKPASSWD, "mkpasswd", "-p", file, NULL);
     261:         _exit(127);
     262:     }
     263:     while ((w = wait(&status)) != pid && w != -1);
     264:     return(w == -1 || status);
     265: }

#### Defined functions

copy defined in line 162; used 1 times

- in line 111

getnewpasswd defined in line 209; used 2 times

- in line 52, 109

main defined in line 41; never used
makedb defined in line 254; used 1 times

- in line 129

#### Defined variables

copyright defined in line 19; never used
sccsid defined in line 25; never used
uid defined in line 39; used 6 times

- in line 54-58(3), 67(2), 218

Last modified: 1989-05-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1756 |