dovecot: Added userdb nss which currently supports glibc-compati...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jul 3 01:50:20 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/c9b49ed99d28
changeset: 5870:c9b49ed99d28
user: Timo Sirainen <tss at iki.fi>
date: Tue Jul 03 01:50:13 2007 +0300
description:
Added userdb nss which currently supports glibc-compatible NSS modules.
diffstat:
4 files changed, 180 insertions(+), 1 deletion(-)
configure.in | 20 ++++++
src/auth/Makefile.am | 3
src/auth/userdb-nss.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++
src/auth/userdb.c | 4 +
diffs (240 lines):
diff -r 38ff50597e54 -r c9b49ed99d28 configure.in
--- a/configure.in Tue Jul 03 00:30:48 2007 +0300
+++ b/configure.in Tue Jul 03 01:50:13 2007 +0300
@@ -81,6 +81,15 @@ AC_ARG_WITH(passwd,
want_passwd=yes
fi,
want_passwd=yes)
+
+AC_ARG_WITH(passwd,
+[ --with-nss Build with NSS module support (default)],
+ if test x$withval = xno; then
+ want_nss=no
+ else
+ want_nss=yes
+ fi,
+ want_nss=yes)
AC_ARG_WITH(passwd-file,
[ --with-passwd-file Build with passwd-like file support (default)],
@@ -1804,6 +1813,17 @@ if test $have_modules = yes; then
AC_SUBST(MODULE_LIBS)
fi
+if test $want_nss = yes && test $have_modules = yes; then
+ AC_TRY_COMPILE([
+ #include <nss.h>
+ ], [
+ enum nss_status status = NSS_STATUS_TRYAGAIN;
+ ], [
+ AC_DEFINE(USERDB_NSS,, Build with NSS module support)
+ userdb="$userdb nss"
+ ])
+fi
+
AC_SUBST(AUTH_CFLAGS)
AC_SUBST(AUTH_LIBS)
AC_SUBST(SQL_CFLAGS)
diff -r 38ff50597e54 -r c9b49ed99d28 src/auth/Makefile.am
--- a/src/auth/Makefile.am Tue Jul 03 00:30:48 2007 +0300
+++ b/src/auth/Makefile.am Tue Jul 03 01:50:13 2007 +0300
@@ -68,11 +68,11 @@ dovecot_auth_SOURCES = \
passdb-blocking.c \
passdb-bsdauth.c \
passdb-cache.c \
+ passdb-checkpassword.c \
passdb-ldap.c \
passdb-passwd.c \
passdb-passwd-file.c \
passdb-pam.c \
- passdb-checkpassword.c \
passdb-shadow.c \
passdb-sia.c \
passdb-vpopmail.c \
@@ -80,6 +80,7 @@ dovecot_auth_SOURCES = \
userdb.c \
userdb-blocking.c \
userdb-ldap.c \
+ userdb-nss.c \
userdb-passwd.c \
userdb-passwd-file.c \
userdb-prefetch.c \
diff -r 38ff50597e54 -r c9b49ed99d28 src/auth/userdb-nss.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/auth/userdb-nss.c Tue Jul 03 01:50:13 2007 +0300
@@ -0,0 +1,154 @@
+/* Copyright (C) 2007 Timo Sirainen */
+
+/* Currently supports only GLIBC-compatible NSS modules */
+
+#include "common.h"
+
+#ifdef USERDB_NSS
+
+#include "module-dir.h"
+#include "userdb.h"
+
+#include <pwd.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <nss.h>
+
+#define USER_CACHE_KEY "%u"
+
+struct nss_userdb_module {
+ struct userdb_module module;
+
+ char *buf;
+ size_t bufsize;
+
+ struct module nss_module;
+ enum nss_status (*getpwnam_r)(const char *name, struct passwd *pwd,
+ char *buffer, size_t buflen, int *errnop);
+};
+
+static void
+userdb_nss_lookup(struct auth_request *auth_request,
+ userdb_callback_t *callback)
+{
+ struct userdb_module *_module = auth_request->userdb->userdb;
+ struct nss_userdb_module *module = (struct nss_userdb_module *)_module;
+ struct auth_stream_reply *reply;
+ struct passwd pw;
+ enum nss_status status;
+ enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
+ int err;
+
+ auth_request_log_debug(auth_request, "nss", "lookup");
+
+ status = module->getpwnam_r(auth_request->user, &pw,
+ module->buf, module->bufsize, &err);
+ switch (status) {
+ case NSS_STATUS_TRYAGAIN:
+ auth_request_log_error(auth_request, "nss",
+ "returned tryagain (err=%d)", err);
+ break;
+ case NSS_STATUS_UNAVAIL:
+ auth_request_log_error(auth_request, "nss",
+ "unavailable (err=%d)", err);
+ break;
+ case NSS_STATUS_NOTFOUND:
+ auth_request_log_info(auth_request, "nss", "unknown user");
+ result = USERDB_RESULT_USER_UNKNOWN;
+ break;
+ case NSS_STATUS_SUCCESS:
+ result = USERDB_RESULT_OK;
+ break;
+ default:
+ auth_request_log_info(auth_request, "nss",
+ "returned %d (err=%d)", status, err);
+ break;
+ }
+
+ if (result != USERDB_RESULT_OK) {
+ callback(result, NULL, auth_request);
+ return;
+ }
+
+ reply = auth_stream_reply_init(auth_request);
+ auth_stream_reply_add(reply, NULL, pw.pw_name);
+ auth_stream_reply_add(reply, "system_user", pw.pw_name);
+ auth_stream_reply_add(reply, "uid", dec2str(pw.pw_uid));
+ auth_stream_reply_add(reply, "gid", dec2str(pw.pw_gid));
+ auth_stream_reply_add(reply, "home", pw.pw_dir);
+
+ callback(USERDB_RESULT_OK, reply, auth_request);
+}
+
+static void
+userdb_nss_load_module(struct nss_userdb_module *module, pool_t pool)
+{
+ const char *name = module->nss_module.name;
+ char *path;
+
+ path = p_strdup_printf(pool, "/usr/lib/libnss_%s.so", name);
+ module->nss_module.handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW);
+ if (module->nss_module.handle == NULL)
+ i_fatal("dlopen(%s) failed: %s", path, dlerror());
+ module->nss_module.path = path;
+
+ module->getpwnam_r =
+ module_get_symbol(&module->nss_module,
+ t_strdup_printf("_nss_%s_getpwnam_r", name));
+ if (module->getpwnam_r == NULL)
+ i_fatal("userdb nss: Module %s missing getpwnam_r()", path);
+}
+
+static struct userdb_module *
+userdb_nss_preinit(struct auth_userdb *auth_userdb, const char *args)
+{
+ struct nss_userdb_module *module;
+ const char *const *tmp;
+ pool_t pool = auth_userdb->auth->pool;
+
+ module = p_new(pool, struct nss_userdb_module, 1);
+ module->bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ module->buf = p_malloc(pool, module->bufsize);
+
+ t_push();
+ for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
+ if (strcmp(*tmp, "blocking=yes") == 0)
+ module->module.blocking = TRUE;
+ else if (strncmp(*tmp, "service=", 8) == 0)
+ module->nss_module.name = p_strdup(pool, *tmp + 8);
+ else
+ i_fatal("userdb nss: Unknown parameter: %s", *tmp);
+ }
+ t_pop();
+
+ if (module->nss_module.name == NULL)
+ i_fatal("userdb nss: Missing service");
+ userdb_nss_load_module(module, pool);
+
+ module->module.cache_key = USER_CACHE_KEY;
+ return &module->module;
+}
+
+static void userdb_nss_deinit(struct userdb_module *_module)
+{
+ struct nss_userdb_module *module = (struct nss_userdb_module *)_module;
+ void (*endpwent)(void);
+
+ endpwent = module_get_symbol(&module->nss_module,
+ t_strdup_printf("_nss_%s_endpwent",
+ module->nss_module.name));
+ if (endpwent != NULL)
+ endpwent();
+}
+
+struct userdb_module_interface userdb_nss = {
+ "nss",
+
+ userdb_nss_preinit,
+ NULL,
+ userdb_nss_deinit,
+
+ userdb_nss_lookup
+};
+
+#endif
diff -r 38ff50597e54 -r c9b49ed99d28 src/auth/userdb.c
--- a/src/auth/userdb.c Tue Jul 03 00:30:48 2007 +0300
+++ b/src/auth/userdb.c Tue Jul 03 01:50:13 2007 +0300
@@ -16,6 +16,7 @@ extern struct userdb_module_interface us
extern struct userdb_module_interface userdb_vpopmail;
extern struct userdb_module_interface userdb_ldap;
extern struct userdb_module_interface userdb_sql;
+extern struct userdb_module_interface userdb_nss;
struct userdb_module_interface *userdb_interfaces[] = {
#ifdef USERDB_PASSWD
@@ -38,6 +39,9 @@ struct userdb_module_interface *userdb_i
#endif
#ifdef USERDB_SQL
&userdb_sql,
+#endif
+#ifdef USERDB_NSS
+ &userdb_nss,
#endif
NULL
};
More information about the dovecot-cvs
mailing list