Annotation of 3BSD/cmd/passwd.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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