0
|
1 /* aliasbr.c - new aliasing mechanism */
|
|
2 #ifndef lint
|
|
3 static char ident[] = "@(#)$Id$";
|
|
4 #endif /* lint */
|
|
5
|
|
6 #include "../h/mh.h"
|
|
7 #include "../h/aliasbr.h"
|
|
8 #ifdef BSD44
|
|
9 #include <sys/types.h>
|
|
10 #endif
|
|
11 #include <ctype.h>
|
|
12 #include <grp.h>
|
|
13 #include <pwd.h>
|
|
14 #include <stdio.h>
|
|
15
|
|
16 static int akvis;
|
|
17 static char *akerrst;
|
|
18
|
|
19 struct aka *akahead = NULL;
|
|
20 struct aka *akatail = NULL;
|
|
21
|
|
22 struct home *homehead = NULL;
|
|
23 struct home *hometail = NULL;
|
|
24
|
|
25 static char *scanp (), *getp (), *seekp (), *akval (), *getalias ();
|
|
26 static struct aka *akalloc ();
|
|
27 static struct home *hmalloc ();
|
|
28
|
|
29 static add_aka();
|
|
30 static int aleq(), addfile(), addgroup(), addmember(), addall();
|
|
31
|
|
32 #ifndef __STDC__
|
|
33 #ifdef SYS5
|
|
34 struct passwd *getpwent ();
|
|
35 struct group *getgrnam (), *getgrgid ();
|
|
36 #endif
|
|
37 #endif
|
|
38
|
|
39 /* */
|
|
40
|
|
41 char *akvalue (s)
|
|
42 register char *s;
|
|
43 {
|
|
44 register char *v;
|
|
45
|
|
46 if (akahead == NULL)
|
|
47 (void) alias (AliasFile);
|
|
48
|
|
49 akvis = -1;
|
|
50 v = akval (akahead, s);
|
|
51 if (akvis == -1)
|
|
52 akvis = 0;
|
|
53 return v;
|
|
54 }
|
|
55
|
|
56
|
|
57 int akvisible () {
|
|
58 return akvis;
|
|
59 }
|
|
60
|
|
61 /* */
|
|
62
|
|
63 char *akresult (ak)
|
|
64 register struct aka *ak;
|
|
65 {
|
|
66 register char *cp = NULL,
|
|
67 *dp,
|
|
68 *pp;
|
|
69 register struct adr *ad;
|
|
70
|
|
71 for (ad = ak -> ak_addr; ad; ad = ad -> ad_next) {
|
|
72 pp = ad -> ad_local ? akval (ak -> ak_next, ad -> ad_text)
|
|
73 : getcpy (ad -> ad_text);
|
|
74
|
|
75 if (dp = cp) {
|
|
76 cp = concat (cp, ",", pp, NULLCP);
|
|
77 free (dp);
|
|
78 free (pp);
|
|
79 }
|
|
80 else
|
|
81 cp = pp;
|
|
82 }
|
|
83
|
|
84 if (akvis == -1)
|
|
85 akvis = ak -> ak_visible;
|
|
86 #ifdef JAPAN
|
|
87 (void) ml_conv(cp);
|
|
88 #endif
|
|
89 return cp;
|
|
90 }
|
|
91
|
|
92
|
|
93 static char *akval (ak, s)
|
|
94 register struct aka *ak;
|
|
95 register char *s;
|
|
96 {
|
|
97 if (!s)
|
|
98 return s; /* XXX */
|
|
99
|
|
100 for (; ak; ak = ak -> ak_next)
|
|
101 if (aleq (s, ak -> ak_name))
|
|
102 return akresult (ak);
|
|
103
|
|
104 return getcpy (s);
|
|
105 }
|
|
106
|
|
107
|
|
108 static int aleq (string, aliasent)
|
|
109 register char *string,
|
|
110 *aliasent;
|
|
111 {
|
|
112 register char c;
|
|
113
|
|
114 while (c = *string++)
|
|
115 if (*aliasent == '*')
|
|
116 return 1;
|
|
117 else
|
|
118 if ((c | 040) != (*aliasent | 040))
|
|
119 return 0;
|
|
120 else
|
|
121 aliasent++;
|
|
122
|
|
123 return (*aliasent == 0 || *aliasent == '*');
|
|
124 }
|
|
125
|
|
126 /* */
|
|
127
|
|
128 int alias (file)
|
|
129 register char *file;
|
|
130 {
|
|
131 int i;
|
|
132 register char *bp,
|
|
133 *cp,
|
|
134 *pp;
|
|
135 char lc,
|
|
136 *ap;
|
|
137 register struct aka *ak = NULL;
|
|
138 register FILE *fp;
|
|
139
|
|
140 if (*file != '/'
|
|
141 && (strncmp (file, "./", 2) && strncmp (file, "../", 3)))
|
|
142 file = libpath (file);
|
|
143 if ((fp = fopen (file, "r")) == NULL) {
|
|
144 akerrst = file;
|
|
145 return AK_NOFILE;
|
|
146 }
|
|
147
|
|
148 while (vfgets (fp, &ap) == OK) {
|
|
149 bp = ap;
|
|
150 switch (*(pp = scanp (bp))) {
|
|
151 case '<': /* recurse a level */
|
|
152 if (!*(cp = getp (pp + 1))) {
|
|
153 akerrst = "'<' without alias-file";
|
|
154 (void) fclose (fp);
|
|
155 return AK_ERROR;
|
|
156 }
|
|
157 if ((i = alias (cp)) != AK_OK) {
|
|
158 (void) fclose (fp);
|
|
159 return i;
|
|
160 }
|
|
161
|
|
162 case ':': /* comment */
|
|
163 case ';':
|
|
164 case '#':
|
|
165 case 0:
|
|
166 continue;
|
|
167 }
|
|
168
|
|
169 akerrst = bp;
|
|
170 if (!*(cp = seekp (pp, &lc, &ap))) {
|
|
171 (void) fclose (fp);
|
|
172 return AK_ERROR;
|
|
173 }
|
|
174 if (!(ak = akalloc (cp))) {
|
|
175 (void) fclose (fp);
|
|
176 return AK_LIMIT;
|
|
177 }
|
|
178 switch (lc) {
|
|
179 case ':':
|
|
180 ak -> ak_visible = 0;
|
|
181 break;
|
|
182
|
|
183 case ';':
|
|
184 ak -> ak_visible = 1;
|
|
185 break;
|
|
186
|
|
187 default:
|
|
188 (void) fclose (fp);
|
|
189 return AK_ERROR;
|
|
190 }
|
|
191
|
|
192 switch (*(pp = scanp (ap))) {
|
|
193 case 0: /* EOL */
|
|
194 (void) fclose (fp);
|
|
195 return AK_ERROR;
|
|
196
|
|
197 case '<': /* read values from file */
|
|
198 if (!*(cp = getp (pp + 1))) {
|
|
199 (void) fclose (fp);
|
|
200 return AK_ERROR;
|
|
201 }
|
|
202 if (!addfile (ak, cp)) {
|
|
203 (void) fclose (fp);
|
|
204 return AK_NOFILE;
|
|
205 }
|
|
206 break;
|
|
207
|
|
208 case '=': /* UNIX group */
|
|
209 if (!*(cp = getp (pp + 1))) {
|
|
210 (void) fclose (fp);
|
|
211 return AK_ERROR;
|
|
212 }
|
|
213 if (!addgroup (ak, cp)) {
|
|
214 (void) fclose (fp);
|
|
215 return AK_NOGROUP;
|
|
216 }
|
|
217 break;
|
|
218
|
|
219 case '+': /* UNIX group members */
|
|
220 if (!*(cp = getp (pp + 1))) {
|
|
221 (void) fclose (fp);
|
|
222 return AK_ERROR;
|
|
223 }
|
|
224 if (!addmember (ak, cp)) {
|
|
225 (void) fclose (fp);
|
|
226 return AK_NOGROUP;
|
|
227 }
|
|
228 break;
|
|
229
|
|
230 case '*': /* Everyone */
|
|
231 (void) addall (ak);
|
|
232 break;
|
|
233
|
|
234 default: /* list */
|
|
235 while (cp = getalias (pp))
|
|
236 add_aka (ak, cp);
|
|
237 break;
|
|
238 }
|
|
239 }
|
|
240
|
|
241 (void) fclose (fp);
|
|
242 return AK_OK;
|
|
243 }
|
|
244
|
|
245 /* */
|
|
246
|
|
247 char *akerror (i)
|
|
248 int i;
|
|
249 {
|
|
250 static char buffer[BUFSIZ];
|
|
251
|
|
252 switch (i) {
|
|
253 case AK_NOFILE:
|
|
254 (void) sprintf (buffer, "unable to read '%s'", akerrst);
|
|
255 break;
|
|
256
|
|
257 case AK_ERROR:
|
|
258 (void) sprintf (buffer, "error in line '%s'", akerrst);
|
|
259 break;
|
|
260
|
|
261 case AK_LIMIT:
|
|
262 (void) sprintf (buffer, "out of memory while on '%s'", akerrst);
|
|
263 break;
|
|
264
|
|
265 case AK_NOGROUP:
|
|
266 (void) sprintf (buffer, "no such group as '%s'", akerrst);
|
|
267 break;
|
|
268
|
|
269 default:
|
|
270 (void) sprintf (buffer, "unknown error (%d)", i);
|
|
271 break;
|
|
272 }
|
|
273
|
|
274 return buffer;
|
|
275 }
|
|
276
|
|
277 /* */
|
|
278
|
|
279 static char *scanp (p)
|
|
280 register char *p;
|
|
281 {
|
|
282 while (isspace (*p))
|
|
283 p++;
|
|
284 return p;
|
|
285 }
|
|
286
|
|
287
|
|
288 static char *getp (p)
|
|
289 register char *p;
|
|
290 {
|
|
291 register char *cp = scanp (p);
|
|
292
|
|
293 p = cp;
|
|
294 while (!isspace (*cp) && *cp)
|
|
295 cp++;
|
|
296 *cp = 0;
|
|
297
|
|
298 return p;
|
|
299 }
|
|
300
|
|
301
|
|
302 static char *seekp (p, c, a)
|
|
303 register char *p,
|
|
304 *c,
|
|
305 **a;
|
|
306 {
|
|
307 register char *cp = scanp (p);
|
|
308
|
|
309 p = cp;
|
|
310 while (!isspace (*cp) && *cp && *cp != ':' && *cp != ';')
|
|
311 cp++;
|
|
312 *c = *cp;
|
|
313 *cp++ = 0;
|
|
314 *a = cp;
|
|
315
|
|
316 return p;
|
|
317 }
|
|
318
|
|
319 /* */
|
|
320
|
|
321 static int addfile (ak, file)
|
|
322 register struct aka *ak;
|
|
323 register char *file;
|
|
324 {
|
|
325 register char *cp;
|
|
326 char buffer[BUFSIZ];
|
|
327 register FILE *fp;
|
|
328
|
|
329 if ((fp = fopen (libpath (file), "r")) == NULL) {
|
|
330 akerrst = file;
|
|
331 return 0;
|
|
332 }
|
|
333
|
|
334 while (fgets (buffer, sizeof buffer, fp) != NULL)
|
|
335 while (cp = getalias (buffer))
|
|
336 add_aka (ak, cp);
|
|
337
|
|
338 (void) fclose (fp);
|
|
339 return 1;
|
|
340 }
|
|
341
|
|
342 /* */
|
|
343
|
|
344 static int addgroup (ak, grp)
|
|
345 register struct aka *ak;
|
|
346 register char *grp;
|
|
347 {
|
|
348 register char *gp;
|
|
349 register struct group *gr = getgrnam (grp);
|
|
350 register struct home *hm = NULL;
|
|
351
|
|
352 if (!gr)
|
|
353 gr = getgrgid (atoi (grp));
|
|
354 if (!gr) {
|
|
355 akerrst = grp;
|
|
356 return 0;
|
|
357 }
|
|
358
|
|
359 #ifndef DBMPWD
|
|
360 if (homehead == NULL)
|
|
361 init_pw ();
|
|
362 #endif /* DBMPWD */
|
|
363
|
|
364 while (gp = *gr -> gr_mem++)
|
|
365 #ifdef DBMPWD
|
|
366 {
|
|
367 struct passwd *pw;
|
|
368 #endif /* DBMPWD */
|
|
369 for (hm = homehead; hm; hm = hm -> h_next)
|
|
370 if (!strcmp (hm -> h_name, gp)) {
|
|
371 add_aka (ak, hm -> h_name);
|
|
372 break;
|
|
373 }
|
|
374 #ifdef DBMPWD
|
|
375 if (pw = getpwnam(gp))
|
|
376 {
|
|
377 hmalloc(pw);
|
|
378 add_aka (ak, gp);
|
|
379 }
|
|
380 }
|
|
381 #endif /* DBMPWD */
|
|
382
|
|
383 return 1;
|
|
384 }
|
|
385
|
|
386 /* */
|
|
387
|
|
388 static int addmember (ak, grp)
|
|
389 register struct aka *ak;
|
|
390 register char *grp;
|
|
391 {
|
|
392 int gid;
|
|
393 register struct group *gr = getgrnam (grp);
|
|
394 register struct home *hm = NULL;
|
|
395
|
|
396 if (gr)
|
|
397 gid = gr -> gr_gid;
|
|
398 else {
|
|
399 gid = atoi (grp);
|
|
400 gr = getgrgid (gid);
|
|
401 }
|
|
402 if (!gr) {
|
|
403 akerrst = grp;
|
|
404 return 0;
|
|
405 }
|
|
406
|
|
407 #ifndef DBMPWD
|
|
408 if (homehead == NULL)
|
|
409 #endif /* DBMPWD */
|
|
410 init_pw ();
|
|
411
|
|
412 for (hm = homehead; hm; hm = hm -> h_next)
|
|
413 if (hm -> h_gid == gid)
|
|
414 add_aka (ak, hm -> h_name);
|
|
415
|
|
416 return 1;
|
|
417 }
|
|
418
|
|
419 /* */
|
|
420
|
|
421 static int addall (ak)
|
|
422 register struct aka *ak;
|
|
423 {
|
|
424 int noshell = NoShell == NULLCP || *NoShell == 0;
|
|
425 register struct home *hm;
|
|
426
|
|
427 #ifndef DBMPWD
|
|
428 if (homehead == NULL)
|
|
429 #endif /* DBMPWD */
|
|
430 init_pw ();
|
|
431 if (Everyone < 0)
|
|
432 Everyone = EVERYONE;
|
|
433
|
|
434 for (hm = homehead; hm; hm = hm -> h_next)
|
|
435 if (hm -> h_uid > Everyone
|
|
436 && (noshell || strcmp (hm -> h_shell, NoShell)))
|
|
437 add_aka (ak, hm -> h_name);
|
|
438
|
|
439 return homehead != NULL;
|
|
440 }
|
|
441
|
|
442 /* */
|
|
443
|
|
444 static char *getalias (addrs)
|
|
445 register char *addrs;
|
|
446 {
|
|
447 register char *pp,
|
|
448 *qp;
|
|
449 static char *cp = NULL;
|
|
450
|
|
451 if (cp == NULL)
|
|
452 cp = addrs;
|
|
453 else
|
|
454 if (*cp == 0)
|
|
455 return (cp = NULL);
|
|
456
|
|
457 for (pp = cp; isspace (*pp); pp++)
|
|
458 continue;
|
|
459 if (*pp == 0)
|
|
460 return (cp = NULL);
|
|
461 for (qp = pp; *qp != 0 && *qp != ','; qp++)
|
|
462 continue;
|
|
463 if (*qp == ',')
|
|
464 *qp++ = 0;
|
|
465 for (cp = qp, qp--; qp > pp; qp--)
|
|
466 if (*qp != 0)
|
|
467 if (isspace (*qp))
|
|
468 *qp = 0;
|
|
469 else
|
|
470 break;
|
|
471
|
|
472 return pp;
|
|
473 }
|
|
474
|
|
475 /* */
|
|
476
|
|
477 static add_aka (ak, pp)
|
|
478 register struct aka *ak;
|
|
479 register char *pp;
|
|
480 {
|
|
481 register struct adr *ad,
|
|
482 *ld;
|
|
483
|
|
484 for (ad = ak -> ak_addr, ld = NULL; ad; ld = ad, ad = ad -> ad_next)
|
|
485 if (!strcmp (pp, ad -> ad_text))
|
|
486 return;
|
|
487
|
|
488 ad = (struct adr *) malloc (sizeof *ad);
|
|
489 if (ad == NULL)
|
|
490 return;
|
|
491 ad -> ad_text = getcpy (pp);
|
|
492 ad -> ad_local = index (pp, '@') == NULL && index (pp, '!') == NULL;
|
|
493 ad -> ad_next = NULL;
|
|
494 if (ak -> ak_addr)
|
|
495 ld -> ad_next = ad;
|
|
496 else
|
|
497 ak -> ak_addr = ad;
|
|
498 }
|
|
499
|
|
500
|
|
501 init_pw () {
|
|
502 register struct passwd *pw;
|
|
503 #ifdef DBMPWD
|
|
504 static int init;
|
|
505
|
|
506 if (!init)
|
|
507 {
|
|
508 /* if the list has yet to be initialized */
|
|
509 /* zap the list, and rebuild from scratch */
|
|
510 homehead=NULL;
|
|
511 hometail=NULL;
|
|
512 init++;
|
|
513 #endif /* DBMPWD */
|
|
514
|
|
515 (void) setpwent ();
|
|
516
|
|
517 while (pw = getpwent ())
|
|
518 if (!hmalloc (pw))
|
|
519 break;
|
|
520
|
|
521 (void) endpwent ();
|
|
522 #ifdef DBMPWD
|
|
523 }
|
|
524 #endif /* DBMPWD */
|
|
525 }
|
|
526
|
|
527 /* */
|
|
528
|
|
529 static struct aka *akalloc (id)
|
|
530 register char *id;
|
|
531 {
|
|
532 register struct aka *p = (struct aka *) malloc (sizeof *p);
|
|
533
|
|
534 if (!p)
|
|
535 return NULL;
|
|
536
|
|
537 p -> ak_name = getcpy (id);
|
|
538 p -> ak_visible = 0;
|
|
539 p -> ak_addr = NULL;
|
|
540 p -> ak_next = NULL;
|
|
541 if (akatail != NULL)
|
|
542 akatail -> ak_next = p;
|
|
543 if (akahead == NULL)
|
|
544 akahead = p;
|
|
545 akatail = p;
|
|
546
|
|
547 return p;
|
|
548 }
|
|
549
|
|
550
|
|
551 static struct home *hmalloc (pw)
|
|
552 struct passwd *pw;
|
|
553 {
|
|
554 register struct home *p = (struct home *) malloc (sizeof *p);
|
|
555
|
|
556 if (!p)
|
|
557 return NULL;
|
|
558
|
|
559 p -> h_name = getcpy (pw -> pw_name);
|
|
560 p -> h_uid = pw -> pw_uid;
|
|
561 p -> h_gid = pw -> pw_gid;
|
|
562 p -> h_home = getcpy (pw -> pw_dir);
|
|
563 p -> h_shell = getcpy (pw -> pw_shell);
|
|
564 #if defined(BSD42) || defined(SVR4)
|
|
565 p -> h_ngrps = 0;
|
|
566 #endif /* BSD42 || SVR4 */
|
|
567 p -> h_next = NULL;
|
|
568 if (hometail != NULL)
|
|
569 hometail -> h_next = p;
|
|
570 if (homehead == NULL)
|
|
571 homehead = p;
|
|
572 hometail = p;
|
|
573
|
|
574 return p;
|
|
575 }
|
|
576
|
|
577 /* */
|
|
578
|
|
579 #ifndef MMDFMTS
|
|
580 struct home *seek_home (name)
|
|
581 register char *name;
|
|
582 {
|
|
583 register struct home *hp;
|
|
584 #ifdef DBMPWD
|
|
585 struct passwd *pw;
|
|
586 char lname[32];
|
|
587 char *c,*c1;
|
|
588 #else /* DBMPWD */
|
|
589
|
|
590 if (homehead == NULL)
|
|
591 init_pw ();
|
|
592 #endif /* DBMPWD */
|
|
593
|
|
594 for (hp = homehead; hp; hp = hp -> h_next)
|
|
595 if (uleq (name, hp -> h_name))
|
|
596 return hp;
|
|
597
|
|
598 #ifdef DBMPWD /* The only place where there might be problems */
|
|
599 /* This assumes that ALL usernames are kept in lowercase */
|
|
600 for (c = name,c1 = lname; *c; c++, c1++)
|
|
601 if (isalpha(*c) && isupper(*c))
|
|
602 *c1 = tolower(*c);
|
|
603 else
|
|
604 *c1 = *c;
|
|
605 *c1 = '\0';
|
|
606 if (pw = getpwnam(lname))
|
|
607 return(hmalloc(pw));
|
|
608 #endif /* DBMPWD */
|
|
609
|
|
610 return NULL;
|
|
611 }
|
|
612 #endif /* MMDFMTS */
|