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[512];
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: }
139: fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
140: pwd->pw_name,
141: pwd->pw_passwd,
142: pwd->pw_uid,
143: pwd->pw_gid,
144: pwd->pw_gecos,
145: pwd->pw_dir,
146: pwd->pw_shell);
147: }
148: endpwent();
149: fclose(tf);
150:
151: /*
152: * copy temp back to passwd file
153: */
154:
155: if((fi=open(temp,0)) < 0) {
156: printf("Temp file disappeared!\n");
157: goto out;
158: }
159: if((fo=creat(passwd, 0644)) < 0) {
160: printf("Cannot recreat passwd file.\n");
161: goto out;
162: }
163: while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u);
164:
165: out:
166: unlink(temp);
167:
168: bex:
169: exit(1);
170: }
Defined functions
main
defined in line
23;
never used
Defined variables
buf
defined in line
21; used 3 times
pw
defined in line
19; used 4 times
pwbuf
defined in line
20; used 7 times
pwd
defined in line
12; used 18 times
temp
defined in line
11; used 5 times