Commit | Line | Data |
---|---|---|
fde98a2d BJ |
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 | char *tfile { "/usr/adm/ptmp" }; | |
7 | char *pfile { "/etc/passwd" }; | |
8 | char *pw; | |
9 | char pwbuf[10]; | |
10 | int ttybuf[3]; | |
11 | int tbuf[259]; | |
12 | int pbuf[259]; | |
13 | ||
14 | main(argc, argv) | |
15 | char *argv[]; | |
16 | { | |
17 | register u, c; | |
18 | register char *p; | |
19 | int exitt(); | |
20 | int v; | |
21 | char x; | |
22 | ||
23 | if(argc < 2) { | |
24 | write(2, "Usage: passwd user [ password ]\n", 32); | |
25 | goto bex; | |
26 | } | |
27 | if(argc == 2) { | |
28 | signal(1, &exitt); | |
29 | signal(2, &exitt); | |
30 | signal(3, &exitt); | |
31 | gtty(0, ttybuf); | |
32 | ttybuf[2] =& ~010; | |
33 | stty(0, ttybuf); | |
34 | again: | |
35 | write(2, "Password: ", 10); | |
36 | p = pwbuf; | |
37 | for(;;) { | |
38 | if(read(0, p, 1) != 1) | |
39 | break; | |
40 | if(*p == '\n') | |
41 | break; | |
42 | if(p < pwbuf+9) | |
43 | p++; | |
44 | } | |
45 | *p = 0; | |
46 | write(2, "\nAgain: ", 8); | |
47 | p = pwbuf; | |
48 | for (;;) { | |
49 | if (read(0, &x, 1) != 1 || x == '\n') | |
50 | break; | |
51 | if (*p++ != x) { | |
52 | xxx: | |
53 | while (read(0, &x, 1) == 1 && x != '\n') | |
54 | continue; | |
55 | write(2, "\nThose weren't the same\n", 24); | |
56 | goto again; | |
57 | } | |
58 | } | |
59 | if (*p != 0) | |
60 | goto xxx; | |
61 | ttybuf[2] =| 010; | |
62 | stty(0, ttybuf); | |
63 | write(2, "\n", 1); | |
64 | pw = pwbuf; | |
65 | } else | |
66 | pw = argv[2]; | |
67 | signal(1, 1); | |
68 | signal(2, 1); | |
69 | signal(3, 1); | |
70 | ||
71 | if(stat(tfile, tbuf+20) >= 0) { | |
72 | write(2, "Temporary file busy -- try again\n", 33); | |
73 | goto bex; | |
74 | } | |
75 | tbuf[0] = creat(tfile, 0600); | |
76 | if(tbuf[0] < 0) { | |
77 | write(2, "Cannot create temporary file\n", 29); | |
78 | goto bex; | |
79 | } | |
80 | pbuf[0] = open(pfile, 0); | |
81 | if(pbuf[0] < 0) { | |
82 | write(2, "Cannot open /etc/passwd\n", 25); | |
83 | goto out; | |
84 | } | |
85 | goto l1; | |
86 | ||
87 | /* | |
88 | * skip to beginning of next line | |
89 | */ | |
90 | ||
91 | skip: | |
92 | while(c != '\n') { | |
93 | if(c < 0) | |
94 | goto ill; | |
95 | c = getc(pbuf); | |
96 | putc(c, tbuf); | |
97 | } | |
98 | ||
99 | /* | |
100 | * compare user names | |
101 | */ | |
102 | ||
103 | l1: | |
104 | c = getc(pbuf); | |
105 | putc(c, tbuf); | |
106 | if(c < 0) { | |
107 | write(2, "User name not found in password file\n", 37); | |
108 | goto out; | |
109 | } | |
110 | p = argv[1]; | |
111 | while(c != ':') { | |
112 | if(*p++ != c) | |
113 | goto skip; | |
114 | c = getc(pbuf); | |
115 | putc(c, tbuf); | |
116 | } | |
117 | if(*p) | |
118 | goto skip; | |
119 | /* | |
120 | * skip old password | |
121 | */ | |
122 | do { | |
123 | c = getc(pbuf); | |
124 | if(c < 0) | |
125 | goto ill; | |
126 | } while(c != ':'); | |
127 | ||
128 | /* | |
129 | * copy in new password | |
130 | */ | |
131 | p = pw; | |
132 | for(c=0; c<9; c++) | |
133 | if(*p++ == 0) | |
134 | break; | |
135 | *--p = 0; | |
136 | if(p != pw) | |
137 | p = crypt(pw); | |
138 | while(*p) | |
139 | putc(*p++, tbuf); | |
140 | putc(':', tbuf); | |
141 | ||
142 | /* | |
143 | * validate uid and gid | |
144 | */ | |
145 | ||
146 | u = 0; | |
147 | do { | |
148 | c = getc(pbuf); | |
149 | putc(c, tbuf); | |
150 | if(c >= '0' && c <= '9') | |
151 | u = u*10 + c-'0'; | |
152 | if(c < 0) | |
153 | goto ill; | |
154 | } while(c != ':'); | |
155 | v = 0; | |
156 | do { | |
157 | c = getc(pbuf); | |
158 | putc(c, tbuf); | |
159 | if(c >= '0' && c <= '9') | |
160 | v = v*10 + c-'0'; | |
161 | if(c < 0) | |
162 | goto ill; | |
163 | } while(c != ':'); | |
164 | c = getuid(); | |
165 | if(c == 0) | |
166 | goto ok; | |
167 | if(c == ((v<<8) | u)) | |
168 | goto ok; | |
169 | if((c&0377) == 0 && ((c>>8)&0377) == v) | |
170 | goto ok; | |
171 | write(2, "Permission denied\n", 18); | |
172 | goto out; | |
173 | ok: | |
174 | ||
175 | /* | |
176 | * copy out and back | |
177 | */ | |
178 | ||
179 | for(;;) { | |
180 | c = getc(pbuf); | |
181 | if(c < 0) { | |
182 | fflush(tbuf); | |
183 | close(pbuf[0]); | |
184 | close(tbuf[0]); | |
185 | tbuf[0] = open(tfile, 0); | |
186 | if(tbuf[0] < 0) { | |
187 | write(2, "Urk\n", 4); | |
188 | goto out; | |
189 | } | |
190 | pbuf[0] = creat(pfile, 0644); | |
191 | if(pbuf[0] < 0) { | |
192 | write(2, "Cannot create /etc/passwd\n", 27); | |
193 | goto out; | |
194 | } | |
195 | while((c = read(tbuf[0], tbuf+1, 512)) > 0) | |
196 | write(pbuf[0], tbuf+1, c); | |
197 | unlink(tfile); | |
198 | exit(0); | |
199 | } | |
200 | putc(c, tbuf); | |
201 | } | |
202 | ||
203 | ill: | |
204 | write(2, "Password file illformed\n", 24); | |
205 | ||
206 | out: | |
207 | unlink(tfile); | |
208 | ||
209 | bex: | |
210 | exit(1); | |
211 | } | |
212 | ||
213 | exitt() | |
214 | { | |
215 | ttybuf[2] =| 010; | |
216 | stty(0, ttybuf); | |
217 | write(2, "\n", 1); | |
218 | exit(1); | |
219 | } |