Exemple #1
0
static int
cmd_user_input(const char *auth_socket_path, const struct authtest_input *input,
	       const char *show_field, bool userdb)
{
	const char *lookup_name = userdb ? "userdb lookup" : "passdb lookup";
	struct auth_master_connection *conn;
	pool_t pool;
	const char *username, *const *fields, *p;
	int ret;

	if (auth_socket_path == NULL) {
		auth_socket_path = t_strconcat(doveadm_settings->base_dir,
					       "/auth-userdb", NULL);
	}

	pool = pool_alloconly_create("auth master lookup", 1024);

	conn = auth_master_init(auth_socket_path, 0);
	if (userdb) {
		ret = auth_master_user_lookup(conn, input->username, &input->info,
					      pool, &username, &fields);
	} else {
		ret = auth_master_pass_lookup(conn, input->username, &input->info,
					      pool, &fields);
	}
	if (ret < 0) {
		if (fields[0] == NULL)
			i_error("%s failed for %s", lookup_name, input->username);
		else {
			i_error("%s failed for %s: %s", lookup_name,
				input->username, fields[0]);
		}
	} else if (ret == 0) {
		fprintf(show_field == NULL ? stdout : stderr,
			"%s: user %s doesn't exist\n", lookup_name,
			input->username);
	} else if (show_field != NULL) {
		unsigned int show_field_len = strlen(show_field);

		for (; *fields; fields++) {
			if (strncmp(*fields, show_field, show_field_len) == 0 &&
			    (*fields)[show_field_len] == '=')
				printf("%s\n", *fields + show_field_len + 1);
		}
	} else {
		printf("%s: %s\n", userdb ? "userdb" : "passdb", input->username);

		for (; *fields; fields++) {
			p = strchr(*fields, '=');
			if (p == NULL)
				printf("  %-10s\n", *fields);
			else {
				printf("  %-10s: %s\n",
				       t_strcut(*fields, '='), p + 1);
			}
		}
	}
	auth_master_deinit(&conn);
	return ret;
}
Exemple #2
0
static int
cmd_user_input(struct auth_master_connection *conn,
	       const struct authtest_input *input,
	       const char *show_field, bool userdb)
{
	const char *lookup_name = userdb ? "userdb lookup" : "passdb lookup";
	pool_t pool;
	const char *updated_username = NULL, *const *fields, *p;
	int ret;

	pool = pool_alloconly_create("auth master lookup", 1024);

	if (userdb) {
		ret = auth_master_user_lookup(conn, input->username, &input->info,
					      pool, &updated_username, &fields);
	} else {
		ret = auth_master_pass_lookup(conn, input->username, &input->info,
					      pool, &fields);
	}
	if (ret < 0) {
		if (fields[0] == NULL)
			i_error("%s failed for %s", lookup_name, input->username);
		else {
			i_error("%s failed for %s: %s", lookup_name,
				input->username, fields[0]);
		}
		ret = -1;
	} else if (ret == 0) {
		fprintf(show_field == NULL ? stdout : stderr,
			"%s: user %s doesn't exist\n", lookup_name,
			input->username);
	} else if (show_field != NULL) {
		unsigned int show_field_len = strlen(show_field);

		for (; *fields; fields++) {
			if (strncmp(*fields, show_field, show_field_len) == 0 &&
			    (*fields)[show_field_len] == '=')
				printf("%s\n", *fields + show_field_len + 1);
		}
	} else {
		printf("%s: %s\n", userdb ? "userdb" : "passdb", input->username);

		if (updated_username != NULL)
			printf("  %-10s: %s\n", "user", updated_username);
		for (; *fields; fields++) {
			p = strchr(*fields, '=');
			if (p == NULL)
				printf("  %-10s\n", *fields);
			else {
				printf("  %-10s: %s\n",
				       t_strcut(*fields, '='), p + 1);
			}
		}
	}
	return ret;
}
Exemple #3
0
static bool client_proxy_rcpt(struct client *client, const char *address,
			      const char *username, const char *detail)
{
	struct auth_master_connection *auth_conn;
	struct lmtp_proxy_rcpt_settings set;
	struct auth_user_info info;
	struct mail_storage_service_input input;
	const char *args, *const *fields, *errstr, *orig_username = username;
	pool_t pool;
	int ret;

	memset(&input, 0, sizeof(input));
	input.module = input.service = "lmtp";
	mail_storage_service_init_settings(storage_service, &input);

	memset(&info, 0, sizeof(info));
	info.service = master_service_get_name(master_service);
	info.local_ip = client->local_ip;
	info.remote_ip = client->remote_ip;
	info.local_port = client->local_port;
	info.remote_port = client->remote_port;

	pool = pool_alloconly_create("auth lookup", 1024);
	auth_conn = mail_storage_service_get_auth_conn(storage_service);
	ret = auth_master_pass_lookup(auth_conn, username, &info,
				      pool, &fields);
	if (ret <= 0) {
		errstr = ret < 0 && fields[0] != NULL ? t_strdup(fields[0]) :
			t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL, address);
		pool_unref(&pool);
		if (ret < 0) {
			client_send_line(client, "%s", errstr);
			return TRUE;
		} else {
			/* user not found from passdb. try userdb also. */
			return FALSE;
		}
	}

	memset(&set, 0, sizeof(set));
	set.port = client->local_port;
	set.protocol = LMTP_CLIENT_PROTOCOL_LMTP;
	set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS;

	if (!client_proxy_rcpt_parse_fields(&set, fields, &username)) {
		/* not proxying this user */
		pool_unref(&pool);
		return FALSE;
	}
	if (strcmp(username, orig_username) != 0) {
		/* username changed. change the address as well */
		if (*detail == '\0')
			address = username;
		else
			address = address_add_detail(client, username, detail);
	} else if (client_proxy_is_ourself(client, &set)) {
		i_error("Proxying to <%s> loops to itself", username);
		client_send_line(client, "554 5.4.6 <%s> "
				 "Proxying loops to itself", address);
		pool_unref(&pool);
		return TRUE;
	}

	if (client->proxy_ttl <= 1) {
		i_error("Proxying to <%s> appears to be looping (TTL=0)",
			username);
		client_send_line(client, "554 5.4.6 <%s> "
				 "Proxying appears to be looping (TTL=0)",
				 username);
		pool_unref(&pool);
		return TRUE;
	}
	if (array_count(&client->state.rcpt_to) != 0) {
		client_send_line(client, "451 4.3.0 <%s> "
			"Can't handle mixed proxy/non-proxy destinations",
			address);
		pool_unref(&pool);
		return TRUE;
	}
	if (client->proxy == NULL) {
		struct lmtp_proxy_settings proxy_set;

		memset(&proxy_set, 0, sizeof(proxy_set));
		proxy_set.my_hostname = client->my_domain;
		proxy_set.dns_client_socket_path = dns_client_socket_path;
		proxy_set.session_id = client->state.session_id;
		proxy_set.source_ip = client->remote_ip;
		proxy_set.source_port = client->remote_port;
		proxy_set.proxy_ttl = client->proxy_ttl-1;

		client->proxy = lmtp_proxy_init(&proxy_set, client->output);
		if (client->state.mail_body_8bitmime)
			args = " BODY=8BITMIME";
		else if (client->state.mail_body_7bit)
			args = " BODY=7BIT";
		else
			args = "";
		lmtp_proxy_mail_from(client->proxy, t_strdup_printf(
			"<%s>%s", client->state.mail_from, args));
	}
	if (lmtp_proxy_add_rcpt(client->proxy, address, &set) < 0)
		client_send_line(client, ERRSTR_TEMP_REMOTE_FAILURE);
	else
		client_send_line(client, "250 2.1.5 OK");
	pool_unref(&pool);
	return TRUE;
}
static int
cmd_user_input(struct auth_master_connection *conn,
               const struct authtest_input *input,
               const char *show_field, bool userdb)
{
    const char *lookup_name = userdb ? "userdb lookup" : "passdb lookup";
    pool_t pool;
    const char *updated_username = NULL, *const *fields, *p;
    int ret;

    pool = pool_alloconly_create("auth master lookup", 1024);

    if (userdb) {
        ret = auth_master_user_lookup(conn, input->username, &input->info,
                                      pool, &updated_username, &fields);
    } else {
        ret = auth_master_pass_lookup(conn, input->username, &input->info,
                                      pool, &fields);
    }
    if (ret < 0) {
        const char *msg;
        if (fields[0] == NULL) {
            msg = t_strdup_printf("\"error\":\"%s failed\"",
                                  lookup_name);
        } else {
            msg = t_strdup_printf("\"error\":\"%s failed: %s\"",
                                  lookup_name,
                                  fields[0]);
        }
        o_stream_nsend_str(doveadm_print_ostream, msg);
        ret = -1;
    } else if (ret == 0) {
        o_stream_nsend_str(doveadm_print_ostream,
                           t_strdup_printf("\"error\":\"%s: user doesn't exist\"",
                                           lookup_name));
    } else if (show_field != NULL) {
        unsigned int show_field_len = strlen(show_field);
        string_t *json_field = t_str_new(show_field_len+1);
        json_append_escaped(json_field, show_field);
        o_stream_nsend_str(doveadm_print_ostream, t_strdup_printf("\"%s\":", str_c(json_field)));
        for (; *fields != NULL; fields++) {
            if (strncmp(*fields, show_field, show_field_len) == 0 &&
                    (*fields)[show_field_len] == '=') {
                string_t *jsonval = t_str_new(32);
                json_append_escaped(jsonval, *fields + show_field_len + 1);
                o_stream_nsend_str(doveadm_print_ostream, "\"");
                o_stream_nsend_str(doveadm_print_ostream, str_c(jsonval));
                o_stream_nsend_str(doveadm_print_ostream, "\"");
            }
        }
    } else {
        string_t *jsonval = t_str_new(64);
        o_stream_nsend_str(doveadm_print_ostream, "\"source\":\"");
        o_stream_nsend_str(doveadm_print_ostream, userdb ? "userdb\"" : "passdb\"");

        if (updated_username != NULL) {
            o_stream_nsend_str(doveadm_print_ostream, ",\"updated_username\":\"");
            str_truncate(jsonval, 0);
            json_append_escaped(jsonval, updated_username);
            o_stream_nsend_str(doveadm_print_ostream, str_c(jsonval));
            o_stream_nsend_str(doveadm_print_ostream, "\"");
        }
        for (; *fields != NULL; fields++) {
            const char *field = *fields;
            if (*field == '\0') continue;
            p = strchr(*fields, '=');
            str_truncate(jsonval, 0);
            if (p != NULL) {
                field = t_strcut(*fields, '=');
            }
            str_truncate(jsonval, 0);
            json_append_escaped(jsonval, field);
            o_stream_nsend_str(doveadm_print_ostream, ",\"");
            o_stream_nsend_str(doveadm_print_ostream, str_c(jsonval));
            o_stream_nsend_str(doveadm_print_ostream, "\":");
            if (p != NULL) {
                str_truncate(jsonval, 0);
                json_append_escaped(jsonval, p+1);
                o_stream_nsend_str(doveadm_print_ostream, "\"");
                o_stream_nsend_str(doveadm_print_ostream, str_c(jsonval));
                o_stream_nsend_str(doveadm_print_ostream, "\"");
            } else {
                o_stream_nsend_str(doveadm_print_ostream, "true");
            }
        }
    }
    return ret;
}