#include #include "auto_break.h" #include "control.h" #include "fmt.h" #include "mysql_queries.h" #include "qsutil.h" #include "subfd.h" #include "substdio.h" #include "stralloc.h" extern int connect_mysql(); extern MYSQL dbh, *mysql; extern MYSQL_RES *result; extern stralloc envnoathost; extern char strnum3[FMT_ULONG]; extern int do_query(stralloc *query, MYSQL_ROW *row); /* map a virtual domain to a user-ext stralloc */ int vdoms_mysql(char *addr, int len, stralloc *ret) { char *host; int at, num, rows; MYSQL_ROW row; stralloc qmail_mysql_query = { 0 }; stralloc real_addr = { 0 }; stralloc real_host = { 0 }; /* stralloc we're passed is unterminated */ addr[len] = '\0'; DEBUG_SAY("vdoms_mysql: "); DEBUG_SAY(addr); DEBUG_SAY("\n"); num = len; host = addr + len; while (*host != '@') { host--; num--; if (host == addr) break; } at = num; /* let's lose the @ we found */ host++; if (! stralloc_ready(&real_addr, 2 * str_len(addr) + 1)) return -1; mysql_escape_string(real_addr.s, addr, at); if (! stralloc_ready(&real_host, 2 * str_len(host) + 1)) { stralloc_free(&real_addr); return -1; } mysql_escape_string(real_host.s, host, str_len(host)); #define ACK {\ stralloc_free(&real_addr);\ stralloc_free(&real_host);\ stralloc_free(&qmail_mysql_query);\ return -1;\ } if (! connect_mysql()) ACK len += real_addr.len + real_host.len + str_len(VIRTUAL) + 2; if (! stralloc_ready(&qmail_mysql_query, len)) ACK if (! stralloc_cats(&qmail_mysql_query, VIRTUAL1)) ACK if (! stralloc_cats(&qmail_mysql_query, real_addr.s)) ACK if (! stralloc_cats(&qmail_mysql_query, VIRTUAL2)) ACK if (! stralloc_cats(&qmail_mysql_query, real_host.s)) ACK if (! stralloc_cats(&qmail_mysql_query, VIRTUAL3)) ACK if (! stralloc_0(&qmail_mysql_query)) ACK #ifndef O_NOT_LOG log3("query: ", qmail_mysql_query.s, ";\n"); #endif rows = do_query(&qmail_mysql_query, &row); /* no row doesn't mean an error */ if (rows < 1) { stralloc_free(&real_addr); stralloc_free(&real_host); return rows; } /* run database sanity check: username may not be blank */ if (! *(row[0])) { log3("MySQL misconfiguration: username for host '", real_host.s, "' is blank in virtual table!\n"); stralloc_free(&real_addr); stralloc_free(&real_host); mysql_free_result(result); return 0; } #define YOW {\ stralloc_free(&real_addr);\ stralloc_free(&real_host);\ mysql_free_result(result);\ return -1;\ } #ifdef MAGIC_FORWARDING if (! str_diff(row[0], MAGIC_FORWARD_USER)) { if (! stralloc_cats(ret, row[1])) YOW if (! stralloc_0(ret)) YOW mysql_free_result(result); stralloc_free(&real_addr); stralloc_free(&real_host); #ifdef MAGIC_LOGGING log2("magic forward: msg ", strnum3); log2(" for ", addr); log3(" to ", row[1], "\n"); #endif return 2; } #endif if (! stralloc_cats(ret, row[0])) YOW /* username */ if (str_len(row[1])) { if (! stralloc_append(ret, auto_break)) YOW if (*row[1] != '@') { if (! stralloc_cats(ret, row[1])) YOW } else if (! stralloc_cats(ret, real_addr.s)) YOW /* ext */ } if (! stralloc_append(ret, "@")) YOW if (! stralloc_cats(ret, real_host.s)) YOW if (! stralloc_0(ret)) YOW mysql_free_result(result); stralloc_free(&real_addr); stralloc_free(&real_host); return 1; }