X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/71fafd9530395ba813bf8669340517a12700c769..38a0a95ff69327042421b9ee6982e386175f141b:/src/src/acl.c diff --git a/src/src/acl.c b/src/src/acl.c index 9df6339a7..8c2ab699a 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.57 2006/03/06 16:05:12 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.64 2006/09/19 11:28:45 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -202,8 +202,8 @@ at the outer level. In the other cases, expansion already occurs in the checking functions. */ static uschar cond_expand_at_top[] = { - TRUE, /* add_header */ TRUE, /* acl */ + TRUE, /* add_header */ FALSE, /* authenticated */ #ifdef EXPERIMENTAL_BRIGHTMAIL TRUE, /* bmi_optin */ @@ -260,8 +260,8 @@ static uschar cond_expand_at_top[] = { /* Flags to identify the modifiers */ static uschar cond_modifiers[] = { - TRUE, /* add_header */ FALSE, /* acl */ + TRUE, /* add_header */ FALSE, /* authenticated */ #ifdef EXPERIMENTAL_BRIGHTMAIL TRUE, /* bmi_optin */ @@ -323,12 +323,14 @@ static unsigned int cond_forbids[] = { 0, /* acl */ (unsigned int) - ~((1<= max) + if (endptr - s < 6) { - BAD_ACL_VAR: - *error = string_sprintf("syntax error or unrecognized name after " - "\"set\" in ACL modifier \"set %s\"", s); + *error = string_sprintf("invalid variable name after \"set\" in ACL " + "modifier \"set %s\" (must be at least 6 characters)", s); return NULL; } - cond->u.varnumber = n + offset; + cond->u.varname = string_copyn(s + 4, endptr - s - 4); s = endptr; while (isspace(*s)) s++; } @@ -2035,6 +2058,7 @@ ACL clauses like: defer ratelimit = 15 / 1h Arguments: arg the option string for ratelimit= + where ACL_WHERE_xxxx indicating which ACL this is log_msgptr for error messages Returns: OK - Sender's rate is above limit @@ -2044,7 +2068,7 @@ Returns: OK - Sender's rate is above limit */ static int -acl_ratelimit(uschar *arg, uschar **log_msgptr) +acl_ratelimit(uschar *arg, int where, uschar **log_msgptr) { double limit, period; uschar *ss, *key; @@ -2263,6 +2287,9 @@ else if (per_byte) dbd->rate = (message_size < 0 ? 0.0 : (double)message_size) * (1 - a) / i_over_p + a * dbd->rate; + else if (per_cmd && where == ACL_WHERE_NOTSMTP) + dbd->rate = (double)recipients_count + * (1 - a) / i_over_p + a * dbd->rate; else dbd->rate = (1 - a) / i_over_p + a * dbd->rate; } @@ -2344,7 +2371,7 @@ acl_check_condition(int verb, acl_condition_block *cb, int where, { uschar *user_message = NULL; uschar *log_message = NULL; -uschar *p; +uschar *p = NULL; int rc = OK; #ifdef WITH_CONTENT_SCAN int sep = '/'; @@ -2407,11 +2434,8 @@ for (; cb != NULL; cb = cb->next) if (cb->type == ACLC_SET) { - int n = cb->u.varnumber; - int t = (n < ACL_CVARS)? 'c' : 'm'; - if (n >= ACL_CVARS) n -= ACL_CVARS; - debug_printf("acl_%c%d ", t, n); - lhswidth += 7; + debug_printf("acl_%s ", cb->u.varname); + lhswidth += 5 + Ustrlen(cb->u.varname); } debug_printf("= %s\n", cb->arg); @@ -2873,7 +2897,7 @@ for (; cb != NULL; cb = cb->next) #endif case ACLC_RATELIMIT: - rc = acl_ratelimit(arg, log_msgptr); + rc = acl_ratelimit(arg, where, log_msgptr); break; case ACLC_RECIPIENTS: @@ -2907,8 +2931,8 @@ for (; cb != NULL; cb = cb->next) case ACLC_SET: { int old_pool = store_pool; - if (cb->u.varnumber < ACL_CVARS) store_pool = POOL_PERM; - acl_var[cb->u.varnumber] = string_copy(arg); + if (cb->u.varname[0] == 'c') store_pool = POOL_PERM; + acl_var_create(cb->u.varname)->data.ptr = string_copy(arg); store_pool = old_pool; } break; @@ -3578,4 +3602,64 @@ if (rc != OK && *user_msgptr != NULL && Ustrlen(*user_msgptr) > 75) return rc; } + + +/************************************************* +* Create ACL variable * +*************************************************/ + +/* Create an ACL variable or reuse an existing one. ACL variables are in a +binary tree (see tree.c) with acl_var_c and acl_var_m as root nodes. + +Argument: + name pointer to the variable's name, starting with c or m + +Returns the pointer to variable's tree node +*/ + +tree_node * +acl_var_create(uschar *name) +{ +tree_node *node, **root; +root = (name[0] == 'c')? &acl_var_c : &acl_var_m; +node = tree_search(*root, name); +if (node == NULL) + { + node = store_get(sizeof(tree_node) + Ustrlen(name)); + Ustrcpy(node->name, name); + (void)tree_insertnode(root, node); + } +node->data.ptr = NULL; +return node; +} + + + +/************************************************* +* Write an ACL variable in spool format * +*************************************************/ + +/* This function is used as a callback for tree_walk when writing variables to +the spool file. To retain spool file compatibility, what is written is -aclc or +-aclm followed by the rest of the name and the data length, space separated, +then the value itself, starting on a new line, and terminated by an additional +newline. When we had only numbered ACL variables, the first line might look +like this: "-aclc 5 20". Now it might be "-aclc foo 20" for the variable called +acl_cfoo. + +Arguments: + name of the variable + value of the variable + ctx FILE pointer (as a void pointer) + +Returns: nothing +*/ + +void +acl_var_write(uschar *name, uschar *value, void *ctx) +{ +FILE *f = (FILE *)ctx; +fprintf(f, "-acl%c %s %d\n%s\n", name[0], name+1, Ustrlen(value), value); +} + /* End of acl.c */