1 #include "all.h"
2
3 struct
4 {
5 RWLock uidlock;
6 char* uidbuf;
7 int flen;
8 int find;
9 } uidgc;
10
11 int
byuid(void * a1,void * a2)12 byuid(void *a1, void *a2)
13 {
14 Uid *u1, *u2;
15
16 u1 = a1;
17 u2 = a2;
18 return u2->uid - u1->uid;
19 }
20
21 int
byname(void * a1,void * a2)22 byname(void *a1, void *a2)
23 {
24 Uid *u1, *u2;
25
26 u1 = a1;
27 u2 = a2;
28 return strcmp(uidspace+u2->offset, uidspace+u1->offset);
29 }
30
31 int
fchar(void)32 fchar(void)
33 {
34
35 if(uidgc.find >= uidgc.flen) {
36 uidgc.find = 0;
37 uidgc.flen = con_read(FID2, uidgc.uidbuf, cons.offset, MAXDAT);
38 if(uidgc.flen <= 0)
39 return 0;
40 cons.offset += uidgc.flen;
41 }
42 return uidgc.uidbuf[uidgc.find++];
43 }
44
45 int
fname(char * name)46 fname(char *name)
47 {
48 int i, c;
49
50 memset(name, 0, NAMELEN);
51 for(i=0;; i++) {
52 c = fchar();
53 switch(c) {
54 case ':':
55 case '\n':
56 case ',':
57 case ' ':
58 case '#':
59 case 0:
60 return c;
61 }
62 if(i < NAMELEN-1)
63 name[i] = c;
64 }
65 }
66
67 #ifdef sometime
68 /*
69 * file format is
70 * uid:name:lead:member,member,...\n
71 */
72 void
read_user(void)73 read_user(void)
74 {
75 int c;
76
77 if((c=fname(ustr))!=':' || (c=fname(name))!=':' || (c=fname(lead))!=':')
78 goto skipline;
79 n = atol(ustr);
80 if(n == 0)
81 goto skipline;
82 if(readu){
83 o -= strlen(name)+1;
84 if(o < 0) {
85 cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
86 return -1;
87 }
88 strcpy(uidspace+o, name);
89 uid[u].uid = n;
90 uid[u].offset = o;
91 u++;
92 if(u >= conf.nuid) {
93 cprint("conf.nuid(%ld) too small\n", conf.nuid);
94 goto initu;
95 }
96 }else{
97 o = strtouid1(name);
98 if(o == 0 && strcmp(name, "") != 0)
99 o = n;
100 for(c=0; c<u; c++)
101 if(uid[c].uid == n) {
102 uid[c].lead = o;
103 break;
104 }
105 while(((c=fname(name))==',' || c=='\n') && name[0]){
106 work here
107 if(c=='\n')
108 break;
109 }
110 }
111
112 skipline:
113 while(c != '\n')
114 fname(ustr);
115 }
116 #endif
117
118 /*
119 -1:adm:adm:
120 0:none:adm:
121 1:tor:tor:
122 10000:sys::
123 10001:map:map:
124 10002:doc::
125 10003:upas:upas:
126 10004:font::
127 10005:bootes:bootes:
128 */
129
130 struct {
131 int uid;
132 char *name;
133 int leader;
134 }
135 admusers[] = {
136 -1, "adm", -1,
137 0, "none", -1,
138 1, "tor", 1,
139 2, "glenda", 2,
140 10000, "sys", 0,
141 10001, "upas", 10001,
142 10002, "bootes", 10002,
143 0, 0, 0,
144 };
145
146
147 void
cmd_user(void)148 cmd_user(void)
149 {
150 int c, n, o, u, g, i;
151 char name[NAMELEN];
152
153 if(con_clone(FID1, FID2))
154 goto ainitu;
155 if(con_path(FID2, "/adm/users"))
156 goto ainitu;
157 if(con_open(FID2, 0)){
158 goto ainitu;
159 }
160
161 wlock(&uidgc.uidlock);
162 uidgc.uidbuf = malloc(MAXDAT);
163
164 memset(uid, 0, conf.nuid * sizeof(*uid));
165 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
166 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
167
168 uidgc.flen = 0;
169 uidgc.find = 0;
170 cons.offset = 0;
171 u = 0;
172 o = conf.uidspace;
173
174 ul1:
175 c = fname(name);
176 if(c != ':')
177 goto uskip;
178 n = atol(name);
179 if(n == 0)
180 goto uskip;
181 c = fname(name);
182 if(c != ':')
183 goto uskip;
184 o -= strlen(name)+1;
185 if(o < 0) {
186 cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
187 goto initu;
188 }
189 strcpy(uidspace+o, name);
190 uid[u].uid = n;
191 uid[u].offset = o;
192 u++;
193 if(u >= conf.nuid) {
194 cprint("conf.nuid(%ld) too small\n", conf.nuid);
195 goto initu;
196 }
197
198 uskip:
199 if(c == '\n')
200 goto ul1;
201 if(c) {
202 c = fname(name);
203 goto uskip;
204 }
205 /* cprint("%d uids read\n", u);/**/
206 qsort(uid, u, sizeof(uid[0]), byuid);
207 for(c=u-1; c>0; c--)
208 if(uid[c].uid == uid[c-1].uid) {
209 cprint("duplicate uids: %d\n", uid[c].uid);
210 cprint(" %s", uidspace+uid[c].offset);
211 cprint(" %s\n", uidspace+uid[c-1].offset);
212 }
213 qsort(uid, u, sizeof(uid[0]), byname);
214 for(c=u-1; c>0; c--)
215 if(!strcmp(uidspace+uid[c].offset,
216 uidspace+uid[c-1].offset)) {
217 cprint("kfs: duplicate names: %s\n", uidspace+uid[c].offset);
218 cprint(" %d", uid[c].uid);
219 cprint(" %d\n", uid[c-1].uid);
220 }
221 if(cons.flags & Fuid)
222 for(c=0; c<u; c++)
223 cprint("%6d %s\n", uid[c].uid, uidspace+uid[c].offset);
224
225 uidgc.flen = 0;
226 uidgc.find = 0;
227 cons.offset = 0;
228 g = 0;
229
230 gl1:
231 c = fname(name);
232 if(c != ':')
233 goto gskip;
234 n = atol(name); /* number */
235 if(n == 0)
236 goto gskip;
237 c = fname(name); /* name */
238 if(c != ':')
239 goto gskip;
240 c = fname(name); /* leader */
241 if(c != ':')
242 goto gskip;
243 o = strtouid1(name);
244 if(o == 0 && strcmp(name, "") != 0)
245 o = n;
246 for(c=0; c<u; c++)
247 if(uid[c].uid == n) {
248 uid[c].lead = o;
249 break;
250 }
251 c = fname(name); /* list of members */
252 if(c != ',' && c != '\n')
253 goto gskip;
254 if(!name[0])
255 goto gskip;
256 gidspace[g++] = n;
257 gl2:
258 n = strtouid1(name);
259 if(n)
260 gidspace[g++] = n;
261 if(g >= conf.gidspace-2) {
262 cprint("conf.gidspace(%ld) too small\n", conf.gidspace);
263 goto initu;
264 }
265 if(c == '\n')
266 goto gl3;
267 c = fname(name);
268 if(c == ',' || c == '\n')
269 goto gl2;
270 cprint("gid truncated\n");
271
272 gl3:
273 gidspace[g++] = 0;
274
275 gskip:
276 if(c == '\n')
277 goto gl1;
278 if(c) {
279 c = fname(name);
280 goto gskip;
281 }
282 if(cons.flags & Fuid) {
283 o = 0;
284 for(c=0; c<g; c++) {
285 n = gidspace[c];
286 if(n == 0) {
287 o = 0;
288 continue;
289 }
290 uidtostr1(name, n);
291 if(o) {
292 if(o > 6) {
293 cprint("\n %s", name);
294 o = 1;
295 } else
296 cprint(" %s", name);
297 } else
298 cprint("\n%6s", name);
299 o++;
300 }
301 cprint("\n");
302 }
303 goto out;
304
305 ainitu:
306 wlock(&uidgc.uidlock);
307 uidgc.uidbuf = malloc(MAXDAT);
308
309 initu:
310 cprint("initializing minimal user table\n");
311 memset(uid, 0, conf.nuid * sizeof(*uid));
312 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
313 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
314 o = conf.uidspace;
315 u = 0;
316
317 for(i=0; admusers[i].name; i++){
318 o -= strlen(admusers[i].name)+1;
319 strcpy(uidspace+o, admusers[i].name);
320 uid[u].uid = admusers[i].uid;
321 uid[u].lead = admusers[i].leader;
322 uid[u].offset = o;
323 u++;
324 }
325
326 out:
327 free(uidgc.uidbuf);
328 writegroup = strtouid1("write");
329 wunlock(&uidgc.uidlock);
330
331 }
332
333 void
uidtostr(char * name,int id)334 uidtostr(char *name, int id)
335 {
336 rlock(&uidgc.uidlock);
337 uidtostr1(name, id);
338 runlock(&uidgc.uidlock);
339 }
340
341 void
uidtostr1(char * name,int id)342 uidtostr1(char *name, int id)
343 {
344 Uid *u;
345 int i;
346
347 if(id == 0){
348 strncpy(name, "none", NAMELEN);
349 return;
350 }
351 for(i=0, u=uid; i<conf.nuid; i++,u++) {
352 if(u->uid == id) {
353 strncpy(name, uidspace+u->offset, NAMELEN);
354 return;
355 }
356 }
357 strncpy(name, "none", NAMELEN);
358 }
359
360 int
strtouid(char * s)361 strtouid(char *s)
362 {
363 int i;
364
365 rlock(&uidgc.uidlock);
366 i = strtouid1(s);
367 runlock(&uidgc.uidlock);
368 return i;
369 }
370
371 int
strtouid1(char * s)372 strtouid1(char *s)
373 {
374 Uid *u;
375 int i;
376
377 for(i=0, u=uid; i<conf.nuid; i++,u++)
378 if(!strcmp(s, uidspace+u->offset))
379 return u->uid;
380 return 0;
381 }
382
383 int
ingroup(int u,int g)384 ingroup(int u, int g)
385 {
386 short *p;
387
388 if(u == g)
389 return 1;
390 rlock(&uidgc.uidlock);
391 for(p=gidspace; *p;) {
392 if(*p != g) {
393 for(p++; *p++;)
394 ;
395 continue;
396 }
397 for(p++; *p; p++)
398 if(*p == u) {
399 runlock(&uidgc.uidlock);
400 return 1;
401 }
402 }
403 runlock(&uidgc.uidlock);
404 return 0;
405 }
406
407 int
leadgroup(int ui,int gi)408 leadgroup(int ui, int gi)
409 {
410 Uid *u;
411 int i;
412
413 rlock(&uidgc.uidlock);
414 for(i=0, u=uid; i<conf.nuid; i++,u++) {
415 if(u->uid == gi) {
416 i = u->lead;
417 runlock(&uidgc.uidlock);
418 if(i == ui)
419 return 1;
420 if(i == 0)
421 return ingroup(ui, gi);
422 return 0;
423 }
424 }
425 runlock(&uidgc.uidlock);
426 return 0;
427 }
428