-/* $Cambridge: exim/src/src/verify.c,v 1.41 2006/10/03 15:11:22 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.43 2006/10/10 15:36:50 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
while (addr_new != NULL)
{
int rc;
- uschar *show_address;
address_item *addr = addr_new;
addr_new = addr->next;
addr->next = NULL;
- /* When full_info is set, child addresses are displayed in top-level
- messages. Otherwise, we show only the top level address. */
-
- show_address = full_info? addr->address : address;
-
DEBUG(D_verify)
{
debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
}
else
{
+ int flags;
uschar *canonical_name;
host_item *host, *nexthost;
host_build_hostlist(&host_list, s, tf.hosts_randomize);
additional host items being inserted into the chain. Hence we must
save the next host first. */
+ flags = HOST_FIND_BY_A;
+ if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
+ if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
+
for (host = host_list; host != NULL; host = nexthost)
{
nexthost = host->next;
if (tf.gethostbyname ||
string_is_ip_address(host->name, NULL) != 0)
- (void)host_find_byname(host, NULL, &canonical_name, TRUE);
+ (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE);
else
- {
- int flags = HOST_FIND_BY_A;
- if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
- if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
(void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
&canonical_name, NULL);
- }
}
}
}
{
address_item *p = addr->parent;
- fprintf(f, "%s%s %s", ko_prefix, show_address,
+ fprintf(f, "%s%s %s", ko_prefix, full_info? addr->address : address,
address_test_mode? "is undeliverable" : "failed to verify");
if (!expn && admin_user)
{
{
address_item *p = addr->parent;
fprintf(f, "%s%s cannot be resolved at this time", ko_prefix,
- show_address);
+ full_info? addr->address : address);
if (!expn && admin_user)
{
if (addr->basic_errno > 0)
(addr_new != NULL && /* At least one new address AND */
success_on_redirect))) /* success_on_redirect is set */
{
- if (f != NULL) fprintf(f, "%s %s\n", show_address,
+ if (f != NULL) fprintf(f, "%s %s\n", address,
address_test_mode? "is deliverable" : "verified");
/* If we have carried on to verify a child address, we want the value
{
header_line *h;
uschar *colon, *s;
+int yield = OK;
-for (h = header_list; h != NULL; h = h->next)
+for (h = header_list; h != NULL && yield == OK; h = h->next)
{
if (h->type != htype_from &&
h->type != htype_reply_to &&
s = colon + 1;
while (isspace(*s)) s++;
- parse_allow_group = TRUE; /* Allow group syntax */
+ /* Loop for multiple addresses in the header, enabling group syntax. Note
+ that we have to reset this after the header has been scanned. */
- /* Loop for multiple addresses in the header */
+ parse_allow_group = TRUE;
while (*s != 0)
{
int start, end, domain;
/* Temporarily terminate the string at this point, and extract the
- operative address within. */
+ operative address within, allowing group syntax. */
*ss = 0;
recipient = parse_extract_address(s,&errmess,&start,&end,&domain,FALSE);
string_sprintf("%s: failing address in \"%.*s:\" header %s: %.*s",
errmess, tt - h->text, h->text, verb, len, s));
- return FAIL;
+ yield = FAIL;
+ break; /* Out of address loop */
}
/* Advance to the next address */
s = ss + (terminator? 1:0);
while (isspace(*s)) s++;
} /* Next address */
- } /* Next header */
-return OK;
+ parse_allow_group = FALSE;
+ parse_found_group = FALSE;
+ } /* Next header unless yield has been set FALSE */
+
+return yield;
}
s = colon + 1;
while (isspace(*s)) s++;
- parse_allow_group = TRUE; /* Allow group syntax */
+ /* Loop for multiple addresses in the header, enabling group syntax. Note
+ that we have to reset this after the header has been scanned. */
- /* Loop for multiple addresses in the header */
+ parse_allow_group = TRUE;
while (*s != 0)
{
int start, end, domain;
/* Temporarily terminate the string at this point, and extract the
- operative address within. */
+ operative address within, allowing group syntax. */
*ss = 0;
recipient = parse_extract_address(s,&errmess,&start,&end,&domain,FALSE);
s = ss + (terminator? 1:0);
while (isspace(*s)) s++;
} /* Next address */
+
+ parse_allow_group = FALSE;
+ parse_found_group = FALSE;
} /* Next header (if found is false) */
if (!found) return FAIL;
uschar *pm_mailfrom, int options, int *verrno)
{
static int header_types[] = { htype_sender, htype_reply_to, htype_from };
+BOOL done = FALSE;
int yield = FAIL;
int i;
-for (i = 0; i < 3; i++)
+for (i = 0; i < 3 && !done; i++)
{
header_line *h;
- for (h = header_list; h != NULL; h = h->next)
+ for (h = header_list; h != NULL && !done; h = h->next)
{
int terminator, new_ok;
uschar *s, *ss, *endname;
if (h->type != header_types[i]) continue;
s = endname = Ustrchr(h->text, ':') + 1;
+ /* Scan the addresses in the header, enabling group syntax. Note that we
+ have to reset this after the header has been scanned. */
+
+ parse_allow_group = TRUE;
+
while (*s != 0)
{
address_item *vaddr;
else
{
int start, end, domain;
- uschar *address = parse_extract_address(s, log_msgptr, &start,
- &end, &domain, FALSE);
+ uschar *address = parse_extract_address(s, log_msgptr, &start, &end,
+ &domain, FALSE);
*ss = terminator;
+ /* If we found an empty address, just carry on with the next one, but
+ kill the message. */
+
+ if (address == NULL && Ustrcmp(*log_msgptr, "empty address") == 0)
+ {
+ *log_msgptr = NULL;
+ s = ss;
+ continue;
+ }
+
/* If verification failed because of a syntax error, fail this
function, and ensure that the failing address gets added to the error
message. */
if (address == NULL)
{
new_ok = FAIL;
- if (*log_msgptr != NULL)
- {
- while (ss > s && isspace(ss[-1])) ss--;
- *log_msgptr = string_sprintf("syntax error in '%.*s' header when "
- "scanning for sender: %s in \"%.*s\"",
- endname - h->text, h->text, *log_msgptr, ss - s, s);
- return FAIL;
- }
+ while (ss > s && isspace(ss[-1])) ss--;
+ *log_msgptr = string_sprintf("syntax error in '%.*s' header when "
+ "scanning for sender: %s in \"%.*s\"",
+ endname - h->text, h->text, *log_msgptr, ss - s, s);
+ yield = FAIL;
+ done = TRUE;
+ break;
}
/* Else go ahead with the sender verification. But it isn't *the*
/* Success or defer */
- if (new_ok == OK) return OK;
+ if (new_ok == OK)
+ {
+ yield = OK;
+ done = TRUE;
+ break;
+ }
+
if (new_ok == DEFER) yield = DEFER;
/* Move on to any more addresses in the header */
s = ss;
- }
- }
- }
+ } /* Next address */
+
+ parse_allow_group = FALSE;
+ parse_found_group = FALSE;
+ } /* Next header, unless done */
+ } /* Next header type unless done */
if (yield == FAIL && *log_msgptr == NULL)
*log_msgptr = US"there is no valid sender in any header line";
h.address = NULL;
h.mx = MX_NONE;
- rc = host_find_byname(&h, NULL, NULL, FALSE);
+ rc = host_find_byname(&h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, FALSE);
if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
{
host_item *hh;