Annotation of 40BSD/cmd/passwd.c, revision 1.1

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

unix.superglobalmegacorp.com

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