userdb-vpopmail.c revision 22535a9e685e29214082878e37a267157044618e
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Thanks to Courier-IMAP for showing how the vpopmail API should be used */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "config.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#undef HAVE_CONFIG_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#if defined(PASSDB_VPOPMAIL) || defined(USERDB_VPOPMAIL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "common.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "userdb.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "userdb-vpopmail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct vqpasswd *vpopmail_lookup_vqp(const char *user, const char *realm,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char vpop_user[VPOPMAIL_LIMIT],
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char vpop_domain[VPOPMAIL_LIMIT])
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct vqpasswd *vpw;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (realm != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (strlen(user) >= VPOPMAIL_LIMIT ||
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen strlen(realm) >= VPOPMAIL_LIMIT)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* vpop_user must be zero-filled or parse_email() leaves an
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen extra character after the user name. we'll fill vpop_domain
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen as well just to be sure... */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(vpop_user, '\0', VPOPMAIL_LIMIT);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(vpop_domain, '\0', VPOPMAIL_LIMIT);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen VPOPMAIL_LIMIT-1) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (verbose) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_info("vpopmail(%s): parse_email() failed",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen vpw = vauth_getpw(vpop_user, vpop_domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (vpw == NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (verbose)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_info("vpopmail(%s): unknown user", user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return vpw;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifdef USERDB_VPOPMAIL
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void vpopmail_lookup(const char *user, const char *realm,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen userdb_callback_t *callback, void *context)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
9a02317c852face76737763fa6ec43b444688de5Timo Sirainen struct vqpasswd *vpw;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct user_data *data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_t uid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen gid_t gid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_t pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (realm != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user = t_strconcat(user, "@", realm, NULL);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (vpw == NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen callback(NULL, context);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* we have to get uid/gid separately, because the gid field in
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct vqpasswd isn't really gid at all but just some flags... */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (vget_assign(vpop_domain, NULL, 0, &uid, &gid) == NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (verbose) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_info("vpopmail(%s): vget_assign(%s) failed",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user, vpop_domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen callback(NULL, context);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* user's homedir doesn't exist yet, create it */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (verbose) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_info("vpopmail(%s): pw_dir isn't set, creating",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (make_user_dir(vpop_user, vpop_domain, uid, gid) == NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("vpopmail(%s): make_user_dir(%s, %s) failed",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user, vpop_user, vpop_domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen callback(NULL, context);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* get the user again so pw_dir is visible */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen vpw = vauth_getpw(vpop_user, vpop_domain);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (vpw == NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen callback(NULL, context);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("user_data", 1024);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data = p_new(pool, struct user_data, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data->pool = pool;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data->uid = uid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data->gid = gid;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data->virtual_user = p_strdup(data->pool, vpw->pw_name);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen data->home = p_strdup(data->pool, vpw->pw_dir);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen callback(data, context);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct userdb_module userdb_vpopmail = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL, NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen vpopmail_lookup
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen