summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/map.c')
-rw-r--r--usr.sbin/sendmail/src/map.c4399
1 files changed, 0 insertions, 4399 deletions
diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c
deleted file mode 100644
index e889736..0000000
--- a/usr.sbin/sendmail/src/map.c
+++ /dev/null
@@ -1,4399 +0,0 @@
-/*
- * Copyright (c) 1992, 1995-1997 Eric P. Allman.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)map.c 8.186 (Berkeley) 10/21/97";
-#endif /* not lint */
-
-#include "sendmail.h"
-
-#ifdef NDBM
-# include <ndbm.h>
-# ifdef R_FIRST
- ERROR README: You are running the Berkeley DB version of ndbm.h. See
- ERROR README: the READ_ME file about tweaking Berkeley DB so it can
- ERROR README: coexist with NDBM, or delete -DNDBM from the Makefile
- ERROR README: and use -DNEWDB instead.
-# endif
-#endif
-#ifdef NEWDB
-# include <db.h>
-#endif
-#ifdef NIS
- struct dom_binding; /* forward reference needed on IRIX */
-# include <rpcsvc/ypclnt.h>
-# ifdef NDBM
-# define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
-# endif
-#endif
-
-/*
-** MAP.C -- implementations for various map classes.
-**
-** Each map class implements a series of functions:
-**
-** bool map_parse(MAP *map, char *args)
-** Parse the arguments from the config file. Return TRUE
-** if they were ok, FALSE otherwise. Fill in map with the
-** values.
-**
-** char *map_lookup(MAP *map, char *key, char **args, int *pstat)
-** Look up the key in the given map. If found, do any
-** rewriting the map wants (including "args" if desired)
-** and return the value. Set *pstat to the appropriate status
-** on error and return NULL. Args will be NULL if called
-** from the alias routines, although this should probably
-** not be relied upon. It is suggested you call map_rewrite
-** to return the results -- it takes care of null termination
-** and uses a dynamically expanded buffer as needed.
-**
-** void map_store(MAP *map, char *key, char *value)
-** Store the key:value pair in the map.
-**
-** bool map_open(MAP *map, int mode)
-** Open the map for the indicated mode. Mode should
-** be either O_RDONLY or O_RDWR. Return TRUE if it
-** was opened successfully, FALSE otherwise. If the open
-** failed an the MF_OPTIONAL flag is not set, it should
-** also print an error. If the MF_ALIAS bit is set
-** and this map class understands the @:@ convention, it
-** should call aliaswait() before returning.
-**
-** void map_close(MAP *map)
-** Close the map.
-**
-** This file also includes the implementation for getcanonname.
-** It is currently implemented in a pretty ad-hoc manner; it ought
-** to be more properly integrated into the map structure.
-*/
-
-#define DBMMODE 0644
-
-#ifndef EX_NOTFOUND
-# define EX_NOTFOUND EX_NOHOST
-#endif
-
-extern bool aliaswait __P((MAP *, char *, int));
-extern bool extract_canonname __P((char *, char *, char[], int));
-
-#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
-# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
-#else
-# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
-#endif
-
-#ifndef O_ACCMODE
-# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-#endif
- /*
-** MAP_PARSEARGS -- parse config line arguments for database lookup
-**
-** This is a generic version of the map_parse method.
-**
-** Parameters:
-** map -- the map being initialized.
-** ap -- a pointer to the args on the config line.
-**
-** Returns:
-** TRUE -- if everything parsed OK.
-** FALSE -- otherwise.
-**
-** Side Effects:
-** null terminates the filename; stores it in map
-*/
-
-bool
-map_parseargs(map, ap)
- MAP *map;
- char *ap;
-{
- register char *p = ap;
-
- map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
- for (;;)
- {
- while (isascii(*p) && isspace(*p))
- p++;
- if (*p != '-')
- break;
- switch (*++p)
- {
- case 'N':
- map->map_mflags |= MF_INCLNULL;
- map->map_mflags &= ~MF_TRY0NULL;
- break;
-
- case 'O':
- map->map_mflags &= ~MF_TRY1NULL;
- break;
-
- case 'o':
- map->map_mflags |= MF_OPTIONAL;
- break;
-
- case 'f':
- map->map_mflags |= MF_NOFOLDCASE;
- break;
-
- case 'm':
- map->map_mflags |= MF_MATCHONLY;
- break;
-
- case 'A':
- map->map_mflags |= MF_APPEND;
- break;
-
- case 'q':
- map->map_mflags |= MF_KEEPQUOTES;
- break;
-
- case 'a':
- map->map_app = ++p;
- break;
-
- case 'k':
- while (isascii(*++p) && isspace(*p))
- continue;
- map->map_keycolnm = p;
- break;
-
- case 'v':
- while (isascii(*++p) && isspace(*p))
- continue;
- map->map_valcolnm = p;
- break;
-
- case 'z':
- if (*++p != '\\')
- map->map_coldelim = *p;
- else
- {
- switch (*++p)
- {
- case 'n':
- map->map_coldelim = '\n';
- break;
-
- case 't':
- map->map_coldelim = '\t';
- break;
-
- default:
- map->map_coldelim = '\\';
- }
- }
- break;
-
- case 't':
- map->map_mflags |= MF_NODEFER;
- break;
-
-#ifdef RESERVED_FOR_SUN
- case 'd':
- map->map_mflags |= MF_DOMAIN_WIDE;
- break;
-
- case 's':
- /* info type */
- break;
-#endif
- }
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p != '\0')
- *p++ = '\0';
- }
- if (map->map_app != NULL)
- map->map_app = newstr(map->map_app);
- if (map->map_keycolnm != NULL)
- map->map_keycolnm = newstr(map->map_keycolnm);
- if (map->map_valcolnm != NULL)
- map->map_valcolnm = newstr(map->map_valcolnm);
-
- if (*p != '\0')
- {
- map->map_file = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p != '\0')
- *p++ = '\0';
- map->map_file = newstr(map->map_file);
- }
-
- while (*p != '\0' && isascii(*p) && isspace(*p))
- p++;
- if (*p != '\0')
- map->map_rebuild = newstr(p);
-
- if (map->map_file == NULL &&
- !bitset(MCF_OPTFILE, map->map_class->map_cflags))
- {
- syserr("No file name for %s map %s",
- map->map_class->map_cname, map->map_mname);
- return FALSE;
- }
- return TRUE;
-}
- /*
-** MAP_REWRITE -- rewrite a database key, interpolating %n indications.
-**
-** It also adds the map_app string. It can be used as a utility
-** in the map_lookup method.
-**
-** Parameters:
-** map -- the map that causes this.
-** s -- the string to rewrite, NOT necessarily null terminated.
-** slen -- the length of s.
-** av -- arguments to interpolate into buf.
-**
-** Returns:
-** Pointer to rewritten result. This is static data that
-** should be copied if it is to be saved!
-**
-** Side Effects:
-** none.
-*/
-
-char *
-map_rewrite(map, s, slen, av)
- register MAP *map;
- register const char *s;
- int slen;
- char **av;
-{
- register char *bp;
- register char c;
- char **avp;
- register char *ap;
- int i;
- int len;
- static int buflen = -1;
- static char *buf = NULL;
-
- if (tTd(39, 1))
- {
- printf("map_rewrite(%.*s), av =", slen, s);
- if (av == NULL)
- printf(" (nullv)");
- else
- {
- for (avp = av; *avp != NULL; avp++)
- printf("\n\t%s", *avp);
- }
- printf("\n");
- }
-
- /* count expected size of output (can safely overestimate) */
- i = len = slen;
- if (av != NULL)
- {
- const char *sp = s;
-
- for (i = slen; --i >= 0 && (c = *sp++) != 0; )
- {
- if (c != '%')
- continue;
- if (--i < 0)
- break;
- c = *sp++;
- if (!(isascii(c) && isdigit(c)))
- continue;
- for (avp = av; --c >= '0' && *avp != NULL; avp++)
- continue;
- if (*avp == NULL)
- continue;
- len += strlen(*avp);
- }
- }
- if (map->map_app != NULL)
- len += strlen(map->map_app);
- if (buflen < ++len)
- {
- /* need to malloc additional space */
- buflen = len;
- if (buf != NULL)
- free(buf);
- buf = xalloc(buflen);
- }
-
- bp = buf;
- if (av == NULL)
- {
- bcopy(s, bp, slen);
- bp += slen;
- }
- else
- {
- while (--slen >= 0 && (c = *s++) != '\0')
- {
- if (c != '%')
- {
- pushc:
- *bp++ = c;
- continue;
- }
- if (--slen < 0 || (c = *s++) == '\0')
- c = '%';
- if (c == '%')
- goto pushc;
- if (!(isascii(c) && isdigit(c)))
- {
- *bp++ = '%';
- goto pushc;
- }
- for (avp = av; --c >= '0' && *avp != NULL; avp++)
- continue;
- if (*avp == NULL)
- continue;
-
- /* transliterate argument into output string */
- for (ap = *avp; (c = *ap++) != '\0'; )
- *bp++ = c;
- }
- }
- if (map->map_app != NULL)
- strcpy(bp, map->map_app);
- else
- *bp = '\0';
- if (tTd(39, 1))
- printf("map_rewrite => %s\n", buf);
- return buf;
-}
- /*
-** INITMAPS -- initialize for aliasing
-**
-** Parameters:
-** rebuild -- if TRUE, this rebuilds the cached versions.
-** e -- current envelope.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** initializes aliases:
-** if alias database: opens the database.
-** if no database available: reads aliases into the symbol table.
-*/
-
-void
-initmaps(rebuild, e)
- bool rebuild;
- register ENVELOPE *e;
-{
- extern void map_init();
-
-#if XDEBUG
- checkfd012("entering initmaps");
-#endif
- CurEnv = e;
-
- stabapply(map_init, 0);
- stabapply(map_init, rebuild ? 2 : 1);
-#if XDEBUG
- checkfd012("exiting initmaps");
-#endif
-}
-
-void
-map_init(s, pass)
- register STAB *s;
- int pass;
-{
- bool rebuildable;
- register MAP *map;
-
- /* has to be a map */
- if (s->s_type != ST_MAP)
- return;
-
- map = &s->s_map;
- if (!bitset(MF_VALID, map->map_mflags))
- return;
-
- if (tTd(38, 2))
- printf("map_init(%s:%s, %s, %d)\n",
- map->map_class->map_cname == NULL ? "NULL" :
- map->map_class->map_cname,
- map->map_mname == NULL ? "NULL" : map->map_mname,
- map->map_file == NULL ? "NULL" : map->map_file,
- pass);
-
- /*
- ** Pass 0 opens all non-rebuildable maps.
- ** Pass 1 opens all rebuildable maps for read.
- ** Pass 2 rebuilds all rebuildable maps.
- */
-
- rebuildable = (bitset(MF_ALIAS, map->map_mflags) &&
- bitset(MCF_REBUILDABLE, map->map_class->map_cflags));
-
- if ((pass == 0 && rebuildable) ||
- ((pass == 1 || pass == 2) && !rebuildable))
- {
- if (tTd(38, 3))
- printf("\twrong pass (pass = %d, rebuildable = %d)\n",
- pass, rebuildable);
- return;
- }
-
- /* if already open, close it (for nested open) */
- if (bitset(MF_OPEN, map->map_mflags))
- {
- map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
- }
-
- if (pass == 2)
- {
- rebuildaliases(map, FALSE);
- return;
- }
-
- if (map->map_class->map_open(map, O_RDONLY))
- {
- if (tTd(38, 4))
- printf("\t%s:%s %s: valid\n",
- map->map_class->map_cname == NULL ? "NULL" :
- map->map_class->map_cname,
- map->map_mname == NULL ? "NULL" :
- map->map_mname,
- map->map_file == NULL ? "NULL" :
- map->map_file);
- map->map_mflags |= MF_OPEN;
- }
- else
- {
- if (tTd(38, 4))
- printf("\t%s:%s %s: invalid: %s\n",
- map->map_class->map_cname == NULL ? "NULL" :
- map->map_class->map_cname,
- map->map_mname == NULL ? "NULL" :
- map->map_mname,
- map->map_file == NULL ? "NULL" :
- map->map_file,
- errstring(errno));
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- extern MAPCLASS BogusMapClass;
-
- map->map_class = &BogusMapClass;
- map->map_mflags |= MF_OPEN;
- }
- }
-}
- /*
-** GETCANONNAME -- look up name using service switch
-**
-** Parameters:
-** host -- the host name to look up.
-** hbsize -- the size of the host buffer.
-** trymx -- if set, try MX records.
-**
-** Returns:
-** TRUE -- if the host was found.
-** FALSE -- otherwise.
-*/
-
-bool
-getcanonname(host, hbsize, trymx)
- char *host;
- int hbsize;
- bool trymx;
-{
- int nmaps;
- int mapno;
- bool found = FALSE;
- bool got_tempfail = FALSE;
- auto int stat;
- char *maptype[MAXMAPSTACK];
- short mapreturn[MAXMAPACTIONS];
-
- nmaps = switch_map_find("hosts", maptype, mapreturn);
- for (mapno = 0; mapno < nmaps; mapno++)
- {
- int i;
-
- if (tTd(38, 20))
- printf("getcanonname(%s), trying %s\n",
- host, maptype[mapno]);
- if (strcmp("files", maptype[mapno]) == 0)
- {
- extern bool text_getcanonname __P((char *, int, int *));
-
- found = text_getcanonname(host, hbsize, &stat);
- }
-#ifdef NIS
- else if (strcmp("nis", maptype[mapno]) == 0)
- {
- extern bool nis_getcanonname __P((char *, int, int *));
-
- found = nis_getcanonname(host, hbsize, &stat);
- }
-#endif
-#ifdef NISPLUS
- else if (strcmp("nisplus", maptype[mapno]) == 0)
- {
- extern bool nisplus_getcanonname __P((char *, int, int *));
-
- found = nisplus_getcanonname(host, hbsize, &stat);
- }
-#endif
-#if NAMED_BIND
- else if (strcmp("dns", maptype[mapno]) == 0)
- {
- extern bool dns_getcanonname __P((char *, int, bool, int *));
-
- found = dns_getcanonname(host, hbsize, trymx, &stat);
- }
-#endif
-#if NETINFO
- else if (strcmp("netinfo", maptype[mapno]) == 0)
- {
- extern bool ni_getcanonname __P((char *, int, int *));
-
- found = ni_getcanonname(host, hbsize, &stat);
- }
-#endif
- else
- {
- found = FALSE;
- stat = EX_UNAVAILABLE;
- }
-
- /*
- ** Heuristic: if $m is not set, we are running during system
- ** startup. In this case, when a name is apparently found
- ** but has no dot, treat is as not found. This avoids
- ** problems if /etc/hosts has no FQDN but is listed first
- ** in the service switch.
- */
-
- if (found &&
- (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL))
- break;
-
- /* see if we should continue */
- if (stat == EX_TEMPFAIL)
- {
- i = MA_TRYAGAIN;
- got_tempfail = TRUE;
- }
- else if (stat == EX_NOTFOUND)
- i = MA_NOTFOUND;
- else
- i = MA_UNAVAIL;
- if (bitset(1 << mapno, mapreturn[i]))
- break;
- }
-
- if (found)
- {
- char *d;
-
- if (tTd(38, 20))
- printf("getcanonname(%s), found\n", host);
-
- /*
- ** If returned name is still single token, compensate
- ** by tagging on $m. This is because some sites set
- ** up their DNS or NIS databases wrong.
- */
-
- if ((d = strchr(host, '.')) == NULL || d[1] == '\0')
- {
- d = macvalue('m', CurEnv);
- if (d != NULL &&
- hbsize > (int) (strlen(host) + strlen(d) + 1))
- {
- if (host[strlen(host) - 1] != '.')
- strcat(host, ".");
- strcat(host, d);
- }
- else
- {
- return FALSE;
- }
- }
- return TRUE;
- }
-
- if (tTd(38, 20))
- printf("getcanonname(%s), failed, stat=%d\n", host, stat);
-
-#if NAMED_BIND
- if (got_tempfail)
- h_errno = TRY_AGAIN;
- else
- h_errno = HOST_NOT_FOUND;
-#endif
-
- return FALSE;
-}
- /*
-** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
-**
-** Parameters:
-** name -- the name against which to match.
-** line -- the /etc/hosts line.
-** cbuf -- the location to store the result.
-** cbuflen -- the size of cbuf.
-**
-** Returns:
-** TRUE -- if the line matched the desired name.
-** FALSE -- otherwise.
-*/
-
-bool
-extract_canonname(name, line, cbuf, cbuflen)
- char *name;
- char *line;
- char cbuf[];
- int cbuflen;
-{
- int i;
- char *p;
- bool found = FALSE;
- extern char *get_column __P((char *, int, char, char *, int));
-
- cbuf[0] = '\0';
- if (line[0] == '#')
- return FALSE;
-
- for (i = 1; ; i++)
- {
- char nbuf[MAXNAME + 1];
-
- p = get_column(line, i, '\0', nbuf, sizeof nbuf);
- if (p == NULL)
- break;
- if (*p == '\0')
- continue;
- if (cbuf[0] == '\0' ||
- (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL))
- {
- snprintf(cbuf, cbuflen, "%s", p);
- }
- if (strcasecmp(name, p) == 0)
- found = TRUE;
- }
- if (found && strchr(cbuf, '.') == NULL)
- {
- /* try to add a domain on the end of the name */
- char *domain = macvalue('m', CurEnv);
-
- if (domain != NULL &&
- strlen(domain) + strlen(cbuf) + 1 < cbuflen)
- {
- p = &cbuf[strlen(cbuf)];
- *p++ = '.';
- strcpy(p, domain);
- }
- }
- return found;
-}
- /*
-** NDBM modules
-*/
-
-#ifdef NDBM
-
-/*
-** NDBM_MAP_OPEN -- DBM-style map open
-*/
-
-bool
-ndbm_map_open(map, mode)
- MAP *map;
- int mode;
-{
- register DBM *dbm;
- struct stat st;
- int dfd;
- int pfd;
- int sff;
- int ret;
- int smode = S_IREAD;
- char dirfile[MAXNAME + 1];
- char pagfile[MAXNAME + 1];
- struct stat std, stp;
-
- if (tTd(38, 2))
- printf("ndbm_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
- map->map_lockfd = -1;
- mode &= O_ACCMODE;
-
- /* do initial file and directory checks */
- snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file);
- snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file);
- sff = SFF_ROOTOK|SFF_REGONLY;
- if (mode == O_RDWR)
- {
- sff |= SFF_NOLINK|SFF_CREAT;
- smode = S_IWRITE;
- }
- else
- {
- sff |= SFF_NOWLINK;
- }
- if (FatalWritableDirs)
- sff |= SFF_SAFEDIRPATH;
- if ((ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName,
- sff, smode, &std)) != 0 ||
- (ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName,
- sff, smode, &stp)) != 0)
- {
- /* cannot open this map */
- if (tTd(38, 2))
- printf("\tunsafe map file: %d\n", ret);
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("dbm map \"%s\": unsafe map file %s",
- map->map_mname, map->map_file);
- return FALSE;
- }
- if (std.st_mode == ST_MODE_NOFILE)
- mode |= O_CREAT|O_EXCL;
-
-#if LOCK_ON_OPEN
- if (mode == O_RDONLY)
- mode |= O_SHLOCK;
- else
- mode |= O_TRUNC|O_EXLOCK;
-#else
- if ((mode & O_ACCMODE) == O_RDWR)
- {
-# if NOFTRUNCATE
- /*
- ** Warning: race condition. Try to lock the file as
- ** quickly as possible after opening it.
- ** This may also have security problems on some systems,
- ** but there isn't anything we can do about it.
- */
-
- mode |= O_TRUNC;
-# else
- /*
- ** This ugly code opens the map without truncating it,
- ** locks the file, then truncates it. Necessary to
- ** avoid race conditions.
- */
-
- int dirfd;
- int pagfd;
-
- dirfd = safeopen(dirfile, mode, DBMMODE,
- SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
- pagfd = safeopen(pagfile, mode, DBMMODE,
- SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
-
- if (dirfd < 0 || pagfd < 0)
- {
- int save_errno = errno;
-
- if (dirfd >= 0)
- (void) close(dirfd);
- if (pagfd >= 0)
- (void) close(pagfd);
- errno = save_errno;
- syserr("ndbm_map_open: cannot create database %s",
- map->map_file);
- return FALSE;
- }
- if (ftruncate(dirfd, (off_t) 0) < 0 ||
- ftruncate(pagfd, (off_t) 0) < 0)
- {
- int save_errno = errno;
-
- (void) close(dirfd);
- (void) close(pagfd);
- errno = save_errno;
- syserr("ndbm_map_open: cannot truncate %s.{dir,pag}",
- map->map_file);
- return FALSE;
- }
-
- /* if new file, get "before" bits for later filechanged check */
- if (std.st_mode == ST_MODE_NOFILE &&
- (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0))
- {
- int save_errno = errno;
-
- (void) close(dirfd);
- (void) close(pagfd);
- errno = save_errno;
- syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file",
- map->map_file);
- return FALSE;
- }
-
- /* have to save the lock for the duration (bletch) */
- map->map_lockfd = dirfd;
- close(pagfd);
-
- /* twiddle bits for dbm_open */
- mode &= ~(O_CREAT|O_EXCL);
-# endif
- }
-#endif
-
- /* open the database */
- dbm = dbm_open(map->map_file, mode, DBMMODE);
- if (dbm == NULL)
- {
- int save_errno = errno;
-
- if (bitset(MF_ALIAS, map->map_mflags) &&
- aliaswait(map, ".pag", FALSE))
- return TRUE;
-#if !LOCK_ON_OPEN && !NOFTRUNCATE
- if (map->map_lockfd >= 0)
- close(map->map_lockfd);
-#endif
- errno = save_errno;
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("Cannot open DBM database %s", map->map_file);
- return FALSE;
- }
- dfd = dbm_dirfno(dbm);
- pfd = dbm_pagfno(dbm);
- if (dfd == pfd)
- {
- /* heuristic: if files are linked, this is actually gdbm */
- dbm_close(dbm);
-#if !LOCK_ON_OPEN && !NOFTRUNCATE
- if (map->map_lockfd >= 0)
- close(map->map_lockfd);
-#endif
- errno = 0;
- syserr("dbm map \"%s\": cannot support GDBM",
- map->map_mname);
- return FALSE;
- }
-
- if (filechanged(dirfile, dfd, &std, sff) ||
- filechanged(pagfile, pfd, &stp, sff))
- {
- int save_errno = errno;
-
- dbm_close(dbm);
-#if !LOCK_ON_OPEN && !NOFTRUNCATE
- if (map->map_lockfd >= 0)
- close(map->map_lockfd);
-#endif
- errno = save_errno;
- syserr("ndbm_map_open(%s): file changed after open",
- map->map_file);
- return FALSE;
- }
-
- map->map_db1 = (ARBPTR_T) dbm;
- if (mode == O_RDONLY)
- {
-#if LOCK_ON_OPEN
- if (dfd >= 0)
- (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
- if (pfd >= 0)
- (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN);
-#endif
- if (bitset(MF_ALIAS, map->map_mflags) &&
- !aliaswait(map, ".pag", TRUE))
- return FALSE;
- }
- else
- {
- map->map_mflags |= MF_LOCKED;
- }
- if (fstat(dfd, &st) >= 0)
- map->map_mtime = st.st_mtime;
- return TRUE;
-}
-
-
-/*
-** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map
-*/
-
-char *
-ndbm_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- datum key, val;
- int fd;
- char keybuf[MAXNAME + 1];
- struct stat stbuf;
-
- if (tTd(38, 20))
- printf("ndbm_map_lookup(%s, %s)\n",
- map->map_mname, name);
-
- key.dptr = name;
- key.dsize = strlen(name);
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- {
- if (key.dsize > sizeof keybuf - 1)
- key.dsize = sizeof keybuf - 1;
- bcopy(key.dptr, keybuf, key.dsize);
- keybuf[key.dsize] = '\0';
- makelower(keybuf);
- key.dptr = keybuf;
- }
-lockdbm:
- fd = dbm_dirfno((DBM *) map->map_db1);
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
- if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
- {
- /* Reopen the database to sync the cache */
- int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
- : O_RDONLY;
-
- map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
- if (map->map_class->map_open(map, omode))
- {
- map->map_mflags |= MF_OPEN;
- if ((omode && O_ACCMODE) == O_RDWR)
- map->map_mflags |= MF_WRITABLE;
- goto lockdbm;
- }
- else
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- extern MAPCLASS BogusMapClass;
-
- *statp = EX_TEMPFAIL;
- map->map_class = &BogusMapClass;
- map->map_mflags |= MF_OPEN;
- syserr("Cannot reopen NDBM database %s",
- map->map_file);
- }
- return NULL;
- }
- }
- val.dptr = NULL;
- if (bitset(MF_TRY0NULL, map->map_mflags))
- {
- val = dbm_fetch((DBM *) map->map_db1, key);
- if (val.dptr != NULL)
- map->map_mflags &= ~MF_TRY1NULL;
- }
- if (val.dptr == NULL && bitset(MF_TRY1NULL, map->map_mflags))
- {
- key.dsize++;
- val = dbm_fetch((DBM *) map->map_db1, key);
- if (val.dptr != NULL)
- map->map_mflags &= ~MF_TRY0NULL;
- }
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
- if (val.dptr == NULL)
- return NULL;
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, name, strlen(name), NULL);
- else
- return map_rewrite(map, val.dptr, val.dsize, av);
-}
-
-
-/*
-** NDBM_MAP_STORE -- store a datum in the database
-*/
-
-void
-ndbm_map_store(map, lhs, rhs)
- register MAP *map;
- char *lhs;
- char *rhs;
-{
- datum key;
- datum data;
- int stat;
- char keybuf[MAXNAME + 1];
-
- if (tTd(38, 12))
- printf("ndbm_map_store(%s, %s, %s)\n",
- map->map_mname, lhs, rhs);
-
- key.dsize = strlen(lhs);
- key.dptr = lhs;
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- {
- if (key.dsize > sizeof keybuf - 1)
- key.dsize = sizeof keybuf - 1;
- bcopy(key.dptr, keybuf, key.dsize);
- keybuf[key.dsize] = '\0';
- makelower(keybuf);
- key.dptr = keybuf;
- }
-
- data.dsize = strlen(rhs);
- data.dptr = rhs;
-
- if (bitset(MF_INCLNULL, map->map_mflags))
- {
- key.dsize++;
- data.dsize++;
- }
-
- stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
- if (stat > 0)
- {
- if (!bitset(MF_APPEND, map->map_mflags))
- message("050 Warning: duplicate alias name %s", lhs);
- else
- {
- static char *buf = NULL;
- static int bufsiz = 0;
- auto int xstat;
- datum old;
-
- old.dptr = ndbm_map_lookup(map, key.dptr, NULL, &xstat);
- if (old.dptr != NULL && *(char *) old.dptr != '\0')
- {
- old.dsize = strlen(old.dptr);
- if (data.dsize + old.dsize + 2 > bufsiz)
- {
- if (buf != NULL)
- (void) free(buf);
- bufsiz = data.dsize + old.dsize + 2;
- buf = xalloc(bufsiz);
- }
- snprintf(buf, bufsiz, "%s,%s",
- data.dptr, old.dptr);
- data.dsize = data.dsize + old.dsize + 1;
- data.dptr = buf;
- if (tTd(38, 9))
- printf("ndbm_map_store append=%s\n", data.dptr);
- }
- }
- stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE);
- }
- if (stat != 0)
- syserr("readaliases: dbm put (%s)", lhs);
-}
-
-
-/*
-** NDBM_MAP_CLOSE -- close the database
-*/
-
-void
-ndbm_map_close(map)
- register MAP *map;
-{
- if (tTd(38, 9))
- printf("ndbm_map_close(%s, %s, %x)\n",
- map->map_mname, map->map_file, map->map_mflags);
-
- if (bitset(MF_WRITABLE, map->map_mflags))
- {
-#ifdef NDBM_YP_COMPAT
- bool inclnull;
- char buf[200];
-
- inclnull = bitset(MF_INCLNULL, map->map_mflags);
- map->map_mflags &= ~MF_INCLNULL;
-
- if (strstr(map->map_file, "/yp/") != NULL)
- {
- long save_mflags = map->map_mflags;
-
- map->map_mflags |= MF_NOFOLDCASE;
-
- (void) snprintf(buf, sizeof buf, "%010ld", curtime());
- ndbm_map_store(map, "YP_LAST_MODIFIED", buf);
-
- (void) gethostname(buf, sizeof buf);
- ndbm_map_store(map, "YP_MASTER_NAME", buf);
-
- map->map_mflags = save_mflags;
- }
-
- if (inclnull)
- map->map_mflags |= MF_INCLNULL;
-#endif
-
- /* write out the distinguished alias */
- ndbm_map_store(map, "@", "@");
- }
- dbm_close((DBM *) map->map_db1);
-
- /* release lock (if needed) */
-#if !LOCK_ON_OPEN
- if (map->map_lockfd >= 0)
- (void) close(map->map_lockfd);
-#endif
-}
-
-#endif
- /*
-** NEWDB (Hash and BTree) Modules
-*/
-
-#ifdef NEWDB
-
-/*
-** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives.
-**
-** These do rather bizarre locking. If you can lock on open,
-** do that to avoid the condition of opening a database that
-** is being rebuilt. If you don't, we'll try to fake it, but
-** there will be a race condition. If opening for read-only,
-** we immediately release the lock to avoid freezing things up.
-** We really ought to hold the lock, but guarantee that we won't
-** be pokey about it. That's hard to do.
-*/
-
-extern bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
-
-/* these should be K line arguments */
-#ifndef DB_CACHE_SIZE
-# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
-#endif
-#ifndef DB_HASH_NELEM
-# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
-#endif
-
-bool
-bt_map_open(map, mode)
- MAP *map;
- int mode;
-{
- BTREEINFO btinfo;
-
- if (tTd(38, 2))
- printf("bt_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- bzero(&btinfo, sizeof btinfo);
- btinfo.cachesize = DB_CACHE_SIZE;
- return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
-}
-
-bool
-hash_map_open(map, mode)
- MAP *map;
- int mode;
-{
- HASHINFO hinfo;
-
- if (tTd(38, 2))
- printf("hash_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- bzero(&hinfo, sizeof hinfo);
- hinfo.nelem = DB_HASH_NELEM;
- hinfo.cachesize = DB_CACHE_SIZE;
- return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
-}
-
-bool
-db_map_open(map, mode, mapclassname, dbtype, openinfo)
- MAP *map;
- int mode;
- char *mapclassname;
- DBTYPE dbtype;
- const void *openinfo;
-{
- DB *db;
- int i;
- int omode;
- int smode = S_IREAD;
- int fd;
- int sff;
- int saveerrno;
- struct stat st;
- char buf[MAXNAME + 1];
-
- /* do initial file and directory checks */
- snprintf(buf, sizeof buf - 3, "%s", map->map_file);
- i = strlen(buf);
- if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
- (void) strcat(buf, ".db");
-
- mode &= O_ACCMODE;
- omode = mode;
-
- sff = SFF_ROOTOK|SFF_REGONLY;
- if (mode == O_RDWR)
- {
- sff |= SFF_NOLINK|SFF_CREAT;
- smode = S_IWRITE;
- }
- else
- {
- sff |= SFF_NOWLINK;
- }
- if (FatalWritableDirs)
- sff |= SFF_SAFEDIRPATH;
- if ((i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName,
- sff, smode, &st)) != 0)
- {
- /* cannot open this map */
- if (tTd(38, 2))
- printf("\tunsafe map file: %s\n", errstring(i));
- errno = i;
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("%s map \"%s\": unsafe map file %s",
- mapclassname, map->map_mname, map->map_file);
- return FALSE;
- }
- if (st.st_mode == ST_MODE_NOFILE)
- omode |= O_CREAT|O_EXCL;
-
- map->map_lockfd = -1;
-
-#if LOCK_ON_OPEN
- if (mode == O_RDWR)
- omode |= O_TRUNC|O_EXLOCK;
-# if !OLD_NEWDB
- else
- omode |= O_SHLOCK;
-# endif
-#else
- /*
- ** Pre-lock the file to avoid race conditions. In particular,
- ** since dbopen returns NULL if the file is zero length, we
- ** must have a locked instance around the dbopen.
- */
-
- fd = open(buf, omode, DBMMODE);
- if (fd < 0)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("db_map_open: cannot pre-open database %s", buf);
- return FALSE;
- }
-
- /* make sure no baddies slipped in just before the open... */
- if (filechanged(buf, fd, &st, sff))
- {
- int save_errno = errno;
-
- (void) close(fd);
- errno = save_errno;
- syserr("db_map_open(%s): file changed after pre-open", buf);
- return FALSE;
- }
-
- /* if new file, get the "before" bits for later filechanged check */
- if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0)
- {
- int save_errno = errno;
-
- (void) close(fd);
- errno = save_errno;
- syserr("db_map_open(%s): cannot fstat pre-opened file",
- buf);
- return FALSE;
- }
-
- /* actually lock the pre-opened file */
- if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
- syserr("db_map_open: cannot lock %s", buf);
-
- /* set up mode bits for dbopen */
- if (mode == O_RDWR)
- omode |= O_TRUNC;
- omode &= ~(O_EXCL|O_CREAT);
-#endif
-
- db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
- saveerrno = errno;
-
-#if !LOCK_ON_OPEN
- if (mode == O_RDWR)
- map->map_lockfd = fd;
- else
- (void) close(fd);
-#endif
-
- if (db == NULL)
- {
- if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
- aliaswait(map, ".db", FALSE))
- return TRUE;
-#if !LOCK_ON_OPEN
- if (map->map_lockfd >= 0)
- (void) close(map->map_lockfd);
-#endif
- errno = saveerrno;
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("Cannot open %s database %s",
- mapclassname, map->map_file);
- return FALSE;
- }
-
- if (filechanged(buf, db->fd(db), &st, sff))
- {
- int save_errno = errno;
-
- db->close(db);
-#if !LOCK_ON_OPEN
- if (map->map_lockfd >= 0)
- close(map->map_lockfd);
-#endif
- errno = save_errno;
- syserr("db_map_open(%s): file changed after open", buf);
- return FALSE;
- }
-
- if (mode == O_RDWR)
- map->map_mflags |= MF_LOCKED;
-#if !OLD_NEWDB
- fd = db->fd(db);
-# if LOCK_ON_OPEN
- if (fd >= 0 && mode == O_RDONLY)
- {
- (void) lockfile(fd, buf, NULL, LOCK_UN);
- }
-# endif
-#endif
-
- /* try to make sure that at least the database header is on disk */
- if (mode == O_RDWR)
-#if OLD_NEWDB
- (void) db->sync(db);
-#else
- (void) db->sync(db, 0);
-
- if (fd >= 0 && fstat(fd, &st) >= 0)
- map->map_mtime = st.st_mtime;
-#endif
-
- map->map_db2 = (ARBPTR_T) db;
- if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
- !aliaswait(map, ".db", TRUE))
- return FALSE;
- return TRUE;
-}
-
-
-/*
-** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
-*/
-
-char *
-db_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- DBT key, val;
- register DB *db = (DB *) map->map_db2;
- int i;
- int st;
- int saveerrno;
- int fd;
- struct stat stbuf;
- char keybuf[MAXNAME + 1];
- char buf[MAXNAME + 1];
-
- if (tTd(38, 20))
- printf("db_map_lookup(%s, %s)\n",
- map->map_mname, name);
-
- i = strlen(map->map_file);
- if (i > MAXNAME)
- i = MAXNAME;
- strncpy(buf, map->map_file, i);
- buf[i] = '\0';
- if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
- buf[i - 3] = '\0';
-
- key.size = strlen(name);
- if (key.size > sizeof keybuf - 1)
- key.size = sizeof keybuf - 1;
- key.data = keybuf;
- bcopy(name, keybuf, key.size);
- keybuf[key.size] = '\0';
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- makelower(keybuf);
-#if !OLD_NEWDB
- lockdb:
- fd = db->fd(db);
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, buf, ".db", LOCK_SH);
- if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
- {
- /* Reopen the database to sync the cache */
- int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
- : O_RDONLY;
-
- map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
- if (map->map_class->map_open(map, omode))
- {
- map->map_mflags |= MF_OPEN;
- if ((omode && O_ACCMODE) == O_RDWR)
- map->map_mflags |= MF_WRITABLE;
- db = (DB *) map->map_db2;
- goto lockdb;
- }
- else
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- extern MAPCLASS BogusMapClass;
-
- *statp = EX_TEMPFAIL;
- map->map_class = &BogusMapClass;
- map->map_mflags |= MF_OPEN;
- syserr("Cannot reopen DB database %s",
- map->map_file);
- }
- return NULL;
- }
- }
-#endif
-
- st = 1;
- if (bitset(MF_TRY0NULL, map->map_mflags))
- {
- st = db->get(db, &key, &val, 0);
- if (st == 0)
- map->map_mflags &= ~MF_TRY1NULL;
- }
- if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
- {
- key.size++;
- st = db->get(db, &key, &val, 0);
- if (st == 0)
- map->map_mflags &= ~MF_TRY0NULL;
- }
- saveerrno = errno;
-#if !OLD_NEWDB
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, buf, ".db", LOCK_UN);
-#endif
- if (st != 0)
- {
- errno = saveerrno;
- if (st < 0)
- syserr("db_map_lookup: get (%s)", name);
- return NULL;
- }
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, name, strlen(name), NULL);
- else
- return map_rewrite(map, val.data, val.size, av);
-}
-
-
-/*
-** DB_MAP_STORE -- store a datum in the NEWDB database
-*/
-
-void
-db_map_store(map, lhs, rhs)
- register MAP *map;
- char *lhs;
- char *rhs;
-{
- int stat;
- DBT key;
- DBT data;
- register DB *db = map->map_db2;
- char keybuf[MAXNAME + 1];
-
- if (tTd(38, 12))
- printf("db_map_store(%s, %s, %s)\n",
- map->map_mname, lhs, rhs);
-
- key.size = strlen(lhs);
- key.data = lhs;
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- {
- if (key.size > sizeof keybuf - 1)
- key.size = sizeof keybuf - 1;
- bcopy(key.data, keybuf, key.size);
- keybuf[key.size] = '\0';
- makelower(keybuf);
- key.data = keybuf;
- }
-
- data.size = strlen(rhs);
- data.data = rhs;
-
- if (bitset(MF_INCLNULL, map->map_mflags))
- {
- key.size++;
- data.size++;
- }
-
- stat = db->put(db, &key, &data, R_NOOVERWRITE);
- if (stat > 0)
- {
- if (!bitset(MF_APPEND, map->map_mflags))
- message("050 Warning: duplicate alias name %s", lhs);
- else
- {
- static char *buf = NULL;
- static int bufsiz = 0;
- DBT old;
-
- old.data = db_map_lookup(map, key.data, NULL, &stat);
- if (old.data != NULL)
- {
- old.size = strlen(old.data);
- if (data.size + old.size + 2 > bufsiz)
- {
- if (buf != NULL)
- (void) free(buf);
- bufsiz = data.size + old.size + 2;
- buf = xalloc(bufsiz);
- }
- snprintf(buf, bufsiz, "%s,%s",
- data.data, old.data);
- data.size = data.size + old.size + 1;
- data.data = buf;
- if (tTd(38, 9))
- printf("db_map_store append=%s\n",
- (char *) data.data);
- }
- }
- stat = db->put(db, &key, &data, 0);
- }
- if (stat != 0)
- syserr("readaliases: db put (%s)", lhs);
-}
-
-
-/*
-** DB_MAP_CLOSE -- add distinguished entries and close the database
-*/
-
-void
-db_map_close(map)
- MAP *map;
-{
- register DB *db = map->map_db2;
-
- if (tTd(38, 9))
- printf("db_map_close(%s, %s, %lx)\n",
- map->map_mname, map->map_file, map->map_mflags);
-
- if (bitset(MF_WRITABLE, map->map_mflags))
- {
- /* write out the distinguished alias */
- db_map_store(map, "@", "@");
- }
-
-#if OLD_NEWDB
- (void) db->sync(db);
-#else
- (void) db->sync(db, 0);
-#endif
-
-#if !LOCK_ON_OPEN
- if (map->map_lockfd >= 0)
- (void) close(map->map_lockfd);
-#endif
-
- if (db->close(db) != 0)
- syserr("readaliases: db close failure");
-}
-
-#endif
- /*
-** NIS Modules
-*/
-
-# ifdef NIS
-
-# ifndef YPERR_BUSY
-# define YPERR_BUSY 16
-# endif
-
-/*
-** NIS_MAP_OPEN -- open DBM map
-*/
-
-bool
-nis_map_open(map, mode)
- MAP *map;
- int mode;
-{
- int yperr;
- register char *p;
- auto char *vp;
- auto int vsize;
-
- if (tTd(38, 2))
- printf("nis_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- /* issue a pseudo-error message */
-#ifdef ENOSYS
- errno = ENOSYS;
-#else
-# ifdef EFTYPE
- errno = EFTYPE;
-# else
- errno = ENXIO;
-# endif
-#endif
- return FALSE;
- }
-
- p = strchr(map->map_file, '@');
- if (p != NULL)
- {
- *p++ = '\0';
- if (*p != '\0')
- map->map_domain = p;
- }
-
- if (*map->map_file == '\0')
- map->map_file = "mail.aliases";
-
- if (map->map_domain == NULL)
- {
- yperr = yp_get_default_domain(&map->map_domain);
- if (yperr != 0)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 NIS map %s specified, but NIS not running",
- map->map_file);
- return FALSE;
- }
- }
-
- /* check to see if this map actually exists */
- yperr = yp_match(map->map_domain, map->map_file, "@", 1,
- &vp, &vsize);
- if (tTd(38, 10))
- printf("nis_map_open: yp_match(@, %s, %s) => %s\n",
- map->map_domain, map->map_file, yperr_string(yperr));
- if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
- {
- /*
- ** We ought to be calling aliaswait() here if this is an
- ** alias file, but powerful HP-UX NIS servers apparently
- ** don't insert the @:@ token into the alias map when it
- ** is rebuilt, so aliaswait() just hangs. I hate HP-UX.
- */
-
-#if 0
- if (!bitset(MF_ALIAS, map->map_mflags) ||
- aliaswait(map, NULL, TRUE))
-#endif
- return TRUE;
- }
-
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- syserr("421 Cannot bind to map %s in domain %s: %s",
- map->map_file, map->map_domain, yperr_string(yperr));
- }
-
- return FALSE;
-}
-
-
-/*
-** NIS_MAP_LOOKUP -- look up a datum in a NIS map
-*/
-
-char *
-nis_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- char *vp;
- auto int vsize;
- int buflen;
- int yperr;
- char keybuf[MAXNAME + 1];
-
- if (tTd(38, 20))
- printf("nis_map_lookup(%s, %s)\n",
- map->map_mname, name);
-
- buflen = strlen(name);
- if (buflen > sizeof keybuf - 1)
- buflen = sizeof keybuf - 1;
- bcopy(name, keybuf, buflen);
- keybuf[buflen] = '\0';
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- makelower(keybuf);
- yperr = YPERR_KEY;
- if (bitset(MF_TRY0NULL, map->map_mflags))
- {
- yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
- &vp, &vsize);
- if (yperr == 0)
- map->map_mflags &= ~MF_TRY1NULL;
- }
- if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
- {
- buflen++;
- yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
- &vp, &vsize);
- if (yperr == 0)
- map->map_mflags &= ~MF_TRY0NULL;
- }
- if (yperr != 0)
- {
- if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
- map->map_mflags &= ~(MF_VALID|MF_OPEN);
- return NULL;
- }
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, name, strlen(name), NULL);
- else
- return map_rewrite(map, vp, vsize, av);
-}
-
-
-/*
-** NIS_GETCANONNAME -- look up canonical name in NIS
-*/
-
-bool
-nis_getcanonname(name, hbsize, statp)
- char *name;
- int hbsize;
- int *statp;
-{
- char *vp;
- auto int vsize;
- int keylen;
- int yperr;
- static bool try0null = TRUE;
- static bool try1null = TRUE;
- static char *yp_domain = NULL;
- char host_record[MAXLINE];
- char cbuf[MAXNAME];
- char nbuf[MAXNAME + 1];
-
- if (tTd(38, 20))
- printf("nis_getcanonname(%s)\n", name);
-
- if (strlen(name) >= sizeof nbuf)
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- (void) strcpy(nbuf, name);
- shorten_hostname(nbuf);
- keylen = strlen(nbuf);
-
- if (yp_domain == NULL)
- yp_get_default_domain(&yp_domain);
- makelower(nbuf);
- yperr = YPERR_KEY;
- if (try0null)
- {
- yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
- &vp, &vsize);
- if (yperr == 0)
- try1null = FALSE;
- }
- if (yperr == YPERR_KEY && try1null)
- {
- keylen++;
- yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
- &vp, &vsize);
- if (yperr == 0)
- try0null = FALSE;
- }
- if (yperr != 0)
- {
- if (yperr == YPERR_KEY)
- *statp = EX_NOHOST;
- else if (yperr == YPERR_BUSY)
- *statp = EX_TEMPFAIL;
- else
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- if (vsize >= sizeof host_record)
- vsize = sizeof host_record - 1;
- strncpy(host_record, vp, vsize);
- host_record[vsize] = '\0';
- if (tTd(38, 44))
- printf("got record `%s'\n", host_record);
- if (!extract_canonname(nbuf, host_record, cbuf, sizeof cbuf))
- {
- /* this should not happen, but.... */
- *statp = EX_NOHOST;
- return FALSE;
- }
- if (hbsize < strlen(cbuf))
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- strcpy(name, cbuf);
- *statp = EX_OK;
- return TRUE;
-}
-
-#endif
- /*
-** NISPLUS Modules
-**
-** This code donated by Sun Microsystems.
-*/
-
-#ifdef NISPLUS
-
-#undef NIS /* symbol conflict in nis.h */
-#undef T_UNSPEC /* symbol conflict in nis.h -> ... -> sys/tiuser.h */
-#include <rpcsvc/nis.h>
-#include <rpcsvc/nislib.h>
-
-#define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
-#define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
-#define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len)
-#define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.')
-
-/*
-** NISPLUS_MAP_OPEN -- open nisplus table
-*/
-
-bool
-nisplus_map_open(map, mode)
- MAP *map;
- int mode;
-{
- nis_result *res = NULL;
- int retry_cnt, max_col, i;
- char qbuf[MAXLINE + NIS_MAXNAMELEN];
-
- if (tTd(38, 2))
- printf("nisplus_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- errno = ENODEV;
- return FALSE;
- }
-
- if (*map->map_file == '\0')
- map->map_file = "mail_aliases.org_dir";
-
- if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL)
- {
- /* set default NISPLUS Domain to $m */
- extern char *nisplus_default_domain();
-
- map->map_domain = newstr(nisplus_default_domain());
- if (tTd(38, 2))
- printf("nisplus_map_open(%s): using domain %s\n",
- map->map_file, map->map_domain);
- }
- if (!PARTIAL_NAME(map->map_file))
- {
- map->map_domain = newstr("");
- snprintf(qbuf, sizeof qbuf, "%s", map->map_file);
- }
- else
- {
- /* check to see if this map actually exists */
- snprintf(qbuf, sizeof qbuf, "%s.%s",
- map->map_file, map->map_domain);
- }
-
- retry_cnt = 0;
- while (res == NULL || res->status != NIS_SUCCESS)
- {
- res = nis_lookup(qbuf, FOLLOW_LINKS);
- switch (res->status)
- {
- case NIS_SUCCESS:
- break;
-
- case NIS_TRYAGAIN:
- case NIS_RPCERROR:
- case NIS_NAMEUNREACHABLE:
- if (retry_cnt++ > 4)
- {
- errno = EBADR;
- return FALSE;
- }
- /* try not to overwhelm hosed server */
- sleep(2);
- break;
-
- default: /* all other nisplus errors */
-#if 0
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 Cannot find table %s.%s: %s",
- map->map_file, map->map_domain,
- nis_sperrno(res->status));
-#endif
- errno = EBADR;
- return FALSE;
- }
- }
-
- if (NIS_RES_NUMOBJ(res) != 1 ||
- (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ))
- {
- if (tTd(38, 10))
- printf("nisplus_map_open: %s is not a table\n", qbuf);
-#if 0
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 %s.%s: %s is not a table",
- map->map_file, map->map_domain,
- nis_sperrno(res->status));
-#endif
- errno = EBADR;
- return FALSE;
- }
- /* default key column is column 0 */
- if (map->map_keycolnm == NULL)
- map->map_keycolnm = newstr(COL_NAME(res,0));
-
- max_col = COL_MAX(res);
-
- /* verify the key column exist */
- for (i=0; i< max_col; i++)
- {
- if (!strcmp(map->map_keycolnm, COL_NAME(res,i)))
- break;
- }
- if (i == max_col)
- {
- if (tTd(38, 2))
- printf("nisplus_map_open(%s): can not find key column %s\n",
- map->map_file, map->map_keycolnm);
- errno = EBADR;
- return FALSE;
- }
-
- /* default value column is the last column */
- if (map->map_valcolnm == NULL)
- {
- map->map_valcolno = max_col - 1;
- return TRUE;
- }
-
- for (i=0; i< max_col; i++)
- {
- if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0)
- {
- map->map_valcolno = i;
- return TRUE;
- }
- }
-
- if (tTd(38, 2))
- printf("nisplus_map_open(%s): can not find column %s\n",
- map->map_file, map->map_keycolnm);
- errno = EBADR;
- return FALSE;
-}
-
-
-/*
-** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table
-*/
-
-char *
-nisplus_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- char *p;
- auto int vsize;
- char *skp;
- int skleft;
- char search_key[MAXNAME + 4];
- char qbuf[MAXLINE + NIS_MAXNAMELEN];
- nis_result *result;
-
- if (tTd(38, 20))
- printf("nisplus_map_lookup(%s, %s)\n",
- map->map_mname, name);
-
- if (!bitset(MF_OPEN, map->map_mflags))
- {
- if (nisplus_map_open(map, O_RDONLY))
- map->map_mflags |= MF_OPEN;
- else
- {
- *statp = EX_UNAVAILABLE;
- return NULL;
- }
- }
-
- /*
- ** Copy the name to the key buffer, escaping double quote characters
- ** by doubling them and quoting "]" and "," to avoid having the
- ** NIS+ parser choke on them.
- */
-
- skleft = sizeof search_key - 4;
- skp = search_key;
- for (p = name; *p != '\0' && skleft > 0; p++)
- {
- switch (*p)
- {
- case ']':
- case ',':
- /* quote the character */
- *skp++ = '"';
- *skp++ = *p;
- *skp++ = '"';
- skleft -= 3;
- break;
-
- case '"':
- /* double the quote */
- *skp++ = '"';
- skleft--;
- /* fall through... */
-
- default:
- *skp++ = *p;
- skleft--;
- break;
- }
- }
- *skp = '\0';
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- makelower(search_key);
-
- /* construct the query */
- if (PARTIAL_NAME(map->map_file))
- snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s",
- map->map_keycolnm, search_key, map->map_file,
- map->map_domain);
- else
- snprintf(qbuf, sizeof qbuf, "[%s=%s],%s",
- map->map_keycolnm, search_key, map->map_file);
-
- if (tTd(38, 20))
- printf("qbuf=%s\n", qbuf);
- result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
- if (result->status == NIS_SUCCESS)
- {
- int count;
- char *str;
-
- if ((count = NIS_RES_NUMOBJ(result)) != 1)
- {
- if (LogLevel > 10)
- sm_syslog(LOG_WARNING, CurEnv->e_id,
- "%s: lookup error, expected 1 entry, got %d",
- map->map_file, count);
-
- /* ignore second entry */
- if (tTd(38, 20))
- printf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n",
- name, count);
- }
-
- p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
- /* set the length of the result */
- if (p == NULL)
- p = "";
- vsize = strlen(p);
- if (tTd(38, 20))
- printf("nisplus_map_lookup(%s), found %s\n",
- name, p);
- if (bitset(MF_MATCHONLY, map->map_mflags))
- str = map_rewrite(map, name, strlen(name), NULL);
- else
- str = map_rewrite(map, p, vsize, av);
- nis_freeresult(result);
- *statp = EX_OK;
- return str;
- }
- else
- {
- if (result->status == NIS_NOTFOUND)
- *statp = EX_NOTFOUND;
- else if (result->status == NIS_TRYAGAIN)
- *statp = EX_TEMPFAIL;
- else
- {
- *statp = EX_UNAVAILABLE;
- map->map_mflags &= ~(MF_VALID|MF_OPEN);
- }
- }
- if (tTd(38, 20))
- printf("nisplus_map_lookup(%s), failed\n", name);
- nis_freeresult(result);
- return NULL;
-}
-
-
-
-/*
-** NISPLUS_GETCANONNAME -- look up canonical name in NIS+
-*/
-
-bool
-nisplus_getcanonname(name, hbsize, statp)
- char *name;
- int hbsize;
- int *statp;
-{
- char *vp;
- auto int vsize;
- nis_result *result;
- char *p;
- char nbuf[MAXNAME + 1];
- char qbuf[MAXLINE + NIS_MAXNAMELEN];
-
- if (strlen(name) >= sizeof nbuf)
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- (void) strcpy(nbuf, name);
- shorten_hostname(nbuf);
-
- p = strchr(nbuf, '.');
- if (p == NULL)
- {
- /* single token */
- snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir", nbuf);
- }
- else if (p[1] != '\0')
- {
- /* multi token -- take only first token in nbuf */
- *p = '\0';
- snprintf(qbuf, sizeof qbuf, "[name=%s],hosts.org_dir.%s",
- nbuf, &p[1]);
- }
- else
- {
- *statp = EX_NOHOST;
- return FALSE;
- }
-
- if (tTd(38, 20))
- printf("\nnisplus_getcanoname(%s), qbuf=%s\n",
- name, qbuf);
-
- result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
- NULL, NULL);
-
- if (result->status == NIS_SUCCESS)
- {
- int count;
- char *domain;
-
- if ((count = NIS_RES_NUMOBJ(result)) != 1)
- {
- if (LogLevel > 10)
- sm_syslog(LOG_WARNING, CurEnv->e_id,
- "nisplus_getcanonname: lookup error, expected 1 entry, got %d",
- count);
-
- /* ignore second entry */
- if (tTd(38, 20))
- printf("nisplus_getcanoname(%s), got %d entries, all but first ignored\n",
- name, count);
- }
-
- if (tTd(38, 20))
- printf("nisplus_getcanoname(%s), found in directory \"%s\"\n",
- name, (NIS_RES_OBJECT(result))->zo_domain);
-
-
- vp = ((NIS_RES_OBJECT(result))->EN_col(0));
- vsize = strlen(vp);
- if (tTd(38, 20))
- printf("nisplus_getcanonname(%s), found %s\n",
- name, vp);
- if (strchr(vp, '.') != NULL)
- {
- domain = "";
- }
- else
- {
- domain = macvalue('m', CurEnv);
- if (domain == NULL)
- domain = "";
- }
- if (hbsize > vsize + (int) strlen(domain) + 1)
- {
- if (domain[0] == '\0')
- strcpy(name, vp);
- else
- snprintf(name, hbsize, "%s.%s", vp, domain);
- *statp = EX_OK;
- }
- else
- *statp = EX_NOHOST;
- nis_freeresult(result);
- return TRUE;
- }
- else
- {
- if (result->status == NIS_NOTFOUND)
- *statp = EX_NOHOST;
- else if (result->status == NIS_TRYAGAIN)
- *statp = EX_TEMPFAIL;
- else
- *statp = EX_UNAVAILABLE;
- }
- if (tTd(38, 20))
- printf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n",
- name, result->status, *statp);
- nis_freeresult(result);
- return FALSE;
-}
-
-
-char *
-nisplus_default_domain()
-{
- static char default_domain[MAXNAME + 1] = "";
- char *p;
-
- if (default_domain[0] != '\0')
- return(default_domain);
-
- p = nis_local_directory();
- snprintf(default_domain, sizeof default_domain, "%s", p);
- return default_domain;
-}
-
-#endif /* NISPLUS */
- /*
-** LDAP Modules
-**
-** Contributed by Booker C. Bense <bbense@networking.stanford.edu>.
-** Get your support from him.
-*/
-
-#ifdef LDAPMAP
-
-# undef NEEDGETOPT /* used for something else in LDAP */
-
-# include <lber.h>
-# include <ldap.h>
-# include "ldap_map.h"
-
-/*
-** LDAP_MAP_OPEN -- open LDAP map
-**
-** Since LDAP is TCP-based there is not much we can or should do
-** here. It might be a good idea to attempt an open/close here.
-*/
-
-bool
-ldap_map_open(map, mode)
- MAP *map;
- int mode;
-{
- if (tTd(38, 2))
- printf("ldap_map_open(%s, %d)\n", map->map_mname, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- /* issue a pseudo-error message */
-#ifdef ENOSYS
- errno = ENOSYS;
-#else
-# ifdef EFTYPE
- errno = EFTYPE;
-# else
- errno = ENXIO;
-# endif
-#endif
- return FALSE;
- }
- return TRUE;
-}
-
-
-/*
-** LDAP_MAP_START -- actually open LDAP map
-**
-** Caching should be investigated.
-*/
-
-bool
-ldap_map_start(map)
- MAP *map;
-{
- LDAP_MAP_STRUCT *lmap;
- LDAP *ld;
-
- if (tTd(38, 2))
- printf("ldap_map_start(%s)\n", map->map_mname);
-
- lmap = (LDAP_MAP_STRUCT *) map->map_db1;
-
- if (tTd(38,9))
- printf("ldap_open(%s, %d)\n", lmap->ldaphost, lmap->ldapport);
-
- if ((ld = ldap_open(lmap->ldaphost,lmap->ldapport)) == NULL)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- syserr("ldapopen failed to %s in map %s",
- lmap->ldaphost, map->map_mname);
- }
- return FALSE;
- }
-
- ld->ld_deref = lmap->deref;
- ld->ld_timelimit = lmap->timelimit;
- ld->ld_sizelimit = lmap->sizelimit;
- ld->ld_options = lmap->ldap_options;
-
- if (ldap_bind_s(ld, lmap->binddn,lmap->passwd,lmap->method) != LDAP_SUCCESS)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- syserr("421 Cannot bind to map %s in ldap server %s",
- map->map_mname, lmap->ldaphost);
- }
- }
- else
- {
- /* We need to cast ld into the map structure */
- lmap->ld = ld;
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/*
-** LDAP_MAP_CLOSE -- close ldap map
-*/
-
-void
-ldap_map_close(map)
- MAP *map;
-{
- LDAP_MAP_STRUCT *lmap ;
- lmap = (LDAP_MAP_STRUCT *) map->map_db1;
- if (lmap->ld != NULL)
- ldap_unbind(lmap->ld);
-}
-
-
-#ifdef SUNET_ID
-/*
-** SUNET_ID_HASH -- Convert a string to it's Sunet_id canonical form
-** This only makes sense at Stanford University.
-*/
-
-char *
-sunet_id_hash(str)
- char *str;
-{
- char *p, *p_last;
-
- p = str;
- p_last = p;
- while (*p != '\0')
- {
- if (islower(*p) || isdigit(*p))
- {
- *p_last = *p;
- p_last++;
- }
- else if (isupper(*p))
- {
- *p_last = tolower(*p);
- p_last++;
- }
- ++p;
- }
- if (*p_last != '\0')
- *p_last = '\0';
- return (str);
-}
-
-
-
-#endif /* SUNET_ID */
-/*
-** LDAP_MAP_LOOKUP -- look up a datum in a LDAP map
-*/
-
-char *
-ldap_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- LDAP_MAP_STRUCT *lmap = NULL;
- LDAPMessage *entry;
- char *vp;
- auto int vsize;
- char keybuf[MAXNAME + 1];
- char filter[LDAP_MAP_MAX_FILTER + 1];
- char **attr_values = NULL;
- char *result;
- int name_len;
-
- if (tTd(38, 20))
- printf("ldap_map_lookup(%s, %s)\n", map->map_mname, name);
-
- /* actually open the map */
- if (!ldap_map_start(map))
- {
- result = NULL;
- *statp = EX_TEMPFAIL;
- goto quick_exit;
- }
-
- /* Get ldap struct pointer from map */
- lmap = (LDAP_MAP_STRUCT *) map->map_db1;
-
- name_len = strlen(name);
- if (name_len > MAXNAME)
- name_len = MAXNAME;
- strncpy(keybuf, name, name_len);
- keybuf[name_len] = '\0';
-
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
-#ifdef SUNET_ID
- sunet_id_hash(keybuf);
-#else
- makelower(keybuf);
-#endif /*SUNET_ID */
-
- /* sprintf keybuf into filter */
- snprintf(filter, sizeof filter, lmap->filter, keybuf);
-
- if (ldap_search_st(lmap->ld, lmap->base,lmap->scope,filter,
- lmap->attr, lmap->attrsonly, &(lmap->timeout),
- &(lmap->res)) != LDAP_SUCCESS)
- {
- /* try close/opening map */
- ldap_map_close(map);
- if (!ldap_map_start(map))
- {
- result = NULL;
- *statp = EX_TEMPFAIL;
- goto quick_exit;
- }
- if (ldap_search_st(lmap->ld, lmap->base, lmap->scope, filter,
- lmap->attr, lmap->attrsonly,
- &(lmap->timeout), &(lmap->res))
- != LDAP_SUCCESS)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- {
- syserr("Error in ldap_search_st using %s in map %s",
- filter, map->map_mname);
- }
- result = NULL;
- *statp = EX_TEMPFAIL;
- goto quick_exit;
- }
- }
-
- entry = ldap_first_entry(lmap->ld,lmap->res);
- if (entry == NULL)
- {
- result = NULL;
- *statp = EX_NOTFOUND;
- goto quick_exit;
- }
-
- /* Need to build the args for map_rewrite here */
- attr_values = ldap_get_values(lmap->ld,entry,lmap->attr[0]);
- if (attr_values == NULL)
- {
- /* bad things happened */
- result = NULL;
- *statp = EX_NOTFOUND;
- goto quick_exit;
- }
-
- *statp = EX_OK;
-
- /* If there is more that one use the first */
- vp = attr_values[0];
- vsize = strlen(vp);
-
- if (LogLevel > 9)
- sm_syslog(LOG_INFO, CurEnv->e_id,
- "ldap %.100s => %s",
- name, vp);
- if (bitset(MF_MATCHONLY, map->map_mflags))
- result = map_rewrite(map, name, strlen(name), NULL);
- else
- result = map_rewrite(map, vp, vsize, av);
-
- quick_exit:
- if (attr_values != NULL)
- ldap_value_free(attr_values);
- if (lmap != NULL)
- ldap_msgfree(lmap->res);
- ldap_map_close(map);
- return result ;
-}
-
-
-/*
-** LDAP_MAP_DEQUOTE - helper routine for ldap_map_parseargs
-*/
-
-char *
-ldap_map_dequote(str)
- char *str;
-{
- char *p;
- char *start;
- p = str;
-
- if (*p == '"')
- {
- start = ++p;
- /* Should probably swallow initial whitespace here */
- }
- else
- {
- return(str);
- }
- while (*p != '"' && *p != '\0')
- {
- p++;
- }
- if (*p != '\0')
- *p = '\0';
- return start;
-}
-
-/*
-** LDAP_MAP_PARSEARGS -- parse ldap map definition args.
-*/
-
-bool
-ldap_map_parseargs(map,args)
- MAP *map;
- char *args;
-{
- register char *p = args;
- register int done;
- LDAP_MAP_STRUCT *lmap;
-
- /* We need to alloc an LDAP_MAP_STRUCT struct */
- lmap = (LDAP_MAP_STRUCT *) xalloc(sizeof(LDAP_MAP_STRUCT));
-
- /* Set default int's here , default strings below */
- lmap->ldapport = DEFAULT_LDAP_MAP_PORT;
- lmap->deref = DEFAULT_LDAP_MAP_DEREF;
- lmap->timelimit = DEFAULT_LDAP_MAP_TIMELIMIT;
- lmap->sizelimit = DEFAULT_LDAP_MAP_SIZELIMIT;
- lmap->ldap_options = DEFAULT_LDAP_MAP_LDAP_OPTIONS;
- lmap->method = DEFAULT_LDAP_MAP_METHOD;
- lmap->scope = DEFAULT_LDAP_MAP_SCOPE;
- lmap->attrsonly = DEFAULT_LDAP_MAP_ATTRSONLY;
- lmap->timeout.tv_sec = DEFAULT_LDAP_MAP_TIMELIMIT;
- lmap->timeout.tv_usec = 0;
-
- /* Default char ptrs to NULL */
- lmap->binddn = NULL;
- lmap->passwd = NULL;
- lmap->base = NULL;
- lmap->ldaphost = NULL;
- map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
- for (;;)
- {
- while (isascii(*p) && isspace(*p))
- p++;
- if (*p != '-')
- break;
- switch (*++p)
- {
- case 'N':
- map->map_mflags |= MF_INCLNULL;
- map->map_mflags &= ~MF_TRY0NULL;
- break;
-
- case 'O':
- map->map_mflags &= ~MF_TRY1NULL;
- break;
-
- case 'o':
- map->map_mflags |= MF_OPTIONAL;
- break;
-
- case 'f':
- map->map_mflags |= MF_NOFOLDCASE;
- break;
-
- case 'm':
- map->map_mflags |= MF_MATCHONLY;
- break;
-
- case 'A':
- map->map_mflags |= MF_APPEND;
- break;
-
- case 'q':
- map->map_mflags |= MF_KEEPQUOTES;
- break;
-
- case 't':
- map->map_mflags |= MF_NODEFER;
- break;
-
- case 'a':
- map->map_app = ++p;
- break;
-
- /* Start of ldap_map specific args */
- case 'k': /* search field */
- while (isascii(*++p) && isspace(*p))
- continue;
- lmap->filter = p;
- break;
-
- case 'v': /* attr to return */
- while (isascii(*++p) && isspace(*p))
- continue;
- lmap->attr[0] = p;
- lmap->attr[1] = NULL;
- break;
-
- /* args stolen from ldapsearch.c */
- case 'R': /* don't auto chase referrals */
-#ifdef LDAP_REFERRALS
- lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
-#else /* LDAP_REFERRALS */
- syserr("compile with -DLDAP_REFERRALS for referral support\n");
-#endif /* LDAP_REFERRALS */
- break;
-
- case 'n': /* retrieve attribute names only -- no values */
- lmap->attrsonly += 1;
- break;
-
- case 's': /* search scope */
- if (strncasecmp(p, "base", 4) == 0)
- {
- lmap->scope = LDAP_SCOPE_BASE;
- }
- else if (strncasecmp(p, "one", 3) == 0)
- {
- lmap->scope = LDAP_SCOPE_ONELEVEL;
- }
- else if (strncasecmp(p, "sub", 3) == 0)
- {
- lmap->scope = LDAP_SCOPE_SUBTREE;
- }
- else
- { /* bad config line */
- if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
- {
- syserr("Scope must be [base|one|sub] not %s in map %s",
- p, map->map_mname);
- return FALSE;
- }
- }
- break;
-
- case 'h': /* ldap host */
- while (isascii(*++p) && isspace(*p))
- continue;
- map->map_domain = p;
- lmap->ldaphost = p;
- break;
-
- case 'b': /* search base */
- while (isascii(*++p) && isspace(*p))
- continue;
- lmap->base = p;
- break;
-
- case 'p': /* ldap port */
- while (isascii(*++p) && isspace(*p))
- continue;
- lmap->ldapport = atoi(p);
- break;
-
- case 'l': /* time limit */
- while (isascii(*++p) && isspace(*p))
- continue;
- lmap->timelimit = atoi(p);
- break;
-
- }
-
- /* need to account for quoted strings here arggg... */
- done = isascii(*p) && isspace(*p);
- while (*p != '\0' && !done)
- {
- if (*p == '"')
- {
- while (*++p != '"' && *p != '\0')
- {
- continue;
- }
- if (*p != '\0')
- p++;
- }
- else
- {
- p++;
- }
- done = isascii(*p) && isspace(*p);
- }
-
- if (*p != '\0')
- *p++ = '\0';
- }
-
- if (map->map_app != NULL)
- map->map_app = newstr(ldap_map_dequote(map->map_app));
-
- if (map->map_domain != NULL)
- map->map_domain = newstr(ldap_map_dequote(map->map_domain));
-
- /*
- ** We need to swallow up all the stuff into a struct
- ** and dump it into map->map_dbptr1
- */
-
- if (lmap->ldaphost != NULL)
- lmap->ldaphost = newstr(ldap_map_dequote(lmap->ldaphost));
- else
- {
- syserr("LDAP map: -h flag is required");
- return FALSE;
- }
-
- if (lmap->binddn != NULL)
- lmap->binddn = newstr(ldap_map_dequote(lmap->binddn));
- else
- lmap->binddn = DEFAULT_LDAP_MAP_BINDDN;
-
-
- if (lmap->passwd != NULL)
- lmap->passwd = newstr(ldap_map_dequote(lmap->passwd));
- else
- lmap->passwd = DEFAULT_LDAP_MAP_PASSWD;
-
- if (lmap->base != NULL)
- lmap->base = newstr(ldap_map_dequote(lmap->base));
- else
- {
- syserr("LDAP map: -b flag is required");
- return FALSE;
- }
-
-
- if (lmap->filter != NULL)
- lmap->filter = newstr(ldap_map_dequote(lmap->filter));
- else
- {
- if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
- {
- syserr("No filter given in map %s", map->map_mname);
- return FALSE;
- }
- }
- if (lmap->attr[0] != NULL)
- lmap->attr[0] = newstr(ldap_map_dequote(lmap->attr[0]));
- else
- {
- if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
- {
- syserr("No return attribute in %s", map->map_mname);
- return FALSE;
- }
- }
-
- map->map_db1 = (ARBPTR_T) lmap;
- return TRUE;
-}
-
-#endif /* LDAP Modules */
- /*
-** syslog map
-*/
-
-#if _FFR_SYSLOG_MAP
-
-#define map_prio map_lockfd /* overload field */
-
-/*
-** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages.
-*/
-
-bool
-syslog_map_parseargs(map, args)
- MAP *map;
- char *args;
-{
- char *p = args;
- char *priority = NULL;
-
- for (;;)
- {
- while (isascii(*p) && isspace(*p))
- p++;
- if (*p != '-')
- break;
- if (*++p == 'L')
- priority = ++p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p != '\0')
- *p++ = '\0';
- }
-
- if (priority == NULL)
- map->map_prio = LOG_INFO;
- else
- {
- if (strncasecmp("LOG_", priority, 4) == 0)
- priority += 4;
-
-#ifdef LOG_EMERG
- if (strcasecmp("EMERG", priority) == 0)
- map->map_prio = LOG_EMERG;
- else
-#endif
-#ifdef LOG_ALERT
- if (strcasecmp("ALERT", priority) == 0)
- map->map_prio = LOG_ALERT;
- else
-#endif
-#ifdef LOG_CRIT
- if (strcasecmp("CRIT", priority) == 0)
- map->map_prio = LOG_CRIT;
- else
-#endif
-#ifdef LOG_ERR
- if (strcasecmp("ERR", priority) == 0)
- map->map_prio = LOG_ERR;
- else
-#endif
-#ifdef LOG_WARNING
- if (strcasecmp("WARNING", priority) == 0)
- map->map_prio = LOG_WARNING;
- else
-#endif
-#ifdef LOG_NOTICE
- if (strcasecmp("NOTICE", priority) == 0)
- map->map_prio = LOG_NOTICE;
- else
-#endif
-#ifdef LOG_INFO
- if (strcasecmp("INFO", priority) == 0)
- map->map_prio = LOG_INFO;
- else
-#endif
-#ifdef LOG_DEBUG
- if (strcasecmp("DEBUG", priority) == 0)
- map->map_prio = LOG_DEBUG;
- else
-#endif
- {
- syserr("syslog_map_parseargs: Unknown priority %s\n",
- priority);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/*
-** SYSLOG_MAP_LOOKUP -- rewrite and syslog message. Always return empty string
-*/
-
-char *
-syslog_map_lookup(map, string, args, statp)
- MAP *map;
- char *string;
- char **args;
- int *statp;
-{
- char *ptr = map_rewrite(map, string, strlen(string), args);
-
- if (ptr != NULL)
- {
- if (tTd(38, 20))
- printf("syslog_map_lookup(%s (priority %d): %s\n",
- map->map_mname, map->map_prio, ptr);
-
- sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr);
- }
-
- *statp = EX_OK;
- return "";
-}
-
-#endif /* _FFR_SYSLOG_MAP */
- /*
-** HESIOD Modules
-*/
-
-#ifdef HESIOD
-
-#include <hesiod.h>
-
-bool
-hes_map_open(map, mode)
- MAP *map;
- int mode;
-{
- if (tTd(38, 2))
- printf("hes_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- if (mode != O_RDONLY)
- {
- /* issue a pseudo-error message */
-#ifdef ENOSYS
- errno = ENOSYS;
-#else
-# ifdef EFTYPE
- errno = EFTYPE;
-# else
- errno = ENXIO;
-# endif
-#endif
- return FALSE;
- }
-
- if (hes_error() == HES_ER_UNINIT)
- hes_init();
- switch (hes_error())
- {
- case HES_ER_OK:
- case HES_ER_NOTFOUND:
- return TRUE;
- }
-
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 cannot initialize Hesiod map (%d)", hes_error());
-
- return FALSE;
-}
-
-char *
-hes_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- char **hp;
-
- if (tTd(38, 20))
- printf("hes_map_lookup(%s, %s)\n", map->map_file, name);
-
- if (name[0] == '\\')
- {
- char *np;
- int nl;
- char nbuf[MAXNAME];
-
- nl = strlen(name);
- if (nl < sizeof nbuf - 1)
- np = nbuf;
- else
- np = xalloc(strlen(name) + 2);
- np[0] = '\\';
- strcpy(&np[1], name);
- hp = hes_resolve(np, map->map_file);
- if (np != nbuf)
- free(np);
- }
- else
- {
- hp = hes_resolve(name, map->map_file);
- }
- if (hp == NULL || hp[0] == NULL)
- {
- switch (hes_error())
- {
- case HES_ER_OK:
- *statp = EX_OK;
- break;
-
- case HES_ER_NOTFOUND:
- *statp = EX_NOTFOUND;
- break;
-
- case HES_ER_CONFIG:
- *statp = EX_UNAVAILABLE;
- break;
-
- case HES_ER_NET:
- *statp = EX_TEMPFAIL;
- break;
- }
- return NULL;
- }
-
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, name, strlen(name), NULL);
- else
- return map_rewrite(map, hp[0], strlen(hp[0]), av);
-}
-
-#endif
- /*
-** NeXT NETINFO Modules
-*/
-
-#if NETINFO
-
-# define NETINFO_DEFAULT_DIR "/aliases"
-# define NETINFO_DEFAULT_PROPERTY "members"
-
-extern char *ni_propval __P((char *, char *, char *, char *, int));
-
-
-/*
-** NI_MAP_OPEN -- open NetInfo Aliases
-*/
-
-bool
-ni_map_open(map, mode)
- MAP *map;
- int mode;
-{
- char *p;
-
- if (tTd(38, 2))
- printf("ni_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
- mode &= O_ACCMODE;
-
- if (*map->map_file == '\0')
- map->map_file = NETINFO_DEFAULT_DIR;
-
- if (map->map_valcolnm == NULL)
- map->map_valcolnm = NETINFO_DEFAULT_PROPERTY;
-
- if (map->map_coldelim == '\0' && bitset(MF_ALIAS, map->map_mflags))
- map->map_coldelim = ',';
-
- return TRUE;
-}
-
-
-/*
-** NI_MAP_LOOKUP -- look up a datum in NetInfo
-*/
-
-char *
-ni_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- char *res;
- char *propval;
-
- if (tTd(38, 20))
- printf("ni_map_lookup(%s, %s)\n", map->map_mname, name);
-
- propval = ni_propval(map->map_file, map->map_keycolnm, name,
- map->map_valcolnm, map->map_coldelim);
-
- if (propval == NULL)
- return NULL;
-
- if (bitset(MF_MATCHONLY, map->map_mflags))
- res = map_rewrite(map, name, strlen(name), NULL);
- else
- res = map_rewrite(map, propval, strlen(propval), av);
- free(propval);
- return res;
-}
-
-
-bool
-ni_getcanonname(name, hbsize, statp)
- char *name;
- int hbsize;
- int *statp;
-{
- char *vptr;
- char nbuf[MAXNAME + 1];
-
- if (tTd(38, 20))
- printf("ni_getcanonname(%s)\n", name);
-
- if (strlen(name) >= sizeof nbuf)
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- (void) strcpy(nbuf, name);
- shorten_hostname(nbuf);
-
- /* we only accept single token search key */
- if (strchr(nbuf, '.'))
- {
- *statp = EX_NOHOST;
- return FALSE;
- }
-
- /* Do the search */
- vptr = ni_propval("/machines", NULL, nbuf, "name", '\0');
-
- if (vptr == NULL)
- {
- *statp = EX_NOHOST;
- return FALSE;
- }
-
- if (hbsize >= strlen(vptr))
- {
- strcpy(name, vptr);
- *statp = EX_OK;
- return TRUE;
- }
- *statp = EX_UNAVAILABLE;
- free(vptr);
- return FALSE;
-}
-
-
-/*
-** NI_PROPVAL -- NetInfo property value lookup routine
-**
-** Parameters:
-** keydir -- the NetInfo directory name in which to search
-** for the key.
-** keyprop -- the name of the property in which to find the
-** property we are interested. Defaults to "name".
-** keyval -- the value for which we are really searching.
-** valprop -- the property name for the value in which we
-** are interested.
-** sepchar -- if non-nil, this can be multiple-valued, and
-** we should return a string separated by this
-** character.
-**
-** Returns:
-** NULL -- if:
-** 1. the directory is not found
-** 2. the property name is not found
-** 3. the property contains multiple values
-** 4. some error occured
-** else -- the value of the lookup.
-**
-** Example:
-** To search for an alias value, use:
-** ni_propval("/aliases", "name", aliasname, "members", ',')
-**
-** Notes:
-** Caller should free the return value of ni_proval
-*/
-
-# include <netinfo/ni.h>
-
-# define LOCAL_NETINFO_DOMAIN "."
-# define PARENT_NETINFO_DOMAIN ".."
-# define MAX_NI_LEVELS 256
-
-char *
-ni_propval(keydir, keyprop, keyval, valprop, sepchar)
- char *keydir;
- char *keyprop;
- char *keyval;
- char *valprop;
- int sepchar;
-{
- char *propval = NULL;
- int i;
- int j, alen;
- void *ni = NULL;
- void *lastni = NULL;
- ni_status nis;
- ni_id nid;
- ni_namelist ninl;
- register char *p;
- char keybuf[1024];
-
- /*
- ** Create the full key from the two parts.
- **
- ** Note that directory can end with, e.g., "name=" to specify
- ** an alternate search property.
- */
-
- i = strlen(keydir) + strlen(keyval) + 2;
- if (keyprop != NULL)
- i += strlen(keyprop) + 1;
- if (i > sizeof keybuf)
- return NULL;
- strcpy(keybuf, keydir);
- strcat(keybuf, "/");
- if (keyprop != NULL)
- {
- strcat(keybuf, keyprop);
- strcat(keybuf, "=");
- }
- strcat(keybuf, keyval);
-
- if (tTd(38, 21))
- printf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
- keydir, keyprop, keyval, valprop, sepchar, keybuf);
- /*
- ** If the passed directory and property name are found
- ** in one of netinfo domains we need to search (starting
- ** from the local domain moving all the way back to the
- ** root domain) set propval to the property's value
- ** and return it.
- */
-
- for (i = 0; i < MAX_NI_LEVELS && propval == NULL; i++)
- {
- if (i == 0)
- {
- nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
- if (tTd(38, 20))
- printf("ni_open(LOCAL) = %d\n", nis);
- }
- else
- {
- if (lastni != NULL)
- ni_free(lastni);
- lastni = ni;
- nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
- if (tTd(38, 20))
- printf("ni_open(PARENT) = %d\n", nis);
- }
-
- /*
- ** Don't bother if we didn't get a handle on a
- ** proper domain. This is not necessarily an error.
- ** We would get a positive ni_status if, for instance
- ** we never found the directory or property and tried
- ** to open the parent of the root domain!
- */
-
- if (nis != 0)
- break;
-
- /*
- ** Find the path to the server information.
- */
-
- if (ni_pathsearch(ni, &nid, keybuf) != 0)
- continue;
-
- /*
- ** Find associated value information.
- */
-
- if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0)
- continue;
-
- if (tTd(38, 20))
- printf("ni_lookupprop: len=%d\n", ninl.ni_namelist_len);
- /*
- ** See if we have an acceptable number of values.
- */
-
- if (ninl.ni_namelist_len <= 0)
- continue;
-
- if (sepchar == '\0' && ninl.ni_namelist_len > 1)
- {
- ni_namelist_free(&ninl);
- continue;
- }
-
- /*
- ** Calculate number of bytes needed and build result
- */
-
- alen = 1;
- for (j = 0; j < ninl.ni_namelist_len; j++)
- alen += strlen(ninl.ni_namelist_val[j]) + 1;
- propval = p = xalloc(alen);
- for (j = 0; j < ninl.ni_namelist_len; j++)
- {
- strcpy(p, ninl.ni_namelist_val[j]);
- p += strlen(p);
- *p++ = sepchar;
- }
- *--p = '\0';
-
- ni_namelist_free(&ninl);
- }
-
- /*
- ** Clean up.
- */
-
- if (ni != NULL)
- ni_free(ni);
- if (lastni != NULL && ni != lastni)
- ni_free(lastni);
- if (tTd(38, 20))
- printf("ni_propval returns: '%s'\n", propval);
-
- return propval;
-}
-
-#endif
- /*
-** TEXT (unindexed text file) Modules
-**
-** This code donated by Sun Microsystems.
-*/
-
-#define map_sff map_lockfd /* overload field */
-
-
-/*
-** TEXT_MAP_OPEN -- open text table
-*/
-
-bool
-text_map_open(map, mode)
- MAP *map;
- int mode;
-{
- int sff;
- int i;
-
- if (tTd(38, 2))
- printf("text_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- errno = ENODEV;
- return FALSE;
- }
-
- if (*map->map_file == '\0')
- {
- syserr("text map \"%s\": file name required",
- map->map_mname);
- return FALSE;
- }
-
- if (map->map_file[0] != '/')
- {
- syserr("text map \"%s\": file name must be fully qualified",
- map->map_mname);
- return FALSE;
- }
-
- sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOWLINK;
- if (FatalWritableDirs)
- sff |= SFF_SAFEDIRPATH;
- if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName,
- sff, S_IRUSR, NULL)) != 0)
- {
- /* cannot open this map */
- if (tTd(38, 2))
- printf("\tunsafe map file: %d\n", i);
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("text map \"%s\": unsafe map file %s",
- map->map_mname, map->map_file);
- return FALSE;
- }
-
- if (map->map_keycolnm == NULL)
- map->map_keycolno = 0;
- else
- {
- if (!isdigit(*map->map_keycolnm))
- {
- syserr("text map \"%s\", file %s: -k should specify a number, not %s",
- map->map_mname, map->map_file,
- map->map_keycolnm);
- return FALSE;
- }
- map->map_keycolno = atoi(map->map_keycolnm);
- }
-
- if (map->map_valcolnm == NULL)
- map->map_valcolno = 0;
- else
- {
- if (!isdigit(*map->map_valcolnm))
- {
- syserr("text map \"%s\", file %s: -v should specify a number, not %s",
- map->map_mname, map->map_file,
- map->map_valcolnm);
- return FALSE;
- }
- map->map_valcolno = atoi(map->map_valcolnm);
- }
-
- if (tTd(38, 2))
- {
- printf("text_map_open(%s, %s): delimiter = ",
- map->map_mname, map->map_file);
- if (map->map_coldelim == '\0')
- printf("(white space)\n");
- else
- printf("%c\n", map->map_coldelim);
- }
-
- map->map_sff = sff;
- return TRUE;
-}
-
-
-/*
-** TEXT_MAP_LOOKUP -- look up a datum in a TEXT table
-*/
-
-char *
-text_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- char *vp;
- auto int vsize;
- int buflen;
- FILE *f;
- char delim;
- int key_idx;
- bool found_it;
- int sff = map->map_sff;
- char search_key[MAXNAME + 1];
- char linebuf[MAXLINE];
- char buf[MAXNAME + 1];
- extern char *get_column __P((char *, int, char, char *, int));
-
- found_it = FALSE;
- if (tTd(38, 20))
- printf("text_map_lookup(%s, %s)\n", map->map_mname, name);
-
- buflen = strlen(name);
- if (buflen > sizeof search_key - 1)
- buflen = sizeof search_key - 1;
- bcopy(name, search_key, buflen);
- search_key[buflen] = '\0';
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
- makelower(search_key);
-
- f = safefopen(map->map_file, O_RDONLY, FileMode, sff);
- if (f == NULL)
- {
- map->map_mflags &= ~(MF_VALID|MF_OPEN);
- *statp = EX_UNAVAILABLE;
- return NULL;
- }
- key_idx = map->map_keycolno;
- delim = map->map_coldelim;
- while (fgets(linebuf, MAXLINE, f) != NULL)
- {
- char *p;
-
- /* skip comment line */
- if (linebuf[0] == '#')
- continue;
- p = strchr(linebuf, '\n');
- if (p != NULL)
- *p = '\0';
- p = get_column(linebuf, key_idx, delim, buf, sizeof buf);
- if (p != NULL && strcasecmp(search_key, p) == 0)
- {
- found_it = TRUE;
- break;
- }
- }
- fclose(f);
- if (!found_it)
- {
- *statp = EX_NOTFOUND;
- return NULL;
- }
- vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof buf);
- vsize = strlen(vp);
- *statp = EX_OK;
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, name, strlen(name), NULL);
- else
- return map_rewrite(map, vp, vsize, av);
-}
-
-
-/*
-** TEXT_GETCANONNAME -- look up canonical name in hosts file
-*/
-
-bool
-text_getcanonname(name, hbsize, statp)
- char *name;
- int hbsize;
- int *statp;
-{
- bool found;
- FILE *f;
- char linebuf[MAXLINE];
- char cbuf[MAXNAME + 1];
- char nbuf[MAXNAME + 1];
-
- if (tTd(38, 20))
- printf("text_getcanonname(%s)\n", name);
-
- if (strlen(name) >= (SIZE_T) sizeof nbuf)
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- (void) strcpy(nbuf, name);
- shorten_hostname(nbuf);
-
- f = fopen(HostsFile, "r");
- if (f == NULL)
- {
- *statp = EX_UNAVAILABLE;
- return FALSE;
- }
- found = FALSE;
- while (!found && fgets(linebuf, MAXLINE, f) != NULL)
- {
- char *p = strpbrk(linebuf, "#\n");
-
- if (p != NULL)
- *p = '\0';
- if (linebuf[0] != '\0')
- found = extract_canonname(nbuf, linebuf, cbuf, sizeof cbuf);
- }
- fclose(f);
- if (!found)
- {
- *statp = EX_NOHOST;
- return FALSE;
- }
-
- if ((SIZE_T) hbsize >= strlen(cbuf))
- {
- strcpy(name, cbuf);
- *statp = EX_OK;
- return TRUE;
- }
- *statp = EX_UNAVAILABLE;
- return FALSE;
-}
- /*
-** STAB (Symbol Table) Modules
-*/
-
-
-/*
-** STAB_MAP_LOOKUP -- look up alias in symbol table
-*/
-
-char *
-stab_map_lookup(map, name, av, pstat)
- register MAP *map;
- char *name;
- char **av;
- int *pstat;
-{
- register STAB *s;
-
- if (tTd(38, 20))
- printf("stab_lookup(%s, %s)\n",
- map->map_mname, name);
-
- s = stab(name, ST_ALIAS, ST_FIND);
- if (s != NULL)
- return (s->s_alias);
- return (NULL);
-}
-
-
-/*
-** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild)
-*/
-
-void
-stab_map_store(map, lhs, rhs)
- register MAP *map;
- char *lhs;
- char *rhs;
-{
- register STAB *s;
-
- s = stab(lhs, ST_ALIAS, ST_ENTER);
- s->s_alias = newstr(rhs);
-}
-
-
-/*
-** STAB_MAP_OPEN -- initialize (reads data file)
-**
-** This is a wierd case -- it is only intended as a fallback for
-** aliases. For this reason, opens for write (only during a
-** "newaliases") always fails, and opens for read open the
-** actual underlying text file instead of the database.
-*/
-
-bool
-stab_map_open(map, mode)
- register MAP *map;
- int mode;
-{
- FILE *af;
- int sff;
- struct stat st;
-
- if (tTd(38, 2))
- printf("stab_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- errno = ENODEV;
- return FALSE;
- }
-
- sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOWLINK;
- if (FatalWritableDirs)
- sff |= SFF_SAFEDIRPATH;
- af = safefopen(map->map_file, O_RDONLY, 0444, sff);
- if (af == NULL)
- return FALSE;
- readaliases(map, af, FALSE, FALSE);
-
- if (fstat(fileno(af), &st) >= 0)
- map->map_mtime = st.st_mtime;
- fclose(af);
-
- return TRUE;
-}
- /*
-** Implicit Modules
-**
-** Tries several types. For back compatibility of aliases.
-*/
-
-
-/*
-** IMPL_MAP_LOOKUP -- lookup in best open database
-*/
-
-char *
-impl_map_lookup(map, name, av, pstat)
- MAP *map;
- char *name;
- char **av;
- int *pstat;
-{
- if (tTd(38, 20))
- printf("impl_map_lookup(%s, %s)\n",
- map->map_mname, name);
-
-#ifdef NEWDB
- if (bitset(MF_IMPL_HASH, map->map_mflags))
- return db_map_lookup(map, name, av, pstat);
-#endif
-#ifdef NDBM
- if (bitset(MF_IMPL_NDBM, map->map_mflags))
- return ndbm_map_lookup(map, name, av, pstat);
-#endif
- return stab_map_lookup(map, name, av, pstat);
-}
-
-/*
-** IMPL_MAP_STORE -- store in open databases
-*/
-
-void
-impl_map_store(map, lhs, rhs)
- MAP *map;
- char *lhs;
- char *rhs;
-{
- if (tTd(38, 12))
- printf("impl_map_store(%s, %s, %s)\n",
- map->map_mname, lhs, rhs);
-#ifdef NEWDB
- if (bitset(MF_IMPL_HASH, map->map_mflags))
- db_map_store(map, lhs, rhs);
-#endif
-#ifdef NDBM
- if (bitset(MF_IMPL_NDBM, map->map_mflags))
- ndbm_map_store(map, lhs, rhs);
-#endif
- stab_map_store(map, lhs, rhs);
-}
-
-/*
-** IMPL_MAP_OPEN -- implicit database open
-*/
-
-bool
-impl_map_open(map, mode)
- MAP *map;
- int mode;
-{
- if (tTd(38, 2))
- printf("impl_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
-#ifdef NEWDB
- map->map_mflags |= MF_IMPL_HASH;
- if (hash_map_open(map, mode))
- {
-# ifdef NDBM_YP_COMPAT
- if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL)
-# endif
- return TRUE;
- }
- else
- map->map_mflags &= ~MF_IMPL_HASH;
-#endif
-#ifdef NDBM
- map->map_mflags |= MF_IMPL_NDBM;
- if (ndbm_map_open(map, mode))
- {
- return TRUE;
- }
- else
- map->map_mflags &= ~MF_IMPL_NDBM;
-#endif
-
-#if defined(NEWDB) || defined(NDBM)
- if (Verbose)
- message("WARNING: cannot open alias database %s", map->map_file);
-#else
- if (mode != O_RDONLY)
- usrerr("Cannot rebuild aliases: no database format defined");
-#endif
-
- return stab_map_open(map, mode);
-}
-
-
-/*
-** IMPL_MAP_CLOSE -- close any open database(s)
-*/
-
-void
-impl_map_close(map)
- MAP *map;
-{
- if (tTd(38, 9))
- printf("impl_map_close(%s, %s, %lx)\n",
- map->map_mname, map->map_file, map->map_mflags);
-#ifdef NEWDB
- if (bitset(MF_IMPL_HASH, map->map_mflags))
- {
- db_map_close(map);
- map->map_mflags &= ~MF_IMPL_HASH;
- }
-#endif
-
-#ifdef NDBM
- if (bitset(MF_IMPL_NDBM, map->map_mflags))
- {
- ndbm_map_close(map);
- map->map_mflags &= ~MF_IMPL_NDBM;
- }
-#endif
-}
- /*
-** User map class.
-**
-** Provides access to the system password file.
-*/
-
-/*
-** USER_MAP_OPEN -- open user map
-**
-** Really just binds field names to field numbers.
-*/
-
-bool
-user_map_open(map, mode)
- MAP *map;
- int mode;
-{
- if (tTd(38, 2))
- printf("user_map_open(%s, %d)\n",
- map->map_mname, mode);
-
- mode &= O_ACCMODE;
- if (mode != O_RDONLY)
- {
- /* issue a pseudo-error message */
-#ifdef ENOSYS
- errno = ENOSYS;
-#else
-# ifdef EFTYPE
- errno = EFTYPE;
-# else
- errno = ENXIO;
-# endif
-#endif
- return FALSE;
- }
- if (map->map_valcolnm == NULL)
- /* nothing */ ;
- else if (strcasecmp(map->map_valcolnm, "name") == 0)
- map->map_valcolno = 1;
- else if (strcasecmp(map->map_valcolnm, "passwd") == 0)
- map->map_valcolno = 2;
- else if (strcasecmp(map->map_valcolnm, "uid") == 0)
- map->map_valcolno = 3;
- else if (strcasecmp(map->map_valcolnm, "gid") == 0)
- map->map_valcolno = 4;
- else if (strcasecmp(map->map_valcolnm, "gecos") == 0)
- map->map_valcolno = 5;
- else if (strcasecmp(map->map_valcolnm, "dir") == 0)
- map->map_valcolno = 6;
- else if (strcasecmp(map->map_valcolnm, "shell") == 0)
- map->map_valcolno = 7;
- else
- {
- syserr("User map %s: unknown column name %s",
- map->map_mname, map->map_valcolnm);
- return FALSE;
- }
- return TRUE;
-}
-
-
-/*
-** USER_MAP_LOOKUP -- look up a user in the passwd file.
-*/
-
-char *
-user_map_lookup(map, key, av, statp)
- MAP *map;
- char *key;
- char **av;
- int *statp;
-{
- struct passwd *pw;
- auto bool fuzzy;
-
- if (tTd(38, 20))
- printf("user_map_lookup(%s, %s)\n",
- map->map_mname, key);
-
- pw = finduser(key, &fuzzy);
- if (pw == NULL)
- return NULL;
- if (bitset(MF_MATCHONLY, map->map_mflags))
- return map_rewrite(map, key, strlen(key), NULL);
- else
- {
- char *rwval = NULL;
- char buf[30];
-
- switch (map->map_valcolno)
- {
- case 0:
- case 1:
- rwval = pw->pw_name;
- break;
-
- case 2:
- rwval = pw->pw_passwd;
- break;
-
- case 3:
- snprintf(buf, sizeof buf, "%d", pw->pw_uid);
- rwval = buf;
- break;
-
- case 4:
- snprintf(buf, sizeof buf, "%d", pw->pw_gid);
- rwval = buf;
- break;
-
- case 5:
- rwval = pw->pw_gecos;
- break;
-
- case 6:
- rwval = pw->pw_dir;
- break;
-
- case 7:
- rwval = pw->pw_shell;
- break;
- }
- return map_rewrite(map, rwval, strlen(rwval), av);
- }
-}
- /*
-** Program map type.
-**
-** This provides access to arbitrary programs. It should be used
-** only very sparingly, since there is no way to bound the cost
-** of invoking an arbitrary program.
-*/
-
-char *
-prog_map_lookup(map, name, av, statp)
- MAP *map;
- char *name;
- char **av;
- int *statp;
-{
- int i;
- register char *p;
- int fd;
- auto pid_t pid;
- char *rval;
- int stat;
- char *argv[MAXPV + 1];
- char buf[MAXLINE];
-
- if (tTd(38, 20))
- printf("prog_map_lookup(%s, %s) %s\n",
- map->map_mname, name, map->map_file);
-
- i = 0;
- argv[i++] = map->map_file;
- if (map->map_rebuild != NULL)
- {
- snprintf(buf, sizeof buf, "%s", map->map_rebuild);
- for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t"))
- {
- if (i >= MAXPV - 1)
- break;
- argv[i++] = p;
- }
- }
- argv[i++] = name;
- argv[i] = NULL;
- if (tTd(38, 21))
- {
- printf("prog_open:");
- for (i = 0; argv[i] != NULL; i++)
- printf(" %s", argv[i]);
- printf("\n");
- }
- (void) blocksignal(SIGCHLD);
- pid = prog_open(argv, &fd, CurEnv);
- if (pid < 0)
- {
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("prog_map_lookup(%s) failed (%s) -- closing",
- map->map_mname, errstring(errno));
- else if (tTd(38, 9))
- printf("prog_map_lookup(%s) failed (%s) -- closing",
- map->map_mname, errstring(errno));
- map->map_mflags &= ~(MF_VALID|MF_OPEN);
- *statp = EX_OSFILE;
- return NULL;
- }
- i = read(fd, buf, sizeof buf - 1);
- if (i < 0)
- {
- syserr("prog_map_lookup(%s): read error %s\n",
- map->map_mname, errstring(errno));
- rval = NULL;
- }
- else if (i == 0)
- {
- if (tTd(38, 20))
- printf("prog_map_lookup(%s): empty answer\n",
- map->map_mname);
- rval = NULL;
- }
- else
- {
- buf[i] = '\0';
- p = strchr(buf, '\n');
- if (p != NULL)
- *p = '\0';
-
- /* collect the return value */
- if (bitset(MF_MATCHONLY, map->map_mflags))
- rval = map_rewrite(map, name, strlen(name), NULL);
- else
- rval = map_rewrite(map, buf, strlen(buf), NULL);
-
- /* now flush any additional output */
- while ((i = read(fd, buf, sizeof buf)) > 0)
- continue;
- }
-
- /* wait for the process to terminate */
- close(fd);
- stat = waitfor(pid);
- (void) releasesignal(SIGCHLD);
-
- if (stat == -1)
- {
- syserr("prog_map_lookup(%s): wait error %s\n",
- map->map_mname, errstring(errno));
- *statp = EX_SOFTWARE;
- rval = NULL;
- }
- else if (WIFEXITED(stat))
- {
- if ((*statp = WEXITSTATUS(stat)) != EX_OK)
- rval = NULL;
- }
- else
- {
- syserr("prog_map_lookup(%s): child died on signal %d",
- map->map_mname, stat);
- *statp = EX_UNAVAILABLE;
- rval = NULL;
- }
- return rval;
-}
- /*
-** Sequenced map type.
-**
-** Tries each map in order until something matches, much like
-** implicit. Stores go to the first map in the list that can
-** support storing.
-**
-** This is slightly unusual in that there are two interfaces.
-** The "sequence" interface lets you stack maps arbitrarily.
-** The "switch" interface builds a sequence map by looking
-** at a system-dependent configuration file such as
-** /etc/nsswitch.conf on Solaris or /etc/svc.conf on Ultrix.
-**
-** We don't need an explicit open, since all maps are
-** opened during startup, including underlying maps.
-*/
-
-/*
-** SEQ_MAP_PARSE -- Sequenced map parsing
-*/
-
-bool
-seq_map_parse(map, ap)
- MAP *map;
- char *ap;
-{
- int maxmap;
-
- if (tTd(38, 2))
- printf("seq_map_parse(%s, %s)\n", map->map_mname, ap);
- maxmap = 0;
- while (*ap != '\0')
- {
- register char *p;
- STAB *s;
-
- /* find beginning of map name */
- while (isascii(*ap) && isspace(*ap))
- ap++;
- for (p = ap; isascii(*p) && isalnum(*p); p++)
- continue;
- if (*p != '\0')
- *p++ = '\0';
- while (*p != '\0' && (!isascii(*p) || !isalnum(*p)))
- p++;
- if (*ap == '\0')
- {
- ap = p;
- continue;
- }
- s = stab(ap, ST_MAP, ST_FIND);
- if (s == NULL)
- {
- syserr("Sequence map %s: unknown member map %s",
- map->map_mname, ap);
- }
- else if (maxmap == MAXMAPSTACK)
- {
- syserr("Sequence map %s: too many member maps (%d max)",
- map->map_mname, MAXMAPSTACK);
- maxmap++;
- }
- else if (maxmap < MAXMAPSTACK)
- {
- map->map_stack[maxmap++] = &s->s_map;
- }
- ap = p;
- }
- return TRUE;
-}
-
-
-/*
-** SWITCH_MAP_OPEN -- open a switched map
-**
-** This looks at the system-dependent configuration and builds
-** a sequence map that does the same thing.
-**
-** Every system must define a switch_map_find routine in conf.c
-** that will return the list of service types associated with a
-** given service class.
-*/
-
-bool
-switch_map_open(map, mode)
- MAP *map;
- int mode;
-{
- int mapno;
- int nmaps;
- char *maptype[MAXMAPSTACK];
-
- if (tTd(38, 2))
- printf("switch_map_open(%s, %s, %d)\n",
- map->map_mname, map->map_file, mode);
-
- mode &= O_ACCMODE;
- nmaps = switch_map_find(map->map_file, maptype, map->map_return);
- if (tTd(38, 19))
- {
- printf("\tswitch_map_find => %d\n", nmaps);
- for (mapno = 0; mapno < nmaps; mapno++)
- printf("\t\t%s\n", maptype[mapno]);
- }
- if (nmaps <= 0 || nmaps > MAXMAPSTACK)
- return FALSE;
-
- for (mapno = 0; mapno < nmaps; mapno++)
- {
- register STAB *s;
- char nbuf[MAXNAME + 1];
-
- if (maptype[mapno] == NULL)
- continue;
- (void) snprintf(nbuf, sizeof nbuf, "%s.%s",
- map->map_mname, maptype[mapno]);
- s = stab(nbuf, ST_MAP, ST_FIND);
- if (s == NULL)
- {
- syserr("Switch map %s: unknown member map %s",
- map->map_mname, nbuf);
- }
- else
- {
- map->map_stack[mapno] = &s->s_map;
- if (tTd(38, 4))
- printf("\tmap_stack[%d] = %s:%s\n",
- mapno, s->s_map.map_class->map_cname,
- nbuf);
- }
- }
- return TRUE;
-}
-
-
-/*
-** SEQ_MAP_CLOSE -- close all underlying maps
-*/
-
-void
-seq_map_close(map)
- MAP *map;
-{
- int mapno;
-
- if (tTd(38, 9))
- printf("seq_map_close(%s)\n", map->map_mname);
-
- for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
- {
- MAP *mm = map->map_stack[mapno];
-
- if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
- continue;
- mm->map_class->map_close(mm);
- mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
- }
-}
-
-
-/*
-** SEQ_MAP_LOOKUP -- sequenced map lookup
-*/
-
-char *
-seq_map_lookup(map, key, args, pstat)
- MAP *map;
- char *key;
- char **args;
- int *pstat;
-{
- int mapno;
- int mapbit = 0x01;
- bool tempfail = FALSE;
-
- if (tTd(38, 20))
- printf("seq_map_lookup(%s, %s)\n", map->map_mname, key);
-
- for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++)
- {
- MAP *mm = map->map_stack[mapno];
- char *rv;
-
- if (mm == NULL)
- continue;
- if (!bitset(MF_OPEN, mm->map_mflags))
- {
- if (bitset(mapbit, map->map_return[MA_UNAVAIL]))
- {
- *pstat = EX_UNAVAILABLE;
- return NULL;
- }
- continue;
- }
- *pstat = EX_OK;
- rv = mm->map_class->map_lookup(mm, key, args, pstat);
- if (rv != NULL)
- return rv;
- if (*pstat == EX_TEMPFAIL)
- {
- if (bitset(mapbit, map->map_return[MA_TRYAGAIN]))
- return NULL;
- tempfail = TRUE;
- }
- else if (bitset(mapbit, map->map_return[MA_NOTFOUND]))
- break;
- }
- if (tempfail)
- *pstat = EX_TEMPFAIL;
- else if (*pstat == EX_OK)
- *pstat = EX_NOTFOUND;
- return NULL;
-}
-
-
-/*
-** SEQ_MAP_STORE -- sequenced map store
-*/
-
-void
-seq_map_store(map, key, val)
- MAP *map;
- char *key;
- char *val;
-{
- int mapno;
-
- if (tTd(38, 12))
- printf("seq_map_store(%s, %s, %s)\n",
- map->map_mname, key, val);
-
- for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
- {
- MAP *mm = map->map_stack[mapno];
-
- if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags))
- continue;
-
- mm->map_class->map_store(mm, key, val);
- return;
- }
- syserr("seq_map_store(%s, %s, %s): no writable map",
- map->map_mname, key, val);
-}
- /*
-** NULL stubs
-*/
-
-bool
-null_map_open(map, mode)
- MAP *map;
- int mode;
-{
- return TRUE;
-}
-
-void
-null_map_close(map)
- MAP *map;
-{
- return;
-}
-
-char *
-null_map_lookup(map, key, args, pstat)
- MAP *map;
- char *key;
- char **args;
- int *pstat;
-{
- *pstat = EX_NOTFOUND;
- return NULL;
-}
-
-void
-null_map_store(map, key, val)
- MAP *map;
- char *key;
- char *val;
-{
- return;
-}
-
-
-/*
-** BOGUS stubs
-*/
-
-char *
-bogus_map_lookup(map, key, args, pstat)
- MAP *map;
- char *key;
- char **args;
- int *pstat;
-{
- *pstat = EX_TEMPFAIL;
- return NULL;
-}
-
-MAPCLASS BogusMapClass =
-{
- "bogus-map", NULL, 0,
- NULL, bogus_map_lookup, null_map_store,
- null_map_open, null_map_close,
-};
OpenPOWER on IntegriCloud