userdb-vpopmail.c revision c64e714193097f841691dcfa2902c270cb47bff8
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen/* Thanks to Courier-IMAP for showing how the vpopmail API should be used */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#include "auth-common.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "userdb.h"
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#if defined(PASSDB_VPOPMAIL) || defined(USERDB_VPOPMAIL)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "str.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "var-expand.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "userdb-vpopmail.h"
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstruct vpopmail_userdb_module {
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen struct userdb_module module;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen const char *quota_template_key;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen const char *quota_template_value;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen};
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct vqpasswd *vpopmail_lookup_vqp(struct auth_request *request,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen char vpop_user[VPOPMAIL_LIMIT],
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen char vpop_domain[VPOPMAIL_LIMIT])
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct vqpasswd *vpw;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* vpop_user must be zero-filled or parse_email() leaves an
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen extra character after the user name. we'll fill vpop_domain
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen as well just to be sure... */
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen memset(vpop_user, '\0', VPOPMAIL_LIMIT);
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen memset(vpop_domain, '\0', VPOPMAIL_LIMIT);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (parse_email(request->user, vpop_user, vpop_domain,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen VPOPMAIL_LIMIT-1) < 0) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_log_info(request, "vpopmail",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "parse_email() failed");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return NULL;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_log_debug(request, "vpopmail",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "lookup user=%s domain=%s",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpop_user, vpop_domain);
82b990b0bb2a1dad5c2634a508a5ad87715db402Timo Sirainen
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen vpw = vauth_getpw(vpop_user, vpop_domain);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (vpw == NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_log_info(request, "vpopmail", "unknown user");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return NULL;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen }
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen return vpw;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#endif
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#ifdef USERDB_VPOPMAIL
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic const char *
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenuserdb_vpopmail_get_quota(const char *template, const char *vpop_str)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const struct var_expand_table *tab;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen string_t *quota;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (template == NULL || *vpop_str == '\0' ||
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen strcmp(vpop_str, "NOQUOTA") == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return "";
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen tab = var_expand_table_build('q', format_maildirquota(vpop_str), '\0');
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen quota = t_str_new(128);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen var_expand(quota, template, tab);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return str_c(quota);
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void vpopmail_lookup(struct auth_request *auth_request,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen userdb_callback_t *callback)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct vpopmail_userdb_module *module =
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (struct vpopmail_userdb_module *)_module;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct vqpasswd *vpw;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const char *quota;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen uid_t uid;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen gid_t gid;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (vpw == NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* we have to get uid/gid separately, because the gid field in
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct vqpasswd isn't really gid at all but just some flags... */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (vget_assign(vpop_domain, NULL, 0, &uid, &gid) == NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_log_info(auth_request, "vpopmail",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "vget_assign(%s) failed", vpop_domain);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
f6c1297c26b355c4aec2a08978f51ec3efecb351Timo Sirainen if (auth_request->successful) {
f6c1297c26b355c4aec2a08978f51ec3efecb351Timo Sirainen /* update the last login only when we're really */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vset_lastauth(vpop_user, vpop_domain,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen t_strdup_noconst(auth_request->service));
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen }
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0') {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* user's homedir doesn't exist yet, create it */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen auth_request_log_info(auth_request, "vpopmail",
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen "pw_dir isn't set, creating");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (make_user_dir(vpop_user, vpop_domain, uid, gid) == NULL) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen auth_request_log_error(auth_request, "vpopmail",
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen "make_user_dir(%s, %s) failed",
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen vpop_user, vpop_domain);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* get the user again so pw_dir is visible */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpw = vauth_getpw(vpop_user, vpop_domain);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (vpw == NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_init_userdb_reply(auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_set_userdb_field(auth_request, "uid", dec2str(uid));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_set_userdb_field(auth_request, "gid", dec2str(gid));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_set_userdb_field(auth_request, "home", vpw->pw_dir);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen quota = userdb_vpopmail_get_quota(module->quota_template_value,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpw->pw_shell);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (*quota != '\0') {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_request_set_userdb_field(auth_request,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->quota_template_key,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen quota);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen callback(USERDB_RESULT_OK, auth_request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic struct userdb_module *
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenvpopmail_preinit(pool_t pool, const char *args)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct vpopmail_userdb_module *module;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const char *const *tmp, *p;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module = p_new(pool, struct vpopmail_userdb_module, 1);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->module.blocking = TRUE;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (strncmp(*tmp, "cache_key=", 10) == 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->module.cache_key = p_strdup(pool, *tmp + 10);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen else if (strncmp(*tmp, "quota_template=", 15) == 0) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen p = strchr(*tmp + 15, '=');
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (p == NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_fatal("vpopmail userdb: "
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "quota_template missing '='");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->quota_template_key =
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen p_strdup_until(pool, *tmp + 15, p);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->quota_template_value = p_strdup(pool, p + 1);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen } else if (strcmp(*tmp, "blocking=no") == 0) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen module->module.blocking = FALSE;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen } else
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_fatal("userdb vpopmail: Unknown setting: %s", *tmp);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return &module->module;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstruct userdb_module_interface userdb_vpopmail = {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "vpopmail",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpopmail_preinit,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen vpopmail_lookup,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen NULL
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#else
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstruct userdb_module_interface userdb_vpopmail = {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen .name = "vpopmail"
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#endif
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen