introduce a new K_AUTH service to allow offloading the credentials to a
authorgilles <gilles@openbsd.org>
Sun, 9 Jun 2024 10:13:05 +0000 (10:13 +0000)
committergilles <gilles@openbsd.org>
Sun, 9 Jun 2024 10:13:05 +0000 (10:13 +0000)
table for non-crypt(3) authentication. tables configured with auth that
support K_AUTH are asked to check if a user and passwd are valid rather
than asked to provide the password for a user so smtpd does crypt(3) on
its side. helps with cases like ldap or custom auth.

ok op@

usr.sbin/smtpd/lka.c
usr.sbin/smtpd/smtpd-api.h
usr.sbin/smtpd/smtpd-tables.7
usr.sbin/smtpd/table.c

index bd75798..7ecf67d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: lka.c,v 1.248 2024/01/20 09:01:03 claudio Exp $       */
+/*     $OpenBSD: lka.c,v 1.249 2024/06/09 10:13:05 gilles Exp $        */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -720,6 +720,7 @@ static int
 lka_authenticate(const char *tablename, const char *user, const char *password)
 {
        struct table            *table;
+       char                     offloadkey[LINE_MAX];
        union lookup             lk;
 
        log_debug("debug: lka: authenticating for %s:%s", tablename, user);
@@ -730,6 +731,26 @@ lka_authenticate(const char *tablename, const char *user, const char *password)
                return (LKA_TEMPFAIL);
        }
 
+       /* table backend supports authentication offloading */
+       if (table_check_service(table, K_AUTH)) {
+               if (!bsnprintf(offloadkey, sizeof(offloadkey), "%s:%s",
+                   user, password)) {
+                       log_warnx("warn: key serialization failed for %s:%s",
+                           tablename, user);
+                       return (LKA_TEMPFAIL);
+               }
+               switch (table_match(table, K_AUTH, offloadkey)) {
+               case -1:
+                       log_warnx("warn: user credentials lookup fail for %s:%s",
+                           tablename, user);
+                       return (LKA_TEMPFAIL);
+               case 0:
+                       return (LKA_PERMFAIL);
+               default:
+                       return (LKA_OK);
+               }
+       }
+
        switch (table_lookup(table, K_CREDENTIALS, user, &lk)) {
        case -1:
                log_warnx("warn: user credentials lookup fail for %s:%s",
index f83edd0..4f362dc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtpd-api.h,v 1.36 2018/12/23 16:06:24 gilles Exp $   */
+/*     $OpenBSD: smtpd-api.h,v 1.37 2024/06/09 10:13:05 gilles Exp $   */
 
 /*
  * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -135,8 +135,9 @@ enum table_service {
        K_RELAYHOST     = 0x200,        /* returns struct relayhost     */
        K_STRING        = 0x400,
        K_REGEX         = 0x800,
+       K_AUTH          = 0x1000,
 };
-#define K_ANY            0xfff
+#define K_ANY            0xffff
 
 enum {
        PROC_TABLE_OK,
index c5cd954..42056f9 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: smtpd-tables.7,v 1.3 2024/05/23 17:10:00 op Exp $
+.\"    $OpenBSD: smtpd-tables.7,v 1.4 2024/06/09 10:13:05 gilles Exp $
 .\"
 .\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
 .\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -18,7 +18,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
 .\"
-.Dd $Mdocdate: May 23 2024 $
+.Dd $Mdocdate: June 9 2024 $
 .Dt SMTPD-TABLES 7
 .Os
 .Sh NAME
@@ -191,6 +191,10 @@ The services and their result format are as follows:
 .Bl -tag -width mailaddrmap -compact
 .It Ic alias
 One or more aliases separated by a comma.
+.It Ic auth
+Only usable for check.
+Lookup key is username and cleartext password separated by
+.Sq \&: .
 .It Ic domain
 A domain name.
 .\" XXX are wildcards allowed?
index 2b9c9cf..aca013d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: table.c,v 1.53 2024/05/28 07:10:30 op Exp $   */
+/*     $OpenBSD: table.c,v 1.54 2024/06/09 10:13:05 gilles Exp $       */
 
 /*
  * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -83,6 +83,7 @@ table_service_name(enum table_service s)
        case K_RELAYHOST:       return "relayhost";
        case K_STRING:          return "string";
        case K_REGEX:           return "regex";
+       case K_AUTH:            return "auth";
        }
        return "???";
 }
@@ -116,6 +117,8 @@ table_service_from_name(const char *service)
                return K_STRING;
        if (!strcmp(service, "regex"))
                return K_REGEX;
+       if (!strcmp(service, "auth"))
+               return K_AUTH;
        return (-1);
 }