aboutsummaryrefslogtreecommitdiff
path: root/src/rcfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rcfile.c')
-rw-r--r--src/rcfile.c242
1 files changed, 125 insertions, 117 deletions
diff --git a/src/rcfile.c b/src/rcfile.c
index 27033c3..9590e5b 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -1,11 +1,11 @@
/*
rcfile.c
This file is part of GNU Anubis.
- Copyright (C) 2001-2014 The Anubis Team.
+ Copyright (C) 2001-2024 The Anubis Team.
GNU Anubis is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
@@ -168,35 +168,35 @@ open_rcfile (int method)
{
get_homedir (session.supervisor, homedir, sizeof (homedir));
rcfile = xmalloc (strlen (homedir) +
strlen (DEFAULT_LOCAL_RCFILE) + 2);
sprintf (rcfile, "%s/%s", homedir, DEFAULT_LOCAL_RCFILE);
}
-
+
if (check_filename (rcfile, &global_mtime) == 0)
{
free (rcfile);
return;
}
rc_section_list_destroy (&parse_tree);
file_id_destroy ();
info (VERBOSE, _("Reading system configuration file %s..."), rcfile);
break;
-
+
case CF_CLIENT:
if ((topt & (T_ALTRC | T_NORC)) == (T_ALTRC | T_NORC))
{
rcfile = strdup (options.altrc);
}
else
{
rcfile = user_rcfile_name ();
}
info (VERBOSE, _("Reading user configuration file %s..."), rcfile);
}
-
+
if ((topt & T_RELAX_PERM_CHECK) == 0 && check_filemode (rcfile) == 0)
{ /* Wrong permissions... */
free (rcfile);
return;
}
@@ -220,49 +220,54 @@ process_rcfile (int method)
rcfile_process_section (method, "AUTH", NULL, NULL);
#endif
}
/* ************************** The CONTROL Section ************************* */
-#define KW_BIND 0
-#define KW_TERMLEVEL 1
-#define KW_LOGLEVEL 2
-#define KW_LOGFILE 3
-#define KW_TRACEFILE 4
-#define KW_REMOTE_MTA 5
-#define KW_LOCAL_MTA 6
-#define KW_RULE_PRIORITY 7
-#define KW_CONTROL_PRIORITY 8
-#define KW_ESMTP_AUTH 9
-#define KW_DROP_UNKNOWN_USER 10
-#define KW_USER_NOTPRIVILEGED 11
-#define KW_SOCKS_PROXY 13
-#define KW_SOCKS_V4 14
-#define KW_SOCKS_AUTH 15
-#define KW_READ_ENTIRE_BODY 16
-#define KW_LOCAL_DOMAIN 17
-#define KW_MODE 18
-#define KW_ESMTP_ANONYMOUS_TOKEN 19
-#define KW_ESMTP_AUTH_ID 20
-#define KW_ESMTP_AUTHZ_ID 21
-#define KW_ESMTP_PASSWORD 22
-#define KW_ESMTP_SERVICE 23
-#define KW_ESMTP_HOSTNAME 24
-#define KW_ESMTP_GENERIC_SERVICE 25
-#define KW_ESMTP_PASSCODE 26
-#define KW_ESMTP_REALM 27
-#define KW_ESMTP_ALLOWED_MECH 28
-#define KW_ESMTP_REQUIRE_ENCRYPTION 29
-#define KW_INCOMING_MAIL_RULE 30
-#define KW_OUTGOING_MAIL_RULE 31
-#define KW_SMTP_COMMAND_RULE 32
-#define KW_HANG 33
-#define KW_ALLOW_HANG 34
-#define KW_LOG_FACILITY 35
-#define KW_LOG_TAG 36
-#define KW_ESMTP_AUTH_DELAYED 37
+enum
+ {
+ KW_BIND,
+ KW_TERMLEVEL,
+ KW_LOGLEVEL,
+ KW_LOGFILE,
+ KW_TRACEFILE,
+ KW_REMOTE_MTA,
+ KW_LOCAL_MTA,
+ KW_RULE_PRIORITY,
+ KW_CONTROL_PRIORITY,
+ KW_ESMTP_AUTH,
+ KW_DROP_UNKNOWN_USER,
+ KW_USER_NOTPRIVILEGED,
+ KW_SOCKS_PROXY,
+ KW_SOCKS_V4,
+ KW_SOCKS_AUTH,
+ KW_READ_ENTIRE_BODY,
+ KW_LOCAL_DOMAIN,
+ KW_MODE,
+ KW_ESMTP_ANONYMOUS_TOKEN,
+ KW_ESMTP_AUTH_ID,
+ KW_ESMTP_AUTHZ_ID,
+ KW_ESMTP_PASSWORD,
+ KW_ESMTP_SERVICE,
+ KW_ESMTP_HOSTNAME,
+ KW_ESMTP_GENERIC_SERVICE,
+ KW_ESMTP_PASSCODE,
+ KW_ESMTP_REALM,
+ KW_ESMTP_ALLOWED_MECH,
+ KW_ESMTP_REQUIRE_ENCRYPTION,
+ KW_INCOMING_MAIL_RULE,
+ KW_OUTGOING_MAIL_RULE,
+ KW_SMTP_COMMAND_RULE,
+ KW_HANG,
+ KW_ALLOW_HANG,
+ KW_LOG_FACILITY,
+ KW_LOG_TAG,
+ KW_ESMTP_AUTH_DELAYED,
+ KW_USE_PAM,
+ KW_IDENTD_KEYFILE,
+ };
char **
list_to_argv (ANUBIS_LIST list)
{
int i, argc;
char **argv, *p;
@@ -285,13 +290,13 @@ list_to_argv (ANUBIS_LIST list)
static void
parse_log_facility (const char *arg)
{
unsigned long n;
char *endp;
struct anubis_keyword kw[] = {
- { "USER", LOG_USER },
+ { "USER", LOG_USER },
{ "DAEMON", LOG_DAEMON },
{ "AUTH", LOG_AUTH },
{ "AUTHPRIV",LOG_AUTHPRIV },
{ "MAIL", LOG_MAIL },
{ "CRON", LOG_CRON },
{ "LOCAL0", LOG_LOCAL0 },
@@ -302,50 +307,34 @@ parse_log_facility (const char *arg)
{ "LOCAL5", LOG_LOCAL5 },
{ "LOCAL6", LOG_LOCAL6 },
{ "LOCAL7", LOG_LOCAL7 },
{ NULL }
};
struct anubis_keyword *p;
-
+
if (strlen (arg) > 4 && strncasecmp (arg, "LOG_", 4) == 0)
arg += 4;
p = anubis_keyword_lookup_ci (kw, arg);
if (p)
log_facility = p->tok;
else if (((n = strtoul (arg, &endp, 0)), *endp == 0)
&& (log_facility = n) == n)
/* nothing */;
else
anubis_warning (0,
_("%s: invalid syslog facility"), arg);
}
-
+
/* When HANG=NUMBER is set in CONTROL section, `_anubis_hang' is set and
Anubis will sleep for one second intervals, decrementing `_anubis_hang'
until it's zero. Thus you can force the program to continue by attaching
a debugger and setting it to 0 yourself. */
static volatile unsigned long _anubis_hang;
/* List of users who are allowed to use HANG in their profiles */
-ANUBIS_LIST allow_hang_users;
-
-static struct rc_kwdef esmtp_kw[] = {
- { "esmtp-auth", KW_ESMTP_AUTH, KWF_HIDDEN },
- { "esmtp-anonymous-token", KW_ESMTP_ANONYMOUS_TOKEN, KWF_HIDDEN },
- { "esmtp-auth-id", KW_ESMTP_AUTH_ID, KWF_HIDDEN },
- { "esmtp-authz-id", KW_ESMTP_AUTHZ_ID, KWF_HIDDEN },
- { "esmtp-password", KW_ESMTP_PASSWORD, KWF_HIDDEN },
- { "esmtp-service", KW_ESMTP_SERVICE, KWF_HIDDEN },
- { "esmtp-hostname", KW_ESMTP_HOSTNAME, KWF_HIDDEN },
- { "esmtp-generic-service", KW_ESMTP_SERVICE, KWF_HIDDEN },
- { "esmtp-passcode", KW_ESMTP_PASSCODE, KWF_HIDDEN },
- { "esmtp-realm", KW_ESMTP_REALM, KWF_HIDDEN },
- { "esmtp-allowed-mech", KW_ESMTP_ALLOWED_MECH },
- { "esmtp-require-encryption", KW_ESMTP_REQUIRE_ENCRYPTION },
- { NULL }
-};
+ANUBIS_LIST allow_hang_users;
static int
parse_esmtp_kv (int key, ANUBIS_LIST arglist)
{
char *arg = list_item (arglist, 0);
switch (key)
@@ -363,128 +352,128 @@ parse_esmtp_kv (int key, ANUBIS_LIST arglist)
topt |= T_ESMTP_AUTH;
}
else
topt &= ~T_ESMTP_AUTH;
}
break;
-
+
case KW_ESMTP_ANONYMOUS_TOKEN:
anon_token = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_AUTH_ID:
authentication_id = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_AUTHZ_ID:
authorization_id = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_PASSWORD:
auth_password = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_SERVICE:
auth_service = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_HOSTNAME:
auth_hostname = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_GENERIC_SERVICE:
generic_service_name = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_PASSCODE:
auth_passcode = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_REALM:
auth_realm = strdup (arg);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_ALLOWED_MECH:
anubis_set_client_mech_list (arglist);
topt |= T_ESMTP_AUTH;
break;
-
+
case KW_ESMTP_REQUIRE_ENCRYPTION:
anubis_set_encryption_mech_list (arglist);
break;
default:
return 1;
-#endif
+#endif
}
return 0;
}
void
control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
{
char *arg = list_item (arglist, 0);
int method = eval_env_method (env);
-
+
switch (key)
{
case KW_BIND:
parse_mtahost (arg, &session.anubis, &session.anubis_port);
if (session.anubis && strlen (session.anubis) != 0)
topt |= T_NAMES;
break;
-
+
case KW_RULE_PRIORITY:
if (strcasecmp (arg, "user") == 0)
anubis_section_set_prio ("RULE", prio_user);
else if (strcasecmp (arg, "user-only") == 0)
anubis_section_set_prio ("RULE", prio_user_only);
else if (strcasecmp (arg, "system") == 0)
anubis_section_set_prio ("RULE", prio_system);
else if (strcasecmp (arg, "system-only") == 0)
anubis_section_set_prio ("RULE", prio_system_only);
else
eval_error (0, env, _("invalid rule priority"));
break;
-
+
case KW_CONTROL_PRIORITY:
if (strcasecmp (arg, "user") == 0)
anubis_section_set_prio ("CONTROL", prio_user);
else if (strcasecmp (arg, "system") == 0)
anubis_section_set_prio ("CONTROL", prio_system);
else
eval_error (0, env, _("invalid control priority"));
break;
-
+
case KW_TERMLEVEL:
if (strcasecmp ("silent", arg) == 0)
options.termlevel = SILENT;
else if (strcasecmp ("normal", arg) == 0)
options.termlevel = NORMAL;
else if (strcasecmp ("verbose", arg) == 0)
options.termlevel = VERBOSE;
else if (strcasecmp ("debug", arg) == 0)
options.termlevel = DEBUG;
else
eval_error (0, env, _("invalid termlevel"));
break;
-
+
case KW_USER_NOTPRIVILEGED:
assign_string (&session.notprivileged, arg);
topt |= T_USER_NOTPRIVIL;
break;
-
+
case KW_LOGFILE:
if (method == CF_CLIENT)
{
xfree (options.ulogfile);
options.ulogfile = xstrdup (arg);
}
@@ -495,24 +484,24 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
{
topt |= T_DISABLE_SYSLOG;
xfree (options.ulogfile);
options.ulogfile = xstrdup (arg);
}
break;
-
+
case KW_LOGLEVEL:
if (strcasecmp ("none", arg) == 0)
options.uloglevel = NONE;
else if (strcasecmp ("all", arg) == 0)
options.uloglevel = ALL;
else if (strcasecmp ("fails", arg) == 0)
options.uloglevel = FAILS;
else
eval_error (0, env, _("invalid loglevel"));
break;
-
+
case KW_TRACEFILE:
if (method & (CF_SUPERVISOR | CF_INIT))
setbool (env, arg, topt, T_TRACEFILE_SYS);
else if (method == CF_CLIENT)
{
if (strcasecmp ("no", arg) == 0)
@@ -535,39 +524,39 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
options.tracefile = xstrdup (arg);
topt |= T_TRACEFILE_USR;
}
}
}
break;
-
+
case KW_REMOTE_MTA:
parse_mtaport (arg, &session.mta, &session.mta_port);
break;
-
+
case KW_LOCAL_MTA:
xfree (session.execpath);
- argcv_free (-1, session.execargs);
+ argv_free (session.execargs);
session.execpath = strdup (arg);
session.execargs = list_to_argv (arglist);
topt |= T_LOCAL_MTA;
break;
-
+
case KW_LOCAL_DOMAIN:
anubis_domain = strdup (arg);
break;
#ifdef USE_SOCKS_PROXY
case KW_SOCKS_PROXY:
parse_mtaport (arg, &session.socks, &session.socks_port);
if_empty_set (session.socks, topt, T_SOCKS);
break;
-
+
case KW_SOCKS_V4:
setbool (env, arg, topt, T_SOCKS_V4);
break;
-
+
case KW_SOCKS_AUTH:
{
char *p = 0;
p = strchr (arg, ':');
if (p)
{
@@ -580,73 +569,72 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
}
#endif /* USE_SOCKS_PROXY */
case KW_READ_ENTIRE_BODY:
setbool (env, arg, topt, T_ENTIRE_BODY);
break;
-
+
case KW_DROP_UNKNOWN_USER:
setbool (env, arg, topt, T_DROP_UNKNOWN_USER);
break;
-
+
case KW_MODE:
- if (anubis_mode != anubis_mda) /* Special case. See comment to
- KW_LOCAL_MAILER directive, though */
+ if (anubis_mode != anubis_mda)
{
if (list_count (arglist) != 1)
eval_error (1, env, _("not enough arguments"));
else if (anubis_set_mode (arg))
eval_error (0, env, _("invalid mode: %s"), arg);
}
break;
-
+
case KW_INCOMING_MAIL_RULE:
incoming_mail_rule = strdup (arg);
break;
-
+
case KW_OUTGOING_MAIL_RULE:
outgoing_mail_rule = strdup (arg);
break;
case KW_SMTP_COMMAND_RULE:
smtp_command_rule = strdup (arg);
break;
-
+
case KW_LOG_FACILITY:
parse_log_facility (arg);
break;
-
+
case KW_LOG_TAG:
log_tag = strdup (arg);
break;
-
+
case KW_ALLOW_HANG:
{
char *p;
ITERATOR itr = iterator_create (arglist);
-
+
allow_hang_users = list_create ();
for (p = iterator_first (itr); p; p = iterator_next (itr))
list_append (allow_hang_users, strdup (p));
}
break;
-
+
case KW_HANG:
if (list_locate (allow_hang_users, session.clientname, anubis_name_cmp))
{
int keep_termlevel = options.termlevel;
-
+
_anubis_hang = atoi (arg ? arg : "3600");
options.termlevel = DEBUG;
eval_warning (env,
ngettext ("Child process suspended for %lu second",
"Child process suspended for %lu seconds",
_anubis_hang),
_anubis_hang);
options.termlevel = keep_termlevel;
-
+
while (_anubis_hang-- > 0)
sleep (1);
}
else
anubis_warning (0,
_("Command HANG is not allowed for user `%s'"),
@@ -655,12 +643,30 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
#if defined (WITH_GSASL)
case KW_ESMTP_AUTH_DELAYED:
topt |= T_ESMTP_AUTH;
setbool (env, arg, topt, T_ESMTP_AUTH_DELAYED);
break;
#endif
+
+ case KW_USE_PAM:
+ setbool (env, arg, use_pam, 1);
+#if !defined(HAVE_PAM)
+ if (use_pam)
+ eval_error (0, env,
+ _("statement ignored: anubis compiled without PAM support"));
+#endif
+ break;
+
+ case KW_IDENTD_KEYFILE:
+ identd_keyfile_name = strdup (arg);
+#if !defined(USE_GCRYPT)
+ eval_error (0, env,
+ _("statement ignored: anubis compiled without libgcrypt"));
+#endif
+ break;
+
default:
if (parse_esmtp_kv (key, arglist))
eval_error (2, env,
_("INTERNAL ERROR at %s:%d: unhandled key %d; "
"please report"),
__FILE__, __LINE__,
@@ -675,12 +681,14 @@ static struct rc_kwdef init_kw[] = {
{ "incoming-mail-rule", KW_INCOMING_MAIL_RULE },
{ "outgoing-mail-rule", KW_OUTGOING_MAIL_RULE },
{ "smtp-command-rule", KW_SMTP_COMMAND_RULE },
{ "log-facility", KW_LOG_FACILITY },
{ "log-tag", KW_LOG_TAG },
{ "ALLOW-HANG", KW_ALLOW_HANG },
+ { "use-pam", KW_USE_PAM },
+ { "identd-keyfile", KW_IDENTD_KEYFILE },
{ NULL },
};
static struct rc_secdef_child init_sect_child = {
NULL,
CF_INIT,
@@ -772,39 +780,39 @@ tls_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
char *arg = list_item (arglist, 0);
switch (key)
{
case KW_SSL:
setbool (env, arg, topt, T_SSL);
break;
-
+
case KW_SSL_ONEWAY:
setbool (env, arg, topt, T_SSL_ONEWAY);
break;
-
+
case KW_SSL_CERT:
xfree (secure.cert);
secure.cert = xstrdup (arg);
break;
-
+
case KW_SSL_KEY:
xfree (secure.key);
secure.key = xstrdup (arg);
if (eval_env_method (env) == CF_CLIENT)
topt |= T_SSL_CKCLIENT;
break;
-
+
case KW_SSL_CAFILE:
xfree (secure.cafile);
secure.cafile = xstrdup (arg);
break;
case KW_SSL_PRIORITIES:
xfree (secure.prio);
secure.prio = xstrdup (arg);
break;
-
+
default:
eval_error (2, env,
_("INTERNAL ERROR at %s:%d: unhandled key %d; "
"please report"),
__FILE__, __LINE__,
key);
@@ -861,32 +869,32 @@ rule_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
switch (key)
{
case KW_SIGNATURE_FILE_APPEND:
if (strcasecmp ("no", arg))
message_append_signature_file (msg);
break;
-
+
case KW_BODY_APPEND:
message_append_text_file (msg, arg, NULL);
break;
-
+
case KW_BODY_CLEAR:
message_replace_body (msg, xstrdup (""));
break;
-
+
case KW_BODY_CLEAR_APPEND:
message_replace_body (msg, xstrdup (""));
message_append_text_file (msg, arg, NULL);
break;
-
+
case KW_EXTERNAL_BODY_PROCESSOR:
argv = list_to_argv (arglist);
message_external_proc (msg, argv);
- argcv_free (-1, argv);
+ argv_free (argv);
break;
-
+
default:
eval_error (2, env,
_("INTERNAL ERROR at %s:%d: unhandled key %d; "
"please report"),
__FILE__, __LINE__,
key);
@@ -930,32 +938,32 @@ smtp_rule_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
switch (key)
{
case KW_SIGNATURE_FILE_APPEND:
if (strcasecmp ("no", arg))
message_append_signature_file (msg);
break;
-
+
case KW_BODY_APPEND:
message_append_text_file (msg, arg, NULL);
break;
-
+
case KW_BODY_CLEAR:
message_replace_body (msg, xstrdup (""));
break;
-
+
case KW_BODY_CLEAR_APPEND:
message_replace_body (msg, xstrdup (""));
message_append_text_file (msg, arg, NULL);
break;
-
+
case KW_EXTERNAL_BODY_PROCESSOR:
argv = list_to_argv (arglist);
message_external_proc (msg, argv);
- argcv_free (-1, argv);
+ argv_free (argv);
break;
-
+
default:
if (parse_esmtp_kv (key, arglist))
eval_error (2, env,
_("INTERNAL ERROR at %s:%d: unhandled key %d; "
"please report"),
__FILE__, __LINE__,

Return to:

Send suggestions and report system problems to the System administrator.