예제 #1
0
static void
mail_user_expand_plugins_envs(struct mail_user *user)
{
	const char **envs, *home;
	string_t *str;
	unsigned int i, count;

	if (!array_is_created(&user->set->plugin_envs))
		return;

	str = t_str_new(256);
	envs = array_get_modifiable(&user->set->plugin_envs, &count);
	i_assert((count % 2) == 0);
	for (i = 0; i < count; i += 2) {
		if (user->_home == NULL &&
		    var_has_key(envs[i+1], 'h', "home") &&
		    mail_user_get_home(user, &home) <= 0) {
			user->error = p_strdup_printf(user->pool,
				"userdb didn't return a home directory, "
				"but plugin setting %s used it (%%h): %s",
				envs[i], envs[i+1]);
			return;
		}
		str_truncate(str, 0);
		var_expand(str, envs[i+1], mail_user_var_expand_table(user));
		envs[i+1] = p_strdup(user->pool, str_c(str));
	}
}
예제 #2
0
static int
client_create_from_input(const struct mail_storage_service_input *input,
			 const struct master_login_client *login_client,
			 int fd_in, int fd_out, const buffer_t *input_buf,
			 const char **error_r)
{
	struct mail_storage_service_user *user;
	struct mail_user *mail_user;
	struct client *client;
	struct imap_settings *set;
	enum mail_auth_request_flags flags;

	if (mail_storage_service_lookup_next(storage_service, input,
					     &user, &mail_user, error_r) <= 0)
		return -1;
	restrict_access_allow_coredumps(TRUE);

	set = mail_storage_service_user_get_set(user)[1];
	if (set->verbose_proctitle)
		verbose_proctitle = TRUE;

	settings_var_expand(&imap_setting_parser_info, set, mail_user->pool,
			    mail_user_var_expand_table(mail_user));

	client = client_create(fd_in, fd_out, input->session_id,
			       mail_user, user, set);
	T_BEGIN {
		client_add_input(client, input_buf);
	} T_END;

	flags = login_client->auth_req.flags;
	if ((flags & MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION) != 0)
		client->tls_compression = TRUE;
	return 0;
}
예제 #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);
	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;
}
예제 #4
0
파일: mail-user.c 프로젝트: bdraco/dovecot
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;
}
예제 #5
0
static int
client_handle_user_command(struct client *client, const char *cmd,
			   const char *const *args, const char **error_r)
{
	struct mail_storage_service_input input;
	struct imap_urlauth_worker_settings *set;
	struct mail_storage_service_user *user;
	struct imap_urlauth_config config;
	struct mail_user *mail_user;
	const char *error;
	unsigned int count;
	int ret;

	/* "USER\t"<username> */
	*error_r = NULL;

	/* check command syntax */
	if (strcmp(cmd, "USER") != 0) {
		*error_r = t_strconcat("Unknown or inappropriate command: ",
				       cmd, NULL);
		return -1;
	}

	if (args[0] == NULL || args[1] != NULL) {
		*error_r = "USER: Invalid number of parameters";
		return -1;
	}

	/* lookup user */
	memset(&input, 0, sizeof(input));
	input.module = "imap-urlauth-worker";
	input.service = "imap-urlauth-worker";
	input.username = args[0];

	if (client->debug)
		i_debug("Looking up user %s", input.username);

	ret = mail_storage_service_lookup_next(storage_service, &input,
					       &user, &mail_user, &error);
	if (ret < 0) {
		i_error("Failed to lookup user %s: %s", input.username, error);
		client_abort(client, "Session aborted: Failed to lookup user");
		return 0;
	} else if (ret == 0) {
		if (client->debug)
			i_debug("User %s doesn't exist", input.username);

		client_send_line(client, "NO");
		timeout_remove(&client->to_delay);
		return 1;
	}

	client->debug = mail_user->mail_debug =
		client->debug || mail_user->mail_debug;

	/* drop privileges */
	restrict_access_allow_coredumps(TRUE);

	set = mail_storage_service_user_get_set(user)[1];
	settings_var_expand(&imap_urlauth_worker_setting_parser_info, set,
			    mail_user->pool,
			    mail_user_var_expand_table(mail_user));

	if (set->verbose_proctitle) {
		verbose_proctitle = TRUE;
		imap_urlauth_worker_refresh_proctitle();
	}

	client->service_user = user;
	client->mail_user = mail_user;
	client->set = set;

	if (client->debug) {
		i_debug("Found user account `%s' on behalf of user `%s'",
			mail_user->username, client->access_user);
	}

	/* initialize urlauth context */
	if (*set->imap_urlauth_host == '\0') {
		i_error("imap_urlauth_host setting is not configured for user %s",
			mail_user->username);
		client_send_line(client, "NO");
		client_abort(client, "Session aborted: URLAUTH not configured");
		return 0;
	}

	memset(&config, 0, sizeof(config));
	config.url_host = set->imap_urlauth_host;
	config.url_port = set->imap_urlauth_port;
	config.access_user = client->access_user;
	config.access_anonymous = client->access_anonymous;
	config.access_applications =
		(const void *)array_get(&client->access_apps, &count);
		
	client->urlauth_ctx = imap_urlauth_init(client->mail_user, &config);
	if (client->debug) {
		i_debug("Providing access to user account `%s' on behalf of `%s'",
			mail_user->username, client->access_user);
	}

	i_set_failure_prefix("imap-urlauth[%s](%s->%s): ",
			     my_pid, client->access_user, mail_user->username);

	client_send_line(client, "OK");
	return 1;
}
예제 #6
0
static int
cmd_user_mail_input(struct mail_storage_service_ctx *storage_service,
                    const struct authtest_input *input,
                    const char *show_field, const char *expand_field)
{
    struct mail_storage_service_input service_input;
    struct mail_storage_service_user *service_user;
    struct mail_user *user;
    const char *error, *const *userdb_fields;
    pool_t pool;
    int ret;

    memset(&service_input, 0, sizeof(service_input));
    service_input.module = "mail";
    service_input.service = input->info.service;
    service_input.username = input->username;
    service_input.local_ip = input->info.local_ip;
    service_input.local_port = input->info.local_port;
    service_input.remote_ip = input->info.remote_ip;
    service_input.remote_port = input->info.remote_port;
    service_input.debug = input->info.debug;

    pool = pool_alloconly_create("userdb fields", 1024);
    mail_storage_service_save_userdb_fields(storage_service, pool,
                                            &userdb_fields);

    if ((ret = mail_storage_service_lookup_next(storage_service, &service_input,
               &service_user, &user,
               &error)) <= 0) {
        pool_unref(&pool);
        if (ret < 0)
            return -1;
        string_t *username = t_str_new(32);
        json_append_escaped(username, input->username);
        o_stream_nsend_str(doveadm_print_ostream,
                           t_strdup_printf("\"error\":\"userdb lookup: user %s doesn't exist\"", str_c(username))
                          );
        return 0;
    }

    if (expand_field == NULL)
        cmd_user_mail_print_fields(input, user, userdb_fields, show_field);
    else {
        string_t *str = t_str_new(128);
        if (var_expand_with_funcs(str, expand_field,
                                  mail_user_var_expand_table(user),
                                  mail_user_var_expand_func_table, user,
                                  &error) <= 0) {
            string_t *str = t_str_new(128);
            str_printfa(str, "\"error\":\"Failed to expand field: ");
            json_append_escaped(str, error);
            str_append_c(str, '"');
            o_stream_nsend(doveadm_print_ostream, str_data(str), str_len(str));
        } else {
            string_t *value = t_str_new(128);
            json_append_escaped(value, expand_field);
            o_stream_nsend_str(doveadm_print_ostream, "\"");
            o_stream_nsend_str(doveadm_print_ostream, str_c(value));
            o_stream_nsend_str(doveadm_print_ostream, "\":\"");
            str_truncate(value, 0);
            json_append_escaped(value, str_c(str));
            o_stream_nsend_str(doveadm_print_ostream, str_c(value));
            o_stream_nsend_str(doveadm_print_ostream, "\"");
        }

    }

    mail_user_unref(&user);
    mail_storage_service_user_free(&service_user);
    pool_unref(&pool);
    return 1;
}