|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.