Hi all,
  I am still working on the table-procexec for opensmtpd
and while there, I was thinking of how to do authentication
using LDAP, which the current table-ldap from ports does not
support.
The primary reason for that, I believe, is that LDAP
authentication should be done by bind and not by returning
the userPassword and us doing the authentication with
crypt_checkpass. That kind of defeats one of the uses of LDAP.

Here I've added a patch which pushes the authentication step
to the table backend and it only returns the final AUTH/NOAUTH
kind of values.

While here, I also made another small change with mailaddrmap,
where instead of returning ALL possible aliases that a user
may use, we now pass the current mailaddr to the table, so
it can now return a smaller set of addresses.

It should not affect any workflow, so testing from others
would be appreciated.

Cheers,
Aisha


diff --git a/usr.sbin/smtpd/aliases.c b/usr.sbin/smtpd/aliases.c
index a473aeca189..8e3835f78a6 100644
--- a/usr.sbin/smtpd/aliases.c
+++ b/usr.sbin/smtpd/aliases.c
@@ -45,7 +45,7 @@ aliases_get(struct expand *expand, const char *username)
        /* first, check if entry has a user-part tag */
        pbuf = strchr(buf, *env->sc_subaddressing_delim);
        if (pbuf) {
-               ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+               ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
                if (ret < 0)
                        return (-1);
                if (ret)
@@ -54,7 +54,7 @@ aliases_get(struct expand *expand, const char *username)
        }
 
        /* no user-part tag, try looking up user */
-       ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+       ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
        if (ret <= 0)
                return ret;
 
@@ -116,7 +116,7 @@ aliases_virtual_get(struct expand *expand, const struct 
mailaddr *maddr)
                if (!bsnprintf(buf, sizeof(buf), "%s%c%s@%s",
                        user, *env->sc_subaddressing_delim, tag, domain))
                        return 0;
-               ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+               ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
                if (ret < 0)
                        return (-1);
                if (ret)
@@ -126,7 +126,7 @@ aliases_virtual_get(struct expand *expand, const struct 
mailaddr *maddr)
        /* then, check if entry exists without user-part tag */
        if (!bsnprintf(buf, sizeof(buf), "%s@%s", user, domain))
                return 0;
-       ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+       ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
        if (ret < 0)
                return (-1);
        if (ret)
@@ -137,7 +137,7 @@ aliases_virtual_get(struct expand *expand, const struct 
mailaddr *maddr)
                if (!bsnprintf(buf, sizeof(buf), "%s%c%s",
                        user, *env->sc_subaddressing_delim, tag))
                        return 0;
-               ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+               ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
                if (ret < 0)
                        return (-1);
                if (ret)
@@ -147,7 +147,7 @@ aliases_virtual_get(struct expand *expand, const struct 
mailaddr *maddr)
        /* Failed ? We lookup for username only */
        if (!bsnprintf(buf, sizeof(buf), "%s", user))
                return 0;
-       ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+       ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
        if (ret < 0)
                return (-1);
        if (ret)
@@ -160,14 +160,14 @@ aliases_virtual_get(struct expand *expand, const struct 
mailaddr *maddr)
        if (!bsnprintf(buf, sizeof(buf), "@%s", domain))
                return 0;
        /* Failed ? We lookup for catch all for virtual domain */
-       ret = table_lookup(mapping, K_ALIAS, buf, &lk);
+       ret = table_lookup(mapping, K_ALIAS, buf, NULL, &lk);
        if (ret < 0)
                return (-1);
        if (ret)
                goto expand;
 
        /* Failed ? We lookup for a *global* catch all */
-       ret = table_lookup(mapping, K_ALIAS, "@", &lk);
+       ret = table_lookup(mapping, K_ALIAS, "@", NULL, &lk);
        if (ret <= 0)
                return (ret);
 
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c
index 764130d6078..3354ccde7d7 100644
--- a/usr.sbin/smtpd/lka.c
+++ b/usr.sbin/smtpd/lka.c
@@ -268,7 +268,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
                        if (domain == NULL)
                                ret = table_fetch(table, K_RELAYHOST, &lk);
                        else
