Ejemplo n.º 1
0
static void
cmd_user_mail_print_fields(const struct authtest_input *input,
                           struct mail_user *user,
                           const char *const *userdb_fields,
                           const char *show_field)
{
    const struct mail_storage_settings *mail_set;
    const char *key, *value;
    unsigned int i;

    if (strcmp(input->username, user->username) != 0) {
        cmd_user_mail_input_field("user", user->username, show_field);
        o_stream_nsend_str(doveadm_print_ostream, ",");
    }
    cmd_user_mail_input_field("uid", user->set->mail_uid, show_field);
    o_stream_nsend_str(doveadm_print_ostream, ",");
    cmd_user_mail_input_field("gid", user->set->mail_gid, show_field);
    o_stream_nsend_str(doveadm_print_ostream, ",");
    cmd_user_mail_input_field("home", user->set->mail_home, show_field);

    mail_set = mail_user_set_get_storage_set(user);
    o_stream_nsend_str(doveadm_print_ostream, ",");
    cmd_user_mail_input_field("mail", mail_set->mail_location, show_field);

    if (userdb_fields != NULL) {
        for (i = 0; userdb_fields[i] != NULL; i++) {
            value = strchr(userdb_fields[i], '=');
            if (value != NULL)
                key = t_strdup_until(userdb_fields[i], value++);
            else {
                key = userdb_fields[i];
                value = "";
            }
            if (strcmp(key, "uid") != 0 &&
                    strcmp(key, "gid") != 0 &&
                    strcmp(key, "home") != 0 &&
                    strcmp(key, "mail") != 0 &&
                    *key != '\0') {
                o_stream_nsend_str(doveadm_print_ostream, ",");
                cmd_user_mail_input_field(key, value, show_field);
            }
        }
    }
}
Ejemplo n.º 2
0
int mail_user_init(struct mail_user *user, const char **error_r)
{
	const struct mail_storage_settings *mail_set;
	const char *home, *key, *value;
	bool need_home_dir;

	need_home_dir = user->_home == NULL &&
		settings_vars_have_key(user->set_info, user->set,
				       'h', "home", &key, &value);
	if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
		user->error = p_strdup_printf(user->pool,
			"userdb didn't return a home directory, "
			"but %s used it (%%h): %s", key, value);
	}

	/* expand settings after we can expand %h */
	settings_var_expand_with_funcs(user->set_info, user->set,
				       user->pool, mail_user_var_expand_table(user),
				       mail_user_var_expand_func_table, user);
	user->settings_expanded = TRUE;
	mail_user_expand_plugins_envs(user);

	/* autocreated users for shared mailboxes need to be fully initialized
	   if they don't exist, since they're going to be used anyway */
	if (user->error == NULL || user->nonexistent) {
		mail_set = mail_user_set_get_storage_set(user);
		user->mail_debug = mail_set->mail_debug;

		user->initialized = TRUE;
		hook_mail_user_created(user);
	}

	if (user->error != NULL) {
		*error_r = t_strdup(user->error);
		return -1;
	}
	return 0;
}
Ejemplo n.º 3
0
int mail_user_init(struct mail_user *user, const char **error_r)
{
	const struct mail_storage_settings *mail_set;
	const char *home, *key, *value;
	bool need_home_dir;

	need_home_dir = user->_home == NULL &&
		settings_vars_have_key(user->set_info, user->set,
				       'h', "home", &key, &value);

	/* expand mail_home setting before calling mail_user_get_home() */
	settings_var_expand(user->set_info, user->set,
			    user->pool, mail_user_var_expand_table(user));

	if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
		*error_r = t_strdup_printf(
			"userdb didn't return a home directory, "
			"but %s used it (%%h): %s", key, value);
		return -1;
	}

	if (mail_user_expand_plugins_envs(user, error_r) < 0)
		return -1;

	mail_set = mail_user_set_get_storage_set(user);
	user->mail_debug = mail_set->mail_debug;

	user->initialized = TRUE;
	hook_mail_user_created(user);

	if (user->error != NULL) {
		*error_r = t_strdup(user->error);
		return -1;
	}
	return 0;
}
Ejemplo n.º 4
0
static int
mail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
			       struct mail_storage_service_user *user,
			       struct mail_storage_service_privileges *priv,
			       struct mail_user **mail_user_r,
			       const char **error_r)
{
	const struct mail_storage_settings *mail_set;
	const char *home = priv->home;
	struct mail_user *mail_user;

	/* NOTE: if more user initialization is added, add it also to
	   mail_user_dup() */
	mail_user = mail_user_alloc(user->input.username, user->user_info,
				    user->user_set);
	mail_user->_service_user = user;
	mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
	mail_user_set_vars(mail_user, ctx->service->name,
			   &user->input.local_ip, &user->input.remote_ip);
	mail_user->uid = priv->uid == (uid_t)-1 ? geteuid() : priv->uid;
	mail_user->gid = priv->gid == (gid_t)-1 ? getegid() : priv->gid;
	mail_user->anonymous = user->anonymous;
	mail_user->admin = user->admin;
	mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token);
	mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user);
	mail_user->session_id =
		p_strdup(mail_user->pool, user->input.session_id);
	mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL :
		p_strarray_dup(mail_user->pool, user->input.userdb_fields);
	mail_user->autoexpunge_enabled =
		(user->flags & MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE) != 0;
	
	mail_set = mail_user_set_get_storage_set(mail_user);

	if (mail_set->mail_debug) {
		string_t *str = t_str_new(64);

		str_printfa(str, "Effective uid=%s, gid=%s, home=%s",
			    dec2str(geteuid()), dec2str(getegid()), home);
		if (*priv->chroot != '\0')
			str_printfa(str, ", chroot=%s", priv->chroot);
		i_debug("%s", str_c(str));
	}

	if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
	    (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
		/* we don't want to write core files to any users' home
		   directories since they could contain information about other
		   users' mails as well. so do no chdiring to home. */
	} else if (*home != '\0' &&
		   (user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
		/* If possible chdir to home directory, so that core file
		   could be written in case we crash. */
		if (chdir(home) < 0) {
			if (errno == EACCES) {
				i_error("%s", eacces_error_get("chdir",
						t_strconcat(home, "/", NULL)));
			} if (errno != ENOENT)
				i_error("chdir(%s) failed: %m", home);
			else if (mail_set->mail_debug)
				i_debug("Home dir not found: %s", home);
		}
	}

	if (mail_user_init(mail_user, error_r) < 0) {
		mail_user_unref(&mail_user);
		return -1;
	}
	if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES) == 0) {
		if (mail_namespaces_init(mail_user, error_r) < 0) {
			mail_user_unref(&mail_user);
			return -1;
		}
	}
	*mail_user_r = mail_user;
	return 0;
}
Ejemplo n.º 5
0
struct client *client_create(int fd_in, int fd_out, const char *session_id,
			     struct mail_user *user,
			     struct mail_storage_service_user *service_user,
			     const struct imap_settings *set)
{
	const struct mail_storage_settings *mail_set;
	struct client *client;
	const char *ident;
	pool_t pool;
	bool explicit_capability = FALSE;

	/* always use nonblocking I/O */
	net_set_nonblock(fd_in, TRUE);
	net_set_nonblock(fd_out, TRUE);

	pool = pool_alloconly_create("imap client", 2048);
	client = p_new(pool, struct client, 1);
	client->pool = pool;
	client->v = imap_client_vfuncs;
	client->set = set;
	client->service_user = service_user;
	client->session_id = p_strdup(pool, session_id);
	client->fd_in = fd_in;
	client->fd_out = fd_out;
	client->input = i_stream_create_fd(fd_in,
					   set->imap_max_line_length, FALSE);
	client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(client->output, TRUE);
	i_stream_set_name(client->input, "<imap client>");
	o_stream_set_name(client->output, "<imap client>");

	o_stream_set_flush_callback(client->output, client_output, client);

	p_array_init(&client->module_contexts, client->pool, 5);
	client->io = io_add_istream(client->input, client_input, client);
        client->last_input = ioloop_time;
	client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS,
				      client_idle_timeout, client);

	client->command_pool =
		pool_alloconly_create(MEMPOOL_GROWING"client command", 1024*2);
	client->user = user;
	client->notify_count_changes = TRUE;
	client->notify_flag_changes = TRUE;

	mail_namespaces_set_storage_callbacks(user->namespaces,
					      &mail_storage_callbacks, client);

	client->capability_string =
		str_new(client->pool, sizeof(CAPABILITY_STRING)+64);

	if (*set->imap_capability == '\0')
		str_append(client->capability_string, CAPABILITY_STRING);
	else if (*set->imap_capability != '+') {
		explicit_capability = TRUE;
		str_append(client->capability_string, set->imap_capability);
	} else {
		str_append(client->capability_string, CAPABILITY_STRING);
		str_append_c(client->capability_string, ' ');
		str_append(client->capability_string, set->imap_capability + 1);
	}
	if (user->fuzzy_search && !explicit_capability) {
		/* Enable FUZZY capability only when it actually has
		   a chance of working */
		str_append(client->capability_string, " SEARCH=FUZZY");
	}

	mail_set = mail_user_set_get_storage_set(user);
	if (mail_set->mailbox_list_index && !explicit_capability) {
		/* NOTIFY is enabled only when mailbox list indexes are
		   enabled, although even that doesn't necessarily guarantee
		   it always */
		str_append(client->capability_string, " NOTIFY");
	}

	if (*set->imap_urlauth_host != '\0' &&
	    *mail_set->mail_attribute_dict != '\0') {
		/* Enable URLAUTH capability only when dict is
		   configured correctly */
		client_init_urlauth(client);
		if (!explicit_capability)
			str_append(client->capability_string, " URLAUTH URLAUTH=BINARY");
	}
	if (set->imap_metadata && *mail_set->mail_attribute_dict != '\0') {
		client->imap_metadata_enabled = TRUE;
		if (!explicit_capability)
			str_append(client->capability_string, " METADATA");
	}
	if (!explicit_capability && user_has_special_use_mailboxes(user)) {
		/* Advertise SPECIAL-USE only if there are actually some
		   SPECIAL-USE flags in mailbox configuration. */
		str_append(client->capability_string, " SPECIAL-USE");
	}

	ident = mail_user_get_anvil_userip_ident(client->user);
	if (ident != NULL) {
		master_service_anvil_send(master_service, t_strconcat(
			"CONNECT\t", my_pid, "\timap/", ident, "\n", NULL));
		client->anvil_sent = TRUE;
	}

	imap_client_count++;
	DLLIST_PREPEND(&imap_clients, client);
	if (hook_client_created != NULL)
		hook_client_created(&client);

	imap_refresh_proctitle();
	return client;
}
Ejemplo n.º 6
0
struct client *client_create(int fd_in, int fd_out,
			     const char *session_id, struct mail_user *user,
			     struct mail_storage_service_user *service_user,
			     const struct submission_settings *set,
			     const char *helo,
			     const unsigned char *pdata, unsigned int pdata_len)
{
	const struct mail_storage_settings *mail_set;
	struct smtp_server_settings smtp_set;
	const char *ident;
	struct client *client;

	/* always use nonblocking I/O */
	net_set_nonblock(fd_in, TRUE);
	net_set_nonblock(fd_out, TRUE);

	client = i_new(struct client, 1);
	client->user = user;
	client->service_user = service_user;
	client->set = set;
	client->session_id = i_strdup(session_id);

	i_zero(&smtp_set);
	smtp_set.hostname = set->hostname;
	smtp_set.login_greeting = set->login_greeting;
	smtp_set.max_recipients = set->submission_max_recipients;
	smtp_set.max_client_idle_time_msecs = CLIENT_IDLE_TIMEOUT_MSECS;
	smtp_set.debug = user->mail_debug;

	client->conn = smtp_server_connection_create(smtp_server,
		fd_in, fd_out, user->conn.remote_ip, user->conn.remote_port,
		FALSE, &smtp_set, &smtp_callbacks, client);

	client_proxy_create(client, set);

	smtp_server_connection_login(client->conn,
		client->user->username, helo,
		pdata, pdata_len, user->conn.ssl_secured);
	smtp_server_connection_start_pending(client->conn);

	mail_set = mail_user_set_get_storage_set(user);
	if (*set->imap_urlauth_host != '\0' &&
	    *mail_set->mail_attribute_dict != '\0') {
		/* Enable BURL capability only when urlauth dict is
		   configured correctly */
		client_init_urlauth(client);
	}

	submission_client_count++;
	DLLIST_PREPEND(&submission_clients, client);

	ident = mail_user_get_anvil_userip_ident(client->user);
	if (ident != NULL) {
		master_service_anvil_send(master_service, t_strconcat(
			"CONNECT\t", my_pid, "\tsubmission/",
			ident, "\n", NULL));
		client->anvil_sent = TRUE;
	}

	if (hook_client_created != NULL)
		hook_client_created(&client);

	submission_refresh_proctitle();
	return client;
}