Skip to content

Commit c25f38f

Browse files
committed
Implement LDAP credentials validation via HTTP API
See discussion #14244 Follow-up to #14414 Cherry-picked from 9a4cb9c and then modified to move validation API endpoint to a separate plugin, `rabbitmq_auth_backend_ldap_management`. These changes will allow a user to make an HTTP API request to... ``` /api/ldap/validate/simple-bind ``` ...with an appropriate JSON body, and the plugin will attempt a connection to the specified LDAP server using the provided credentials. This allows validation that a connection can be made to an LDAP server from a RabbitMQ cluster environment.
1 parent 2714c7f commit c25f38f

File tree

27 files changed

+1178
-274
lines changed

27 files changed

+1178
-274
lines changed

.github/workflows/test-make-tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ jobs:
8888
- rabbitmq_auth_backend_cache
8989
- rabbitmq_auth_backend_http
9090
- rabbitmq_auth_backend_ldap
91+
- rabbitmq_auth_backend_ldap_management
9192
- rabbitmq_auth_backend_oauth2
9293
- rabbitmq_auth_mechanism_ssl
9394
- rabbitmq_aws

.github/workflows/test-make-type-check.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
- rabbitmq_auth_backend_cache
3030
- rabbitmq_auth_backend_http
3131
- rabbitmq_auth_backend_ldap
32+
- rabbitmq_auth_backend_ldap_management
3233
- rabbitmq_auth_backend_oauth2
3334
- rabbitmq_auth_mechanism_ssl
3435
- rabbitmq_aws

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ elvis
3939
!/deps/rabbitmq_auth_backend_http/
4040
!/deps/rabbitmq_auth_backend_internal_loopback/
4141
!/deps/rabbitmq_auth_backend_ldap/
42+
!/deps/rabbitmq_auth_backend_ldap_management/
4243
!/deps/rabbitmq_auth_backend_oauth2/
4344
!/deps/rabbitmq_auth_mechanism_ssl/
4445
!/deps/rabbitmq_aws/

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ TIER1_PLUGINS := \
524524
rabbitmq_auth_backend_http \
525525
rabbitmq_auth_backend_internal_loopback \
526526
rabbitmq_auth_backend_ldap \
527+
rabbitmq_auth_backend_ldap_management \
527528
rabbitmq_auth_backend_oauth2 \
528529
rabbitmq_auth_mechanism_ssl \
529530
rabbitmq_aws \

deps/rabbitmq_auth_backend_ldap/test/system_SUITE.erl

Lines changed: 15 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -11,83 +11,8 @@
1111
-include_lib("common_test/include/ct.hrl").
1212
-include_lib("eunit/include/eunit.hrl").
1313
-include_lib("amqp_client/include/amqp_client.hrl").
14-
15-
-define(ALICE_NAME, "Alice").
16-
-define(BOB_NAME, "Bob").
17-
-define(CAROL_NAME, "Carol").
18-
-define(PETER_NAME, "Peter").
19-
-define(JIMMY_NAME, "Jimmy").
20-
21-
-define(VHOST, "test").
22-
23-
-define(ALICE, #amqp_params_network{username = <<?ALICE_NAME>>,
24-
password = <<"password">>,
25-
virtual_host = <<?VHOST>>}).
26-
27-
-define(BOB, #amqp_params_network{username = <<?BOB_NAME>>,
28-
password = <<"password">>,
29-
virtual_host = <<?VHOST>>}).
30-
31-
-define(CAROL, #amqp_params_network{username = <<?CAROL_NAME>>,
32-
password = <<"password">>,
33-
virtual_host = <<?VHOST>>}).
34-
35-
-define(PETER, #amqp_params_network{username = <<?PETER_NAME>>,
36-
password = <<"password">>,
37-
virtual_host = <<?VHOST>>}).
38-
39-
-define(JIMMY, #amqp_params_network{username = <<?JIMMY_NAME>>,
40-
password = <<"password">>,
41-
virtual_host = <<?VHOST>>}).
42-
43-
-define(BASE_CONF_RABBIT, {rabbit, [{default_vhost, <<"test">>}]}).
44-
45-
base_conf_ldap(LdapPort, IdleTimeout, PoolSize) ->
46-
{rabbitmq_auth_backend_ldap, [{servers, ["localhost"]},
47-
{user_dn_pattern, "cn=${username},ou=People,dc=rabbitmq,dc=com"},
48-
{other_bind, anon},
49-
{use_ssl, false},
50-
{port, LdapPort},
51-
{idle_timeout, IdleTimeout},
52-
{pool_size, PoolSize},
53-
{log, true},
54-
{group_lookup_base, "ou=groups,dc=rabbitmq,dc=com"},
55-
{vhost_access_query, vhost_access_query_base()},
56-
{resource_access_query,
57-
{for, [{resource, exchange,
58-
{for, [{permission, configure,
59-
{in_group, "cn=wheel,ou=groups,dc=rabbitmq,dc=com"}
60-
},
61-
{permission, write, {constant, true}},
62-
{permission, read,
63-
{match, {string, "${name}"},
64-
{string, "^xch-${username}-.*"}}
65-
}
66-
]}},
67-
{resource, queue,
68-
{for, [{permission, configure,
69-
{match, {attribute, "${user_dn}", "description"},
70-
{string, "can-declare-queues"}}
71-
},
72-
{permission, write, {constant, true}},
73-
{permission, read,
74-
{'or',
75-
[{'and',
76-
[{equals, "${name}", "test1"},
77-
{equals, "${username}", "Alice"}]},
78-
{'and',
79-
[{equals, "${name}", "test2"},
80-
{'not', {equals, "${username}", "Bob"}}]}
81-
]}}
82-
]}}
83-
]}},
84-
{topic_access_query, topic_access_query_base()},
85-
{tag_queries, [{monitor, {constant, true}},
86-
{administrator, {constant, false}},
87-
{management, {constant, false}}]}
88-
]}.
89-
90-
%%--------------------------------------------------------------------
14+
-include_lib("rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl").
15+
-include_lib("rabbitmq_ct_helpers/include/rabbit_ldap_test.hrl").
9116

