Annotation of coherent/d/bin/passwd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Rec'd from Lauren Weinstein, 7-16-84.
        !             3:  * Passwd - set login password
        !             4:  * for a user.
        !             5:  */
        !             6: 
        !             7: #include <stdio.h>
        !             8: #include <ctype.h>
        !             9: #include <sys/types.h>
        !            10: #include <pwd.h>
        !            11: #include <signal.h>
        !            12: #include <errno.h>
        !            13: 
        !            14: #define        NSALT   64              /* Size of salt character set */
        !            15: #define        NSALTC  2               /* Number of characters in salt */
        !            16: #define        NPASSC  32              /* Maximum characters copied into pass. buf */
        !            17: #define        AWRITE  2               /* Access for write */
        !            18: #define        NLOKOUT 7               /* Maximum number of lockout attempts */
        !            19: #define        NPWCHAR 256             /* Number of characters in passwd file line */
        !            20: 
        !            21: char   notrich[] = "\
        !            22: Password is too easily broken\n\
        !            23: Try again: \
        !            24: ";
        !            25: char   pfile[] = "/etc/passwd";
        !            26: char   tmpfile[] = "/tmp/passwd";
        !            27: 
        !            28: char   salttab[NSALT] =
        !            29:        "./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        !            30: 
        !            31: char   pwline[NPWCHAR];
        !            32: 
        !            33: FILE   *lockopen();
        !            34: char   *crypt();
        !            35: int    cleanup();
        !            36: time_t time();
        !            37: 
        !            38: int    tmpflag;                /* Says tempfile is open */
        !            39: 
        !            40: main(argc, argv)
        !            41: char *argv[];
        !            42: {
        !            43:        register struct passwd *pwp;
        !            44:        register char *pass, *name;
        !            45:        char passbuf[NPASSC+1];
        !            46:        int myuid;
        !            47:        char *myname;
        !            48:        extern char *getpass();
        !            49:        extern char *getlogin();
        !            50: 
        !            51:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !            52:                signal(SIGINT, cleanup);
        !            53:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
        !            54:                signal(SIGHUP, cleanup);
        !            55:        myuid = getuid();
        !            56: 
        !            57:        umask(077);  /* mask out file access by other users */
        !            58: 
        !            59:        if (argc > 1) { /* By supplied argument */
        !            60:                if (argc != 2)
        !            61:                        usage();
        !            62:                if ((pwp = getpwnam(argv[1])) == NULL)
        !            63:                        perr("%s: bad user name\n", argv[1]);
        !            64:                if (myuid!=0 && pwp->pw_uid!=myuid)
        !            65:                        perr("%s: not allowed to change password\n", argv[1]);
        !            66:                name = argv[1];  /* get name for change */
        !            67:        } else          /* By getlogin from /etc/utmp */
        !            68:        if ((myname = getlogin()) != NULL) {
        !            69:                if ((pwp = getpwnam(myname)) == NULL)
        !            70:                        perr("%s: bad login name\n", argv[1]);
        !            71:                if (myuid != 0 && pwp->pw_uid != myuid)
        !            72:                        perr("%s: not allowed to change password\n", argv[1]);
        !            73:                name = myname;  /* get name for change */
        !            74:        } else {        /* By user id */
        !            75:                if ((pwp = getpwuid(myuid)) == NULL)
        !            76:                        perr("Error on /etc/passwd\n");
        !            77:                while ((pwp = getpwent()) != NULL)
        !            78:                        if (pwp->pw_uid == myuid)
        !            79:                                perr("user id is not unique\n");
        !            80:                pwp = getpwuid(myuid);
        !            81:                name = pwp->pw_name;  /* changing our own name */
        !            82:        }
        !            83:        if (myuid!=0 && pwp->pw_passwd[0]!='\0') {
        !            84:                if ((pass = getpass("Old password: ")) == NULL)
        !            85:                        exit(1);
        !            86:                if (!checkpass(pwp->pw_passwd, pass))
        !            87:                        perr("Sorry\n");
        !            88:        }
        !            89:        if ((pass = getpass("New password: ")) == NULL)
        !            90:           exit(1);
        !            91:        if (pass[0] != 0 || (pass[0] == 0 && getuid() != 0))
        !            92:           while (!richenough(pass) || !strcmp(pass, pwp->pw_name))
        !            93:              if ((pass = getpass(notrich)) == NULL)
        !            94:                 exit(1);
        !            95:        strncpy(passbuf, pass, NPASSC);
        !            96:        if ((pass = getpass("Verification: ")) == NULL) 
        !            97:           exit(1);
        !            98:        if (strncmp(pass, passbuf, NPASSC) != 0)
        !            99:           perr("No match: password not changed\n");
        !           100:        setpass(name, pass);
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * Tests to see if a password is rich enough
        !           105:  * (i.e. not too easy to break by exhaustion).
        !           106:  * A password must be 4 characters if the alphabet
        !           107:  * is rich enough and 6 characters if it is in a
        !           108:  * single case.  Perhaps the dictionary should
        !           109:  * be searched as well for more security-conscious
        !           110:  * systems.  We also check (above) to make sure
        !           111:  * that the selected password is not the same as the username!
        !           112:  */
        !           113: richenough(passwd)
        !           114: char *passwd;
        !           115: {
        !           116:        register char *cp;
        !           117:        register int uflag=0, lflag=0, oflag=0;
        !           118:        register int l;
        !           119: 
        !           120:        for (cp = passwd; *cp != '\0'; cp++) {
        !           121:                if (islower(*cp))
        !           122:                        lflag = 1;
        !           123:                else if (isupper(*cp))
        !           124:                        uflag = 1;
        !           125:                else
        !           126:                        oflag = 1;
        !           127:        }
        !           128:        l = cp-passwd;
        !           129:        if (l < 4)
        !           130:                return (0);
        !           131:        if (oflag==0 && lflag^uflag && l<6)
        !           132:                return (0);
        !           133:        return (1);
        !           134: }
        !           135: 
        !           136: /*
        !           137:  * Check the passwd in the password file (`rpass')
        !           138:  * against the typed-in (`tpass') password.
        !           139:  */
        !           140: checkpass(rpass, tpass)
        !           141: register char *rpass, *tpass;
        !           142: {
        !           143:        char salt[3];
        !           144: 
        !           145:        salt[0] = rpass[0];
        !           146:        salt[1] = rpass[1];
        !           147:        return (strcmp(crypt(tpass, salt), rpass) == 0);
        !           148: }
        !           149: 
        !           150: /*
        !           151:  * Set password for specified name.
        !           152:  */
        !           153: setpass(name, passwd)
        !           154: char *name, *passwd;
        !           155: {
        !           156:        char salt[NSALTC+1];
        !           157:        char namebuff[NPWCHAR];  /* name buffer */
        !           158:        time_t xtime;
        !           159:        register char *p1, *p2;
        !           160:        register int c;
        !           161:        register FILE *pwf;
        !           162:        register FILE *tf;
        !           163: 
        !           164:        /*
        !           165:         * Generate the salt for crypt.
        !           166:         */
        !           167:        time(&xtime);
        !           168:        srand((int)xtime);
        !           169:        salt[0] = salttab[rand()%NSALT];
        !           170:        salt[1] = salttab[rand()%NSALT];
        !           171:        salt[2] = '\0';
        !           172:        if (*passwd != '\0')
        !           173:                passwd = crypt(passwd, salt);
        !           174:        /*
        !           175:         * Copy password file to tempfile
        !           176:         * looking for slot to change.
        !           177:         * The format of a passwd entry is:
        !           178:         * name:password:uid:...
        !           179:         */
        !           180:        if ((pwf = fopen(pfile, "r")) == NULL)
        !           181:                perr("Cannot open %s\n", pfile);
        !           182:        tf = lockopen(tmpfile);
        !           183:        while (fgets(pwline, NPWCHAR, pwf) != NULL) {
        !           184:                strcpy(namebuff, pwline);  /* copy line */
        !           185:                p1 = namebuff;          
        !           186:                while (*p1 != '\0')
        !           187:                        if (*p1++ == ':')
        !           188:                                break;  
        !           189:                *--p1 = '\0';  /* null terminate user name */
        !           190:                                        
        !           191:                p1 = pwline;
        !           192:                while (*p1 != '\0')
        !           193:                        if (*p1++ == ':')
        !           194:                                break;
        !           195:                p2 = p1;
        !           196:                while (*p2 != '\0')
        !           197:                        if (*p2++ == ':')
        !           198:                                break;
        !           199: 
        !           200:                if (!strcmp(namebuff, name)) {  /* check for name match */
        !           201:                        *p1 = '\0';
        !           202:                        fputs(pwline, tf);
        !           203:                        fputs(passwd, tf);
        !           204:                        putc(':', tf);
        !           205:                        fputs(p2, tf);
        !           206:                        break;
        !           207:                }
        !           208:                fputs(pwline, tf);
        !           209:        }
        !           210:        while ((c = getc(pwf)) != EOF)  /* copy rest of file */
        !           211:                putc(c, tf);
        !           212:        fclose(pwf);
        !           213:        /*
        !           214:         * Copy tempfile back to password
        !           215:         * file -- this runs protected
        !           216:         * from interrupts.
        !           217:         */
        !           218:        signal(SIGINT, SIG_IGN);
        !           219:        signal(SIGHUP, SIG_IGN);
        !           220:        signal(SIGQUIT, SIG_IGN);
        !           221:        if ((pwf = fopen(pfile, "w")) == NULL)
        !           222:                perr("Cannot create %s\n", pfile);
        !           223:        fflush(tf);
        !           224:        rewind(tf);
        !           225:        while ((c = getc(tf)) != EOF)
        !           226:                putc(c, pwf);
        !           227:        fflush(pwf);
        !           228:        unlink(tmpfile);  
        !           229: }
        !           230: 
        !           231: /*
        !           232:  * Open the tempfile waiting
        !           233:  * for the tempfile to come free.
        !           234:  */
        !           235: FILE *
        !           236: lockopen(file)
        !           237: char *file;
        !           238: {
        !           239:        register int n;
        !           240:        register FILE *fp;
        !           241:        extern int errno;
        !           242: 
        !           243:        for (n=NLOKOUT; n>0; n--)
        !           244:                if (access(file, AWRITE)<0 && errno==ENOENT) {
        !           245:                        if ((fp=fopen(file, "w")) == NULL
        !           246:                        ||  (fp=freopen(file, "r+w", fp)) == NULL)
        !           247:                                perr("Cannot create tempfile\n");
        !           248:                        tmpflag = 1;
        !           249:                        return (fp);
        !           250:                }
        !           251:        perr("Tempfile busy, try again later\n");
        !           252: }
        !           253: 
        !           254: /*
        !           255:  * Cleanup the tempfile.
        !           256:  */
        !           257: cleanup()
        !           258: {
        !           259:        if (tmpflag)
        !           260:                unlink(tmpfile);
        !           261:        exit (1);
        !           262: }
        !           263: 
        !           264: /*
        !           265:  * Error routines
        !           266:  */
        !           267: usage()
        !           268: {
        !           269:        perr("Usage: passwd [name]\n");
        !           270: }
        !           271: 
        !           272: perr(x)
        !           273: {
        !           274:        fprintf(stderr, "%r", &x);
        !           275:        exit(1);
        !           276: }

unix.superglobalmegacorp.com

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