Deleted Added
full compact
map.c (43730) map.c (64562)
1/*
1/*
2 * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
2 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
3 * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved.
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 */
12
13#ifndef lint
4 * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#ifndef lint
14static char sccsid[] = "@(#)map.c 8.261 (Berkeley) 2/2/1999";
15#endif /* not lint */
15static char id[] = "@(#)$Id: map.c,v 8.414.4.13 2000/07/14 16:48:21 ca Exp $";
16#endif /* ! lint */
16
17
17#include "sendmail.h"
18#include <sendmail.h>
18
19
20
19#ifdef NDBM
20# include <ndbm.h>
21# ifdef R_FIRST
22 ERROR README: You are running the Berkeley DB version of ndbm.h. See
23 ERROR README: the README file about tweaking Berkeley DB so it can
24 ERROR README: coexist with NDBM, or delete -DNDBM from the Makefile
25 ERROR README: and use -DNEWDB instead.
21#ifdef NDBM
22# include <ndbm.h>
23# ifdef R_FIRST
24 ERROR README: You are running the Berkeley DB version of ndbm.h. See
25 ERROR README: the README file about tweaking Berkeley DB so it can
26 ERROR README: coexist with NDBM, or delete -DNDBM from the Makefile
27 ERROR README: and use -DNEWDB instead.
26# endif
27#endif
28# endif /* R_FIRST */
29#endif /* NDBM */
28#ifdef NEWDB
29# include <db.h>
30# ifndef DB_VERSION_MAJOR
31# define DB_VERSION_MAJOR 1
30#ifdef NEWDB
31# include <db.h>
32# ifndef DB_VERSION_MAJOR
33# define DB_VERSION_MAJOR 1
32# endif
33#endif
34# endif /* ! DB_VERSION_MAJOR */
35#endif /* NEWDB */
34#ifdef NIS
35 struct dom_binding; /* forward reference needed on IRIX */
36# include <rpcsvc/ypclnt.h>
37# ifdef NDBM
38# define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
36#ifdef NIS
37 struct dom_binding; /* forward reference needed on IRIX */
38# include <rpcsvc/ypclnt.h>
39# ifdef NDBM
40# define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
39# endif
40#endif
41# endif /* NDBM */
42#endif /* NIS */
41
43
44#ifdef NEWDB
45# if DB_VERSION_MAJOR < 2
46static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
47# endif /* DB_VERSION_MAJOR < 2 */
48# if DB_VERSION_MAJOR == 2
49static bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *));
50# endif /* DB_VERSION_MAJOR == 2 */
51# if DB_VERSION_MAJOR > 2
52static bool db_map_open __P((MAP *, int, char *, DBTYPE, void **));
53# endif /* DB_VERSION_MAJOR > 2 */
54#endif /* NEWDB */
55static bool extract_canonname __P((char *, char *, char[], int));
56#ifdef LDAPMAP
57static void ldapmap_clear __P((LDAPMAP_STRUCT *));
58static STAB *ldapmap_findconn __P((LDAPMAP_STRUCT *));
59static int ldapmap_geterrno __P((LDAP *));
60static void ldapmap_setopts __P((LDAP *, LDAPMAP_STRUCT *));
61static bool ldapmap_start __P((MAP *));
62static void ldaptimeout __P((int));
63#endif /* LDAPMAP */
64static void map_close __P((STAB *, int));
65static void map_init __P((STAB *, int));
66#ifdef NISPLUS
67static bool nisplus_getcanonname __P((char *, int, int *));
68#endif /* NISPLUS */
69#ifdef NIS
70static bool nis_getcanonname __P((char *, int, int *));
71#endif /* NIS */
72#if NETINFO
73static bool ni_getcanonname __P((char *, int, int *));
74#endif /* NETINFO */
75static bool text_getcanonname __P((char *, int, int *));
76
42/*
43** MAP.C -- implementations for various map classes.
44**
45** Each map class implements a series of functions:
46**
47** bool map_parse(MAP *map, char *args)
48** Parse the arguments from the config file. Return TRUE
49** if they were ok, FALSE otherwise. Fill in map with the

--- 28 unchanged lines hidden (view full) ---

78** It is currently implemented in a pretty ad-hoc manner; it ought
79** to be more properly integrated into the map structure.
80*/
81
82#define DBMMODE 0644
83
84#ifndef EX_NOTFOUND
85# define EX_NOTFOUND EX_NOHOST
77/*
78** MAP.C -- implementations for various map classes.
79**
80** Each map class implements a series of functions:
81**
82** bool map_parse(MAP *map, char *args)
83** Parse the arguments from the config file. Return TRUE
84** if they were ok, FALSE otherwise. Fill in map with the

--- 28 unchanged lines hidden (view full) ---

113** It is currently implemented in a pretty ad-hoc manner; it ought
114** to be more properly integrated into the map structure.
115*/
116
117#define DBMMODE 0644
118
119#ifndef EX_NOTFOUND
120# define EX_NOTFOUND EX_NOHOST
86#endif
121#endif /* ! EX_NOTFOUND */
87
122
88extern bool aliaswait __P((MAP *, char *, int));
89extern bool extract_canonname __P((char *, char *, char[], int));
90
91#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
92# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
123#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
124# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
93#else
125#else /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
94# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
126# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
95#endif
127#endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
96
97#ifndef O_ACCMODE
98# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
128
129#ifndef O_ACCMODE
130# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
99#endif
131#endif /* ! O_ACCMODE */
100 /*
101** MAP_PARSEARGS -- parse config line arguments for database lookup
102**
103** This is a generic version of the map_parse method.
104**
105** Parameters:
106** map -- the map being initialized.
107** ap -- a pointer to the args on the config line.

--- 8 unchanged lines hidden (view full) ---

116
117bool
118map_parseargs(map, ap)
119 MAP *map;
120 char *ap;
121{
122 register char *p = ap;
123
132 /*
133** MAP_PARSEARGS -- parse config line arguments for database lookup
134**
135** This is a generic version of the map_parse method.
136**
137** Parameters:
138** map -- the map being initialized.
139** ap -- a pointer to the args on the config line.

--- 8 unchanged lines hidden (view full) ---

148
149bool
150map_parseargs(map, ap)
151 MAP *map;
152 char *ap;
153{
154 register char *p = ap;
155
156 /*
157 ** there is no check whether there is really an argument,
158 ** but that's not important enough to warrant extra code
159 */
124 map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
160 map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
161 map->map_spacesub = SpaceSub; /* default value */
125 for (;;)
126 {
127 while (isascii(*p) && isspace(*p))
128 p++;
129 if (*p != '-')
130 break;
131 switch (*++p)
132 {

--- 66 unchanged lines hidden (view full) ---

199 }
200 }
201 break;
202
203 case 't':
204 map->map_mflags |= MF_NODEFER;
205 break;
206
162 for (;;)
163 {
164 while (isascii(*p) && isspace(*p))
165 p++;
166 if (*p != '-')
167 break;
168 switch (*++p)
169 {

--- 66 unchanged lines hidden (view full) ---

236 }
237 }
238 break;
239
240 case 't':
241 map->map_mflags |= MF_NODEFER;
242 break;
243
207#ifdef RESERVED_FOR_SUN
208 case 'd':
209 map->map_mflags |= MF_DOMAIN_WIDE;
244
245 case 'S':
246 map->map_spacesub = *++p;
210 break;
211
247 break;
248
212 case 's':
213 /* info type */
249 case 'D':
250 map->map_mflags |= MF_DEFER;
214 break;
251 break;
215#endif
252
253 default:
254 syserr("Illegal option %c map %s", *p, map->map_mname);
255 break;
216 }
217 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
218 p++;
219 if (*p != '\0')
220 *p++ = '\0';
221 }
222 if (map->map_app != NULL)
223 map->map_app = newstr(map->map_app);

--- 61 unchanged lines hidden (view full) ---

285 register char *ap;
286 size_t l;
287 size_t len;
288 static size_t buflen = 0;
289 static char *buf = NULL;
290
291 if (tTd(39, 1))
292 {
256 }
257 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
258 p++;
259 if (*p != '\0')
260 *p++ = '\0';
261 }
262 if (map->map_app != NULL)
263 map->map_app = newstr(map->map_app);

--- 61 unchanged lines hidden (view full) ---

325 register char *ap;
326 size_t l;
327 size_t len;
328 static size_t buflen = 0;
329 static char *buf = NULL;
330
331 if (tTd(39, 1))
332 {
293 printf("map_rewrite(%.*s), av =", (int)slen, s);
333 dprintf("map_rewrite(%.*s), av =", (int)slen, s);
294 if (av == NULL)
334 if (av == NULL)
295 printf(" (nullv)");
335 dprintf(" (nullv)");
296 else
297 {
298 for (avp = av; *avp != NULL; avp++)
336 else
337 {
338 for (avp = av; *avp != NULL; avp++)
299 printf("\n\t%s", *avp);
339 dprintf("\n\t%s", *avp);
300 }
340 }
301 printf("\n");
341 dprintf("\n");
302 }
303
304 /* count expected size of output (can safely overestimate) */
305 l = len = slen;
306 if (av != NULL)
307 {
308 const char *sp = s;
309

--- 22 unchanged lines hidden (view full) ---

332 if (buf != NULL)
333 free(buf);
334 buf = xalloc(buflen);
335 }
336
337 bp = buf;
338 if (av == NULL)
339 {
342 }
343
344 /* count expected size of output (can safely overestimate) */
345 l = len = slen;
346 if (av != NULL)
347 {
348 const char *sp = s;
349

--- 22 unchanged lines hidden (view full) ---

372 if (buf != NULL)
373 free(buf);
374 buf = xalloc(buflen);
375 }
376
377 bp = buf;
378 if (av == NULL)
379 {
340 bcopy(s, bp, slen);
380 memmove(bp, s, slen);
341 bp += slen;
381 bp += slen;
382
383 /* assert(len > slen); */
384 len -= slen;
342 }
343 else
344 {
345 while (slen-- > 0 && (c = *s++) != '\0')
346 {
347 if (c != '%')
348 {
349 pushc:
385 }
386 else
387 {
388 while (slen-- > 0 && (c = *s++) != '\0')
389 {
390 if (c != '%')
391 {
392 pushc:
393 if (--len <= 0)
394 break;
350 *bp++ = c;
351 continue;
352 }
353 if (slen-- <= 0 || (c = *s++) == '\0')
354 c = '%';
355 if (c == '%')
356 goto pushc;
357 if (!(isascii(c) && isdigit(c)))
358 {
359 *bp++ = '%';
395 *bp++ = c;
396 continue;
397 }
398 if (slen-- <= 0 || (c = *s++) == '\0')
399 c = '%';
400 if (c == '%')
401 goto pushc;
402 if (!(isascii(c) && isdigit(c)))
403 {
404 *bp++ = '%';
405 --len;
360 goto pushc;
361 }
362 for (avp = av; --c >= '0' && *avp != NULL; avp++)
363 continue;
364 if (*avp == NULL)
365 continue;
366
367 /* transliterate argument into output string */
406 goto pushc;
407 }
408 for (avp = av; --c >= '0' && *avp != NULL; avp++)
409 continue;
410 if (*avp == NULL)
411 continue;
412
413 /* transliterate argument into output string */
368 for (ap = *avp; (c = *ap++) != '\0'; )
414 for (ap = *avp; (c = *ap++) != '\0' && len > 0; --len)
369 *bp++ = c;
370 }
371 }
415 *bp++ = c;
416 }
417 }
372 if (map->map_app != NULL)
373 strcpy(bp, map->map_app);
418 if (map->map_app != NULL && len > 0)
419 (void) strlcpy(bp, map->map_app, len);
374 else
375 *bp = '\0';
376 if (tTd(39, 1))
420 else
421 *bp = '\0';
422 if (tTd(39, 1))
377 printf("map_rewrite => %s\n", buf);
423 dprintf("map_rewrite => %s\n", buf);
378 return buf;
379}
380 /*
424 return buf;
425}
426 /*
381** INITMAPS -- initialize for aliasing
427** INITMAPS -- rebuild alias maps
382**
383** Parameters:
428**
429** Parameters:
384** rebuild -- if TRUE, this rebuilds the cached versions.
385** e -- current envelope.
430** none.
386**
387** Returns:
388** none.
431**
432** Returns:
433** none.
389**
390** Side Effects:
391** initializes aliases:
392** if alias database: opens the database.
393** if no database available: reads aliases into the symbol table.
394*/
395
396void
434*/
435
436void
397initmaps(rebuild, e)
398 bool rebuild;
399 register ENVELOPE *e;
437initmaps()
400{
438{
401 extern void map_init __P((STAB *, int));
402
403#if XDEBUG
404 checkfd012("entering initmaps");
439#if XDEBUG
440 checkfd012("entering initmaps");
405#endif
406 CurEnv = e;
407
441#endif /* XDEBUG */
408 stabapply(map_init, 0);
442 stabapply(map_init, 0);
409 stabapply(map_init, rebuild ? 2 : 1);
410#if XDEBUG
411 checkfd012("exiting initmaps");
443#if XDEBUG
444 checkfd012("exiting initmaps");
412#endif
445#endif /* XDEBUG */
413}
446}
447 /*
448** MAP_INIT -- rebuild a map
449**
450** Parameters:
451** s -- STAB entry: if map: try to rebuild
452** unused -- unused variable
453**
454** Returns:
455** none.
456**
457** Side Effects:
458** will close already open rebuildable map.
459*/
414
460
415void
416map_init(s, pass)
461/* ARGSUSED1 */
462static void
463map_init(s, unused)
417 register STAB *s;
464 register STAB *s;
418 int pass;
465 int unused;
419{
466{
420 bool rebuildable;
421 register MAP *map;
422
423 /* has to be a map */
424 if (s->s_type != ST_MAP)
425 return;
426
427 map = &s->s_map;
428 if (!bitset(MF_VALID, map->map_mflags))
429 return;
430
431 if (tTd(38, 2))
467 register MAP *map;
468
469 /* has to be a map */
470 if (s->s_type != ST_MAP)
471 return;
472
473 map = &s->s_map;
474 if (!bitset(MF_VALID, map->map_mflags))
475 return;
476
477 if (tTd(38, 2))
432 printf("map_init(%s:%s, %s, %d)\n",
478 dprintf("map_init(%s:%s, %s)\n",
433 map->map_class->map_cname == NULL ? "NULL" :
434 map->map_class->map_cname,
435 map->map_mname == NULL ? "NULL" : map->map_mname,
479 map->map_class->map_cname == NULL ? "NULL" :
480 map->map_class->map_cname,
481 map->map_mname == NULL ? "NULL" : map->map_mname,
436 map->map_file == NULL ? "NULL" : map->map_file,
437 pass);
482 map->map_file == NULL ? "NULL" : map->map_file);
438
483
439 /*
440 ** Pass 0 opens all non-rebuildable maps.
441 ** Pass 1 opens all rebuildable maps for read.
442 ** Pass 2 rebuilds all rebuildable maps.
443 */
444
445 rebuildable = (bitset(MF_ALIAS, map->map_mflags) &&
446 bitset(MCF_REBUILDABLE, map->map_class->map_cflags));
447
448 if ((pass == 0 && rebuildable) ||
449 ((pass == 1 || pass == 2) && !rebuildable))
484 if (!bitset(MF_ALIAS, map->map_mflags) ||
485 !bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
450 {
451 if (tTd(38, 3))
486 {
487 if (tTd(38, 3))
452 printf("\twrong pass (pass = %d, rebuildable = %d)\n",
453 pass, rebuildable);
488 dprintf("\tnot rebuildable\n");
454 return;
455 }
456
457 /* if already open, close it (for nested open) */
458 if (bitset(MF_OPEN, map->map_mflags))
459 {
460 map->map_class->map_close(map);
461 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
462 }
463
489 return;
490 }
491
492 /* if already open, close it (for nested open) */
493 if (bitset(MF_OPEN, map->map_mflags))
494 {
495 map->map_class->map_close(map);
496 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
497 }
498
464 if (pass == 2)
499 (void) rebuildaliases(map, FALSE);
500 return;
501}
502 /*
503** OPENMAP -- open a map
504**
505** Parameters:
506** map -- map to open (it must not be open).
507**
508** Returns:
509** whether open succeeded.
510**
511*/
512
513bool
514openmap(map)
515 MAP *map;
516{
517 bool restore = FALSE;
518 bool savehold = HoldErrs;
519 bool savequick = QuickAbort;
520 int saveerrors = Errors;
521
522 if (!bitset(MF_VALID, map->map_mflags))
523 return FALSE;
524
525 /* better safe than sorry... */
526 if (bitset(MF_OPEN, map->map_mflags))
527 return TRUE;
528
529 /* Don't send a map open error out via SMTP */
530 if ((OnlyOneError || QuickAbort) &&
531 (OpMode == MD_SMTP || OpMode == MD_DAEMON))
465 {
532 {
466 (void) rebuildaliases(map, FALSE);
467 return;
533 restore = TRUE;
534 HoldErrs = TRUE;
535 QuickAbort = FALSE;
468 }
469
536 }
537
538 errno = 0;
470 if (map->map_class->map_open(map, O_RDONLY))
471 {
472 if (tTd(38, 4))
539 if (map->map_class->map_open(map, O_RDONLY))
540 {
541 if (tTd(38, 4))
473 printf("\t%s:%s %s: valid\n",
542 dprintf("openmap()\t%s:%s %s: valid\n",
474 map->map_class->map_cname == NULL ? "NULL" :
475 map->map_class->map_cname,
476 map->map_mname == NULL ? "NULL" :
477 map->map_mname,
478 map->map_file == NULL ? "NULL" :
479 map->map_file);
480 map->map_mflags |= MF_OPEN;
481 map->map_pid = getpid();
482 }
483 else
484 {
485 if (tTd(38, 4))
543 map->map_class->map_cname == NULL ? "NULL" :
544 map->map_class->map_cname,
545 map->map_mname == NULL ? "NULL" :
546 map->map_mname,
547 map->map_file == NULL ? "NULL" :
548 map->map_file);
549 map->map_mflags |= MF_OPEN;
550 map->map_pid = getpid();
551 }
552 else
553 {
554 if (tTd(38, 4))
486 printf("\t%s:%s %s: invalid: %s\n",
555 dprintf("openmap()\t%s:%s %s: invalid%s%s\n",
487 map->map_class->map_cname == NULL ? "NULL" :
488 map->map_class->map_cname,
489 map->map_mname == NULL ? "NULL" :
490 map->map_mname,
491 map->map_file == NULL ? "NULL" :
492 map->map_file,
556 map->map_class->map_cname == NULL ? "NULL" :
557 map->map_class->map_cname,
558 map->map_mname == NULL ? "NULL" :
559 map->map_mname,
560 map->map_file == NULL ? "NULL" :
561 map->map_file,
493 errstring(errno));
562 errno == 0 ? "" : ": ",
563 errno == 0 ? "" : errstring(errno));
494 if (!bitset(MF_OPTIONAL, map->map_mflags))
495 {
496 extern MAPCLASS BogusMapClass;
497
498 map->map_class = &BogusMapClass;
499 map->map_mflags |= MF_OPEN;
500 map->map_pid = getpid();
501 }
564 if (!bitset(MF_OPTIONAL, map->map_mflags))
565 {
566 extern MAPCLASS BogusMapClass;
567
568 map->map_class = &BogusMapClass;
569 map->map_mflags |= MF_OPEN;
570 map->map_pid = getpid();
571 }
572 else
573 {
574 /* don't try again */
575 map->map_mflags &= ~MF_VALID;
576 }
502 }
577 }
578
579 if (restore)
580 {
581 Errors = saveerrors;
582 HoldErrs = savehold;
583 QuickAbort = savequick;
584 }
585
586 return bitset(MF_OPEN, map->map_mflags);
503}
504 /*
505** CLOSEMAPS -- close all open maps opened by the current pid.
506**
507** Parameters:
508** none
509**
510** Returns:
511** none.
512*/
513
514void
515closemaps()
516{
587}
588 /*
589** CLOSEMAPS -- close all open maps opened by the current pid.
590**
591** Parameters:
592** none
593**
594** Returns:
595** none.
596*/
597
598void
599closemaps()
600{
517 extern void map_close __P((STAB *, int));
518
519 stabapply(map_close, 0);
520}
601 stabapply(map_close, 0);
602}
603 /*
604** MAP_CLOSE -- close a map opened by the current pid.
605**
606** Parameters:
607** s -- STAB entry: if map: try to open
608** second parameter is unused (required by stabapply())
609**
610** Returns:
611** none.
612*/
521
522/* ARGSUSED1 */
613
614/* ARGSUSED1 */
523void
615static void
524map_close(s, unused)
525 register STAB *s;
526 int unused;
527{
528 MAP *map;
529
530 if (s->s_type != ST_MAP)
531 return;
616map_close(s, unused)
617 register STAB *s;
618 int unused;
619{
620 MAP *map;
621
622 if (s->s_type != ST_MAP)
623 return;
532
624
533 map = &s->s_map;
534
535 if (!bitset(MF_VALID, map->map_mflags) ||
536 !bitset(MF_OPEN, map->map_mflags) ||
625 map = &s->s_map;
626
627 if (!bitset(MF_VALID, map->map_mflags) ||
628 !bitset(MF_OPEN, map->map_mflags) ||
629 bitset(MF_SHARED, map->map_mflags) ||
537 map->map_pid != getpid())
538 return;
630 map->map_pid != getpid())
631 return;
539
632
540 if (tTd(38, 5))
633 if (tTd(38, 5))
541 printf("closemaps: closing %s (%s)\n",
542 map->map_mname == NULL ? "NULL" : map->map_mname,
543 map->map_file == NULL ? "NULL" : map->map_file);
544
634 dprintf("closemaps: closing %s (%s)\n",
635 map->map_mname == NULL ? "NULL" : map->map_mname,
636 map->map_file == NULL ? "NULL" : map->map_file);
637
545 map->map_class->map_close(map);
546 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
547}
548 /*
549** GETCANONNAME -- look up name using service switch
550**
551** Parameters:
552** host -- the host name to look up.

--- 10 unchanged lines hidden (view full) ---

563 char *host;
564 int hbsize;
565 bool trymx;
566{
567 int nmaps;
568 int mapno;
569 bool found = FALSE;
570 bool got_tempfail = FALSE;
638 map->map_class->map_close(map);
639 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
640}
641 /*
642** GETCANONNAME -- look up name using service switch
643**
644** Parameters:
645** host -- the host name to look up.

--- 10 unchanged lines hidden (view full) ---

656 char *host;
657 int hbsize;
658 bool trymx;
659{
660 int nmaps;
661 int mapno;
662 bool found = FALSE;
663 bool got_tempfail = FALSE;
571 auto int stat;
664 auto int status;
572 char *maptype[MAXMAPSTACK];
573 short mapreturn[MAXMAPACTIONS];
574
575 nmaps = switch_map_find("hosts", maptype, mapreturn);
576 for (mapno = 0; mapno < nmaps; mapno++)
577 {
578 int i;
579
580 if (tTd(38, 20))
665 char *maptype[MAXMAPSTACK];
666 short mapreturn[MAXMAPACTIONS];
667
668 nmaps = switch_map_find("hosts", maptype, mapreturn);
669 for (mapno = 0; mapno < nmaps; mapno++)
670 {
671 int i;
672
673 if (tTd(38, 20))
581 printf("getcanonname(%s), trying %s\n",
674 dprintf("getcanonname(%s), trying %s\n",
582 host, maptype[mapno]);
583 if (strcmp("files", maptype[mapno]) == 0)
584 {
675 host, maptype[mapno]);
676 if (strcmp("files", maptype[mapno]) == 0)
677 {
585 extern bool text_getcanonname __P((char *, int, int *));
586
587 found = text_getcanonname(host, hbsize, &stat);
678 found = text_getcanonname(host, hbsize, &status);
588 }
589#ifdef NIS
590 else if (strcmp("nis", maptype[mapno]) == 0)
591 {
679 }
680#ifdef NIS
681 else if (strcmp("nis", maptype[mapno]) == 0)
682 {
592 extern bool nis_getcanonname __P((char *, int, int *));
593
594 found = nis_getcanonname(host, hbsize, &stat);
683 found = nis_getcanonname(host, hbsize, &status);
595 }
684 }
596#endif
685#endif /* NIS */
597#ifdef NISPLUS
598 else if (strcmp("nisplus", maptype[mapno]) == 0)
599 {
686#ifdef NISPLUS
687 else if (strcmp("nisplus", maptype[mapno]) == 0)
688 {
600 extern bool nisplus_getcanonname __P((char *, int, int *));
601
602 found = nisplus_getcanonname(host, hbsize, &stat);
689 found = nisplus_getcanonname(host, hbsize, &status);
603 }
690 }
604#endif
691#endif /* NISPLUS */
605#if NAMED_BIND
606 else if (strcmp("dns", maptype[mapno]) == 0)
607 {
692#if NAMED_BIND
693 else if (strcmp("dns", maptype[mapno]) == 0)
694 {
608 extern bool dns_getcanonname __P((char *, int, bool, int *));
609
610 found = dns_getcanonname(host, hbsize, trymx, &stat);
695 found = dns_getcanonname(host, hbsize, trymx, &status);
611 }
696 }
612#endif
697#endif /* NAMED_BIND */
613#if NETINFO
614 else if (strcmp("netinfo", maptype[mapno]) == 0)
615 {
698#if NETINFO
699 else if (strcmp("netinfo", maptype[mapno]) == 0)
700 {
616 extern bool ni_getcanonname __P((char *, int, int *));
617
618 found = ni_getcanonname(host, hbsize, &stat);
701 found = ni_getcanonname(host, hbsize, &status);
619 }
702 }
620#endif
703#endif /* NETINFO */
621 else
622 {
623 found = FALSE;
704 else
705 {
706 found = FALSE;
624 stat = EX_UNAVAILABLE;
707 status = EX_UNAVAILABLE;
625 }
626
627 /*
628 ** Heuristic: if $m is not set, we are running during system
629 ** startup. In this case, when a name is apparently found
630 ** but has no dot, treat is as not found. This avoids
631 ** problems if /etc/hosts has no FQDN but is listed first
632 ** in the service switch.
633 */
634
635 if (found &&
636 (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL))
637 break;
638
639 /* see if we should continue */
708 }
709
710 /*
711 ** Heuristic: if $m is not set, we are running during system
712 ** startup. In this case, when a name is apparently found
713 ** but has no dot, treat is as not found. This avoids
714 ** problems if /etc/hosts has no FQDN but is listed first
715 ** in the service switch.
716 */
717
718 if (found &&
719 (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL))
720 break;
721
722 /* see if we should continue */
640 if (stat == EX_TEMPFAIL)
723 if (status == EX_TEMPFAIL)
641 {
642 i = MA_TRYAGAIN;
643 got_tempfail = TRUE;
644 }
724 {
725 i = MA_TRYAGAIN;
726 got_tempfail = TRUE;
727 }
645 else if (stat == EX_NOTFOUND)
728 else if (status == EX_NOTFOUND)
646 i = MA_NOTFOUND;
647 else
648 i = MA_UNAVAIL;
649 if (bitset(1 << mapno, mapreturn[i]))
650 break;
651 }
652
653 if (found)
654 {
655 char *d;
656
657 if (tTd(38, 20))
729 i = MA_NOTFOUND;
730 else
731 i = MA_UNAVAIL;
732 if (bitset(1 << mapno, mapreturn[i]))
733 break;
734 }
735
736 if (found)
737 {
738 char *d;
739
740 if (tTd(38, 20))
658 printf("getcanonname(%s), found\n", host);
741 dprintf("getcanonname(%s), found\n", host);
659
660 /*
661 ** If returned name is still single token, compensate
662 ** by tagging on $m. This is because some sites set
663 ** up their DNS or NIS databases wrong.
664 */
665
666 if ((d = strchr(host, '.')) == NULL || d[1] == '\0')
667 {
668 d = macvalue('m', CurEnv);
669 if (d != NULL &&
670 hbsize > (int) (strlen(host) + strlen(d) + 1))
671 {
672 if (host[strlen(host) - 1] != '.')
742
743 /*
744 ** If returned name is still single token, compensate
745 ** by tagging on $m. This is because some sites set
746 ** up their DNS or NIS databases wrong.
747 */
748
749 if ((d = strchr(host, '.')) == NULL || d[1] == '\0')
750 {
751 d = macvalue('m', CurEnv);
752 if (d != NULL &&
753 hbsize > (int) (strlen(host) + strlen(d) + 1))
754 {
755 if (host[strlen(host) - 1] != '.')
673 strcat(host, ".");
674 strcat(host, d);
756 (void) strlcat(host, ".", hbsize);
757 (void) strlcat(host, d, hbsize);
675 }
676 else
758 }
759 else
677 {
678 return FALSE;
760 return FALSE;
679 }
680 }
681 return TRUE;
682 }
683
684 if (tTd(38, 20))
761 }
762 return TRUE;
763 }
764
765 if (tTd(38, 20))
685 printf("getcanonname(%s), failed, stat=%d\n", host, stat);
766 dprintf("getcanonname(%s), failed, status=%d\n", host, status);
686
687#if NAMED_BIND
688 if (got_tempfail)
689 h_errno = TRY_AGAIN;
690 else
691 h_errno = HOST_NOT_FOUND;
767
768#if NAMED_BIND
769 if (got_tempfail)
770 h_errno = TRY_AGAIN;
771 else
772 h_errno = HOST_NOT_FOUND;
692#endif
773#endif /* NAMED_BIND */
693
694 return FALSE;
695}
696 /*
697** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
698**
699** Parameters:
700** name -- the name against which to match.
701** line -- the /etc/hosts line.
702** cbuf -- the location to store the result.
703** cbuflen -- the size of cbuf.
704**
705** Returns:
706** TRUE -- if the line matched the desired name.
707** FALSE -- otherwise.
708*/
709
774
775 return FALSE;
776}
777 /*
778** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
779**
780** Parameters:
781** name -- the name against which to match.
782** line -- the /etc/hosts line.
783** cbuf -- the location to store the result.
784** cbuflen -- the size of cbuf.
785**
786** Returns:
787** TRUE -- if the line matched the desired name.
788** FALSE -- otherwise.
789*/
790
710bool
791static bool
711extract_canonname(name, line, cbuf, cbuflen)
712 char *name;
713 char *line;
714 char cbuf[];
715 int cbuflen;
716{
717 int i;
718 char *p;
719 bool found = FALSE;
792extract_canonname(name, line, cbuf, cbuflen)
793 char *name;
794 char *line;
795 char cbuf[];
796 int cbuflen;
797{
798 int i;
799 char *p;
800 bool found = FALSE;
720 extern char *get_column __P((char *, int, char, char *, int));
721
722 cbuf[0] = '\0';
723 if (line[0] == '#')
724 return FALSE;
725
726 for (i = 1; ; i++)
727 {
728 char nbuf[MAXNAME + 1];

--- 12 unchanged lines hidden (view full) ---

741 found = TRUE;
742 }
743 if (found && strchr(cbuf, '.') == NULL)
744 {
745 /* try to add a domain on the end of the name */
746 char *domain = macvalue('m', CurEnv);
747
748 if (domain != NULL &&
801
802 cbuf[0] = '\0';
803 if (line[0] == '#')
804 return FALSE;
805
806 for (i = 1; ; i++)
807 {
808 char nbuf[MAXNAME + 1];

--- 12 unchanged lines hidden (view full) ---

821 found = TRUE;
822 }
823 if (found && strchr(cbuf, '.') == NULL)
824 {
825 /* try to add a domain on the end of the name */
826 char *domain = macvalue('m', CurEnv);
827
828 if (domain != NULL &&
749 strlen(domain) + strlen(cbuf) + 1 < cbuflen)
829 strlen(domain) + (i = strlen(cbuf)) + 1 < (size_t) cbuflen)
750 {
830 {
751 p = &cbuf[strlen(cbuf)];
831 p = &cbuf[i];
752 *p++ = '.';
832 *p++ = '.';
753 strcpy(p, domain);
833 (void) strlcpy(p, domain, cbuflen - i - 1);
754 }
755 }
756 return found;
757}
758 /*
759** NDBM modules
760*/
761

--- 4 unchanged lines hidden (view full) ---

766*/
767
768bool
769ndbm_map_open(map, mode)
770 MAP *map;
771 int mode;
772{
773 register DBM *dbm;
834 }
835 }
836 return found;
837}
838 /*
839** NDBM modules
840*/
841

--- 4 unchanged lines hidden (view full) ---

846*/
847
848bool
849ndbm_map_open(map, mode)
850 MAP *map;
851 int mode;
852{
853 register DBM *dbm;
774 struct stat st;
854 int save_errno;
775 int dfd;
776 int pfd;
855 int dfd;
856 int pfd;
777 int sff;
857 long sff;
778 int ret;
779 int smode = S_IREAD;
780 char dirfile[MAXNAME + 1];
781 char pagfile[MAXNAME + 1];
858 int ret;
859 int smode = S_IREAD;
860 char dirfile[MAXNAME + 1];
861 char pagfile[MAXNAME + 1];
862 struct stat st;
782 struct stat std, stp;
783
784 if (tTd(38, 2))
863 struct stat std, stp;
864
865 if (tTd(38, 2))
785 printf("ndbm_map_open(%s, %s, %d)\n",
866 dprintf("ndbm_map_open(%s, %s, %d)\n",
786 map->map_mname, map->map_file, mode);
787 map->map_lockfd = -1;
788 mode &= O_ACCMODE;
789
790 /* do initial file and directory checks */
791 snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file);
792 snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file);
793 sff = SFF_ROOTOK|SFF_REGONLY;
794 if (mode == O_RDWR)
795 {
796 sff |= SFF_CREAT;
867 map->map_mname, map->map_file, mode);
868 map->map_lockfd = -1;
869 mode &= O_ACCMODE;
870
871 /* do initial file and directory checks */
872 snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file);
873 snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file);
874 sff = SFF_ROOTOK|SFF_REGONLY;
875 if (mode == O_RDWR)
876 {
877 sff |= SFF_CREAT;
797 if (!bitset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
878 if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
798 sff |= SFF_NOSLINK;
879 sff |= SFF_NOSLINK;
799 if (!bitset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
880 if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
800 sff |= SFF_NOHLINK;
801 smode = S_IWRITE;
802 }
803 else
804 {
881 sff |= SFF_NOHLINK;
882 smode = S_IWRITE;
883 }
884 else
885 {
805 if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
886 if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
806 sff |= SFF_NOWLINK;
807 }
887 sff |= SFF_NOWLINK;
888 }
808 if (!bitset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
889 if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
809 sff |= SFF_SAFEDIRPATH;
810 ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName,
811 sff, smode, &std);
812 if (ret == 0)
813 ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName,
814 sff, smode, &stp);
890 sff |= SFF_SAFEDIRPATH;
891 ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName,
892 sff, smode, &std);
893 if (ret == 0)
894 ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName,
895 sff, smode, &stp);
896
897# if !_FFR_REMOVE_AUTOREBUILD
815 if (ret == ENOENT && AutoRebuild &&
816 bitset(MCF_REBUILDABLE, map->map_class->map_cflags) &&
817 (bitset(MF_IMPL_NDBM, map->map_mflags) ||
818 bitset(MF_ALIAS, map->map_mflags)) &&
819 mode == O_RDONLY)
820 {
821 bool impl = bitset(MF_IMPL_NDBM, map->map_mflags);
898 if (ret == ENOENT && AutoRebuild &&
899 bitset(MCF_REBUILDABLE, map->map_class->map_cflags) &&
900 (bitset(MF_IMPL_NDBM, map->map_mflags) ||
901 bitset(MF_ALIAS, map->map_mflags)) &&
902 mode == O_RDONLY)
903 {
904 bool impl = bitset(MF_IMPL_NDBM, map->map_mflags);
822 extern bool impl_map_open __P((MAP *, int));
823
824 /* may be able to rebuild */
825 map->map_mflags &= ~MF_IMPL_NDBM;
826 if (!rebuildaliases(map, TRUE))
827 return FALSE;
828 if (impl)
829 return impl_map_open(map, O_RDONLY);
830 else
831 return ndbm_map_open(map, O_RDONLY);
832 }
905
906 /* may be able to rebuild */
907 map->map_mflags &= ~MF_IMPL_NDBM;
908 if (!rebuildaliases(map, TRUE))
909 return FALSE;
910 if (impl)
911 return impl_map_open(map, O_RDONLY);
912 else
913 return ndbm_map_open(map, O_RDONLY);
914 }
915# endif /* !_FFR_REMOVE_AUTOREBUILD */
916
833 if (ret != 0)
834 {
835 char *prob = "unsafe";
836
837 /* cannot open this map */
838 if (ret == ENOENT)
839 prob = "missing";
840 if (tTd(38, 2))
917 if (ret != 0)
918 {
919 char *prob = "unsafe";
920
921 /* cannot open this map */
922 if (ret == ENOENT)
923 prob = "missing";
924 if (tTd(38, 2))
841 printf("\t%s map file: %d\n", prob, ret);
925 dprintf("\t%s map file: %d\n", prob, ret);
842 if (!bitset(MF_OPTIONAL, map->map_mflags))
843 syserr("dbm map \"%s\": %s map file %s",
844 map->map_mname, prob, map->map_file);
845 return FALSE;
846 }
847 if (std.st_mode == ST_MODE_NOFILE)
848 mode |= O_CREAT|O_EXCL;
849
926 if (!bitset(MF_OPTIONAL, map->map_mflags))
927 syserr("dbm map \"%s\": %s map file %s",
928 map->map_mname, prob, map->map_file);
929 return FALSE;
930 }
931 if (std.st_mode == ST_MODE_NOFILE)
932 mode |= O_CREAT|O_EXCL;
933
850#if LOCK_ON_OPEN
934# if LOCK_ON_OPEN
851 if (mode == O_RDONLY)
852 mode |= O_SHLOCK;
853 else
854 mode |= O_TRUNC|O_EXLOCK;
935 if (mode == O_RDONLY)
936 mode |= O_SHLOCK;
937 else
938 mode |= O_TRUNC|O_EXLOCK;
855#else
939# else /* LOCK_ON_OPEN */
856 if ((mode & O_ACCMODE) == O_RDWR)
857 {
940 if ((mode & O_ACCMODE) == O_RDWR)
941 {
858# if NOFTRUNCATE
942# if NOFTRUNCATE
859 /*
860 ** Warning: race condition. Try to lock the file as
861 ** quickly as possible after opening it.
862 ** This may also have security problems on some systems,
863 ** but there isn't anything we can do about it.
864 */
865
866 mode |= O_TRUNC;
943 /*
944 ** Warning: race condition. Try to lock the file as
945 ** quickly as possible after opening it.
946 ** This may also have security problems on some systems,
947 ** but there isn't anything we can do about it.
948 */
949
950 mode |= O_TRUNC;
867# else
951# else /* NOFTRUNCATE */
868 /*
869 ** This ugly code opens the map without truncating it,
870 ** locks the file, then truncates it. Necessary to
871 ** avoid race conditions.
872 */
873
874 int dirfd;
875 int pagfd;
952 /*
953 ** This ugly code opens the map without truncating it,
954 ** locks the file, then truncates it. Necessary to
955 ** avoid race conditions.
956 */
957
958 int dirfd;
959 int pagfd;
876 int sff = SFF_CREAT|SFF_OPENASROOT;
960 long sff = SFF_CREAT|SFF_OPENASROOT;
877
961
878 if (!bitset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
962 if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
879 sff |= SFF_NOSLINK;
963 sff |= SFF_NOSLINK;
880 if (!bitset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
964 if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
881 sff |= SFF_NOHLINK;
882
883 dirfd = safeopen(dirfile, mode, DBMMODE, sff);
884 pagfd = safeopen(pagfile, mode, DBMMODE, sff);
885
886 if (dirfd < 0 || pagfd < 0)
887 {
965 sff |= SFF_NOHLINK;
966
967 dirfd = safeopen(dirfile, mode, DBMMODE, sff);
968 pagfd = safeopen(pagfile, mode, DBMMODE, sff);
969
970 if (dirfd < 0 || pagfd < 0)
971 {
888 int save_errno = errno;
889
972 save_errno = errno;
890 if (dirfd >= 0)
891 (void) close(dirfd);
892 if (pagfd >= 0)
893 (void) close(pagfd);
894 errno = save_errno;
895 syserr("ndbm_map_open: cannot create database %s",
896 map->map_file);
897 return FALSE;
898 }
899 if (ftruncate(dirfd, (off_t) 0) < 0 ||
900 ftruncate(pagfd, (off_t) 0) < 0)
901 {
973 if (dirfd >= 0)
974 (void) close(dirfd);
975 if (pagfd >= 0)
976 (void) close(pagfd);
977 errno = save_errno;
978 syserr("ndbm_map_open: cannot create database %s",
979 map->map_file);
980 return FALSE;
981 }
982 if (ftruncate(dirfd, (off_t) 0) < 0 ||
983 ftruncate(pagfd, (off_t) 0) < 0)
984 {
902 int save_errno = errno;
903
985 save_errno = errno;
904 (void) close(dirfd);
905 (void) close(pagfd);
906 errno = save_errno;
907 syserr("ndbm_map_open: cannot truncate %s.{dir,pag}",
908 map->map_file);
909 return FALSE;
910 }
911
912 /* if new file, get "before" bits for later filechanged check */
913 if (std.st_mode == ST_MODE_NOFILE &&
914 (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0))
915 {
986 (void) close(dirfd);
987 (void) close(pagfd);
988 errno = save_errno;
989 syserr("ndbm_map_open: cannot truncate %s.{dir,pag}",
990 map->map_file);
991 return FALSE;
992 }
993
994 /* if new file, get "before" bits for later filechanged check */
995 if (std.st_mode == ST_MODE_NOFILE &&
996 (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0))
997 {
916 int save_errno = errno;
917
998 save_errno = errno;
918 (void) close(dirfd);
919 (void) close(pagfd);
920 errno = save_errno;
921 syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file",
922 map->map_file);
923 return FALSE;
924 }
925
926 /* have to save the lock for the duration (bletch) */
927 map->map_lockfd = dirfd;
999 (void) close(dirfd);
1000 (void) close(pagfd);
1001 errno = save_errno;
1002 syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file",
1003 map->map_file);
1004 return FALSE;
1005 }
1006
1007 /* have to save the lock for the duration (bletch) */
1008 map->map_lockfd = dirfd;
928 close(pagfd);
1009 (void) close(pagfd);
929
930 /* twiddle bits for dbm_open */
931 mode &= ~(O_CREAT|O_EXCL);
1010
1011 /* twiddle bits for dbm_open */
1012 mode &= ~(O_CREAT|O_EXCL);
932# endif
1013# endif /* NOFTRUNCATE */
933 }
1014 }
934#endif
1015# endif /* LOCK_ON_OPEN */
935
936 /* open the database */
937 dbm = dbm_open(map->map_file, mode, DBMMODE);
938 if (dbm == NULL)
939 {
1016
1017 /* open the database */
1018 dbm = dbm_open(map->map_file, mode, DBMMODE);
1019 if (dbm == NULL)
1020 {
940 int save_errno = errno;
941
1021 save_errno = errno;
942 if (bitset(MF_ALIAS, map->map_mflags) &&
943 aliaswait(map, ".pag", FALSE))
944 return TRUE;
1022 if (bitset(MF_ALIAS, map->map_mflags) &&
1023 aliaswait(map, ".pag", FALSE))
1024 return TRUE;
945#if !LOCK_ON_OPEN && !NOFTRUNCATE
1025# if !LOCK_ON_OPEN && !NOFTRUNCATE
946 if (map->map_lockfd >= 0)
1026 if (map->map_lockfd >= 0)
947 close(map->map_lockfd);
948#endif
1027 (void) close(map->map_lockfd);
1028# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
949 errno = save_errno;
950 if (!bitset(MF_OPTIONAL, map->map_mflags))
951 syserr("Cannot open DBM database %s", map->map_file);
952 return FALSE;
953 }
954 dfd = dbm_dirfno(dbm);
955 pfd = dbm_pagfno(dbm);
956 if (dfd == pfd)
957 {
958 /* heuristic: if files are linked, this is actually gdbm */
959 dbm_close(dbm);
1029 errno = save_errno;
1030 if (!bitset(MF_OPTIONAL, map->map_mflags))
1031 syserr("Cannot open DBM database %s", map->map_file);
1032 return FALSE;
1033 }
1034 dfd = dbm_dirfno(dbm);
1035 pfd = dbm_pagfno(dbm);
1036 if (dfd == pfd)
1037 {
1038 /* heuristic: if files are linked, this is actually gdbm */
1039 dbm_close(dbm);
960#if !LOCK_ON_OPEN && !NOFTRUNCATE
1040# if !LOCK_ON_OPEN && !NOFTRUNCATE
961 if (map->map_lockfd >= 0)
1041 if (map->map_lockfd >= 0)
962 close(map->map_lockfd);
963#endif
1042 (void) close(map->map_lockfd);
1043# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
964 errno = 0;
965 syserr("dbm map \"%s\": cannot support GDBM",
966 map->map_mname);
967 return FALSE;
968 }
969
970 if (filechanged(dirfile, dfd, &std) ||
971 filechanged(pagfile, pfd, &stp))
972 {
1044 errno = 0;
1045 syserr("dbm map \"%s\": cannot support GDBM",
1046 map->map_mname);
1047 return FALSE;
1048 }
1049
1050 if (filechanged(dirfile, dfd, &std) ||
1051 filechanged(pagfile, pfd, &stp))
1052 {
973 int save_errno = errno;
974
1053 save_errno = errno;
975 dbm_close(dbm);
1054 dbm_close(dbm);
976#if !LOCK_ON_OPEN && !NOFTRUNCATE
1055# if !LOCK_ON_OPEN && !NOFTRUNCATE
977 if (map->map_lockfd >= 0)
1056 if (map->map_lockfd >= 0)
978 close(map->map_lockfd);
979#endif
1057 (void) close(map->map_lockfd);
1058# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
980 errno = save_errno;
981 syserr("ndbm_map_open(%s): file changed after open",
982 map->map_file);
983 return FALSE;
984 }
985
986 map->map_db1 = (ARBPTR_T) dbm;
1059 errno = save_errno;
1060 syserr("ndbm_map_open(%s): file changed after open",
1061 map->map_file);
1062 return FALSE;
1063 }
1064
1065 map->map_db1 = (ARBPTR_T) dbm;
1066
1067 /*
1068 ** Need to set map_mtime before the call to aliaswait()
1069 ** as aliaswait() will call map_lookup() which requires
1070 ** map_mtime to be set
1071 */
1072
1073 if (fstat(dfd, &st) >= 0)
1074 map->map_mtime = st.st_mtime;
1075
987 if (mode == O_RDONLY)
988 {
1076 if (mode == O_RDONLY)
1077 {
989#if LOCK_ON_OPEN
1078# if LOCK_ON_OPEN
990 if (dfd >= 0)
991 (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
992 if (pfd >= 0)
993 (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN);
1079 if (dfd >= 0)
1080 (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
1081 if (pfd >= 0)
1082 (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN);
994#endif
1083# endif /* LOCK_ON_OPEN */
995 if (bitset(MF_ALIAS, map->map_mflags) &&
996 !aliaswait(map, ".pag", TRUE))
997 return FALSE;
998 }
999 else
1000 {
1001 map->map_mflags |= MF_LOCKED;
1084 if (bitset(MF_ALIAS, map->map_mflags) &&
1085 !aliaswait(map, ".pag", TRUE))
1086 return FALSE;
1087 }
1088 else
1089 {
1090 map->map_mflags |= MF_LOCKED;
1002#if _FFR_TRUSTED_USER
1003 if (geteuid() == 0 && TrustedUid != 0)
1004 {
1091 if (geteuid() == 0 && TrustedUid != 0)
1092 {
1093# if HASFCHOWN
1005 if (fchown(dfd, TrustedUid, -1) < 0 ||
1006 fchown(pfd, TrustedUid, -1) < 0)
1007 {
1008 int err = errno;
1009
1010 sm_syslog(LOG_ALERT, NOQID,
1011 "ownership change on %s failed: %s",
1012 map->map_file, errstring(err));
1013 message("050 ownership change on %s failed: %s",
1014 map->map_file, errstring(err));
1015 }
1094 if (fchown(dfd, TrustedUid, -1) < 0 ||
1095 fchown(pfd, TrustedUid, -1) < 0)
1096 {
1097 int err = errno;
1098
1099 sm_syslog(LOG_ALERT, NOQID,
1100 "ownership change on %s failed: %s",
1101 map->map_file, errstring(err));
1102 message("050 ownership change on %s failed: %s",
1103 map->map_file, errstring(err));
1104 }
1105# endif /* HASFCHOWN */
1016 }
1106 }
1017#endif
1018 }
1107 }
1019 if (fstat(dfd, &st) >= 0)
1020 map->map_mtime = st.st_mtime;
1021 return TRUE;
1022}
1023
1024
1025/*
1026** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map
1027*/
1028

--- 5 unchanged lines hidden (view full) ---

1034 int *statp;
1035{
1036 datum key, val;
1037 int fd;
1038 char keybuf[MAXNAME + 1];
1039 struct stat stbuf;
1040
1041 if (tTd(38, 20))
1108 return TRUE;
1109}
1110
1111
1112/*
1113** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map
1114*/
1115

--- 5 unchanged lines hidden (view full) ---

1121 int *statp;
1122{
1123 datum key, val;
1124 int fd;
1125 char keybuf[MAXNAME + 1];
1126 struct stat stbuf;
1127
1128 if (tTd(38, 20))
1042 printf("ndbm_map_lookup(%s, %s)\n",
1129 dprintf("ndbm_map_lookup(%s, %s)\n",
1043 map->map_mname, name);
1044
1045 key.dptr = name;
1046 key.dsize = strlen(name);
1047 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1048 {
1049 if (key.dsize > sizeof keybuf - 1)
1050 key.dsize = sizeof keybuf - 1;
1130 map->map_mname, name);
1131
1132 key.dptr = name;
1133 key.dsize = strlen(name);
1134 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1135 {
1136 if (key.dsize > sizeof keybuf - 1)
1137 key.dsize = sizeof keybuf - 1;
1051 bcopy(key.dptr, keybuf, key.dsize);
1138 memmove(keybuf, key.dptr, key.dsize);
1052 keybuf[key.dsize] = '\0';
1053 makelower(keybuf);
1054 key.dptr = keybuf;
1055 }
1056lockdbm:
1057 fd = dbm_dirfno((DBM *) map->map_db1);
1058 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1059 (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
1060 if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
1061 {
1062 /* Reopen the database to sync the cache */
1063 int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
1064 : O_RDONLY;
1065
1139 keybuf[key.dsize] = '\0';
1140 makelower(keybuf);
1141 key.dptr = keybuf;
1142 }
1143lockdbm:
1144 fd = dbm_dirfno((DBM *) map->map_db1);
1145 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1146 (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
1147 if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
1148 {
1149 /* Reopen the database to sync the cache */
1150 int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
1151 : O_RDONLY;
1152
1153 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1154 (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
1066 map->map_class->map_close(map);
1067 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
1068 if (map->map_class->map_open(map, omode))
1069 {
1070 map->map_mflags |= MF_OPEN;
1071 map->map_pid = getpid();
1072 if ((omode && O_ACCMODE) == O_RDWR)
1073 map->map_mflags |= MF_WRITABLE;

--- 47 unchanged lines hidden (view full) ---

1121void
1122ndbm_map_store(map, lhs, rhs)
1123 register MAP *map;
1124 char *lhs;
1125 char *rhs;
1126{
1127 datum key;
1128 datum data;
1155 map->map_class->map_close(map);
1156 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
1157 if (map->map_class->map_open(map, omode))
1158 {
1159 map->map_mflags |= MF_OPEN;
1160 map->map_pid = getpid();
1161 if ((omode && O_ACCMODE) == O_RDWR)
1162 map->map_mflags |= MF_WRITABLE;

--- 47 unchanged lines hidden (view full) ---

1210void
1211ndbm_map_store(map, lhs, rhs)
1212 register MAP *map;
1213 char *lhs;
1214 char *rhs;
1215{
1216 datum key;
1217 datum data;
1129 int stat;
1218 int status;
1130 char keybuf[MAXNAME + 1];
1131
1132 if (tTd(38, 12))
1219 char keybuf[MAXNAME + 1];
1220
1221 if (tTd(38, 12))
1133 printf("ndbm_map_store(%s, %s, %s)\n",
1222 dprintf("ndbm_map_store(%s, %s, %s)\n",
1134 map->map_mname, lhs, rhs);
1135
1136 key.dsize = strlen(lhs);
1137 key.dptr = lhs;
1138 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1139 {
1140 if (key.dsize > sizeof keybuf - 1)
1141 key.dsize = sizeof keybuf - 1;
1223 map->map_mname, lhs, rhs);
1224
1225 key.dsize = strlen(lhs);
1226 key.dptr = lhs;
1227 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1228 {
1229 if (key.dsize > sizeof keybuf - 1)
1230 key.dsize = sizeof keybuf - 1;
1142 bcopy(key.dptr, keybuf, key.dsize);
1231 memmove(keybuf, key.dptr, key.dsize);
1143 keybuf[key.dsize] = '\0';
1144 makelower(keybuf);
1145 key.dptr = keybuf;
1146 }
1147
1148 data.dsize = strlen(rhs);
1149 data.dptr = rhs;
1150
1151 if (bitset(MF_INCLNULL, map->map_mflags))
1152 {
1153 key.dsize++;
1154 data.dsize++;
1155 }
1156
1232 keybuf[key.dsize] = '\0';
1233 makelower(keybuf);
1234 key.dptr = keybuf;
1235 }
1236
1237 data.dsize = strlen(rhs);
1238 data.dptr = rhs;
1239
1240 if (bitset(MF_INCLNULL, map->map_mflags))
1241 {
1242 key.dsize++;
1243 data.dsize++;
1244 }
1245
1157 stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
1158 if (stat > 0)
1246 status = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
1247 if (status > 0)
1159 {
1160 if (!bitset(MF_APPEND, map->map_mflags))
1161 message("050 Warning: duplicate alias name %s", lhs);
1162 else
1163 {
1164 static char *buf = NULL;
1165 static int bufsiz = 0;
1166 auto int xstat;

--- 11 unchanged lines hidden (view full) ---

1178 bufsiz = data.dsize + old.dsize + 2;
1179 buf = xalloc(bufsiz);
1180 }
1181 snprintf(buf, bufsiz, "%s,%s",
1182 data.dptr, old.dptr);
1183 data.dsize = data.dsize + old.dsize + 1;
1184 data.dptr = buf;
1185 if (tTd(38, 9))
1248 {
1249 if (!bitset(MF_APPEND, map->map_mflags))
1250 message("050 Warning: duplicate alias name %s", lhs);
1251 else
1252 {
1253 static char *buf = NULL;
1254 static int bufsiz = 0;
1255 auto int xstat;

--- 11 unchanged lines hidden (view full) ---

1267 bufsiz = data.dsize + old.dsize + 2;
1268 buf = xalloc(bufsiz);
1269 }
1270 snprintf(buf, bufsiz, "%s,%s",
1271 data.dptr, old.dptr);
1272 data.dsize = data.dsize + old.dsize + 1;
1273 data.dptr = buf;
1274 if (tTd(38, 9))
1186 printf("ndbm_map_store append=%s\n", data.dptr);
1275 dprintf("ndbm_map_store append=%s\n",
1276 data.dptr);
1187 }
1188 }
1277 }
1278 }
1189 stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE);
1279 status = dbm_store((DBM *) map->map_db1,
1280 key, data, DBM_REPLACE);
1190 }
1281 }
1191 if (stat != 0)
1192 syserr("readaliases: dbm put (%s)", lhs);
1282 if (status != 0)
1283 syserr("readaliases: dbm put (%s): %d", lhs, status);
1193}
1194
1195
1196/*
1197** NDBM_MAP_CLOSE -- close the database
1198*/
1199
1200void
1201ndbm_map_close(map)
1202 register MAP *map;
1203{
1204 if (tTd(38, 9))
1284}
1285
1286
1287/*
1288** NDBM_MAP_CLOSE -- close the database
1289*/
1290
1291void
1292ndbm_map_close(map)
1293 register MAP *map;
1294{
1295 if (tTd(38, 9))
1205 printf("ndbm_map_close(%s, %s, %lx)\n",
1296 dprintf("ndbm_map_close(%s, %s, %lx)\n",
1206 map->map_mname, map->map_file, map->map_mflags);
1207
1208 if (bitset(MF_WRITABLE, map->map_mflags))
1209 {
1297 map->map_mname, map->map_file, map->map_mflags);
1298
1299 if (bitset(MF_WRITABLE, map->map_mflags))
1300 {
1210#ifdef NDBM_YP_COMPAT
1301# ifdef NDBM_YP_COMPAT
1211 bool inclnull;
1212 char buf[MAXHOSTNAMELEN];
1213
1214 inclnull = bitset(MF_INCLNULL, map->map_mflags);
1215 map->map_mflags &= ~MF_INCLNULL;
1216
1217 if (strstr(map->map_file, "/yp/") != NULL)
1218 {

--- 7 unchanged lines hidden (view full) ---

1226 (void) gethostname(buf, sizeof buf);
1227 ndbm_map_store(map, "YP_MASTER_NAME", buf);
1228
1229 map->map_mflags = save_mflags;
1230 }
1231
1232 if (inclnull)
1233 map->map_mflags |= MF_INCLNULL;
1302 bool inclnull;
1303 char buf[MAXHOSTNAMELEN];
1304
1305 inclnull = bitset(MF_INCLNULL, map->map_mflags);
1306 map->map_mflags &= ~MF_INCLNULL;
1307
1308 if (strstr(map->map_file, "/yp/") != NULL)
1309 {

--- 7 unchanged lines hidden (view full) ---

1317 (void) gethostname(buf, sizeof buf);
1318 ndbm_map_store(map, "YP_MASTER_NAME", buf);
1319
1320 map->map_mflags = save_mflags;
1321 }
1322
1323 if (inclnull)
1324 map->map_mflags |= MF_INCLNULL;
1234#endif
1325# endif /* NDBM_YP_COMPAT */
1235
1236 /* write out the distinguished alias */
1237 ndbm_map_store(map, "@", "@");
1238 }
1239 dbm_close((DBM *) map->map_db1);
1240
1241 /* release lock (if needed) */
1326
1327 /* write out the distinguished alias */
1328 ndbm_map_store(map, "@", "@");
1329 }
1330 dbm_close((DBM *) map->map_db1);
1331
1332 /* release lock (if needed) */
1242#if !LOCK_ON_OPEN
1333# if !LOCK_ON_OPEN
1243 if (map->map_lockfd >= 0)
1244 (void) close(map->map_lockfd);
1334 if (map->map_lockfd >= 0)
1335 (void) close(map->map_lockfd);
1245#endif
1336# endif /* !LOCK_ON_OPEN */
1246}
1247
1337}
1338
1248#endif
1339#endif /* NDBM */
1249 /*
1250** NEWDB (Hash and BTree) Modules
1251*/
1252
1253#ifdef NEWDB
1254
1255/*
1256** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives.
1257**
1258** These do rather bizarre locking. If you can lock on open,
1259** do that to avoid the condition of opening a database that
1260** is being rebuilt. If you don't, we'll try to fake it, but
1261** there will be a race condition. If opening for read-only,
1262** we immediately release the lock to avoid freezing things up.
1263** We really ought to hold the lock, but guarantee that we won't
1264** be pokey about it. That's hard to do.
1265*/
1266
1340 /*
1341** NEWDB (Hash and BTree) Modules
1342*/
1343
1344#ifdef NEWDB
1345
1346/*
1347** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives.
1348**
1349** These do rather bizarre locking. If you can lock on open,
1350** do that to avoid the condition of opening a database that
1351** is being rebuilt. If you don't, we'll try to fake it, but
1352** there will be a race condition. If opening for read-only,
1353** we immediately release the lock to avoid freezing things up.
1354** We really ought to hold the lock, but guarantee that we won't
1355** be pokey about it. That's hard to do.
1356*/
1357
1267#if DB_VERSION_MAJOR < 2
1268extern bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
1269#else
1270extern bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *));
1271#endif
1272
1273/* these should be K line arguments */
1358/* these should be K line arguments */
1274#if DB_VERSION_MAJOR < 2
1275# define db_cachesize cachesize
1276# define h_nelem nelem
1277# ifndef DB_CACHE_SIZE
1278# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
1279# endif
1280# ifndef DB_HASH_NELEM
1281# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
1282# endif
1283#endif
1359# if DB_VERSION_MAJOR < 2
1360# define db_cachesize cachesize
1361# define h_nelem nelem
1362# ifndef DB_CACHE_SIZE
1363# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
1364# endif /* ! DB_CACHE_SIZE */
1365# ifndef DB_HASH_NELEM
1366# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
1367# endif /* ! DB_HASH_NELEM */
1368# endif /* DB_VERSION_MAJOR < 2 */
1284
1285bool
1286bt_map_open(map, mode)
1287 MAP *map;
1288 int mode;
1289{
1369
1370bool
1371bt_map_open(map, mode)
1372 MAP *map;
1373 int mode;
1374{
1290#if DB_VERSION_MAJOR < 2
1375# if DB_VERSION_MAJOR < 2
1291 BTREEINFO btinfo;
1376 BTREEINFO btinfo;
1292#else
1377# endif /* DB_VERSION_MAJOR < 2 */
1378# if DB_VERSION_MAJOR == 2
1293 DB_INFO btinfo;
1379 DB_INFO btinfo;
1294#endif
1380# endif /* DB_VERSION_MAJOR == 2 */
1381# if DB_VERSION_MAJOR > 2
1382 void *btinfo = NULL;
1383# endif /* DB_VERSION_MAJOR > 2 */
1295
1296 if (tTd(38, 2))
1384
1385 if (tTd(38, 2))
1297 printf("bt_map_open(%s, %s, %d)\n",
1386 dprintf("bt_map_open(%s, %s, %d)\n",
1298 map->map_mname, map->map_file, mode);
1299
1387 map->map_mname, map->map_file, mode);
1388
1300 bzero(&btinfo, sizeof btinfo);
1301#ifdef DB_CACHE_SIZE
1389# if DB_VERSION_MAJOR < 3
1390 memset(&btinfo, '\0', sizeof btinfo);
1391# ifdef DB_CACHE_SIZE
1302 btinfo.db_cachesize = DB_CACHE_SIZE;
1392 btinfo.db_cachesize = DB_CACHE_SIZE;
1303#endif
1393# endif /* DB_CACHE_SIZE */
1394# endif /* DB_VERSION_MAJOR < 3 */
1395
1304 return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
1305}
1306
1307bool
1308hash_map_open(map, mode)
1309 MAP *map;
1310 int mode;
1311{
1396 return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
1397}
1398
1399bool
1400hash_map_open(map, mode)
1401 MAP *map;
1402 int mode;
1403{
1312#if DB_VERSION_MAJOR < 2
1404# if DB_VERSION_MAJOR < 2
1313 HASHINFO hinfo;
1405 HASHINFO hinfo;
1314#else
1406# endif /* DB_VERSION_MAJOR < 2 */
1407# if DB_VERSION_MAJOR == 2
1315 DB_INFO hinfo;
1408 DB_INFO hinfo;
1316#endif
1409# endif /* DB_VERSION_MAJOR == 2 */
1410# if DB_VERSION_MAJOR > 2
1411 void *hinfo = NULL;
1412# endif /* DB_VERSION_MAJOR > 2 */
1317
1318 if (tTd(38, 2))
1413
1414 if (tTd(38, 2))
1319 printf("hash_map_open(%s, %s, %d)\n",
1415 dprintf("hash_map_open(%s, %s, %d)\n",
1320 map->map_mname, map->map_file, mode);
1321
1416 map->map_mname, map->map_file, mode);
1417
1322 bzero(&hinfo, sizeof hinfo);
1323#ifdef DB_HASH_NELEM
1418# if DB_VERSION_MAJOR < 3
1419 memset(&hinfo, '\0', sizeof hinfo);
1420# ifdef DB_HASH_NELEM
1324 hinfo.h_nelem = DB_HASH_NELEM;
1421 hinfo.h_nelem = DB_HASH_NELEM;
1325#endif
1326#ifdef DB_CACHE_SIZE
1422# endif /* DB_HASH_NELEM */
1423# ifdef DB_CACHE_SIZE
1327 hinfo.db_cachesize = DB_CACHE_SIZE;
1424 hinfo.db_cachesize = DB_CACHE_SIZE;
1328#endif
1425# endif /* DB_CACHE_SIZE */
1426# endif /* DB_VERSION_MAJOR < 3 */
1427
1329 return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
1330}
1331
1428 return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
1429}
1430
1332bool
1431static bool
1333db_map_open(map, mode, mapclassname, dbtype, openinfo)
1334 MAP *map;
1335 int mode;
1336 char *mapclassname;
1337 DBTYPE dbtype;
1432db_map_open(map, mode, mapclassname, dbtype, openinfo)
1433 MAP *map;
1434 int mode;
1435 char *mapclassname;
1436 DBTYPE dbtype;
1338#if DB_VERSION_MAJOR < 2
1437# if DB_VERSION_MAJOR < 2
1339 const void *openinfo;
1438 const void *openinfo;
1340#else
1439# endif /* DB_VERSION_MAJOR < 2 */
1440# if DB_VERSION_MAJOR == 2
1341 DB_INFO *openinfo;
1441 DB_INFO *openinfo;
1342#endif
1442# endif /* DB_VERSION_MAJOR == 2 */
1443# if DB_VERSION_MAJOR > 2
1444 void **openinfo;
1445# endif /* DB_VERSION_MAJOR > 2 */
1343{
1344 DB *db = NULL;
1345 int i;
1346 int omode;
1347 int smode = S_IREAD;
1348 int fd;
1446{
1447 DB *db = NULL;
1448 int i;
1449 int omode;
1450 int smode = S_IREAD;
1451 int fd;
1349 int sff;
1350 int saveerrno;
1452 long sff;
1453 int save_errno;
1351 struct stat st;
1352 char buf[MAXNAME + 1];
1353
1354 /* do initial file and directory checks */
1454 struct stat st;
1455 char buf[MAXNAME + 1];
1456
1457 /* do initial file and directory checks */
1355 snprintf(buf, sizeof buf - 3, "%s", map->map_file);
1458 (void) strlcpy(buf, map->map_file, sizeof buf - 3);
1356 i = strlen(buf);
1357 if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
1459 i = strlen(buf);
1460 if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
1358 (void) strcat(buf, ".db");
1461 (void) strlcat(buf, ".db", sizeof buf);
1359
1360 mode &= O_ACCMODE;
1361 omode = mode;
1362
1363 sff = SFF_ROOTOK|SFF_REGONLY;
1364 if (mode == O_RDWR)
1365 {
1366 sff |= SFF_CREAT;
1462
1463 mode &= O_ACCMODE;
1464 omode = mode;
1465
1466 sff = SFF_ROOTOK|SFF_REGONLY;
1467 if (mode == O_RDWR)
1468 {
1469 sff |= SFF_CREAT;
1367 if (!bitset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
1470 if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
1368 sff |= SFF_NOSLINK;
1471 sff |= SFF_NOSLINK;
1369 if (!bitset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
1472 if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
1370 sff |= SFF_NOHLINK;
1371 smode = S_IWRITE;
1372 }
1373 else
1374 {
1473 sff |= SFF_NOHLINK;
1474 smode = S_IWRITE;
1475 }
1476 else
1477 {
1375 if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
1478 if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
1376 sff |= SFF_NOWLINK;
1377 }
1479 sff |= SFF_NOWLINK;
1480 }
1378 if (!bitset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
1481 if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
1379 sff |= SFF_SAFEDIRPATH;
1380 i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
1482 sff |= SFF_SAFEDIRPATH;
1483 i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
1484
1485# if !_FFR_REMOVE_AUTOREBUILD
1381 if (i == ENOENT && AutoRebuild &&
1382 bitset(MCF_REBUILDABLE, map->map_class->map_cflags) &&
1383 (bitset(MF_IMPL_HASH, map->map_mflags) ||
1384 bitset(MF_ALIAS, map->map_mflags)) &&
1385 mode == O_RDONLY)
1386 {
1387 bool impl = bitset(MF_IMPL_HASH, map->map_mflags);
1486 if (i == ENOENT && AutoRebuild &&
1487 bitset(MCF_REBUILDABLE, map->map_class->map_cflags) &&
1488 (bitset(MF_IMPL_HASH, map->map_mflags) ||
1489 bitset(MF_ALIAS, map->map_mflags)) &&
1490 mode == O_RDONLY)
1491 {
1492 bool impl = bitset(MF_IMPL_HASH, map->map_mflags);
1388 extern bool impl_map_open __P((MAP *, int));
1389
1390 /* may be able to rebuild */
1391 map->map_mflags &= ~MF_IMPL_HASH;
1392 if (!rebuildaliases(map, TRUE))
1393 return FALSE;
1394 if (impl)
1395 return impl_map_open(map, O_RDONLY);
1396 else
1397 return db_map_open(map, O_RDONLY, mapclassname,
1398 dbtype, openinfo);
1399 }
1493
1494 /* may be able to rebuild */
1495 map->map_mflags &= ~MF_IMPL_HASH;
1496 if (!rebuildaliases(map, TRUE))
1497 return FALSE;
1498 if (impl)
1499 return impl_map_open(map, O_RDONLY);
1500 else
1501 return db_map_open(map, O_RDONLY, mapclassname,
1502 dbtype, openinfo);
1503 }
1504# endif /* !_FFR_REMOVE_AUTOREBUILD */
1400
1401 if (i != 0)
1402 {
1403 char *prob = "unsafe";
1404
1405 /* cannot open this map */
1406 if (i == ENOENT)
1407 prob = "missing";
1408 if (tTd(38, 2))
1505
1506 if (i != 0)
1507 {
1508 char *prob = "unsafe";
1509
1510 /* cannot open this map */
1511 if (i == ENOENT)
1512 prob = "missing";
1513 if (tTd(38, 2))
1409 printf("\t%s map file: %s\n", prob, errstring(i));
1514 dprintf("\t%s map file: %s\n", prob, errstring(i));
1410 errno = i;
1411 if (!bitset(MF_OPTIONAL, map->map_mflags))
1412 syserr("%s map \"%s\": %s map file %s",
1413 mapclassname, map->map_mname, prob, buf);
1414 return FALSE;
1415 }
1416 if (st.st_mode == ST_MODE_NOFILE)
1417 omode |= O_CREAT|O_EXCL;
1418
1419 map->map_lockfd = -1;
1420
1515 errno = i;
1516 if (!bitset(MF_OPTIONAL, map->map_mflags))
1517 syserr("%s map \"%s\": %s map file %s",
1518 mapclassname, map->map_mname, prob, buf);
1519 return FALSE;
1520 }
1521 if (st.st_mode == ST_MODE_NOFILE)
1522 omode |= O_CREAT|O_EXCL;
1523
1524 map->map_lockfd = -1;
1525
1421#if LOCK_ON_OPEN
1526# if LOCK_ON_OPEN
1422 if (mode == O_RDWR)
1423 omode |= O_TRUNC|O_EXLOCK;
1424 else
1425 omode |= O_SHLOCK;
1527 if (mode == O_RDWR)
1528 omode |= O_TRUNC|O_EXLOCK;
1529 else
1530 omode |= O_SHLOCK;
1426#else
1531# else /* LOCK_ON_OPEN */
1427 /*
1428 ** Pre-lock the file to avoid race conditions. In particular,
1429 ** since dbopen returns NULL if the file is zero length, we
1430 ** must have a locked instance around the dbopen.
1431 */
1432
1433 fd = open(buf, omode, DBMMODE);
1434 if (fd < 0)
1435 {
1436 if (!bitset(MF_OPTIONAL, map->map_mflags))
1437 syserr("db_map_open: cannot pre-open database %s", buf);
1438 return FALSE;
1439 }
1440
1441 /* make sure no baddies slipped in just before the open... */
1442 if (filechanged(buf, fd, &st))
1443 {
1532 /*
1533 ** Pre-lock the file to avoid race conditions. In particular,
1534 ** since dbopen returns NULL if the file is zero length, we
1535 ** must have a locked instance around the dbopen.
1536 */
1537
1538 fd = open(buf, omode, DBMMODE);
1539 if (fd < 0)
1540 {
1541 if (!bitset(MF_OPTIONAL, map->map_mflags))
1542 syserr("db_map_open: cannot pre-open database %s", buf);
1543 return FALSE;
1544 }
1545
1546 /* make sure no baddies slipped in just before the open... */
1547 if (filechanged(buf, fd, &st))
1548 {
1444 int save_errno = errno;
1445
1549 save_errno = errno;
1446 (void) close(fd);
1447 errno = save_errno;
1448 syserr("db_map_open(%s): file changed after pre-open", buf);
1449 return FALSE;
1450 }
1451
1452 /* if new file, get the "before" bits for later filechanged check */
1453 if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0)
1454 {
1550 (void) close(fd);
1551 errno = save_errno;
1552 syserr("db_map_open(%s): file changed after pre-open", buf);
1553 return FALSE;
1554 }
1555
1556 /* if new file, get the "before" bits for later filechanged check */
1557 if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0)
1558 {
1455 int save_errno = errno;
1456
1559 save_errno = errno;
1457 (void) close(fd);
1458 errno = save_errno;
1459 syserr("db_map_open(%s): cannot fstat pre-opened file",
1460 buf);
1461 return FALSE;
1462 }
1463
1464 /* actually lock the pre-opened file */
1465 if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
1466 syserr("db_map_open: cannot lock %s", buf);
1467
1468 /* set up mode bits for dbopen */
1469 if (mode == O_RDWR)
1470 omode |= O_TRUNC;
1471 omode &= ~(O_EXCL|O_CREAT);
1560 (void) close(fd);
1561 errno = save_errno;
1562 syserr("db_map_open(%s): cannot fstat pre-opened file",
1563 buf);
1564 return FALSE;
1565 }
1566
1567 /* actually lock the pre-opened file */
1568 if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
1569 syserr("db_map_open: cannot lock %s", buf);
1570
1571 /* set up mode bits for dbopen */
1572 if (mode == O_RDWR)
1573 omode |= O_TRUNC;
1574 omode &= ~(O_EXCL|O_CREAT);
1472#endif
1575# endif /* LOCK_ON_OPEN */
1473
1576
1474#if DB_VERSION_MAJOR < 2
1577# if DB_VERSION_MAJOR < 2
1475 db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
1578 db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
1476#else
1579# else /* DB_VERSION_MAJOR < 2 */
1477 {
1478 int flags = 0;
1580 {
1581 int flags = 0;
1582# if DB_VERSION_MAJOR > 2
1583 int ret;
1584# endif /* DB_VERSION_MAJOR > 2 */
1479
1480 if (mode == O_RDONLY)
1481 flags |= DB_RDONLY;
1482 if (bitset(O_CREAT, omode))
1483 flags |= DB_CREATE;
1484 if (bitset(O_TRUNC, omode))
1485 flags |= DB_TRUNCATE;
1486
1585
1586 if (mode == O_RDONLY)
1587 flags |= DB_RDONLY;
1588 if (bitset(O_CREAT, omode))
1589 flags |= DB_CREATE;
1590 if (bitset(O_TRUNC, omode))
1591 flags |= DB_TRUNCATE;
1592
1593# if !HASFLOCK && defined(DB_FCNTL_LOCKING)
1594 flags |= DB_FCNTL_LOCKING;
1595# endif /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */
1596
1597# if DB_VERSION_MAJOR > 2
1598 ret = db_create(&db, NULL, 0);
1599# ifdef DB_CACHE_SIZE
1600 if (ret == 0 && db != NULL)
1601 {
1602 ret = db->set_cachesize(db, 0, DB_CACHE_SIZE, 0);
1603 if (ret != 0)
1604 {
1605 (void) db->close(db, 0);
1606 db = NULL;
1607 }
1608 }
1609# endif /* DB_CACHE_SIZE */
1610# ifdef DB_HASH_NELEM
1611 if (dbtype == DB_HASH && ret == 0 && db != NULL)
1612 {
1613 ret = db->set_h_nelem(db, DB_HASH_NELEM);
1614 if (ret != 0)
1615 {
1616 (void) db->close(db, 0);
1617 db = NULL;
1618 }
1619 }
1620# endif /* DB_HASH_NELEM */
1621 if (ret == 0 && db != NULL)
1622 {
1623 ret = db->open(db, buf, NULL, dbtype, flags, DBMMODE);
1624 if (ret != 0)
1625 {
1626 (void) db->close(db, 0);
1627 db = NULL;
1628 }
1629 }
1630 errno = ret;
1631# else /* DB_VERSION_MAJOR > 2 */
1487 errno = db_open(buf, dbtype, flags, DBMMODE,
1488 NULL, openinfo, &db);
1632 errno = db_open(buf, dbtype, flags, DBMMODE,
1633 NULL, openinfo, &db);
1634# endif /* DB_VERSION_MAJOR > 2 */
1489 }
1635 }
1490#endif
1491 saveerrno = errno;
1636# endif /* DB_VERSION_MAJOR < 2 */
1637 save_errno = errno;
1492
1638
1493#if !LOCK_ON_OPEN
1639# if !LOCK_ON_OPEN
1494 if (mode == O_RDWR)
1495 map->map_lockfd = fd;
1496 else
1497 (void) close(fd);
1640 if (mode == O_RDWR)
1641 map->map_lockfd = fd;
1642 else
1643 (void) close(fd);
1498#endif
1644# endif /* !LOCK_ON_OPEN */
1499
1500 if (db == NULL)
1501 {
1502 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
1503 aliaswait(map, ".db", FALSE))
1504 return TRUE;
1645
1646 if (db == NULL)
1647 {
1648 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
1649 aliaswait(map, ".db", FALSE))
1650 return TRUE;
1505#if !LOCK_ON_OPEN
1651# if !LOCK_ON_OPEN
1506 if (map->map_lockfd >= 0)
1507 (void) close(map->map_lockfd);
1652 if (map->map_lockfd >= 0)
1653 (void) close(map->map_lockfd);
1508#endif
1509 errno = saveerrno;
1654# endif /* !LOCK_ON_OPEN */
1655 errno = save_errno;
1510 if (!bitset(MF_OPTIONAL, map->map_mflags))
1511 syserr("Cannot open %s database %s",
1512 mapclassname, buf);
1513 return FALSE;
1514 }
1515
1656 if (!bitset(MF_OPTIONAL, map->map_mflags))
1657 syserr("Cannot open %s database %s",
1658 mapclassname, buf);
1659 return FALSE;
1660 }
1661
1516#if DB_VERSION_MAJOR < 2
1662# if DB_VERSION_MAJOR < 2
1517 fd = db->fd(db);
1663 fd = db->fd(db);
1518#else
1664# else /* DB_VERSION_MAJOR < 2 */
1519 fd = -1;
1520 errno = db->fd(db, &fd);
1665 fd = -1;
1666 errno = db->fd(db, &fd);
1521#endif
1667# endif /* DB_VERSION_MAJOR < 2 */
1522 if (filechanged(buf, fd, &st))
1523 {
1668 if (filechanged(buf, fd, &st))
1669 {
1524 int save_errno = errno;
1525
1526#if DB_VERSION_MAJOR < 2
1527 db->close(db);
1528#else
1670 save_errno = errno;
1671# if DB_VERSION_MAJOR < 2
1672 (void) db->close(db);
1673# else /* DB_VERSION_MAJOR < 2 */
1529 errno = db->close(db, 0);
1674 errno = db->close(db, 0);
1530#endif
1531#if !LOCK_ON_OPEN
1675# endif /* DB_VERSION_MAJOR < 2 */
1676# if !LOCK_ON_OPEN
1532 if (map->map_lockfd >= 0)
1677 if (map->map_lockfd >= 0)
1533 close(map->map_lockfd);
1534#endif
1678 (void) close(map->map_lockfd);
1679# endif /* !LOCK_ON_OPEN */
1535 errno = save_errno;
1536 syserr("db_map_open(%s): file changed after open", buf);
1537 return FALSE;
1538 }
1539
1540 if (mode == O_RDWR)
1541 map->map_mflags |= MF_LOCKED;
1680 errno = save_errno;
1681 syserr("db_map_open(%s): file changed after open", buf);
1682 return FALSE;
1683 }
1684
1685 if (mode == O_RDWR)
1686 map->map_mflags |= MF_LOCKED;
1542#if LOCK_ON_OPEN
1687# if LOCK_ON_OPEN
1543 if (fd >= 0 && mode == O_RDONLY)
1544 {
1545 (void) lockfile(fd, buf, NULL, LOCK_UN);
1546 }
1688 if (fd >= 0 && mode == O_RDONLY)
1689 {
1690 (void) lockfile(fd, buf, NULL, LOCK_UN);
1691 }
1547#endif
1692# endif /* LOCK_ON_OPEN */
1548
1549 /* try to make sure that at least the database header is on disk */
1550 if (mode == O_RDWR)
1551 {
1552 (void) db->sync(db, 0);
1693
1694 /* try to make sure that at least the database header is on disk */
1695 if (mode == O_RDWR)
1696 {
1697 (void) db->sync(db, 0);
1553#if _FFR_TRUSTED_USER
1554 if (geteuid() == 0 && TrustedUid != 0)
1555 {
1698 if (geteuid() == 0 && TrustedUid != 0)
1699 {
1700# if HASFCHOWN
1556 if (fchown(fd, TrustedUid, -1) < 0)
1557 {
1558 int err = errno;
1559
1560 sm_syslog(LOG_ALERT, NOQID,
1561 "ownership change on %s failed: %s",
1562 buf, errstring(err));
1563 message("050 ownership change on %s failed: %s",
1564 buf, errstring(err));
1565 }
1701 if (fchown(fd, TrustedUid, -1) < 0)
1702 {
1703 int err = errno;
1704
1705 sm_syslog(LOG_ALERT, NOQID,
1706 "ownership change on %s failed: %s",
1707 buf, errstring(err));
1708 message("050 ownership change on %s failed: %s",
1709 buf, errstring(err));
1710 }
1711# endif /* HASFCHOWN */
1566 }
1712 }
1567#endif
1568 }
1569
1713 }
1714
1715 map->map_db2 = (ARBPTR_T) db;
1716
1717 /*
1718 ** Need to set map_mtime before the call to aliaswait()
1719 ** as aliaswait() will call map_lookup() which requires
1720 ** map_mtime to be set
1721 */
1722
1570 if (fd >= 0 && fstat(fd, &st) >= 0)
1571 map->map_mtime = st.st_mtime;
1572
1723 if (fd >= 0 && fstat(fd, &st) >= 0)
1724 map->map_mtime = st.st_mtime;
1725
1573 map->map_db2 = (ARBPTR_T) db;
1574 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
1575 !aliaswait(map, ".db", TRUE))
1576 return FALSE;
1577 return TRUE;
1578}
1579
1580
1581/*

--- 6 unchanged lines hidden (view full) ---

1588 char *name;
1589 char **av;
1590 int *statp;
1591{
1592 DBT key, val;
1593 register DB *db = (DB *) map->map_db2;
1594 int i;
1595 int st;
1726 if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
1727 !aliaswait(map, ".db", TRUE))
1728 return FALSE;
1729 return TRUE;
1730}
1731
1732
1733/*

--- 6 unchanged lines hidden (view full) ---

1740 char *name;
1741 char **av;
1742 int *statp;
1743{
1744 DBT key, val;
1745 register DB *db = (DB *) map->map_db2;
1746 int i;
1747 int st;
1596 int saveerrno;
1748 int save_errno;
1597 int fd;
1598 struct stat stbuf;
1599 char keybuf[MAXNAME + 1];
1600 char buf[MAXNAME + 1];
1601
1749 int fd;
1750 struct stat stbuf;
1751 char keybuf[MAXNAME + 1];
1752 char buf[MAXNAME + 1];
1753
1602 bzero(&key, sizeof key);
1603 bzero(&val, sizeof val);
1754 memset(&key, '\0', sizeof key);
1755 memset(&val, '\0', sizeof val);
1604
1605 if (tTd(38, 20))
1756
1757 if (tTd(38, 20))
1606 printf("db_map_lookup(%s, %s)\n",
1758 dprintf("db_map_lookup(%s, %s)\n",
1607 map->map_mname, name);
1608
1609 i = strlen(map->map_file);
1610 if (i > MAXNAME)
1611 i = MAXNAME;
1759 map->map_mname, name);
1760
1761 i = strlen(map->map_file);
1762 if (i > MAXNAME)
1763 i = MAXNAME;
1612 strncpy(buf, map->map_file, i);
1613 buf[i] = '\0';
1764 (void) strlcpy(buf, map->map_file, i + 1);
1614 if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
1615 buf[i - 3] = '\0';
1616
1617 key.size = strlen(name);
1618 if (key.size > sizeof keybuf - 1)
1619 key.size = sizeof keybuf - 1;
1620 key.data = keybuf;
1765 if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
1766 buf[i - 3] = '\0';
1767
1768 key.size = strlen(name);
1769 if (key.size > sizeof keybuf - 1)
1770 key.size = sizeof keybuf - 1;
1771 key.data = keybuf;
1621 bcopy(name, keybuf, key.size);
1772 memmove(keybuf, name, key.size);
1622 keybuf[key.size] = '\0';
1623 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1624 makelower(keybuf);
1625 lockdb:
1773 keybuf[key.size] = '\0';
1774 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1775 makelower(keybuf);
1776 lockdb:
1626#if DB_VERSION_MAJOR < 2
1777# if DB_VERSION_MAJOR < 2
1627 fd = db->fd(db);
1778 fd = db->fd(db);
1628#else
1779# else /* DB_VERSION_MAJOR < 2 */
1629 fd = -1;
1630 errno = db->fd(db, &fd);
1780 fd = -1;
1781 errno = db->fd(db, &fd);
1631#endif
1782# endif /* DB_VERSION_MAJOR < 2 */
1632 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1633 (void) lockfile(fd, buf, ".db", LOCK_SH);
1634 if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
1635 {
1636 /* Reopen the database to sync the cache */
1637 int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
1638 : O_RDONLY;
1639
1783 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1784 (void) lockfile(fd, buf, ".db", LOCK_SH);
1785 if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
1786 {
1787 /* Reopen the database to sync the cache */
1788 int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
1789 : O_RDONLY;
1790
1791 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1792 (void) lockfile(fd, buf, ".db", LOCK_UN);
1640 map->map_class->map_close(map);
1641 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
1642 if (map->map_class->map_open(map, omode))
1643 {
1644 map->map_mflags |= MF_OPEN;
1645 map->map_pid = getpid();
1646 if ((omode && O_ACCMODE) == O_RDWR)
1647 map->map_mflags |= MF_WRITABLE;

--- 15 unchanged lines hidden (view full) ---

1663 }
1664 return NULL;
1665 }
1666 }
1667
1668 st = 1;
1669 if (bitset(MF_TRY0NULL, map->map_mflags))
1670 {
1793 map->map_class->map_close(map);
1794 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
1795 if (map->map_class->map_open(map, omode))
1796 {
1797 map->map_mflags |= MF_OPEN;
1798 map->map_pid = getpid();
1799 if ((omode && O_ACCMODE) == O_RDWR)
1800 map->map_mflags |= MF_WRITABLE;

--- 15 unchanged lines hidden (view full) ---

1816 }
1817 return NULL;
1818 }
1819 }
1820
1821 st = 1;
1822 if (bitset(MF_TRY0NULL, map->map_mflags))
1823 {
1671#if DB_VERSION_MAJOR < 2
1824# if DB_VERSION_MAJOR < 2
1672 st = db->get(db, &key, &val, 0);
1825 st = db->get(db, &key, &val, 0);
1673#else
1826# else /* DB_VERSION_MAJOR < 2 */
1674 errno = db->get(db, NULL, &key, &val, 0);
1675 switch (errno)
1676 {
1677 case DB_NOTFOUND:
1678 case DB_KEYEMPTY:
1679 st = 1;
1680 break;
1681
1682 case 0:
1683 st = 0;
1684 break;
1685
1686 default:
1687 st = -1;
1688 break;
1689 }
1827 errno = db->get(db, NULL, &key, &val, 0);
1828 switch (errno)
1829 {
1830 case DB_NOTFOUND:
1831 case DB_KEYEMPTY:
1832 st = 1;
1833 break;
1834
1835 case 0:
1836 st = 0;
1837 break;
1838
1839 default:
1840 st = -1;
1841 break;
1842 }
1690#endif
1843# endif /* DB_VERSION_MAJOR < 2 */
1691 if (st == 0)
1692 map->map_mflags &= ~MF_TRY1NULL;
1693 }
1694 if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
1695 {
1696 key.size++;
1844 if (st == 0)
1845 map->map_mflags &= ~MF_TRY1NULL;
1846 }
1847 if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
1848 {
1849 key.size++;
1697#if DB_VERSION_MAJOR < 2
1850# if DB_VERSION_MAJOR < 2
1698 st = db->get(db, &key, &val, 0);
1851 st = db->get(db, &key, &val, 0);
1699#else
1852# else /* DB_VERSION_MAJOR < 2 */
1700 errno = db->get(db, NULL, &key, &val, 0);
1701 switch (errno)
1702 {
1703 case DB_NOTFOUND:
1704 case DB_KEYEMPTY:
1705 st = 1;
1706 break;
1707
1708 case 0:
1709 st = 0;
1710 break;
1711
1712 default:
1713 st = -1;
1714 break;
1715 }
1853 errno = db->get(db, NULL, &key, &val, 0);
1854 switch (errno)
1855 {
1856 case DB_NOTFOUND:
1857 case DB_KEYEMPTY:
1858 st = 1;
1859 break;
1860
1861 case 0:
1862 st = 0;
1863 break;
1864
1865 default:
1866 st = -1;
1867 break;
1868 }
1716#endif
1869# endif /* DB_VERSION_MAJOR < 2 */
1717 if (st == 0)
1718 map->map_mflags &= ~MF_TRY0NULL;
1719 }
1870 if (st == 0)
1871 map->map_mflags &= ~MF_TRY0NULL;
1872 }
1720 saveerrno = errno;
1873 save_errno = errno;
1721 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1722 (void) lockfile(fd, buf, ".db", LOCK_UN);
1723 if (st != 0)
1724 {
1874 if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
1875 (void) lockfile(fd, buf, ".db", LOCK_UN);
1876 if (st != 0)
1877 {
1725 errno = saveerrno;
1878 errno = save_errno;
1726 if (st < 0)
1727 syserr("db_map_lookup: get (%s)", name);
1728 return NULL;
1729 }
1730 if (bitset(MF_MATCHONLY, map->map_mflags))
1731 return map_rewrite(map, name, strlen(name), NULL);
1732 else
1733 return map_rewrite(map, val.data, val.size, av);

--- 5 unchanged lines hidden (view full) ---

1739*/
1740
1741void
1742db_map_store(map, lhs, rhs)
1743 register MAP *map;
1744 char *lhs;
1745 char *rhs;
1746{
1879 if (st < 0)
1880 syserr("db_map_lookup: get (%s)", name);
1881 return NULL;
1882 }
1883 if (bitset(MF_MATCHONLY, map->map_mflags))
1884 return map_rewrite(map, name, strlen(name), NULL);
1885 else
1886 return map_rewrite(map, val.data, val.size, av);

--- 5 unchanged lines hidden (view full) ---

1892*/
1893
1894void
1895db_map_store(map, lhs, rhs)
1896 register MAP *map;
1897 char *lhs;
1898 char *rhs;
1899{
1747 int stat;
1900 int status;
1748 DBT key;
1749 DBT data;
1750 register DB *db = map->map_db2;
1751 char keybuf[MAXNAME + 1];
1752
1901 DBT key;
1902 DBT data;
1903 register DB *db = map->map_db2;
1904 char keybuf[MAXNAME + 1];
1905
1753 bzero(&key, sizeof key);
1754 bzero(&data, sizeof data);
1906 memset(&key, '\0', sizeof key);
1907 memset(&data, '\0', sizeof data);
1755
1756 if (tTd(38, 12))
1908
1909 if (tTd(38, 12))
1757 printf("db_map_store(%s, %s, %s)\n",
1910 dprintf("db_map_store(%s, %s, %s)\n",
1758 map->map_mname, lhs, rhs);
1759
1760 key.size = strlen(lhs);
1761 key.data = lhs;
1762 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1763 {
1764 if (key.size > sizeof keybuf - 1)
1765 key.size = sizeof keybuf - 1;
1911 map->map_mname, lhs, rhs);
1912
1913 key.size = strlen(lhs);
1914 key.data = lhs;
1915 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1916 {
1917 if (key.size > sizeof keybuf - 1)
1918 key.size = sizeof keybuf - 1;
1766 bcopy(key.data, keybuf, key.size);
1919 memmove(keybuf, key.data, key.size);
1767 keybuf[key.size] = '\0';
1768 makelower(keybuf);
1769 key.data = keybuf;
1770 }
1771
1772 data.size = strlen(rhs);
1773 data.data = rhs;
1774
1775 if (bitset(MF_INCLNULL, map->map_mflags))
1776 {
1777 key.size++;
1778 data.size++;
1779 }
1780
1920 keybuf[key.size] = '\0';
1921 makelower(keybuf);
1922 key.data = keybuf;
1923 }
1924
1925 data.size = strlen(rhs);
1926 data.data = rhs;
1927
1928 if (bitset(MF_INCLNULL, map->map_mflags))
1929 {
1930 key.size++;
1931 data.size++;
1932 }
1933
1781#if DB_VERSION_MAJOR < 2
1782 stat = db->put(db, &key, &data, R_NOOVERWRITE);
1783#else
1934# if DB_VERSION_MAJOR < 2
1935 status = db->put(db, &key, &data, R_NOOVERWRITE);
1936# else /* DB_VERSION_MAJOR < 2 */
1784 errno = db->put(db, NULL, &key, &data, DB_NOOVERWRITE);
1785 switch (errno)
1786 {
1787 case DB_KEYEXIST:
1937 errno = db->put(db, NULL, &key, &data, DB_NOOVERWRITE);
1938 switch (errno)
1939 {
1940 case DB_KEYEXIST:
1788 stat = 1;
1941 status = 1;
1789 break;
1790
1791 case 0:
1942 break;
1943
1944 case 0:
1792 stat = 0;
1945 status = 0;
1793 break;
1794
1795 default:
1946 break;
1947
1948 default:
1796 stat = -1;
1949 status = -1;
1797 break;
1798 }
1950 break;
1951 }
1799#endif
1800 if (stat > 0)
1952# endif /* DB_VERSION_MAJOR < 2 */
1953 if (status > 0)
1801 {
1802 if (!bitset(MF_APPEND, map->map_mflags))
1803 message("050 Warning: duplicate alias name %s", lhs);
1804 else
1805 {
1806 static char *buf = NULL;
1807 static int bufsiz = 0;
1808 DBT old;
1809
1954 {
1955 if (!bitset(MF_APPEND, map->map_mflags))
1956 message("050 Warning: duplicate alias name %s", lhs);
1957 else
1958 {
1959 static char *buf = NULL;
1960 static int bufsiz = 0;
1961 DBT old;
1962
1810 bzero(&old, sizeof old);
1963 memset(&old, '\0', sizeof old);
1811
1964
1812 old.data = db_map_lookup(map, key.data,
1813 (char **)NULL, &stat);
1965 old.data = db_map_lookup(map, key.data,
1966 (char **)NULL, &status);
1814 if (old.data != NULL)
1815 {
1816 old.size = strlen(old.data);
1967 if (old.data != NULL)
1968 {
1969 old.size = strlen(old.data);
1817 if (data.size + old.size + 2 > bufsiz)
1970 if (data.size + old.size + 2 > (size_t)bufsiz)
1818 {
1819 if (buf != NULL)
1820 (void) free(buf);
1821 bufsiz = data.size + old.size + 2;
1822 buf = xalloc(bufsiz);
1823 }
1824 snprintf(buf, bufsiz, "%s,%s",
1825 (char *) data.data, (char *) old.data);
1826 data.size = data.size + old.size + 1;
1827 data.data = buf;
1828 if (tTd(38, 9))
1971 {
1972 if (buf != NULL)
1973 (void) free(buf);
1974 bufsiz = data.size + old.size + 2;
1975 buf = xalloc(bufsiz);
1976 }
1977 snprintf(buf, bufsiz, "%s,%s",
1978 (char *) data.data, (char *) old.data);
1979 data.size = data.size + old.size + 1;
1980 data.data = buf;
1981 if (tTd(38, 9))
1829 printf("db_map_store append=%s\n",
1830 (char *) data.data);
1982 dprintf("db_map_store append=%s\n",
1983 (char *) data.data);
1831 }
1832 }
1984 }
1985 }
1833#if DB_VERSION_MAJOR < 2
1834 stat = db->put(db, &key, &data, 0);
1835#else
1836 stat = errno = db->put(db, NULL, &key, &data, 0);
1837#endif
1986# if DB_VERSION_MAJOR < 2
1987 status = db->put(db, &key, &data, 0);
1988# else /* DB_VERSION_MAJOR < 2 */
1989 status = errno = db->put(db, NULL, &key, &data, 0);
1990# endif /* DB_VERSION_MAJOR < 2 */
1838 }
1991 }
1839 if (stat != 0)
1992 if (status != 0)
1840 syserr("readaliases: db put (%s)", lhs);
1841}
1842
1843
1844/*
1845** DB_MAP_CLOSE -- add distinguished entries and close the database
1846*/
1847
1848void
1849db_map_close(map)
1850 MAP *map;
1851{
1852 register DB *db = map->map_db2;
1853
1854 if (tTd(38, 9))
1993 syserr("readaliases: db put (%s)", lhs);
1994}
1995
1996
1997/*
1998** DB_MAP_CLOSE -- add distinguished entries and close the database
1999*/
2000
2001void
2002db_map_close(map)
2003 MAP *map;
2004{
2005 register DB *db = map->map_db2;
2006
2007 if (tTd(38, 9))
1855 printf("db_map_close(%s, %s, %lx)\n",
2008 dprintf("db_map_close(%s, %s, %lx)\n",
1856 map->map_mname, map->map_file, map->map_mflags);
1857
1858 if (bitset(MF_WRITABLE, map->map_mflags))
1859 {
1860 /* write out the distinguished alias */
1861 db_map_store(map, "@", "@");
1862 }
1863
1864 (void) db->sync(db, 0);
1865
2009 map->map_mname, map->map_file, map->map_mflags);
2010
2011 if (bitset(MF_WRITABLE, map->map_mflags))
2012 {
2013 /* write out the distinguished alias */
2014 db_map_store(map, "@", "@");
2015 }
2016
2017 (void) db->sync(db, 0);
2018
1866#if !LOCK_ON_OPEN
2019# if !LOCK_ON_OPEN
1867 if (map->map_lockfd >= 0)
1868 (void) close(map->map_lockfd);
2020 if (map->map_lockfd >= 0)
2021 (void) close(map->map_lockfd);
1869#endif
2022# endif /* !LOCK_ON_OPEN */
1870
2023
1871#if DB_VERSION_MAJOR < 2
2024# if DB_VERSION_MAJOR < 2
1872 if (db->close(db) != 0)
2025 if (db->close(db) != 0)
1873#else
2026# else /* DB_VERSION_MAJOR < 2 */
1874 /*
1875 ** Berkeley DB can use internal shared memory
1876 ** locking for its memory pool. Closing a map
1877 ** opened by another process will interfere
1878 ** with the shared memory and locks of the parent
1879 ** process leaving things in a bad state.
1880 */
1881

--- 8 unchanged lines hidden (view full) ---

1890
1891 errno = db->fd(db, &fd);
1892 if (fd >= 0)
1893 (void) close(fd);
1894 return;
1895 }
1896
1897 if ((errno = db->close(db, 0)) != 0)
2027 /*
2028 ** Berkeley DB can use internal shared memory
2029 ** locking for its memory pool. Closing a map
2030 ** opened by another process will interfere
2031 ** with the shared memory and locks of the parent
2032 ** process leaving things in a bad state.
2033 */
2034

--- 8 unchanged lines hidden (view full) ---

2043
2044 errno = db->fd(db, &fd);
2045 if (fd >= 0)
2046 (void) close(fd);
2047 return;
2048 }
2049
2050 if ((errno = db->close(db, 0)) != 0)
1898#endif
2051# endif /* DB_VERSION_MAJOR < 2 */
1899 syserr("db_map_close(%s, %s, %lx): db close failure",
1900 map->map_mname, map->map_file, map->map_mflags);
1901}
2052 syserr("db_map_close(%s, %s, %lx): db close failure",
2053 map->map_mname, map->map_file, map->map_mflags);
2054}
1902
1903#endif
2055#endif /* NEWDB */
1904 /*
1905** NIS Modules
1906*/
1907
2056 /*
2057** NIS Modules
2058*/
2059
1908# ifdef NIS
2060#ifdef NIS
1909
1910# ifndef YPERR_BUSY
1911# define YPERR_BUSY 16
2061
2062# ifndef YPERR_BUSY
2063# define YPERR_BUSY 16
1912# endif
2064# endif /* ! YPERR_BUSY */
1913
1914/*
1915** NIS_MAP_OPEN -- open DBM map
1916*/
1917
1918bool
1919nis_map_open(map, mode)
1920 MAP *map;
1921 int mode;
1922{
1923 int yperr;
1924 register char *p;
1925 auto char *vp;
1926 auto int vsize;
1927
1928 if (tTd(38, 2))
2065
2066/*
2067** NIS_MAP_OPEN -- open DBM map
2068*/
2069
2070bool
2071nis_map_open(map, mode)
2072 MAP *map;
2073 int mode;
2074{
2075 int yperr;
2076 register char *p;
2077 auto char *vp;
2078 auto int vsize;
2079
2080 if (tTd(38, 2))
1929 printf("nis_map_open(%s, %s, %d)\n",
2081 dprintf("nis_map_open(%s, %s, %d)\n",
1930 map->map_mname, map->map_file, mode);
1931
1932 mode &= O_ACCMODE;
1933 if (mode != O_RDONLY)
1934 {
1935 /* issue a pseudo-error message */
2082 map->map_mname, map->map_file, mode);
2083
2084 mode &= O_ACCMODE;
2085 if (mode != O_RDONLY)
2086 {
2087 /* issue a pseudo-error message */
1936#ifdef ENOSYS
2088# ifdef ENOSYS
1937 errno = ENOSYS;
2089 errno = ENOSYS;
1938#else
1939# ifdef EFTYPE
2090# else /* ENOSYS */
2091# ifdef EFTYPE
1940 errno = EFTYPE;
2092 errno = EFTYPE;
1941# else
2093# else /* EFTYPE */
1942 errno = ENXIO;
2094 errno = ENXIO;
1943# endif
1944#endif
2095# endif /* EFTYPE */
2096# endif /* ENOSYS */
1945 return FALSE;
1946 }
1947
1948 p = strchr(map->map_file, '@');
1949 if (p != NULL)
1950 {
1951 *p++ = '\0';
1952 if (*p != '\0')

--- 4 unchanged lines hidden (view full) ---

1957 map->map_file = "mail.aliases";
1958
1959 if (map->map_domain == NULL)
1960 {
1961 yperr = yp_get_default_domain(&map->map_domain);
1962 if (yperr != 0)
1963 {
1964 if (!bitset(MF_OPTIONAL, map->map_mflags))
2097 return FALSE;
2098 }
2099
2100 p = strchr(map->map_file, '@');
2101 if (p != NULL)
2102 {
2103 *p++ = '\0';
2104 if (*p != '\0')

--- 4 unchanged lines hidden (view full) ---

2109 map->map_file = "mail.aliases";
2110
2111 if (map->map_domain == NULL)
2112 {
2113 yperr = yp_get_default_domain(&map->map_domain);
2114 if (yperr != 0)
2115 {
2116 if (!bitset(MF_OPTIONAL, map->map_mflags))
1965 syserr("421 NIS map %s specified, but NIS not running",
1966 map->map_file);
2117 syserr("421 4.3.5 NIS map %s specified, but NIS not running",
2118 map->map_file);
1967 return FALSE;
1968 }
1969 }
1970
1971 /* check to see if this map actually exists */
2119 return FALSE;
2120 }
2121 }
2122
2123 /* check to see if this map actually exists */
2124 vp = NULL;
1972 yperr = yp_match(map->map_domain, map->map_file, "@", 1,
1973 &vp, &vsize);
1974 if (tTd(38, 10))
2125 yperr = yp_match(map->map_domain, map->map_file, "@", 1,
2126 &vp, &vsize);
2127 if (tTd(38, 10))
1975 printf("nis_map_open: yp_match(@, %s, %s) => %s\n",
2128 dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n",
1976 map->map_domain, map->map_file, yperr_string(yperr));
2129 map->map_domain, map->map_file, yperr_string(yperr));
2130 if (vp != NULL)
2131 free(vp);
2132
1977 if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
1978 {
1979 /*
1980 ** We ought to be calling aliaswait() here if this is an
1981 ** alias file, but powerful HP-UX NIS servers apparently
1982 ** don't insert the @:@ token into the alias map when it
1983 ** is rebuilt, so aliaswait() just hangs. I hate HP-UX.
1984 */
1985
2133 if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
2134 {
2135 /*
2136 ** We ought to be calling aliaswait() here if this is an
2137 ** alias file, but powerful HP-UX NIS servers apparently
2138 ** don't insert the @:@ token into the alias map when it
2139 ** is rebuilt, so aliaswait() just hangs. I hate HP-UX.
2140 */
2141
1986#if 0
2142# if 0
1987 if (!bitset(MF_ALIAS, map->map_mflags) ||
1988 aliaswait(map, NULL, TRUE))
2143 if (!bitset(MF_ALIAS, map->map_mflags) ||
2144 aliaswait(map, NULL, TRUE))
1989#endif
2145# endif /* 0 */
1990 return TRUE;
1991 }
1992
1993 if (!bitset(MF_OPTIONAL, map->map_mflags))
1994 {
2146 return TRUE;
2147 }
2148
2149 if (!bitset(MF_OPTIONAL, map->map_mflags))
2150 {
1995 syserr("421 Cannot bind to map %s in domain %s: %s",
2151 syserr("421 4.0.0 Cannot bind to map %s in domain %s: %s",
1996 map->map_file, map->map_domain, yperr_string(yperr));
1997 }
1998
1999 return FALSE;
2000}
2001
2002
2003/*

--- 10 unchanged lines hidden (view full) ---

2014{
2015 char *vp;
2016 auto int vsize;
2017 int buflen;
2018 int yperr;
2019 char keybuf[MAXNAME + 1];
2020
2021 if (tTd(38, 20))
2152 map->map_file, map->map_domain, yperr_string(yperr));
2153 }
2154
2155 return FALSE;
2156}
2157
2158
2159/*

--- 10 unchanged lines hidden (view full) ---

2170{
2171 char *vp;
2172 auto int vsize;
2173 int buflen;
2174 int yperr;
2175 char keybuf[MAXNAME + 1];
2176
2177 if (tTd(38, 20))
2022 printf("nis_map_lookup(%s, %s)\n",
2178 dprintf("nis_map_lookup(%s, %s)\n",
2023 map->map_mname, name);
2024
2025 buflen = strlen(name);
2026 if (buflen > sizeof keybuf - 1)
2027 buflen = sizeof keybuf - 1;
2179 map->map_mname, name);
2180
2181 buflen = strlen(name);
2182 if (buflen > sizeof keybuf - 1)
2183 buflen = sizeof keybuf - 1;
2028 bcopy(name, keybuf, buflen);
2184 memmove(keybuf, name, buflen);
2029 keybuf[buflen] = '\0';
2030 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
2031 makelower(keybuf);
2032 yperr = YPERR_KEY;
2185 keybuf[buflen] = '\0';
2186 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
2187 makelower(keybuf);
2188 yperr = YPERR_KEY;
2189 vp = NULL;
2033 if (bitset(MF_TRY0NULL, map->map_mflags))
2034 {
2035 yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
2036 &vp, &vsize);
2037 if (yperr == 0)
2038 map->map_mflags &= ~MF_TRY1NULL;
2039 }
2040 if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
2041 {
2190 if (bitset(MF_TRY0NULL, map->map_mflags))
2191 {
2192 yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
2193 &vp, &vsize);
2194 if (yperr == 0)
2195 map->map_mflags &= ~MF_TRY1NULL;
2196 }
2197 if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
2198 {
2199 if (vp != NULL)
2200 {
2201 free(vp);
2202 vp = NULL;
2203 }
2042 buflen++;
2043 yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
2044 &vp, &vsize);
2045 if (yperr == 0)
2046 map->map_mflags &= ~MF_TRY0NULL;
2047 }
2048 if (yperr != 0)
2049 {
2050 if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
2051 map->map_mflags &= ~(MF_VALID|MF_OPEN);
2204 buflen++;
2205 yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
2206 &vp, &vsize);
2207 if (yperr == 0)
2208 map->map_mflags &= ~MF_TRY0NULL;
2209 }
2210 if (yperr != 0)
2211 {
2212 if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
2213 map->map_mflags &= ~(MF_VALID|MF_OPEN);
2214 if (vp != NULL)
2215 free(vp);
2052 return NULL;
2053 }
2054 if (bitset(MF_MATCHONLY, map->map_mflags))
2055 return map_rewrite(map, name, strlen(name), NULL);
2056 else
2216 return NULL;
2217 }
2218 if (bitset(MF_MATCHONLY, map->map_mflags))
2219 return map_rewrite(map, name, strlen(name), NULL);
2220 else
2057 return map_rewrite(map, vp, vsize, av);
2221 {
2222 char *ret;
2223
2224 ret = map_rewrite(map, vp, vsize, av);
2225 if (vp != NULL)
2226 free(vp);
2227 return ret;
2228 }
2058}
2059
2060
2061/*
2062** NIS_GETCANONNAME -- look up canonical name in NIS
2063*/
2064
2229}
2230
2231
2232/*
2233** NIS_GETCANONNAME -- look up canonical name in NIS
2234*/
2235
2065bool
2236static bool
2066nis_getcanonname(name, hbsize, statp)
2067 char *name;
2068 int hbsize;
2069 int *statp;
2070{
2071 char *vp;
2072 auto int vsize;
2073 int keylen;
2074 int yperr;
2075 static bool try0null = TRUE;
2076 static bool try1null = TRUE;
2077 static char *yp_domain = NULL;
2078 char host_record[MAXLINE];
2079 char cbuf[MAXNAME];
2080 char nbuf[MAXNAME + 1];
2081
2082 if (tTd(38, 20))
2237nis_getcanonname(name, hbsize, statp)
2238 char *name;
2239 int hbsize;
2240 int *statp;
2241{
2242 char *vp;
2243 auto int vsize;
2244 int keylen;
2245 int yperr;
2246 static bool try0null = TRUE;
2247 static bool try1null = TRUE;
2248 static char *yp_domain = NULL;
2249 char host_record[MAXLINE];
2250 char cbuf[MAXNAME];
2251 char nbuf[MAXNAME + 1];
2252
2253 if (tTd(38, 20))
2083 printf("nis_getcanonname(%s)\n", name);
2254 dprintf("nis_getcanonname(%s)\n", name);
2084
2255
2085 if (strlen(name) >= sizeof nbuf)
2256 if (strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
2086 {
2087 *statp = EX_UNAVAILABLE;
2088 return FALSE;
2089 }
2257 {
2258 *statp = EX_UNAVAILABLE;
2259 return FALSE;
2260 }
2090 (void) strcpy(nbuf, name);
2091 shorten_hostname(nbuf);
2092 keylen = strlen(nbuf);
2093
2094 if (yp_domain == NULL)
2261 shorten_hostname(nbuf);
2262 keylen = strlen(nbuf);
2263
2264 if (yp_domain == NULL)
2095 yp_get_default_domain(&yp_domain);
2265 (void) yp_get_default_domain(&yp_domain);
2096 makelower(nbuf);
2097 yperr = YPERR_KEY;
2266 makelower(nbuf);
2267 yperr = YPERR_KEY;
2268 vp = NULL;
2098 if (try0null)
2099 {
2100 yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
2101 &vp, &vsize);
2102 if (yperr == 0)
2103 try1null = FALSE;
2104 }
2105 if (yperr == YPERR_KEY && try1null)
2106 {
2269 if (try0null)
2270 {
2271 yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
2272 &vp, &vsize);
2273 if (yperr == 0)
2274 try1null = FALSE;
2275 }
2276 if (yperr == YPERR_KEY && try1null)
2277 {
2278 if (vp != NULL)
2279 {
2280 free(vp);
2281 vp = NULL;
2282 }
2107 keylen++;
2108 yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
2109 &vp, &vsize);
2110 if (yperr == 0)
2111 try0null = FALSE;
2112 }
2113 if (yperr != 0)
2114 {
2115 if (yperr == YPERR_KEY)
2116 *statp = EX_NOHOST;
2117 else if (yperr == YPERR_BUSY)
2118 *statp = EX_TEMPFAIL;
2119 else
2120 *statp = EX_UNAVAILABLE;
2283 keylen++;
2284 yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
2285 &vp, &vsize);
2286 if (yperr == 0)
2287 try0null = FALSE;
2288 }
2289 if (yperr != 0)
2290 {
2291 if (yperr == YPERR_KEY)
2292 *statp = EX_NOHOST;
2293 else if (yperr == YPERR_BUSY)
2294 *statp = EX_TEMPFAIL;
2295 else
2296 *statp = EX_UNAVAILABLE;
2297 if (vp != NULL)
2298 free(vp);
2121 return FALSE;
2122 }
2299 return FALSE;
2300 }
2123 if (vsize >= sizeof host_record)
2124 vsize = sizeof host_record - 1;
2125 strncpy(host_record, vp, vsize);
2126 host_record[vsize] = '\0';
2301 (void) strlcpy(host_record, vp, sizeof host_record);
2302 free(vp);
2127 if (tTd(38, 44))
2303 if (tTd(38, 44))
2128 printf("got record `%s'\n", host_record);
2304 dprintf("got record `%s'\n", host_record);
2129 if (!extract_canonname(nbuf, host_record, cbuf, sizeof cbuf))
2130 {
2131 /* this should not happen, but.... */
2132 *statp = EX_NOHOST;
2133 return FALSE;
2134 }
2135 if (hbsize < strlen(cbuf))
2136 {
2137 *statp = EX_UNAVAILABLE;
2138 return FALSE;
2139 }
2305 if (!extract_canonname(nbuf, host_record, cbuf, sizeof cbuf))
2306 {
2307 /* this should not happen, but.... */
2308 *statp = EX_NOHOST;
2309 return FALSE;
2310 }
2311 if (hbsize < strlen(cbuf))
2312 {
2313 *statp = EX_UNAVAILABLE;
2314 return FALSE;
2315 }
2140 strcpy(name, cbuf);
2316 (void) strlcpy(name, cbuf, hbsize);
2141 *statp = EX_OK;
2142 return TRUE;
2143}
2144
2317 *statp = EX_OK;
2318 return TRUE;
2319}
2320
2145#endif
2321#endif /* NIS */
2146 /*
2147** NISPLUS Modules
2148**
2149** This code donated by Sun Microsystems.
2150*/
2151
2152#ifdef NISPLUS
2153
2322 /*
2323** NISPLUS Modules
2324**
2325** This code donated by Sun Microsystems.
2326*/
2327
2328#ifdef NISPLUS
2329
2154#undef NIS /* symbol conflict in nis.h */
2155#undef T_UNSPEC /* symbol conflict in nis.h -> ... -> sys/tiuser.h */
2156#include
2157#include
2330# undef NIS /* symbol conflict in nis.h */
2331# undef T_UNSPEC /* symbol conflict in nis.h -> ... -> sys/tiuser.h */
2332# include <rpcsvc/nis.h>
2333# include <rpcsvc/nislib.h>
2158
2334
2159#define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
2160#define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
2161#define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len)
2162#define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.')
2335# define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
2336# define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
2337# define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len)
2338# define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.')
2163
2164/*
2165** NISPLUS_MAP_OPEN -- open nisplus table
2166*/
2167
2168bool
2169nisplus_map_open(map, mode)
2170 MAP *map;
2171 int mode;
2172{
2173 nis_result *res = NULL;
2174 int retry_cnt, max_col, i;
2175 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2176
2177 if (tTd(38, 2))
2339
2340/*
2341** NISPLUS_MAP_OPEN -- open nisplus table
2342*/
2343
2344bool
2345nisplus_map_open(map, mode)
2346 MAP *map;
2347 int mode;
2348{
2349 nis_result *res = NULL;
2350 int retry_cnt, max_col, i;
2351 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2352
2353 if (tTd(38, 2))
2178 printf("nisplus_map_open(%s, %s, %d)\n",
2354 dprintf("nisplus_map_open(%s, %s, %d)\n",
2179 map->map_mname, map->map_file, mode);
2180
2181 mode &= O_ACCMODE;
2182 if (mode != O_RDONLY)
2183 {
2184 errno = EPERM;
2185 return FALSE;
2186 }
2187
2188 if (*map->map_file == '\0')
2189 map->map_file = "mail_aliases.org_dir";
2190
2191 if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL)
2192 {
2193 /* set default NISPLUS Domain to $m */
2355 map->map_mname, map->map_file, mode);
2356
2357 mode &= O_ACCMODE;
2358 if (mode != O_RDONLY)
2359 {
2360 errno = EPERM;
2361 return FALSE;
2362 }
2363
2364 if (*map->map_file == '\0')
2365 map->map_file = "mail_aliases.org_dir";
2366
2367 if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL)
2368 {
2369 /* set default NISPLUS Domain to $m */
2194 extern char *nisplus_default_domain __P((void));
2195
2196 map->map_domain = newstr(nisplus_default_domain());
2197 if (tTd(38, 2))
2370 map->map_domain = newstr(nisplus_default_domain());
2371 if (tTd(38, 2))
2198 printf("nisplus_map_open(%s): using domain %s\n",
2199 map->map_file, map->map_domain);
2372 dprintf("nisplus_map_open(%s): using domain %s\n",
2373 map->map_file, map->map_domain);
2200 }
2201 if (!PARTIAL_NAME(map->map_file))
2202 {
2203 map->map_domain = newstr("");
2204 snprintf(qbuf, sizeof qbuf, "%s", map->map_file);
2205 }
2206 else
2207 {

--- 19 unchanged lines hidden (view full) ---

2227 errno = EAGAIN;
2228 return FALSE;
2229 }
2230 /* try not to overwhelm hosed server */
2231 sleep(2);
2232 break;
2233
2234 default: /* all other nisplus errors */
2374 }
2375 if (!PARTIAL_NAME(map->map_file))
2376 {
2377 map->map_domain = newstr("");
2378 snprintf(qbuf, sizeof qbuf, "%s", map->map_file);
2379 }
2380 else
2381 {

--- 19 unchanged lines hidden (view full) ---

2401 errno = EAGAIN;
2402 return FALSE;
2403 }
2404 /* try not to overwhelm hosed server */
2405 sleep(2);
2406 break;
2407
2408 default: /* all other nisplus errors */
2235#if 0
2409# if 0
2236 if (!bitset(MF_OPTIONAL, map->map_mflags))
2410 if (!bitset(MF_OPTIONAL, map->map_mflags))
2237 syserr("421 Cannot find table %s.%s: %s",
2411 syserr("421 4.0.0 Cannot find table %s.%s: %s",
2238 map->map_file, map->map_domain,
2239 nis_sperrno(res->status));
2412 map->map_file, map->map_domain,
2413 nis_sperrno(res->status));
2240#endif
2414# endif /* 0 */
2241 errno = EAGAIN;
2242 return FALSE;
2243 }
2244 }
2245
2246 if (NIS_RES_NUMOBJ(res) != 1 ||
2247 (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ))
2248 {
2249 if (tTd(38, 10))
2415 errno = EAGAIN;
2416 return FALSE;
2417 }
2418 }
2419
2420 if (NIS_RES_NUMOBJ(res) != 1 ||
2421 (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ))
2422 {
2423 if (tTd(38, 10))
2250 printf("nisplus_map_open: %s is not a table\n", qbuf);
2251#if 0
2424 dprintf("nisplus_map_open: %s is not a table\n", qbuf);
2425# if 0
2252 if (!bitset(MF_OPTIONAL, map->map_mflags))
2426 if (!bitset(MF_OPTIONAL, map->map_mflags))
2253 syserr("421 %s.%s: %s is not a table",
2427 syserr("421 4.0.0 %s.%s: %s is not a table",
2254 map->map_file, map->map_domain,
2255 nis_sperrno(res->status));
2428 map->map_file, map->map_domain,
2429 nis_sperrno(res->status));
2256#endif
2430# endif /* 0 */
2257 errno = EBADF;
2258 return FALSE;
2259 }
2260 /* default key column is column 0 */
2261 if (map->map_keycolnm == NULL)
2262 map->map_keycolnm = newstr(COL_NAME(res,0));
2263
2264 max_col = COL_MAX(res);
2265
2266 /* verify the key column exist */
2431 errno = EBADF;
2432 return FALSE;
2433 }
2434 /* default key column is column 0 */
2435 if (map->map_keycolnm == NULL)
2436 map->map_keycolnm = newstr(COL_NAME(res,0));
2437
2438 max_col = COL_MAX(res);
2439
2440 /* verify the key column exist */
2267 for (i=0; i< max_col; i++)
2441 for (i = 0; i< max_col; i++)
2268 {
2442 {
2269 if (!strcmp(map->map_keycolnm, COL_NAME(res,i)))
2443 if (strcmp(map->map_keycolnm, COL_NAME(res,i)) == 0)
2270 break;
2271 }
2272 if (i == max_col)
2273 {
2274 if (tTd(38, 2))
2444 break;
2445 }
2446 if (i == max_col)
2447 {
2448 if (tTd(38, 2))
2275 printf("nisplus_map_open(%s): can not find key column %s\n",
2449 dprintf("nisplus_map_open(%s): can not find key column %s\n",
2276 map->map_file, map->map_keycolnm);
2277 errno = ENOENT;
2278 return FALSE;
2279 }
2280
2281 /* default value column is the last column */
2282 if (map->map_valcolnm == NULL)
2283 {
2284 map->map_valcolno = max_col - 1;
2285 return TRUE;
2286 }
2287
2450 map->map_file, map->map_keycolnm);
2451 errno = ENOENT;
2452 return FALSE;
2453 }
2454
2455 /* default value column is the last column */
2456 if (map->map_valcolnm == NULL)
2457 {
2458 map->map_valcolno = max_col - 1;
2459 return TRUE;
2460 }
2461
2288 for (i=0; i< max_col; i++)
2462 for (i = 0; i< max_col; i++)
2289 {
2290 if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0)
2291 {
2292 map->map_valcolno = i;
2293 return TRUE;
2294 }
2295 }
2296
2297 if (tTd(38, 2))
2463 {
2464 if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0)
2465 {
2466 map->map_valcolno = i;
2467 return TRUE;
2468 }
2469 }
2470
2471 if (tTd(38, 2))
2298 printf("nisplus_map_open(%s): can not find column %s\n",
2299 map->map_file, map->map_keycolnm);
2472 dprintf("nisplus_map_open(%s): can not find column %s\n",
2473 map->map_file, map->map_keycolnm);
2300 errno = ENOENT;
2301 return FALSE;
2302}
2303
2304
2305/*
2306** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table
2307*/

--- 9 unchanged lines hidden (view full) ---

2317 auto int vsize;
2318 char *skp;
2319 int skleft;
2320 char search_key[MAXNAME + 4];
2321 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2322 nis_result *result;
2323
2324 if (tTd(38, 20))
2474 errno = ENOENT;
2475 return FALSE;
2476}
2477
2478
2479/*
2480** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table
2481*/

--- 9 unchanged lines hidden (view full) ---

2491 auto int vsize;
2492 char *skp;
2493 int skleft;
2494 char search_key[MAXNAME + 4];
2495 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2496 nis_result *result;
2497
2498 if (tTd(38, 20))
2325 printf("nisplus_map_lookup(%s, %s)\n",
2499 dprintf("nisplus_map_lookup(%s, %s)\n",
2326 map->map_mname, name);
2327
2328 if (!bitset(MF_OPEN, map->map_mflags))
2329 {
2330 if (nisplus_map_open(map, O_RDONLY))
2331 {
2332 map->map_mflags |= MF_OPEN;
2333 map->map_pid = getpid();

--- 25 unchanged lines hidden (view full) ---

2359 *skp++ = '"';
2360 skleft -= 3;
2361 break;
2362
2363 case '"':
2364 /* double the quote */
2365 *skp++ = '"';
2366 skleft--;
2500 map->map_mname, name);
2501
2502 if (!bitset(MF_OPEN, map->map_mflags))
2503 {
2504 if (nisplus_map_open(map, O_RDONLY))
2505 {
2506 map->map_mflags |= MF_OPEN;
2507 map->map_pid = getpid();

--- 25 unchanged lines hidden (view full) ---

2533 *skp++ = '"';
2534 skleft -= 3;
2535 break;
2536
2537 case '"':
2538 /* double the quote */
2539 *skp++ = '"';
2540 skleft--;
2367 /* fall through... */
2541 /* FALLTHROUGH */
2368
2369 default:
2370 *skp++ = *p;
2371 skleft--;
2372 break;
2373 }
2374 }
2375 *skp = '\0';

--- 5 unchanged lines hidden (view full) ---

2381 snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s",
2382 map->map_keycolnm, search_key, map->map_file,
2383 map->map_domain);
2384 else
2385 snprintf(qbuf, sizeof qbuf, "[%s=%s],%s",
2386 map->map_keycolnm, search_key, map->map_file);
2387
2388 if (tTd(38, 20))
2542
2543 default:
2544 *skp++ = *p;
2545 skleft--;
2546 break;
2547 }
2548 }
2549 *skp = '\0';

--- 5 unchanged lines hidden (view full) ---

2555 snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s",
2556 map->map_keycolnm, search_key, map->map_file,
2557 map->map_domain);
2558 else
2559 snprintf(qbuf, sizeof qbuf, "[%s=%s],%s",
2560 map->map_keycolnm, search_key, map->map_file);
2561
2562 if (tTd(38, 20))
2389 printf("qbuf=%s\n", qbuf);
2563 dprintf("qbuf=%s\n", qbuf);
2390 result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
2391 if (result->status == NIS_SUCCESS)
2392 {
2393 int count;
2394 char *str;
2395
2396 if ((count = NIS_RES_NUMOBJ(result)) != 1)
2397 {
2398 if (LogLevel > 10)
2399 sm_syslog(LOG_WARNING, CurEnv->e_id,
2564 result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
2565 if (result->status == NIS_SUCCESS)
2566 {
2567 int count;
2568 char *str;
2569
2570 if ((count = NIS_RES_NUMOBJ(result)) != 1)
2571 {
2572 if (LogLevel > 10)
2573 sm_syslog(LOG_WARNING, CurEnv->e_id,
2400 "%s: lookup error, expected 1 entry, got %d",
2401 map->map_file, count);
2574 "%s: lookup error, expected 1 entry, got %d",
2575 map->map_file, count);
2402
2403 /* ignore second entry */
2404 if (tTd(38, 20))
2576
2577 /* ignore second entry */
2578 if (tTd(38, 20))
2405 printf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n",
2579 dprintf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n",
2406 name, count);
2407 }
2408
2409 p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
2410 /* set the length of the result */
2411 if (p == NULL)
2412 p = "";
2413 vsize = strlen(p);
2414 if (tTd(38, 20))
2580 name, count);
2581 }
2582
2583 p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
2584 /* set the length of the result */
2585 if (p == NULL)
2586 p = "";
2587 vsize = strlen(p);
2588 if (tTd(38, 20))
2415 printf("nisplus_map_lookup(%s), found %s\n",
2589 dprintf("nisplus_map_lookup(%s), found %s\n",
2416 name, p);
2417 if (bitset(MF_MATCHONLY, map->map_mflags))
2418 str = map_rewrite(map, name, strlen(name), NULL);
2419 else
2420 str = map_rewrite(map, p, vsize, av);
2421 nis_freeresult(result);
2422 *statp = EX_OK;
2423 return str;

--- 6 unchanged lines hidden (view full) ---

2430 *statp = EX_TEMPFAIL;
2431 else
2432 {
2433 *statp = EX_UNAVAILABLE;
2434 map->map_mflags &= ~(MF_VALID|MF_OPEN);
2435 }
2436 }
2437 if (tTd(38, 20))
2590 name, p);
2591 if (bitset(MF_MATCHONLY, map->map_mflags))
2592 str = map_rewrite(map, name, strlen(name), NULL);
2593 else
2594 str = map_rewrite(map, p, vsize, av);
2595 nis_freeresult(result);
2596 *statp = EX_OK;
2597 return str;

--- 6 unchanged lines hidden (view full) ---

2604 *statp = EX_TEMPFAIL;
2605 else
2606 {
2607 *statp = EX_UNAVAILABLE;
2608 map->map_mflags &= ~(MF_VALID|MF_OPEN);
2609 }
2610 }
2611 if (tTd(38, 20))
2438 printf("nisplus_map_lookup(%s), failed\n", name);
2612 dprintf("nisplus_map_lookup(%s), failed\n", name);
2439 nis_freeresult(result);
2440 return NULL;
2441}
2442
2443
2444
2445/*
2446** NISPLUS_GETCANONNAME -- look up canonical name in NIS+
2447*/
2448
2613 nis_freeresult(result);
2614 return NULL;
2615}
2616
2617
2618
2619/*
2620** NISPLUS_GETCANONNAME -- look up canonical name in NIS+
2621*/
2622
2449bool
2623static bool
2450nisplus_getcanonname(name, hbsize, statp)
2451 char *name;
2452 int hbsize;
2453 int *statp;
2454{
2455 char *vp;
2456 auto int vsize;
2457 nis_result *result;
2458 char *p;
2459 char nbuf[MAXNAME + 1];
2460 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2461
2462 if (strlen(name) >= sizeof nbuf)
2463 {
2464 *statp = EX_UNAVAILABLE;
2465 return FALSE;
2466 }
2624nisplus_getcanonname(name, hbsize, statp)
2625 char *name;
2626 int hbsize;
2627 int *statp;
2628{
2629 char *vp;
2630 auto int vsize;
2631 nis_result *result;
2632 char *p;
2633 char nbuf[MAXNAME + 1];
2634 char qbuf[MAXLINE + NIS_MAXNAMELEN];
2635
2636 if (strlen(name) >= sizeof nbuf)
2637 {
2638 *statp = EX_UNAVAILABLE;
2639 return FALSE;
2640 }
2467 (void) strcpy(nbuf, name);
2641 (void) strlcpy(nbuf, name, sizeof nbuf);
2468 shorten_hostname(nbuf);
2469
2470 p = strchr(nbuf, '.');
2471 if (p == NULL)
2472 {
2473 /* single token */
2474 snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir", nbuf);
2475 }

--- 6 unchanged lines hidden (view full) ---

2482 }
2483 else
2484 {
2485 *statp = EX_NOHOST;
2486 return FALSE;
2487 }
2488
2489 if (tTd(38, 20))
2642 shorten_hostname(nbuf);
2643
2644 p = strchr(nbuf, '.');
2645 if (p == NULL)
2646 {
2647 /* single token */
2648 snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir", nbuf);
2649 }

--- 6 unchanged lines hidden (view full) ---

2656 }
2657 else
2658 {
2659 *statp = EX_NOHOST;
2660 return FALSE;
2661 }
2662
2663 if (tTd(38, 20))
2490 printf("\nnisplus_getcanoname(%s), qbuf=%s\n",
2491 name, qbuf);
2664 dprintf("\nnisplus_getcanoname(%s), qbuf=%s\n",
2665 name, qbuf);
2492
2493 result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
2494 NULL, NULL);
2495
2496 if (result->status == NIS_SUCCESS)
2497 {
2498 int count;
2499 char *domain;
2500
2501 if ((count = NIS_RES_NUMOBJ(result)) != 1)
2502 {
2503 if (LogLevel > 10)
2504 sm_syslog(LOG_WARNING, CurEnv->e_id,
2666
2667 result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
2668 NULL, NULL);
2669
2670 if (result->status == NIS_SUCCESS)
2671 {
2672 int count;
2673 char *domain;
2674
2675 if ((count = NIS_RES_NUMOBJ(result)) != 1)
2676 {
2677 if (LogLevel > 10)
2678 sm_syslog(LOG_WARNING, CurEnv->e_id,
2505 "nisplus_getcanonname: lookup error, expected 1 entry, got %d",
2506 count);
2679 "nisplus_getcanonname: lookup error, expected 1 entry, got %d",
2680 count);
2507
2508 /* ignore second entry */
2509 if (tTd(38, 20))
2681
2682 /* ignore second entry */
2683 if (tTd(38, 20))
2510 printf("nisplus_getcanoname(%s), got %d entries, all but first ignored\n",
2684 dprintf("nisplus_getcanoname(%s), got %d entries, all but first ignored\n",
2511 name, count);
2512 }
2513
2514 if (tTd(38, 20))
2685 name, count);
2686 }
2687
2688 if (tTd(38, 20))
2515 printf("nisplus_getcanoname(%s), found in directory \"%s\"\n",
2516 name, (NIS_RES_OBJECT(result))->zo_domain);
2689 dprintf("nisplus_getcanoname(%s), found in directory \"%s\"\n",
2690 name, (NIS_RES_OBJECT(result))->zo_domain);
2517
2518
2519 vp = ((NIS_RES_OBJECT(result))->EN_col(0));
2520 vsize = strlen(vp);
2521 if (tTd(38, 20))
2691
2692
2693 vp = ((NIS_RES_OBJECT(result))->EN_col(0));
2694 vsize = strlen(vp);
2695 if (tTd(38, 20))
2522 printf("nisplus_getcanonname(%s), found %s\n",
2696 dprintf("nisplus_getcanonname(%s), found %s\n",
2523 name, vp);
2524 if (strchr(vp, '.') != NULL)
2525 {
2526 domain = "";
2527 }
2528 else
2529 {
2530 domain = macvalue('m', CurEnv);
2531 if (domain == NULL)
2532 domain = "";
2533 }
2534 if (hbsize > vsize + (int) strlen(domain) + 1)
2535 {
2536 if (domain[0] == '\0')
2697 name, vp);
2698 if (strchr(vp, '.') != NULL)
2699 {
2700 domain = "";
2701 }
2702 else
2703 {
2704 domain = macvalue('m', CurEnv);
2705 if (domain == NULL)
2706 domain = "";
2707 }
2708 if (hbsize > vsize + (int) strlen(domain) + 1)
2709 {
2710 if (domain[0] == '\0')
2537 strcpy(name, vp);
2711 (void) strlcpy(name, vp, hbsize);
2538 else
2539 snprintf(name, hbsize, "%s.%s", vp, domain);
2540 *statp = EX_OK;
2541 }
2542 else
2543 *statp = EX_NOHOST;
2544 nis_freeresult(result);
2545 return TRUE;
2546 }
2547 else
2548 {
2549 if (result->status == NIS_NOTFOUND)
2550 *statp = EX_NOHOST;
2551 else if (result->status == NIS_TRYAGAIN)
2552 *statp = EX_TEMPFAIL;
2553 else
2554 *statp = EX_UNAVAILABLE;
2555 }
2556 if (tTd(38, 20))
2712 else
2713 snprintf(name, hbsize, "%s.%s", vp, domain);
2714 *statp = EX_OK;
2715 }
2716 else
2717 *statp = EX_NOHOST;
2718 nis_freeresult(result);
2719 return TRUE;
2720 }
2721 else
2722 {
2723 if (result->status == NIS_NOTFOUND)
2724 *statp = EX_NOHOST;
2725 else if (result->status == NIS_TRYAGAIN)
2726 *statp = EX_TEMPFAIL;
2727 else
2728 *statp = EX_UNAVAILABLE;
2729 }
2730 if (tTd(38, 20))
2557 printf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n",
2731 dprintf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n",
2558 name, result->status, *statp);
2559 nis_freeresult(result);
2560 return FALSE;
2561}
2562
2732 name, result->status, *statp);
2733 nis_freeresult(result);
2734 return FALSE;
2735}
2736
2563
2564char *
2565nisplus_default_domain()
2566{
2567 static char default_domain[MAXNAME + 1] = "";
2568 char *p;
2569
2570 if (default_domain[0] != '\0')
2737char *
2738nisplus_default_domain()
2739{
2740 static char default_domain[MAXNAME + 1] = "";
2741 char *p;
2742
2743 if (default_domain[0] != '\0')
2571 return(default_domain);
2744 return default_domain;
2572
2573 p = nis_local_directory();
2574 snprintf(default_domain, sizeof default_domain, "%s", p);
2575 return default_domain;
2576}
2577
2578#endif /* NISPLUS */
2579 /*
2580** LDAP Modules
2745
2746 p = nis_local_directory();
2747 snprintf(default_domain, sizeof default_domain, "%s", p);
2748 return default_domain;
2749}
2750
2751#endif /* NISPLUS */
2752 /*
2753** LDAP Modules
2581**
2582** Contributed by Booker C. Bense <bbense@networking.stanford.edu>.
2583** Get your support from him.
2584*/
2585
2754*/
2755
2586#ifdef LDAPMAP
2756/*
2757** LDAPMAP_DEQUOTE - helper routine for ldapmap_parseargs
2758*/
2587
2759
2588# undef NEEDGETOPT /* used for something else in LDAP */
2760#if defined(LDAPMAP) || defined(PH_MAP)
2589
2761
2590# include <lber.h>
2591# include <ldap.h>
2592# include "ldap_map.h"
2762# ifdef PH_MAP
2763# define ph_map_dequote ldapmap_dequote
2764# endif /* PH_MAP */
2593
2765
2766char *
2767ldapmap_dequote(str)
2768 char *str;
2769{
2770 char *p;
2771 char *start;
2772
2773 if (str == NULL)
2774 return NULL;
2775
2776 p = str;
2777 if (*p == '"')
2778 {
2779 /* Should probably swallow initial whitespace here */
2780 start = ++p;
2781 }
2782 else
2783 return str;
2784 while (*p != '"' && *p != '\0')
2785 p++;
2786 if (*p != '\0')
2787 *p = '\0';
2788 return start;
2789}
2790#endif /* defined(LDAPMAP) || defined(PH_MAP) */
2791
2792#ifdef LDAPMAP
2793
2794LDAPMAP_STRUCT *LDAPDefaults = NULL;
2795
2594/*
2796/*
2595** LDAP_MAP_OPEN -- open LDAP map
2797** LDAPMAP_OPEN -- open LDAP map
2596**
2798**
2597** Since LDAP is TCP-based there is not much we can or should do
2598** here. It might be a good idea to attempt an open/close here.
2799** Connect to the LDAP server. Re-use existing connections since a
2800** single server connection to a host (with the same host, port,
2801** bind DN, and secret) can answer queries for multiple maps.
2599*/
2600
2601bool
2802*/
2803
2804bool
2602ldap_map_open(map, mode)
2805ldapmap_open(map, mode)
2603 MAP *map;
2604 int mode;
2605{
2806 MAP *map;
2807 int mode;
2808{
2809 LDAPMAP_STRUCT *lmap;
2810 STAB *s;
2811
2606 if (tTd(38, 2))
2812 if (tTd(38, 2))
2607 printf("ldap_map_open(%s, %d)\n", map->map_mname, mode);
2813 dprintf("ldapmap_open(%s, %d)\n", map->map_mname, mode);
2608
2609 mode &= O_ACCMODE;
2814
2815 mode &= O_ACCMODE;
2816
2817 /* sendmail doesn't have the ability to write to LDAP (yet) */
2610 if (mode != O_RDONLY)
2611 {
2612 /* issue a pseudo-error message */
2818 if (mode != O_RDONLY)
2819 {
2820 /* issue a pseudo-error message */
2613#ifdef ENOSYS
2821# ifdef ENOSYS
2614 errno = ENOSYS;
2822 errno = ENOSYS;
2615#else
2616# ifdef EFTYPE
2823# else /* ENOSYS */
2824# ifdef EFTYPE
2617 errno = EFTYPE;
2825 errno = EFTYPE;
2618# else
2826# else /* EFTYPE */
2619 errno = ENXIO;
2827 errno = ENXIO;
2620# endif
2621#endif
2828# endif /* EFTYPE */
2829# endif /* ENOSYS */
2622 return FALSE;
2623 }
2830 return FALSE;
2831 }
2832
2833 /* Comma separate if used as an alias file */
2834 if (map->map_coldelim == '\0' && bitset(MF_ALIAS, map->map_mflags))
2835 map->map_coldelim = ',';
2836
2837 lmap = (LDAPMAP_STRUCT *) map->map_db1;
2838
2839 s = ldapmap_findconn(lmap);
2840 if (s->s_ldap != NULL)
2841 {
2842 /* Already have a connection open to this LDAP server */
2843 lmap->ldap_ld = s->s_ldap;
2844 map->map_mflags |= MF_SHARED;
2845 return TRUE;
2846 }
2847
2848 /* No connection yet, connect */
2849 if (!ldapmap_start(map))
2850 return FALSE;
2851
2852 /* Save connection for reuse */
2853 s->s_ldap = lmap->ldap_ld;
2624 return TRUE;
2625}
2626
2854 return TRUE;
2855}
2856
2627
2628/*
2857/*
2629** LDAP_MAP_START -- actually open LDAP map
2858** LDAPMAP_START -- actually connect to an LDAP server
2630**
2859**
2631** Caching should be investigated.
2860** Parameters:
2861** map -- the map being opened.
2862**
2863** Returns:
2864** TRUE if connection is successful, FALSE otherwise.
2865**
2866** Side Effects:
2867** Populates lmap->ldap_ld.
2632*/
2633
2634static jmp_buf LDAPTimeout;
2635
2868*/
2869
2870static jmp_buf LDAPTimeout;
2871
2636static void
2637ldaptimeout(sig_no)
2638 int sig_no;
2639{
2640 longjmp(LDAPTimeout, 1);
2641}
2642
2643bool
2644ldap_map_start(map)
2872static bool
2873ldapmap_start(map)
2645 MAP *map;
2646{
2874 MAP *map;
2875{
2647 LDAP_MAP_STRUCT *lmap;
2648 LDAP *ld;
2876 register int bind_result;
2877 int save_errno;
2649 register EVENT *ev = NULL;
2878 register EVENT *ev = NULL;
2879 LDAPMAP_STRUCT *lmap;
2880 LDAP *ld;
2650
2651 if (tTd(38, 2))
2881
2882 if (tTd(38, 2))
2652 printf("ldap_map_start(%s)\n", map->map_mname);
2883 dprintf("ldapmap_start(%s)\n", map->map_mname);
2653
2884
2654 lmap = (LDAP_MAP_STRUCT *) map->map_db1;
2885 lmap = (LDAPMAP_STRUCT *) map->map_db1;
2655
2656 if (tTd(38,9))
2886
2887 if (tTd(38,9))
2657 printf("ldap_open(%s, %d)\n", lmap->ldaphost, lmap->ldapport);
2888 dprintf("ldapmap_start(%s, %d)\n",
2889 lmap->ldap_host == NULL ? "localhost" : lmap->ldap_host,
2890 lmap->ldap_port);
2658
2891
2659 /* Need to set an alarm here, ldap_open is hopelessly broken. */
2892# if USE_LDAP_INIT
2893 ld = ldap_init(lmap->ldap_host, lmap->ldap_port);
2894# else /* USE_LDAP_INIT */
2895 /*
2896 ** If using ldap_open(), the actual connection to the server
2897 ** happens now so we need the timeout here. For ldap_init(),
2898 ** the connection happens at bind time.
2899 */
2660
2661 /* set the timeout */
2900
2901 /* set the timeout */
2662 if (lmap->timeout.tv_sec != 0)
2902 if (lmap->ldap_timeout.tv_sec != 0)
2663 {
2664 if (setjmp(LDAPTimeout) != 0)
2665 {
2666 if (LogLevel > 1)
2667 sm_syslog(LOG_NOTICE, CurEnv->e_id,
2903 {
2904 if (setjmp(LDAPTimeout) != 0)
2905 {
2906 if (LogLevel > 1)
2907 sm_syslog(LOG_NOTICE, CurEnv->e_id,
2668 "timeout waiting for ldap_open to %.100s",
2669 lmap->ldaphost);
2670 return (FALSE);
2908 "timeout conning to LDAP server %.100s",
2909 lmap->ldap_host == NULL ? "localhost" : lmap->ldap_host);
2910 return FALSE;
2671 }
2911 }
2672 ev = setevent(lmap->timeout.tv_sec, ldaptimeout, 0);
2912 ev = setevent(lmap->ldap_timeout.tv_sec, ldaptimeout, 0);
2673 }
2674
2913 }
2914
2675#ifdef USE_LDAP_INIT
2676 ld = ldap_init(lmap->ldaphost,lmap->ldapport);
2677#else
2678 ld = ldap_open(lmap->ldaphost,lmap->ldapport);
2679#endif
2915 ld = ldap_open(lmap->ldap_host, lmap->ldap_port);
2916 save_errno = errno;
2680
2917
2681 /* clear the event if it has not sprung */
2682 if (lmap->timeout.tv_sec != 0)
2918 /* clear the event if it has not sprung */
2919 if (ev != NULL)
2683 clrevent(ev);
2920 clrevent(ev);
2921# endif /* USE_LDAP_INIT */
2684
2922
2923 errno = save_errno;
2685 if (ld == NULL)
2686 {
2687 if (!bitset(MF_OPTIONAL, map->map_mflags))
2688 {
2924 if (ld == NULL)
2925 {
2926 if (!bitset(MF_OPTIONAL, map->map_mflags))
2927 {
2689 syserr("%sldapopen failed to %s in map %s",
2690 bitset(MF_NODEFER, map->map_mflags) ? "" : "421 ",
2691 lmap->ldaphost, map->map_mname);
2928 if (bitset(MF_NODEFER, map->map_mflags))
2929 syserr("%s failed to %s in map %s",
2930# if USE_LDAP_INIT
2931 "ldap_init",
2932# else /* USE_LDAP_INIT */
2933 "ldap_open",
2934# endif /* USE_LDAP_INIT */
2935 lmap->ldap_host == NULL ? "localhost"
2936 : lmap->ldap_host,
2937 map->map_mname);
2938 else
2939 syserr("421 4.0.0 %s failed to %s in map %s",
2940# if USE_LDAP_INIT
2941 "ldap_init",
2942# else /* USE_LDAP_INIT */
2943 "ldap_open",
2944# endif /* USE_LDAP_INIT */
2945 lmap->ldap_host == NULL ? "localhost"
2946 : lmap->ldap_host,
2947 map->map_mname);
2692 }
2693 return FALSE;
2694 }
2695
2948 }
2949 return FALSE;
2950 }
2951
2696#ifdef USE_LDAP_SET_OPTION
2697 ldap_set_option(ld, LDAP_OPT_DEREF, &lmap->deref);
2698 ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->timelimit);
2699 ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->sizelimit);
2700 ldap_set_option(ld, LDAP_OPT_REFERRALS,
2701 bitset(LDAP_OPT_REFERRALS, lmap->ldap_options) ?
2702 LDAP_OPT_ON : LDAP_OPT_OFF);
2703#else
2704 /* From here on in we can use ldap internal timelimits */
2705 ld->ld_deref = lmap->deref;
2706 ld->ld_timelimit = lmap->timelimit;
2707 ld->ld_sizelimit = lmap->sizelimit;
2708 ld->ld_options = lmap->ldap_options;
2709#endif
2952 ldapmap_setopts(ld, lmap);
2710
2953
2711#ifdef USE_LDAP_INIT
2712 /* ld needs to be cast into the map struct */
2713 lmap->ld = ld;
2714 return TRUE;
2715#else
2716 if (ldap_bind_s(ld, lmap->binddn,lmap->passwd,lmap->method) != LDAP_SUCCESS)
2954# if USE_LDAP_INIT
2955 /*
2956 ** If using ldap_init(), the actual connection to the server
2957 ** happens at ldap_bind_s() so we need the timeout here.
2958 */
2959
2960 /* set the timeout */
2961 if (lmap->ldap_timeout.tv_sec != 0)
2717 {
2962 {
2718 if (!bitset(MF_OPTIONAL, map->map_mflags))
2963 if (setjmp(LDAPTimeout) != 0)
2719 {
2964 {
2720 syserr("421 Cannot bind to map %s in ldap server %s",
2721 map->map_mname, lmap->ldaphost);
2965 if (LogLevel > 1)
2966 sm_syslog(LOG_NOTICE, CurEnv->e_id,
2967 "timeout conning to LDAP server %.100s",
2968 lmap->ldap_host == NULL ? "localhost"
2969 : lmap->ldap_host);
2970 return FALSE;
2722 }
2971 }
2972 ev = setevent(lmap->ldap_timeout.tv_sec, ldaptimeout, 0);
2723 }
2973 }
2724 else
2974# endif /* USE_LDAP_INIT */
2975
2976# ifdef LDAP_AUTH_KRBV4
2977 if (lmap->ldap_method == LDAP_AUTH_KRBV4 &&
2978 lmap->ldap_secret != NULL)
2725 {
2979 {
2726 /* We need to cast ld into the map structure */
2727 lmap->ld = ld;
2728 return TRUE;
2980 /*
2981 ** Need to put ticket in environment here instead of
2982 ** during parseargs as there may be different tickets
2983 ** for different LDAP connections.
2984 */
2985
2986 (void) putenv(lmap->ldap_secret);
2729 }
2987 }
2988# endif /* LDAP_AUTH_KRBV4 */
2730
2989
2731 return FALSE;
2732#endif
2990 bind_result = ldap_bind_s(ld, lmap->ldap_binddn,
2991 lmap->ldap_secret, lmap->ldap_method);
2992
2993# if USE_LDAP_INIT
2994 /* clear the event if it has not sprung */
2995 if (ev != NULL)
2996 clrevent(ev);
2997# endif /* USE_LDAP_INIT */
2998
2999 if (bind_result != LDAP_SUCCESS)
3000 {
3001 errno = bind_result + E_LDAPBASE;
3002 if (!bitset(MF_OPTIONAL, map->map_mflags))
3003 {
3004 syserr("421 4.0.0 Cannot bind to map %s in ldap server %s",
3005 map->map_mname,
3006 lmap->ldap_host == NULL ? "localhost" : lmap->ldap_host);
3007 }
3008 return FALSE;
3009 }
3010
3011 /* We need to cast ld into the map structure */
3012 lmap->ldap_ld = ld;
3013 return TRUE;
2733}
2734
3014}
3015
3016/* ARGSUSED */
3017static void
3018ldaptimeout(sig_no)
3019 int sig_no;
3020{
3021 longjmp(LDAPTimeout, 1);
3022}
2735
2736/*
3023
3024/*
2737** LDAP_MAP_STOP -- close the ldap connection
3025** LDAPMAP_CLOSE -- close ldap map
2738*/
2739
2740void
3026*/
3027
3028void
2741ldap_map_stop(map)
3029ldapmap_close(map)
2742 MAP *map;
2743{
3030 MAP *map;
3031{
2744 LDAP_MAP_STRUCT *lmap;
3032 LDAPMAP_STRUCT *lmap;
3033 STAB *s;
2745
3034
2746 lmap = (LDAP_MAP_STRUCT *) map->map_db1;
2747 if (lmap->ld != NULL)
3035 if (tTd(38, 2))
3036 dprintf("ldapmap_close(%s)\n", map->map_mname);
3037
3038 lmap = (LDAPMAP_STRUCT *) map->map_db1;
3039
3040 /* Check if already closed */
3041 if (lmap->ldap_ld == NULL)
3042 return;
3043
3044 s = ldapmap_findconn(lmap);
3045
3046 /* Check if already closed */
3047 if (s->s_ldap == NULL)
3048 return;
3049
3050 /* If same as saved connection, stored connection is going away */
3051 if (s->s_ldap == lmap->ldap_ld)
3052 s->s_ldap = NULL;
3053
3054 if (lmap->ldap_ld != NULL)
2748 {
3055 {
2749 ldap_unbind(lmap->ld);
2750 lmap->ld = NULL;
3056 ldap_unbind(lmap->ldap_ld);
3057 lmap->ldap_ld = NULL;
2751 }
2752}
2753
3058 }
3059}
3060
3061# ifdef SUNET_ID
2754/*
3062/*
2755** LDAP_MAP_CLOSE -- close ldap map
2756*/
2757
2758void
2759ldap_map_close(map)
2760 MAP *map;
2761{
2762 ldap_map_stop(map);
2763}
2764
2765#ifdef SUNET_ID
2766/*
2767** SUNET_ID_HASH -- Convert a string to it's Sunet_id canonical form
2768** This only makes sense at Stanford University.
2769*/
2770
2771char *
2772sunet_id_hash(str)
2773 char *str;
2774{

--- 12 unchanged lines hidden (view full) ---

2787 {
2788 *p_last = tolower(*p);
2789 p_last++;
2790 }
2791 ++p;
2792 }
2793 if (*p_last != '\0')
2794 *p_last = '\0';
3063** SUNET_ID_HASH -- Convert a string to it's Sunet_id canonical form
3064** This only makes sense at Stanford University.
3065*/
3066
3067char *
3068sunet_id_hash(str)
3069 char *str;
3070{

--- 12 unchanged lines hidden (view full) ---

3083 {
3084 *p_last = tolower(*p);
3085 p_last++;
3086 }
3087 ++p;
3088 }
3089 if (*p_last != '\0')
3090 *p_last = '\0';
2795 return (str);
3091 return str;
2796}
3092}
3093# endif /* SUNET_ID */
2797
3094
2798
2799
2800#endif /* SUNET_ID */
2801/*
3095/*
2802** LDAP_MAP_LOOKUP -- look up a datum in a LDAP map
3096** LDAPMAP_LOOKUP -- look up a datum in a LDAP map
2803*/
2804
2805char *
3097*/
3098
3099char *
2806ldap_map_lookup(map, name, av, statp)
3100ldapmap_lookup(map, name, av, statp)
2807 MAP *map;
2808 char *name;
2809 char **av;
2810 int *statp;
2811{
3101 MAP *map;
3102 char *name;
3103 char **av;
3104 int *statp;
3105{
2812 LDAP_MAP_STRUCT *lmap = NULL;
2813 LDAPMessage *entry;
2814 char *vp;
2815 auto int vsize;
3106 int i;
3107 int entries = 0;
3108 int msgid;
3109 int ret;
3110 int vsize;
3111 char *fp, *vp;
3112 char *p, *q;
3113 char *result = NULL;
3114 LDAPMAP_STRUCT *lmap = NULL;
2816 char keybuf[MAXNAME + 1];
3115 char keybuf[MAXNAME + 1];
2817 char filter[LDAP_MAP_MAX_FILTER + 1];
2818 char **attr_values = NULL;
2819 char *result;
2820 int name_len;
2821 char *fp, *p, *q;
3116 char filter[LDAPMAP_MAX_FILTER + 1];
2822
2823 if (tTd(38, 20))
3117
3118 if (tTd(38, 20))
2824 printf("ldap_map_lookup(%s, %s)\n", map->map_mname, name);
3119 dprintf("ldapmap_lookup(%s, %s)\n", map->map_mname, name);
2825
3120
2826 /* actually open the map */
2827 if (!ldap_map_start(map))
2828 {
2829 result = NULL;
2830 *statp = EX_TEMPFAIL;
2831 goto quick_exit;
2832 }
2833
2834 /* Get ldap struct pointer from map */
3121 /* Get ldap struct pointer from map */
2835 lmap = (LDAP_MAP_STRUCT *) map->map_db1;
3122 lmap = (LDAPMAP_STRUCT *) map->map_db1;
3123 ldapmap_setopts(lmap->ldap_ld, lmap);
2836
3124
2837 name_len = strlen(name);
2838 if (name_len > MAXNAME)
2839 name_len = MAXNAME;
2840 strncpy(keybuf, name, name_len);
2841 keybuf[name_len] = '\0';
3125 (void) strlcpy(keybuf, name, sizeof keybuf);
2842
2843 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
3126
3127 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
2844#ifdef SUNET_ID
3128 {
3129# ifdef SUNET_ID
2845 sunet_id_hash(keybuf);
3130 sunet_id_hash(keybuf);
2846#else
3131# else /* SUNET_ID */
2847 makelower(keybuf);
3132 makelower(keybuf);
2848#endif /*SUNET_ID */
3133# endif /* SUNET_ID */
3134 }
2849
2850 /* substitute keybuf into filter, perhaps multiple times */
3135
3136 /* substitute keybuf into filter, perhaps multiple times */
3137 memset(filter, '\0', sizeof filter);
2851 fp = filter;
3138 fp = filter;
2852 p = lmap->filter;
3139 p = lmap->ldap_filter;
2853 while ((q = strchr(p, '%')) != NULL)
2854 {
2855 if (q[1] == 's')
2856 {
2857 snprintf(fp, SPACELEFT(filter, fp), "%.*s%s",
2858 q - p, p, keybuf);
3140 while ((q = strchr(p, '%')) != NULL)
3141 {
3142 if (q[1] == 's')
3143 {
3144 snprintf(fp, SPACELEFT(filter, fp), "%.*s%s",
3145 q - p, p, keybuf);
3146 fp += strlen(fp);
2859 p = q + 2;
2860 }
3147 p = q + 2;
3148 }
3149 else if (q[1] == '0')
3150 {
3151 char *k = keybuf;
3152
3153 snprintf(fp, SPACELEFT(filter, fp), "%.*s",
3154 q - p, p);
3155 fp += strlen(fp);
3156 p = q + 2;
3157
3158 /* Properly escape LDAP special characters */
3159 while (SPACELEFT(filter, fp) > 0 &&
3160 *k != '\0')
3161 {
3162 if (*k == '*' || *k == '(' ||
3163 *k == ')' || *k == '\\')
3164 {
3165 (void) strlcat(fp,
3166 (*k == '*' ? "\\2A" :
3167 (*k == '(' ? "\\28" :
3168 (*k == ')' ? "\\29" :
3169 (*k == '\\' ? "\\5C" :
3170 "\00")))),
3171 SPACELEFT(filter, fp));
3172 fp += strlen(fp);
3173 k++;
3174 }
3175 else
3176 *fp++ = *k++;
3177 }
3178 }
2861 else
2862 {
2863 snprintf(fp, SPACELEFT(filter, fp), "%.*s",
2864 q - p + 1, p);
2865 p = q + (q[1] == '%' ? 2 : 1);
3179 else
3180 {
3181 snprintf(fp, SPACELEFT(filter, fp), "%.*s",
3182 q - p + 1, p);
3183 p = q + (q[1] == '%' ? 2 : 1);
3184 fp += strlen(fp);
2866 }
3185 }
2867 fp += strlen(fp);
2868 }
2869 snprintf(fp, SPACELEFT(filter, fp), "%s", p);
2870 if (tTd(38, 20))
3186 }
3187 snprintf(fp, SPACELEFT(filter, fp), "%s", p);
3188 if (tTd(38, 20))
2871 printf("ldap search filter=%s\n", filter);
3189 dprintf("ldap search filter=%s\n", filter);
2872
3190
2873 if (ldap_search_st(lmap->ld, lmap->base,lmap->scope,filter,
2874 lmap->attr, lmap->attrsonly, &(lmap->timeout),
2875 &(lmap->res)) != LDAP_SUCCESS)
3191 lmap->ldap_res = NULL;
3192 msgid = ldap_search(lmap->ldap_ld, lmap->ldap_base, lmap->ldap_scope,
3193 filter,
3194 (lmap->ldap_attr[0] == NULL ? NULL :
3195 lmap->ldap_attr),
3196 lmap->ldap_attrsonly);
3197 if (msgid == -1)
2876 {
3198 {
2877 /* try stopping/starting map */
2878 ldap_map_stop(map);
2879 if (!ldap_map_start(map))
3199 errno = ldapmap_geterrno(lmap->ldap_ld) + E_LDAPBASE;
3200 if (!bitset(MF_OPTIONAL, map->map_mflags))
2880 {
3201 {
2881 result = NULL;
2882 *statp = EX_TEMPFAIL;
2883 goto quick_exit;
3202 if (bitset(MF_NODEFER, map->map_mflags))
3203 syserr("Error in ldap_search_st using %s in map %s",
3204 filter, map->map_mname);
3205 else
3206 syserr("421 4.0.0 Error in ldap_search_st using %s in map %s",
3207 filter, map->map_mname);
2884 }
3208 }
2885 if (ldap_search_st(lmap->ld, lmap->base, lmap->scope, filter,
2886 lmap->attr, lmap->attrsonly,
2887 &(lmap->timeout), &(lmap->res))
2888 != LDAP_SUCCESS)
3209 *statp = EX_TEMPFAIL;
3210 return NULL;
3211 }
3212
3213 *statp = EX_NOTFOUND;
3214 vp = NULL;
3215
3216 /* Get results (all if MF_NOREWRITE, otherwise one by one) */
3217 while ((ret = ldap_result(lmap->ldap_ld, msgid,
3218 bitset(MF_NOREWRITE, map->map_mflags),
3219 (lmap->ldap_timeout.tv_sec == 0 ? NULL :
3220 &(lmap->ldap_timeout)),
3221 &(lmap->ldap_res))) == LDAP_RES_SEARCH_ENTRY)
3222 {
3223 LDAPMessage *entry;
3224
3225 if (bitset(MF_SINGLEMATCH, map->map_mflags))
2889 {
3226 {
3227 entries += ldap_count_entries(lmap->ldap_ld,
3228 lmap->ldap_res);
3229 if (entries > 1)
3230 {
3231 *statp = EX_NOTFOUND;
3232 if (lmap->ldap_res != NULL)
3233 {
3234 ldap_msgfree(lmap->ldap_res);
3235 lmap->ldap_res = NULL;
3236 }
3237 (void) ldap_abandon(lmap->ldap_ld, msgid);
3238 if (vp != NULL)
3239 free(vp);
3240 if (tTd(38, 25))
3241 dprintf("ldap search found multiple on a single match query\n");
3242 return NULL;
3243 }
3244 }
3245
3246 /* If we don't want multiple values and we have one, break */
3247 if (map->map_coldelim == '\0' && vp != NULL)
3248 break;
3249
3250 /* Cycle through all entries */
3251 for (entry = ldap_first_entry(lmap->ldap_ld, lmap->ldap_res);
3252 entry != NULL;
3253 entry = ldap_next_entry(lmap->ldap_ld, lmap->ldap_res))
3254 {
3255 BerElement *ber;
3256 char *attr;
3257 char **vals = NULL;
3258
3259 /*
3260 ** If matching only and found an entry,
3261 ** no need to spin through attributes
3262 */
3263
3264 if (*statp == EX_OK &&
3265 bitset(MF_MATCHONLY, map->map_mflags))
3266 continue;
3267
3268# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
3269 /*
3270 ** Reset value to prevent lingering
3271 ** LDAP_DECODING_ERROR due to
3272 ** OpenLDAP 1.X's hack (see below)
3273 */
3274
3275 lmap->ldap_ld->ld_errno = LDAP_SUCCESS;
3276# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
3277
3278 for (attr = ldap_first_attribute(lmap->ldap_ld, entry,
3279 &ber);
3280 attr != NULL;
3281 attr = ldap_next_attribute(lmap->ldap_ld, entry,
3282 ber))
3283 {
3284 char *tmp, *vp_tmp;
3285
3286 if (lmap->ldap_attrsonly == LDAPMAP_FALSE)
3287 {
3288 vals = ldap_get_values(lmap->ldap_ld,
3289 entry,
3290 attr);
3291 if (vals == NULL)
3292 {
3293 errno = ldapmap_geterrno(lmap->ldap_ld);
3294 if (errno == LDAP_SUCCESS)
3295 continue;
3296
3297 /* Must be an error */
3298 errno += E_LDAPBASE;
3299 if (!bitset(MF_OPTIONAL,
3300 map->map_mflags))
3301 {
3302 if (bitset(MF_NODEFER,
3303 map->map_mflags))
3304 syserr("Error getting LDAP values in map %s",
3305 map->map_mname);
3306 else
3307 syserr("421 4.0.0 Error getting LDAP values in map %s",
3308 map->map_mname);
3309 }
3310 *statp = EX_TEMPFAIL;
3311# if USING_NETSCAPE_LDAP
3312 ldap_mem_free(attr);
3313# endif /* USING_NETSCAPE_LDAP */
3314 if (lmap->ldap_res != NULL)
3315 {
3316 ldap_msgfree(lmap->ldap_res);
3317 lmap->ldap_res = NULL;
3318 }
3319 (void) ldap_abandon(lmap->ldap_ld,
3320 msgid);
3321 if (vp != NULL)
3322 free(vp);
3323 return NULL;
3324 }
3325 }
3326
3327 *statp = EX_OK;
3328
3329# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
3330 /*
3331 ** Reset value to prevent lingering
3332 ** LDAP_DECODING_ERROR due to
3333 ** OpenLDAP 1.X's hack (see below)
3334 */
3335
3336 lmap->ldap_ld->ld_errno = LDAP_SUCCESS;
3337# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
3338
3339 /*
3340 ** If matching only,
3341 ** no need to spin through entries
3342 */
3343
3344 if (bitset(MF_MATCHONLY, map->map_mflags))
3345 continue;
3346
3347 /*
3348 ** If we don't want multiple values,
3349 ** return first found.
3350 */
3351
3352 if (map->map_coldelim == '\0')
3353 {
3354 if (lmap->ldap_attrsonly == LDAPMAP_TRUE)
3355 {
3356 vp = newstr(attr);
3357# if USING_NETSCAPE_LDAP
3358 ldap_mem_free(attr);
3359# endif /* USING_NETSCAPE_LDAP */
3360 break;
3361 }
3362
3363 if (vals[0] == NULL)
3364 {
3365 ldap_value_free(vals);
3366# if USING_NETSCAPE_LDAP
3367 ldap_mem_free(attr);
3368# endif /* USING_NETSCAPE_LDAP */
3369 continue;
3370 }
3371
3372 vp = newstr(vals[0]);
3373 ldap_value_free(vals);
3374# if USING_NETSCAPE_LDAP
3375 ldap_mem_free(attr);
3376# endif /* USING_NETSCAPE_LDAP */
3377 break;
3378 }
3379
3380 /* attributes only */
3381 if (lmap->ldap_attrsonly == LDAPMAP_TRUE)
3382 {
3383 if (vp == NULL)
3384 vp = newstr(attr);
3385 else
3386 {
3387 vsize = strlen(vp) +
3388 strlen(attr) + 2;
3389 tmp = xalloc(vsize);
3390 snprintf(tmp, vsize, "%s%c%s",
3391 vp, map->map_coldelim,
3392 attr);
3393 free(vp);
3394 vp = tmp;
3395 }
3396# if USING_NETSCAPE_LDAP
3397 ldap_mem_free(attr);
3398# endif /* USING_NETSCAPE_LDAP */
3399 continue;
3400 }
3401
3402 /*
3403 ** If there is more than one,
3404 ** munge then into a map_coldelim
3405 ** separated string
3406 */
3407
3408 vsize = 0;
3409 for (i = 0; vals[i] != NULL; i++)
3410 vsize += strlen(vals[i]) + 1;
3411 vp_tmp = xalloc(vsize);
3412 *vp_tmp = '\0';
3413
3414 p = vp_tmp;
3415 for (i = 0; vals[i] != NULL; i++)
3416 {
3417 p += strlcpy(p, vals[i],
3418 vsize - (p - vp_tmp));
3419 if (p >= vp_tmp + vsize)
3420 syserr("ldapmap_lookup: Internal error: buffer too small for LDAP values");
3421 if (vals[i + 1] != NULL)
3422 *p++ = map->map_coldelim;
3423 }
3424
3425 ldap_value_free(vals);
3426# if USING_NETSCAPE_LDAP
3427 ldap_mem_free(attr);
3428# endif /* USING_NETSCAPE_LDAP */
3429 if (vp == NULL)
3430 {
3431 vp = vp_tmp;
3432 continue;
3433 }
3434 vsize = strlen(vp) + strlen(vp_tmp) + 2;
3435 tmp = xalloc(vsize);
3436 snprintf(tmp, vsize, "%s%c%s",
3437 vp, map->map_coldelim, vp_tmp);
3438
3439 free(vp);
3440 free(vp_tmp);
3441 vp = tmp;
3442 }
3443 errno = ldapmap_geterrno(lmap->ldap_ld);
3444
3445 /*
3446 ** We check errno != LDAP_DECODING_ERROR since
3447 ** OpenLDAP 1.X has a very ugly *undocumented*
3448 ** hack of returning this error code from
3449 ** ldap_next_attribute() if the library freed the
3450 ** ber attribute. See:
3451 ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html
3452 */
3453
3454 if (errno != LDAP_SUCCESS &&
3455 errno != LDAP_DECODING_ERROR)
3456 {
3457 /* Must be an error */
3458 errno += E_LDAPBASE;
3459 if (!bitset(MF_OPTIONAL, map->map_mflags))
3460 {
3461 if (bitset(MF_NODEFER, map->map_mflags))
3462 syserr("Error getting LDAP attributes in map %s",
3463 map->map_mname);
3464 else
3465 syserr("421 4.0.0 Error getting LDAP attributes in map %s",
3466 map->map_mname);
3467 }
3468 *statp = EX_TEMPFAIL;
3469 if (lmap->ldap_res != NULL)
3470 {
3471 ldap_msgfree(lmap->ldap_res);
3472 lmap->ldap_res = NULL;
3473 }
3474 (void) ldap_abandon(lmap->ldap_ld, msgid);
3475 if (vp != NULL)
3476 free(vp);
3477 return NULL;
3478 }
3479
3480 /* We don't want multiple values and we have one */
3481 if (map->map_coldelim == '\0' && vp != NULL)
3482 break;
3483 }
3484 errno = ldapmap_geterrno(lmap->ldap_ld);
3485 if (errno != LDAP_SUCCESS && errno != LDAP_DECODING_ERROR)
3486 {
3487 /* Must be an error */
3488 errno += E_LDAPBASE;
2890 if (!bitset(MF_OPTIONAL, map->map_mflags))
2891 {
3489 if (!bitset(MF_OPTIONAL, map->map_mflags))
3490 {
2892 syserr("%sError in ldap_search_st using %s in map %s",
2893 bitset(MF_NODEFER, map->map_mflags) ? "" : "421 ",
2894 filter, map->map_mname);
3491 if (bitset(MF_NODEFER, map->map_mflags))
3492 syserr("Error getting LDAP entries in map %s",
3493 map->map_mname);
3494 else
3495 syserr("421 4.0.0 Error getting LDAP entries in map %s",
3496 map->map_mname);
2895 }
3497 }
2896 result = NULL;
2897 *statp = EX_TEMPFAIL;
3498 *statp = EX_TEMPFAIL;
2898 goto quick_exit;
3499 if (lmap->ldap_res != NULL)
3500 {
3501 ldap_msgfree(lmap->ldap_res);
3502 lmap->ldap_res = NULL;
3503 }
3504 (void) ldap_abandon(lmap->ldap_ld, msgid);
3505 if (vp != NULL)
3506 free(vp);
3507 return NULL;
2899 }
3508 }
3509 ldap_msgfree(lmap->ldap_res);
3510 lmap->ldap_res = NULL;
2900 }
2901
3511 }
3512
2902 entry = ldap_first_entry(lmap->ld,lmap->res);
2903 if (entry == NULL)
3513 /*
3514 ** If grabbing all results at once for MF_NOREWRITE and
3515 ** only want a single match, make sure that's all we have
3516 */
3517
3518 if (ret == LDAP_RES_SEARCH_RESULT &&
3519 bitset(MF_NOREWRITE|MF_SINGLEMATCH, map->map_mflags))
2904 {
3520 {
2905 result = NULL;
2906 *statp = EX_NOTFOUND;
2907 goto quick_exit;
3521 entries += ldap_count_entries(lmap->ldap_ld, lmap->ldap_res);
3522 if (entries > 1)
3523 {
3524 *statp = EX_NOTFOUND;
3525 if (lmap->ldap_res != NULL)
3526 {
3527 ldap_msgfree(lmap->ldap_res);
3528 lmap->ldap_res = NULL;
3529 }
3530 if (vp != NULL)
3531 free(vp);
3532 return NULL;
3533 }
3534 *statp = EX_OK;
2908 }
2909
3535 }
3536
2910 /* Need to build the args for map_rewrite here */
2911 attr_values = ldap_get_values(lmap->ld,entry,lmap->attr[0]);
2912 if (attr_values == NULL)
3537 if (ret == 0)
3538 errno = ETIMEDOUT;
3539 else
3540 errno = ldapmap_geterrno(lmap->ldap_ld);
3541 if (errno != LDAP_SUCCESS)
2913 {
3542 {
2914 /* bad things happened */
2915 result = NULL;
2916 *statp = EX_NOTFOUND;
2917 goto quick_exit;
3543 /* Must be an error */
3544 if (ret != 0)
3545 errno += E_LDAPBASE;
3546 if (!bitset(MF_OPTIONAL, map->map_mflags))
3547 {
3548 if (bitset(MF_NODEFER, map->map_mflags))
3549 syserr("Error getting LDAP results in map %s",
3550 map->map_mname);
3551 else
3552 syserr("421 4.0.0 Error getting LDAP results in map %s",
3553 map->map_mname);
3554 }
3555 *statp = EX_TEMPFAIL;
3556 if (vp != NULL)
3557 free(vp);
3558 return NULL;
2918 }
2919
3559 }
3560
2920 *statp = EX_OK;
3561 /* Did we match anything? */
3562 if (vp == NULL)
3563 return NULL;
2921
3564
2922 /* If there is more that one use the first */
2923 vp = attr_values[0];
2924 vsize = strlen(vp);
3565 /*
3566 ** If MF_NOREWRITE, we are special map which doesn't
3567 ** actually return a map value. Instead, we don't free
3568 ** ldap_res and let the calling function process the LDAP
3569 ** results. The caller should ldap_msgfree(lmap->ldap_res).
3570 */
2925
3571
2926 if (LogLevel > 9)
2927 sm_syslog(LOG_INFO, CurEnv->e_id,
2928 "ldap %.100s => %s",
2929 name, vp);
2930 if (bitset(MF_MATCHONLY, map->map_mflags))
2931 result = map_rewrite(map, name, strlen(name), NULL);
2932 else
2933 result = map_rewrite(map, vp, vsize, av);
3572 if (bitset(MF_NOREWRITE, map->map_mflags))
3573 {
3574 /* vp != NULL due to test above */
3575 free(vp);
3576 return "";
3577 }
2934
3578
2935 quick_exit:
2936 if (attr_values != NULL)
2937 ldap_value_free(attr_values);
2938 if (lmap != NULL)
2939 ldap_msgfree(lmap->res);
2940 ldap_map_stop(map);
2941 return result ;
3579 if (*statp == EX_OK)
3580 {
3581 /* vp != NULL due to test above */
3582 if (LogLevel > 9)
3583 sm_syslog(LOG_INFO, CurEnv->e_id,
3584 "ldap %.100s => %s", name, vp);
3585 if (bitset(MF_MATCHONLY, map->map_mflags))
3586 result = map_rewrite(map, name, strlen(name), NULL);
3587 else
3588 result = map_rewrite(map, vp, strlen(vp), av);
3589 free(vp);
3590 }
3591 return result;
2942}
2943
3592}
3593
2944
2945/*
3594/*
2946** LDAP_MAP_DEQUOTE - helper routine for ldap_map_parseargs
3595** LDAPMAP_FINDCONN -- find an LDAP connection to the server
3596**
3597** Cache LDAP connections based on the host, port, bind DN,
3598** and secret so we don't have multiple connections open to
3599** the same server for different maps.
3600**
3601** Parameters:
3602** lmap -- LDAP map information
3603**
3604** Returns:
3605** Symbol table entry for the LDAP connection.
3606**
2947*/
2948
3607*/
3608
2949char *
2950ldap_map_dequote(str)
2951 char *str;
3609static STAB *
3610ldapmap_findconn(lmap)
3611 LDAPMAP_STRUCT *lmap;
2952{
3612{
2953 char *p;
2954 char *start;
2955 p = str;
3613 int len;
3614 char *nbuf;
3615 STAB *s;
2956
3616
2957 if (*p == '"')
2958 {
2959 start = ++p;
2960 /* Should probably swallow initial whitespace here */
2961 }
3617 len = (lmap->ldap_host == NULL ? strlen("localhost") :
3618 strlen(lmap->ldap_host)) + 1 + 8 + 1 +
3619 (lmap->ldap_binddn == NULL ? 0 : strlen(lmap->ldap_binddn)) +
3620 1 +
3621 (lmap->ldap_secret == NULL ? 0 : strlen(lmap->ldap_secret)) +
3622 1;
3623 nbuf = xalloc(len);
3624 snprintf(nbuf, len, "%s%c%d%c%s%c%s",
3625 (lmap->ldap_host == NULL ? "localhost" : lmap->ldap_host),
3626 CONDELSE,
3627 lmap->ldap_port,
3628 CONDELSE,
3629 (lmap->ldap_binddn == NULL ? "" : lmap->ldap_binddn),
3630 CONDELSE,
3631 (lmap->ldap_secret == NULL ? "" : lmap->ldap_secret));
3632 s = stab(nbuf, ST_LDAP, ST_ENTER);
3633 free(nbuf);
3634 return s;
3635}
3636 /*
3637** LDAPMAP_SETOPTS -- set LDAP options
3638**
3639** Parameters:
3640** ld -- LDAP session handle
3641** lmap -- LDAP map information
3642**
3643** Returns:
3644** None.
3645**
3646*/
3647
3648static void
3649ldapmap_setopts(ld, lmap)
3650 LDAP *ld;
3651 LDAPMAP_STRUCT *lmap;
3652{
3653# if USE_LDAP_SET_OPTION
3654 ldap_set_option(ld, LDAP_OPT_DEREF, &lmap->ldap_deref);
3655 if (bitset(LDAP_OPT_REFERRALS, lmap->ldap_options))
3656 ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON);
2962 else
3657 else
2963 {
2964 return(str);
2965 }
2966 while (*p != '"' && *p != '\0')
2967 {
2968 p++;
2969 }
2970 if (*p != '\0')
2971 *p = '\0';
2972 return start;
3658 ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
3659 ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->ldap_sizelimit);
3660 ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->ldap_timelimit);
3661# else /* USE_LDAP_SET_OPTION */
3662 /* From here on in we can use ldap internal timelimits */
3663 ld->ld_deref = lmap->ldap_deref;
3664 ld->ld_options = lmap->ldap_options;
3665 ld->ld_sizelimit = lmap->ldap_sizelimit;
3666 ld->ld_timelimit = lmap->ldap_timelimit;
3667# endif /* USE_LDAP_SET_OPTION */
2973}
3668}
3669 /*
3670** LDAPMAP_GETERRNO -- get ldap errno value
3671**
3672** Parameters:
3673** ld -- LDAP session handle
3674**
3675** Returns:
3676** LDAP errno.
3677**
3678*/
2974
3679
3680static int
3681ldapmap_geterrno(ld)
3682 LDAP *ld;
3683{
3684 int err = LDAP_SUCCESS;
3685
3686# if defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3
3687 (void) ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
3688# else /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
3689# ifdef LDAP_OPT_SIZELIMIT
3690 err = ldap_get_lderrno(ld, NULL, NULL);
3691# else /* LDAP_OPT_SIZELIMIT */
3692 err = ld->ld_errno;
3693
3694 /*
3695 ** Reset value to prevent lingering LDAP_DECODING_ERROR due to
3696 ** OpenLDAP 1.X's hack (see above)
3697 */
3698
3699 ld->ld_errno = LDAP_SUCCESS;
3700# endif /* LDAP_OPT_SIZELIMIT */
3701# endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
3702 return err;
3703}
3704
2975/*
3705/*
2976** LDAP_MAP_PARSEARGS -- parse ldap map definition args.
3706** LDAPX_MAP_PARSEARGS -- print warning about use of ldapx map.
2977*/
2978
2979bool
3707*/
3708
3709bool
2980ldap_map_parseargs(map,args)
3710ldapx_map_parseargs(map, args)
2981 MAP *map;
2982 char *args;
2983{
3711 MAP *map;
3712 char *args;
3713{
2984 register char *p = args;
2985 register int done;
2986 LDAP_MAP_STRUCT *lmap;
3714 printf("Warning: The \"ldapx\" map class is deprecated and will be removed in a future\n");
3715 printf(" version. Use the \"ldap\" map class instead for map \"%s\".\n",
3716 map->map_mname);
3717 return ldapmap_parseargs(map, args);
3718}
2987
3719
2988 /* We need to alloc an LDAP_MAP_STRUCT struct */
2989 lmap = (LDAP_MAP_STRUCT *) xalloc(sizeof(LDAP_MAP_STRUCT));
3720/*
3721** LDAPMAP_PARSEARGS -- parse ldap map definition args.
3722*/
2990
3723
2991 /* Set default int's here , default strings below */
2992 lmap->ldapport = DEFAULT_LDAP_MAP_PORT;
2993 lmap->deref = DEFAULT_LDAP_MAP_DEREF;
2994 lmap->timelimit = DEFAULT_LDAP_MAP_TIMELIMIT;
2995 lmap->sizelimit = DEFAULT_LDAP_MAP_SIZELIMIT;
2996 lmap->ldap_options = DEFAULT_LDAP_MAP_LDAP_OPTIONS;
2997 lmap->method = DEFAULT_LDAP_MAP_METHOD;
2998 lmap->scope = DEFAULT_LDAP_MAP_SCOPE;
2999 lmap->attrsonly = DEFAULT_LDAP_MAP_ATTRSONLY;
3000 lmap->timeout.tv_sec = DEFAULT_LDAP_MAP_TIMELIMIT;
3001 lmap->timeout.tv_usec = 0;
3724struct lamvalues LDAPAuthMethods[] =
3725{
3726 { "none", LDAP_AUTH_NONE },
3727 { "simple", LDAP_AUTH_SIMPLE },
3728# ifdef LDAP_AUTH_KRBV4
3729 { "krbv4", LDAP_AUTH_KRBV4 },
3730# endif /* LDAP_AUTH_KRBV4 */
3731 { NULL, 0 }
3732};
3002
3733
3003 /* Default char ptrs to NULL */
3004 lmap->binddn = NULL;
3005 lmap->passwd = NULL;
3006 lmap->base = NULL;
3007 lmap->ldaphost = NULL;
3734struct ladvalues LDAPAliasDereference[] =
3735{
3736 { "never", LDAP_DEREF_NEVER },
3737 { "always", LDAP_DEREF_ALWAYS },
3738 { "search", LDAP_DEREF_SEARCHING },
3739 { "find", LDAP_DEREF_FINDING },
3740 { NULL, 0 }
3741};
3008
3742
3009 /* Default general ptrs to NULL */
3010 lmap->ld = NULL;
3011 lmap->res = NULL;
3743struct lssvalues LDAPSearchScope[] =
3744{
3745 { "base", LDAP_SCOPE_BASE },
3746 { "one", LDAP_SCOPE_ONELEVEL },
3747 { "sub", LDAP_SCOPE_SUBTREE },
3748 { NULL, 0 }
3749};
3012
3750
3013 map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
3751bool
3752ldapmap_parseargs(map, args)
3753 MAP *map;
3754 char *args;
3755{
3756 bool secretread = TRUE;
3757 int i;
3758 register char *p = args;
3759 LDAPMAP_STRUCT *lmap;
3760 struct lamvalues *lam;
3761 struct ladvalues *lad;
3762 struct lssvalues *lss;
3763 char m_tmp[MAXPATHLEN + LDAPMAP_MAX_PASSWD];
3764
3765 /* Get ldap struct pointer from map */
3766 lmap = (LDAPMAP_STRUCT *) map->map_db1;
3767
3768 /* Check if setting the initial LDAP defaults */
3769 if (lmap == NULL || lmap != LDAPDefaults)
3770 {
3771 /* We need to alloc an LDAPMAP_STRUCT struct */
3772 lmap = (LDAPMAP_STRUCT *) xalloc(sizeof *lmap);
3773 if (LDAPDefaults == NULL)
3774 ldapmap_clear(lmap);
3775 else
3776 STRUCTCOPY(*LDAPDefaults, *lmap);
3777 }
3778
3779 /* there is no check whether there is really an argument */
3780 map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
3781 map->map_spacesub = SpaceSub; /* default value */
3014 for (;;)
3015 {
3016 while (isascii(*p) && isspace(*p))
3017 p++;
3018 if (*p != '-')
3019 break;
3020 switch (*++p)
3021 {

--- 21 unchanged lines hidden (view full) ---

3043 case 'A':
3044 map->map_mflags |= MF_APPEND;
3045 break;
3046
3047 case 'q':
3048 map->map_mflags |= MF_KEEPQUOTES;
3049 break;
3050
3782 for (;;)
3783 {
3784 while (isascii(*p) && isspace(*p))
3785 p++;
3786 if (*p != '-')
3787 break;
3788 switch (*++p)
3789 {

--- 21 unchanged lines hidden (view full) ---

3811 case 'A':
3812 map->map_mflags |= MF_APPEND;
3813 break;
3814
3815 case 'q':
3816 map->map_mflags |= MF_KEEPQUOTES;
3817 break;
3818
3051 case 't':
3052 map->map_mflags |= MF_NODEFER;
3053 break;
3054
3055 case 'a':
3056 map->map_app = ++p;
3057 break;
3058
3059 case 'T':
3060 map->map_tapp = ++p;
3061 break;
3062
3819 case 'a':
3820 map->map_app = ++p;
3821 break;
3822
3823 case 'T':
3824 map->map_tapp = ++p;
3825 break;
3826
3063 /* Start of ldap_map specific args */
3827 case 't':
3828 map->map_mflags |= MF_NODEFER;
3829 break;
3830
3831 case 'S':
3832 map->map_spacesub = *++p;
3833 break;
3834
3835 case 'D':
3836 map->map_mflags |= MF_DEFER;
3837 break;
3838
3839 case 'z':
3840 if (*++p != '\\')
3841 map->map_coldelim = *p;
3842 else
3843 {
3844 switch (*++p)
3845 {
3846 case 'n':
3847 map->map_coldelim = '\n';
3848 break;
3849
3850 case 't':
3851 map->map_coldelim = '\t';
3852 break;
3853
3854 default:
3855 map->map_coldelim = '\\';
3856 }
3857 }
3858 break;
3859
3860 /* Start of ldapmap specific args */
3064 case 'k': /* search field */
3065 while (isascii(*++p) && isspace(*p))
3066 continue;
3861 case 'k': /* search field */
3862 while (isascii(*++p) && isspace(*p))
3863 continue;
3067 lmap->filter = p;
3864 lmap->ldap_filter = p;
3068 break;
3069
3070 case 'v': /* attr to return */
3071 while (isascii(*++p) && isspace(*p))
3072 continue;
3865 break;
3866
3867 case 'v': /* attr to return */
3868 while (isascii(*++p) && isspace(*p))
3869 continue;
3073 lmap->attr[0] = p;
3074 lmap->attr[1] = NULL;
3870 lmap->ldap_attr[0] = p;
3871 lmap->ldap_attr[1] = NULL;
3075 break;
3076
3872 break;
3873
3874 case '1':
3875 map->map_mflags |= MF_SINGLEMATCH;
3876 break;
3877
3077 /* args stolen from ldapsearch.c */
3078 case 'R': /* don't auto chase referrals */
3878 /* args stolen from ldapsearch.c */
3879 case 'R': /* don't auto chase referrals */
3079#ifdef LDAP_REFERRALS
3880# ifdef LDAP_REFERRALS
3080 lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
3881 lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
3081#else /* LDAP_REFERRALS */
3882# else /* LDAP_REFERRALS */
3082 syserr("compile with -DLDAP_REFERRALS for referral support\n");
3883 syserr("compile with -DLDAP_REFERRALS for referral support\n");
3083#endif /* LDAP_REFERRALS */
3884# endif /* LDAP_REFERRALS */
3084 break;
3085
3885 break;
3886
3086 case 'n': /* retrieve attribute names only -- no values */
3087 lmap->attrsonly += 1;
3887 case 'n': /* retrieve attribute names only */
3888 lmap->ldap_attrsonly = LDAPMAP_TRUE;
3088 break;
3089
3889 break;
3890
3090 case 's': /* search scope */
3091 if (strncasecmp(++p, "base", 4) == 0)
3891 case 'r': /* alias dereferencing */
3892 while (isascii(*++p) && isspace(*p))
3893 continue;
3894
3895 if (strncasecmp(p, "LDAP_DEREF_", 11) == 0)
3896 p += 11;
3897
3898 for (lad = LDAPAliasDereference;
3899 lad != NULL && lad->lad_name != NULL; lad++)
3092 {
3900 {
3093 lmap->scope = LDAP_SCOPE_BASE;
3901 if (strncasecmp(p, lad->lad_name,
3902 strlen(lad->lad_name)) == 0)
3903 break;
3094 }
3904 }
3095 else if (strncasecmp(p, "one", 3) == 0)
3905 if (lad->lad_name != NULL)
3906 lmap->ldap_deref = lad->lad_code;
3907 else
3096 {
3908 {
3097 lmap->scope = LDAP_SCOPE_ONELEVEL;
3909 /* bad config line */
3910 if (!bitset(MCF_OPTFILE,
3911 map->map_class->map_cflags))
3912 {
3913 char *ptr;
3914
3915 if ((ptr = strchr(p, ' ')) != NULL)
3916 *ptr = '\0';
3917 syserr("Deref must be [never|always|search|find] not %s in map %s",
3918 p, map->map_mname);
3919 if (ptr != NULL)
3920 *ptr = ' ';
3921 return FALSE;
3922 }
3098 }
3923 }
3099 else if (strncasecmp(p, "sub", 3) == 0)
3924 break;
3925
3926 case 's': /* search scope */
3927 while (isascii(*++p) && isspace(*p))
3928 continue;
3929
3930 if (strncasecmp(p, "LDAP_SCOPE_", 11) == 0)
3931 p += 11;
3932
3933 for (lss = LDAPSearchScope;
3934 lss != NULL && lss->lss_name != NULL; lss++)
3100 {
3935 {
3101 lmap->scope = LDAP_SCOPE_SUBTREE;
3936 if (strncasecmp(p, lss->lss_name,
3937 strlen(lss->lss_name)) == 0)
3938 break;
3102 }
3939 }
3940 if (lss->lss_name != NULL)
3941 lmap->ldap_scope = lss->lss_code;
3103 else
3942 else
3104 { /* bad config line */
3105 if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
3943 {
3944 /* bad config line */
3945 if (!bitset(MCF_OPTFILE,
3946 map->map_class->map_cflags))
3106 {
3107 char *ptr;
3108
3109 if ((ptr = strchr(p, ' ')) != NULL)
3110 *ptr = '\0';
3111 syserr("Scope must be [base|one|sub] not %s in map %s",
3112 p, map->map_mname);
3113 if (ptr != NULL)
3114 *ptr = ' ';
3115 return FALSE;
3116 }
3117 }
3118 break;
3119
3120 case 'h': /* ldap host */
3121 while (isascii(*++p) && isspace(*p))
3122 continue;
3947 {
3948 char *ptr;
3949
3950 if ((ptr = strchr(p, ' ')) != NULL)
3951 *ptr = '\0';
3952 syserr("Scope must be [base|one|sub] not %s in map %s",
3953 p, map->map_mname);
3954 if (ptr != NULL)
3955 *ptr = ' ';
3956 return FALSE;
3957 }
3958 }
3959 break;
3960
3961 case 'h': /* ldap host */
3962 while (isascii(*++p) && isspace(*p))
3963 continue;
3123 map->map_domain = p;
3124 lmap->ldaphost = p;
3964 lmap->ldap_host = p;
3125 break;
3126
3127 case 'b': /* search base */
3128 while (isascii(*++p) && isspace(*p))
3129 continue;
3965 break;
3966
3967 case 'b': /* search base */
3968 while (isascii(*++p) && isspace(*p))
3969 continue;
3130 lmap->base = p;
3970 lmap->ldap_base = p;
3131 break;
3132
3133 case 'p': /* ldap port */
3134 while (isascii(*++p) && isspace(*p))
3135 continue;
3971 break;
3972
3973 case 'p': /* ldap port */
3974 while (isascii(*++p) && isspace(*p))
3975 continue;
3136 lmap->ldapport = atoi(p);
3976 lmap->ldap_port = atoi(p);
3137 break;
3138
3139 case 'l': /* time limit */
3140 while (isascii(*++p) && isspace(*p))
3141 continue;
3977 break;
3978
3979 case 'l': /* time limit */
3980 while (isascii(*++p) && isspace(*p))
3981 continue;
3142 lmap->timelimit = atoi(p);
3143 lmap->timeout.tv_sec = lmap->timelimit;
3982 lmap->ldap_timelimit = atoi(p);
3983 lmap->ldap_timeout.tv_sec = lmap->ldap_timelimit;
3144 break;
3145
3984 break;
3985
3986 case 'Z':
3987 while (isascii(*++p) && isspace(*p))
3988 continue;
3989 lmap->ldap_sizelimit = atoi(p);
3990 break;
3991
3992 case 'd': /* Dn to bind to server as */
3993 while (isascii(*++p) && isspace(*p))
3994 continue;
3995 lmap->ldap_binddn = p;
3996 break;
3997
3998 case 'M': /* Method for binding */
3999 while (isascii(*++p) && isspace(*p))
4000 continue;
4001
4002 if (strncasecmp(p, "LDAP_AUTH_", 10) == 0)
4003 p += 10;
4004
4005 for (lam = LDAPAuthMethods;
4006 lam != NULL && lam->lam_name != NULL; lam++)
4007 {
4008 if (strncasecmp(p, lam->lam_name,
4009 strlen(lam->lam_name)) == 0)
4010 break;
4011 }
4012 if (lam->lam_name != NULL)
4013 lmap->ldap_method = lam->lam_code;
4014 else
4015 {
4016 /* bad config line */
4017 if (!bitset(MCF_OPTFILE,
4018 map->map_class->map_cflags))
4019 {
4020 char *ptr;
4021
4022 if ((ptr = strchr(p, ' ')) != NULL)
4023 *ptr = '\0';
4024 syserr("Method for binding must be [none|simple|krbv4] not %s in map %s",
4025 p, map->map_mname);
4026 if (ptr != NULL)
4027 *ptr = ' ';
4028 return FALSE;
4029 }
4030 }
4031
4032 break;
4033
4034 /*
4035 ** This is a string that is dependent on the
4036 ** method used defined above.
4037 */
4038
4039 case 'P': /* Secret password for binding */
4040 while (isascii(*++p) && isspace(*p))
4041 continue;
4042 lmap->ldap_secret = p;
4043 secretread = FALSE;
4044 break;
4045
4046 default:
4047 syserr("Illegal option %c map %s", *p, map->map_mname);
4048 break;
3146 }
3147
4049 }
4050
3148 /* need to account for quoted strings here arggg... */
3149 done = isascii(*p) && isspace(*p);
3150 while (*p != '\0' && !done)
4051 /* need to account for quoted strings here */
4052 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
3151 {
3152 if (*p == '"')
3153 {
3154 while (*++p != '"' && *p != '\0')
4053 {
4054 if (*p == '"')
4055 {
4056 while (*++p != '"' && *p != '\0')
3155 {
3156 continue;
4057 continue;
3157 }
3158 if (*p != '\0')
3159 p++;
3160 }
3161 else
4058 if (*p != '\0')
4059 p++;
4060 }
4061 else
3162 {
3163 p++;
4062 p++;
3164 }
3165 done = isascii(*p) && isspace(*p);
3166 }
3167
3168 if (*p != '\0')
3169 *p++ = '\0';
3170 }
3171
3172 if (map->map_app != NULL)
4063 }
4064
4065 if (*p != '\0')
4066 *p++ = '\0';
4067 }
4068
4069 if (map->map_app != NULL)
3173 map->map_app = newstr(ldap_map_dequote(map->map_app));
4070 map->map_app = newstr(ldapmap_dequote(map->map_app));
3174 if (map->map_tapp != NULL)
4071 if (map->map_tapp != NULL)
3175 map->map_tapp = newstr(ldap_map_dequote(map->map_tapp));
3176 if (map->map_domain != NULL)
3177 map->map_domain = newstr(ldap_map_dequote(map->map_domain));
4072 map->map_tapp = newstr(ldapmap_dequote(map->map_tapp));
3178
3179 /*
3180 ** We need to swallow up all the stuff into a struct
3181 ** and dump it into map->map_dbptr1
3182 */
3183
4073
4074 /*
4075 ** We need to swallow up all the stuff into a struct
4076 ** and dump it into map->map_dbptr1
4077 */
4078
3184 if (lmap->ldaphost != NULL)
3185 lmap->ldaphost = newstr(ldap_map_dequote(lmap->ldaphost));
3186 else
4079 if (lmap->ldap_host != NULL &&
4080 (LDAPDefaults == NULL ||
4081 LDAPDefaults == lmap ||
4082 LDAPDefaults->ldap_host != lmap->ldap_host))
4083 lmap->ldap_host = newstr(ldapmap_dequote(lmap->ldap_host));
4084 map->map_domain = lmap->ldap_host;
4085
4086 if (lmap->ldap_binddn != NULL &&
4087 (LDAPDefaults == NULL ||
4088 LDAPDefaults == lmap ||
4089 LDAPDefaults->ldap_binddn != lmap->ldap_binddn))
4090 lmap->ldap_binddn = newstr(ldapmap_dequote(lmap->ldap_binddn));
4091
4092 if (lmap->ldap_secret != NULL &&
4093 (LDAPDefaults == NULL ||
4094 LDAPDefaults == lmap ||
4095 LDAPDefaults->ldap_secret != lmap->ldap_secret))
3187 {
4096 {
3188 syserr("LDAP map: -h flag is required");
3189 return FALSE;
3190 }
4097 FILE *sfd;
4098 long sff = SFF_OPENASROOT|SFF_ROOTOK|SFF_NOWLINK|SFF_NOWWFILES|SFF_NOGWFILES;
3191
4099
3192 if (lmap->binddn != NULL)
3193 lmap->binddn = newstr(ldap_map_dequote(lmap->binddn));
3194 else
3195 lmap->binddn = DEFAULT_LDAP_MAP_BINDDN;
4100 if (DontLockReadFiles)
4101 sff |= SFF_NOLOCK;
3196
4102
4103 /* need to use method to map secret to passwd string */
4104 switch (lmap->ldap_method)
4105 {
4106 case LDAP_AUTH_NONE:
4107 /* Do nothing */
4108 break;
3197
4109
3198 if (lmap->passwd != NULL)
3199 lmap->passwd = newstr(ldap_map_dequote(lmap->passwd));
3200 else
3201 lmap->passwd = DEFAULT_LDAP_MAP_PASSWD;
4110 case LDAP_AUTH_SIMPLE:
3202
4111
3203 if (lmap->base != NULL)
3204 lmap->base = newstr(ldap_map_dequote(lmap->base));
3205 else
3206 {
3207 syserr("LDAP map: -b flag is required");
3208 return FALSE;
4112 /*
4113 ** Secret is the name of a file with
4114 ** the first line as the password.
4115 */
4116
4117 /* Already read in the secret? */
4118 if (secretread)
4119 break;
4120
4121 sfd = safefopen(ldapmap_dequote(lmap->ldap_secret),
4122 O_RDONLY, 0, sff);
4123 if (sfd == NULL)
4124 {
4125 syserr("LDAP map: cannot open secret %s",
4126 ldapmap_dequote(lmap->ldap_secret));
4127 return FALSE;
4128 }
4129 lmap->ldap_secret = sfgets(m_tmp, LDAPMAP_MAX_PASSWD,
4130 sfd, 0, "ldapmap_parseargs");
4131 (void) fclose(sfd);
4132 if (lmap->ldap_secret != NULL &&
4133 strlen(m_tmp) > 0)
4134 {
4135 /* chomp newline */
4136 if (m_tmp[strlen(m_tmp) - 1] == '\n')
4137 m_tmp[strlen(m_tmp) - 1] = '\0';
4138
4139 lmap->ldap_secret = m_tmp;
4140 }
4141 break;
4142
4143# ifdef LDAP_AUTH_KRBV4
4144 case LDAP_AUTH_KRBV4:
4145
4146 /*
4147 ** Secret is where the ticket file is
4148 ** stashed
4149 */
4150
4151 snprintf(m_tmp, MAXPATHLEN + LDAPMAP_MAX_PASSWD,
4152 "KRBTKFILE=%s",
4153 ldapmap_dequote(lmap->ldap_secret));
4154 lmap->ldap_secret = m_tmp;
4155 break;
4156# endif /* LDAP_AUTH_KRBV4 */
4157
4158 default: /* Should NEVER get here */
4159 syserr("LDAP map: Illegal value in lmap method");
4160 return FALSE;
4161 break;
4162 }
3209 }
3210
4163 }
4164
4165 if (lmap->ldap_secret != NULL &&
4166 (LDAPDefaults == NULL ||
4167 LDAPDefaults == lmap ||
4168 LDAPDefaults->ldap_secret != lmap->ldap_secret))
4169 lmap->ldap_secret = newstr(ldapmap_dequote(lmap->ldap_secret));
3211
4170
3212 if (lmap->filter != NULL)
3213 lmap->filter = newstr(ldap_map_dequote(lmap->filter));
4171 if (lmap->ldap_base != NULL &&
4172 (LDAPDefaults == NULL ||
4173 LDAPDefaults == lmap ||
4174 LDAPDefaults->ldap_base != lmap->ldap_base))
4175 lmap->ldap_base = newstr(ldapmap_dequote(lmap->ldap_base));
4176
4177 /*
4178 ** Save the server from extra work. If request is for a single
4179 ** match, tell the server to only return enough records to
4180 ** determine if there is a single match or not. This can not
4181 ** be one since the server would only return one and we wouldn't
4182 ** know if there were others available.
4183 */
4184
4185 if (bitset(MF_SINGLEMATCH, map->map_mflags))
4186 lmap->ldap_sizelimit = 2;
4187
4188 /* If setting defaults, don't process ldap_filter and ldap_attr */
4189 if (lmap == LDAPDefaults)
4190 return TRUE;
4191
4192 if (lmap->ldap_filter != NULL)
4193 lmap->ldap_filter = newstr(ldapmap_dequote(lmap->ldap_filter));
3214 else
3215 {
3216 if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
3217 {
3218 syserr("No filter given in map %s", map->map_mname);
3219 return FALSE;
3220 }
3221 }
4194 else
4195 {
4196 if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
4197 {
4198 syserr("No filter given in map %s", map->map_mname);
4199 return FALSE;
4200 }
4201 }
3222 if (lmap->attr[0] != NULL)
3223 lmap->attr[0] = newstr(ldap_map_dequote(lmap->attr[0]));
3224 else
4202
4203 if (lmap->ldap_attr[0] != NULL)
3225 {
4204 {
3226 if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
4205 i = 0;
4206 p = ldapmap_dequote(lmap->ldap_attr[0]);
4207 lmap->ldap_attr[0] = NULL;
4208
4209 while (p != NULL)
3227 {
4210 {
3228 syserr("No return attribute in %s", map->map_mname);
3229 return FALSE;
4211 char *v;
4212
4213 while (isascii(*p) && isspace(*p))
4214 p++;
4215 if (*p == '\0')
4216 break;
4217 v = p;
4218 p = strchr(v, ',');
4219 if (p != NULL)
4220 *p++ = '\0';
4221
4222 if (i == LDAPMAP_MAX_ATTR)
4223 {
4224 syserr("Too many return attributes in %s (max %d)",
4225 map->map_mname, LDAPMAP_MAX_ATTR);
4226 return FALSE;
4227 }
4228 if (*v != '\0')
4229 lmap->ldap_attr[i++] = newstr(v);
3230 }
4230 }
4231 lmap->ldap_attr[i] = NULL;
3231 }
3232
3233 map->map_db1 = (ARBPTR_T) lmap;
3234 return TRUE;
3235}
3236
4232 }
4233
4234 map->map_db1 = (ARBPTR_T) lmap;
4235 return TRUE;
4236}
4237
3237#endif /* LDAP Modules */
4238/*
4239** LDAPMAP_CLEAR -- set default values for LDAPMAP_STRUCT
4240**
4241** Parameters:
4242** lmap -- pointer to LDAPMAP_STRUCT to clear
4243**
4244** Returns:
4245** None.
4246**
4247*/
4248
4249static void
4250ldapmap_clear(lmap)
4251 LDAPMAP_STRUCT *lmap;
4252{
4253 lmap->ldap_host = NULL;
4254 lmap->ldap_port = LDAP_PORT;
4255 lmap->ldap_deref = LDAP_DEREF_NEVER;
4256 lmap->ldap_timelimit = LDAP_NO_LIMIT;
4257 lmap->ldap_sizelimit = LDAP_NO_LIMIT;
4258# ifdef LDAP_REFERRALS
4259 lmap->ldap_options = LDAP_OPT_REFERRALS;
4260# else /* LDAP_REFERRALS */
4261 lmap->ldap_options = 0;
4262# endif /* LDAP_REFERRALS */
4263 lmap->ldap_binddn = NULL;
4264 lmap->ldap_secret = NULL;
4265 lmap->ldap_method = LDAP_AUTH_SIMPLE;
4266 lmap->ldap_base = NULL;
4267 lmap->ldap_scope = LDAP_SCOPE_SUBTREE;
4268 lmap->ldap_attrsonly = LDAPMAP_FALSE;
4269 lmap->ldap_timeout.tv_sec = 0;
4270 lmap->ldap_timeout.tv_usec = 0;
4271 lmap->ldap_ld = NULL;
4272 lmap->ldap_filter = NULL;
4273 lmap->ldap_attr[0] = NULL;
4274 lmap->ldap_res = NULL;
4275}
3238 /*
4276 /*
3239** syslog map
4277** LDAPMAP_SET_DEFAULTS -- Read default map spec from LDAPDefaults in .cf
4278**
4279** Parameters:
4280** spec -- map argument string from LDAPDefaults option
4281**
4282** Returns:
4283** None.
4284**
3240*/
3241
4285*/
4286
3242#if _FFR_MAP_SYSLOG
4287void
4288ldapmap_set_defaults(spec)
4289 char *spec;
4290{
4291 MAP map;
3243
4292
4293 /* Allocate and set the default values */
4294 if (LDAPDefaults == NULL)
4295 LDAPDefaults = (LDAPMAP_STRUCT *) xalloc(sizeof *LDAPDefaults);
4296 ldapmap_clear(LDAPDefaults);
4297
4298 memset(&map, '\0', sizeof map);
4299 map.map_db1 = (ARBPTR_T) LDAPDefaults;
4300
4301 (void) ldapmap_parseargs(&map, spec);
4302
4303 /* These should never be set in LDAPDefaults */
4304 if (map.map_mflags != (MF_TRY0NULL|MF_TRY1NULL) ||
4305 map.map_spacesub != SpaceSub ||
4306 map.map_app != NULL ||
4307 map.map_tapp != NULL)
4308 {
4309 syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
4310 if (map.map_app != NULL)
4311 {
4312 free(map.map_app);
4313 map.map_app = NULL;
4314 }
4315 if (map.map_tapp != NULL)
4316 {
4317 free(map.map_tapp);
4318 map.map_tapp = NULL;
4319 }
4320 }
4321
4322 if (LDAPDefaults->ldap_filter != NULL)
4323 {
4324 syserr("readcf: option LDAPDefaultSpec: Do not set the LDAP search filter");
4325 /* don't free, it isn't malloc'ed in parseargs */
4326 LDAPDefaults->ldap_filter = NULL;
4327 }
4328
4329 if (LDAPDefaults->ldap_attr[0] != NULL)
4330 {
4331 syserr("readcf: option LDAPDefaultSpec: Do not set the requested LDAP attributes");
4332 /* don't free, they aren't malloc'ed in parseargs */
4333 LDAPDefaults->ldap_attr[0] = NULL;
4334 }
4335}
4336#endif /* LDAPMAP */
4337 /*
4338** PH map
4339*/
4340
4341#ifdef PH_MAP
4342
4343/*
4344** Support for the CCSO Nameserver (ph/qi).
4345** This code is intended to replace the so-called "ph mailer".
4346** Contributed by Mark D. Roth <roth@uiuc.edu>. Contact him for support.
4347*/
4348
4349# include <qiapi.h>
4350# include <qicode.h>
4351
4352/*
4353** PH_MAP_PARSEARGS -- parse ph map definition args.
4354*/
4355
4356bool
4357ph_map_parseargs(map, args)
4358 MAP *map;
4359 char *args;
4360{
4361 int i;
4362 register int done;
4363 PH_MAP_STRUCT *pmap = NULL;
4364 register char *p = args;
4365
4366 pmap = (PH_MAP_STRUCT *) xalloc(sizeof *pmap);
4367
4368 /* defaults */
4369 pmap->ph_servers = NULL;
4370 pmap->ph_field_list = NULL;
4371 pmap->ph_to_server = NULL;
4372 pmap->ph_from_server = NULL;
4373 pmap->ph_sockfd = -1;
4374 pmap->ph_timeout = 0;
4375
4376 map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
4377 for (;;)
4378 {
4379 while (isascii(*p) && isspace(*p))
4380 p++;
4381 if (*p != '-')
4382 break;
4383 switch (*++p)
4384 {
4385 case 'N':
4386 map->map_mflags |= MF_INCLNULL;
4387 map->map_mflags &= ~MF_TRY0NULL;
4388 break;
4389
4390 case 'O':
4391 map->map_mflags &= ~MF_TRY1NULL;
4392 break;
4393
4394 case 'o':
4395 map->map_mflags |= MF_OPTIONAL;
4396 break;
4397
4398 case 'f':
4399 map->map_mflags |= MF_NOFOLDCASE;
4400 break;
4401
4402 case 'm':
4403 map->map_mflags |= MF_MATCHONLY;
4404 break;
4405
4406 case 'A':
4407 map->map_mflags |= MF_APPEND;
4408 break;
4409
4410 case 'q':
4411 map->map_mflags |= MF_KEEPQUOTES;
4412 break;
4413
4414 case 't':
4415 map->map_mflags |= MF_NODEFER;
4416 break;
4417
4418 case 'a':
4419 map->map_app = ++p;
4420 break;
4421
4422 case 'T':
4423 map->map_tapp = ++p;
4424 break;
4425
4426#if _FFR_PHMAP_TIMEOUT
4427 case 'l':
4428 while (isascii(*++p) && isspace(*p))
4429 continue;
4430 pmap->ph_timeout = atoi(p);
4431 break;
4432#endif /* _FFR_PHMAP_TIMEOUT */
4433
4434 case 'S':
4435 map->map_spacesub = *++p;
4436 break;
4437
4438 case 'D':
4439 map->map_mflags |= MF_DEFER;
4440 break;
4441
4442 case 'h': /* PH server list */
4443 while (isascii(*++p) && isspace(*p))
4444 continue;
4445 pmap->ph_servers = p;
4446 break;
4447
4448 case 'v': /* fields to search for */
4449 while (isascii(*++p) && isspace(*p))
4450 continue;
4451 pmap->ph_field_list = p;
4452 break;
4453
4454 default:
4455 syserr("ph_map_parseargs: unknown option -%c\n", *p);
4456 }
4457
4458 /* try to account for quoted strings */
4459 done = isascii(*p) && isspace(*p);
4460 while (*p != '\0' && !done)
4461 {
4462 if (*p == '"')
4463 {
4464 while (*++p != '"' && *p != '\0')
4465 continue;
4466 if (*p != '\0')
4467 p++;
4468 }
4469 else
4470 p++;
4471 done = isascii(*p) && isspace(*p);
4472 }
4473
4474 if (*p != '\0')
4475 *p++ = '\0';
4476 }
4477
4478 if (map->map_app != NULL)
4479 map->map_app = newstr(ph_map_dequote(map->map_app));
4480 if (map->map_tapp != NULL)
4481 map->map_tapp = newstr(ph_map_dequote(map->map_tapp));
4482
4483 if (pmap->ph_field_list != NULL)
4484 pmap->ph_field_list = newstr(ph_map_dequote(pmap->ph_field_list));
4485 else
4486 pmap->ph_field_list = DEFAULT_PH_MAP_FIELDS;
4487
4488 if (pmap->ph_servers != NULL)
4489 pmap->ph_servers = newstr(ph_map_dequote(pmap->ph_servers));
4490 else
4491 {
4492 syserr("ph_map_parseargs: -h flag is required");
4493 return FALSE;
4494 }
4495
4496 map->map_db1 = (ARBPTR_T) pmap;
4497 return TRUE;
4498}
4499
4500#if _FFR_PHMAP_TIMEOUT
4501/*
4502** PH_MAP_CLOSE -- close the connection to the ph server
4503*/
4504
4505static void
4506ph_map_safeclose(map)
4507 MAP *map;
4508{
4509 int save_errno = errno;
4510 PH_MAP_STRUCT *pmap;
4511
4512 pmap = (PH_MAP_STRUCT *)map->map_db1;
4513
4514 if (pmap->ph_sockfd != -1)
4515 {
4516 (void) close(pmap->ph_sockfd);
4517 pmap->ph_sockfd = -1;
4518 }
4519 if (pmap->ph_from_server != NULL)
4520 {
4521 (void) fclose(pmap->ph_from_server);
4522 pmap->ph_from_server = NULL;
4523 }
4524 if (pmap->ph_to_server != NULL)
4525 {
4526 (void) fclose(pmap->ph_to_server);
4527 pmap->ph_to_server = NULL;
4528 }
4529 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
4530 errno = save_errno;
4531}
4532
4533void
4534ph_map_close(map)
4535 MAP *map;
4536{
4537 PH_MAP_STRUCT *pmap;
4538
4539 pmap = (PH_MAP_STRUCT *)map->map_db1;
4540 (void) fprintf(pmap->ph_to_server, "quit\n");
4541 (void) fflush(pmap->ph_to_server);
4542 ph_map_safeclose(map);
4543}
4544
4545static jmp_buf PHTimeout;
4546
4547/* ARGSUSED */
4548static void
4549ph_timeout_func(sig_no)
4550 int sig_no;
4551{
4552 longjmp(PHTimeout, 1);
4553}
4554#else /* _FFR_PHMAP_TIMEOUT */
4555/*
4556** PH_MAP_CLOSE -- close the connection to the ph server
4557*/
4558
4559void
4560ph_map_close(map)
4561 MAP *map;
4562{
4563 PH_MAP_STRUCT *pmap;
4564
4565 pmap = (PH_MAP_STRUCT *)map->map_db1;
4566 CloseQi(pmap->ph_to_server, pmap->ph_from_server);
4567 pmap->ph_to_server = NULL;
4568 pmap->ph_from_server = NULL;
4569}
4570#endif /* _FFR_PHMAP_TIMEOUT */
4571
4572 /*
4573** PH_MAP_OPEN -- sub for opening PH map
4574*/
4575bool
4576ph_map_open(map, mode)
4577 MAP *map;
4578 int mode;
4579{
4580#if !_FFR_PHMAP_TIMEOUT
4581 int save_errno = 0;
4582#endif /* !_FFR_PHMAP_TIMEOUT */
4583 int j;
4584 char *hostlist, *tmp;
4585 QIR *server_data = NULL;
4586 PH_MAP_STRUCT *pmap;
4587#if _FFR_PHMAP_TIMEOUT
4588 register EVENT *ev = NULL;
4589#endif /* _FFR_PHMAP_TIMEOUT */
4590
4591 if (tTd(38, 2))
4592 dprintf("ph_map_open(%s)\n", map->map_mname);
4593
4594 mode &= O_ACCMODE;
4595 if (mode != O_RDONLY)
4596 {
4597 /* issue a pseudo-error message */
4598# ifdef ENOSYS
4599 errno = ENOSYS;
4600# else /* ENOSYS */
4601# ifdef EFTYPE
4602 errno = EFTYPE;
4603# else /* EFTYPE */
4604 errno = ENXIO;
4605# endif /* EFTYPE */
4606# endif /* ENOSYS */
4607 return FALSE;
4608 }
4609
4610 pmap = (PH_MAP_STRUCT *)map->map_db1;
4611
4612 hostlist = newstr(pmap->ph_servers);
4613 tmp = strtok(hostlist, " ");
4614 do
4615 {
4616#if _FFR_PHMAP_TIMEOUT
4617 if (pmap->ph_timeout != 0)
4618 {
4619 if (setjmp(PHTimeout) != 0)
4620 {
4621 ev = NULL;
4622 if (LogLevel > 1)
4623 sm_syslog(LOG_NOTICE, CurEnv->e_id,
4624 "timeout connecting to PH server %.100s",
4625 tmp);
4626# ifdef ETIMEDOUT
4627 errno = ETIMEDOUT;
4628# else /* ETIMEDOUT */
4629 errno = 0;
4630# endif /* ETIMEDOUT */
4631 goto ph_map_open_abort;
4632 }
4633 ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
4634 }
4635 if (!OpenQiSock(tmp, &(pmap->ph_sockfd)) &&
4636 !Sock2FILEs(pmap->ph_sockfd, &(pmap->ph_to_server),
4637 &(pmap->ph_from_server)) &&
4638 fprintf(pmap->ph_to_server, "id sendmail+phmap\n") >= 0 &&
4639 fflush(pmap->ph_to_server) == 0 &&
4640 (server_data = ReadQi(pmap->ph_from_server, &j)) != NULL &&
4641 server_data->code == 200)
4642 {
4643 if (ev != NULL)
4644 clrevent(ev);
4645 FreeQIR(server_data);
4646#else /* _FFR_PHMAP_TIMEOUT */
4647 if (OpenQi(tmp, &(pmap->ph_to_server),
4648 &(pmap->ph_from_server)) >= 0)
4649 {
4650 if (fprintf(pmap->ph_to_server,
4651 "id sendmail+phmap\n") < 0 ||
4652 fflush(pmap->ph_to_server) < 0 ||
4653 (server_data = ReadQi(pmap->ph_from_server,
4654 &j)) == NULL ||
4655 server_data->code != 200)
4656 {
4657 save_errno = errno;
4658 CloseQi(pmap->ph_to_server,
4659 pmap->ph_from_server);
4660 continue;
4661 }
4662 if (server_data != NULL)
4663 FreeQIR(server_data);
4664#endif /* _FFR_PHMAP_TIMEOUT */
4665 free(hostlist);
4666 return TRUE;
4667 }
4668#if _FFR_PHMAP_TIMEOUT
4669 ph_map_open_abort:
4670 if (ev != NULL)
4671 clrevent(ev);
4672 ph_map_safeclose(map);
4673 if (server_data != NULL)
4674 {
4675 FreeQIR(server_data);
4676 server_data = NULL;
4677 }
4678#else /* _FFR_PHMAP_TIMEOUT */
4679 save_errno = errno;
4680#endif /* _FFR_PHMAP_TIMEOUT */
4681 } while (tmp = strtok(NULL, " "));
4682
4683#if !_FFR_PHMAP_TIMEOUT
4684 errno = save_errno;
4685#endif /* !_FFR_PHMAP_TIMEOUT */
4686 if (!bitset(MF_OPTIONAL, map->map_mflags))
4687 {
4688 if (errno == 0 && !bitset(MF_NODEFER,map->map_mflags))
4689 errno = EAGAIN;
4690 syserr("ph_map_open: cannot connect to PH server");
4691 }
4692 else if (LogLevel > 1)
4693 sm_syslog(LOG_NOTICE, CurEnv->e_id,
4694 "ph_map_open: cannot connect to PH server");
4695 free(hostlist);
4696 return FALSE;
4697}
4698
4699/*
4700** PH_MAP_LOOKUP -- look up key from ph server
4701*/
4702
4703#if _FFR_PHMAP_TIMEOUT
4704# define MAX_PH_FIELDS 20
4705#endif /* _FFR_PHMAP_TIMEOUT */
4706
4707char *
4708ph_map_lookup(map, key, args, pstat)
4709 MAP *map;
4710 char *key;
4711 char **args;
4712 int *pstat;
4713{
4714 int j;
4715 size_t sz;
4716 char *tmp, *tmp2;
4717 char *message = NULL, *field = NULL, *fmtkey;
4718 QIR *server_data = NULL;
4719 QIR *qirp;
4720 char keybuf[MAXKEY + 1], fieldbuf[101];
4721#if _FFR_PHMAP_TIMEOUT
4722 QIR *hold_data[MAX_PH_FIELDS];
4723 int hold_data_idx = 0;
4724 register EVENT *ev = NULL;
4725#endif /* _FFR_PHMAP_TIMEOUT */
4726 PH_MAP_STRUCT *pmap;
4727
4728 pmap = (PH_MAP_STRUCT *)map->map_db1;
4729
4730 *pstat = EX_OK;
4731
4732#if _FFR_PHMAP_TIMEOUT
4733 if (pmap->ph_timeout != 0)
4734 {
4735 if (setjmp(PHTimeout) != 0)
4736 {
4737 ev = NULL;
4738 if (LogLevel > 1)
4739 sm_syslog(LOG_NOTICE, CurEnv->e_id,
4740 "timeout during PH lookup of %.100s",
4741 key);
4742# ifdef ETIMEDOUT
4743 errno = ETIMEDOUT;
4744# else /* ETIMEDOUT */
4745 errno = 0;
4746# endif /* ETIMEDOUT */
4747 *pstat = EX_TEMPFAIL;
4748 goto ph_map_lookup_abort;
4749 }
4750 ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
4751 }
4752
4753#endif /* _FFR_PHMAP_TIMEOUT */
4754 /* check all relevant fields */
4755 tmp = pmap->ph_field_list;
4756 do
4757 {
4758#if _FFR_PHMAP_TIMEOUT
4759 server_data = NULL;
4760#endif /* _FFR_PHMAP_TIMEOUT */
4761 while (isascii(*tmp) && isspace(*tmp))
4762 tmp++;
4763 if (*tmp == '\0')
4764 break;
4765 sz = strcspn(tmp, " ") + 1;
4766 if (sz > sizeof fieldbuf)
4767 sz = sizeof fieldbuf;
4768 (void) strlcpy(fieldbuf, tmp, sz);
4769 field = fieldbuf;
4770 tmp += sz;
4771
4772 (void) strlcpy(keybuf, key, sizeof keybuf);
4773 fmtkey = keybuf;
4774 if (strcmp(field, "alias") == 0)
4775 {
4776 /*
4777 ** for alias lookups, replace any punctuation
4778 ** characters with '-'
4779 */
4780
4781 for (tmp2 = fmtkey; *tmp2 != '\0'; tmp2++)
4782 {
4783 if (isascii(*tmp2) && ispunct(*tmp2))
4784 *tmp2 = '-';
4785 }
4786 tmp2 = field;
4787 }
4788 else if (strcmp(field,"spacedname") == 0)
4789 {
4790 /*
4791 ** for "spaced" name lookups, replace any
4792 ** punctuation characters with a space
4793 */
4794
4795 for (tmp2 = fmtkey; *tmp2 != '\0'; tmp2++)
4796 {
4797 if (isascii(*tmp2) && ispunct(*tmp2) &&
4798 *tmp2 != '*')
4799 *tmp2 = ' ';
4800 }
4801 tmp2 = &(field[6]);
4802 }
4803 else
4804 tmp2 = field;
4805
4806 if (LogLevel > 9)
4807 sm_syslog(LOG_NOTICE, CurEnv->e_id,
4808 "ph_map_lookup: query %s=\"%s\" return email",
4809 tmp2, fmtkey);
4810 if (tTd(38, 20))
4811 dprintf("ph_map_lookup: query %s=\"%s\" return email\n",
4812 tmp2, fmtkey);
4813
4814 j = 0;
4815
4816 if (fprintf(pmap->ph_to_server, "query %s=%s return email\n",
4817 tmp2, fmtkey) < 0)
4818 message = "qi query command failed";
4819 else if (fflush(pmap->ph_to_server) < 0)
4820 message = "qi fflush failed";
4821 else if ((server_data = ReadQi(pmap->ph_from_server,
4822 &j)) == NULL)
4823 message = "ReadQi() returned NULL";
4824
4825#if _FFR_PHMAP_TIMEOUT
4826 if ((hold_data[hold_data_idx] = server_data) != NULL)
4827 {
4828 /* save pointer for later free() */
4829 hold_data_idx++;
4830 }
4831#endif /* _FFR_PHMAP_TIMEOUT */
4832
4833 if (server_data == NULL ||
4834 (server_data->code >= 400 &&
4835 server_data->code < 500))
4836 {
4837 /* temporary failure */
4838 *pstat = EX_TEMPFAIL;
4839#if _FFR_PHMAP_TIMEOUT
4840 break;
4841#else /* _FFR_PHMAP_TIMEOUT */
4842 if (server_data != NULL)
4843 {
4844 FreeQIR(server_data);
4845 server_data = NULL;
4846 }
4847 return NULL;
4848#endif /* _FFR_PHMAP_TIMEOUT */
4849 }
4850
4851 /*
4852 ** if we found a single match, break out.
4853 ** otherwise, try the next field.
4854 */
4855
4856 if (j == 1)
4857 break;
4858
4859 /*
4860 ** check for a single response which is an error:
4861 ** ReadQi() doesn't set j on error responses,
4862 ** but we should stop here instead of moving on if
4863 ** it happens (e.g., alias found but email field empty)
4864 */
4865
4866 for (qirp = server_data;
4867 qirp != NULL && qirp->code < 0;
4868 qirp++)
4869 {
4870 if (tTd(38, 20))
4871 dprintf("ph_map_lookup: QIR: %d:%d:%d:%s\n",
4872 qirp->code, qirp->subcode, qirp->field,
4873 (qirp->message ? qirp->message
4874 : "[NULL]"));
4875 if (qirp->code <= -500)
4876 {
4877 j = 0;
4878 goto ph_map_lookup_abort;
4879 }
4880 }
4881
4882#if _FFR_PHMAP_TIMEOUT
4883 } while (*tmp != '\0' && hold_data_idx < MAX_PH_FIELDS);
4884#else /* _FFR_PHMAP_TIMEOUT */
4885 } while (*tmp != '\0');
4886#endif /* _FFR_PHMAP_TIMEOUT */
4887
4888 ph_map_lookup_abort:
4889#if _FFR_PHMAP_TIMEOUT
4890 if (ev != NULL)
4891 clrevent(ev);
4892
4893 /*
4894 ** Return EX_TEMPFAIL if the timer popped
4895 ** or we got a temporary PH error
4896 */
4897
4898 if (*pstat == EX_TEMPFAIL)
4899 ph_map_safeclose(map);
4900
4901 /* if we didn't find a single match, bail out */
4902 if (*pstat == EX_OK && j != 1)
4903 *pstat = EX_UNAVAILABLE;
4904
4905 if (*pstat == EX_OK)
4906 {
4907 /*
4908 ** skip leading whitespace and chop at first address
4909 */
4910
4911 for (tmp = server_data->message;
4912 isascii(*tmp) && isspace(*tmp);
4913 tmp++)
4914 continue;
4915
4916 for (tmp2 = tmp; *tmp2 != '\0'; tmp2++)
4917 {
4918 if (isascii(*tmp2) && isspace(*tmp2))
4919 {
4920 *tmp2 = '\0';
4921 break;
4922 }
4923 }
4924
4925 if (tTd(38,20))
4926 dprintf("ph_map_lookup: %s => %s\n", key, tmp);
4927
4928 if (bitset(MF_MATCHONLY, map->map_mflags))
4929 message = map_rewrite(map, key, strlen(key), NULL);
4930 else
4931 message = map_rewrite(map, tmp, strlen(tmp), args);
4932 }
4933
4934 /*
4935 ** Deferred free() of returned server_data values
4936 ** the deferral is to avoid the risk of a free() being
4937 ** interrupted by the event timer. By now the timeout event
4938 ** has been cleared and none of the data is still in use.
4939 */
4940
4941 while (--hold_data_idx >= 0)
4942 {
4943 if (hold_data[hold_data_idx] != NULL)
4944 FreeQIR(hold_data[hold_data_idx]);
4945 }
4946
4947 if (*pstat == EX_OK)
4948 return message;
4949
4950 return NULL;
4951#else /* _FFR_PHMAP_TIMEOUT */
4952 /* if we didn't find a single match, bail out */
4953 if (j != 1)
4954 {
4955 *pstat = EX_UNAVAILABLE;
4956 if (server_data != NULL)
4957 {
4958 FreeQIR(server_data);
4959 server_data = NULL;
4960 }
4961 return NULL;
4962 }
4963
4964 /*
4965 ** skip leading whitespace and chop at first address
4966 */
4967
4968 for (tmp = server_data->message;
4969 isascii(*tmp) && isspace(*tmp);
4970 tmp++)
4971 continue;
4972
4973 for (tmp2 = tmp; *tmp2 != '\0'; tmp2++)
4974 {
4975 if (isascii(*tmp2) && isspace(*tmp2))
4976 {
4977 *tmp2 = '\0';
4978 break;
4979 }
4980 }
4981
4982 if (tTd(38,20))
4983 dprintf("ph_map_lookup: %s => %s\n", key, tmp);
4984
4985 if (bitset(MF_MATCHONLY, map->map_mflags))
4986 message = map_rewrite(map, key, strlen(key), NULL);
4987 else
4988 message = map_rewrite(map, tmp, strlen(tmp), args);
4989 if (server_data != NULL)
4990 {
4991 FreeQIR(server_data);
4992 server_data = NULL;
4993 }
4994 return message;
4995#endif /* _FFR_PHMAP_TIMEOUT */
4996}
4997#endif /* PH_MAP */
4998 /*
4999** syslog map
5000*/
5001
3244#define map_prio map_lockfd /* overload field */
3245
3246/*
3247** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages.
3248*/
3249
3250bool
3251syslog_map_parseargs(map, args)
3252 MAP *map;
3253 char *args;
3254{
3255 char *p = args;
3256 char *priority = NULL;
3257
5002#define map_prio map_lockfd /* overload field */
5003
5004/*
5005** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages.
5006*/
5007
5008bool
5009syslog_map_parseargs(map, args)
5010 MAP *map;
5011 char *args;
5012{
5013 char *p = args;
5014 char *priority = NULL;
5015
3258 for (;;)
5016 /* there is no check whether there is really an argument */
5017 while (*p != '\0')
3259 {
3260 while (isascii(*p) && isspace(*p))
3261 p++;
3262 if (*p != '-')
3263 break;
5018 {
5019 while (isascii(*p) && isspace(*p))
5020 p++;
5021 if (*p != '-')
5022 break;
3264 if (*++p == 'L')
3265 priority = ++p;
3266 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
3267 p++;
3268 if (*p != '\0')
3269 *p++ = '\0';
5023 ++p;
5024 if (*p == 'D')
5025 {
5026 map->map_mflags |= MF_DEFER;
5027 ++p;
5028 }
5029 else if (*p == 'S')
5030 {
5031 map->map_spacesub = *++p;
5032 if (*p != '\0')
5033 p++;
5034 }
5035 else if (*p == 'L')
5036 {
5037 while (*++p != '\0' && isascii(*p) && isspace(*p))
5038 continue;
5039 if (*p == '\0')
5040 break;
5041 priority = p;
5042 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
5043 p++;
5044 if (*p != '\0')
5045 *p++ = '\0';
5046 }
5047 else
5048 {
5049 syserr("Illegal option %c map syslog", *p);
5050 ++p;
5051 }
3270 }
3271
3272 if (priority == NULL)
3273 map->map_prio = LOG_INFO;
3274 else
3275 {
3276 if (strncasecmp("LOG_", priority, 4) == 0)
3277 priority += 4;
3278
3279#ifdef LOG_EMERG
3280 if (strcasecmp("EMERG", priority) == 0)
3281 map->map_prio = LOG_EMERG;
3282 else
5052 }
5053
5054 if (priority == NULL)
5055 map->map_prio = LOG_INFO;
5056 else
5057 {
5058 if (strncasecmp("LOG_", priority, 4) == 0)
5059 priority += 4;
5060
5061#ifdef LOG_EMERG
5062 if (strcasecmp("EMERG", priority) == 0)
5063 map->map_prio = LOG_EMERG;
5064 else
3283#endif
5065#endif /* LOG_EMERG */
3284#ifdef LOG_ALERT
3285 if (strcasecmp("ALERT", priority) == 0)
3286 map->map_prio = LOG_ALERT;
3287 else
5066#ifdef LOG_ALERT
5067 if (strcasecmp("ALERT", priority) == 0)
5068 map->map_prio = LOG_ALERT;
5069 else
3288#endif
5070#endif /* LOG_ALERT */
3289#ifdef LOG_CRIT
3290 if (strcasecmp("CRIT", priority) == 0)
3291 map->map_prio = LOG_CRIT;
3292 else
5071#ifdef LOG_CRIT
5072 if (strcasecmp("CRIT", priority) == 0)
5073 map->map_prio = LOG_CRIT;
5074 else
3293#endif
5075#endif /* LOG_CRIT */
3294#ifdef LOG_ERR
3295 if (strcasecmp("ERR", priority) == 0)
3296 map->map_prio = LOG_ERR;
3297 else
5076#ifdef LOG_ERR
5077 if (strcasecmp("ERR", priority) == 0)
5078 map->map_prio = LOG_ERR;
5079 else
3298#endif
5080#endif /* LOG_ERR */
3299#ifdef LOG_WARNING
3300 if (strcasecmp("WARNING", priority) == 0)
3301 map->map_prio = LOG_WARNING;
3302 else
5081#ifdef LOG_WARNING
5082 if (strcasecmp("WARNING", priority) == 0)
5083 map->map_prio = LOG_WARNING;
5084 else
3303#endif
5085#endif /* LOG_WARNING */
3304#ifdef LOG_NOTICE
3305 if (strcasecmp("NOTICE", priority) == 0)
3306 map->map_prio = LOG_NOTICE;
3307 else
5086#ifdef LOG_NOTICE
5087 if (strcasecmp("NOTICE", priority) == 0)
5088 map->map_prio = LOG_NOTICE;
5089 else
3308#endif
5090#endif /* LOG_NOTICE */
3309#ifdef LOG_INFO
3310 if (strcasecmp("INFO", priority) == 0)
3311 map->map_prio = LOG_INFO;
3312 else
5091#ifdef LOG_INFO
5092 if (strcasecmp("INFO", priority) == 0)
5093 map->map_prio = LOG_INFO;
5094 else
3313#endif
5095#endif /* LOG_INFO */
3314#ifdef LOG_DEBUG
3315 if (strcasecmp("DEBUG", priority) == 0)
3316 map->map_prio = LOG_DEBUG;
3317 else
5096#ifdef LOG_DEBUG
5097 if (strcasecmp("DEBUG", priority) == 0)
5098 map->map_prio = LOG_DEBUG;
5099 else
3318#endif
5100#endif /* LOG_DEBUG */
3319 {
3320 syserr("syslog_map_parseargs: Unknown priority %s\n",
3321 priority);
3322 return FALSE;
3323 }
3324 }
3325 return TRUE;
3326}

--- 9 unchanged lines hidden (view full) ---

3336 char **args;
3337 int *statp;
3338{
3339 char *ptr = map_rewrite(map, string, strlen(string), args);
3340
3341 if (ptr != NULL)
3342 {
3343 if (tTd(38, 20))
5101 {
5102 syserr("syslog_map_parseargs: Unknown priority %s\n",
5103 priority);
5104 return FALSE;
5105 }
5106 }
5107 return TRUE;
5108}

--- 9 unchanged lines hidden (view full) ---

5118 char **args;
5119 int *statp;
5120{
5121 char *ptr = map_rewrite(map, string, strlen(string), args);
5122
5123 if (ptr != NULL)
5124 {
5125 if (tTd(38, 20))
3344 printf("syslog_map_lookup(%s (priority %d): %s\n",
3345 map->map_mname, map->map_prio, ptr);
5126 dprintf("syslog_map_lookup(%s (priority %d): %s\n",
5127 map->map_mname, map->map_prio, ptr);
3346
3347 sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr);
3348 }
3349
3350 *statp = EX_OK;
3351 return "";
3352}
3353
5128
5129 sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr);
5130 }
5131
5132 *statp = EX_OK;
5133 return "";
5134}
5135
3354#endif /* _FFR_MAP_SYSLOG */
3355 /*
3356** HESIOD Modules
3357*/
3358
3359#ifdef HESIOD
3360
3361bool
3362hes_map_open(map, mode)
3363 MAP *map;
3364 int mode;
3365{
3366 if (tTd(38, 2))
5136 /*
5137** HESIOD Modules
5138*/
5139
5140#ifdef HESIOD
5141
5142bool
5143hes_map_open(map, mode)
5144 MAP *map;
5145 int mode;
5146{
5147 if (tTd(38, 2))
3367 printf("hes_map_open(%s, %s, %d)\n",
5148 dprintf("hes_map_open(%s, %s, %d)\n",
3368 map->map_mname, map->map_file, mode);
3369
3370 if (mode != O_RDONLY)
3371 {
3372 /* issue a pseudo-error message */
5149 map->map_mname, map->map_file, mode);
5150
5151 if (mode != O_RDONLY)
5152 {
5153 /* issue a pseudo-error message */
3373#ifdef ENOSYS
5154# ifdef ENOSYS
3374 errno = ENOSYS;
5155 errno = ENOSYS;
3375#else
3376# ifdef EFTYPE
5156# else /* ENOSYS */
5157# ifdef EFTYPE
3377 errno = EFTYPE;
5158 errno = EFTYPE;
3378# else
5159# else /* EFTYPE */
3379 errno = ENXIO;
5160 errno = ENXIO;
3380# endif
3381#endif
5161# endif /* EFTYPE */
5162# endif /* ENOSYS */
3382 return FALSE;
3383 }
3384
5163 return FALSE;
5164 }
5165
3385#ifdef HESIOD_INIT
5166# ifdef HESIOD_INIT
3386 if (HesiodContext != NULL || hesiod_init(&HesiodContext) == 0)
3387 return TRUE;
3388
3389 if (!bitset(MF_OPTIONAL, map->map_mflags))
5167 if (HesiodContext != NULL || hesiod_init(&HesiodContext) == 0)
5168 return TRUE;
5169
5170 if (!bitset(MF_OPTIONAL, map->map_mflags))
3390 syserr("421 cannot initialize Hesiod map (%s)",
5171 syserr("421 4.0.0 cannot initialize Hesiod map (%s)",
3391 errstring(errno));
3392 return FALSE;
5172 errstring(errno));
5173 return FALSE;
3393#else
5174# else /* HESIOD_INIT */
3394 if (hes_error() == HES_ER_UNINIT)
3395 hes_init();
3396 switch (hes_error())
3397 {
3398 case HES_ER_OK:
3399 case HES_ER_NOTFOUND:
3400 return TRUE;
3401 }
3402
3403 if (!bitset(MF_OPTIONAL, map->map_mflags))
5175 if (hes_error() == HES_ER_UNINIT)
5176 hes_init();
5177 switch (hes_error())
5178 {
5179 case HES_ER_OK:
5180 case HES_ER_NOTFOUND:
5181 return TRUE;
5182 }
5183
5184 if (!bitset(MF_OPTIONAL, map->map_mflags))
3404 syserr("421 cannot initialize Hesiod map (%d)", hes_error());
5185 syserr("421 4.0.0 cannot initialize Hesiod map (%d)", hes_error());
3405
3406 return FALSE;
5186
5187 return FALSE;
3407#endif /* HESIOD_INIT */
5188# endif /* HESIOD_INIT */
3408}
3409
3410char *
3411hes_map_lookup(map, name, av, statp)
3412 MAP *map;
3413 char *name;
3414 char **av;
3415 int *statp;
3416{
3417 char **hp;
3418
3419 if (tTd(38, 20))
5189}
5190
5191char *
5192hes_map_lookup(map, name, av, statp)
5193 MAP *map;
5194 char *name;
5195 char **av;
5196 int *statp;
5197{
5198 char **hp;
5199
5200 if (tTd(38, 20))
3420 printf("hes_map_lookup(%s, %s)\n", map->map_file, name);
5201 dprintf("hes_map_lookup(%s, %s)\n", map->map_file, name);
3421
3422 if (name[0] == '\\')
3423 {
3424 char *np;
3425 int nl;
3426 char nbuf[MAXNAME];
3427
3428 nl = strlen(name);
3429 if (nl < sizeof nbuf - 1)
3430 np = nbuf;
3431 else
3432 np = xalloc(strlen(name) + 2);
3433 np[0] = '\\';
5202
5203 if (name[0] == '\\')
5204 {
5205 char *np;
5206 int nl;
5207 char nbuf[MAXNAME];
5208
5209 nl = strlen(name);
5210 if (nl < sizeof nbuf - 1)
5211 np = nbuf;
5212 else
5213 np = xalloc(strlen(name) + 2);
5214 np[0] = '\\';
3434 strcpy(&np[1], name);
3435#ifdef HESIOD_INIT
5215 (void) strlcpy(&np[1], name, (sizeof nbuf) - 1);
5216# ifdef HESIOD_INIT
3436 hp = hesiod_resolve(HesiodContext, np, map->map_file);
5217 hp = hesiod_resolve(HesiodContext, np, map->map_file);
3437#else
5218# else /* HESIOD_INIT */
3438 hp = hes_resolve(np, map->map_file);
5219 hp = hes_resolve(np, map->map_file);
3439#endif /* HESIOD_INIT */
5220# endif /* HESIOD_INIT */
3440 if (np != nbuf)
3441 free(np);
3442 }
3443 else
3444 {
5221 if (np != nbuf)
5222 free(np);
5223 }
5224 else
5225 {
3445#ifdef HESIOD_INIT
5226# ifdef HESIOD_INIT
3446 hp = hesiod_resolve(HesiodContext, name, map->map_file);
5227 hp = hesiod_resolve(HesiodContext, name, map->map_file);
3447#else
5228# else /* HESIOD_INIT */
3448 hp = hes_resolve(name, map->map_file);
5229 hp = hes_resolve(name, map->map_file);
3449#endif /* HESIOD_INIT */
5230# endif /* HESIOD_INIT */
3450 }
5231 }
3451#ifdef HESIOD_INIT
5232# ifdef HESIOD_INIT
3452 if (hp == NULL)
3453 return NULL;
3454 if (*hp == NULL)
3455 {
3456 hesiod_free_list(HesiodContext, hp);
3457 switch (errno)
3458 {
3459 case ENOENT:

--- 5 unchanged lines hidden (view full) ---

3465 break;
3466 case ENOMEM:
3467 default:
3468 *statp = EX_UNAVAILABLE;
3469 break;
3470 }
3471 return NULL;
3472 }
5233 if (hp == NULL)
5234 return NULL;
5235 if (*hp == NULL)
5236 {
5237 hesiod_free_list(HesiodContext, hp);
5238 switch (errno)
5239 {
5240 case ENOENT:

--- 5 unchanged lines hidden (view full) ---

5246 break;
5247 case ENOMEM:
5248 default:
5249 *statp = EX_UNAVAILABLE;
5250 break;
5251 }
5252 return NULL;
5253 }
3473#else
5254# else /* HESIOD_INIT */
3474 if (hp == NULL || hp[0] == NULL)
3475 {
3476 switch (hes_error())
3477 {
3478 case HES_ER_OK:
3479 *statp = EX_OK;
3480 break;
3481

--- 6 unchanged lines hidden (view full) ---

3488 break;
3489
3490 case HES_ER_NET:
3491 *statp = EX_TEMPFAIL;
3492 break;
3493 }
3494 return NULL;
3495 }
5255 if (hp == NULL || hp[0] == NULL)
5256 {
5257 switch (hes_error())
5258 {
5259 case HES_ER_OK:
5260 *statp = EX_OK;
5261 break;
5262

--- 6 unchanged lines hidden (view full) ---

5269 break;
5270
5271 case HES_ER_NET:
5272 *statp = EX_TEMPFAIL;
5273 break;
5274 }
5275 return NULL;
5276 }
3496#endif /* HESIOD_INIT */
5277# endif /* HESIOD_INIT */
3497
3498 if (bitset(MF_MATCHONLY, map->map_mflags))
3499 return map_rewrite(map, name, strlen(name), NULL);
3500 else
3501 return map_rewrite(map, hp[0], strlen(hp[0]), av);
3502}
3503
5278
5279 if (bitset(MF_MATCHONLY, map->map_mflags))
5280 return map_rewrite(map, name, strlen(name), NULL);
5281 else
5282 return map_rewrite(map, hp[0], strlen(hp[0]), av);
5283}
5284
3504#endif
5285#endif /* HESIOD */
3505 /*
3506** NeXT NETINFO Modules
3507*/
3508
3509#if NETINFO
3510
3511# define NETINFO_DEFAULT_DIR "/aliases"
3512# define NETINFO_DEFAULT_PROPERTY "members"
3513
5286 /*
5287** NeXT NETINFO Modules
5288*/
5289
5290#if NETINFO
5291
5292# define NETINFO_DEFAULT_DIR "/aliases"
5293# define NETINFO_DEFAULT_PROPERTY "members"
5294
3514extern char *ni_propval __P((char *, char *, char *, char *, int));
3515
3516
3517/*
3518** NI_MAP_OPEN -- open NetInfo Aliases
3519*/
3520
3521bool
3522ni_map_open(map, mode)
3523 MAP *map;
3524 int mode;
3525{
3526 if (tTd(38, 2))
5295/*
5296** NI_MAP_OPEN -- open NetInfo Aliases
5297*/
5298
5299bool
5300ni_map_open(map, mode)
5301 MAP *map;
5302 int mode;
5303{
5304 if (tTd(38, 2))
3527 printf("ni_map_open(%s, %s, %d)\n",
5305 dprintf("ni_map_open(%s, %s, %d)\n",
3528 map->map_mname, map->map_file, mode);
3529 mode &= O_ACCMODE;
3530
3531 if (*map->map_file == '\0')
3532 map->map_file = NETINFO_DEFAULT_DIR;
3533
3534 if (map->map_valcolnm == NULL)
3535 map->map_valcolnm = NETINFO_DEFAULT_PROPERTY;

--- 15 unchanged lines hidden (view full) ---

3551 char *name;
3552 char **av;
3553 int *statp;
3554{
3555 char *res;
3556 char *propval;
3557
3558 if (tTd(38, 20))
5306 map->map_mname, map->map_file, mode);
5307 mode &= O_ACCMODE;
5308
5309 if (*map->map_file == '\0')
5310 map->map_file = NETINFO_DEFAULT_DIR;
5311
5312 if (map->map_valcolnm == NULL)
5313 map->map_valcolnm = NETINFO_DEFAULT_PROPERTY;

--- 15 unchanged lines hidden (view full) ---

5329 char *name;
5330 char **av;
5331 int *statp;
5332{
5333 char *res;
5334 char *propval;
5335
5336 if (tTd(38, 20))
3559 printf("ni_map_lookup(%s, %s)\n", map->map_mname, name);
5337 dprintf("ni_map_lookup(%s, %s)\n", map->map_mname, name);
3560
3561 propval = ni_propval(map->map_file, map->map_keycolnm, name,
3562 map->map_valcolnm, map->map_coldelim);
3563
3564 if (propval == NULL)
3565 return NULL;
3566
3567 if (bitset(MF_MATCHONLY, map->map_mflags))
3568 res = map_rewrite(map, name, strlen(name), NULL);
3569 else
3570 res = map_rewrite(map, propval, strlen(propval), av);
3571 free(propval);
3572 return res;
3573}
3574
3575
5338
5339 propval = ni_propval(map->map_file, map->map_keycolnm, name,
5340 map->map_valcolnm, map->map_coldelim);
5341
5342 if (propval == NULL)
5343 return NULL;
5344
5345 if (bitset(MF_MATCHONLY, map->map_mflags))
5346 res = map_rewrite(map, name, strlen(name), NULL);
5347 else
5348 res = map_rewrite(map, propval, strlen(propval), av);
5349 free(propval);
5350 return res;
5351}
5352
5353
3576bool
5354static bool
3577ni_getcanonname(name, hbsize, statp)
3578 char *name;
3579 int hbsize;
3580 int *statp;
3581{
3582 char *vptr;
3583 char *ptr;
3584 char nbuf[MAXNAME + 1];
3585
3586 if (tTd(38, 20))
5355ni_getcanonname(name, hbsize, statp)
5356 char *name;
5357 int hbsize;
5358 int *statp;
5359{
5360 char *vptr;
5361 char *ptr;
5362 char nbuf[MAXNAME + 1];
5363
5364 if (tTd(38, 20))
3587 printf("ni_getcanonname(%s)\n", name);
5365 dprintf("ni_getcanonname(%s)\n", name);
3588
5366
3589 if (strlen(name) >= sizeof nbuf)
5367 if (strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
3590 {
3591 *statp = EX_UNAVAILABLE;
3592 return FALSE;
3593 }
5368 {
5369 *statp = EX_UNAVAILABLE;
5370 return FALSE;
5371 }
3594 (void) strcpy(nbuf, name);
3595 shorten_hostname(nbuf);
3596
3597 /* we only accept single token search key */
3598 if (strchr(nbuf, '.'))
3599 {
3600 *statp = EX_NOHOST;
3601 return FALSE;
3602 }

--- 8 unchanged lines hidden (view full) ---

3611 }
3612
3613 /* Only want the first machine name */
3614 if ((ptr = strchr(vptr, '\n')) != NULL)
3615 *ptr = '\0';
3616
3617 if (hbsize >= strlen(vptr))
3618 {
5372 shorten_hostname(nbuf);
5373
5374 /* we only accept single token search key */
5375 if (strchr(nbuf, '.'))
5376 {
5377 *statp = EX_NOHOST;
5378 return FALSE;
5379 }

--- 8 unchanged lines hidden (view full) ---

5388 }
5389
5390 /* Only want the first machine name */
5391 if ((ptr = strchr(vptr, '\n')) != NULL)
5392 *ptr = '\0';
5393
5394 if (hbsize >= strlen(vptr))
5395 {
3619 strcpy(name, vptr);
5396 (void) strlcpy(name, vptr, hbsize);
5397 free(vptr);
3620 *statp = EX_OK;
3621 return TRUE;
3622 }
3623 *statp = EX_UNAVAILABLE;
3624 free(vptr);
3625 return FALSE;
3626}
3627

--- 13 unchanged lines hidden (view full) ---

3641** we should return a string separated by this
3642** character.
3643**
3644** Returns:
3645** NULL -- if:
3646** 1. the directory is not found
3647** 2. the property name is not found
3648** 3. the property contains multiple values
5398 *statp = EX_OK;
5399 return TRUE;
5400 }
5401 *statp = EX_UNAVAILABLE;
5402 free(vptr);
5403 return FALSE;
5404}
5405

--- 13 unchanged lines hidden (view full) ---

5419** we should return a string separated by this
5420** character.
5421**
5422** Returns:
5423** NULL -- if:
5424** 1. the directory is not found
5425** 2. the property name is not found
5426** 3. the property contains multiple values
3649** 4. some error occured
5427** 4. some error occurred
3650** else -- the value of the lookup.
3651**
3652** Example:
3653** To search for an alias value, use:
3654** ni_propval("/aliases", "name", aliasname, "members", ',')
3655**
3656** Notes:
5428** else -- the value of the lookup.
5429**
5430** Example:
5431** To search for an alias value, use:
5432** ni_propval("/aliases", "name", aliasname, "members", ',')
5433**
5434** Notes:
3657** Caller should free the return value of ni_proval
5435** Caller should free the return value of ni_proval
3658*/
3659
3660# include <netinfo/ni.h>
3661
5436*/
5437
5438# include <netinfo/ni.h>
5439
3662# define LOCAL_NETINFO_DOMAIN "."
3663# define PARENT_NETINFO_DOMAIN ".."
3664# define MAX_NI_LEVELS 256
5440# define LOCAL_NETINFO_DOMAIN "."
5441# define PARENT_NETINFO_DOMAIN ".."
5442# define MAX_NI_LEVELS 256
3665
3666char *
3667ni_propval(keydir, keyprop, keyval, valprop, sepchar)
3668 char *keydir;
3669 char *keyprop;
3670 char *keyval;
3671 char *valprop;
3672 int sepchar;
3673{
3674 char *propval = NULL;
3675 int i;
5443
5444char *
5445ni_propval(keydir, keyprop, keyval, valprop, sepchar)
5446 char *keydir;
5447 char *keyprop;
5448 char *keyval;
5449 char *valprop;
5450 int sepchar;
5451{
5452 char *propval = NULL;
5453 int i;
3676 int j, alen;
5454 int j, alen, l;
3677 void *ni = NULL;
3678 void *lastni = NULL;
3679 ni_status nis;
3680 ni_id nid;
3681 ni_namelist ninl;
3682 register char *p;
3683 char keybuf[1024];
3684
3685 /*
3686 ** Create the full key from the two parts.
3687 **
3688 ** Note that directory can end with, e.g., "name=" to specify
3689 ** an alternate search property.
3690 */
3691
3692 i = strlen(keydir) + strlen(keyval) + 2;
3693 if (keyprop != NULL)
3694 i += strlen(keyprop) + 1;
5455 void *ni = NULL;
5456 void *lastni = NULL;
5457 ni_status nis;
5458 ni_id nid;
5459 ni_namelist ninl;
5460 register char *p;
5461 char keybuf[1024];
5462
5463 /*
5464 ** Create the full key from the two parts.
5465 **
5466 ** Note that directory can end with, e.g., "name=" to specify
5467 ** an alternate search property.
5468 */
5469
5470 i = strlen(keydir) + strlen(keyval) + 2;
5471 if (keyprop != NULL)
5472 i += strlen(keyprop) + 1;
3695 if (i > sizeof keybuf)
5473 if (i >= sizeof keybuf)
3696 return NULL;
5474 return NULL;
3697 strcpy(keybuf, keydir);
3698 strcat(keybuf, "/");
5475 (void) strlcpy(keybuf, keydir, sizeof keybuf);
5476 (void) strlcat(keybuf, "/", sizeof keybuf);
3699 if (keyprop != NULL)
3700 {
5477 if (keyprop != NULL)
5478 {
3701 strcat(keybuf, keyprop);
3702 strcat(keybuf, "=");
5479 (void) strlcat(keybuf, keyprop, sizeof keybuf);
5480 (void) strlcat(keybuf, "=", sizeof keybuf);
3703 }
5481 }
3704 strcat(keybuf, keyval);
5482 (void) strlcat(keybuf, keyval, sizeof keybuf);
3705
3706 if (tTd(38, 21))
5483
5484 if (tTd(38, 21))
3707 printf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
5485 dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
3708 keydir, keyprop, keyval, valprop, sepchar, keybuf);
3709 /*
3710 ** If the passed directory and property name are found
3711 ** in one of netinfo domains we need to search (starting
3712 ** from the local domain moving all the way back to the
3713 ** root domain) set propval to the property's value
3714 ** and return it.
3715 */
3716
3717 for (i = 0; i < MAX_NI_LEVELS && propval == NULL; i++)
3718 {
3719 if (i == 0)
3720 {
3721 nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
3722 if (tTd(38, 20))
5486 keydir, keyprop, keyval, valprop, sepchar, keybuf);
5487 /*
5488 ** If the passed directory and property name are found
5489 ** in one of netinfo domains we need to search (starting
5490 ** from the local domain moving all the way back to the
5491 ** root domain) set propval to the property's value
5492 ** and return it.
5493 */
5494
5495 for (i = 0; i < MAX_NI_LEVELS && propval == NULL; i++)
5496 {
5497 if (i == 0)
5498 {
5499 nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
5500 if (tTd(38, 20))
3723 printf("ni_open(LOCAL) = %d\n", nis);
5501 dprintf("ni_open(LOCAL) = %d\n", nis);
3724 }
3725 else
3726 {
3727 if (lastni != NULL)
3728 ni_free(lastni);
3729 lastni = ni;
3730 nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
3731 if (tTd(38, 20))
5502 }
5503 else
5504 {
5505 if (lastni != NULL)
5506 ni_free(lastni);
5507 lastni = ni;
5508 nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
5509 if (tTd(38, 20))
3732 printf("ni_open(PARENT) = %d\n", nis);
5510 dprintf("ni_open(PARENT) = %d\n", nis);
3733 }
3734
3735 /*
3736 ** Don't bother if we didn't get a handle on a
3737 ** proper domain. This is not necessarily an error.
3738 ** We would get a positive ni_status if, for instance
3739 ** we never found the directory or property and tried
3740 ** to open the parent of the root domain!

--- 12 unchanged lines hidden (view full) ---

3753 /*
3754 ** Find associated value information.
3755 */
3756
3757 if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0)
3758 continue;
3759
3760 if (tTd(38, 20))
5511 }
5512
5513 /*
5514 ** Don't bother if we didn't get a handle on a
5515 ** proper domain. This is not necessarily an error.
5516 ** We would get a positive ni_status if, for instance
5517 ** we never found the directory or property and tried
5518 ** to open the parent of the root domain!

--- 12 unchanged lines hidden (view full) ---

5531 /*
5532 ** Find associated value information.
5533 */
5534
5535 if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0)
5536 continue;
5537
5538 if (tTd(38, 20))
3761 printf("ni_lookupprop: len=%d\n", ninl.ni_namelist_len);
5539 dprintf("ni_lookupprop: len=%d\n",
5540 ninl.ni_namelist_len);
5541
3762 /*
3763 ** See if we have an acceptable number of values.
3764 */
3765
3766 if (ninl.ni_namelist_len <= 0)
3767 continue;
3768
3769 if (sepchar == '\0' && ninl.ni_namelist_len > 1)

--- 7 unchanged lines hidden (view full) ---

3777 */
3778
3779 alen = 1;
3780 for (j = 0; j < ninl.ni_namelist_len; j++)
3781 alen += strlen(ninl.ni_namelist_val[j]) + 1;
3782 propval = p = xalloc(alen);
3783 for (j = 0; j < ninl.ni_namelist_len; j++)
3784 {
5542 /*
5543 ** See if we have an acceptable number of values.
5544 */
5545
5546 if (ninl.ni_namelist_len <= 0)
5547 continue;
5548
5549 if (sepchar == '\0' && ninl.ni_namelist_len > 1)

--- 7 unchanged lines hidden (view full) ---

5557 */
5558
5559 alen = 1;
5560 for (j = 0; j < ninl.ni_namelist_len; j++)
5561 alen += strlen(ninl.ni_namelist_val[j]) + 1;
5562 propval = p = xalloc(alen);
5563 for (j = 0; j < ninl.ni_namelist_len; j++)
5564 {
3785 strcpy(p, ninl.ni_namelist_val[j]);
3786 p += strlen(p);
5565 (void) strlcpy(p, ninl.ni_namelist_val[j], alen);
5566 l = strlen(p);
5567 p += l;
3787 *p++ = sepchar;
5568 *p++ = sepchar;
5569 alen -= l + 1;
3788 }
3789 *--p = '\0';
3790
3791 ni_namelist_free(&ninl);
3792 }
3793
3794 /*
3795 ** Clean up.
3796 */
3797
3798 if (ni != NULL)
3799 ni_free(ni);
3800 if (lastni != NULL && ni != lastni)
3801 ni_free(lastni);
3802 if (tTd(38, 20))
5570 }
5571 *--p = '\0';
5572
5573 ni_namelist_free(&ninl);
5574 }
5575
5576 /*
5577 ** Clean up.
5578 */
5579
5580 if (ni != NULL)
5581 ni_free(ni);
5582 if (lastni != NULL && ni != lastni)
5583 ni_free(lastni);
5584 if (tTd(38, 20))
3803 printf("ni_propval returns: '%s'\n", propval);
5585 dprintf("ni_propval returns: '%s'\n", propval);
3804
3805 return propval;
3806}
3807
3808#endif /* NETINFO */
3809 /*
3810** TEXT (unindexed text file) Modules
3811**

--- 7 unchanged lines hidden (view full) ---

3819** TEXT_MAP_OPEN -- open text table
3820*/
3821
3822bool
3823text_map_open(map, mode)
3824 MAP *map;
3825 int mode;
3826{
5586
5587 return propval;
5588}
5589
5590#endif /* NETINFO */
5591 /*
5592** TEXT (unindexed text file) Modules
5593**

--- 7 unchanged lines hidden (view full) ---

5601** TEXT_MAP_OPEN -- open text table
5602*/
5603
5604bool
5605text_map_open(map, mode)
5606 MAP *map;
5607 int mode;
5608{
3827 int sff;
5609 long sff;
3828 int i;
3829
3830 if (tTd(38, 2))
5610 int i;
5611
5612 if (tTd(38, 2))
3831 printf("text_map_open(%s, %s, %d)\n",
5613 dprintf("text_map_open(%s, %s, %d)\n",
3832 map->map_mname, map->map_file, mode);
3833
3834 mode &= O_ACCMODE;
3835 if (mode != O_RDONLY)
3836 {
3837 errno = EPERM;
3838 return FALSE;
3839 }

--- 8 unchanged lines hidden (view full) ---

3848 if (map->map_file[0] != '/')
3849 {
3850 syserr("text map \"%s\": file name must be fully qualified",
3851 map->map_mname);
3852 return FALSE;
3853 }
3854
3855 sff = SFF_ROOTOK|SFF_REGONLY;
5614 map->map_mname, map->map_file, mode);
5615
5616 mode &= O_ACCMODE;
5617 if (mode != O_RDONLY)
5618 {
5619 errno = EPERM;
5620 return FALSE;
5621 }

--- 8 unchanged lines hidden (view full) ---

5630 if (map->map_file[0] != '/')
5631 {
5632 syserr("text map \"%s\": file name must be fully qualified",
5633 map->map_mname);
5634 return FALSE;
5635 }
5636
5637 sff = SFF_ROOTOK|SFF_REGONLY;
3856 if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
5638 if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
3857 sff |= SFF_NOWLINK;
5639 sff |= SFF_NOWLINK;
3858 if (!bitset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
5640 if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
3859 sff |= SFF_SAFEDIRPATH;
3860 if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName,
3861 sff, S_IRUSR, NULL)) != 0)
3862 {
5641 sff |= SFF_SAFEDIRPATH;
5642 if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName,
5643 sff, S_IRUSR, NULL)) != 0)
5644 {
5645 int save_errno = errno;
5646
3863 /* cannot open this map */
3864 if (tTd(38, 2))
5647 /* cannot open this map */
5648 if (tTd(38, 2))
3865 printf("\tunsafe map file: %d\n", i);
5649 dprintf("\tunsafe map file: %d\n", i);
5650 errno = save_errno;
3866 if (!bitset(MF_OPTIONAL, map->map_mflags))
3867 syserr("text map \"%s\": unsafe map file %s",
3868 map->map_mname, map->map_file);
3869 return FALSE;
3870 }
3871
3872 if (map->map_keycolnm == NULL)
3873 map->map_keycolno = 0;

--- 20 unchanged lines hidden (view full) ---

3894 map->map_valcolnm);
3895 return FALSE;
3896 }
3897 map->map_valcolno = atoi(map->map_valcolnm);
3898 }
3899
3900 if (tTd(38, 2))
3901 {
5651 if (!bitset(MF_OPTIONAL, map->map_mflags))
5652 syserr("text map \"%s\": unsafe map file %s",
5653 map->map_mname, map->map_file);
5654 return FALSE;
5655 }
5656
5657 if (map->map_keycolnm == NULL)
5658 map->map_keycolno = 0;

--- 20 unchanged lines hidden (view full) ---

5679 map->map_valcolnm);
5680 return FALSE;
5681 }
5682 map->map_valcolno = atoi(map->map_valcolnm);
5683 }
5684
5685 if (tTd(38, 2))
5686 {
3902 printf("text_map_open(%s, %s): delimiter = ",
5687 dprintf("text_map_open(%s, %s): delimiter = ",
3903 map->map_mname, map->map_file);
3904 if (map->map_coldelim == '\0')
5688 map->map_mname, map->map_file);
5689 if (map->map_coldelim == '\0')
3905 printf("(white space)\n");
5690 dprintf("(white space)\n");
3906 else
5691 else
3907 printf("%c\n", map->map_coldelim);
5692 dprintf("%c\n", map->map_coldelim);
3908 }
3909
3910 map->map_sff = sff;
3911 return TRUE;
3912}
3913
3914
3915/*

--- 9 unchanged lines hidden (view full) ---

3925{
3926 char *vp;
3927 auto int vsize;
3928 int buflen;
3929 FILE *f;
3930 char delim;
3931 int key_idx;
3932 bool found_it;
5693 }
5694
5695 map->map_sff = sff;
5696 return TRUE;
5697}
5698
5699
5700/*

--- 9 unchanged lines hidden (view full) ---

5710{
5711 char *vp;
5712 auto int vsize;
5713 int buflen;
5714 FILE *f;
5715 char delim;
5716 int key_idx;
5717 bool found_it;
3933 int sff = map->map_sff;
5718 long sff = map->map_sff;
3934 char search_key[MAXNAME + 1];
3935 char linebuf[MAXLINE];
3936 char buf[MAXNAME + 1];
5719 char search_key[MAXNAME + 1];
5720 char linebuf[MAXLINE];
5721 char buf[MAXNAME + 1];
3937 extern char *get_column __P((char *, int, char, char *, int));
3938
3939 found_it = FALSE;
3940 if (tTd(38, 20))
5722
5723 found_it = FALSE;
5724 if (tTd(38, 20))
3941 printf("text_map_lookup(%s, %s)\n", map->map_mname, name);
5725 dprintf("text_map_lookup(%s, %s)\n", map->map_mname, name);
3942
3943 buflen = strlen(name);
3944 if (buflen > sizeof search_key - 1)
3945 buflen = sizeof search_key - 1;
5726
5727 buflen = strlen(name);
5728 if (buflen > sizeof search_key - 1)
5729 buflen = sizeof search_key - 1;
3946 bcopy(name, search_key, buflen);
5730 memmove(search_key, name, buflen);
3947 search_key[buflen] = '\0';
3948 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
3949 makelower(search_key);
3950
3951 f = safefopen(map->map_file, O_RDONLY, FileMode, sff);
3952 if (f == NULL)
3953 {
3954 map->map_mflags &= ~(MF_VALID|MF_OPEN);

--- 14 unchanged lines hidden (view full) ---

3969 *p = '\0';
3970 p = get_column(linebuf, key_idx, delim, buf, sizeof buf);
3971 if (p != NULL && strcasecmp(search_key, p) == 0)
3972 {
3973 found_it = TRUE;
3974 break;
3975 }
3976 }
5731 search_key[buflen] = '\0';
5732 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
5733 makelower(search_key);
5734
5735 f = safefopen(map->map_file, O_RDONLY, FileMode, sff);
5736 if (f == NULL)
5737 {
5738 map->map_mflags &= ~(MF_VALID|MF_OPEN);

--- 14 unchanged lines hidden (view full) ---

5753 *p = '\0';
5754 p = get_column(linebuf, key_idx, delim, buf, sizeof buf);
5755 if (p != NULL && strcasecmp(search_key, p) == 0)
5756 {
5757 found_it = TRUE;
5758 break;
5759 }
5760 }
3977 fclose(f);
5761 (void) fclose(f);
3978 if (!found_it)
3979 {
3980 *statp = EX_NOTFOUND;
3981 return NULL;
3982 }
3983 vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof buf);
3984 if (vp == NULL)
3985 {
3986 *statp = EX_NOTFOUND;
3987 return NULL;
3988 }
3989 vsize = strlen(vp);
3990 *statp = EX_OK;
3991 if (bitset(MF_MATCHONLY, map->map_mflags))
3992 return map_rewrite(map, name, strlen(name), NULL);
3993 else
3994 return map_rewrite(map, vp, vsize, av);
3995}
3996
5762 if (!found_it)
5763 {
5764 *statp = EX_NOTFOUND;
5765 return NULL;
5766 }
5767 vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof buf);
5768 if (vp == NULL)
5769 {
5770 *statp = EX_NOTFOUND;
5771 return NULL;
5772 }
5773 vsize = strlen(vp);
5774 *statp = EX_OK;
5775 if (bitset(MF_MATCHONLY, map->map_mflags))
5776 return map_rewrite(map, name, strlen(name), NULL);
5777 else
5778 return map_rewrite(map, vp, vsize, av);
5779}
5780
3997
3998/*
3999** TEXT_GETCANONNAME -- look up canonical name in hosts file
4000*/
4001
5781/*
5782** TEXT_GETCANONNAME -- look up canonical name in hosts file
5783*/
5784
4002bool
5785static bool
4003text_getcanonname(name, hbsize, statp)
4004 char *name;
4005 int hbsize;
4006 int *statp;
4007{
4008 bool found;
4009 FILE *f;
4010 char linebuf[MAXLINE];
4011 char cbuf[MAXNAME + 1];
4012 char nbuf[MAXNAME + 1];
4013
4014 if (tTd(38, 20))
5786text_getcanonname(name, hbsize, statp)
5787 char *name;
5788 int hbsize;
5789 int *statp;
5790{
5791 bool found;
5792 FILE *f;
5793 char linebuf[MAXLINE];
5794 char cbuf[MAXNAME + 1];
5795 char nbuf[MAXNAME + 1];
5796
5797 if (tTd(38, 20))
4015 printf("text_getcanonname(%s)\n", name);
5798 dprintf("text_getcanonname(%s)\n", name);
4016
4017 if (strlen(name) >= (SIZE_T) sizeof nbuf)
4018 {
4019 *statp = EX_UNAVAILABLE;
4020 return FALSE;
4021 }
5799
5800 if (strlen(name) >= (SIZE_T) sizeof nbuf)
5801 {
5802 *statp = EX_UNAVAILABLE;
5803 return FALSE;
5804 }
4022 (void) strcpy(nbuf, name);
5805 (void) strlcpy(nbuf, name, sizeof nbuf);
4023 shorten_hostname(nbuf);
4024
4025 f = fopen(HostsFile, "r");
4026 if (f == NULL)
4027 {
4028 *statp = EX_UNAVAILABLE;
4029 return FALSE;
4030 }
4031 found = FALSE;
4032 while (!found && fgets(linebuf, MAXLINE, f) != NULL)
4033 {
4034 char *p = strpbrk(linebuf, "#\n");
4035
4036 if (p != NULL)
4037 *p = '\0';
4038 if (linebuf[0] != '\0')
4039 found = extract_canonname(nbuf, linebuf, cbuf, sizeof cbuf);
4040 }
5806 shorten_hostname(nbuf);
5807
5808 f = fopen(HostsFile, "r");
5809 if (f == NULL)
5810 {
5811 *statp = EX_UNAVAILABLE;
5812 return FALSE;
5813 }
5814 found = FALSE;
5815 while (!found && fgets(linebuf, MAXLINE, f) != NULL)
5816 {
5817 char *p = strpbrk(linebuf, "#\n");
5818
5819 if (p != NULL)
5820 *p = '\0';
5821 if (linebuf[0] != '\0')
5822 found = extract_canonname(nbuf, linebuf, cbuf, sizeof cbuf);
5823 }
4041 fclose(f);
5824 (void) fclose(f);
4042 if (!found)
4043 {
4044 *statp = EX_NOHOST;
4045 return FALSE;
4046 }
4047
4048 if ((SIZE_T) hbsize >= strlen(cbuf))
4049 {
5825 if (!found)
5826 {
5827 *statp = EX_NOHOST;
5828 return FALSE;
5829 }
5830
5831 if ((SIZE_T) hbsize >= strlen(cbuf))
5832 {
4050 strcpy(name, cbuf);
5833 (void) strlcpy(name, cbuf, hbsize);
4051 *statp = EX_OK;
4052 return TRUE;
4053 }
4054 *statp = EX_UNAVAILABLE;
4055 return FALSE;
4056}
4057 /*
4058** STAB (Symbol Table) Modules

--- 10 unchanged lines hidden (view full) ---

4069 register MAP *map;
4070 char *name;
4071 char **av;
4072 int *pstat;
4073{
4074 register STAB *s;
4075
4076 if (tTd(38, 20))
5834 *statp = EX_OK;
5835 return TRUE;
5836 }
5837 *statp = EX_UNAVAILABLE;
5838 return FALSE;
5839}
5840 /*
5841** STAB (Symbol Table) Modules

--- 10 unchanged lines hidden (view full) ---

5852 register MAP *map;
5853 char *name;
5854 char **av;
5855 int *pstat;
5856{
5857 register STAB *s;
5858
5859 if (tTd(38, 20))
4077 printf("stab_lookup(%s, %s)\n",
5860 dprintf("stab_lookup(%s, %s)\n",
4078 map->map_mname, name);
4079
4080 s = stab(name, ST_ALIAS, ST_FIND);
4081 if (s != NULL)
5861 map->map_mname, name);
5862
5863 s = stab(name, ST_ALIAS, ST_FIND);
5864 if (s != NULL)
4082 return (s->s_alias);
4083 return (NULL);
5865 return s->s_alias;
5866 return NULL;
4084}
4085
4086
4087/*
4088** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild)
4089*/
4090
4091void

--- 19 unchanged lines hidden (view full) ---

4111*/
4112
4113bool
4114stab_map_open(map, mode)
4115 register MAP *map;
4116 int mode;
4117{
4118 FILE *af;
5867}
5868
5869
5870/*
5871** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild)
5872*/
5873
5874void

--- 19 unchanged lines hidden (view full) ---

5894*/
5895
5896bool
5897stab_map_open(map, mode)
5898 register MAP *map;
5899 int mode;
5900{
5901 FILE *af;
4119 int sff;
5902 long sff;
4120 struct stat st;
4121
4122 if (tTd(38, 2))
5903 struct stat st;
5904
5905 if (tTd(38, 2))
4123 printf("stab_map_open(%s, %s, %d)\n",
5906 dprintf("stab_map_open(%s, %s, %d)\n",
4124 map->map_mname, map->map_file, mode);
4125
4126 mode &= O_ACCMODE;
4127 if (mode != O_RDONLY)
4128 {
4129 errno = EPERM;
4130 return FALSE;
4131 }
4132
4133 sff = SFF_ROOTOK|SFF_REGONLY;
5907 map->map_mname, map->map_file, mode);
5908
5909 mode &= O_ACCMODE;
5910 if (mode != O_RDONLY)
5911 {
5912 errno = EPERM;
5913 return FALSE;
5914 }
5915
5916 sff = SFF_ROOTOK|SFF_REGONLY;
4134 if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
5917 if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
4135 sff |= SFF_NOWLINK;
5918 sff |= SFF_NOWLINK;
4136 if (!bitset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
5919 if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
4137 sff |= SFF_SAFEDIRPATH;
4138 af = safefopen(map->map_file, O_RDONLY, 0444, sff);
4139 if (af == NULL)
4140 return FALSE;
4141 readaliases(map, af, FALSE, FALSE);
4142
4143 if (fstat(fileno(af), &st) >= 0)
4144 map->map_mtime = st.st_mtime;
5920 sff |= SFF_SAFEDIRPATH;
5921 af = safefopen(map->map_file, O_RDONLY, 0444, sff);
5922 if (af == NULL)
5923 return FALSE;
5924 readaliases(map, af, FALSE, FALSE);
5925
5926 if (fstat(fileno(af), &st) >= 0)
5927 map->map_mtime = st.st_mtime;
4145 fclose(af);
5928 (void) fclose(af);
4146
4147 return TRUE;
4148}
4149 /*
4150** Implicit Modules
4151**
4152** Tries several types. For back compatibility of aliases.
4153*/

--- 6 unchanged lines hidden (view full) ---

4160char *
4161impl_map_lookup(map, name, av, pstat)
4162 MAP *map;
4163 char *name;
4164 char **av;
4165 int *pstat;
4166{
4167 if (tTd(38, 20))
5929
5930 return TRUE;
5931}
5932 /*
5933** Implicit Modules
5934**
5935** Tries several types. For back compatibility of aliases.
5936*/

--- 6 unchanged lines hidden (view full) ---

5943char *
5944impl_map_lookup(map, name, av, pstat)
5945 MAP *map;
5946 char *name;
5947 char **av;
5948 int *pstat;
5949{
5950 if (tTd(38, 20))
4168 printf("impl_map_lookup(%s, %s)\n",
5951 dprintf("impl_map_lookup(%s, %s)\n",
4169 map->map_mname, name);
4170
4171#ifdef NEWDB
4172 if (bitset(MF_IMPL_HASH, map->map_mflags))
4173 return db_map_lookup(map, name, av, pstat);
5952 map->map_mname, name);
5953
5954#ifdef NEWDB
5955 if (bitset(MF_IMPL_HASH, map->map_mflags))
5956 return db_map_lookup(map, name, av, pstat);
4174#endif
5957#endif /* NEWDB */
4175#ifdef NDBM
4176 if (bitset(MF_IMPL_NDBM, map->map_mflags))
4177 return ndbm_map_lookup(map, name, av, pstat);
5958#ifdef NDBM
5959 if (bitset(MF_IMPL_NDBM, map->map_mflags))
5960 return ndbm_map_lookup(map, name, av, pstat);
4178#endif
5961#endif /* NDBM */
4179 return stab_map_lookup(map, name, av, pstat);
4180}
4181
4182/*
4183** IMPL_MAP_STORE -- store in open databases
4184*/
4185
4186void
4187impl_map_store(map, lhs, rhs)
4188 MAP *map;
4189 char *lhs;
4190 char *rhs;
4191{
4192 if (tTd(38, 12))
5962 return stab_map_lookup(map, name, av, pstat);
5963}
5964
5965/*
5966** IMPL_MAP_STORE -- store in open databases
5967*/
5968
5969void
5970impl_map_store(map, lhs, rhs)
5971 MAP *map;
5972 char *lhs;
5973 char *rhs;
5974{
5975 if (tTd(38, 12))
4193 printf("impl_map_store(%s, %s, %s)\n",
5976 dprintf("impl_map_store(%s, %s, %s)\n",
4194 map->map_mname, lhs, rhs);
4195#ifdef NEWDB
4196 if (bitset(MF_IMPL_HASH, map->map_mflags))
4197 db_map_store(map, lhs, rhs);
5977 map->map_mname, lhs, rhs);
5978#ifdef NEWDB
5979 if (bitset(MF_IMPL_HASH, map->map_mflags))
5980 db_map_store(map, lhs, rhs);
4198#endif
5981#endif /* NEWDB */
4199#ifdef NDBM
4200 if (bitset(MF_IMPL_NDBM, map->map_mflags))
4201 ndbm_map_store(map, lhs, rhs);
5982#ifdef NDBM
5983 if (bitset(MF_IMPL_NDBM, map->map_mflags))
5984 ndbm_map_store(map, lhs, rhs);
4202#endif
5985#endif /* NDBM */
4203 stab_map_store(map, lhs, rhs);
4204}
4205
4206/*
4207** IMPL_MAP_OPEN -- implicit database open
4208*/
4209
4210bool
4211impl_map_open(map, mode)
4212 MAP *map;
4213 int mode;
4214{
4215 if (tTd(38, 2))
5986 stab_map_store(map, lhs, rhs);
5987}
5988
5989/*
5990** IMPL_MAP_OPEN -- implicit database open
5991*/
5992
5993bool
5994impl_map_open(map, mode)
5995 MAP *map;
5996 int mode;
5997{
5998 if (tTd(38, 2))
4216 printf("impl_map_open(%s, %s, %d)\n",
5999 dprintf("impl_map_open(%s, %s, %d)\n",
4217 map->map_mname, map->map_file, mode);
4218
4219 mode &= O_ACCMODE;
4220#ifdef NEWDB
4221 map->map_mflags |= MF_IMPL_HASH;
4222 if (hash_map_open(map, mode))
4223 {
4224# ifdef NDBM_YP_COMPAT
4225 if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL)
6000 map->map_mname, map->map_file, mode);
6001
6002 mode &= O_ACCMODE;
6003#ifdef NEWDB
6004 map->map_mflags |= MF_IMPL_HASH;
6005 if (hash_map_open(map, mode))
6006 {
6007# ifdef NDBM_YP_COMPAT
6008 if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL)
4226# endif
6009# endif /* NDBM_YP_COMPAT */
4227 return TRUE;
4228 }
4229 else
4230 map->map_mflags &= ~MF_IMPL_HASH;
6010 return TRUE;
6011 }
6012 else
6013 map->map_mflags &= ~MF_IMPL_HASH;
4231#endif
6014#endif /* NEWDB */
4232#ifdef NDBM
4233 map->map_mflags |= MF_IMPL_NDBM;
4234 if (ndbm_map_open(map, mode))
4235 {
4236 return TRUE;
4237 }
4238 else
4239 map->map_mflags &= ~MF_IMPL_NDBM;
6015#ifdef NDBM
6016 map->map_mflags |= MF_IMPL_NDBM;
6017 if (ndbm_map_open(map, mode))
6018 {
6019 return TRUE;
6020 }
6021 else
6022 map->map_mflags &= ~MF_IMPL_NDBM;
4240#endif
6023#endif /* NDBM */
4241
4242#if defined(NEWDB) || defined(NDBM)
4243 if (Verbose)
4244 message("WARNING: cannot open alias database %s%s",
4245 map->map_file,
4246 mode == O_RDONLY ? "; reading text version" : "");
6024
6025#if defined(NEWDB) || defined(NDBM)
6026 if (Verbose)
6027 message("WARNING: cannot open alias database %s%s",
6028 map->map_file,
6029 mode == O_RDONLY ? "; reading text version" : "");
4247#else
6030#else /* defined(NEWDB) || defined(NDBM) */
4248 if (mode != O_RDONLY)
4249 usrerr("Cannot rebuild aliases: no database format defined");
6031 if (mode != O_RDONLY)
6032 usrerr("Cannot rebuild aliases: no database format defined");
4250#endif
6033#endif /* defined(NEWDB) || defined(NDBM) */
4251
4252 if (mode == O_RDONLY)
4253 return stab_map_open(map, mode);
4254 else
4255 return FALSE;
4256}
4257
4258
4259/*
4260** IMPL_MAP_CLOSE -- close any open database(s)
4261*/
4262
4263void
4264impl_map_close(map)
4265 MAP *map;
4266{
4267 if (tTd(38, 9))
6034
6035 if (mode == O_RDONLY)
6036 return stab_map_open(map, mode);
6037 else
6038 return FALSE;
6039}
6040
6041
6042/*
6043** IMPL_MAP_CLOSE -- close any open database(s)
6044*/
6045
6046void
6047impl_map_close(map)
6048 MAP *map;
6049{
6050 if (tTd(38, 9))
4268 printf("impl_map_close(%s, %s, %lx)\n",
6051 dprintf("impl_map_close(%s, %s, %lx)\n",
4269 map->map_mname, map->map_file, map->map_mflags);
4270#ifdef NEWDB
4271 if (bitset(MF_IMPL_HASH, map->map_mflags))
4272 {
4273 db_map_close(map);
4274 map->map_mflags &= ~MF_IMPL_HASH;
4275 }
6052 map->map_mname, map->map_file, map->map_mflags);
6053#ifdef NEWDB
6054 if (bitset(MF_IMPL_HASH, map->map_mflags))
6055 {
6056 db_map_close(map);
6057 map->map_mflags &= ~MF_IMPL_HASH;
6058 }
4276#endif
6059#endif /* NEWDB */
4277
4278#ifdef NDBM
4279 if (bitset(MF_IMPL_NDBM, map->map_mflags))
4280 {
4281 ndbm_map_close(map);
4282 map->map_mflags &= ~MF_IMPL_NDBM;
4283 }
6060
6061#ifdef NDBM
6062 if (bitset(MF_IMPL_NDBM, map->map_mflags))
6063 {
6064 ndbm_map_close(map);
6065 map->map_mflags &= ~MF_IMPL_NDBM;
6066 }
4284#endif
6067#endif /* NDBM */
4285}
4286 /*
4287** User map class.
4288**
4289** Provides access to the system password file.
4290*/
4291
4292/*
4293** USER_MAP_OPEN -- open user map
4294**
4295** Really just binds field names to field numbers.
4296*/
4297
4298bool
4299user_map_open(map, mode)
4300 MAP *map;
4301 int mode;
4302{
4303 if (tTd(38, 2))
6068}
6069 /*
6070** User map class.
6071**
6072** Provides access to the system password file.
6073*/
6074
6075/*
6076** USER_MAP_OPEN -- open user map
6077**
6078** Really just binds field names to field numbers.
6079*/
6080
6081bool
6082user_map_open(map, mode)
6083 MAP *map;
6084 int mode;
6085{
6086 if (tTd(38, 2))
4304 printf("user_map_open(%s, %d)\n",
6087 dprintf("user_map_open(%s, %d)\n",
4305 map->map_mname, mode);
4306
4307 mode &= O_ACCMODE;
4308 if (mode != O_RDONLY)
4309 {
4310 /* issue a pseudo-error message */
4311#ifdef ENOSYS
4312 errno = ENOSYS;
6088 map->map_mname, mode);
6089
6090 mode &= O_ACCMODE;
6091 if (mode != O_RDONLY)
6092 {
6093 /* issue a pseudo-error message */
6094#ifdef ENOSYS
6095 errno = ENOSYS;
4313#else
6096#else /* ENOSYS */
4314# ifdef EFTYPE
4315 errno = EFTYPE;
6097# ifdef EFTYPE
6098 errno = EFTYPE;
4316# else
6099# else /* EFTYPE */
4317 errno = ENXIO;
6100 errno = ENXIO;
4318# endif
4319#endif
6101# endif /* EFTYPE */
6102#endif /* ENOSYS */
4320 return FALSE;
4321 }
4322 if (map->map_valcolnm == NULL)
6103 return FALSE;
6104 }
6105 if (map->map_valcolnm == NULL)
6106 /* EMPTY */
4323 /* nothing */ ;
4324 else if (strcasecmp(map->map_valcolnm, "name") == 0)
4325 map->map_valcolno = 1;
4326 else if (strcasecmp(map->map_valcolnm, "passwd") == 0)
4327 map->map_valcolno = 2;
4328 else if (strcasecmp(map->map_valcolnm, "uid") == 0)
4329 map->map_valcolno = 3;
4330 else if (strcasecmp(map->map_valcolnm, "gid") == 0)

--- 25 unchanged lines hidden (view full) ---

4356 char *key;
4357 char **av;
4358 int *statp;
4359{
4360 struct passwd *pw;
4361 auto bool fuzzy;
4362
4363 if (tTd(38, 20))
6107 /* nothing */ ;
6108 else if (strcasecmp(map->map_valcolnm, "name") == 0)
6109 map->map_valcolno = 1;
6110 else if (strcasecmp(map->map_valcolnm, "passwd") == 0)
6111 map->map_valcolno = 2;
6112 else if (strcasecmp(map->map_valcolnm, "uid") == 0)
6113 map->map_valcolno = 3;
6114 else if (strcasecmp(map->map_valcolnm, "gid") == 0)

--- 25 unchanged lines hidden (view full) ---

6140 char *key;
6141 char **av;
6142 int *statp;
6143{
6144 struct passwd *pw;
6145 auto bool fuzzy;
6146
6147 if (tTd(38, 20))
4364 printf("user_map_lookup(%s, %s)\n",
6148 dprintf("user_map_lookup(%s, %s)\n",
4365 map->map_mname, key);
4366
4367 pw = finduser(key, &fuzzy);
4368 if (pw == NULL)
4369 return NULL;
4370 if (bitset(MF_MATCHONLY, map->map_mflags))
4371 return map_rewrite(map, key, strlen(key), NULL);
4372 else

--- 8 unchanged lines hidden (view full) ---

4381 rwval = pw->pw_name;
4382 break;
4383
4384 case 2:
4385 rwval = pw->pw_passwd;
4386 break;
4387
4388 case 3:
6149 map->map_mname, key);
6150
6151 pw = finduser(key, &fuzzy);
6152 if (pw == NULL)
6153 return NULL;
6154 if (bitset(MF_MATCHONLY, map->map_mflags))
6155 return map_rewrite(map, key, strlen(key), NULL);
6156 else

--- 8 unchanged lines hidden (view full) ---

6165 rwval = pw->pw_name;
6166 break;
6167
6168 case 2:
6169 rwval = pw->pw_passwd;
6170 break;
6171
6172 case 3:
4389 snprintf(buf, sizeof buf, "%d", pw->pw_uid);
6173 snprintf(buf, sizeof buf, "%d", (int) pw->pw_uid);
4390 rwval = buf;
4391 break;
4392
4393 case 4:
6174 rwval = buf;
6175 break;
6176
6177 case 4:
4394 snprintf(buf, sizeof buf, "%d", pw->pw_gid);
6178 snprintf(buf, sizeof buf, "%d", (int) pw->pw_gid);
4395 rwval = buf;
4396 break;
4397
4398 case 5:
4399 rwval = pw->pw_gecos;
4400 break;
4401
4402 case 6:

--- 18 unchanged lines hidden (view full) ---

4421char *
4422prog_map_lookup(map, name, av, statp)
4423 MAP *map;
4424 char *name;
4425 char **av;
4426 int *statp;
4427{
4428 int i;
6179 rwval = buf;
6180 break;
6181
6182 case 5:
6183 rwval = pw->pw_gecos;
6184 break;
6185
6186 case 6:

--- 18 unchanged lines hidden (view full) ---

6205char *
6206prog_map_lookup(map, name, av, statp)
6207 MAP *map;
6208 char *name;
6209 char **av;
6210 int *statp;
6211{
6212 int i;
4429 register char *p;
6213 int save_errno;
4430 int fd;
6214 int fd;
6215 int status;
4431 auto pid_t pid;
6216 auto pid_t pid;
6217 register char *p;
4432 char *rval;
6218 char *rval;
4433 int stat;
4434 char *argv[MAXPV + 1];
4435 char buf[MAXLINE];
4436
4437 if (tTd(38, 20))
6219 char *argv[MAXPV + 1];
6220 char buf[MAXLINE];
6221
6222 if (tTd(38, 20))
4438 printf("prog_map_lookup(%s, %s) %s\n",
6223 dprintf("prog_map_lookup(%s, %s) %s\n",
4439 map->map_mname, name, map->map_file);
4440
4441 i = 0;
4442 argv[i++] = map->map_file;
4443 if (map->map_rebuild != NULL)
4444 {
4445 snprintf(buf, sizeof buf, "%s", map->map_rebuild);
4446 for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t"))
4447 {
4448 if (i >= MAXPV - 1)
4449 break;
4450 argv[i++] = p;
4451 }
4452 }
4453 argv[i++] = name;
4454 argv[i] = NULL;
4455 if (tTd(38, 21))
4456 {
6224 map->map_mname, name, map->map_file);
6225
6226 i = 0;
6227 argv[i++] = map->map_file;
6228 if (map->map_rebuild != NULL)
6229 {
6230 snprintf(buf, sizeof buf, "%s", map->map_rebuild);
6231 for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t"))
6232 {
6233 if (i >= MAXPV - 1)
6234 break;
6235 argv[i++] = p;
6236 }
6237 }
6238 argv[i++] = name;
6239 argv[i] = NULL;
6240 if (tTd(38, 21))
6241 {
4457 printf("prog_open:");
6242 dprintf("prog_open:");
4458 for (i = 0; argv[i] != NULL; i++)
6243 for (i = 0; argv[i] != NULL; i++)
4459 printf(" %s", argv[i]);
4460 printf("\n");
6244 dprintf(" %s", argv[i]);
6245 dprintf("\n");
4461 }
4462 (void) blocksignal(SIGCHLD);
4463 pid = prog_open(argv, &fd, CurEnv);
4464 if (pid < 0)
4465 {
4466 if (!bitset(MF_OPTIONAL, map->map_mflags))
4467 syserr("prog_map_lookup(%s) failed (%s) -- closing",
4468 map->map_mname, errstring(errno));
4469 else if (tTd(38, 9))
6246 }
6247 (void) blocksignal(SIGCHLD);
6248 pid = prog_open(argv, &fd, CurEnv);
6249 if (pid < 0)
6250 {
6251 if (!bitset(MF_OPTIONAL, map->map_mflags))
6252 syserr("prog_map_lookup(%s) failed (%s) -- closing",
6253 map->map_mname, errstring(errno));
6254 else if (tTd(38, 9))
4470 printf("prog_map_lookup(%s) failed (%s) -- closing",
6255 dprintf("prog_map_lookup(%s) failed (%s) -- closing",
4471 map->map_mname, errstring(errno));
4472 map->map_mflags &= ~(MF_VALID|MF_OPEN);
4473 *statp = EX_OSFILE;
4474 return NULL;
4475 }
4476 i = read(fd, buf, sizeof buf - 1);
4477 if (i < 0)
4478 {
4479 syserr("prog_map_lookup(%s): read error %s\n",
4480 map->map_mname, errstring(errno));
4481 rval = NULL;
4482 }
4483 else if (i == 0)
4484 {
4485 if (tTd(38, 20))
6256 map->map_mname, errstring(errno));
6257 map->map_mflags &= ~(MF_VALID|MF_OPEN);
6258 *statp = EX_OSFILE;
6259 return NULL;
6260 }
6261 i = read(fd, buf, sizeof buf - 1);
6262 if (i < 0)
6263 {
6264 syserr("prog_map_lookup(%s): read error %s\n",
6265 map->map_mname, errstring(errno));
6266 rval = NULL;
6267 }
6268 else if (i == 0)
6269 {
6270 if (tTd(38, 20))
4486 printf("prog_map_lookup(%s): empty answer\n",
6271 dprintf("prog_map_lookup(%s): empty answer\n",
4487 map->map_mname);
4488 rval = NULL;
4489 }
4490 else
4491 {
4492 buf[i] = '\0';
4493 p = strchr(buf, '\n');
4494 if (p != NULL)

--- 6 unchanged lines hidden (view full) ---

4501 rval = map_rewrite(map, buf, strlen(buf), NULL);
4502
4503 /* now flush any additional output */
4504 while ((i = read(fd, buf, sizeof buf)) > 0)
4505 continue;
4506 }
4507
4508 /* wait for the process to terminate */
6272 map->map_mname);
6273 rval = NULL;
6274 }
6275 else
6276 {
6277 buf[i] = '\0';
6278 p = strchr(buf, '\n');
6279 if (p != NULL)

--- 6 unchanged lines hidden (view full) ---

6286 rval = map_rewrite(map, buf, strlen(buf), NULL);
6287
6288 /* now flush any additional output */
6289 while ((i = read(fd, buf, sizeof buf)) > 0)
6290 continue;
6291 }
6292
6293 /* wait for the process to terminate */
4509 close(fd);
4510 stat = waitfor(pid);
6294 (void) close(fd);
6295 status = waitfor(pid);
6296 save_errno = errno;
4511 (void) releasesignal(SIGCHLD);
6297 (void) releasesignal(SIGCHLD);
6298 errno = save_errno;
4512
6299
4513 if (stat == -1)
6300 if (status == -1)
4514 {
4515 syserr("prog_map_lookup(%s): wait error %s\n",
4516 map->map_mname, errstring(errno));
4517 *statp = EX_SOFTWARE;
4518 rval = NULL;
4519 }
6301 {
6302 syserr("prog_map_lookup(%s): wait error %s\n",
6303 map->map_mname, errstring(errno));
6304 *statp = EX_SOFTWARE;
6305 rval = NULL;
6306 }
4520 else if (WIFEXITED(stat))
6307 else if (WIFEXITED(status))
4521 {
6308 {
4522 if ((*statp = WEXITSTATUS(stat)) != EX_OK)
6309 if ((*statp = WEXITSTATUS(status)) != EX_OK)
4523 rval = NULL;
4524 }
4525 else
4526 {
4527 syserr("prog_map_lookup(%s): child died on signal %d",
6310 rval = NULL;
6311 }
6312 else
6313 {
6314 syserr("prog_map_lookup(%s): child died on signal %d",
4528 map->map_mname, stat);
6315 map->map_mname, status);
4529 *statp = EX_UNAVAILABLE;
4530 rval = NULL;
4531 }
4532 return rval;
4533}
4534 /*
4535** Sequenced map type.
4536**

--- 18 unchanged lines hidden (view full) ---

4555bool
4556seq_map_parse(map, ap)
4557 MAP *map;
4558 char *ap;
4559{
4560 int maxmap;
4561
4562 if (tTd(38, 2))
6316 *statp = EX_UNAVAILABLE;
6317 rval = NULL;
6318 }
6319 return rval;
6320}
6321 /*
6322** Sequenced map type.
6323**

--- 18 unchanged lines hidden (view full) ---

6342bool
6343seq_map_parse(map, ap)
6344 MAP *map;
6345 char *ap;
6346{
6347 int maxmap;
6348
6349 if (tTd(38, 2))
4563 printf("seq_map_parse(%s, %s)\n", map->map_mname, ap);
6350 dprintf("seq_map_parse(%s, %s)\n", map->map_mname, ap);
4564 maxmap = 0;
4565 while (*ap != '\0')
4566 {
4567 register char *p;
4568 STAB *s;
4569
4570 /* find beginning of map name */
4571 while (isascii(*ap) && isspace(*ap))
4572 ap++;
6351 maxmap = 0;
6352 while (*ap != '\0')
6353 {
6354 register char *p;
6355 STAB *s;
6356
6357 /* find beginning of map name */
6358 while (isascii(*ap) && isspace(*ap))
6359 ap++;
4573 for (p = ap; isascii(*p) && isalnum(*p); p++)
6360 for (p = ap;
6361 (isascii(*p) && isalnum(*p)) || *p == '_' || *p == '.';
6362 p++)
4574 continue;
4575 if (*p != '\0')
4576 *p++ = '\0';
4577 while (*p != '\0' && (!isascii(*p) || !isalnum(*p)))
4578 p++;
4579 if (*ap == '\0')
4580 {
4581 ap = p;

--- 37 unchanged lines hidden (view full) ---

4619 MAP *map;
4620 int mode;
4621{
4622 int mapno;
4623 int nmaps;
4624 char *maptype[MAXMAPSTACK];
4625
4626 if (tTd(38, 2))
6363 continue;
6364 if (*p != '\0')
6365 *p++ = '\0';
6366 while (*p != '\0' && (!isascii(*p) || !isalnum(*p)))
6367 p++;
6368 if (*ap == '\0')
6369 {
6370 ap = p;

--- 37 unchanged lines hidden (view full) ---

6408 MAP *map;
6409 int mode;
6410{
6411 int mapno;
6412 int nmaps;
6413 char *maptype[MAXMAPSTACK];
6414
6415 if (tTd(38, 2))
4627 printf("switch_map_open(%s, %s, %d)\n",
6416 dprintf("switch_map_open(%s, %s, %d)\n",
4628 map->map_mname, map->map_file, mode);
4629
4630 mode &= O_ACCMODE;
4631 nmaps = switch_map_find(map->map_file, maptype, map->map_return);
4632 if (tTd(38, 19))
4633 {
6417 map->map_mname, map->map_file, mode);
6418
6419 mode &= O_ACCMODE;
6420 nmaps = switch_map_find(map->map_file, maptype, map->map_return);
6421 if (tTd(38, 19))
6422 {
4634 printf("\tswitch_map_find => %d\n", nmaps);
6423 dprintf("\tswitch_map_find => %d\n", nmaps);
4635 for (mapno = 0; mapno < nmaps; mapno++)
6424 for (mapno = 0; mapno < nmaps; mapno++)
4636 printf("\t\t%s\n", maptype[mapno]);
6425 dprintf("\t\t%s\n", maptype[mapno]);
4637 }
4638 if (nmaps <= 0 || nmaps > MAXMAPSTACK)
4639 return FALSE;
4640
4641 for (mapno = 0; mapno < nmaps; mapno++)
4642 {
4643 register STAB *s;
4644 char nbuf[MAXNAME + 1];

--- 7 unchanged lines hidden (view full) ---

4652 {
4653 syserr("Switch map %s: unknown member map %s",
4654 map->map_mname, nbuf);
4655 }
4656 else
4657 {
4658 map->map_stack[mapno] = &s->s_map;
4659 if (tTd(38, 4))
6426 }
6427 if (nmaps <= 0 || nmaps > MAXMAPSTACK)
6428 return FALSE;
6429
6430 for (mapno = 0; mapno < nmaps; mapno++)
6431 {
6432 register STAB *s;
6433 char nbuf[MAXNAME + 1];

--- 7 unchanged lines hidden (view full) ---

6441 {
6442 syserr("Switch map %s: unknown member map %s",
6443 map->map_mname, nbuf);
6444 }
6445 else
6446 {
6447 map->map_stack[mapno] = &s->s_map;
6448 if (tTd(38, 4))
4660 printf("\tmap_stack[%d] = %s:%s\n",
6449 dprintf("\tmap_stack[%d] = %s:%s\n",
4661 mapno, s->s_map.map_class->map_cname,
4662 nbuf);
4663 }
4664 }
4665 return TRUE;
4666}
4667
4668
4669/*
4670** SEQ_MAP_CLOSE -- close all underlying maps
4671*/
4672
4673void
4674seq_map_close(map)
4675 MAP *map;
4676{
4677 int mapno;
4678
4679 if (tTd(38, 9))
6450 mapno, s->s_map.map_class->map_cname,
6451 nbuf);
6452 }
6453 }
6454 return TRUE;
6455}
6456
6457
6458/*
6459** SEQ_MAP_CLOSE -- close all underlying maps
6460*/
6461
6462void
6463seq_map_close(map)
6464 MAP *map;
6465{
6466 int mapno;
6467
6468 if (tTd(38, 9))
4680 printf("seq_map_close(%s)\n", map->map_mname);
6469 dprintf("seq_map_close(%s)\n", map->map_mname);
4681
4682 for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
4683 {
4684 MAP *mm = map->map_stack[mapno];
4685
4686 if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
4687 continue;
4688 mm->map_class->map_close(mm);

--- 13 unchanged lines hidden (view full) ---

4702 char **args;
4703 int *pstat;
4704{
4705 int mapno;
4706 int mapbit = 0x01;
4707 bool tempfail = FALSE;
4708
4709 if (tTd(38, 20))
6470
6471 for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
6472 {
6473 MAP *mm = map->map_stack[mapno];
6474
6475 if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
6476 continue;
6477 mm->map_class->map_close(mm);

--- 13 unchanged lines hidden (view full) ---

6491 char **args;
6492 int *pstat;
6493{
6494 int mapno;
6495 int mapbit = 0x01;
6496 bool tempfail = FALSE;
6497
6498 if (tTd(38, 20))
4710 printf("seq_map_lookup(%s, %s)\n", map->map_mname, key);
6499 dprintf("seq_map_lookup(%s, %s)\n", map->map_mname, key);
4711
4712 for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++)
4713 {
4714 MAP *mm = map->map_stack[mapno];
4715 char *rv;
4716
4717 if (mm == NULL)
4718 continue;
6500
6501 for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++)
6502 {
6503 MAP *mm = map->map_stack[mapno];
6504 char *rv;
6505
6506 if (mm == NULL)
6507 continue;
4719 if (!bitset(MF_OPEN, mm->map_mflags))
6508 if (!bitset(MF_OPEN, mm->map_mflags) &&
6509 !openmap(mm))
4720 {
4721 if (bitset(mapbit, map->map_return[MA_UNAVAIL]))
4722 {
4723 *pstat = EX_UNAVAILABLE;
4724 return NULL;
4725 }
4726 continue;
4727 }

--- 26 unchanged lines hidden (view full) ---

4754seq_map_store(map, key, val)
4755 MAP *map;
4756 char *key;
4757 char *val;
4758{
4759 int mapno;
4760
4761 if (tTd(38, 12))
6510 {
6511 if (bitset(mapbit, map->map_return[MA_UNAVAIL]))
6512 {
6513 *pstat = EX_UNAVAILABLE;
6514 return NULL;
6515 }
6516 continue;
6517 }

--- 26 unchanged lines hidden (view full) ---

6544seq_map_store(map, key, val)
6545 MAP *map;
6546 char *key;
6547 char *val;
6548{
6549 int mapno;
6550
6551 if (tTd(38, 12))
4762 printf("seq_map_store(%s, %s, %s)\n",
6552 dprintf("seq_map_store(%s, %s, %s)\n",
4763 map->map_mname, key, val);
4764
4765 for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
4766 {
4767 MAP *mm = map->map_stack[mapno];
4768
4769 if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags))
4770 continue;

--- 64 unchanged lines hidden (view full) ---

4835
4836MAPCLASS BogusMapClass =
4837{
4838 "bogus-map", NULL, 0,
4839 NULL, bogus_map_lookup, null_map_store,
4840 null_map_open, null_map_close,
4841};
4842 /*
6553 map->map_mname, key, val);
6554
6555 for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
6556 {
6557 MAP *mm = map->map_stack[mapno];
6558
6559 if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags))
6560 continue;

--- 64 unchanged lines hidden (view full) ---

6625
6626MAPCLASS BogusMapClass =
6627{
6628 "bogus-map", NULL, 0,
6629 NULL, bogus_map_lookup, null_map_store,
6630 null_map_open, null_map_close,
6631};
6632 /*
6633** MACRO modules
6634*/
6635
6636char *
6637macro_map_lookup(map, name, av, statp)
6638 MAP *map;
6639 char *name;
6640 char **av;
6641 int *statp;
6642{
6643 int mid;
6644
6645 if (tTd(38, 20))
6646 dprintf("macro_map_lookup(%s, %s)\n", map->map_mname,
6647 name == NULL ? "NULL" : name);
6648
6649 if (name == NULL ||
6650 *name == '\0' ||
6651 (mid = macid(name, NULL)) == '\0')
6652 {
6653 *statp = EX_CONFIG;
6654 return NULL;
6655 }
6656
6657 if (av[1] == NULL)
6658 define(mid, NULL, CurEnv);
6659 else
6660 define(mid, newstr(av[1]), CurEnv);
6661
6662 *statp = EX_OK;
6663 return "";
6664}
6665 /*
4843** REGEX modules
4844*/
4845
4846#ifdef MAP_REGEX
4847
4848# include <regex.h>
4849
4850# define DEFAULT_DELIM CONDELSE
4851
4852# define END_OF_FIELDS -1
4853
4854# define ERRBUF_SIZE 80
4855# define MAX_MATCH 32
4856
6666** REGEX modules
6667*/
6668
6669#ifdef MAP_REGEX
6670
6671# include <regex.h>
6672
6673# define DEFAULT_DELIM CONDELSE
6674
6675# define END_OF_FIELDS -1
6676
6677# define ERRBUF_SIZE 80
6678# define MAX_MATCH 32
6679
4857# define xnalloc(s) memset(xalloc(s), 0, s);
6680# define xnalloc(s) memset(xalloc(s), '\0', s);
4858
4859struct regex_map
4860{
6681
6682struct regex_map
6683{
4861 regex_t pattern_buf; /* xalloc it */
6684 regex_t regex_pattern_buf; /* xalloc it */
4862 int *regex_subfields; /* move to type MAP */
6685 int *regex_subfields; /* move to type MAP */
4863 char *delim; /* move to type MAP */
6686 char *regex_delim; /* move to type MAP */
4864};
4865
4866static int
4867parse_fields(s, ibuf, blen, nr_substrings)
4868 char *s;
4869 int *ibuf; /* array */
4870 int blen; /* number of elements in ibuf */
4871 int nr_substrings; /* number of substrings in the pattern */

--- 50 unchanged lines hidden (view full) ---

4922 int regerr;
4923 struct regex_map *map_p;
4924 register char *p;
4925 char *sub_param = NULL;
4926 int pflags;
4927 static char defdstr[] = { (char)DEFAULT_DELIM, '\0' };
4928
4929 if (tTd(38, 2))
6687};
6688
6689static int
6690parse_fields(s, ibuf, blen, nr_substrings)
6691 char *s;
6692 int *ibuf; /* array */
6693 int blen; /* number of elements in ibuf */
6694 int nr_substrings; /* number of substrings in the pattern */

--- 50 unchanged lines hidden (view full) ---

6745 int regerr;
6746 struct regex_map *map_p;
6747 register char *p;
6748 char *sub_param = NULL;
6749 int pflags;
6750 static char defdstr[] = { (char)DEFAULT_DELIM, '\0' };
6751
6752 if (tTd(38, 2))
4930 printf("regex_map_init: mapname '%s', args '%s'\n",
4931 map->map_mname, ap);
6753 dprintf("regex_map_init: mapname '%s', args '%s'\n",
6754 map->map_mname, ap);
4932
4933 pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB;
4934
4935 p = ap;
4936
6755
6756 pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB;
6757
6758 p = ap;
6759
4937 map_p = (struct regex_map *) xnalloc(sizeof(struct regex_map));
6760 map_p = (struct regex_map *) xnalloc(sizeof *map_p);
4938
4939 for (;;)
6761
6762 for (;;)
4940 {
6763 {
4941 while (isascii(*p) && isspace(*p))
4942 p++;
4943 if (*p != '-')
4944 break;
4945 switch (*++p)
4946 {
4947 case 'n': /* not */
4948 map->map_mflags |= MF_REGEX_NOT;

--- 9 unchanged lines hidden (view full) ---

4958 break;
4959
4960 case 's': /* substring match () syntax */
4961 sub_param = ++p;
4962 pflags &= ~REG_NOSUB;
4963 break;
4964
4965 case 'd': /* delimiter */
6764 while (isascii(*p) && isspace(*p))
6765 p++;
6766 if (*p != '-')
6767 break;
6768 switch (*++p)
6769 {
6770 case 'n': /* not */
6771 map->map_mflags |= MF_REGEX_NOT;

--- 9 unchanged lines hidden (view full) ---

6781 break;
6782
6783 case 's': /* substring match () syntax */
6784 sub_param = ++p;
6785 pflags &= ~REG_NOSUB;
6786 break;
6787
6788 case 'd': /* delimiter */
4966 map_p->delim = ++p;
6789 map_p->regex_delim = ++p;
4967 break;
4968
4969 case 'a': /* map append */
4970 map->map_app = ++p;
4971 break;
4972
4973 case 'm': /* matchonly */
4974 map->map_mflags |= MF_MATCHONLY;
4975 break;
4976
6790 break;
6791
6792 case 'a': /* map append */
6793 map->map_app = ++p;
6794 break;
6795
6796 case 'm': /* matchonly */
6797 map->map_mflags |= MF_MATCHONLY;
6798 break;
6799
6800 case 'S':
6801 map->map_spacesub = *++p;
6802 break;
6803
6804 case 'D':
6805 map->map_mflags |= MF_DEFER;
6806 break;
6807
4977 }
6808 }
4978 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
4979 p++;
4980 if (*p != '\0')
4981 *p++ = '\0';
6809 while (*p != '\0' && !(isascii(*p) && isspace(*p)))
6810 p++;
6811 if (*p != '\0')
6812 *p++ = '\0';
4982 }
4983 if (tTd(38, 3))
6813 }
6814 if (tTd(38, 3))
4984 printf("regex_map_init: compile '%s' 0x%x\n", p, pflags);
6815 dprintf("regex_map_init: compile '%s' 0x%x\n", p, pflags);
4985
6816
4986 if ((regerr = regcomp(&(map_p->pattern_buf), p, pflags)) != 0)
6817 if ((regerr = regcomp(&(map_p->regex_pattern_buf), p, pflags)) != 0)
4987 {
4988 /* Errorhandling */
4989 char errbuf[ERRBUF_SIZE];
4990
6818 {
6819 /* Errorhandling */
6820 char errbuf[ERRBUF_SIZE];
6821
4991 regerror(regerr, &(map_p->pattern_buf), errbuf, ERRBUF_SIZE);
6822 (void) regerror(regerr, &(map_p->regex_pattern_buf),
6823 errbuf, ERRBUF_SIZE);
4992 syserr("pattern-compile-error: %s\n", errbuf);
4993 free(map_p);
4994 return FALSE;
4995 }
4996
4997 if (map->map_app != NULL)
4998 map->map_app = newstr(map->map_app);
6824 syserr("pattern-compile-error: %s\n", errbuf);
6825 free(map_p);
6826 return FALSE;
6827 }
6828
6829 if (map->map_app != NULL)
6830 map->map_app = newstr(map->map_app);
4999 if (map_p->delim != NULL)
5000 map_p->delim = newstr(map_p->delim);
6831 if (map_p->regex_delim != NULL)
6832 map_p->regex_delim = newstr(map_p->regex_delim);
5001 else
6833 else
5002 map_p->delim = defdstr;
6834 map_p->regex_delim = defdstr;
5003
5004 if (!bitset(REG_NOSUB, pflags))
5005 {
5006 /* substring matching */
5007 int substrings;
6835
6836 if (!bitset(REG_NOSUB, pflags))
6837 {
6838 /* substring matching */
6839 int substrings;
5008 int *fields = (int *)xalloc(sizeof(int) * (MAX_MATCH + 1));
6840 int *fields = (int *) xalloc(sizeof(int) * (MAX_MATCH + 1));
5009
6841
5010 substrings = map_p->pattern_buf.re_nsub + 1;
6842 substrings = map_p->regex_pattern_buf.re_nsub + 1;
5011
5012 if (tTd(38, 3))
6843
6844 if (tTd(38, 3))
5013 printf("regex_map_init: nr of substrings %d\n", substrings);
6845 dprintf("regex_map_init: nr of substrings %d\n",
6846 substrings);
5014
5015 if (substrings >= MAX_MATCH)
5016 {
5017 syserr("too many substrings, %d max\n", MAX_MATCH);
5018 free(map_p);
5019 return FALSE;
5020 }
5021 if (sub_param != NULL && sub_param[0] != '\0')
5022 {
5023 /* optional parameter -sfields */
5024 if (parse_fields(sub_param, fields,
5025 MAX_MATCH + 1, substrings) == -1)
5026 return FALSE;
5027 }
5028 else
5029 {
6847
6848 if (substrings >= MAX_MATCH)
6849 {
6850 syserr("too many substrings, %d max\n", MAX_MATCH);
6851 free(map_p);
6852 return FALSE;
6853 }
6854 if (sub_param != NULL && sub_param[0] != '\0')
6855 {
6856 /* optional parameter -sfields */
6857 if (parse_fields(sub_param, fields,
6858 MAX_MATCH + 1, substrings) == -1)
6859 return FALSE;
6860 }
6861 else
6862 {
5030 /* set default fields */
6863 /* set default fields */
5031 int i;
5032
5033 for (i = 0; i < substrings; i++)
5034 fields[i] = i;
5035 fields[i] = END_OF_FIELDS;
5036 }
5037 map_p->regex_subfields = fields;
5038 if (tTd(38, 3))
5039 {
5040 int *ip;
5041
6864 int i;
6865
6866 for (i = 0; i < substrings; i++)
6867 fields[i] = i;
6868 fields[i] = END_OF_FIELDS;
6869 }
6870 map_p->regex_subfields = fields;
6871 if (tTd(38, 3))
6872 {
6873 int *ip;
6874
5042 printf("regex_map_init: subfields");
6875 dprintf("regex_map_init: subfields");
5043 for (ip = fields; *ip != END_OF_FIELDS; ip++)
6876 for (ip = fields; *ip != END_OF_FIELDS; ip++)
5044 printf(" %d", *ip);
5045 printf("\n");
6877 dprintf(" %d", *ip);
6878 dprintf("\n");
5046 }
5047 }
5048 map->map_db1 = (ARBPTR_T)map_p; /* dirty hack */
5049
5050 return TRUE;
5051}
5052
5053static char *

--- 19 unchanged lines hidden (view full) ---

5073 int reg_res;
5074 struct regex_map *map_p;
5075 regmatch_t pmatch[MAX_MATCH];
5076
5077 if (tTd(38, 20))
5078 {
5079 char **cpp;
5080
6879 }
6880 }
6881 map->map_db1 = (ARBPTR_T)map_p; /* dirty hack */
6882
6883 return TRUE;
6884}
6885
6886static char *

--- 19 unchanged lines hidden (view full) ---

6906 int reg_res;
6907 struct regex_map *map_p;
6908 regmatch_t pmatch[MAX_MATCH];
6909
6910 if (tTd(38, 20))
6911 {
6912 char **cpp;
6913
5081 printf("regex_map_lookup: key '%s'\n", name);
5082 for (cpp = av; cpp && *cpp; cpp++)
5083 printf("regex_map_lookup: arg '%s'\n", *cpp);
6914 dprintf("regex_map_lookup: key '%s'\n", name);
6915 for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
6916 dprintf("regex_map_lookup: arg '%s'\n", *cpp);
5084 }
5085
5086 map_p = (struct regex_map *)(map->map_db1);
6917 }
6918
6919 map_p = (struct regex_map *)(map->map_db1);
5087 reg_res = regexec(&(map_p->pattern_buf), name, MAX_MATCH, pmatch, 0);
6920 reg_res = regexec(&(map_p->regex_pattern_buf),
6921 name, MAX_MATCH, pmatch, 0);
5088
5089 if (bitset(MF_REGEX_NOT, map->map_mflags))
5090 {
5091 /* option -n */
5092 if (reg_res == REG_NOMATCH)
5093 return regex_map_rewrite(map, "", (size_t)0, av);
5094 else
5095 return NULL;

--- 14 unchanged lines hidden (view full) ---

5110 int *ip;
5111
5112 dp = retbuf;
5113 ldp = retbuf + sizeof(retbuf) - 1;
5114
5115 if (av[1] != NULL)
5116 {
5117 if (parse_fields(av[1], fields, MAX_MATCH + 1,
6922
6923 if (bitset(MF_REGEX_NOT, map->map_mflags))
6924 {
6925 /* option -n */
6926 if (reg_res == REG_NOMATCH)
6927 return regex_map_rewrite(map, "", (size_t)0, av);
6928 else
6929 return NULL;

--- 14 unchanged lines hidden (view full) ---

6944 int *ip;
6945
6946 dp = retbuf;
6947 ldp = retbuf + sizeof(retbuf) - 1;
6948
6949 if (av[1] != NULL)
6950 {
6951 if (parse_fields(av[1], fields, MAX_MATCH + 1,
5118 (int) map_p->pattern_buf.re_nsub + 1) == -1)
6952 (int) map_p->regex_pattern_buf.re_nsub + 1) == -1)
5119 {
5120 *statp = EX_CONFIG;
5121 return NULL;
5122 }
5123 ip = fields;
5124 }
5125 else
5126 ip = map_p->regex_subfields;
5127
5128 for ( ; *ip != END_OF_FIELDS; ip++)
5129 {
5130 if (!first)
5131 {
6953 {
6954 *statp = EX_CONFIG;
6955 return NULL;
6956 }
6957 ip = fields;
6958 }
6959 else
6960 ip = map_p->regex_subfields;
6961
6962 for ( ; *ip != END_OF_FIELDS; ip++)
6963 {
6964 if (!first)
6965 {
5132 for (sp = map_p->delim; *sp; sp++)
6966 for (sp = map_p->regex_delim; *sp; sp++)
5133 {
5134 if (dp < ldp)
5135 *dp++ = *sp;
5136 }
5137 }
5138 else
5139 first = FALSE;
5140
5141
5142 if (pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0)
5143 continue;
5144
5145 sp = name + pmatch[*ip].rm_so;
5146 endp = name + pmatch[*ip].rm_eo;
5147 for (; endp > sp; sp++)
5148 {
5149 if (dp < ldp)
5150 {
6967 {
6968 if (dp < ldp)
6969 *dp++ = *sp;
6970 }
6971 }
6972 else
6973 first = FALSE;
6974
6975
6976 if (pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0)
6977 continue;
6978
6979 sp = name + pmatch[*ip].rm_so;
6980 endp = name + pmatch[*ip].rm_eo;
6981 for (; endp > sp; sp++)
6982 {
6983 if (dp < ldp)
6984 {
5151 if(bslashmode)
5152 {
6985 if (bslashmode)
6986 {
5153 *dp++ = *sp;
5154 bslashmode = FALSE;
5155 }
6987 *dp++ = *sp;
6988 bslashmode = FALSE;
6989 }
5156 else if(quotemode && *sp != '"' &&
6990 else if (quotemode && *sp != '"' &&
5157 *sp != '\\')
5158 {
5159 *dp++ = *sp;
5160 }
5161 else switch(*dp++ = *sp)
5162 {
5163 case '\\':
5164 bslashmode = TRUE;

--- 24 unchanged lines hidden (view full) ---

5189 break;
5190 }
5191 }
5192 }
5193 }
5194 if (anglecnt != 0 || cmntcnt != 0 || quotemode ||
5195 bslashmode || spacecnt != 0)
5196 {
6991 *sp != '\\')
6992 {
6993 *dp++ = *sp;
6994 }
6995 else switch(*dp++ = *sp)
6996 {
6997 case '\\':
6998 bslashmode = TRUE;

--- 24 unchanged lines hidden (view full) ---

7023 break;
7024 }
7025 }
7026 }
7027 }
7028 if (anglecnt != 0 || cmntcnt != 0 || quotemode ||
7029 bslashmode || spacecnt != 0)
7030 {
5197 sm_syslog(LOG_WARNING, NOQID,
5198 "Warning: regex may cause prescan() failure map=%s lookup=%s",
5199 map->map_mname, name);
7031 sm_syslog(LOG_WARNING, NOQID,
7032 "Warning: regex may cause prescan() failure map=%s lookup=%s",
7033 map->map_mname, name);
5200 return NULL;
5201 }
5202
5203 *dp = '\0';
5204
5205 return regex_map_rewrite(map, retbuf, strlen(retbuf), av);
5206 }
5207 return regex_map_rewrite(map, "", (size_t)0, av);
5208}
5209#endif /* MAP_REGEX */
7034 return NULL;
7035 }
7036
7037 *dp = '\0';
7038
7039 return regex_map_rewrite(map, retbuf, strlen(retbuf), av);
7040 }
7041 return regex_map_rewrite(map, "", (size_t)0, av);
7042}
7043#endif /* MAP_REGEX */
7044 /*
7045** NSD modules
7046*/
7047#ifdef MAP_NSD
7048
7049# include <ndbm.h>
7050# define _DATUM_DEFINED
7051# include <ns_api.h>
7052
7053typedef struct ns_map_list
7054{
7055 ns_map_t *map;
7056 char *mapname;
7057 struct ns_map_list *next;
7058} ns_map_list_t;
7059
7060static ns_map_t *
7061ns_map_t_find(mapname)
7062 char *mapname;
7063{
7064 static ns_map_list_t *ns_maps = NULL;
7065 ns_map_list_t *ns_map;
7066
7067 /* walk the list of maps looking for the correctly named map */
7068 for (ns_map = ns_maps; ns_map != NULL; ns_map = ns_map->next)
7069 {
7070 if (strcmp(ns_map->mapname, mapname) == 0)
7071 break;
7072 }
7073
7074 /* if we are looking at a NULL ns_map_list_t, then create a new one */
7075 if (ns_map == NULL)
7076 {
7077 ns_map = (ns_map_list_t *) xalloc(sizeof *ns_map);
7078 ns_map->mapname = newstr(mapname);
7079 ns_map->map = (ns_map_t *) xalloc(sizeof *ns_map->map);
7080 ns_map->next = ns_maps;
7081 ns_maps = ns_map;
7082 }
7083 return ns_map->map;
7084}
7085
7086char *
7087nsd_map_lookup(map, name, av, statp)
7088 MAP *map;
7089 char *name;
7090 char **av;
7091 int *statp;
7092{
7093 int buflen;
7094 char *p;
7095 ns_map_t *ns_map;
7096 char keybuf[MAXNAME + 1];
7097 char buf[MAXLINE];
7098
7099 if (tTd(38, 20))
7100 dprintf("nsd_map_lookup(%s, %s)\n", map->map_mname, name);
7101
7102 buflen = strlen(name);
7103 if (buflen > sizeof keybuf - 1)
7104 buflen = sizeof keybuf - 1;
7105 memmove(keybuf, name, buflen);
7106 keybuf[buflen] = '\0';
7107 if (!bitset(MF_NOFOLDCASE, map->map_mflags))
7108 makelower(keybuf);
7109
7110 ns_map = ns_map_t_find(map->map_file);
7111 if (ns_map == NULL)
7112 {
7113 if (tTd(38, 20))
7114 dprintf("nsd_map_t_find failed\n");
7115 return NULL;
7116 }
7117
7118 if (ns_lookup(ns_map, NULL, map->map_file,
7119 keybuf, NULL, buf, MAXLINE) == NULL)
7120 return NULL;
7121
7122 /* Null out trailing \n */
7123 if ((p = strchr(buf, '\n')) != NULL)
7124 *p = '\0';
7125
7126 return map_rewrite(map, buf, strlen(buf), av);
7127}
7128#endif /* MAP_NSD */
7129
7130char *
7131arith_map_lookup(map, name, av, statp)
7132 MAP *map;
7133 char *name;
7134 char **av;
7135 int *statp;
7136{
7137 long r;
7138 long v[2];
7139 bool res = FALSE;
7140 bool boolres;
7141 static char result[16];
7142 char **cpp;
7143
7144 if (tTd(38, 2))
7145 {
7146 dprintf("arith_map_lookup: key '%s'\n", name);
7147 for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
7148 dprintf("arith_map_lookup: arg '%s'\n", *cpp);
7149 }
7150 r = 0;
7151 boolres = FALSE;
7152 cpp = av;
7153 *statp = EX_OK;
7154
7155 /*
7156 ** read arguments for arith map
7157 ** - no check is made whether they are really numbers
7158 ** - just ignores args after the second
7159 */
7160 for (++cpp; cpp != NULL && *cpp != NULL && r < 2; cpp++)
7161 v[r++] = strtol(*cpp, NULL, 0);
7162
7163 /* operator and (at least) two operands given? */
7164 if (name != NULL && r == 2)
7165 {
7166 switch(*name)
7167 {
7168#if _FFR_ARITH
7169 case '|':
7170 r = v[0] | v[1];
7171 break;
7172
7173 case '&':
7174 r = v[0] & v[1];
7175 break;
7176
7177 case '%':
7178 if (v[1] == 0)
7179 return NULL;
7180 r = v[0] % v[1];
7181 break;
7182#endif /* _FFR_ARITH */
7183
7184 case '+':
7185 r = v[0] + v[1];
7186 break;
7187
7188 case '-':
7189 r = v[0] - v[1];
7190 break;
7191
7192 case '*':
7193 r = v[0] * v[1];
7194 break;
7195
7196 case '/':
7197 if (v[1] == 0)
7198 return NULL;
7199 r = v[0] / v[1];
7200 break;
7201
7202 case 'l':
7203 res = v[0] < v[1];
7204 boolres = TRUE;
7205 break;
7206
7207 case '=':
7208 res = v[0] == v[1];
7209 boolres = TRUE;
7210 break;
7211
7212 default:
7213 /* XXX */
7214 *statp = EX_CONFIG;
7215 if (LogLevel > 10)
7216 sm_syslog(LOG_WARNING, NOQID,
7217 "arith_map: unknown operator %c",
7218 isprint(*name) ? *name : '?');
7219 return NULL;
7220 }
7221 if (boolres)
7222 snprintf(result, sizeof result, res ? "TRUE" : "FALSE");
7223 else
7224 snprintf(result, sizeof result, "%ld", r);
7225 return result;
7226 }
7227 *statp = EX_CONFIG;
7228 return NULL;
7229}