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;
 }

Reply via email to