userdb.c revision 747e77e3ab073a8e9e69c7a3e71b4593c5655d03
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include "common.h"
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include "auth-module.h"
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include "auth-worker-server.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "userdb.h"
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include <stdlib.h>
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include <pwd.h>
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#include <grp.h>
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_prefetch;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_static;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_passwd;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_passwd_file;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_vpopmail;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_ldap;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct userdb_module_interface userdb_sql;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct userdb_module_interface *userdb_interfaces[] = {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_PASSWD
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_passwd,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_PASSWD_FILE
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_passwd_file,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_PREFETCH
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_prefetch,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_STATIC
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_static,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_VPOPMAIL
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_vpopmail,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_LDAP
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_ldap,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef USERDB_SQL
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch &userdb_sql,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch NULL
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch};
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschuid_t userdb_parse_uid(struct auth_request *request, const char *str)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch{
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct passwd *pw;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (str == NULL)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return (uid_t)-1;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (*str >= '0' && *str <= '9')
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return (uid_t)strtoul(str, NULL, 10);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch pw = getpwnam(str);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch if (pw == NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (request != NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_request_log_error(request, "userdb",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Invalid UID field '%s'", str);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch }
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return (uid_t)-1;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch }
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return pw->pw_uid;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch}
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschgid_t userdb_parse_gid(struct auth_request *request, const char *str)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch{
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct group *gr;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (str == NULL)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return (uid_t)-1;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (*str >= '0' && *str <= '9')
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return (gid_t)strtoul(str, NULL, 10);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch gr = getgrnam(str);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (gr == NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (request != NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_request_log_error(request, "userdb",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Invalid GID field '%s'", str);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return (gid_t)-1;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return gr->gr_gid;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch}
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid userdb_preinit(struct auth *auth, const char *driver, const char *args)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch{
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct userdb_module_interface **p, *iface;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct auth_userdb *auth_userdb, **dest;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (args == NULL) args = "";
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen auth_userdb = p_new(auth->pool, struct auth_userdb, 1);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->auth = auth;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->args = p_strdup(auth->pool, args);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (dest = &auth->userdbs; *dest != NULL; dest = &(*dest)->next)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->num++;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch *dest = auth_userdb;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch iface = NULL;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (p = userdb_interfaces; *p != NULL; p++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (strcmp((*p)->name, driver) == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch iface = *p;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch break;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef HAVE_MODULES
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (auth_userdb->userdb == NULL)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->module = auth_module_open(driver);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (auth_userdb->module != NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch iface = auth_module_sym(auth_userdb->module,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch t_strconcat("userdb_", driver, NULL));
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (iface == NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch i_fatal("Unknown userdb driver '%s' "
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "(typo, or Dovecot was built without support for it? "
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Check with dovecot --build-options)",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch driver);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (iface->preinit == NULL) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->userdb =
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch p_new(auth->pool, struct userdb_module, 1);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch } else {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->userdb =
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch iface->preinit(auth_userdb, auth_userdb->args);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_userdb->userdb->iface = iface;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch}
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid userdb_init(struct auth_userdb *userdb)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch{
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (userdb->userdb->iface->init != NULL)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch userdb->userdb->iface->init(userdb->userdb, userdb->args);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (userdb->userdb->blocking && !worker) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* blocking userdb - we need an auth server */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_worker_server_init();
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch }
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch}
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid userdb_deinit(struct auth_userdb *userdb)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch{
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (userdb->userdb->iface->deinit != NULL)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch userdb->userdb->iface->deinit(userdb->userdb);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#ifdef HAVE_MODULES
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (userdb->module != NULL)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch auth_module_close(userdb->module);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch#endif
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch}
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch