doesn't necessarily work :) Works now with new master config.
--HG--
branch : HEAD
Makefile
Makefile.in
so_locations
-imap-auth
+dovecot-auth
pkglibexecdir = $(libexecdir)/dovecot
-pkglibexec_PROGRAMS = imap-auth
+pkglibexec_PROGRAMS = dovecot-auth
INCLUDES = \
-I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-settings \
$(VPOPMAIL_CFLAGS)
-imap_auth_LDADD = \
+dovecot_auth_LDADD = \
+ ../lib-settings/libsettings.a \
../lib/liblib.a \
$(PASSDB_LIBS) \
$(SASL_LIBS) \
$(VPOPMAIL_LIBS)
-imap_auth_SOURCES = \
+dovecot_auth_SOURCES = \
+ db-ldap.c \
+ db-passwd-file.c \
login-connection.c \
main.c \
master-connection.c \
passdb-pam.c \
passdb-shadow.c \
passdb-vpopmail.c \
- passwd-file.c \
userdb.c \
+ userdb-ldap.c \
userdb-passwd.c \
userdb-passwd-file.c \
userdb-static.c \
auth-login-interface.h \
auth-master-interface.h \
auth-mech-desc.h \
+ db-passwd-file.h \
common.h \
login-connection.h \
master-connection.h \
mech.h \
mycrypt.h \
passdb.h \
- passwd-file.h \
userdb.h \
userdb-vpopmail.h
--- /dev/null
+/* Copyright (C) 2003 Timo Sirainen */
+
+#include "config.h"
+#undef HAVE_CONFIG_H
+
+#if defined(PASSDB_LDAP) || defined(USERDB_LDAP)
+
+#include "common.h"
+#include "ioloop.h"
+#include "hash.h"
+#include "settings.h"
+#include "db-ldap.h"
+
+#include <stddef.h>
+
+#define DEF(type, name) \
+ { type, #name, offsetof(struct ldap_settings, name) }
+
+static struct setting_def setting_defs[] = {
+ DEF(SET_STR, hosts),
+ DEF(SET_STR, user),
+ DEF(SET_STR, pass),
+ DEF(SET_STR, deref),
+ DEF(SET_STR, base),
+ DEF(SET_STR, attrs),
+ DEF(SET_STR, filter)
+};
+
+struct ldap_settings default_ldap_settings = {
+ MEMBER(hosts) "localhost",
+ MEMBER(user) NULL,
+ MEMBER(pass) NULL,
+ MEMBER(deref) "never",
+ MEMBER(base) NULL,
+ MEMBER(attrs) NULL,
+ MEMBER(filter) NULL
+};
+
+static int ldap_conn_open(struct ldap_connection *conn);
+
+static int deref2str(const char *str)
+{
+ if (strcasecmp(str, "never") == 0)
+ return LDAP_DEREF_NEVER;
+ if (strcasecmp(str, "searching") == 0)
+ return LDAP_DEREF_SEARCHING;
+ if (strcasecmp(str, "finding") == 0)
+ return LDAP_DEREF_FINDING;
+ if (strcasecmp(str, "always") == 0)
+ return LDAP_DEREF_ALWAYS;
+
+ i_fatal("LDAP: Unknown deref option '%s'", str);
+}
+
+static const char *get_ldap_error(struct ldap_connection *conn)
+{
+ int ret, err;
+
+ ret = ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, (void *) &err);
+ if (ret != LDAP_SUCCESS) {
+ i_error("LDAP: Can't get error number: %s",
+ ldap_err2string(ret));
+ return "??";
+ }
+
+ return ldap_err2string(err);
+}
+
+void db_ldap_search(struct ldap_connection *conn, const char *base, int scope,
+ const char *filter, char **attributes,
+ struct ldap_request *request)
+{
+ int msgid;
+
+ if (!conn->connected) {
+ if (!ldap_conn_open(conn)) {
+ request->callback(conn, request, NULL);
+ return;
+ }
+ }
+
+ msgid = ldap_search(conn->ld, base, scope, filter, attributes, 0);
+ if (msgid == -1) {
+ i_error("LDAP: ldap_search() failed (filter %s): %s",
+ filter, get_ldap_error(conn));
+ request->callback(conn, request, NULL);
+ return;
+ }
+
+ hash_insert(conn->requests, POINTER_CAST(msgid), request);
+}
+
+static void ldap_input(void *context)
+{
+ struct ldap_connection *conn = context;
+ struct ldap_request *request;
+ struct timeval timeout;
+ LDAPMessage *res;
+ int ret, msgid;
+
+ for (;;) {
+ memset(&timeout, 0, sizeof(timeout));
+ ret = ldap_result(conn->ld, LDAP_RES_ANY, 1, &timeout, &res);
+ if (ret <= 0) {
+ if (ret < 0) {
+ i_error("LDAP: ldap_result() failed: %s",
+ get_ldap_error(conn));
+ }
+ return;
+ }
+
+ ret = ldap_result2error(conn->ld, res, 0);
+ if (ret != LDAP_SUCCESS) {
+ i_error("LDAP: ldap_result() failed: %s",
+ ldap_err2string(ret));
+ } else {
+ msgid = ldap_msgid(res);
+
+ request = hash_lookup(conn->requests,
+ POINTER_CAST(msgid));
+ if (request != NULL) {
+ request->callback(conn, request, res);
+ hash_remove(conn->requests,
+ POINTER_CAST(msgid));
+ i_free(request);
+ } else {
+ i_error("LDAP: Reply with unknown msgid %d",
+ msgid);
+ }
+ }
+
+ ldap_msgfree(res);
+ }
+}
+
+static int ldap_conn_open(struct ldap_connection *conn)
+{
+ int ret, fd;
+
+ if (conn->connected)
+ return TRUE;
+
+ if (conn->ld == NULL) {
+ conn->ld = ldap_init(conn->set.hosts, LDAP_PORT);
+ if (conn->ld == NULL)
+ i_fatal("LDAP: ldap_init() failed with hosts: %s",
+ conn->set.hosts);
+
+ ret = ldap_set_option(conn->ld, LDAP_OPT_DEREF,
+ (void *) &conn->set.ldap_deref);
+ if (ret != LDAP_SUCCESS) {
+ i_fatal("LDAP: Can't set deref option: %s",
+ ldap_err2string(ret));
+ }
+ }
+
+ /* NOTE: we use blocking connect, we couldn't do anything anyway
+ until it's done. */
+ ret = ldap_simple_bind_s(conn->ld, conn->set.user, conn->set.pass);
+ if (ret != LDAP_SUCCESS) {
+ i_error("LDAP: ldap_simple_bind_s() failed: %s",
+ ldap_err2string(ret));
+ return FALSE;
+ }
+
+ conn->connected = TRUE;
+
+ /* register LDAP input to ioloop */
+ ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, (void *) &fd);
+ if (ret != LDAP_SUCCESS) {
+ i_fatal("LDAP: Can't get connection fd: %s",
+ ldap_err2string(ret));
+ }
+
+ conn->io = io_add(fd, IO_READ, ldap_input, conn);
+ return TRUE;
+}
+
+static void ldap_conn_close(struct ldap_connection *conn)
+{
+ if (conn->connected) {
+ io_remove(conn->io);
+ conn->io = NULL;
+
+ conn->connected = FALSE;
+ }
+
+ if (conn->ld != NULL) {
+ ldap_unbind(conn->ld);
+ conn->ld = NULL;
+ }
+}
+
+void db_ldap_set_attrs(struct ldap_connection *conn, const char *value,
+ unsigned int **attrs, char ***attr_names)
+{
+ const char *const *attr;
+ unsigned int i, dest, size;
+
+ attr = t_strsplit(value, ",");
+ if (*attr == NULL || **attr == '\0')
+ i_fatal("Missing uid field in attrs");
+
+ for (size = 0; attr[size] != NULL; size++) ;
+
+ /* +1 for terminating NULL */
+ *attrs = p_new(conn->pool, unsigned int, size);
+ *attr_names = p_new(conn->pool, char *, size + 1);
+ for (i = 0, dest = 0; *attr != NULL; i++, attr++) {
+ if (**attr != '\0') {
+ (*attrs)[dest] = i;
+ (*attr_names)[dest] = p_strdup(conn->pool, *attr);
+ dest++;
+ }
+ }
+}
+
+static const char *parse_setting(const char *key, const char *value,
+ void *context)
+{
+ struct ldap_connection *conn = context;
+
+ return parse_setting_from_defs(conn->pool, setting_defs,
+ &conn->set, key, value);
+}
+
+struct ldap_connection *db_ldap_init(const char *config_path)
+{
+ struct ldap_connection *conn;
+ pool_t pool;
+
+ pool = pool_alloconly_create("ldap_connection", 1024);
+ conn = p_new(pool, struct ldap_connection, 1);
+ conn->pool = pool;
+
+ conn->refcount = 1;
+ conn->requests = hash_create(default_pool, pool, 0, NULL, NULL);
+
+ conn->set = default_ldap_settings;
+ settings_read(config_path, parse_setting, conn);
+
+ if (conn->set.user == NULL)
+ i_fatal("LDAP: No user given");
+ if (conn->set.pass == NULL)
+ i_fatal("LDAP: No password given");
+ if (conn->set.base == NULL)
+ i_fatal("LDAP: No base given");
+
+ conn->set.ldap_deref = deref2str(conn->set.deref);
+
+ (void)ldap_conn_open(conn);
+ return conn;
+}
+
+void db_ldap_unref(struct ldap_connection *conn)
+{
+ if (--conn->refcount > 0)
+ return;
+
+ ldap_conn_close(conn);
+
+ hash_destroy(conn->requests);
+ pool_unref(conn->pool);
+}
+
+#endif
--- /dev/null
+#ifndef __DB_LDAP_H
+#define __DB_LDAP_H
+
+#include <ldap.h>
+
+struct ldap_connection;
+struct ldap_request;
+
+typedef void db_search_callback_t(struct ldap_connection *conn,
+ struct ldap_request *request,
+ LDAPMessage *res);
+
+struct ldap_settings {
+ const char *hosts;
+ const char *user;
+ const char *pass;
+ const char *deref;
+ const char *base;
+ const char *attrs;
+ const char *filter;
+
+ int ldap_deref;
+};
+
+struct ldap_connection {
+ pool_t pool;
+ int refcount;
+
+ char *config_path;
+ struct ldap_settings set;
+
+ LDAP *ld;
+ struct io *io;
+ struct hash_table *requests;
+
+ unsigned int connected:1;
+};
+
+struct ldap_request {
+ db_search_callback_t *callback;
+ void *context;
+};
+
+void db_ldap_search(struct ldap_connection *conn, const char *base, int scope,
+ const char *filter, char **attributes,
+ struct ldap_request *request);
+
+void db_ldap_set_attrs(struct ldap_connection *conn, const char *value,
+ unsigned int **attrs, char ***attr_names);
+
+struct ldap_connection *db_ldap_init(const char *config_path);
+void db_ldap_unref(struct ldap_connection *conn);
+
+#endif
#include "common.h"
#include "userdb.h"
-#include "passwd-file.h"
+#include "db-passwd-file.h"
#include "buffer.h"
#include "istream.h"
}
}
-struct passwd_file *passwd_file_parse(const char *path)
+static void passwd_file_sync(struct passwd_file *pw)
+{
+ struct stat st;
+
+ if (stat(pw->path, &st) < 0)
+ i_fatal("stat() failed for %s: %m", pw->path);
+
+ if (st.st_mtime != pw->stamp) {
+ passwd_file_close(pw);
+ passwd_file_open(pw);
+ }
+}
+
+struct passwd_file *db_passwd_file_parse(const char *path)
{
struct passwd_file *pw;
return pw;
}
-void passwd_file_unref(struct passwd_file *pw)
+void db_passwd_file_unref(struct passwd_file *pw)
{
if (--pw->refcount == 0) {
passwd_file_close(pw);
}
}
-static void passwd_file_sync(struct passwd_file *pw)
-{
- struct stat st;
-
- if (stat(pw->path, &st) < 0)
- i_fatal("stat() failed for %s: %m", pw->path);
-
- if (st.st_mtime != pw->stamp) {
- passwd_file_close(pw);
- passwd_file_open(pw);
- }
-}
-
struct passwd_user *
-passwd_file_lookup_user(struct passwd_file *pw,
- const char *user, const char *realm)
+db_passwd_file_lookup(struct passwd_file *pw,
+ const char *user, const char *realm)
{
struct passwd_user *pu;
-#ifndef __PASSWD_FILE_H
-#define __PASSWD_FILE_H
+#ifndef __DB_PASSWD_FILE_H
+#define __DB_PASSWD_FILE_H
enum password_type {
PASSWORD_NONE,
extern struct passwd_file *passdb_pwf;
struct passwd_user *
-passwd_file_lookup_user(struct passwd_file *pw,
- const char *user, const char *realm);
+db_passwd_file_lookup(struct passwd_file *pw,
+ const char *user, const char *realm);
-struct passwd_file *passwd_file_parse(const char *path);
-void passwd_file_unref(struct passwd_file *pw);
+struct passwd_file *db_passwd_file_parse(const char *path);
+void db_passwd_file_unref(struct passwd_file *pw);
#endif
i_stream_skip(conn->input, sizeof(rec));
if (rec.pid == 0) {
- i_error("BUG: imap-login said it's PID 0");
+ i_error("BUG: login said it's PID 0");
login_connection_destroy(conn);
} else if (login_connection_lookup(rec.pid) != NULL) {
/* well, it might have just reconnected very fast .. although
there's not much reason for it. */
- i_error("BUG: imap-login gave a PID of existing connection");
+ i_error("BUG: login gave a PID of existing connection");
login_connection_destroy(conn);
} else {
conn->pid = rec.pid;
safe_memset(data + sizeof(request), 0, request.data_size);
} else {
/* unknown request */
- i_error("BUG: imap-login sent us unknown request %u", type);
+ i_error("BUG: login sent us unknown request %u", type);
login_connection_destroy(conn);
}
}
return;
case -2:
/* buffer full */
- i_error("BUG: imap-login sent us more than %d bytes of data",
+ i_error("BUG: login sent us more than %d bytes of data",
(int)MAX_INBUF_SIZE);
login_connection_destroy(conn);
return;
static void open_logfile(void)
{
- if (getenv("IMAP_USE_SYSLOG") != NULL)
- i_set_failure_syslog("imap-auth", LOG_NDELAY, LOG_MAIL);
+ if (getenv("USE_SYSLOG") != NULL)
+ i_set_failure_syslog("dovecot-auth", LOG_NDELAY, LOG_MAIL);
else {
/* log to file or stderr */
- i_set_failure_file(getenv("IMAP_LOGFILE"), "imap-auth");
+ i_set_failure_file(getenv("LOGFILE"), "dovecot-auth");
}
- if (getenv("IMAP_INFOLOGFILE") != NULL)
- i_set_info_file(getenv("IMAP_INFOLOGFILE"));
+ if (getenv("INFOLOGFILE") != NULL)
+ i_set_info_file(getenv("INFOLOGFILE"));
- i_set_failure_timestamp_format(getenv("IMAP_LOGSTAMP"));
+ i_set_failure_timestamp_format(getenv("LOGSTAMP"));
}
static void drop_privileges(void)
{
int ret;
- ret = sasl_server_init(sasl_callbacks, "imap-auth");
+ ret = sasl_server_init(sasl_callbacks, "dovecot-auth");
if (ret != SASL_OK) {
i_fatal("sasl_server_init() failed: %s",
sasl_errstring(ret, NULL, NULL));
if ((auth_mechanisms & request->mech) == 0) {
/* unsupported mechanism */
- i_error("BUG: imap-login requested unsupported "
+ i_error("BUG: login requested unsupported "
"auth mechanism %d", request->mech);
failure_reply.id = request->id;
callback(&failure_reply, NULL, conn);
#include "common.h"
#include "passdb.h"
-#include "passwd-file.h"
+#include "db-passwd-file.h"
#include "hex-binary.h"
#include "md5.h"
unsigned char digest[16];
const char *str;
- pu = passwd_file_lookup_user(passdb_pwf, user, realm);
+ pu = db_passwd_file_lookup(passdb_pwf, user, realm);
if (pu == NULL) {
callback(PASSDB_RESULT_USER_UNKNOWN, context);
return;
{
struct passwd_user *pu;
- pu = passwd_file_lookup_user(passdb_pwf, user, realm);
+ pu = db_passwd_file_lookup(passdb_pwf, user, realm);
if (pu == NULL) {
callback(NULL, context);
return;
passdb_pwf = userdb_pwf;
passdb_pwf->refcount++;
} else {
- passdb_pwf = passwd_file_parse(args);
+ passdb_pwf = db_passwd_file_parse(args);
}
}
static void passwd_file_deinit(void)
{
- passwd_file_unref(passdb_pwf);
+ db_passwd_file_unref(passdb_pwf);
}
struct passdb_module passdb_passwd_file = {
if (name == NULL)
i_fatal("PASSDB environment is unset");
+ args = strchr(name, ' ');
+ name = t_strcut(name, ' ');
+
#ifdef PASSDB_PASSWD
if (strcasecmp(name, "passwd") == 0)
passdb = &passdb_passwd;
i_fatal("Unknown passdb type '%s'", name);
/* initialize */
- if (passdb->init != NULL) {
- args = getenv("PASSDB_ARGS");
- if (args == NULL) args = "";
-
- passdb->init(args);
- }
+ if (passdb->init != NULL)
+ passdb->init(args != NULL ? args+1 : "");
if ((auth_mechanisms & AUTH_MECH_PLAIN) &&
passdb->verify_plain == NULL)
--- /dev/null
+/* Copyright (C) 2003 Timo Sirainen */
+
+#include "config.h"
+#undef HAVE_CONFIG_H
+
+#if defined(PASSDB_LDAP) || defined(USERDB_LDAP)
+
+#include "common.h"
+#include "ioloop.h"
+#include "hash.h"
+#include "str.h"
+#include "db-ldap.h"
+#include "userdb.h"
+
+#include <ldap.h>
+#include <stdlib.h>
+
+/* using posixAccount */
+#define DEFAULT_ATTRIBUTES "uid,homeDirectory,,uid,uidNumber,gidNumber"
+
+enum ldap_user_attr {
+ ATTR_VIRTUAL_USER = 0,
+ ATTR_HOME,
+ ATTR_MAIL,
+ ATTR_SYSTEM_USER,
+ ATTR_UID_NUMBER,
+ ATTR_GID_NUMBER,
+ ATTR_CHROOT,
+
+ ATTR_COUNT
+};
+
+struct userdb_ldap_connection {
+ struct ldap_connection *conn;
+
+ unsigned int *attrs;
+ char **attr_names;
+};
+
+struct userdb_ldap_request {
+ struct ldap_request request;
+ userdb_callback_t *userdb_callback;
+};
+
+static struct userdb_ldap_connection *userdb_ldap_conn;
+
+static void parse_attr(struct userdb_ldap_connection *conn,
+ struct user_data *user,
+ const char *attr, const char *value)
+{
+ enum ldap_user_attr i;
+
+ for (i = 0; i < ATTR_COUNT; i++) {
+ if (strcasecmp(conn->attr_names[i], attr) == 0)
+ break;
+ }
+
+ if (i == ATTR_COUNT) {
+ i_error("LDAP: Unknown attribute '%s'", attr);
+ return;
+ }
+
+ switch (i) {
+ case ATTR_VIRTUAL_USER:
+ user->virtual_user = t_strdup(value);
+ break;
+ case ATTR_HOME:
+ user->home = t_strdup(value);
+ break;
+ case ATTR_MAIL:
+ user->mail = t_strdup(value);
+ break;
+ case ATTR_SYSTEM_USER:
+ user->system_user = t_strdup(value);
+ break;
+ case ATTR_UID_NUMBER:
+ user->uid = atoi(value);
+ break;
+ case ATTR_GID_NUMBER:
+ user->gid = atoi(value);
+ break;
+ case ATTR_CHROOT:
+ user->chroot = value[0] == 'Y' || value[0] == 'y';
+ break;
+
+ case ATTR_COUNT:
+ break;
+ }
+}
+
+static void handle_request(struct ldap_connection *conn,
+ struct ldap_request *request, LDAPMessage *res)
+{
+ struct userdb_ldap_request *urequest =
+ (struct userdb_ldap_request *) request;
+ struct user_data user;
+ LDAPMessage *entry;
+ BerElement *ber;
+ char *attr, **vals;
+
+ entry = ldap_first_entry(conn->ld, res);
+ if (entry == NULL) {
+ i_error("LDAP: ldap_first_entry failed()");
+ return;
+ }
+
+ t_push();
+ memset(&user, 0, sizeof(user));
+
+ attr = ldap_first_attribute(conn->ld, entry, &ber);
+ while (attr != NULL) {
+ vals = ldap_get_values(conn->ld, entry, attr);
+ if (vals != NULL && vals[0] != NULL && vals[1] == NULL) {
+ parse_attr(userdb_ldap_conn, &user, attr, vals[0]);
+ ldap_value_free(vals);
+ ldap_memfree(attr);
+ }
+
+ attr = ldap_next_attribute(conn->ld, entry, ber);
+ }
+
+ if (user.virtual_user == NULL)
+ i_error("LDAP: No username in reply");
+ else {
+ if (ldap_next_entry(conn->ld, entry) != NULL) {
+ i_error("LDAP: Multiple replies found for user %s",
+ user.virtual_user);
+ } else {
+ urequest->userdb_callback(&user, request->context);
+ }
+ }
+
+ t_pop();
+}
+
+static void userdb_ldap_lookup(const char *user, const char *realm,
+ userdb_callback_t *callback, void *context)
+{
+ struct ldap_connection *conn = userdb_ldap_conn->conn;
+ struct userdb_ldap_request *request;
+ const char *filter;
+
+ if (realm != NULL)
+ user = t_strconcat(user, "@", realm, NULL);
+
+ if (conn->set.filter == NULL) {
+ filter = t_strdup_printf("(%s=%s)",
+ userdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user);
+ } else {
+ filter = t_strdup_printf("(&%s(%s=%s))", conn->set.filter,
+ userdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user);
+ }
+
+ request = i_new(struct userdb_ldap_request, 1);
+ request->request.callback = handle_request;
+ request->request.context = context;
+ request->userdb_callback = callback;
+
+ db_ldap_search(conn, conn->set.base, LDAP_SCOPE_SUBTREE,
+ filter, userdb_ldap_conn->attr_names,
+ &request->request);
+}
+
+static void userdb_ldap_init(const char *args)
+{
+ struct userdb_ldap_connection *conn;
+
+ conn = i_new(struct userdb_ldap_connection, 1);
+ conn->conn = db_ldap_init(args);
+
+ db_ldap_set_attrs(conn->conn, conn->conn->set.attrs ?
+ conn->conn->set.attrs : DEFAULT_ATTRIBUTES,
+ &conn->attrs, &conn->attr_names);
+}
+
+static void userdb_ldap_deinit(void)
+{
+ db_ldap_unref(userdb_ldap_conn->conn);
+ i_free(userdb_ldap_conn);
+}
+
+struct userdb_module userdb_ldap = {
+ userdb_ldap_init,
+ userdb_ldap_deinit,
+
+ userdb_ldap_lookup
+};
+
+#endif
#include "common.h"
#include "userdb.h"
-#include "passwd-file.h"
+#include "db-passwd-file.h"
struct passwd_file *userdb_pwf = NULL;
static void passwd_file_lookup(const char *user, const char *realm,
userdb_callback_t *callback, void *context)
{
- struct user_data *data;
+ struct user_data data;
struct passwd_user *pu;
- pool_t pool;
- pu = passwd_file_lookup_user(userdb_pwf, user, realm);
+ pu = db_passwd_file_lookup(userdb_pwf, user, realm);
if (pu == NULL) {
callback(NULL, context);
return;
}
- pool = pool_alloconly_create("user_data", 512);
- data = p_new(pool, struct user_data, 1);
- data->pool = pool;
+ memset(&data, 0, sizeof(data));
+ data.uid = pu->uid;
+ data.gid = pu->gid;
- data->uid = pu->uid;
- data->gid = pu->gid;
+ data.virtual_user = realm == NULL ? user :
+ t_strconcat(user, "@", realm, NULL);
+ data.home = pu->home;
+ data.mail = pu->mail;
- data->virtual_user = realm == NULL ? p_strdup(data->pool, user) :
- p_strconcat(data->pool, user, "@", realm, NULL);
- data->home = p_strdup(data->pool, pu->home);
- data->mail = p_strdup(data->pool, pu->mail);
+ data.chroot = pu->chroot;
- data->chroot = pu->chroot;
-
- callback(data, context);
+ callback(&data, context);
}
static void passwd_file_init(const char *args)
userdb_pwf = passdb_pwf;
userdb_pwf->refcount++;
} else {
- userdb_pwf = passwd_file_parse(args);
+ userdb_pwf = db_passwd_file_parse(args);
}
}
static void passwd_file_deinit(void)
{
- passwd_file_unref(userdb_pwf);
+ db_passwd_file_unref(userdb_pwf);
}
struct userdb_module userdb_passwd_file = {
static void passwd_lookup(const char *user, const char *realm,
userdb_callback_t *callback, void *context)
{
- struct user_data *data;
+ struct user_data data;
struct passwd *pw;
- pool_t pool;
if (realm != NULL)
user = t_strconcat(user, "@", realm, NULL);
return;
}
- pool = pool_alloconly_create("user_data", 512);
- data = p_new(pool, struct user_data, 1);
- data->pool = pool;
+ memset(&data, 0, sizeof(data));
+ data.uid = pw->pw_uid;
+ data.gid = pw->pw_gid;
- data->uid = pw->pw_uid;
- data->gid = pw->pw_gid;
+ data.virtual_user = data.system_user = pw->pw_name;
+ data.home = pw->pw_dir;
- data->system_user = p_strdup(data->pool, pw->pw_name);
- data->virtual_user = data->system_user;
- data->home = p_strdup(data->pool, pw->pw_dir);
-
- callback(data, context);
+ callback(&data, context);
}
struct userdb_module userdb_passwd = {
static void static_lookup(const char *user, const char *realm,
userdb_callback_t *callback, void *context)
{
- struct user_data *data;
- pool_t pool;
+ struct user_data data;
string_t *str;
if (realm != NULL)
user = t_strconcat(user, "@", realm, NULL);
- pool = pool_alloconly_create("user_data", 512);
- data = p_new(pool, struct user_data, 1);
- data->pool = pool;
+ memset(&data, 0, sizeof(data));
+ data.uid = static_uid;
+ data.gid = static_gid;
- data->uid = static_uid;
- data->gid = static_gid;
-
- data->system_user = p_strdup(data->pool, user);
- data->virtual_user = data->system_user;
+ data.virtual_user = data.system_user = user;
str = t_str_new(256);
var_expand(str, static_home_template, user, NULL);
- data->home = p_strdup(data->pool, str_c(str));
+ data.home = str_c(str);
- callback(data, context);
+ callback(&data, context);
}
static void static_init(const char *args)
if (name == NULL)
i_fatal("USERDB environment is unset");
+ args = strchr(name, ' ');
+ name = t_strcut(name, ' ');
+
#ifdef USERDB_PASSWD
if (strcasecmp(name, "passwd") == 0)
userdb = &userdb_passwd;
i_fatal("Unknown userdb type '%s'", name);
/* initialize */
- if (userdb->init != NULL) {
- args = getenv("USERDB_ARGS");
- if (args == NULL) args = "";
-
- userdb->init(args);
- }
+ if (userdb->init != NULL)
+ userdb->init(args != NULL ? args+1 : "");
}
void userdb_deinit(void)
#define __USERDB_H
struct user_data {
- pool_t pool;
+ const char *virtual_user;
+ const char *home;
+ const char *mail;
- char *virtual_user;
- char *home;
- char *mail;
-
- char *system_user;
+ const char *system_user;
uid_t uid;
gid_t gid;