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