#include "exim.h"
+#ifndef MACRO_PREDEF
/* Default callout timeout */
[ACL_WARN] = BIT(OK)
};
+#endif
+
/* ACL condition and modifier codes - keep in step with the table that
follows.
down. */
};
+#ifdef MACRO_PREDEF
+# include "macro_predef.h"
+void
+features_acl(void)
+{
+for (condition_def * c = conditions; c < conditions + nelem(conditions); c++)
+ {
+ uschar buf[64], * p, * s;
+ int n = sprintf(CS buf, "_ACL_%s_", c->is_modifier ? "MOD" : "COND");
+ for (p = buf + n, s = c->name; *s; s++) *p++ = toupper(*s);
+ *p = '\0';
+ builtin_macro_create(buf);
+ }
+}
+#endif
+
+
+#ifndef MACRO_PREDEF
/* Return values from decode_control(); used as index so keep in step
with the controls_list table that follows! */
{ US"no_delay_flush", FALSE,
ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START
},
-
+
[CONTROL_NO_ENFORCE_SYNC] =
{ US"no_enforce_sync", FALSE,
ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START
int v, c;
BOOL negated = FALSE;
uschar *saveline = s;
- uschar name[64];
+ uschar name[EXIM_DRIVERNAME_MAX];
/* Conditions (but not verbs) are allowed to be negated by an initial
exclamation mark. */
case CONTROL_FAKEREJECT:
cancel_cutthrough_connection(TRUE, US"fakereject");
- case CONTROL_FAKEDEFER:
+ case CONTROL_FAKEDEFER:
fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
if (*p == '/')
{
const uschar *pp = p + 1;
while (*pp) pp++;
- fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
+ /* The entire control= line was expanded at top so no need to expand
+ the part after the / */
+ fake_response_text = string_copyn(p+1, pp-p-1);
p = pp;
}
else /* Explicitly reset to default string */
}
break;
- #ifndef DISABLE_DKIM
+#ifndef DISABLE_DKIM
case ACLC_DKIM_SIGNER:
if (dkim_cur_signer)
rc = match_isinlist(dkim_cur_signer,
rc = match_isinlist(dkim_verify_status,
&arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL);
break;
- #endif
+#endif
#ifdef SUPPORT_DMARC
case ACLC_DMARC_STATUS:
#endif
case ACLC_QUEUE:
- if (is_tainted(arg))
{
- *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted",
- arg);
- return ERROR;
- }
- if (Ustrchr(arg, '/'))
- {
- *log_msgptr = string_sprintf(
- "Directory separator not permitted in queue name: '%s'", arg);
- return ERROR;
+ uschar *m;
+ if ((m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)))
+ {
+ *log_msgptr = m;
+ return ERROR;
+ }
+ if (Ustrchr(arg, '/'))
+ {
+ *log_msgptr = string_sprintf(
+ "Directory separator not permitted in queue name: '%s'", arg);
+ return ERROR;
+ }
+ queue_name = string_copy_perm(arg, FALSE);
+ break;
}
- queue_name = string_copy_perm(arg, FALSE);
- break;
case ACLC_RATELIMIT:
rc = acl_ratelimit(arg, where, log_msgptr);
acl_text = ss;
-#ifdef notyet_taintwarn
if ( !f.running_in_test_harness
&& is_tainted2(acl_text, LOG_MAIN|LOG_PANIC,
- "attempt to use tainted ACL text \"%s\"", acl_text))
- {
- /* Avoid leaking info to an attacker */
- *log_msgptr = US"internal configuration error";
- return ERROR;
- }
-#else
-if (is_tainted(acl_text) && !f.running_in_test_harness)
+ "Tainted ACL text \"%s\"", acl_text))
{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "attempt to use tainted ACL text \"%s\"", acl_text);
/* Avoid leaking info to an attacker */
*log_msgptr = US"internal configuration error";
return ERROR;
}
-#endif
/* Handle the case of a string that does not contain any spaces. Look for a
named ACL among those read from the configuration, or a previously read file.
else if (*ss == '/')
{
struct stat statbuf;
+ if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted ACL file name '%s'", ss))
+ {
+ /* Avoid leaking info to an attacker */
+ *log_msgptr = US"internal configuration error";
+ return ERROR;
+ }
if ((fd = Uopen(ss, O_RDONLY, 0)) < 0)
{
*log_msgptr = string_sprintf("failed to open ACL file \"%s\": %s", ss,
fprintf(f, "-acl%c %s %d\n%s\n", name[0], name+1, Ustrlen(value), value);
}
+#endif /* !MACRO_PREDEF */
/* vi: aw ai sw=2
*/
/* End of acl.c */