diff options
Diffstat (limited to 'contrib/sendmail/src/map.c')
-rw-r--r-- | contrib/sendmail/src/map.c | 554 |
1 files changed, 409 insertions, 145 deletions
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c index 9a7bf7a..510b7c9 100644 --- a/contrib/sendmail/src/map.c +++ b/contrib/sendmail/src/map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: map.c,v 8.672 2006/04/18 01:26:41 ca Exp $") +SM_RCSID("@(#)$Id: map.c,v 8.696 2007/04/03 21:33:14 ca Exp $") #if LDAPMAP # include <sm/ldap.h> @@ -39,6 +39,8 @@ SM_RCSID("@(#)$Id: map.c,v 8.672 2006/04/18 01:26:41 ca Exp $") # endif /* NDBM */ #endif /* NIS */ +#include "map.h" + #if NEWDB # if DB_VERSION_MAJOR < 2 static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *)); @@ -659,6 +661,50 @@ map_close(s, bogus) } map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING); } + +#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) +extern int getdomainname(); + +/* this is mainly for backward compatibility in Sun environment */ +static char * +sun_init_domain() +{ + /* + ** Get the domain name from the kernel. + ** If it does not start with a leading dot, then remove + ** the first component. Since leading dots are funny Unix + ** files, we treat a leading "+" the same as a leading dot. + ** Finally, force there to be at least one dot in the domain name + ** (i.e. top-level domains are not allowed, like "com", must be + ** something like "sun.com"). + */ + + char buf[MAXNAME]; + char *period, *autodomain; + + if (getdomainname(buf, sizeof buf) < 0) + return NULL; + + if (buf[0] == '\0') + return NULL; + + if (tTd(0, 20)) + printf("domainname = %s\n", buf); + + if (buf[0] == '+') + buf[0] = '.'; + period = strchr(buf, '.'); + if (period == NULL) + autodomain = buf; + else + autodomain = period + 1; + if (strchr(autodomain, '.') == NULL) + return newstr(buf); + else + return newstr(autodomain); +} +#endif /* SUN_EXTENSIONS && SUN_INIT_DOMAIN */ + /* ** GETCANONNAME -- look up name using service switch ** @@ -687,6 +733,10 @@ getcanonname(host, hbsize, trymx, pttl) auto int status; char *maptype[MAXMAPSTACK]; short mapreturn[MAXMAPACTIONS]; +#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) + bool should_try_nis_domain = false; + static char *nis_domain = NULL; +#endif nmaps = switch_map_find("hosts", maptype, mapreturn); if (pttl != 0) @@ -706,12 +756,20 @@ getcanonname(host, hbsize, trymx, pttl) else if (strcmp("nis", maptype[mapno]) == 0) { found = nis_getcanonname(host, hbsize, &status); +# 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 /* NIS */ #if NISPLUS else if (strcmp("nisplus", maptype[mapno]) == 0) { found = nisplus_getcanonname(host, hbsize, &status); +# 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 /* NISPLUS */ #if NAMED_BIND @@ -744,6 +802,12 @@ getcanonname(host, hbsize, trymx, pttl) (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL)) break; +#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) + if (found) + should_try_nis_domain = true; + /* but don't break, as we need to try all methods first */ +#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ + /* see if we should continue */ if (status == EX_TEMPFAIL) { @@ -784,11 +848,33 @@ getcanonname(host, hbsize, trymx, pttl) (void) sm_strlcat(host, d, hbsize); } else + { +#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) + if (VendorCode == VENDOR_SUN && + should_try_nis_domain) + { + goto try_nis_domain; + } +#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ return false; + } } return true; } +#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) + if (VendorCode == VENDOR_SUN && should_try_nis_domain) + { + try_nis_domain: + if (nis_domain != NULL && + strlen(nis_domain) + strlen(host) + 1 < hbsize) + { + (void) sm_strlcat2(host, ".", nis_domain, hbsize); + return true; + } + } +#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ + if (tTd(38, 20)) sm_dprintf("getcanonname(%s), failed, status=%d\n", host, status); @@ -835,7 +921,7 @@ extract_canonname(name, dot, line, cbuf, cbuflen) { char nbuf[MAXNAME + 1]; - p = get_column(line, i, '\0', nbuf, sizeof nbuf); + p = get_column(line, i, '\0', nbuf, sizeof(nbuf)); if (p == NULL) break; if (*p == '\0') @@ -918,17 +1004,7 @@ dns_map_open(map, mode) ** false -- otherwise. */ -# if _FFR_DNSMAP_MULTILIMIT -# if !_FFR_DNSMAP_MULTI - ERROR README: You must define _FFR_DNSMAP_MULTI to use _FFR_DNSMAP_MULTILIMIT -# endif /* ! _FFR_DNSMAP_MULTI */ -# endif /* _FFR_DNSMAP_MULTILIMIT */ - -# if _FFR_DNSMAP_MULTI -# if _FFR_DNSMAP_MULTILIMIT -# define map_sizelimit map_lockfd /* overload field */ -# endif /* _FFR_DNSMAP_MULTILIMIT */ -# endif /* _FFR_DNSMAP_MULTI */ +#define map_sizelimit map_lockfd /* overload field */ struct dns_map { @@ -943,7 +1019,7 @@ dns_map_parseargs(map,args) register char *p = args; struct dns_map *map_p; - map_p = (struct dns_map *) xalloc(sizeof *map_p); + map_p = (struct dns_map *) xalloc(sizeof(*map_p)); map_p->dns_m_type = -1; map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; @@ -1016,7 +1092,6 @@ dns_map_parseargs(map,args) map->map_retry = atoi(p); break; -# if _FFR_DNSMAP_MULTI case 'z': if (*++p != '\\') map->map_coldelim = *p; @@ -1038,14 +1113,11 @@ dns_map_parseargs(map,args) } break; -# if _FFR_DNSMAP_MULTILIMIT case 'Z': while (isascii(*++p) && isspace(*p)) continue; map->map_sizelimit = atoi(p); break; -# endif /* _FFR_DNSMAP_MULTILIMIT */ -# endif /* _FFR_DNSMAP_MULTI */ /* Start of dns_map specific args */ case 'R': /* search field */ @@ -1066,7 +1138,6 @@ dns_map_parseargs(map,args) } break; -# if _FFR_DNSMAP_BASE case 'B': /* base domain */ { char *h; @@ -1087,8 +1158,6 @@ dns_map_parseargs(map,args) *h = ' '; } break; -# endif /* _FFR_DNSMAP_BASE */ - } while (*p != '\0' && !(isascii(*p) && isspace(*p))) p++; @@ -1103,7 +1172,7 @@ dns_map_parseargs(map,args) map->map_tapp = newstr(map->map_tapp); /* - ** Assumption: assert(sizeof int <= sizeof(ARBPTR_T)); + ** Assumption: assert(sizeof(int) <= sizeof(ARBPTR_T)); ** Even if this assumption is wrong, we use only one byte, ** so it doesn't really matter. */ @@ -1133,11 +1202,7 @@ dns_map_lookup(map, name, av, statp) char **av; int *statp; { -# if _FFR_DNSMAP_MULTI -# if _FFR_DNSMAP_MULTILIMIT int resnum = 0; -# endif /* _FFR_DNSMAP_MULTILIMIT */ -# endif /* _FFR_DNSMAP_MULTI */ char *vp = NULL, *result = NULL; size_t vsize; struct dns_map *map_p; @@ -1152,7 +1217,6 @@ dns_map_lookup(map, name, av, statp) map->map_mname, name); map_p = (struct dns_map *)(map->map_db1); -# if _FFR_DNSMAP_BASE if (map->map_file != NULL && *map->map_file != '\0') { size_t len; @@ -1171,7 +1235,6 @@ dns_map_lookup(map, name, av, statp) sm_free(appdomain); } else -# endif /* _FFR_DNSMAP_BASE */ { r = dns_lookup_int(name, C_IN, map_p->dns_m_type, map->map_timeout, map->map_retry); @@ -1232,7 +1295,7 @@ dns_map_lookup(map, name, av, statp) case T_AAAA: type = "T_AAAA"; value = anynet_ntop(rr->rr_u.rr_aaaa, buf6, - sizeof buf6); + sizeof(buf6)); break; # endif /* NETINET6 */ } @@ -1263,12 +1326,9 @@ dns_map_lookup(map, name, av, statp) type != NULL ? type : "<UNKNOWN>", rr->rr_type, value != NULL ? value : "<NO VALUE>"); -# if _FFR_DNSMAP_MULTI if (value != NULL && (map->map_coldelim == '\0' || -# if _FFR_DNSMAP_MULTILIMIT map->map_sizelimit == 1 || -# endif /* _FFR_DNSMAP_MULTILIMIT */ bitset(MF_MATCHONLY, map->map_mflags))) { /* Only care about the first match */ @@ -1292,16 +1352,10 @@ dns_map_lookup(map, name, av, statp) vp, map->map_coldelim, value); sm_free(vp); vp = new; -# if _FFR_DNSMAP_MULTILIMIT if (map->map_sizelimit > 0 && ++resnum >= map->map_sizelimit) break; -# endif /* _FFR_DNSMAP_MULTILIMIT */ } -# else /* _FFR_DNSMAP_MULTI */ - vp = value; - break; -# endif /* _FFR_DNSMAP_MULTI */ } if (vp == NULL) { @@ -1312,10 +1366,8 @@ dns_map_lookup(map, name, av, statp) goto cleanup; } -# if _FFR_DNSMAP_MULTI /* Cleanly truncate for rulesets */ truncate_at_delim(vp, PSBUFSIZE / 2, map->map_coldelim); -# endif /* _FFR_DNSMAP_MULTI */ vsize = strlen(vp); @@ -1328,10 +1380,8 @@ dns_map_lookup(map, name, av, statp) result = map_rewrite(map, vp, vsize, av); cleanup: -# if _FFR_DNSMAP_MULTI if (vp != NULL) sm_free(vp); -# endif /* _FFR_DNSMAP_MULTI */ if (r != NULL) dns_free_data(r); return result; @@ -1373,10 +1423,10 @@ ndbm_map_open(map, mode) mode &= O_ACCMODE; /* do initial file and directory checks */ - if (sm_strlcpyn(dirfile, sizeof dirfile, 2, - map->map_file, ".dir") >= sizeof dirfile || - sm_strlcpyn(pagfile, sizeof pagfile, 2, - map->map_file, ".pag") >= sizeof pagfile) + if (sm_strlcpyn(dirfile, sizeof(dirfile), 2, + map->map_file, ".dir") >= sizeof(dirfile) || + sm_strlcpyn(pagfile, sizeof(pagfile), 2, + map->map_file, ".pag") >= sizeof(pagfile)) { errno = 0; if (!bitset(MF_OPTIONAL, map->map_mflags)) @@ -1632,8 +1682,8 @@ ndbm_map_lookup(map, name, av, statp) key.dsize = strlen(name); if (!bitset(MF_NOFOLDCASE, map->map_mflags)) { - if (key.dsize > sizeof keybuf - 1) - key.dsize = sizeof keybuf - 1; + if (key.dsize > sizeof(keybuf) - 1) + key.dsize = sizeof(keybuf) - 1; memmove(keybuf, key.dptr, key.dsize); keybuf[key.dsize] = '\0'; makelower(keybuf); @@ -1729,8 +1779,8 @@ ndbm_map_store(map, lhs, rhs) key.dptr = lhs; if (!bitset(MF_NOFOLDCASE, map->map_mflags)) { - if (key.dsize > sizeof keybuf - 1) - key.dsize = sizeof keybuf - 1; + if (key.dsize > sizeof(keybuf) - 1) + key.dsize = sizeof(keybuf) - 1; memmove(keybuf, key.dptr, key.dsize); keybuf[key.dsize] = '\0'; makelower(keybuf); @@ -1814,10 +1864,10 @@ ndbm_map_close(map) map->map_mflags |= MF_NOFOLDCASE; - (void) sm_snprintf(buf, sizeof buf, "%010ld", curtime()); + (void) sm_snprintf(buf, sizeof(buf), "%010ld", curtime()); ndbm_map_store(map, "YP_LAST_MODIFIED", buf); - (void) gethostname(buf, sizeof buf); + (void) gethostname(buf, sizeof(buf)); ndbm_map_store(map, "YP_MASTER_NAME", buf); map->map_mflags = save_mflags; @@ -1890,7 +1940,7 @@ bt_map_open(map, mode) map->map_mname, map->map_file, mode); # if DB_VERSION_MAJOR < 3 - memset(&btinfo, '\0', sizeof btinfo); + memset(&btinfo, '\0', sizeof(btinfo)); # ifdef DB_CACHE_SIZE btinfo.db_cachesize = DB_CACHE_SIZE; # endif /* DB_CACHE_SIZE */ @@ -1919,7 +1969,7 @@ hash_map_open(map, mode) map->map_mname, map->map_file, mode); # if DB_VERSION_MAJOR < 3 - memset(&hinfo, '\0', sizeof hinfo); + memset(&hinfo, '\0', sizeof(hinfo)); # ifdef DB_HASH_NELEM hinfo.h_nelem = DB_HASH_NELEM; # endif /* DB_HASH_NELEM */ @@ -1958,7 +2008,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) char buf[MAXPATHLEN]; /* do initial file and directory checks */ - if (sm_strlcpy(buf, map->map_file, sizeof buf) >= sizeof buf) + if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf)) { errno = 0; if (!bitset(MF_OPTIONAL, map->map_mflags)) @@ -1969,7 +2019,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) i = strlen(buf); if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) { - if (sm_strlcat(buf, ".db", sizeof buf) >= sizeof buf) + if (sm_strlcat(buf, ".db", sizeof(buf)) >= sizeof(buf)) { errno = 0; if (!bitset(MF_OPTIONAL, map->map_mflags)) @@ -2258,14 +2308,14 @@ db_map_lookup(map, name, av, statp) char keybuf[MAXNAME + 1]; char buf[MAXPATHLEN]; - memset(&key, '\0', sizeof key); - memset(&val, '\0', sizeof val); + memset(&key, '\0', sizeof(key)); + memset(&val, '\0', sizeof(val)); if (tTd(38, 20)) sm_dprintf("db_map_lookup(%s, %s)\n", map->map_mname, name); - if (sm_strlcpy(buf, map->map_file, sizeof buf) >= sizeof buf) + if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf)) { errno = 0; if (!bitset(MF_OPTIONAL, map->map_mflags)) @@ -2278,8 +2328,8 @@ db_map_lookup(map, name, av, statp) buf[i - 3] = '\0'; key.size = strlen(name); - if (key.size > sizeof keybuf - 1) - key.size = sizeof keybuf - 1; + if (key.size > sizeof(keybuf) - 1) + key.size = sizeof(keybuf) - 1; key.data = keybuf; memmove(keybuf, name, key.size); keybuf[key.size] = '\0'; @@ -2417,8 +2467,8 @@ db_map_store(map, lhs, rhs) register DB *db = map->map_db2; char keybuf[MAXNAME + 1]; - memset(&key, '\0', sizeof key); - memset(&data, '\0', sizeof data); + memset(&key, '\0', sizeof(key)); + memset(&data, '\0', sizeof(data)); if (tTd(38, 12)) sm_dprintf("db_map_store(%s, %s, %s)\n", @@ -2428,8 +2478,8 @@ db_map_store(map, lhs, rhs) key.data = lhs; if (!bitset(MF_NOFOLDCASE, map->map_mflags)) { - if (key.size > sizeof keybuf - 1) - key.size = sizeof keybuf - 1; + if (key.size > sizeof(keybuf) - 1) + key.size = sizeof(keybuf) - 1; memmove(keybuf, key.data, key.size); keybuf[key.size] = '\0'; makelower(keybuf); @@ -2474,7 +2524,7 @@ db_map_store(map, lhs, rhs) static int bufsiz = 0; DBT old; - memset(&old, '\0', sizeof old); + memset(&old, '\0', sizeof(old)); old.data = db_map_lookup(map, key.data, (char **) NULL, &status); @@ -2688,8 +2738,8 @@ nis_map_lookup(map, name, av, statp) map->map_mname, name); buflen = strlen(name); - if (buflen > sizeof keybuf - 1) - buflen = sizeof keybuf - 1; + if (buflen > sizeof(keybuf) - 1) + buflen = sizeof(keybuf) - 1; memmove(keybuf, name, buflen); keybuf[buflen] = '\0'; if (!bitset(MF_NOFOLDCASE, map->map_mflags)) @@ -2757,7 +2807,7 @@ nis_getcanonname(name, hbsize, statp) if (tTd(38, 20)) sm_dprintf("nis_getcanonname(%s)\n", name); - if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf) + if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) { *statp = EX_UNAVAILABLE; return false; @@ -2798,14 +2848,14 @@ nis_getcanonname(name, hbsize, statp) sm_free(vp); return false; } - (void) sm_strlcpy(host_record, vp, sizeof host_record); + (void) sm_strlcpy(host_record, vp, sizeof(host_record)); sm_free(vp); if (tTd(38, 44)) sm_dprintf("got record `%s'\n", host_record); vp = strpbrk(host_record, "#\n"); if (vp != NULL) *vp = '\0'; - if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof cbuf)) + if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof(cbuf))) { /* this should not happen, but.... */ *statp = EX_NOHOST; @@ -2877,12 +2927,12 @@ nisplus_map_open(map, mode) if (!PARTIAL_NAME(map->map_file)) { map->map_domain = newstr(""); - (void) sm_strlcpy(qbuf, map->map_file, sizeof qbuf); + (void) sm_strlcpy(qbuf, map->map_file, sizeof(qbuf)); } else { /* check to see if this map actually exists */ - (void) sm_strlcpyn(qbuf, sizeof qbuf, 3, + (void) sm_strlcpyn(qbuf, sizeof(qbuf), 3, map->map_file, ".", map->map_domain); } @@ -3021,7 +3071,7 @@ nisplus_map_lookup(map, name, av, statp) ** NIS+ parser choke on them. */ - skleft = sizeof search_key - 4; + skleft = sizeof(search_key) - 4; skp = search_key; for (p = name; *p != '\0' && skleft > 0; p++) { @@ -3054,11 +3104,11 @@ nisplus_map_lookup(map, name, av, statp) /* construct the query */ if (PARTIAL_NAME(map->map_file)) - (void) sm_snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s", + (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s.%s", map->map_keycolnm, search_key, map->map_file, map->map_domain); else - (void) sm_snprintf(qbuf, sizeof qbuf, "[%s=%s],%s", + (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s", map->map_keycolnm, search_key, map->map_file); if (tTd(38, 20)) @@ -3135,7 +3185,7 @@ nisplus_getcanonname(name, hbsize, statp) char nbuf[MAXNAME + 1]; char qbuf[MAXLINE + NIS_MAXNAMELEN]; - if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf) + if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) { *statp = EX_UNAVAILABLE; return false; @@ -3146,14 +3196,14 @@ nisplus_getcanonname(name, hbsize, statp) if (p == NULL) { /* single token */ - (void) sm_snprintf(qbuf, sizeof qbuf, + (void) sm_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'; - (void) sm_snprintf(qbuf, sizeof qbuf, + (void) sm_snprintf(qbuf, sizeof(qbuf), "[name=%s],hosts.org_dir.%s", nbuf, &p[1]); } else @@ -3247,7 +3297,7 @@ nisplus_default_domain() return default_domain; p = nis_local_directory(); - (void) sm_strlcpy(default_domain, p, sizeof default_domain); + (void) sm_strlcpy(default_domain, p, sizeof(default_domain)); return default_domain; } @@ -3318,6 +3368,15 @@ ldapmap_open(map, mode) if (tTd(38, 2)) sm_dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode); +#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \ + HASLDAPGETALIASBYNAME + if (VendorCode == VENDOR_SUN && + strcmp(map->map_mname, "aliases.ldap") == 0) + { + return true; + } +#endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */ + mode &= O_ACCMODE; /* sendmail doesn't have the ability to write to LDAP (yet) */ @@ -3471,6 +3530,9 @@ sunet_id_hash(str) *p_last = '\0'; return str; } +# define SM_CONVERT_ID(str) sunet_id_hash(str) +# else /* SUNET_ID */ +# define SM_CONVERT_ID(str) makelower(str) # endif /* SUNET_ID */ /* @@ -3485,6 +3547,7 @@ ldapmap_lookup(map, name, av, statp) int *statp; { int flags; + int i; int plen = 0; int psize = 0; int msgid; @@ -3493,39 +3556,122 @@ ldapmap_lookup(map, name, av, statp) char *result = NULL; SM_RPOOL_T *rpool; SM_LDAP_STRUCT *lmap = NULL; + char *argv[SM_LDAP_ARGS]; 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 */ - if (tTd(38, 20)) - sm_dprintf("ldapmap_lookup(%s, %s)\n", map->map_mname, name); +#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \ + HASLDAPGETALIASBYNAME + if (VendorCode == VENDOR_SUN && + strcmp(map->map_mname, "aliases.ldap") == 0) + { + char answer[MAXNAME + 1]; + int rc; + + rc = __getldapaliasbyname(name, answer, sizeof(answer)); + if (rc != 0) + { + if (tTd(38, 20)) + sm_dprintf("getldapaliasbyname(%.100s) failed, errno=%d\n", + name, errno); + *statp = EX_NOTFOUND; + return NULL; + } + *statp = EX_OK; + if (tTd(38, 20)) + sm_dprintf("getldapaliasbyname(%.100s) => %s\n", name, + answer); + if (bitset(MF_MATCHONLY, map->map_mflags)) + result = map_rewrite(map, name, strlen(name), NULL); + else + result = map_rewrite(map, answer, strlen(answer), av); + return result; + } +#endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */ /* Get ldap struct pointer from map */ lmap = (SM_LDAP_STRUCT *) map->map_db1; sm_ldap_setopts(lmap->ldap_ld, lmap); - (void) sm_strlcpy(keybuf, name, sizeof keybuf); + if (lmap->ldap_multi_args) + { + SM_REQUIRE(av != NULL); + memset(argv, '\0', sizeof(argv)); + for (i = 0; i < SM_LDAP_ARGS && av[i] != NULL; i++) + { + argv[i] = sm_strdup(av[i]); + if (argv[i] == NULL) + { + int save_errno, j; + + save_errno = errno; + for (j = 0; j < i && argv[j] != NULL; j++) + SM_FREE(argv[j]); + *statp = EX_TEMPFAIL; + errno = save_errno; + return NULL; + } - if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + SM_CONVERT_ID(av[i]); + } + } + else { -# ifdef SUNET_ID - sunet_id_hash(keybuf); -# else /* SUNET_ID */ - makelower(keybuf); -# endif /* SUNET_ID */ + (void) sm_strlcpy(keybuf, name, sizeof(keybuf)); + + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + SM_CONVERT_ID(keybuf); + } + + if (tTd(38, 20)) + { + if (lmap->ldap_multi_args) + { + sm_dprintf("ldapmap_lookup(%s, argv)\n", + map->map_mname); + for (i = 0; i < SM_LDAP_ARGS; i++) + { + sm_dprintf(" argv[%d] = %s\n", i, + argv[i] == NULL ? "NULL" : argv[i]); + } + } + else + { + sm_dprintf("ldapmap_lookup(%s, %s)\n", + map->map_mname, name); + } } - msgid = sm_ldap_search(lmap, keybuf); - if (msgid == -1) + if (lmap->ldap_multi_args) + { + msgid = sm_ldap_search_m(lmap, argv); + + /* free the argv array and its content, no longer needed */ + for (i = 0; i < SM_LDAP_ARGS && argv[i] != NULL; i++) + SM_FREE(argv[i]); + } + else + msgid = sm_ldap_search(lmap, keybuf); + if (msgid == SM_LDAP_ERR) { errno = sm_ldap_geterrno(lmap->ldap_ld) + E_LDAPBASE; save_errno = errno; if (!bitset(MF_OPTIONAL, map->map_mflags)) { + /* + ** Do not include keybuf as this error may be shown + ** to outsiders. + */ + if (bitset(MF_NODEFER, map->map_mflags)) - syserr("Error in ldap_search using %s in map %s", - keybuf, map->map_mname); + syserr("Error in ldap_search in map %s", + map->map_mname); else - syserr("451 4.3.5 Error in ldap_search using %s in map %s", - keybuf, map->map_mname); + syserr("451 4.3.5 Error in ldap_search in map %s", + map->map_mname); } *statp = EX_TEMPFAIL; switch (save_errno - E_LDAPBASE) @@ -3542,6 +3688,19 @@ ldapmap_lookup(map, name, av, statp) errno = save_errno; return NULL; } +#if SM_LDAP_ERROR_ON_MISSING_ARGS + else if (msgid == SM_LDAP_ERR_ARG_MISS) + { + if (bitset(MF_NODEFER, map->map_mflags)) + syserr("Error in ldap_search in map %s, too few arguments", + map->map_mname); + else + syserr("554 5.3.5 Error in ldap_search in map %s, too few arguments", + map->map_mname); + *statp = EX_CONFIG; + return NULL; + } +#endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */ *statp = EX_NOTFOUND; vp = NULL; @@ -3722,7 +3881,7 @@ ldapmap_parseargs(map, args) if (lmap == NULL || lmap != LDAPDefaults) { /* We need to alloc an SM_LDAP_STRUCT struct */ - lmap = (SM_LDAP_STRUCT *) xalloc(sizeof *lmap); + lmap = (SM_LDAP_STRUCT *) xalloc(sizeof(*lmap)); if (LDAPDefaults == NULL) sm_ldap_clear(lmap); else @@ -3746,11 +3905,11 @@ ldapmap_parseargs(map, args) char lcbuf[MAXLINE]; /* Get $j */ - expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope); + expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope); if (jbuf[0] == '\0') { (void) sm_strlcpy(jbuf, "localhost", - sizeof jbuf); + sizeof(jbuf)); } lc = macvalue(macid("{sendmailMTACluster}"), CurEnv); @@ -3758,14 +3917,14 @@ ldapmap_parseargs(map, args) lc = ""; else { - expand(lc, lcbuf, sizeof lcbuf, CurEnv); + expand(lc, lcbuf, sizeof(lcbuf), CurEnv); lc = lcbuf; } - n = sm_snprintf(ldapfilt, sizeof ldapfilt, + n = sm_snprintf(ldapfilt, sizeof(ldapfilt), "(&(objectClass=sendmailMTAAliasObject)(sendmailMTAAliasGrouping=aliases)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))(sendmailMTAKey=%%0))", lc, jbuf); - if (n >= sizeof ldapfilt) + if (n >= sizeof(ldapfilt)) { syserr("%s: Default LDAP string too long", map->map_mname); @@ -4138,6 +4297,10 @@ ldapmap_parseargs(map, args) # endif /* LDAP_VERSION_MIN */ break; + case 'K': + lmap->ldap_multi_args = true; + break; + default: syserr("Illegal option %c map %s", *p, map->map_mname); break; @@ -4228,7 +4391,7 @@ ldapmap_parseargs(map, args) ldapmap_dequote(lmap->ldap_secret)); return false; } - lmap->ldap_secret = sfgets(m_tmp, sizeof m_tmp, + lmap->ldap_secret = sfgets(m_tmp, sizeof(m_tmp), sfd, TimeOuts.to_fileopen, "ldapmap_parseargs"); (void) sm_io_close(sfd, SM_TIME_DEFAULT); @@ -4257,7 +4420,7 @@ ldapmap_parseargs(map, args) ** stashed */ - (void) sm_snprintf(m_tmp, sizeof m_tmp, + (void) sm_snprintf(m_tmp, sizeof(m_tmp), "KRBTKFILE=%s", ldapmap_dequote(lmap->ldap_secret)); lmap->ldap_secret = m_tmp; @@ -4481,10 +4644,10 @@ ldapmap_set_defaults(spec) /* Allocate and set the default values */ if (LDAPDefaults == NULL) - LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof *LDAPDefaults); + LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof(*LDAPDefaults)); sm_ldap_clear(LDAPDefaults); - memset(&map, '\0', sizeof map); + memset(&map, '\0', sizeof(map)); /* look up the class */ class = stab("ldap", ST_MAPCLASS, ST_FIND); @@ -4535,7 +4698,7 @@ ldapmap_set_defaults(spec) /* ** Support for the CCSO Nameserver (ph/qi). ** This code is intended to replace the so-called "ph mailer". -** Contributed by Mark D. Roth <roth@uiuc.edu>. Contact him for support. +** Contributed by Mark D. Roth. Contact him for support. */ /* what version of the ph map code we're running */ @@ -4572,11 +4735,11 @@ ph_map_parseargs(map, args) PH_MAP_STRUCT *pmap = NULL; /* initialize version string */ - (void) sm_snprintf(phmap_id, sizeof phmap_id, + (void) sm_snprintf(phmap_id, sizeof(phmap_id), "sendmail-%s phmap-20010529 libphclient-%s", Version, libphclient_version); - pmap = (PH_MAP_STRUCT *) xalloc(sizeof *pmap); + pmap = (PH_MAP_STRUCT *) xalloc(sizeof(*pmap)); /* defaults */ pmap->ph_servers = NULL; @@ -4961,6 +5124,7 @@ ph_map_lookup(map, key, args, pstat) return NULL; } #endif /* PH_MAP */ + /* ** syslog map */ @@ -5099,6 +5263,99 @@ syslog_map_lookup(map, string, args, statp) return ""; } +#if _FFR_DPRINTF_MAP +/* +** dprintf map +*/ + +#define map_dbg_level map_lockfd /* overload field */ + +/* +** DPRINTF_MAP_PARSEARGS -- check for priority level to dprintf messages. +*/ + +bool +dprintf_map_parseargs(map, args) + MAP *map; + char *args; +{ + char *p = args; + char *dbg_level = NULL; + + /* there is no check whether there is really an argument */ + while (*p != '\0') + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + ++p; + if (*p == 'D') + { + map->map_mflags |= MF_DEFER; + ++p; + } + else if (*p == 'S') + { + map->map_spacesub = *++p; + if (*p != '\0') + p++; + } + else if (*p == 'd') + { + while (*++p != '\0' && isascii(*p) && isspace(*p)) + continue; + if (*p == '\0') + break; + dbg_level = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + } + else + { + syserr("Illegal option %c map dprintf", *p); + ++p; + } + } + + if (dbg_level == NULL) + map->map_dbg_level = 0; + else + { + if (!(isascii(*dbg_level) && isdigit(*dbg_level))) + { + syserr("dprintf map \"%s\", file %s: -d should specify a number, not %s", + map->map_mname, map->map_file, + dbg_level); + return false; + } + map->map_dbg_level = atoi(dbg_level); + } + return true; +} + +/* +** DPRINTF_MAP_LOOKUP -- rewrite and print message. Always return empty string +*/ + +char * +dprintf_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 && tTd(85, map->map_dbg_level)) + sm_dprintf("%s\n", ptr); + *statp = EX_OK; + return ""; +} +#endif /* _FFR_DPRINTF_MAP */ + /* ** HESIOD Modules */ @@ -5166,12 +5423,12 @@ hes_map_lookup(map, name, av, statp) char nbuf[MAXNAME]; nl = strlen(name); - if (nl < sizeof nbuf - 1) + if (nl < sizeof(nbuf) - 1) np = nbuf; else np = xalloc(strlen(name) + 2); np[0] = '\\'; - (void) sm_strlcpy(&np[1], name, (sizeof nbuf) - 1); + (void) sm_strlcpy(&np[1], name, (sizeof(nbuf)) - 1); # ifdef HESIOD_INIT hp = hesiod_resolve(HesiodContext, np, map->map_file); # else /* HESIOD_INIT */ @@ -5352,7 +5609,7 @@ ni_getcanonname(name, hbsize, statp) if (tTd(38, 20)) sm_dprintf("ni_getcanonname(%s)\n", name); - if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf) + if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) { *statp = EX_UNAVAILABLE; return false; @@ -5527,8 +5784,8 @@ text_map_lookup(map, name, av, statp) sm_dprintf("text_map_lookup(%s, %s)\n", map->map_mname, name); buflen = strlen(name); - if (buflen > sizeof search_key - 1) - buflen = sizeof search_key - 1; /* XXX just cut if off? */ + if (buflen > sizeof(search_key) - 1) + buflen = sizeof(search_key) - 1; /* XXX just cut if off? */ memmove(search_key, name, buflen); search_key[buflen] = '\0'; if (!bitset(MF_NOFOLDCASE, map->map_mflags)) @@ -5544,7 +5801,7 @@ text_map_lookup(map, name, av, statp) key_idx = map->map_keycolno; delim = map->map_coldelim; while (sm_io_fgets(f, SM_TIME_DEFAULT, - linebuf, sizeof linebuf) != NULL) + linebuf, sizeof(linebuf)) != NULL) { char *p; @@ -5554,7 +5811,7 @@ text_map_lookup(map, name, av, statp) p = strchr(linebuf, '\n'); if (p != NULL) *p = '\0'; - p = get_column(linebuf, key_idx, delim, buf, sizeof buf); + p = get_column(linebuf, key_idx, delim, buf, sizeof(buf)); if (p != NULL && sm_strcasecmp(search_key, p) == 0) { found_it = true; @@ -5567,7 +5824,7 @@ text_map_lookup(map, name, av, statp) *statp = EX_NOTFOUND; return NULL; } - vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof buf); + vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof(buf)); if (vp == NULL) { *statp = EX_NOTFOUND; @@ -5601,7 +5858,7 @@ text_getcanonname(name, hbsize, statp) if (tTd(38, 20)) sm_dprintf("text_getcanonname(%s)\n", name); - if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf) + if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) { *statp = EX_UNAVAILABLE; return false; @@ -5618,7 +5875,7 @@ text_getcanonname(name, hbsize, statp) found = false; while (!found && sm_io_fgets(f, SM_TIME_DEFAULT, - linebuf, sizeof linebuf) != NULL) + linebuf, sizeof(linebuf)) != NULL) { char *p = strpbrk(linebuf, "#\n"); @@ -5626,7 +5883,7 @@ text_getcanonname(name, hbsize, statp) *p = '\0'; if (linebuf[0] != '\0') found = extract_canonname(nbuf, dot, linebuf, - cbuf, sizeof cbuf); + cbuf, sizeof(cbuf)); } (void) sm_io_close(f, SM_TIME_DEFAULT); if (!found) @@ -5970,13 +6227,13 @@ user_map_lookup(map, key, av, statp) break; case 3: - (void) sm_snprintf(buf, sizeof buf, "%d", + (void) sm_snprintf(buf, sizeof(buf), "%d", (int) user.mbdb_uid); rwval = buf; break; case 4: - (void) sm_snprintf(buf, sizeof buf, "%d", + (void) sm_snprintf(buf, sizeof(buf), "%d", (int) user.mbdb_gid); rwval = buf; break; @@ -6033,7 +6290,7 @@ prog_map_lookup(map, name, av, statp) argv[i++] = map->map_file; if (map->map_rebuild != NULL) { - (void) sm_strlcpy(buf, map->map_rebuild, sizeof buf); + (void) sm_strlcpy(buf, map->map_rebuild, sizeof(buf)); for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t")) { if (i >= MAXPV - 1) @@ -6064,7 +6321,7 @@ prog_map_lookup(map, name, av, statp) *statp = EX_OSFILE; return NULL; } - i = read(fd, buf, sizeof buf - 1); + i = read(fd, buf, sizeof(buf) - 1); if (i < 0) { syserr("prog_map_lookup(%s): read error %s", @@ -6092,7 +6349,7 @@ prog_map_lookup(map, name, av, statp) rval = map_rewrite(map, buf, strlen(buf), av); /* now flush any additional output */ - while ((i = read(fd, buf, sizeof buf)) > 0) + while ((i = read(fd, buf, sizeof(buf))) > 0) continue; } @@ -6239,7 +6496,7 @@ switch_map_open(map, mode) if (maptype[mapno] == NULL) continue; - (void) sm_strlcpyn(nbuf, sizeof nbuf, 3, + (void) sm_strlcpyn(nbuf, sizeof(nbuf), 3, map->map_mname, ".", maptype[mapno]); s = stab(nbuf, ST_MAP, ST_FIND); if (s == NULL) @@ -6561,7 +6818,7 @@ regex_map_init(map, ap) pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB; p = ap; - map_p = (struct regex_map *) xnalloc(sizeof *map_p); + map_p = (struct regex_map *) xnalloc(sizeof(*map_p)); map_p->regex_pattern_buf = (regex_t *)xnalloc(sizeof(regex_t)); for (;;) @@ -6629,7 +6886,7 @@ regex_map_init(map, ap) char errbuf[ERRBUF_SIZE]; (void) regerror(regerr, map_p->regex_pattern_buf, - errbuf, sizeof errbuf); + errbuf, sizeof(errbuf)); syserr("pattern-compile-error: %s", errbuf); sm_free(map_p->regex_pattern_buf); /* XXX */ sm_free(map_p); /* XXX */ @@ -6884,10 +7141,10 @@ ns_map_t_find(mapname) /* if we are looking at a NULL ns_map_list_t, then create a new one */ if (ns_map == NULL) { - ns_map = (ns_map_list_t *) xalloc(sizeof *ns_map); + ns_map = (ns_map_list_t *) xalloc(sizeof(*ns_map)); ns_map->mapname = newstr(mapname); - ns_map->map = (ns_map_t *) xalloc(sizeof *ns_map->map); - memset(ns_map->map, '\0', sizeof *ns_map->map); + ns_map->map = (ns_map_t *) xalloc(sizeof(*ns_map->map)); + memset(ns_map->map, '\0', sizeof(*ns_map->map)); ns_map->next = ns_maps; ns_maps = ns_map; } @@ -6911,8 +7168,8 @@ nsd_map_lookup(map, name, av, statp) sm_dprintf("nsd_map_lookup(%s, %s)\n", map->map_mname, name); buflen = strlen(name); - if (buflen > sizeof keybuf - 1) - buflen = sizeof keybuf - 1; /* XXX simply cut off? */ + if (buflen > sizeof(keybuf) - 1) + buflen = sizeof(keybuf) - 1; /* XXX simply cut off? */ memmove(keybuf, name, buflen); keybuf[buflen] = '\0'; if (!bitset(MF_NOFOLDCASE, map->map_mflags)) @@ -6927,7 +7184,7 @@ nsd_map_lookup(map, name, av, statp) return NULL; } r = ns_lookup(ns_map, NULL, map->map_file, keybuf, NULL, - buf, sizeof buf); + buf, sizeof(buf)); if (r == NS_UNAVAIL || r == NS_TRYAGAIN) { *statp = EX_TEMPFAIL; @@ -7038,6 +7295,13 @@ arith_map_lookup(map, name, av, statp) boolres = true; break; + case 'r': + r = v[1] - v[0] + 1; + if (r <= 0) + return NULL; + r = get_random() % r + v[0]; + break; + default: /* XXX */ *statp = EX_CONFIG; @@ -7048,10 +7312,10 @@ arith_map_lookup(map, name, av, statp) return NULL; } if (boolres) - (void) sm_snprintf(result, sizeof result, + (void) sm_snprintf(result, sizeof(result), res ? "TRUE" : "FALSE"); else - (void) sm_snprintf(result, sizeof result, "%ld", r); + (void) sm_snprintf(result, sizeof(result), "%ld", r); return result; } *statp = EX_CONFIG; @@ -7129,7 +7393,7 @@ socket_map_open(map, mode) /* XXX It should be put in a library... */ /* protocol:filename or protocol:port@host */ - memset(&addr, '\0', sizeof addr); + memset(&addr, '\0', sizeof(addr)); p = map->map_file; colon = strchr(p, ':'); if (colon != NULL) @@ -7213,7 +7477,7 @@ socket_map_open(map, mode) long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; at = colon; - if (strlen(colon) >= sizeof addr.sunix.sun_path) + if (strlen(colon) >= sizeof(addr.sunix.sun_path)) { syserr("socket map \"%s\": local socket name %s too long", map->map_mname, colon); @@ -7231,8 +7495,8 @@ socket_map_open(map, mode) } (void) sm_strlcpy(addr.sunix.sun_path, colon, - sizeof addr.sunix.sun_path); - addrlen = sizeof (struct sockaddr_un); + sizeof(addr.sunix.sun_path)); + addrlen = sizeof(struct sockaddr_un); } else # endif /* NETUNIX */ @@ -7305,7 +7569,7 @@ socket_map_open(map, mode) } # endif /* NETINET */ # if NETINET6 - (void) memset(&hid6, '\0', sizeof hid6); + (void) memset(&hid6, '\0', sizeof(hid6)); if (addr.sa.sa_family == AF_INET6 && anynet_pton(AF_INET6, &at[1], &hid6.sin6_addr) == 1) @@ -7347,7 +7611,7 @@ socket_map_open(map, mode) memmove(&addr.sin.sin_addr, hp->h_addr, INADDRSZ); addr.sin.sin_port = port; - addrlen = sizeof (struct sockaddr_in); + addrlen = sizeof(struct sockaddr_in); addrno = 1; break; # endif /* NETINET */ @@ -7357,7 +7621,7 @@ socket_map_open(map, mode) memmove(&addr.sin6.sin6_addr, hp->h_addr, IN6ADDRSZ); addr.sin6.sin6_port = port; - addrlen = sizeof (struct sockaddr_in6); + addrlen = sizeof(struct sockaddr_in6); addrno = 1; break; # endif /* NETINET6 */ @@ -7584,8 +7848,8 @@ socket_map_lookup(map, name, av, statp) if (!bitset(MF_NOFOLDCASE, map->map_mflags)) { nettolen = strlen(name); - if (nettolen > sizeof keybuf - 1) - nettolen = sizeof keybuf - 1; + if (nettolen > sizeof(keybuf) - 1) + nettolen = sizeof(keybuf) - 1; memmove(keybuf, name, nettolen); keybuf[nettolen] = '\0'; makelower(keybuf); |