On 21/10/08 05:34PM, aisha wrote: > 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 >
Same patch but change my horrible enums representation to bitshifts 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..0052d66366a 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 = 1<<1, /* returns struct destination */ + K_AUTHENTICATE = 1<<2, /* returns int authenticated */ + K_CREDENTIALS = 1<<3, /* returns struct credentials */ + K_NETADDR = 1<<4, /* returns struct netaddr */ + K_USERINFO = 1<<5, /* returns struct userinfo */ + K_SOURCE = 1<<6, /* returns struct source */ + K_MAILADDR = 1<<7, /* returns struct mailaddr */ + K_ADDRNAME = 1<<8, /* returns struct addrname */ + K_MAILADDRMAP = 1<<9, /* returns struct maddrmap */ + K_RELAYHOST = 1<<10, /* returns struct relayhost */ + K_STRING = 1<<11, + K_REGEX = 1<<12 }; -#define K_ANY 0xfff +#define K_ANY ((1<<13)-1) 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