From: Mark Wooding Date: Thu, 16 Mar 2006 23:16:15 +0000 (+0000) Subject: Merge branch 'nail' X-Git-Tag: mdw/1.03-5^0 X-Git-Url: https://git.distorted.org.uk/~mdw/qmail/commitdiff_plain/5794b37af853f8e487dc5f7c2a83220b3899f596?hp=3a23c310cf11c5781c5a41a7551f5ecd25dd4841 Merge branch 'nail' * nail: addrcheck: Don't spew userv error messages at SMTP clients. addrcheck: Strip off the domain part before passing to userv service. addrcheck: Add commentary for the functions, because I'm confused. --- diff --git a/addrcheck.c b/addrcheck.c index 08d29b9..0b189a7 100644 --- a/addrcheck.c +++ b/addrcheck.c @@ -5,6 +5,7 @@ #include "addrcheck.h" #include #include +#include /* #define DEBUG */ #ifdef DEBUG @@ -17,6 +18,23 @@ #define STRALLOC_INIT { 0 } +/* --- @probe@ --- * + * + * Arguments: @int cdb@ = the CDB file descriptor + * @int prefix@ = the prefix character (e.g., @'V'@) + * @const char *key, int len@ = the key string and its length + * @const char *suffix@ = a suffix to append to the key + * @const char **kp@ = where to put the full key string + * @uint32 *dlen@ = where to put the answer's length + * + * Returns: Zero if the lookup failed, @+1@ on success, or @-1@ for an + * error. + * + * Use: Probes a CDB file. The key looked up is the character + * @prefix@ followed by the first @len@ bytes of @key@, followed + * by @suffix@ (if non-null). + */ + static int probe(int cdb, int prefix, const char *key, int len, const char *suffix, const char **kp, uint32 *dlen) { @@ -57,6 +75,24 @@ static int probe(int cdb, int prefix, const char *key, int len, return (rc); } +/* --- @localprobe@ --- * + * + * Arguments: @int cdb@ = the CDB file descriptor + * @const char *sender@ = the envelope-sender address + * @const char *key, int len@ = the (possibly defaulted) mailbox + * name to look up + * @const char *suffix@ = a suffix to append to the key (e.g., + * @"-default"@) + * @const char *tail@ = the tail of the local address matching + * any defaulted extension part + * @int *rc@ = where to put the answer + * + * Returns: Positive if found, zero if not found, negative on error. + * + * Use: Looks up a local-part in the database. This may involve + * invoking a Userv service for the recipient's owner. + */ + static int localprobe(int cdb, const char *sender, const char *key, int len, const char *suffix, const char *tail, int *rc) @@ -96,9 +132,10 @@ static int localprobe(int cdb, const char *sender, if (pipe(p) || (kid = fork()) == -1) return (-1); if (!kid) { + close(0); open("/dev/null", O_RDONLY); dup2(p[1], 1); - close(p[0]); - close(p[1]); + close(2); open("/dev/null", O_WRONLY); + close(p[0]); close(p[1]); execl("/usr/bin/userv", "/usr/bin/userv", "-f", "stdin=/dev/null", u.s, serv.s, @@ -121,6 +158,22 @@ static int localprobe(int cdb, const char *sender, return (1); } +/* --- @local@ --- * + * + * Arguments: @int cdb@ = file descriptor for the CDB + * @const char *l@ = pointer to local-part to look up + * @int len@ = length of the local-part + * @const char *sender@ = envelope sender address + * @int *rc@ = where to put the answer + * + * Returns: Positive if answered, zero if lookup failed, negative on + * error. + * + * Use: Finds out whether @l@ is a valid local-part for a non-virtual + * mailbox name. Handles defaulting of extension addresses and + * suchlike. + */ + static int local(int cdb, const char *l, int len, const char *sender, int *rc) { @@ -153,6 +206,23 @@ done: return (err); } +/* --- @virt@ --- * + * + * Arguments: @int cdb@ = file descriptor for CDB + * @const char *u@ = the local-part of the recipient mailbox + * @int ulen@ = length of the local-part + * @const char *addr@ = the virtual domain to look up + * @int alen@ = length of the virtual domain + * @const char *sender@ = the envelope sender address + * @int *rc@ = where to put the answer + * + * Returns: Positive if found, zero if not found, negative on error. + * + * Use: Looks up the address as a virtual domain. If found, the + * local-part is appended to the local mailbox handling the + * virtual domain and passed to @local@. + */ + static int virt(int cdb, const char *u, int ulen, const char *addr, int alen, const char *sender, int *rc) { @@ -172,11 +242,26 @@ static int virt(int cdb, const char *u, int ulen, return (1); } +/* --- @addrcheck@ --- * + * + * Arguments: @int cdb@ = file descriptor for CDB to look things up in + * @const char *addr@ = the (full) recipient mailbox to look up + * @const char *sender@ = the (full) envelope sender address + * @int *rc@ = where to put the answer. + * + * Returns: Nonnegative on success, or @-1@ on failure. + * + * Use: Determines whether @addr@ is a valid mailbox on this system, + * by examining the given CDB file. On exit, @*rc@ is set to + * @'+'@ if the mailbox is valid, or @'-'@ if not. + */ + int addrcheck(int cdb, const char *addr, const char *sender, int *rc) { int at, len, dot; int err = 0; uint32 dlen; + static stralloc l = STRALLOC_INIT; len = str_len(addr); at = str_chr(addr, '@'); @@ -196,8 +281,11 @@ int addrcheck(int cdb, const char *addr, const char *sender, int *rc) return (-1); if (!err) { *rc = 1; return (0); } if (dlen != 0) { errno = EINVAL; return (-1); } - - return (local(cdb, addr, at, sender, rc)); + l.len = 0; + if (!stralloc_catb(&l, addr, at) || + !stralloc_0(&l)) + return (-1); + return (local(cdb, l.s, l.len - 1, sender, rc)); } #ifdef TEST