The simplest thing that could possibly work. You can authenticate as an LDAP user, but there are plenty of limitations.

This commit is contained in:
Simon MacMullen 2010-11-22 14:15:00 +00:00
parent 7291e2cc25
commit d302c633b1
10 changed files with 297 additions and 3 deletions

View File

@ -1,5 +1,6 @@
PACKAGE=rabbitmq-auth-backend-ldap
APPNAME=rabbit_auth_backend_ldap
DEPS=rabbitmq-server rabbitmq-erlang-client
ELDAP_DIR=eldap
ELDAP_URI=https://github.com/etnt/eldap.git

19
deps/rabbitmq_auth_backend_ldap/README vendored Normal file
View File

@ -0,0 +1,19 @@
Currently this needs bug23455 in the server, erlang client, and management (if
you're using that). Build it like any other plugin.
Example config stanza:
{rabbit_auth_backend_ldap,
[ {servers, ["my-ldap-server1", "my-ldap-server-2"]},
{user_dn_pattern, "cn=~s,ou=People,dc=example,dc=com"} ] },
The user_dn_pattern must contain exactly one instance of "~s". This will be
where the username supplied by the client is subsitituted.
Currently all users authenticated by LDAP:
* Are not administrators.
* Can connect to any vhost.
* Can do anything within a vhost.
These last two limitations will probably get removed at some point.

View File

@ -1,8 +1,10 @@
%% -*- erlang -*-
{application, rabbit_auth_backend_ldap,
[{description, "RabbitMQ LDAP Authentication Backend"},
{vsn, "%%VSN%%"},
{modules, [rabbit_auth_backend_ldap]}, %% TODO generate automatically.
{modules, [rabbit_auth_backend_ldap_app]}, %% TODO generate automatically.
{registered, []},
{mod, {rabbit_auth_backend_ldap, []}},
{env, []},
{mod, {rabbit_auth_backend_ldap_app, []}},
{env, [ {servers, ["ldap"]},
{user_dn_pattern, "cn=~s,ou=People,dc=example,dc=com"} ]},
{applications, [kernel, stdlib]}]}.

View File

@ -0,0 +1,5 @@
This is a very simple example, designed to be set up with the modern
Debian / Ubuntu packaging of OpenLDAP. Running setup.sh after "apt-get
install slapd" should get you a domain dc=example,dc=com, an admin
user cn=admin,dc=example,dc=com (password "admin"), and a normal user
cn=Simon MacMullen,ou=people,dc=example,dc=com (password "password").

View File

@ -0,0 +1,27 @@
# Load modules for database type
dn: cn=module,cn=config
objectclass: olcModuleList
cn: module
olcModuleLoad: back_bdb.la
# Create directory database
dn: olcDatabase=bdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcBdbConfig
olcDatabase: bdb
# Domain name (e.g. example.com)
olcSuffix: dc=example,dc=com
# Location on system where database is stored
olcDbDirectory: /var/lib/ldap
# Manager of the database
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: admin
olcAccess: to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=admin,dc=example,dc=com" write
by * none
olcAccess: to *
by self write
by dn.base="cn=admin,dc=example,dc=com" write
by * read

View File

@ -0,0 +1,8 @@
#!/bin/sh
# Based on instructions found at
# http://ubuntuforums.org/showthread.php?p=8161118#post8161118
# - yes that does sseem to be the most authoritative place.
ldapadd -Y EXTERNAL -H ldapi:/// -f example.ldif
ldapadd -x -D cn=admin,dc=example,dc=com -w admin -f simon.ldif

View File

@ -0,0 +1,21 @@
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: example.com
dc: example
description: Example
dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups
dn: cn=Simon MacMullen,ou=people,dc=example,dc=com
objectClass: person
cn: Simon MacMullen
sn: MacMullen
userPassword: password

View File

@ -0,0 +1,124 @@
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License at
%% http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
%% License for the specific language governing rights and limitations
%% under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developers of the Original Code are LShift Ltd,
%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
%% Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
%% Ltd. Portions created by Cohesive Financial Technologies LLC are
%% Copyright (C) 2007-2010 Cohesive Financial Technologies
%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
%% (C) 2007-2010 Rabbit Technologies Ltd.
%%
%% All Rights Reserved.
%%
%% Contributor(s): ______________________________________.
%%
-module(rabbit_auth_backend_ldap).
%% Connect to an LDAP server for authentication and authorisation
-include_lib("rabbit_common/include/rabbit.hrl").
-behaviour(rabbit_auth_backend).
%%-include("rabbit_auth_backend_spec.hrl").
-export([description/0]).
-export([check_user_login/2, check_vhost_access/2, check_resource_access/3]).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
-define(SERVER, ?MODULE).
-record(state, { servers, user_dn_pattern }).
%%--------------------------------------------------------------------
description() ->
[{name, <<"LDAP">>},
{description, <<"LDAP authentication / authorisation">>}].
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
%%--------------------------------------------------------------------
check_user_login(_Username, []) ->
exit(passwordless_not_supported_yet);
check_user_login(Username, [{password, Password}]) ->
gen_server:call(?SERVER, {login, Username, Password}, infinity);
check_user_login(Username, AuthProps) ->
exit({unknown_auth_props, Username, AuthProps}).
check_vhost_access(#user{username = _Username}, _VHostPath) ->
true.
check_resource_access(#user{username = _Username},
#resource{virtual_host = _VHostPath, name = _Name},
_Permission) ->
true.
%%--------------------------------------------------------------------
init([]) ->
{ok, Servers} = application:get_env(servers),
{ok, UserDnPattern} = application:get_env(user_dn_pattern),
{ok, #state{ servers = Servers,
user_dn_pattern = UserDnPattern }}.
handle_call({login, Username, Password}, _From,
State = #state{ servers = Servers,
user_dn_pattern = UserDnPattern}) ->
case eldap:open(Servers, []) of
{ok, LDAP} ->
Dn = lists:flatten(io_lib:format(UserDnPattern, [Username])),
Reply = case eldap:simple_bind(LDAP, Dn, Password) of
ok ->
{ok, #user{username = Username,
is_admin = false,
auth_backend = ?MODULE,
impl = none}};
{error, invalidCredentials} ->
{refused, Username};
{error, _} = E ->
E
end,
{reply, Reply, State};
Error ->
{reply, Error, State}
end;
handle_call(_Req, _From, State) ->
{reply, unknown_request, State}.
handle_cast(_C, State) ->
{noreply, State}.
handle_info(_I, State) ->
{noreply, State}.
terminate(_, _) -> ok.
code_change(_, State, _) -> {ok, State}.

View File

@ -0,0 +1,41 @@
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License at
%% http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
%% License for the specific language governing rights and limitations
%% under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developers of the Original Code are LShift Ltd,
%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
%% Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
%% Ltd. Portions created by Cohesive Financial Technologies LLC are
%% Copyright (C) 2007-2010 Cohesive Financial Technologies
%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
%% (C) 2007-2010 Rabbit Technologies Ltd.
%%
%% All Rights Reserved.
%%
%% Contributor(s): ______________________________________.
%%
-module(rabbit_auth_backend_ldap_app).
-behaviour(application).
-export([start/2, stop/1]).
start(_Type, _StartArgs) ->
rabbit_auth_backend_ldap_sup:start_link().
stop(_State) ->
ok.

View File

@ -0,0 +1,46 @@
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License at
%% http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
%% License for the specific language governing rights and limitations
%% under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developers of the Original Code are LShift Ltd,
%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
%% Technologies LLC, and Rabbit Technologies Ltd.
%%
%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
%% Ltd. Portions created by Cohesive Financial Technologies LLC are
%% Copyright (C) 2007-2010 Cohesive Financial Technologies
%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
%% (C) 2007-2010 Rabbit Technologies Ltd.
%%
%% All Rights Reserved.
%%
%% Contributor(s): ______________________________________.
%%
-module(rabbit_auth_backend_ldap_sup).
-behaviour(supervisor).
-export([init/1]).
-export([start_link/0]).
init([]) ->
{ok, {{one_for_one, 10, 10},
[{rabbit_auth_backend_ldap,
{rabbit_auth_backend_ldap, start_link, []},
permanent, 5000, worker, [rabbit_auth_backend_ldap]}]}}.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).