summaryrefslogtreecommitdiff
path: root/src/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map.c')
-rw-r--r--src/map.c998
1 files changed, 773 insertions, 225 deletions
diff --git a/src/map.c b/src/map.c
index 2cc283e5f52c3..0931ea69235b9 100644
--- a/src/map.c
+++ b/src/map.c
@@ -17,7 +17,7 @@ SM_RCSID("@(#)$Id: map.c,v 8.713 2013-11-22 20:51:55 ca Exp $")
#if LDAPMAP
# include <sm/ldap.h>
-#endif /* LDAPMAP */
+#endif
#if NDBM
# include <ndbm.h>
@@ -30,43 +30,46 @@ SM_RCSID("@(#)$Id: map.c,v 8.713 2013-11-22 20:51:55 ca Exp $")
#endif /* NDBM */
#if NEWDB
# include "sm/bdb.h"
-#endif /* NEWDB */
+#endif
#if NIS
struct dom_binding; /* forward reference needed on IRIX */
# include <rpcsvc/ypclnt.h>
# if NDBM
# define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
-# endif /* NDBM */
+# endif
#endif /* NIS */
+#if CDB
+# include <cdb.h>
+#endif
#include "map.h"
#if NEWDB
# if DB_VERSION_MAJOR < 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *));
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, void **));
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
#endif /* NEWDB */
static bool extract_canonname __P((char *, char *, char *, char[], int));
static void map_close __P((STAB *, int));
static void map_init __P((STAB *, int));
#ifdef LDAPMAP
static STAB * ldapmap_findconn __P((SM_LDAP_STRUCT *));
-#endif /* LDAPMAP */
+#endif
#if NISPLUS
static bool nisplus_getcanonname __P((char *, int, int *));
-#endif /* NISPLUS */
+#endif
#if NIS
static bool nis_getcanonname __P((char *, int, int *));
-#endif /* NIS */
+#endif
#if NETINFO
static bool ni_getcanonname __P((char *, int, int *));
-#endif /* NETINFO */
+#endif
static bool text_getcanonname __P((char *, int, int *));
#if SOCKETMAP
static STAB *socket_map_findconn __P((const char*));
@@ -81,9 +84,9 @@ static STAB *socket_map_findconn __P((const char*));
#else /* ENOSYS */
# ifdef EFTYPE
# define SM_EMAPCANTWRITE EFTYPE
-# else /* EFTYPE */
+# else
# define SM_EMAPCANTWRITE ENXIO
-# endif /* EFTYPE */
+# endif
#endif /* ENOSYS */
/*
@@ -128,9 +131,9 @@ static STAB *socket_map_findconn __P((const char*));
#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
-#else /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
+#else
# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
-#endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
+#endif
/*
** MAP_PARSEARGS -- parse config line arguments for database lookup
@@ -165,45 +168,24 @@ map_parseargs(map, ap)
map->map_spacesub = SpaceSub; /* default value */
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_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 'D':
+ map->map_mflags |= MF_DEFER;
+ break;
+
case 'd':
{
char *h;
@@ -218,8 +200,8 @@ map_parseargs(map, ap)
}
break;
- case 'T':
- map->map_tapp = ++p;
+ case 'f':
+ map->map_mflags |= MF_NOFOLDCASE;
break;
case 'k':
@@ -228,6 +210,39 @@ map_parseargs(map, ap)
map->map_keycolnm = p;
break;
+ case 'm':
+ map->map_mflags |= MF_MATCHONLY;
+ break;
+
+ 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 'q':
+ map->map_mflags |= MF_KEEPQUOTES;
+ break;
+
+ case 'S':
+ map->map_spacesub = *++p;
+ break;
+
+ case 'T':
+ map->map_tapp = ++p;
+ break;
+
+ case 't':
+ map->map_mflags |= MF_NODEFER;
+ break;
+
case 'v':
while (isascii(*++p) && isspace(*p))
continue;
@@ -255,24 +270,11 @@ map_parseargs(map, ap)
}
break;
- case 't':
- map->map_mflags |= MF_NODEFER;
- break;
-
-
- case 'S':
- map->map_spacesub = *++p;
- break;
-
- case 'D':
- map->map_mflags |= MF_DEFER;
- break;
-
default:
syserr("Illegal option %c map %s", *p, map->map_mname);
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -289,14 +291,14 @@ map_parseargs(map, ap)
if (*p != '\0')
{
map->map_file = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
map->map_file = newstr(map->map_file);
}
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
if (*p != '\0')
map->map_rebuild = newstr(p);
@@ -454,11 +456,11 @@ initmaps()
{
#if XDEBUG
checkfd012("entering initmaps");
-#endif /* XDEBUG */
+#endif
stabapply(map_init, 0);
#if XDEBUG
checkfd012("exiting initmaps");
-#endif /* XDEBUG */
+#endif
}
/*
** MAP_INIT -- rebuild a map
@@ -629,7 +631,6 @@ closemaps(bogus)
** none.
*/
-/* ARGSUSED1 */
static void
map_close(s, bogus)
register STAB *s;
@@ -729,11 +730,11 @@ sun_init_domain()
** pttl -- pointer to return TTL (can be NULL).
**
** Returns:
-** true -- if the host was found.
-** false -- otherwise.
+** >0 -- if the host was found.
+** 0 -- otherwise.
*/
-bool
+int
getcanonname(host, hbsize, trymx, pttl)
char *host;
int hbsize;
@@ -751,9 +752,10 @@ getcanonname(host, hbsize, trymx, pttl)
bool should_try_nis_domain = false;
static char *nis_domain = NULL;
#endif
+ bool secure = true; /* consider all maps secure by default */
nmaps = switch_map_find("hosts", maptype, mapreturn);
- if (pttl != 0)
+ if (pttl != NULL)
*pttl = SM_DEFAULT_TTL;
for (mapno = 0; mapno < nmaps; mapno++)
{
@@ -773,7 +775,7 @@ getcanonname(host, hbsize, trymx, pttl)
# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
if (nis_domain == NULL)
nis_domain = sun_init_domain();
-# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+# endif
}
#endif /* NIS */
#if NISPLUS
@@ -783,13 +785,18 @@ getcanonname(host, hbsize, trymx, pttl)
# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
if (nis_domain == NULL)
nis_domain = sun_init_domain();
-# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+# endif
}
#endif /* NISPLUS */
#if NAMED_BIND
else if (strcmp("dns", maptype[mapno]) == 0)
{
- found = dns_getcanonname(host, hbsize, trymx, &status, pttl);
+ int r;
+
+ r = dns_getcanonname(host, hbsize, trymx, &status,
+ pttl);
+ secure = HOST_SECURE == r;
+ found = r > 0;
}
#endif /* NAMED_BIND */
#if NETINFO
@@ -841,7 +848,7 @@ getcanonname(host, hbsize, trymx, pttl)
char *d;
if (tTd(38, 20))
- sm_dprintf("getcanonname(%s), found\n", host);
+ sm_dprintf("getcanonname(%s), found, ad=%d\n", host, secure);
/*
** If returned name is still single token, compensate
@@ -870,10 +877,10 @@ getcanonname(host, hbsize, trymx, pttl)
goto try_nis_domain;
}
#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
- return false;
+ return HOST_NOTFOUND;
}
}
- return true;
+ return secure ? HOST_SECURE : HOST_OK;
}
#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
@@ -884,7 +891,7 @@ getcanonname(host, hbsize, trymx, pttl)
strlen(nis_domain) + strlen(host) + 1 < hbsize)
{
(void) sm_strlcat2(host, ".", nis_domain, hbsize);
- return true;
+ return HOST_OK;
}
}
#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
@@ -898,7 +905,7 @@ getcanonname(host, hbsize, trymx, pttl)
else
SM_SET_H_ERRNO(HOST_NOT_FOUND);
- return false;
+ return HOST_NOTFOUND;
}
/*
** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
@@ -982,7 +989,7 @@ extract_canonname(name, dot, line, cbuf, cbuflen)
# include "sm_resolve.h"
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
/*
** DNS_MAP_OPEN -- stub to check proper value for dns map type
@@ -1023,6 +1030,7 @@ dns_map_open(map, mode)
struct dns_map
{
int dns_m_type;
+ unsigned int dns_m_options;
};
bool
@@ -1034,56 +1042,54 @@ dns_map_parseargs(map,args)
struct dns_map *map_p;
map_p = (struct dns_map *) xalloc(sizeof(*map_p));
+ memset(map_p, '\0', sizeof(*map_p));
map_p->dns_m_type = -1;
map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_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;
+#if DNSSEC_TEST
+ case '@':
+ ++p;
+ if (nsportip(p) < 0)
+ syserr("dns map %s: nsportip(%s)=failed",
+ map->map_mname, p);
break;
+#endif /* DNSSEC_TEST */
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;
- case 'T':
- map->map_tapp = ++p;
+ case 'B': /* base domain */
+ {
+ char *h;
+
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ h = strchr(p, ' ');
+ if (h != NULL)
+ *h = '\0';
+
+ /*
+ ** slight abuse of map->map_file; it isn't
+ ** used otherwise in this map type.
+ */
+
+ map->map_file = newstr(p);
+ if (h != NULL)
+ *h = ' ';
+ }
break;
case 'd':
@@ -1100,12 +1106,51 @@ dns_map_parseargs(map,args)
}
break;
+ case 'f':
+ map->map_mflags |= MF_NOFOLDCASE;
+ break;
+
+ case 'm':
+ map->map_mflags |= MF_MATCHONLY;
+ break;
+
+ 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 'q':
+ map->map_mflags |= MF_KEEPQUOTES;
+ break;
+
+ case 'S':
+#if defined(RES_USE_EDNS0) && defined(RES_USE_DNSSEC)
+ map_p->dns_m_options |= SM_RES_DNSSEC;
+#endif
+ break;
+
case 'r':
while (isascii(*++p) && isspace(*p))
continue;
map->map_retry = atoi(p);
break;
+ case 't':
+ map->map_mflags |= MF_NODEFER;
+ break;
+
+ case 'T':
+ map->map_tapp = ++p;
+ break;
+
case 'z':
if (*++p != '\\')
map->map_coldelim = *p;
@@ -1152,28 +1197,8 @@ dns_map_parseargs(map,args)
}
break;
- case 'B': /* base domain */
- {
- char *h;
-
- while (isascii(*++p) && isspace(*p))
- continue;
- h = strchr(p, ' ');
- if (h != NULL)
- *h = '\0';
-
- /*
- ** slight abuse of map->map_file; it isn't
- ** used otherwise in this map type.
- */
-
- map->map_file = newstr(p);
- if (h != NULL)
- *h = ' ';
- }
- break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -1222,15 +1247,17 @@ dns_map_lookup(map, name, av, statp)
struct dns_map *map_p;
RESOURCE_RECORD_T *rr = NULL;
DNS_REPLY_T *r = NULL;
+ unsigned int options;
# if NETINET6
static char buf6[INET6_ADDRSTRLEN];
-# endif /* NETINET6 */
+# endif
if (tTd(38, 20))
sm_dprintf("dns_map_lookup(%s, %s)\n",
map->map_mname, name);
map_p = (struct dns_map *)(map->map_db1);
+ options = map_p->dns_m_options;
if (map->map_file != NULL && *map->map_file != '\0')
{
size_t len;
@@ -1244,14 +1271,14 @@ dns_map_lookup(map, name, av, statp)
return NULL;
}
(void) sm_strlcpyn(appdomain, len, 3, name, ".", map->map_file);
- r = dns_lookup_int(appdomain, C_IN, map_p->dns_m_type,
- map->map_timeout, map->map_retry);
+ r = dns_lookup_map(appdomain, C_IN, map_p->dns_m_type,
+ map->map_timeout, map->map_retry, options);
sm_free(appdomain);
}
else
{
- r = dns_lookup_int(name, C_IN, map_p->dns_m_type,
- map->map_timeout, map->map_retry);
+ r = dns_lookup_map(name, C_IN, map_p->dns_m_type,
+ map->map_timeout, map->map_retry, options);
}
if (r == NULL)
@@ -1312,6 +1339,12 @@ dns_map_lookup(map, name, av, statp)
sizeof(buf6));
break;
# endif /* NETINET6 */
+# ifdef T_TLSA
+ case T_TLSA:
+ type = "T_TLSA";
+ value = rr->rr_u.rr_txt;
+ break;
+# endif /* T_TLSA */
}
(void) strreplnonprt(value, 'X');
@@ -1396,8 +1429,7 @@ dns_map_lookup(map, name, av, statp)
cleanup:
if (vp != NULL)
sm_free(vp);
- if (r != NULL)
- dns_free_data(r);
+ dns_free_data(r);
return result;
}
# endif /* DNSMAP */
@@ -1582,7 +1614,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = save_errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open DBM database %s", map->map_file);
@@ -1597,7 +1629,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = 0;
syserr("dbm map \"%s\": cannot support GDBM",
map->map_mname);
@@ -1612,7 +1644,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = save_errno;
syserr("ndbm_map_open(%s): file changed after open",
map->map_file);
@@ -1840,7 +1872,7 @@ ndbm_map_store(map, lhs, rhs)
data.dptr = buf;
if (tTd(38, 9))
sm_dprintf("ndbm_map_store append=%s\n",
- (char *)data.dptr);
+ data.dptr);
}
}
status = dbm_store((DBM *) map->map_db1,
@@ -1900,7 +1932,7 @@ ndbm_map_close(map)
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
}
#endif /* NDBM */
@@ -1928,10 +1960,10 @@ ndbm_map_close(map)
# define h_nelem nelem
# ifndef DB_CACHE_SIZE
# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
-# endif /* ! DB_CACHE_SIZE */
+# endif
# ifndef DB_HASH_NELEM
# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
-# endif /* ! DB_HASH_NELEM */
+# endif
# endif /* DB_VERSION_MAJOR < 2 */
bool
@@ -1941,13 +1973,13 @@ bt_map_open(map, mode)
{
# if DB_VERSION_MAJOR < 2
BTREEINFO btinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO btinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void *btinfo = NULL;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (tTd(38, 2))
sm_dprintf("bt_map_open(%s, %s, %d)\n",
@@ -1957,7 +1989,7 @@ bt_map_open(map, mode)
memset(&btinfo, '\0', sizeof(btinfo));
# ifdef DB_CACHE_SIZE
btinfo.db_cachesize = DB_CACHE_SIZE;
-# endif /* DB_CACHE_SIZE */
+# endif
# endif /* DB_VERSION_MAJOR < 3 */
return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
@@ -1970,13 +2002,13 @@ hash_map_open(map, mode)
{
# if DB_VERSION_MAJOR < 2
HASHINFO hinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO hinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void *hinfo = NULL;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (tTd(38, 2))
sm_dprintf("hash_map_open(%s, %s, %d)\n",
@@ -1986,10 +2018,10 @@ hash_map_open(map, mode)
memset(&hinfo, '\0', sizeof(hinfo));
# ifdef DB_HASH_NELEM
hinfo.h_nelem = DB_HASH_NELEM;
-# endif /* DB_HASH_NELEM */
+# endif
# ifdef DB_CACHE_SIZE
hinfo.db_cachesize = DB_CACHE_SIZE;
-# endif /* DB_CACHE_SIZE */
+# endif
# endif /* DB_VERSION_MAJOR < 3 */
return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
@@ -2003,13 +2035,13 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
DBTYPE dbtype;
# if DB_VERSION_MAJOR < 2
const void *openinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO *openinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void **openinfo;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
{
DB *db = NULL;
int i;
@@ -2143,7 +2175,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
int flags = 0;
# if DB_VERSION_MAJOR > 2
int ret;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (mode == O_RDONLY)
flags |= DB_RDONLY;
@@ -2216,7 +2248,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
errno = save_errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open %s database %s",
@@ -2226,7 +2258,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
# if DB_VERSION_MAJOR < 2
fd = db->fd(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
fd = -1;
errno = db->fd(db, &fd);
# endif /* DB_VERSION_MAJOR < 2 */
@@ -2235,13 +2267,13 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
save_errno = errno;
# if DB_VERSION_MAJOR < 2
(void) db->close(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
errno = db->close(db, 0);
# endif /* DB_VERSION_MAJOR < 2 */
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
errno = save_errno;
syserr("db_map_open(%s): file changed after open", buf);
return false;
@@ -2352,7 +2384,7 @@ db_map_lookup(map, name, av, statp)
lockdb:
# if DB_VERSION_MAJOR < 2
fd = db->fd(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
fd = -1;
errno = db->fd(db, &fd);
# endif /* DB_VERSION_MAJOR < 2 */
@@ -2564,7 +2596,7 @@ db_map_store(map, lhs, rhs)
}
# if DB_VERSION_MAJOR < 2
status = db->put(db, &key, &data, 0);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
status = errno = db->put(db, NULL, &key, &data, 0);
# endif /* DB_VERSION_MAJOR < 2 */
}
@@ -2633,6 +2665,389 @@ db_map_close(map)
map->map_mname, map->map_file, map->map_mflags);
}
#endif /* NEWDB */
+
+#if CDB
+/*
+** CDB Modules
+*/
+
+static bool smdb_add_extension __P((char *, int, char *, char *));
+
+/*
+** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
+**
+** Just adds a . followed by a string to a db_name if there
+** is room and the db_name does not already have that extension.
+**
+** Parameters:
+** full_name -- The final file name.
+** max_full_name_len -- The max length for full_name.
+** db_name -- The name of the db.
+** extension -- The extension to add.
+**
+** Returns:
+** SMDBE_OK -- Success.
+** Anything else is an error. Look up more info about the
+** error in the comments for the specific open() used.
+*/
+
+static bool
+smdb_add_extension(full_name, max_full_name_len, db_name, extension)
+ char *full_name;
+ int max_full_name_len;
+ char *db_name;
+ char *extension;
+{
+ int extension_len;
+ int db_name_len;
+
+ if (full_name == NULL || db_name == NULL || extension == NULL)
+ return false; /* SMDBE_INVALID_PARAMETER; */
+
+ extension_len = strlen(extension);
+ db_name_len = strlen(db_name);
+
+ if (extension_len + db_name_len + 2 > max_full_name_len)
+ return false; /* SMDBE_DB_NAME_TOO_LONG; */
+
+ if (db_name_len < extension_len + 1 ||
+ db_name[db_name_len - extension_len - 1] != '.' ||
+ strcmp(&db_name[db_name_len - extension_len], extension) != 0)
+ (void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
+ db_name, extension);
+ else
+ (void) sm_strlcpy(full_name, db_name, max_full_name_len);
+
+ return true;
+}
+
+bool
+cdb_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ int fd, status, omode, smode;
+ long sff;
+ struct stat st;
+ char buf[MAXPATHLEN];
+
+ if (tTd(38, 2))
+ sm_dprintf("cdb_map_open(%s, %s, %d)\n",
+ map->map_mname, map->map_file, mode);
+ map->map_db1 = (ARBPTR_T)NULL;
+ map->map_db2 = (ARBPTR_T)NULL;
+
+ mode &= O_ACCMODE;
+ omode = mode;
+
+ /*
+ ** Notes:
+ ** If a temporary file is used, then there must be some check
+ ** that the rename() is "safe" (i.e., does not overwrite some
+ ** "other" file created by an attacker).
+ **
+ ** The code to add the extension and to set up safefile()
+ ** and open() should be in a common function
+ ** (it would be nice to re-use libsmdb?)
+ */
+
+ if (!smdb_add_extension(buf, sizeof(buf), map->map_file, CDBext))
+ {
+ errno = 0;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb map \"%s\": map file %s name too long",
+ map->map_mname, map->map_file);
+ return false;
+ }
+
+ sff = SFF_ROOTOK|SFF_REGONLY;
+ if (mode == O_RDWR)
+ {
+ if (sm_strlcat(buf, ".tmp", sizeof buf) >= sizeof buf)
+ {
+ errno = 0;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb map \"%s\": map file %s name too long",
+ map->map_mname, map->map_file);
+ return false;
+ }
+ sff |= SFF_CREAT;
+ if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
+ sff |= SFF_NOSLINK;
+ if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
+ sff |= SFF_NOHLINK;
+ smode = S_IWRITE;
+ }
+ else
+ {
+ smode = S_IREAD;
+ if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
+ sff |= SFF_NOWLINK;
+ }
+ if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
+ sff |= SFF_SAFEDIRPATH;
+ status = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
+ if (status != 0)
+ {
+ char *prob = "unsafe";
+
+ /* cannot open this map */
+ if (status == ENOENT)
+ prob = "missing";
+ errno = status;
+ if (tTd(38, 2))
+ sm_dprintf("\t%s map file: %s\n", prob, sm_errstring(status));
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("%s map \"%s\": %s map file %s",
+ map->map_mname, prob, buf, sm_errstring(status));
+ return false;
+ }
+
+ if (st.st_mode == ST_MODE_NOFILE)
+ omode |= O_CREAT|O_EXCL;
+# if LOCK_ON_OPEN
+ if (mode == O_RDWR)
+ omode |= O_TRUNC|O_EXLOCK;
+ else
+ omode |= O_SHLOCK;
+# else
+ if (mode == O_RDWR)
+ omode |= O_TRUNC;
+# endif /* LOCK_ON_OPEN */
+
+ fd = open(buf, omode, DBMMODE);
+ if (fd < 0)
+ {
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb_map_open: cannot open database %s", buf);
+ return false;
+ }
+
+# if !LOCK_ON_OPEN
+ /* make sure no baddies slipped in just before the open... */
+ if (filechanged(buf, fd, &st))
+ {
+ int save_errno;
+
+ save_errno = errno;
+ (void) close(fd);
+ errno = save_errno;
+ syserr("cdb_map_open(%s): file changed after open", buf);
+ return false;
+ }
+
+ /* actually lock the opened file */
+ if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
+ syserr("cdb_map_open: cannot lock %s", buf);
+# endif /* !LOCK_ON_OPEN */
+
+ /* only for aliases! */
+ if (mode == O_RDWR)
+ {
+ struct cdb_make *cdbmp;
+
+ cdbmp = (struct cdb_make *) xalloc(sizeof(*cdbmp));
+ status = cdb_make_start(cdbmp, fd);
+ if (status != 0)
+ {
+ close(fd);
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("initialization of cdb map (make) failed");
+ return false;
+ }
+
+ map->map_db2 = (ARBPTR_T)cdbmp;
+ return true;
+ }
+ else
+ {
+ struct cdb *cdbp;
+
+ cdbp = (struct cdb *) xalloc(sizeof(*cdbp));
+ status = cdb_init(cdbp, fd);
+ if (status != 0)
+ {
+ close(fd);
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("initialization of cdb map failed");
+ return false;
+ }
+ map->map_db1 = (ARBPTR_T)cdbp;
+ return true;
+ }
+
+ /* NOTREACHED */
+ return false;
+}
+
+char *
+cdb_map_lookup (map, name, av, statp)
+ MAP * map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ char * data;
+ struct cdb *cdbmap;
+ unsigned int klen, dlen;
+ int st;
+ char key[MAXNAME+1];
+
+ data = NULL;
+ cdbmap = map->map_db1;
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_lookup(%s, %s)\n", map->map_mname, name);
+
+ klen = strlen(name);
+ if (klen > sizeof(key) - 1)
+ klen = sizeof(key) - 1;
+ memmove(key, name, klen);
+ key[klen] = '\0';
+
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ makelower(key);
+
+ st = 0;
+ if (bitset(MF_TRY0NULL, map->map_mflags))
+ {
+ st = cdb_find(cdbmap, key, klen);
+ if (st == 1)
+ map->map_mflags &= ~MF_TRY1NULL;
+ }
+ if (st != 1 && bitset(MF_TRY1NULL, map->map_mflags))
+ {
+ st = cdb_find(cdbmap, key, klen + 1);
+ if (st == 1)
+ map->map_mflags &= ~MF_TRY0NULL;
+ }
+ if (st != 1)
+ {
+ if (st < 0)
+ syserr("cdb_map_lookup: get (%s)", name);
+ return NULL;
+ }
+ else
+ {
+ dlen = cdb_datalen(cdbmap);
+ data = malloc(dlen + 1);
+ cdb_read(cdbmap, data, dlen, cdb_datapos(cdbmap));
+ data[dlen] = '\0';
+ }
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, data, dlen, av);
+}
+
+/*
+** CDB_MAP_STORE -- store a datum in the CDB database
+*/
+
+void
+cdb_map_store(map, lhs, rhs)
+ MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ struct cdb_make *cdbmp;
+ size_t klen;
+ size_t vlen;
+ int status;
+ char keybuf[MAXNAME + 1];
+
+ cdbmp = map->map_db2;
+ if (cdbmp == NULL)
+ return; /* XXX */
+
+ klen = strlen(lhs);
+ vlen = strlen(rhs);
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ {
+ if (klen > sizeof(keybuf) - 1)
+ klen = sizeof(keybuf) - 1;
+ memmove(keybuf, lhs, klen);
+ keybuf[klen] = '\0';
+ makelower(keybuf);
+ lhs = keybuf;
+ }
+
+ if (bitset(MF_INCLNULL, map->map_mflags))
+ {
+ klen++;
+ vlen++;
+ }
+
+ /* flags? */
+ status = cdb_make_put(cdbmp, lhs, klen, rhs, vlen, 0);
+ /* and now? */
+}
+
+void
+cdb_map_close(map)
+ MAP * map;
+{
+ struct cdb *cdbp;
+ struct cdb_make *cdbmp;
+ int fd;
+
+ fd = -1;
+ cdbp = map->map_db1;
+ if (cdbp != NULL)
+ {
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_close(%p)\n", (void *)cdbp);
+ fd = cdb_fileno(cdbp);
+ cdb_free(cdbp);
+ sm_free(cdbp);
+ cdbp = NULL;
+ }
+ cdbmp = map->map_db2;
+ if (cdbmp != NULL)
+ {
+ char tmpfn[MAXPATHLEN], cdbfn[MAXPATHLEN];
+
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_close(%p)\n", (void *)cdbmp);
+ fd = cdb_fileno(cdbmp);
+
+ /* write out the distinguished alias */
+ /* XXX Why isn't this in a common place? */
+ cdb_map_store(map, "@", "@");
+
+ if (cdb_make_finish(cdbmp) != 0)
+ syserr("cdb: failed to write %s", map->map_file);
+ if (fd >=0)
+ {
+ if (fsync(fd) == -1)
+ syserr("cdb: fsync(%s) failed", map->map_file);
+ if (close(fd) == -1)
+ syserr("cdb: close(%s) failed", map->map_file);
+ }
+
+ if (!smdb_add_extension(cdbfn, sizeof(cdbfn), map->map_file,
+ CDBext))
+ {
+ syserr("cdb: add extension to %s failed",
+ map->map_file);
+ }
+ if (sm_strlcpy(tmpfn, cdbfn, sizeof tmpfn) >= sizeof tmpfn ||
+ sm_strlcat(tmpfn, ".tmp", sizeof tmpfn) >= sizeof tmpfn)
+ {
+ syserr("cdb: set temp filename for %s failed",
+ map->map_file);
+ }
+ if (tTd(38, 80))
+ sm_dprintf("rename(%s, %s)\n", tmpfn, cdbfn);
+ if (rename(tmpfn, cdbfn) == -1)
+ syserr("cdb: rename(%s, %s) failed", tmpfn, cdbfn);
+ sm_free(cdbmp);
+ cdbmp = NULL;
+ }
+ if (fd >=0)
+ close(fd);
+}
+#endif /* CDB */
+
/*
** NIS Modules
*/
@@ -2641,7 +3056,7 @@ db_map_close(map)
# ifndef YPERR_BUSY
# define YPERR_BUSY 16
-# endif /* ! YPERR_BUSY */
+# endif
/*
** NIS_MAP_OPEN -- open DBM map
@@ -2706,7 +3121,7 @@ nis_map_open(map, mode)
{
/*
** We ought to be calling aliaswait() here if this is an
- ** alias file, but powerful HP-UX NIS servers apparently
+ ** 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.
*/
@@ -2714,7 +3129,7 @@ nis_map_open(map, mode)
# if 0
if (!bitset(MF_ALIAS, map->map_mflags) ||
aliaswait(map, NULL, true))
-# endif /* 0 */
+# endif
return true;
}
@@ -2769,7 +3184,7 @@ nis_map_lookup(map, name, av, statp)
}
if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
{
- SM_FREE_CLR(vp);
+ SM_FREE(vp);
buflen++;
yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
&vp, &vsize);
@@ -2843,7 +3258,7 @@ nis_getcanonname(name, hbsize, statp)
}
if (yperr == YPERR_KEY && try1null)
{
- SM_FREE_CLR(vp);
+ SM_FREE(vp);
keylen++;
yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
&vp, &vsize);
@@ -2899,7 +3314,7 @@ nis_getcanonname(name, hbsize, statp)
# include <rpcsvc/nislib.h>
# ifndef NIS_TABLE_OBJ
# define NIS_TABLE_OBJ TABLE_OBJ
-# endif /* NIS_TABLE_OBJ */
+# endif
# 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
@@ -3331,7 +3746,7 @@ nisplus_default_domain()
# if PH_MAP
# define ph_map_dequote ldapmap_dequote
-# endif /* PH_MAP */
+# endif
static char *ldapmap_dequote __P((char *));
@@ -3462,9 +3877,9 @@ ldapmap_open(map, mode)
syserr("%s failed to %s in map %s",
# if USE_LDAP_INIT
"ldap_init/ldap_bind",
-# else /* USE_LDAP_INIT */
+# else
"ldap_open",
-# endif /* USE_LDAP_INIT */
+# endif
id, map->map_mname);
}
else
@@ -3472,9 +3887,9 @@ ldapmap_open(map, mode)
syserr("451 4.3.5 %s failed to %s in map %s",
# if USE_LDAP_INIT
"ldap_init/ldap_bind",
-# else /* USE_LDAP_INIT */
+# else
"ldap_open",
-# endif /* USE_LDAP_INIT */
+# endif
id, map->map_mname);
}
}
@@ -3589,7 +4004,7 @@ ldapmap_lookup(map, name, av, statp)
char keybuf[MAXKEY];
#if SM_LDAP_ARGS != MAX_MAP_ARGS
# ERROR _SM_LDAP_ARGS must be the same as _MAX_MAP_ARGS
-#endif /* SM_LDAP_ARGS != MAX_MAP_ARGS */
+#endif
#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
HASLDAPGETALIASBYNAME
@@ -3717,7 +4132,7 @@ ldapmap_lookup(map, name, av, statp)
{
# ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN:
-# endif /* LDAP_SERVER_DOWN */
+# endif
case LDAP_TIMEOUT:
case LDAP_UNAVAILABLE:
/* server disappeared, try reopen on next search */
@@ -3752,7 +4167,7 @@ ldapmap_lookup(map, name, av, statp)
# if _FFR_LDAP_SINGLEDN
if (bitset(MF_SINGLEDN, map->map_mflags))
flags |= SM_LDAP_SINGLEDN;
-# endif /* _FFR_LDAP_SINGLEDN */
+# endif
/* Create an rpool for search related memory usage */
rpool = sm_rpool_new_x(NULL);
@@ -3876,7 +4291,7 @@ static struct lamvalues LDAPAuthMethods[] =
{ "simple", LDAP_AUTH_SIMPLE },
# ifdef LDAP_AUTH_KRBV4
{ "krbv4", LDAP_AUTH_KRBV4 },
-# endif /* LDAP_AUTH_KRBV4 */
+# endif
{ NULL, 0 }
};
@@ -3996,13 +4411,15 @@ ldapmap_parseargs(map, args)
map->map_coldelim = ' ';
}
-# if _FFR_LDAP_NETWORK_TIMEOUT
- lmap->ldap_networktmo = 120;
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+# if LDAP_NETWORK_TIMEOUT
+ if (0 == lmap->ldap_networktmo)
+ lmap->ldap_networktmo = (LDAP_NETWORK_TIMEOUT > 1)
+ ? LDAP_NETWORK_TIMEOUT : 60;
+# endif
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -4095,13 +4512,13 @@ ldapmap_parseargs(map, args)
lmap->ldap_base = p;
break;
-# if _FFR_LDAP_NETWORK_TIMEOUT
+# if LDAP_NETWORK_TIMEOUT
case 'c': /* network (connect) timeout */
while (isascii(*++p) && isspace(*p))
continue;
lmap->ldap_networktmo = atoi(p);
break;
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+# endif /* LDAP_NETWORK_TIMEOUT */
case 'd': /* Dn to bind to server as */
while (isascii(*++p) && isspace(*p))
@@ -4217,7 +4634,7 @@ ldapmap_parseargs(map, args)
case 'R': /* don't auto chase referrals */
# ifdef LDAP_REFERRALS
lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
-# else /* LDAP_REFERRALS */
+# else
syserr("compile with -DLDAP_REFERRALS for referral support");
# endif /* LDAP_REFERRALS */
break;
@@ -4345,6 +4762,14 @@ ldapmap_parseargs(map, args)
# endif /* LDAP_VERSION_MIN */
break;
+ case 'x':
+# if _FFR_SM_LDAP_DBG
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ lmap->ldap_debug = atoi(p);
+# endif
+ break;
+
case 'Z':
while (isascii(*++p) && isspace(*p))
continue;
@@ -4357,7 +4782,7 @@ ldapmap_parseargs(map, args)
}
/* need to account for quoted strings here */
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
{
if (*p == '"')
{
@@ -4542,7 +4967,7 @@ ldapmap_parseargs(map, args)
{
char *v;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -4719,8 +5144,8 @@ ldapmap_set_defaults(spec)
map.map_tapp != NULL)
{
syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
- SM_FREE_CLR(map.map_app);
- SM_FREE_CLR(map.map_tapp);
+ SM_FREE(map.map_app);
+ SM_FREE(map.map_tapp);
}
if (LDAPDefaults->ldap_filter != NULL)
@@ -4801,7 +5226,7 @@ ph_map_parseargs(map, args)
map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -4879,7 +5304,7 @@ ph_map_parseargs(map, args)
}
/* try to account for quoted strings */
- done = isascii(*p) && isspace(*p);
+ done = SM_ISSPACE(*p);
while (*p != '\0' && !done)
{
if (*p == '"')
@@ -4891,7 +5316,7 @@ ph_map_parseargs(map, args)
}
else
p++;
- done = isascii(*p) && isspace(*p);
+ done = SM_ISSPACE(*p);
}
if (*p != '\0')
@@ -5196,7 +5621,7 @@ syslog_map_parseargs(map, args)
/* there is no check whether there is really an argument */
while (*p != '\0')
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -5214,12 +5639,12 @@ syslog_map_parseargs(map, args)
}
else if (*p == 'L')
{
- while (*++p != '\0' && isascii(*p) && isspace(*p))
+ while (*++p != '\0' && SM_ISSPACE(*p))
continue;
if (*p == '\0')
break;
priority = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -5335,7 +5760,7 @@ dprintf_map_parseargs(map, args)
/* there is no check whether there is really an argument */
while (*p != '\0')
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -5353,12 +5778,12 @@ dprintf_map_parseargs(map, args)
}
else if (*p == 'd')
{
- while (*++p != '\0' && isascii(*p) && isspace(*p))
+ while (*++p != '\0' && SM_ISSPACE(*p))
continue;
if (*p == '\0')
break;
dbg_level = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -5481,7 +5906,7 @@ hes_map_lookup(map, name, av, statp)
(void) sm_strlcpy(&np[1], name, (sizeof(nbuf)) - 1);
# ifdef HESIOD_INIT
hp = hesiod_resolve(HesiodContext, np, map->map_file);
-# else /* HESIOD_INIT */
+# else
hp = hes_resolve(np, map->map_file);
# endif /* HESIOD_INIT */
save_errno = errno;
@@ -5493,7 +5918,7 @@ hes_map_lookup(map, name, av, statp)
{
# ifdef HESIOD_INIT
hp = hesiod_resolve(HesiodContext, name, map->map_file);
-# else /* HESIOD_INIT */
+# else
hp = hes_resolve(name, map->map_file);
# endif /* HESIOD_INIT */
}
@@ -6069,11 +6494,15 @@ impl_map_lookup(map, name, av, pstat)
#if NEWDB
if (bitset(MF_IMPL_HASH, map->map_mflags))
return db_map_lookup(map, name, av, pstat);
-#endif /* NEWDB */
+#endif
#if NDBM
if (bitset(MF_IMPL_NDBM, map->map_mflags))
return ndbm_map_lookup(map, name, av, pstat);
-#endif /* NDBM */
+#endif
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ return cdb_map_lookup(map, name, av, pstat);
+#endif
return stab_map_lookup(map, name, av, pstat);
}
@@ -6093,11 +6522,15 @@ impl_map_store(map, lhs, rhs)
#if NEWDB
if (bitset(MF_IMPL_HASH, map->map_mflags))
db_map_store(map, lhs, rhs);
-#endif /* NEWDB */
+#endif
#if NDBM
if (bitset(MF_IMPL_NDBM, map->map_mflags))
ndbm_map_store(map, lhs, rhs);
-#endif /* NDBM */
+#endif
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ cdb_map_store(map, lhs, rhs);
+#endif
stab_map_store(map, lhs, rhs);
}
@@ -6110,19 +6543,25 @@ impl_map_open(map, mode)
MAP *map;
int mode;
{
+ bool wasopt;
+
if (tTd(38, 2))
sm_dprintf("impl_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
+ wasopt = bitset(MF_OPTIONAL, map->map_mflags);
+
+ /* suppress error msgs */
+ map->map_mflags |= MF_OPTIONAL;
#if 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 /* NDBM_YP_COMPAT */
- return true;
+# endif
+ goto ok;
}
else
map->map_mflags &= ~MF_IMPL_HASH;
@@ -6130,27 +6569,43 @@ impl_map_open(map, mode)
#if NDBM
map->map_mflags |= MF_IMPL_NDBM;
if (ndbm_map_open(map, mode))
- {
- return true;
- }
+ goto ok;
else
map->map_mflags &= ~MF_IMPL_NDBM;
#endif /* NDBM */
-#if defined(NEWDB) || defined(NDBM)
+#if CDB
+ map->map_mflags |= MF_IMPL_CDB;
+ if (cdb_map_open(map, mode))
+ goto ok;
+ else
+ map->map_mflags &= ~MF_IMPL_CDB;
+#endif /* CDB */
+
+ if (!bitset(MF_ALIAS, map->map_mflags))
+ goto fail;
+#if NEWDB || NDBM || CDB
if (Verbose)
message("WARNING: cannot open alias database %s%s",
map->map_file,
mode == O_RDONLY ? "; reading text version" : "");
-#else /* defined(NEWDB) || defined(NDBM) */
+#else
if (mode != O_RDONLY)
usrerr("Cannot rebuild aliases: no database format defined");
-#endif /* defined(NEWDB) || defined(NDBM) */
+#endif
- if (mode == O_RDONLY)
- return stab_map_open(map, mode);
- else
- return false;
+ if (mode == O_RDONLY && stab_map_open(map, mode))
+ goto ok;
+
+ fail:
+ if (!wasopt)
+ map->map_mflags &= ~MF_OPTIONAL;
+ return false;
+
+ ok:
+ if (!wasopt)
+ map->map_mflags &= ~MF_OPTIONAL;
+ return true;
}
@@ -6180,7 +6635,15 @@ impl_map_close(map)
map->map_mflags &= ~MF_IMPL_NDBM;
}
#endif /* NDBM */
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ {
+ cdb_map_close(map);
+ map->map_mflags &= ~MF_IMPL_CDB;
+ }
+#endif /* CDB */
}
+
/*
** User map class.
**
@@ -6468,7 +6931,7 @@ seq_map_parse(map, ap)
STAB *s;
/* find beginning of map name */
- while (isascii(*ap) && isspace(*ap))
+ while (SM_ISSPACE(*ap))
ap++;
for (p = ap;
(isascii(*p) && isalnum(*p)) || *p == '_' || *p == '.';
@@ -6880,7 +7343,7 @@ regex_map_init(map, ap)
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -6929,7 +7392,7 @@ regex_map_init(map, ap)
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -7250,7 +7713,7 @@ nsd_map_lookup(map, name, av, statp)
if (r == NS_BADREQ
# ifdef NS_NOPERM
|| r == NS_NOPERM
-# endif /* NS_NOPERM */
+# endif
)
{
*statp = EX_CONFIG;
@@ -7459,11 +7922,88 @@ arpa_map_lookup(map, name, av, statp)
return rval;
}
+#if _FFR_SETDEBUG_MAP
+char *
+setdebug_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+
+ if (tTd(38, 2))
+ {
+ char **cpp;
+
+ sm_dprintf("setdebug_map_lookup: key '%s'\n", name);
+ for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
+ sm_dprintf("setdebug_map_lookup: arg '%s'\n", *cpp);
+ }
+ *statp = EX_OK;
+ tTflag(name);
+ return NULL;
+}
+#endif
+
+#if _FFR_SETOPT_MAP
+char *
+setopt_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+# if !_FFR_SETANYOPT
+ int val;
+# endif
+ char **cpp;
+
+ if (tTd(38, 2))
+ {
+ sm_dprintf("setopt_map_lookup: key '%s'\n", name);
+ for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
+ sm_dprintf("setopt_map_lookup: arg '%s'\n", *cpp);
+ }
+# if _FFR_SETANYOPT
+ /*
+ ** API screwed up...
+ ** first arg is the "short" name and second is the entire string...
+ */
+
+ sm_dprintf("setoption: name=%s\n", name);
+ setoption(' ', name, true, false, CurEnv);
+ *statp = EX_OK;
+ return NULL;
+# else /* _FFR_SETANYOPT */
+ *statp = EX_CONFIG;
+
+ cpp = av;
+ if (cpp == NULL || ++cpp == NULL || *cpp == NULL)
+ return NULL;
+ *statp = EX_OK;
+ errno = 0;
+ val = strtol(*cpp, NULL, 0);
+ /* check for valid number? */
+
+ /* use a table? */
+ if (sm_strcasecmp(name, "LogLevel") == 0)
+ {
+ LogLevel = val;
+ sm_dprintf("LogLevel=%d\n", val);
+ return NULL;
+ }
+# endif /* _FFR_SETANYOPT */
+ *statp = EX_CONFIG;
+ return NULL;
+}
+#endif
+
+
#if SOCKETMAP
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
# define socket_map_next map_stack[0]
@@ -7577,7 +8117,7 @@ socket_map_open(map, mode)
{
# ifdef EPROTONOSUPPORT
errno = EPROTONOSUPPORT;
-# else /* EPROTONOSUPPORT */
+# else
errno = EINVAL;
# endif /* EPROTONOSUPPORT */
syserr("socket map \"%s\": unknown socket type %s",
@@ -7642,10 +8182,10 @@ socket_map_open(map, mode)
if (false
# if NETINET
|| addr.sa.sa_family == AF_INET
-# endif /* NETINET */
+# endif
# if NETINET6
|| addr.sa.sa_family == AF_INET6
-# endif /* NETINET6 */
+# endif
)
{
unsigned short port;
@@ -7691,10 +8231,10 @@ socket_map_open(map, mode)
bool found = false;
# if NETINET
unsigned long hid = INADDR_NONE;
-# endif /* NETINET */
+# endif
# if NETINET6
struct sockaddr_in6 hid6;
-# endif /* NETINET6 */
+# endif
*end = '\0';
# if NETINET
@@ -7769,7 +8309,7 @@ socket_map_open(map, mode)
map->map_mname, at, hp->h_addrtype);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
}
@@ -7841,7 +8381,7 @@ socket_map_open(map, mode)
hp->h_addrtype);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
continue;
@@ -7855,7 +8395,7 @@ socket_map_open(map, mode)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
# if NETINET6
@@ -7979,6 +8519,7 @@ socket_map_lookup(map, name, av, statp)
int *statp;
{
unsigned int nettolen, replylen, recvlen;
+ int ret;
char *replybuf, *rval, *value, *status, *key;
SM_FILE_T *f;
char keybuf[MAXNAME + 1];
@@ -8017,13 +8558,20 @@ socket_map_lookup(map, name, av, statp)
goto errcl;
}
- if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1)
+ if ((ret = sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen)) != 1)
{
if (errno == EAGAIN)
{
syserr("451 4.3.0 socket_map_lookup(%s): read timeout",
map->map_mname);
}
+ else if (SM_IO_EOF == ret)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_INFO, CurEnv->e_id,
+ "socket_map_lookup(%s): EOF",
+ map->map_mname);
+ }
else
{
syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply %d",