Annotation of 42BSD/bin/passwd.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)passwd.c   4.4 (Berkeley) 7/10/83";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Enter a password in the password file.
        !             7:  * This program should be suid with an owner
        !             8:  * with write permission on /etc/passwd.
        !             9:  */
        !            10: #include <sys/file.h>
        !            11: 
        !            12: #include <stdio.h>
        !            13: #include <signal.h>
        !            14: #include <pwd.h>
        !            15: #include <errno.h>
        !            16: 
        !            17: char   passwd[] = "/etc/passwd";
        !            18: char   temp[]   = "/etc/ptmp";
        !            19: struct passwd *pwd;
        !            20: struct passwd *getpwent();
        !            21: int    endpwent();
        !            22: char   *strcpy();
        !            23: char   *crypt();
        !            24: char   *getpass();
        !            25: char   *getlogin();
        !            26: char   *pw;
        !            27: char   pwbuf[10];
        !            28: extern int errno;
        !            29: 
        !            30: main(argc, argv)
        !            31:        char *argv[];
        !            32: {
        !            33:        char *p;
        !            34:        int i;
        !            35:        char saltc[2];
        !            36:        long salt;
        !            37:        int u;
        !            38:        int insist;
        !            39:        int ok, flags;
        !            40:        int c, pwlen, fd;
        !            41:        FILE *tf;
        !            42:        char *uname;
        !            43: 
        !            44:        insist = 0;
        !            45:        if (argc < 2) {
        !            46:                if ((uname = getlogin()) == NULL) {
        !            47:                        printf ("Usage: passwd user\n");
        !            48:                        exit(1);
        !            49:                }
        !            50:                printf("Changing password for %s\n", uname);
        !            51:        } else
        !            52:                uname = argv[1];
        !            53:        while (((pwd = getpwent()) != NULL) && strcmp(pwd->pw_name, uname))
        !            54:                ;
        !            55:        u = getuid();
        !            56:        if (pwd == NULL || (u != 0 && u != pwd->pw_uid)) {
        !            57:                printf("Permission denied.\n");
        !            58:                exit(1);
        !            59:        }
        !            60:        endpwent();
        !            61:        if (pwd->pw_passwd[0] && u != 0) {
        !            62:                strcpy(pwbuf, getpass("Old password:"));
        !            63:                pw = crypt(pwbuf, pwd->pw_passwd);
        !            64:                if (strcmp(pw, pwd->pw_passwd) != 0) {
        !            65:                        printf("Sorry.\n");
        !            66:                        exit(1);
        !            67:                }
        !            68:        }
        !            69: tryagain:
        !            70:        strcpy(pwbuf, getpass("New password:"));
        !            71:        pwlen = strlen(pwbuf);
        !            72:        if (pwlen == 0) {
        !            73:                printf("Password unchanged.\n");
        !            74:                exit(1);
        !            75:        }
        !            76:        /*
        !            77:         * Insure password is of reasonable length and
        !            78:         * composition.  If we really wanted to make things
        !            79:         * sticky, we could check the dictionary for common
        !            80:         * words, but then things would really be slow.
        !            81:         */
        !            82:        ok = 0;
        !            83:        flags = 0;
        !            84:        p = pwbuf;
        !            85:        while (c = *p++) {
        !            86:                if (c >= 'a' && c <= 'z')
        !            87:                        flags |= 2;
        !            88:                else if (c >= 'A' && c <= 'Z')
        !            89:                        flags |= 4;
        !            90:                else if (c >= '0' && c <= '9')
        !            91:                        flags |= 1;
        !            92:                else
        !            93:                        flags |= 8;
        !            94:        }
        !            95:        if (flags >= 7 && pwlen >= 4)
        !            96:                ok = 1;
        !            97:        if ((flags == 2 || flags == 4) && pwlen >= 6)
        !            98:                ok = 1;
        !            99:        if ((flags == 3 || flags == 5 || flags == 6) && pwlen >= 5)
        !           100:                ok = 1;
        !           101:        if (!ok && insist < 2) {
        !           102:                printf("Please use %s.\n", flags == 1 ?
        !           103:                        "at least one non-numeric character" :
        !           104:                        "a longer password");
        !           105:                insist++;
        !           106:                goto tryagain;
        !           107:        }
        !           108:        if (strcmp(pwbuf, getpass("Retype new password:")) != 0) {
        !           109:                printf("Mismatch - password unchanged.\n");
        !           110:                exit(1);
        !           111:        }
        !           112:        time(&salt);
        !           113:        salt = 9 * getpid();
        !           114:        saltc[0] = salt & 077;
        !           115:        saltc[1] = (salt>>6) & 077;
        !           116:        for (i = 0; i < 2; i++) {
        !           117:                c = saltc[i] + '.';
        !           118:                if (c > '9')
        !           119:                        c += 7;
        !           120:                if (c > 'Z')
        !           121:                        c += 6;
        !           122:                saltc[i] = c;
        !           123:        }
        !           124:        pw = crypt(pwbuf, saltc);
        !           125:        signal(SIGHUP, SIG_IGN);
        !           126:        signal(SIGINT, SIG_IGN);
        !           127:        signal(SIGQUIT, SIG_IGN);
        !           128:        (void) umask(0);
        !           129:        fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
        !           130:        if (fd < 0) {
        !           131:                fprintf(stderr, "passwd: ");
        !           132:                if (errno == EEXIST)
        !           133:                        fprintf(stderr, "password file busy - try again.\n");
        !           134:                else
        !           135:                        perror(temp);
        !           136:                exit(1);
        !           137:        }
        !           138:        signal(SIGTSTP, SIG_IGN);
        !           139:        if ((tf = fdopen(fd, "w")) == NULL) {
        !           140:                fprintf(stderr, "passwd: fdopen failed?\n");
        !           141:                exit(1);
        !           142:        }
        !           143:        /*
        !           144:         * Copy passwd to temp, replacing matching lines
        !           145:         * with new password.
        !           146:         */
        !           147:        while ((pwd = getpwent()) != NULL) {
        !           148:                if (strcmp(pwd->pw_name,uname) == 0) {
        !           149:                        u = getuid();
        !           150:                        if (u && u != pwd->pw_uid) {
        !           151:                                fprintf(stderr, "passwd: permission denied.\n");
        !           152:                                unlink(temp);
        !           153:                                exit(1);
        !           154:                        }
        !           155:                        pwd->pw_passwd = pw;
        !           156:                        if (pwd->pw_gecos[0] == '*')
        !           157:                                pwd->pw_gecos++;
        !           158:                }
        !           159:                fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
        !           160:                        pwd->pw_name,
        !           161:                        pwd->pw_passwd,
        !           162:                        pwd->pw_uid,
        !           163:                        pwd->pw_gid,
        !           164:                        pwd->pw_gecos,
        !           165:                        pwd->pw_dir,
        !           166:                        pwd->pw_shell);
        !           167:        }
        !           168:        endpwent();
        !           169:        if (rename(temp, passwd) < 0) {
        !           170:                fprintf(stderr, "passwd: "); perror("rename");
        !           171:                unlink(temp);
        !           172:                exit(1);
        !           173:        }
        !           174:        fclose(tf);
        !           175: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.