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