userdb.c revision 2521482f3f897c83f7d5a2f9e17fe99fa4ba2cbe
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "common.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "auth-module.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "auth-worker-server.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "userdb.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <stdlib.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <pwd.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <grp.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_prefetch;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_static;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_passwd;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_passwd_file;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_vpopmail;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_ldap;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_sql;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenextern struct userdb_module_interface userdb_nss;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct userdb_module_interface *userdb_interfaces[] = {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_PASSWD
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_passwd,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_PASSWD_FILE
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_passwd_file,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_PREFETCH
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_prefetch,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_STATIC
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_static,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_VPOPMAIL
a21f618de284dc22a480af1371d5f5cea50a39dfTimo Sirainen &userdb_vpopmail,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_LDAP
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_ldap,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_SQL
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_sql,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef USERDB_NSS
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &userdb_nss,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen NULL
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen};
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenuid_t userdb_parse_uid(struct auth_request *request, const char *str)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct passwd *pw;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen uid_t uid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen char *p;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (str == NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return (uid_t)-1;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*str >= '0' && *str <= '9') {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen uid = (uid_t)strtoul(str, &p, 10);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*p == '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return uid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pw = getpwnam(str);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (pw == NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (request != NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_request_log_error(request, "userdb",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "Invalid UID value '%s'", str);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return (uid_t)-1;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return pw->pw_uid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainengid_t userdb_parse_gid(struct auth_request *request, const char *str)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct group *gr;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen gid_t gid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen char *p;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (str == NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return (gid_t)-1;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*str >= '0' && *str <= '9') {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen gid = (gid_t)strtoul(str, &p, 10);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*p == '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return gid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen gr = getgrnam(str);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (gr == NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (request != NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_request_log_error(request, "userdb",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "Invalid GID value '%s'", str);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return (gid_t)-1;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return gr->gr_gid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid userdb_preinit(struct auth *auth, const char *driver, const char *args)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct userdb_module_interface **p, *iface;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct auth_userdb *auth_userdb, **dest;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (args == NULL) args = "";
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_userdb = p_new(auth->pool, struct auth_userdb, 1);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_userdb->auth = auth;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_userdb->args = p_strdup(auth->pool, args);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (dest = &auth->userdbs; *dest != NULL; dest = &(*dest)->next)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_userdb->num++;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen *dest = auth_userdb;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen iface = NULL;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (p = userdb_interfaces; *p != NULL; p++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (strcmp((*p)->name, driver) == 0) {
d48e40d6c77d673ad402d96571198d1cce4da225Timo Sirainen iface = *p;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen break;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
a327d9301f593433c228c4cc8cca05c95b37f6fbTimo Sirainen#ifdef HAVE_MODULES
d48e40d6c77d673ad402d96571198d1cce4da225Timo Sirainen if (auth_userdb->userdb == NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_userdb->module = auth_module_open(driver);
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen if (auth_userdb->module != NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen iface = auth_module_sym(auth_userdb->module,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen t_strconcat("userdb_", driver, NULL));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (iface == NULL) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("Unknown userdb driver '%s' "
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "(typo, or Dovecot was built without support for it? "
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "Check with dovecot --build-options)",
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen driver);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen }
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen if (iface->preinit == NULL) {
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_userdb->userdb =
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen p_new(auth->pool, struct userdb_module, 1);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen } else {
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_userdb->userdb =
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen iface->preinit(auth_userdb, auth_userdb->args);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen }
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_userdb->userdb->iface = iface;
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen}
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenvoid userdb_init(struct auth_userdb *userdb)
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (userdb->userdb->iface->init != NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen userdb->userdb->iface->init(userdb->userdb, userdb->args);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (userdb->userdb->blocking && !worker) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* blocking userdb - we need an auth server */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_worker_server_init();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid userdb_deinit(struct auth_userdb *userdb)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (userdb->userdb->iface->deinit != NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen userdb->userdb->iface->deinit(userdb->userdb);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#ifdef HAVE_MODULES
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (userdb->module != NULL)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_module_close(&userdb->module);
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen#endif
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen