Hi. This diff changes the internal table interface. The backends now return results as formatted strings, parsing is delegated to the upper layer.
It's been lightly tested already, but more tests would be very welcome, especially with setups involving lots of tables (including external ones). Eric. Index: smtpd.h =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v retrieving revision 1.594 diff -u -p -r1.594 smtpd.h --- smtpd.h 13 Dec 2018 17:08:10 -0000 1.594 +++ smtpd.h 17 Dec 2018 16:33:09 -0000 @@ -375,8 +375,8 @@ struct table_backend { void *(*open)(struct table *); int (*update)(struct table *); void (*close)(void *); - int (*lookup)(void *, struct dict *, const char *, enum table_service, union lookup *); - int (*fetch)(void *, struct dict *, enum table_service, union lookup *); + int (*lookup)(void *, struct dict *, const char *, enum table_service, char **); + int (*fetch)(void *, struct dict *, enum table_service, char **); }; @@ -1601,8 +1601,6 @@ int table_regex_match(const char *, cons void table_open_all(struct smtpd *); void table_dump_all(struct smtpd *); void table_close_all(struct smtpd *); -int table_parse_lookup(enum table_service, const char *, const char *, - union lookup *); /* to.c */ Index: table.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/table.c,v retrieving revision 1.32 diff -u -p -r1.32 table.c --- table.c 2 Nov 2018 13:45:59 -0000 1.32 +++ table.c 17 Dec 2018 16:09:02 -0000 @@ -53,6 +53,8 @@ extern struct table_backend table_backen static const char * table_service_name(enum table_service); static const char * table_backend_name(struct table_backend *); static const char * table_dump_lookup(enum table_service, union lookup *); +static int table_parse_lookup(enum table_service, const char *, const char *, + union lookup *); static int parse_sockaddr(struct sockaddr *, int, const char *); static unsigned int last_table_id = 0; @@ -125,7 +127,7 @@ table_lookup(struct table *table, struct union lookup *lk) { int r; - char lkey[1024]; + char lkey[1024], *buf = NULL; if (table->t_backend->lookup == NULL) return (-1); @@ -135,9 +137,9 @@ table_lookup(struct table *table, struct return -1; } - r = table->t_backend->lookup(table->t_handle, params, lkey, kind, lk); + r = table->t_backend->lookup(table->t_handle, params, lkey, kind, lk ? &buf : NULL); - if (r == 1) + if (r == 1) { log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s -> %s%s%s", lk ? "lookup" : "check", lkey, @@ -145,8 +147,11 @@ table_lookup(struct table *table, struct table_backend_name(table->t_backend), table->t_name, lk ? "\"" : "", - (lk) ? table_dump_lookup(kind, lk): "found", + (lk) ? buf : "found", lk ? "\"" : ""); + if (buf) + r = table_parse_lookup(kind, lkey, buf, lk); + } else log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s -> %d", lk ? "lookup" : "check", @@ -156,6 +161,8 @@ table_lookup(struct table *table, struct table->t_name, r); + free(buf); + return (r); } @@ -163,20 +170,24 @@ int table_fetch(struct table *table, struct dict *params, enum table_service kind, union lookup *lk) { int r; + char *buf = NULL; if (table->t_backend->fetch == NULL) return (-1); - r = table->t_backend->fetch(table->t_handle, params, kind, lk); + r = table->t_backend->fetch(table->t_handle, params, kind, lk ? &buf : NULL); - if (r == 1) + if (r == 1) { log_trace(TRACE_LOOKUP, "lookup: fetch %s from table %s:%s -> %s%s%s", table_service_name(kind), table_backend_name(table->t_backend), table->t_name, lk ? "\"" : "", - (lk) ? table_dump_lookup(kind, lk): "found", + (lk) ? buf : "found", lk ? "\"" : ""); + if (buf) + r = table_parse_lookup(kind, NULL, buf, lk); + } else log_trace(TRACE_LOOKUP, "lookup: fetch %s from table %s:%s -> %d", table_service_name(kind), @@ -184,6 +195,8 @@ table_fetch(struct table *table, struct table->t_name, r); + free(buf); + return (r); } @@ -535,7 +548,7 @@ table_close_all(struct smtpd *conf) table_close(t); } -int +static int table_parse_lookup(enum table_service service, const char *key, const char *line, union lookup *lk) { Index: table_db.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/table_db.c,v retrieving revision 1.10 diff -u -p -r1.10 table_db.c --- table_db.c 31 May 2018 21:06:12 -0000 1.10 +++ table_db.c 18 Dec 2018 14:43:14 -0000 @@ -43,8 +43,8 @@ static int table_db_config(struct table *); static int table_db_update(struct table *); static void *table_db_open(struct table *); -static int table_db_lookup(void *, struct dict *, const char *, enum table_service, union lookup *); -static int table_db_fetch(void *, struct dict *, enum table_service, union lookup *); +static int table_db_lookup(void *, struct dict *, const char *, enum table_service, char **); +static int table_db_fetch(void *, struct dict *, enum table_service, char **); static void table_db_close(void *); static char *table_db_get_entry(void *, const char *, size_t *); @@ -143,7 +143,7 @@ table_db_close(void *hdl) static int table_db_lookup(void *hdl, struct dict *params, const char *key, enum table_service service, - union lookup *lk) + char **dst) { struct dbhandle *handle = hdl; struct table *table = NULL; @@ -176,15 +176,16 @@ table_db_lookup(void *hdl, struct dict * return 0; ret = 1; - if (lk) - ret = table_parse_lookup(service, key, line, lk); - free(line); + if (dst) + *dst = line; + else + free(line); return ret; } static int -table_db_fetch(void *hdl, struct dict *params, enum table_service service, union lookup *lk) +table_db_fetch(void *hdl, struct dict *params, enum table_service service, char **dst) { struct dbhandle *handle = hdl; struct table *table = handle->table; @@ -203,7 +204,13 @@ table_db_fetch(void *hdl, struct dict *p return 0; } - return table_parse_lookup(service, NULL, dbk.data, lk); + if (dst) { + *dst = strdup(dbk.data); + if (*dst == NULL) + return -1; + } + + return 1; } Index: table_getpwnam.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/table_getpwnam.c,v retrieving revision 1.4 diff -u -p -r1.4 table_getpwnam.c --- table_getpwnam.c 20 Jan 2015 17:37:54 -0000 1.4 +++ table_getpwnam.c 18 Dec 2018 16:33:49 -0000 @@ -42,7 +42,7 @@ static int table_getpwnam_config(struct static int table_getpwnam_update(struct table *); static void *table_getpwnam_open(struct table *); static int table_getpwnam_lookup(void *, struct dict *, const char *, enum table_service, - union lookup *); + char **); static void table_getpwnam_close(void *); struct table_backend table_backend_getpwnam = { @@ -83,10 +83,9 @@ table_getpwnam_close(void *hdl) static int table_getpwnam_lookup(void *hdl, struct dict *params, const char *key, enum table_service kind, - union lookup *lk) + char **dst) { struct passwd *pw; - size_t s; if (kind != K_USERINFO) return -1; @@ -101,19 +100,16 @@ table_getpwnam_lookup(void *hdl, struct return -1; return 0; } - if (lk == NULL) + if (dst == NULL) return 1; - lk->userinfo.uid = pw->pw_uid; - lk->userinfo.gid = pw->pw_gid; - s = strlcpy(lk->userinfo.username, pw->pw_name, - sizeof(lk->userinfo.username)); - if (s >= sizeof(lk->userinfo.username)) - return (-1); - s = strlcpy(lk->userinfo.directory, pw->pw_dir, - sizeof(lk->userinfo.directory)); - if (s >= sizeof(lk->userinfo.directory)) - return (-1); + if (asprintf(dst, "%d:%d:%s", + pw->pw_uid, + pw->pw_gid, + pw->pw_dir) == -1) { + *dst = NULL; + return -1; + } return (1); } Index: table_proc.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/table_proc.c,v retrieving revision 1.7 diff -u -p -r1.7 table_proc.c --- table_proc.c 31 May 2018 21:06:12 -0000 1.7 +++ table_proc.c 18 Dec 2018 14:42:36 -0000 @@ -196,15 +196,14 @@ imsg_add_params(struct ibuf *buf, struct } static int -table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_service s, - union lookup *lk) +table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_service s, char **dst) { struct table_proc_priv *priv = arg; struct ibuf *buf; int r; buf = imsg_create(&priv->ibuf, - lk ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0, + dst ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0, sizeof(s) + strlen(k) + 1); if (buf == NULL) @@ -220,7 +219,7 @@ table_proc_lookup(void *arg, struct dict table_proc_call(priv); table_proc_read(&r, sizeof(r)); - if (r == 1 && lk) { + if (r == 1 && dst) { if (rlen == 0) { log_warnx("warn: table-proc: empty response"); fatalx("table-proc: exiting"); @@ -229,7 +228,9 @@ table_proc_lookup(void *arg, struct dict log_warnx("warn: table-proc: not NUL-terminated"); fatalx("table-proc: exiting"); } - r = table_parse_lookup(s, k, rdata, lk); + *dst = strdup(rdata); + if (*dst == NULL) + r = -1; table_proc_read(NULL, rlen); } @@ -239,7 +240,7 @@ table_proc_lookup(void *arg, struct dict } static int -table_proc_fetch(void *arg, struct dict *params, enum table_service s, union lookup *lk) +table_proc_fetch(void *arg, struct dict *params, enum table_service s, char **dst) { struct table_proc_priv *priv = arg; struct ibuf *buf; @@ -266,7 +267,9 @@ table_proc_fetch(void *arg, struct dict log_warnx("warn: table-proc: not NUL-terminated"); fatalx("table-proc: exiting"); } - r = table_parse_lookup(s, NULL, rdata, lk); + *dst = strdup(rdata); + if (*dst == NULL) + r = -1; table_proc_read(NULL, rlen); } Index: table_static.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/table_static.c,v retrieving revision 1.20 diff -u -p -r1.20 table_static.c --- table_static.c 1 Nov 2018 10:47:46 -0000 1.20 +++ table_static.c 18 Dec 2018 14:41:49 -0000 @@ -43,9 +43,9 @@ static int table_static_config(struct ta static int table_static_update(struct table *); static void *table_static_open(struct table *); static int table_static_lookup(void *, struct dict *, const char *, - enum table_service, union lookup *); + enum table_service, char **); static int table_static_fetch(void *, struct dict *, enum table_service, - union lookup *); + char **); static void table_static_close(void *); struct table_backend table_backend_static = { @@ -216,7 +216,7 @@ table_static_close(void *hdl) static int table_static_lookup(void *hdl, struct dict *params, const char *key, - enum table_service service, union lookup *lk) + enum table_service service, char **dst) { struct table *m = hdl; char *line; @@ -251,18 +251,22 @@ table_static_lookup(void *hdl, struct di break; } - if (lk == NULL) + if (dst == NULL) return ret ? 1 : 0; if (ret == 0) return 0; - return table_parse_lookup(service, key, line, lk); + *dst = strdup(line); + if (*dst == NULL) + return -1; + + return 1; } static int table_static_fetch(void *hdl, struct dict *params, - enum table_service service, union lookup *lk) + enum table_service service, char **dst) { struct table *t = hdl; const char *k; @@ -273,8 +277,12 @@ table_static_fetch(void *hdl, struct dic return 0; } - if (lk == NULL) + if (dst == NULL) return 1; - return table_parse_lookup(service, NULL, k, lk); + *dst = strdup(k); + if (*dst == NULL) + return -1; + + return 1; }