📄 conf.c
字号:
dequote_map, null_map_store);
#ifdef MAP_REGEX
MAPDEF("regex", NULL, 0,
regex_map_init, null_map_open, null_map_close,
regex_map_lookup, null_map_store);
#endif /* MAP_REGEX */
#if USERDB
/* user database */
MAPDEF("userdb", ".db", 0,
map_parseargs, null_map_open, null_map_close,
udb_map_lookup, null_map_store);
#endif /* USERDB */
/* arbitrary programs */
MAPDEF("program", NULL, MCF_ALIASOK,
map_parseargs, null_map_open, null_map_close,
prog_map_lookup, null_map_store);
/* sequenced maps */
MAPDEF("sequence", NULL, MCF_ALIASOK,
seq_map_parse, null_map_open, null_map_close,
seq_map_lookup, seq_map_store);
/* switched interface to sequenced maps */
MAPDEF("switch", NULL, MCF_ALIASOK,
map_parseargs, switch_map_open, null_map_close,
seq_map_lookup, seq_map_store);
/* null map lookup -- really for internal use only */
MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
map_parseargs, null_map_open, null_map_close,
null_map_lookup, null_map_store);
/* syslog map -- logs information to syslog */
MAPDEF("syslog", NULL, 0,
syslog_map_parseargs, null_map_open, null_map_close,
syslog_map_lookup, null_map_store);
/* macro storage map -- rulesets can set macros */
MAPDEF("macro", NULL, 0,
dequote_init, null_map_open, null_map_close,
macro_map_lookup, null_map_store);
/* arithmetic map -- add/subtract/compare */
MAPDEF("arith", NULL, 0,
dequote_init, null_map_open, null_map_close,
arith_map_lookup, null_map_store);
if (tTd(38, 2))
{
/* bogus map -- always return tempfail */
MAPDEF("bogus", NULL, MCF_ALIASOK|MCF_OPTFILE,
map_parseargs, null_map_open, null_map_close,
bogus_map_lookup, null_map_store);
}
}
#undef MAPDEF
/*
** INITHOSTMAPS -- initial host-dependent maps
**
** This should act as an interface to any local service switch
** provided by the host operating system.
**
** Parameters:
** none
**
** Returns:
** none
**
** Side Effects:
** Should define maps "host" and "users" as necessary
** for this OS. If they are not defined, they will get
** a default value later. It should check to make sure
** they are not defined first, since it's possible that
** the config file has provided an override.
*/
void
inithostmaps()
{
register int i;
int nmaps;
char *maptype[MAXMAPSTACK];
short mapreturn[MAXMAPACTIONS];
char buf[MAXLINE];
/*
** Set up default hosts maps.
*/
#if 0
nmaps = switch_map_find("hosts", maptype, mapreturn);
for (i = 0; i < nmaps; i++)
{
if (strcmp(maptype[i], "files") == 0 &&
stab("hosts.files", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts",
sizeof buf);
(void) makemapentry(buf);
}
# if NAMED_BIND
else if (strcmp(maptype[i], "dns") == 0 &&
stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "hosts.dns dns A", sizeof buf);
(void) makemapentry(buf);
}
# endif /* NAMED_BIND */
# ifdef NISPLUS
else if (strcmp(maptype[i], "nisplus") == 0 &&
stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir",
sizeof buf);
(void) makemapentry(buf);
}
# endif /* NISPLUS */
# ifdef NIS
else if (strcmp(maptype[i], "nis") == 0 &&
stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname",
sizeof buf);
(void) makemapentry(buf);
}
# endif /* NIS */
# if NETINFO
else if (strcmp(maptype[i], "netinfo") == 0) &&
stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "hosts.netinfo netinfo -v name /machines",
sizeof buf);
(void) makemapentry(buf);
}
# endif /* NETINFO */
}
#endif /* 0 */
/*
** Make sure we have a host map.
*/
if (stab("host", ST_MAP, ST_FIND) == NULL)
{
/* user didn't initialize: set up host map */
(void) strlcpy(buf, "host host", sizeof buf);
#if NAMED_BIND
if (ConfigLevel >= 2)
(void) strlcat(buf, " -a. -D", sizeof buf);
#endif /* NAMED_BIND */
(void) makemapentry(buf);
}
/*
** Set up default aliases maps
*/
nmaps = switch_map_find("aliases", maptype, mapreturn);
for (i = 0; i < nmaps; i++)
{
if (strcmp(maptype[i], "files") == 0 &&
stab("aliases.files", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases.files null", sizeof buf);
(void) makemapentry(buf);
}
#ifdef NISPLUS
else if (strcmp(maptype[i], "nisplus") == 0 &&
stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir",
sizeof buf);
(void) makemapentry(buf);
}
#endif /* NISPLUS */
#ifdef NIS
else if (strcmp(maptype[i], "nis") == 0 &&
stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases.nis nis mail.aliases",
sizeof buf);
(void) makemapentry(buf);
}
#endif /* NIS */
#if NETINFO
else if (strcmp(maptype[i], "netinfo") == 0 &&
stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases.netinfo netinfo -z, /aliases",
sizeof buf);
(void) makemapentry(buf);
}
#endif /* NETINFO */
#ifdef HESIOD
else if (strcmp(maptype[i], "hesiod") == 0 &&
stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases.hesiod hesiod aliases",
sizeof buf);
(void) makemapentry(buf);
}
#endif /* HESIOD */
}
if (stab("aliases", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "aliases switch aliases", sizeof buf);
(void) makemapentry(buf);
}
#if 0 /* "user" map class is a better choice */
/*
** Set up default users maps.
*/
nmaps = switch_map_find("passwd", maptype, mapreturn);
for (i = 0; i < nmaps; i++)
{
if (strcmp(maptype[i], "files") == 0 &&
stab("users.files", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd",
sizeof buf);
(void) makemapentry(buf);
}
# ifdef NISPLUS
else if (strcmp(maptype[i], "nisplus") == 0 &&
stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir",
sizeof buf);
(void) makemapentry(buf);
}
# endif /* NISPLUS */
# ifdef NIS
else if (strcmp(maptype[i], "nis") == 0 &&
stab("users.nis", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "users.nis nis -m passwd.byname",
sizeof buf);
(void) makemapentry(buf);
}
# endif /* NIS */
# ifdef HESIOD
else if (strcmp(maptype[i], "hesiod") == 0) &&
stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "users.hesiod hesiod", sizeof buf);
(void) makemapentry(buf);
}
# endif /* HESIOD */
}
if (stab("users", ST_MAP, ST_FIND) == NULL)
{
(void) strlcpy(buf, "users switch -m passwd", sizeof buf);
(void) makemapentry(buf);
}
#endif /* 0 */
}
/*
** SWITCH_MAP_FIND -- find the list of types associated with a map
**
** This is the system-dependent interface to the service switch.
**
** Parameters:
** service -- the name of the service of interest.
** maptype -- an out-array of strings containing the types
** of access to use for this service. There can
** be at most MAXMAPSTACK types for a single service.
** mapreturn -- an out-array of return information bitmaps
** for the map.
**
** Returns:
** The number of map types filled in, or -1 for failure.
**
** Side effects:
** Preserves errno so nothing in the routine clobbers it.
*/
#if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
# define _USE_SUN_NSSWITCH_
#endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
#ifdef _USE_SUN_NSSWITCH_
# include <nsswitch.h>
#endif /* _USE_SUN_NSSWITCH_ */
#if defined(ultrix) || (defined(__osf__) && defined(__alpha))
# define _USE_DEC_SVC_CONF_
#endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
#ifdef _USE_DEC_SVC_CONF_
# include <sys/svcinfo.h>
#endif /* _USE_DEC_SVC_CONF_ */
int
switch_map_find(service, maptype, mapreturn)
char *service;
char *maptype[MAXMAPSTACK];
short mapreturn[MAXMAPACTIONS];
{
int svcno;
int save_errno = errno;
#ifdef _USE_SUN_NSSWITCH_
struct __nsw_switchconfig *nsw_conf;
enum __nsw_parse_err pserr;
struct __nsw_lookup *lk;
static struct __nsw_lookup lkp0 =
{ "files", {1, 0, 0, 0}, NULL, NULL };
static struct __nsw_switchconfig lkp_default =
{ 0, "sendmail", 3, &lkp0 };
for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
mapreturn[svcno] = 0;
if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
lk = lkp_default.lookups;
else
lk = nsw_conf->lookups;
svcno = 0;
while (lk != NULL)
{
maptype[svcno] = lk->service_name;
if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
mapreturn[MA_NOTFOUND] |= 1 << svcno;
if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
mapreturn[MA_TRYAGAIN] |= 1 << svcno;
if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
mapreturn[MA_TRYAGAIN] |= 1 << svcno;
svcno++;
lk = lk->next;
}
errno = save_errno;
return svcno;
#endif /* _USE_SUN_NSSWITCH_ */
#ifdef _USE_DEC_SVC_CONF_
struct svcinfo *svcinfo;
int svc;
for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
mapreturn[svcno] = 0;
svcinfo = getsvc();
if (svcinfo == NULL)
goto punt;
if (strcmp(service, "hosts") == 0)
svc = SVC_HOSTS;
else if (strcmp(service, "aliases") == 0)
svc = SVC_ALIASES;
else if (strcmp(service, "passwd") == 0)
svc = SVC_PASSWD;
else
{
errno = save_errno;
return -1;
}
for (svcno = 0; svcno < SVC_PATHSIZE; svcno++)
{
switch (svcinfo->svcpath[svc][svcno])
{
case SVC_LOCAL:
maptype[svcno] = "files";
break;
case SVC_YP:
maptype[svcno] = "nis";
break;
case SVC_BIND:
maptype[svcno] = "dns";
break;
# ifdef SVC_HESIOD
case SVC_HESIOD:
maptype[svcno] = "hesiod";
break;
# endif /* SVC_HESIOD */
case SVC_LAST:
errno = save_errno;
return svcno;
}
}
errno = save_errno;
return svcno;
#endif /* _USE_DEC_SVC_CONF_ */
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
/*
** Fall-back mechanism.
*/
STAB *st;
time_t now = curtime();
for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
mapreturn[svcno] = 0;
if ((now - ServiceCacheTime) > (time_t) ServiceCacheMaxAge)
{
/* (re)read service switch */
register FILE *fp;
long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK;
if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR,
DontBlameSendmail))
sff |= SFF_NOWLINK;
if (ConfigFileRead)
ServiceCacheTime = now;
fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff);
if (fp != NULL)
{
char buf[MAXLINE];
while (fgets(buf, sizeof buf, fp) != NULL)
{
register char *p;
p = strpbrk(buf, "#\n");
if (p != NULL)
*p = '\0';
p = strpbrk(buf, " \t");
if (p != NULL)
*p++ = '\0';
if (buf[0] == '\0')
continue;
if (p == NULL)
{
sm_syslog(LOG_ERR, NOQID,
"Bad line on %.100s: %.100s",
ServiceSwitchFile,
buf);
continue;
}
while (isspace(*p))
p++;
if (*p == '\0')
continue;
/*
** Find/allocate space for this service entry.
** Space for all of the service strings
** are allocated at once. This means
** that we only have to free the first
** one to free all of them.
*/
st = stab(buf, ST_SERVICE, ST_ENTER);
if (st->s_service[0] != NULL)
free((void *) st->s_service[0]);
p = newstr(p);
for (svcno = 0; svcno < MAXMAPSTACK; )
{
if (*p == '\0')
break;
st->s_service[svcno++] = p;
p = strpbrk(p, " \t");
if (p == NULL)
break;
*p++ = '\0';
while (isspace(*p))
p++;
}
if (svcno < MAXMAPSTACK)
st->s_service[svcno] = NULL;
}
(void) fclose(fp);
}
}
/* look up entry in cache */
st = stab(service, ST_SERVICE, ST_FIND);
if (st != NULL && st->s_service[0] != NULL)
{
/* extract data */
svcno = 0;
while (svcno < MAXMAPSTACK)
{
maptype[svcno] = st->s_service[svcno];
if (maptype[svcno++] == NULL)
break;
}
errno = save_errno;
return --svcno;
}
#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
#if !defined(_USE_SUN_NSSWITCH_)
/* if the service file doesn't work, use an absolute fallback */
# ifdef _USE_DEC_SVC_CONF_
punt:
# endif /* _USE_DEC_SVC_CONF_ */
for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
mapreturn[svcno] = 0;
svcno = 0;
if (strcmp(service, "aliases") == 0)
{
maptype[svcno++] = "files";
# if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
maptype[svcno++] = "netinfo";
# endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
# ifdef AUTO_NIS_ALIASES
# ifdef NISPLUS
maptype[svcno++] = "nisplus";
# endif /* NISPLUS */
# ifdef NIS
maptype[svcno++] = "nis";
# endif /* NIS */
# endif /* AUTO_NIS_ALIASES */
errno = save_errno;
return svcno;
}
if (strcmp(service, "hosts") == 0)
{
# if NAMED_BIND
maptype[svcno++] = "dns";
# else /* NAMED_BIND */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -