mail-user.c revision a443e5aaf632257bfd1e7aa9b3c42c09512bbe43
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "lib.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "array.h"
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen#include "auth-master.h"
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#include "mail-namespace.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "mail-user.h"
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
994bb1a8a80da664083691d41dd9aec5d6fba2bfTimo Sirainen#include <stdlib.h>
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct mail_user_module_register mail_user_module_register = { 0 };
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainenvoid (*hook_mail_user_created)(struct mail_user *user) = NULL;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic struct auth_master_connection *auth_master_conn;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainenstatic void mail_user_deinit_base(struct mail_user *user)
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen{
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen mail_namespaces_deinit(&user->namespaces);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen pool_unref(&user->pool);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen}
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstruct mail_user *mail_user_init(const char *username)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mail_user *user;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen pool_t pool;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen i_assert(username != NULL);
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen pool = pool_alloconly_create("mail user", 512);
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen user = p_new(pool, struct mail_user, 1);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->pool = pool;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->refcount = 1;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->username = p_strdup_empty(pool, username);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->v.deinit = mail_user_deinit_base;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen p_array_init(&user->module_contexts, user->pool, 5);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (hook_mail_user_created != NULL)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen hook_mail_user_created(user);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return user;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainenvoid mail_user_ref(struct mail_user *user)
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen{
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen i_assert(user->refcount > 0);
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->refcount++;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainenvoid mail_user_unref(struct mail_user **_user)
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mail_user *user = *_user;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert(user->refcount > 0);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen *_user = NULL;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (--user->refcount == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->v.deinit(user);
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainenstruct mail_user *mail_user_find(struct mail_user *user, const char *name)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mail_namespace *ns;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return ns->owner;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return NULL;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen}
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenvoid mail_user_set_home(struct mail_user *user, const char *home)
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen{
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen user->_home = p_strdup(user->pool, home);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen user->home_looked_up = TRUE;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenvoid mail_user_add_namespace(struct mail_user *user, struct mail_namespace *ns)
b66412da78711db8423288847ecfb08469609a03Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mail_namespace **tmp, *next;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (; ns != NULL; ns = next) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen next = ns->next;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen tmp = &user->namespaces;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen for (; *tmp != NULL; tmp = &(*tmp)->next) {
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen if (strlen(ns->prefix) < strlen((*tmp)->prefix))
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen break;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen ns->next = *tmp;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen *tmp = ns;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenvoid mail_user_drop_useless_namespaces(struct mail_user *user)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mail_namespace *ns, *next;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = next) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen next = ns->next;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_USABLE) == 0 &&
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mail_namespace_destroy(ns);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenconst char *mail_user_home_expand(struct mail_user *user, const char *path)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (void)mail_user_try_home_expand(user, &path);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return path;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenint mail_user_get_home(struct mail_user *user, const char **home_r)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct auth_user_reply reply;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen pool_t userdb_pool;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen int ret;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen userdb_pool = pool_alloconly_create("userdb lookup", 512);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen ret = auth_master_user_lookup(auth_master_conn, user->username,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen AUTH_SERVICE_INTERNAL,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen userdb_pool, &reply);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (ret < 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen *home_r = NULL;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen else {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen user->_home = ret == 0 ? NULL :
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen p_strdup(user->pool, reply.home);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen user->home_looked_up = TRUE;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen ret = user->_home != NULL ? 1 : 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen *home_r = user->_home;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen pool_unref(&userdb_pool);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return ret;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenint mail_user_try_home_expand(struct mail_user *user, const char **pathp)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const char *home, *path = *pathp;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (!user->home_looked_up) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (mail_user_get_home(user, &home) < 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return -1;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (user->_home == NULL)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return -1;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen *pathp = t_strconcat(user->_home, path + 1, NULL);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenvoid mail_users_init(const char *auth_socket_path, bool debug)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen const char *base_dir;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (auth_socket_path == NULL) {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen base_dir = getenv("BASE_DIR");
b66412da78711db8423288847ecfb08469609a03Timo Sirainen if (base_dir == NULL)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen base_dir = PKG_RUNDIR;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen auth_socket_path = t_strconcat(base_dir, "/auth-master", NULL);
b66412da78711db8423288847ecfb08469609a03Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen auth_master_conn = auth_master_init(auth_socket_path, debug);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b66412da78711db8423288847ecfb08469609a03Timo Sirainenvoid mail_users_deinit(void)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_master_deinit(&auth_master_conn);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen