1: static char sccsid[] = "@(#)passwd.c 2.7"; /* SCCS id keywords */
2: #include <whoami.h>
3:
4: #define SMLROOT 1 /* Small root device, forces two copies */
5: /* #define V6CRYPT 1 /* Accept version 6 passwd as well */
6:
7: /*
8: * enter a password in the password file
9: * this program should be suid with owner
10: * with an owner with write permission on /etc/passwd
11: */
12: #include <stdio.h>
13: #include <signal.h>
14: #include <pwd.h>
15:
16: #define V7PWDSIZE 13
17: static char passwd[] = "/etc/passwd";
18: #ifndef SMLROOT
19: char temp[] = "/etc/ptmp";
20: #else
21: char temp[] = "/tmp/pwdXXXXXX";
22: #endif
23:
24: struct passwd *pwd;
25: struct passwd *getpwent();
26: int endpwent();
27: char *strcpy();
28: char *crypt();
29: #ifdef V6CRYPT
30: char *v6crypt();
31: #endif
32: char *getpass();
33: char *getlogin();
34: char *pw;
35: char pwbuf[10];
36: char buf[512];
37: int sizechanged = 0;
38:
39: main(argc, argv)
40: char *argv[];
41: {
42: char *p;
43: int i;
44: char saltc[2];
45: long salt;
46: int u,g,fi,fo;
47: int insist;
48: int ok, flags;
49: int c;
50: int pwlen;
51: FILE *tf;
52: char *uname;
53:
54: insist = 0;
55: if(argc < 2) {
56: if ((uname = getlogin()) == NULL) {
57: printf ("Usage: passwd user\n");
58: goto bex;
59: } else {
60: printf("Changing password for %s\n", uname);
61: fflush(stdout);
62: }
63: } else {
64: uname = argv[1];
65: }
66: while(((pwd=getpwent()) != NULL)&&(strcmp(pwd->pw_name,uname)!=0));
67: u = getuid();
68: g = getgid();
69: #ifdef UCB_GRPMAST
70: if((pwd==NULL) || (u!=0 && u != pwd->pw_uid &&
71: (u!=g || g!=pwd->pw_gid)))
72: #else
73: if((pwd==NULL) || (u!=0 && u != pwd->pw_uid))
74: #endif
75: {
76: printf("Permission denied.\n");
77: goto bex;
78: }
79: endpwent();
80: if (pwd->pw_passwd[0] && u == pwd->pw_uid) {
81: strcpy(pwbuf, getpass("Old password:"));
82: pw = crypt(pwbuf, pwd->pw_passwd);
83: if(strcmp(pw, pwd->pw_passwd) != 0) {
84: #ifdef V6CRYPT
85: pw = v6crypt(pwbuf);
86: if (strcmp(pw, pwd->pw_passwd) != 0) {
87: #endif
88: printf("Sorry.\n");
89: goto bex;
90: }
91: #ifdef V6CRYPT
92: }
93: #endif
94: }
95: sizechanged = (strlen(pwd->pw_passwd) != V7PWDSIZE);
96: tryagn:
97: strcpy(pwbuf, getpass("New password:"));
98: pwlen = strlen(pwbuf);
99: if (pwlen == 0) {
100: printf("Password unchanged.\n");
101: goto bex;
102: }
103: ok = 0;
104: flags = 0;
105: p = pwbuf;
106: while(c = *p++){
107: if(c>='a' && c<='z') flags |= 2;
108: else if(c>='A' && c<='Z') flags |= 4;
109: else if(c>='0' && c<='9') flags |= 1;
110: else flags |= 8;
111: }
112: if(flags >=7 && pwlen>= 4) ok = 1;
113: if(((flags==2)||(flags==4)) && pwlen>=6) ok = 1;
114: if(((flags==3)||(flags==5)||(flags==6))&&pwlen>=5) ok = 1;
115:
116: if((ok==0) && (insist<2)){
117: if(flags==1)
118: printf("Please use at least one non-numeric character.\n");
119: else
120: printf("Please use a longer password.\n");
121: fflush(stdout);
122: insist++;
123: goto tryagn;
124: }
125:
126: if (strcmp(pwbuf,getpass("Retype new password:")) != 0) {
127: printf ("Mismatch - password unchanged.\n");
128: goto bex;
129: }
130:
131: time(&salt);
132: salt += getpid();
133:
134: saltc[0] = salt & 077;
135: saltc[1] = (salt>>6) & 077;
136: for(i=0;i<2;i++){
137: c = saltc[i] + '.';
138: if(c>'9') c += 7;
139: if(c>'Z') c += 6;
140: saltc[i] = c;
141: }
142: pw = crypt(pwbuf, saltc);
143: signal(SIGHUP, SIG_IGN);
144: signal(SIGINT, SIG_IGN);
145: signal(SIGQUIT, SIG_IGN);
146:
147: if (pwlock("r")) {
148: printf("Temporary file busy -- try again\n");
149: goto bex;
150: }
151: #ifdef SMLROOT
152: mktemp(temp);
153: #endif
154: close(creat(temp,0600));
155: if((tf=fopen(temp,"w")) == NULL) {
156: printf("Cannot create temporary file\n");
157: goto bex;
158: }
159:
160: if((fi=open(temp,0)) < 0) {
161: printf("Temp file disappeared!\n");
162: goto out;
163: }
164:
165: /*
166: * copy passwd to temp, replacing matching lines
167: * with new password.
168: */
169:
170: while((pwd=getpwent()) != NULL) {
171: if(strcmp(pwd->pw_name,uname) == 0) {
172: u = getuid();
173: g = getgid();
174: #ifdef UCB_GRPMAST
175: if(u!=0 && u != pwd->pw_uid &&
176: (u!=g || g!=pwd->pw_gid))
177: #else
178: if(u!=0 && u != pwd->pw_uid)
179: #endif
180: {
181: printf("Permission denied.\n");
182: goto out;
183: }
184: pwd->pw_passwd = pw;
185: }
186: fprintf(tf,"%s:%s:%u:%u:%s:%s:%s\n",
187: pwd->pw_name,
188: pwd->pw_passwd,
189: pwd->pw_uid,
190: pwd->pw_gid,
191: pwd->pw_gecos,
192: pwd->pw_dir,
193: pwd->pw_shell);
194: }
195: endpwent();
196: fclose(tf);
197:
198: /*
199: * copy temp back to passwd file
200: */
201:
202: if((fo=creat(passwd, 0644)) < 0) {
203: printf("Cannot recreat passwd file.\n");
204: goto out;
205: }
206: while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u);
207:
208: out:
209: if (sizechanged)
210: #ifdef UCB_PWHASH
211: pwtable();
212: #else
213: ;
214: #endif
215: unlink(temp);
216: pwunlock();
217: exit(0);
218: bex:
219:
220: exit(1);
221: }
Defined functions
main
defined in line
39;
never used
Defined variables
buf
defined in line
36; used 3 times
pw
defined in line
34; used 6 times
pwbuf
defined in line
35; used 8 times
pwd
defined in line
24; used 26 times
sccsid
defined in line
1;
never used
temp
defined in line
21; used 5 times
Defined macros