Annotation of 40BSD/cmd/passwd.c, revision 1.1.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.