-                               ret = table_lookup(table, K_RELAYHOST, domain, 
&lk);
+                               ret = table_lookup(table, K_RELAYHOST, domain, 
NULL, &lk);
 
                        if (ret == -1)
                                m_add_int(p, LKA_TEMPFAIL);
@@ -729,7 +729,7 @@ lka_authenticate(const char *tablename, const char *user, 
const char *password)
                return (LKA_TEMPFAIL);
        }
 
-       switch (table_lookup(table, K_CREDENTIALS, user, &lk)) {
+       switch (table_lookup(table, K_AUTHENTICATE, user, password, &lk)) {
        case -1:
                log_warnx("warn: user credentials lookup fail for %s:%s",
                    tablename, user);
@@ -737,9 +737,7 @@ lka_authenticate(const char *tablename, const char *user, 
const char *password)
        case 0:
                return (LKA_PERMFAIL);
        default:
-               if (crypt_checkpass(password, lk.creds.password) == 0)
-                       return (LKA_OK);
-               return (LKA_PERMFAIL);
+               return (LKA_OK);
        }
 }
 
@@ -759,7 +757,7 @@ lka_credentials(const char *tablename, const char *label, 
char *dst, size_t sz)
 
        dst[0] = '\0';
 
-       switch (table_lookup(table, K_CREDENTIALS, label, &lk)) {
+       switch (table_lookup(table, K_CREDENTIALS, label, NULL, &lk)) {
        case -1:
                log_warnx("warn: credentials lookup fail for %s:%s",
                    tablename, label);
@@ -800,7 +798,7 @@ lka_userinfo(const char *tablename, const char *username, 
struct userinfo *res)
                return (LKA_TEMPFAIL);
        }
 
-       switch (table_lookup(table, K_USERINFO, username, &lk)) {
+       switch (table_lookup(table, K_USERINFO, username, NULL, &lk)) {
        case -1:
                log_warnx("warn: failure during userinfo lookup %s:%s",
                    tablename, username);
@@ -830,7 +828,7 @@ lka_addrname(const char *tablename, const struct sockaddr 
*sa,
                return (LKA_TEMPFAIL);
        }
 
-       switch (table_lookup(table, K_ADDRNAME, source, &lk)) {
+       switch (table_lookup(table, K_ADDRNAME, source, NULL, &lk)) {
        case -1:
                log_warnx("warn: failure during helo lookup %s:%s",
                    tablename, source);
@@ -858,7 +856,7 @@ lka_mailaddrmap(const char *tablename, const char 
*username, const struct mailad
                return (LKA_TEMPFAIL);
        }
 
-       switch (table_lookup(table, K_MAILADDRMAP, username, &lk)) {
+       switch (table_lookup(table, K_MAILADDRMAP, username, 
mailaddr_to_text(maddr), &lk)) {
        case -1:
                log_warnx("warn: failure during mailaddrmap lookup %s:%s",
                    tablename, username);
diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c
index cac9108349e..6976c584c7d 100644
--- a/usr.sbin/smtpd/lka_session.c
+++ b/usr.sbin/smtpd/lka_session.c
@@ -383,7 +383,7 @@ lka_expand(struct lka_session *lks, struct rule *rule, 
struct expandnode *xn)
                }
 
                userbase = table_find(env, dsp->u.local.table_userbase);
-               r = table_lookup(userbase, K_USERINFO, xn->u.user, &lk);
+               r = table_lookup(userbase, K_USERINFO, xn->u.user, NULL, &lk);
                if (r == -1) {
                        log_trace(TRACE_EXPAND, "expand: lka_expand: "
                            "backend error while searching user");
diff --git a/usr.sbin/smtpd/smtpd-api.h b/usr.sbin/smtpd/smtpd-api.h
index f83edd05854..f2841107a43 100644
--- a/usr.sbin/smtpd/smtpd-api.h
+++ b/usr.sbin/smtpd/smtpd-api.h
@@ -122,21 +122,22 @@ struct table_open_params {
 };
 
 enum table_service {
-       K_NONE          = 0x000,
-       K_ALIAS         = 0x001,        /* returns struct expand        */
-       K_DOMAIN        = 0x002,        /* returns struct destination   */
-       K_CREDENTIALS   = 0x004,        /* returns struct credentials   */
-       K_NETADDR       = 0x008,        /* returns struct netaddr       */
-       K_USERINFO      = 0x010,        /* returns struct userinfo      */
-       K_SOURCE        = 0x020,        /* returns struct source        */
-       K_MAILADDR      = 0x040,        /* returns struct mailaddr      */
-       K_ADDRNAME      = 0x080,        /* returns struct addrname      */
-       K_MAILADDRMAP   = 0x100,        /* returns struct maddrmap      */
-       K_RELAYHOST     = 0x200,        /* returns struct relayhost     */
-       K_STRING        = 0x400,
-       K_REGEX         = 0x800,
+       K_NONE          = 0,
+       K_ALIAS         = 1,    /* returns struct expand        */
+       K_DOMAIN        = 2,    /* returns struct destination   */
+       K_AUTHENTICATE  = 4,    /* returns int    authenticated */
+       K_CREDENTIALS   = 8,    /* returns struct credentials   */
+       K_NETADDR       = 16,   /* returns struct netaddr       */
+       K_USERINFO      = 32,   /* returns struct userinfo      */
+       K_SOURCE        = 64,   /* returns struct source        */
+       K_MAILADDR      = 128,  /* returns struct mailaddr      */
+       K_ADDRNAME      = 256,  /* returns struct addrname      */
+       K_MAILADDRMAP   = 512,  /* returns struct maddrmap      */
+       K_RELAYHOST     = 1024, /* returns struct relayhost     */
+       K_STRING        = 2048,
+       K_REGEX         = 4096
 };
-#define K_ANY            0xfff
+#define K_ANY            8191
 
 enum {
        PROC_TABLE_OK,
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index e6fc114d0a6..8dff20d8c3f 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -156,6 +156,7 @@ union lookup {
        struct mailaddr          mailaddr;
        struct addrname          addrname;
        struct maddrmap         *maddrmap;
+       int                      authenticated;
        char                     relayhost[LINE_MAX];
 };
 
@@ -372,7 +373,7 @@ struct table_backend {
        int     (*open)(struct table *);
        int     (*update)(struct table *);
        void    (*close)(struct table *);
-       int     (*lookup)(struct table *, enum table_service, const char *, 
char **);
+       int     (*lookup)(struct table *, enum table_service, const char *, 
const char *, char **);
        int     (*fetch)(struct table *, enum table_service, char **);
 };
 
@@ -1652,7 +1653,7 @@ int       table_check_type(struct table *, uint32_t);
 int    table_check_service(struct table *, uint32_t);
 int    table_match(struct table *, enum table_service, const char *);
 int    table_lookup(struct table *, enum table_service, const char *,
-    union lookup *);
+    const char *, union lookup *);
 int    table_fetch(struct table *, enum table_service, union lookup *);
 void table_destroy(struct smtpd *, struct table *);
 void table_add(struct table *, const char *, const char *);
diff --git a/usr.sbin/smtpd/table.c b/usr.sbin/smtpd/table.c
index 7328cf5df6e..631c17af6c2 100644
--- a/usr.sbin/smtpd/table.c
+++ b/usr.sbin/smtpd/table.c
@@ -39,7 +39,7 @@ extern struct table_backend table_backend_proc;
 
 static const char * table_service_name(enum table_service);
 static int table_parse_lookup(enum table_service, const char *, const char *,
-    union lookup *);
+    const char *, union lookup *);
 static int parse_sockaddr(struct sockaddr *, int, const char *);
 
 static unsigned int last_table_id = 0;
@@ -74,6 +74,7 @@ table_service_name(enum table_service s)
        case K_NONE:            return "NONE";
        case K_ALIAS:           return "ALIAS";
        case K_DOMAIN:          return "DOMAIN";
+       case K_AUTHENTICATE:    return "AUTHENTICATE";
        case K_CREDENTIALS:     return "CREDENTIALS";
        case K_NETADDR:         return "NETADDR";
        case K_USERINFO:        return "USERINFO";
@@ -97,12 +98,12 @@ table_find(struct smtpd *conf, const char *name)
 int
 table_match(struct table *table, enum table_service kind, const char *key)
 {
-       return table_lookup(table, kind, key, NULL);
+       return table_lookup(table, kind, key, NULL, NULL);
 }
 
 int
 table_lookup(struct table *table, enum table_service kind, const char *key,
-    union lookup *lk)
+    const char *data, union lookup *lk)
 {
        char lkey[1024], *buf = NULL;
        int r;
@@ -115,7 +116,7 @@ table_lookup(struct table *table, enum table_service kind, 
const char *key,
                errno = EINVAL;
        }
        else
-               r = table->t_backend->lookup(table, kind, lkey, lk ? &buf : 
NULL);
+               r = table->t_backend->lookup(table, kind, lkey, data, lk ? &buf 
: NULL);
 
        if (r == 1) {
                log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s 
-> %s%s%s",
@@ -128,7 +129,7 @@ table_lookup(struct table *table, enum table_service kind, 
const char *key,
                    lk ? buf : "true",
                    lk ? "\"" : "");
                if (buf)
-                       r = table_parse_lookup(kind, lkey, buf, lk);
+                       r = table_parse_lookup(kind, lkey, buf, data, lk);
        }
        else
                log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s 
-> %s%s",
@@ -163,7 +164,7 @@ table_fetch(struct table *table, enum table_service kind, 
union lookup *lk)
                    table->t_backend->name,
                    table->t_name,
                    buf);
-               r = table_parse_lookup(kind, NULL, buf, lk);
+               r = table_parse_lookup(kind, NULL, buf, NULL, lk);
        }
        else
                log_trace(TRACE_LOOKUP, "lookup: fetch %s from table %s:%s -> 
%s%s",
@@ -510,7 +511,7 @@ table_close_all(struct smtpd *conf)
 
 static int
 table_parse_lookup(enum table_service service, const char *key,
-    const char *line, union lookup *lk)
+    const char *line, const char *data, union lookup *lk)
 {
        char    buffer[LINE_MAX], *p;
        size_t  len;
@@ -534,6 +535,14 @@ table_parse_lookup(enum table_service service, const char 
*key,
                        return (-1);
                return (1);
 
+       case K_AUTHENTICATE:
+               if (strncmp(line, "AUTHENTICATED", 13) == 0){
+                       lk->authenticated = 1;
+                       return 1;
+               }
+               lk->authenticated = -1;
+               return -1;
+
        case K_CREDENTIALS:
 
                /* credentials are stored as user:password */
diff --git a/usr.sbin/smtpd/table_db.c b/usr.sbin/smtpd/table_db.c
index b4db8f7ccae..5977820948a 100644
--- a/usr.sbin/smtpd/table_db.c
+++ b/usr.sbin/smtpd/table_db.c
@@ -22,6 +22,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "smtpd.h"
 #include "log.h"
@@ -31,7 +32,7 @@ static int table_db_config(struct table *);
 static int table_db_update(struct table *);
 static int table_db_open(struct table *);
 static void *table_db_open2(struct table *);
-static int table_db_lookup(struct table *, enum table_service, const char *, 
char **);
+static int table_db_lookup(struct table *, enum table_service, const char *, 
const char *, char **);
 static int table_db_fetch(struct table *, enum table_service, char **);
 static void table_db_close(struct table *);
 static void table_db_close2(void *);
@@ -153,7 +154,7 @@ table_db_close2(void *hdl)
 
 static int
 table_db_lookup(struct table *table, enum table_service service, const char 
*key,
-    char **dst)
+    const char *data, char **dst)
 {
        struct dbhandle *handle = table->t_handle;
        char           *line;
@@ -184,11 +185,28 @@ table_db_lookup(struct table *table, enum table_service 
service, const char *key
                return 0;
 
        ret = 1;
-       if (dst)
-               *dst = line;
-       else
-               free(line);
-
+       switch(service) {
+       case K_AUTHENTICATE: {
+               char authy[] = "AUTHENTICATED";
+               char authn[] = "INCORRECT-AUTH";
+               if (crypt_checkpass(data, line) == 0){
+                       *dst = strdup(authy);
+                       ret = 1;
+               }
+               else{
+                       *dst = strdup(authn);
+                       ret = 0;
+               }
+               break;
+       }
+       default:
+               if (dst)
+                       *dst = line;
+               else
+                       free(line);
+               ret = 1;
+               break;
+       }
        return ret;
 }
 
diff --git a/usr.sbin/smtpd/table_getpwnam.c b/usr.sbin/smtpd/table_getpwnam.c
index d40f1920073..9d9086ae67c 100644
--- a/usr.sbin/smtpd/table_getpwnam.c
+++ b/usr.sbin/smtpd/table_getpwnam.c
@@ -26,7 +26,7 @@ static int table_getpwnam_config(struct table *);
 static int table_getpwnam_update(struct table *);
 static int table_getpwnam_open(struct table *);
 static int table_getpwnam_lookup(struct table *, enum table_service, const 
char *,
-    char **);
+    const char *, char **);
 static void table_getpwnam_close(struct table *);
 
 struct table_backend table_backend_getpwnam = {
@@ -70,7 +70,7 @@ table_getpwnam_close(struct table *table)
 
 static int
 table_getpwnam_lookup(struct table *table, enum table_service kind, const char 
*key,
-    char **dst)
+    const char *data, char **dst)
 {
        struct passwd          *pw;
 
diff --git a/usr.sbin/smtpd/table_proc.c b/usr.sbin/smtpd/table_proc.c
index 56893a0fb61..6d903492740 100644
--- a/usr.sbin/smtpd/table_proc.c
+++ b/usr.sbin/smtpd/table_proc.c
@@ -169,7 +169,7 @@ imsg_add_params(struct ibuf *buf)
 }
 
 static int
-table_proc_lookup(struct table *table, enum table_service s, const char *k, 
char **dst)
+table_proc_lookup(struct table *table, enum table_service s, const char *k, 
const char *data, char **dst)
 {
        struct table_proc_priv  *priv = table->t_handle;
        struct ibuf             *buf;
diff --git a/usr.sbin/smtpd/table_static.c b/usr.sbin/smtpd/table_static.c
index af57038f231..c4f5f774ed5 100644
--- a/usr.sbin/smtpd/table_static.c
+++ b/usr.sbin/smtpd/table_static.c
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "smtpd.h"
 #include "log.h"
@@ -38,7 +39,7 @@ static void table_static_dump(struct table *);
 static int table_static_update(struct table *);
 static int table_static_open(struct table *);
 static int table_static_lookup(struct table *, enum table_service, const char 
*,
-    char **);
+    const char *, char **);
 static int table_static_fetch(struct table *, enum table_service, char **);
 static void table_static_close(struct table *);
 
@@ -314,7 +315,7 @@ table_static_close(struct table *table)
 
 static int
 table_static_lookup(struct table *table, enum table_service service, const 
char *key,
-    char **dst)
+    const char *data, char **dst)
 {
        struct table_static_priv *priv = table->t_handle;
        char           *line;
@@ -355,11 +356,29 @@ table_static_lookup(struct table *table, enum 
table_service service, const char
        if (ret == 0)
                return 0;
 
-       *dst = strdup(line);
+       int ans;
+       switch(service) {
+       case K_AUTHENTICATE: {
+               char authy[] = "AUTHENTICATED";
+               char authn[] = "INCORRECT-AUTH";
+               if (crypt_checkpass(data, line) == 0){
+                       *dst = strdup(authy);
+                       ans = 1;
+               }
+               else{
+                       *dst = strdup(authn);
+                       ans = 0;
+               }
+               break;
+       }
+       default:
+               *dst = strdup(line);
+               ans = 1;
+               break;
+       }
        if (*dst == NULL)
                return -1;
-
-       return 1;
+       return ans;
 }
 
 static int

Reply via email to