9217
all() ->
9318
[
@@ -127,70 +52,16 @@ suite() ->
12752

12853
init_per_suite(Config) ->
12954
rabbit_ct_helpers:log_environment(),
130-
rabbit_ct_helpers:run_setup_steps(Config, [fun init_slapd/1]).
55+
rabbit_ct_helpers:run_setup_steps(Config, [fun rabbit_ct_ldap_utils:init_slapd/1]).
13156

13257
end_per_suite(Config) ->
133-
rabbit_ct_helpers:run_teardown_steps(Config, [fun stop_slapd/1]).
58+
rabbit_ct_helpers:run_teardown_steps(Config, [fun rabbit_ct_ldap_utils:stop_slapd/1]).
13459

13560
init_per_group(Group, Config) ->
136-
Config1 = rabbit_ct_helpers:set_config(Config, [
137-
{rmq_nodename_suffix, Group}
138-
]),
139-
LdapPort = ?config(ldap_port, Config),
140-
Config2 = rabbit_ct_helpers:merge_app_env(Config1, ?BASE_CONF_RABBIT),
141-
Config3 = rabbit_ct_helpers:merge_app_env(Config2,
142-
base_conf_ldap(LdapPort,
143-
idle_timeout(Group),
144-
pool_size(Group))),
145-
rabbit_ldap_seed:seed({"localhost", LdapPort}),
146-
Config4 = rabbit_ct_helpers:set_config(Config3, {ldap_port, LdapPort}),
147-
148-
rabbit_ct_helpers:run_steps(Config4,
149-
rabbit_ct_broker_helpers:setup_steps() ++
150-
rabbit_ct_client_helpers:setup_steps()).
151-
152-
end_per_group(_, Config) ->
153-
rabbit_ldap_seed:delete({"localhost", ?config(ldap_port, Config)}),
154-
rabbit_ct_helpers:run_steps(Config,
155-
rabbit_ct_client_helpers:teardown_steps() ++
156-
rabbit_ct_broker_helpers:teardown_steps()).
157-
158-
init_slapd(Config) ->
159-
DataDir = ?config(data_dir, Config),
160-
PrivDir = ?config(priv_dir, Config),
161-
TcpPort = 25389,
162-
SlapdDir = filename:join([PrivDir, "openldap"]),
163-
InitSlapd = filename:join([DataDir, "init-slapd.sh"]),
164-
Cmd = [InitSlapd, SlapdDir, {"~b", [TcpPort]}],
165-
case rabbit_ct_helpers:exec(Cmd) of
166-
{ok, Stdout} ->
167-
{match, [SlapdPid]} = re:run(
168-
Stdout,
169-
"^SLAPD_PID=([0-9]+)$",
170-
[{capture, all_but_first, list},
171-
multiline]),
172-
ct:pal(?LOW_IMPORTANCE,
173-
"slapd(8) PID: ~ts~nslapd(8) listening on: ~b",
174-
[SlapdPid, TcpPort]),
175-
rabbit_ct_helpers:set_config(Config,
176-
[{slapd_pid, SlapdPid},
177-
{ldap_port, TcpPort}]);
178-
_ ->
179-
_ = rabbit_ct_helpers:exec(["pkill", "-INT", "slapd"]),
180-
{skip, "Failed to initialize slapd(8)"}
181-
end.
182-
183-
stop_slapd(Config) ->
184-
SlapdPid = ?config(slapd_pid, Config),
185-
Cmd = ["kill", "-INT", SlapdPid],
186-
_ = rabbit_ct_helpers:exec(Cmd),
187-
Config.
61+
rabbit_ct_ldap_utils:init_per_group(Group, Config).
18862

189-
idle_timeout(with_idle_timeout) -> 2000;
190-
idle_timeout(non_parallel_tests) -> infinity.
191-
192-
pool_size(with_idle_timeout) -> 1;
193-
pool_size(non_parallel_tests) -> 10.
63+
end_per_group(Group, Config) ->
64+
rabbit_ct_ldap_utils:end_per_group(Group, Config).
19465

19566
init_internal(Config) ->
19667
ok = control_action(Config, add_user, [?ALICE_NAME, ""]),
@@ -206,6 +77,7 @@ end_internal(Config) ->
20677
ok = control_action(Config, delete_user, [?BOB_NAME]),
20778
ok = control_action(Config, delete_user, [?PETER_NAME]).
20879

80+
20981
init_per_testcase(Testcase, Config)
21082
when Testcase == ldap_and_internal;
21183
Testcase == internal_followed_ldap_and_internal ->
@@ -265,6 +137,11 @@ end_per_testcase(Testcase, Config)
265137
end_per_testcase(Testcase, Config) ->
266138
rabbit_ct_helpers:testcase_finished(Config, Testcase).
267139

140+
idle_timeout(Arg) ->
141+
rabbit_ct_ldap_utils:idle_timeout(Arg).
142+
143+
pool_size(Arg) ->
144+
rabbit_ct_ldap_utils:pool_size(Arg).
268145

269146
%% -------------------------------------------------------------------
270147
%% Testsuite cases
@@ -688,10 +565,7 @@ vhost_access_query_nested_groups_env() ->
688565
[{vhost_access_query, {in_group_nested, "cn=admins,ou=groups,dc=rabbitmq,dc=com"}}].
689566

690567
vhost_access_query_base_env() ->
691-
[{vhost_access_query, vhost_access_query_base()}].
692-
693-
vhost_access_query_base() ->
694-
{exists, "ou=${vhost},ou=vhosts,dc=rabbitmq,dc=com"}.
568+
[{vhost_access_query, rabbit_ct_ldap_utils:vhost_access_query_base()}].
695569

696570
resource_access_query_match_gh_100() ->
697571
[{resource_access_query,
@@ -724,10 +598,7 @@ resource_access_query_match_query_and_re_query_are_strings() ->
724598
}].
725599

726600
topic_access_query_base_env() ->
727-
[{topic_access_query, topic_access_query_base()}].
728-
729-
topic_access_query_base() ->
730-
{constant, true}.
601+
[{topic_access_query, rabbit_ct_ldap_utils:topic_access_query_base()}].
731602

732603
test_login(Config, {N, Env}, Login, FilterList, ResultFun) ->
733604
case lists:member(N, FilterList) of

deps/rabbitmq_auth_backend_ldap/test/system_SUITE_data/init-slapd.sh

Lines changed: 0 additions & 127 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../rabbitmq_ct_helpers/tools/init-slapd.sh
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../rabbitmq_ct_helpers/tools/ldif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
PROJECT = rabbitmq_auth_backend_ldap_management
2+
PROJECT_DESCRIPTION = Management extension for the LDAP plugin
3+
4+
define PROJECT_APP_EXTRA_KEYS
5+
{broker_version_requirements, []}
6+
endef
7+
8+
DEPS = rabbit_common rabbit rabbitmq_management rabbitmq_auth_backend_ldap
9+
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
10+
11+
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
12+
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
13+
14+
include ../../rabbitmq-components.mk
15+
include ../../erlang.mk

0 commit comments

Comments
 (0)