Improvement coming from trunk (SVN #606):

* doc/guide.tex: Updated (thanks to Evgeniy Khramtsov)
* src/ejabberd_auth_ldap.erl: Better LDAP support (thanks to
Evgeniy Khramtsov)
* src/mod_vcard_ldap.erl: Likewise
* src/eldap/eldap_filter.erl: Likewise

SVN Revision: 615
This commit is contained in:
Mickaël Rémond 2006-09-22 08:36:09 +00:00
parent 677a6004cf
commit 23b78b0f0c
7 changed files with 2187 additions and 1083 deletions

View File

@ -1,3 +1,12 @@
2006-09-14 Alexey Shchepin <alexey@sevcom.net>
* doc/guide.tex: Updated (thanks to Evgeniy Khramtsov)
* src/ejabberd_auth_ldap.erl: Better LDAP support (thanks to
Evgeniy Khramtsov)
* src/mod_vcard_ldap.erl: Likewise
* src/eldap/eldap_filter.erl: Likewise
2006-09-11 Mickael Remond <mickael.remond@process-one.net>
* src/odbc/mssql.sql: Removed unused fields.

File diff suppressed because it is too large Load Diff

View File

@ -1985,15 +1985,14 @@ Options:
Examples:
\begin{itemize}
\item Next example prohibits the registration of too short account names and of
account names with exotic characters in it:
\begin{verbatim}
\item Next example prohibits the registration of too short account names:
\begin{verbatim}
{acl, shortname, {user_glob, "?"}}.
{acl, shortname, {user_glob, "??"}}.
{acl, strangename, {user_regexp, "^..?$"}}.
% The same using regexp:
%{acl, shortname, {user_regexp, "^..?$"}}.
...
{access, register, [{deny, shortname},
{deny, strangename},
{allow, all}]}.
...
{modules,
@ -2292,6 +2291,338 @@ Examples:
\end{verbatim}
\end{itemize}
\subsection{LDAP and \modvcardldap{}}
\label{sec:ldap}
\ind{modules!\modvcardldap{}}\ind{JUD}\ind{Jabber User Directory}\ind{vCard}\ind{protocols!JEP-0054: vcard-temp}
\subsubsection{Features}
\label{sec:ldapfeatures}
\ejabberd{} has built-in LDAP support. You can authenticate users against LDAP
server and use LDAP directory as vCard storage. Shared rosters are not
supported yet.
\subsubsection{Connection}
\label{sec:ldapconnection}
Parameters:
\begin{description}
\titem{ldap\_server} \ind{options!ldap_server}IP address or dns name of your
LDAP server. This option is required.
\titem{ldap\_port} \ind{options!ldap_port}Port to connect to LDAP server.
Default is~389.
\titem{ldap\_rootdn} \ind{options!ldap_rootdn}Bind DN. Default is~\term{""}
which means anonymous connection.
\titem{ldap\_password} \ind{options!ldap_password}Bind password. Default
is~\term{""}.
\end{description}
Example:
\begin{verbatim}
{auth_method, ldap}.
{ldap_servers, ["ldap.mydomain.org"]}.
{ldap_port, 389}.
{ldap_rootdn, "cn=Manager,dc=domain,dc=org"}.
{ldap_password, "secret"}.
\end{verbatim}
Note that current LDAP implementation doesn't support SSL connection and SASL
authentication.
\subsubsection{Authentication}
\label{sec:ldapauthentication}
You can authenticate users against LDAP directory. Available parameters are
listed below:
\begin{description}
\titem{ldap\_base} \ind{options!ldap_base}LDAP base directory which stores users
accounts. This option is required.
\titem{ldap\_uidattr} \ind{options!ldap_uidattr}LDAP attribute which holds
user's part of JID. Default is \term{"uid"}.
\titem{ldap\_uidattr\_format} \ind{options!ldap_uidattr_format}Format of the
\term{ldap\_uidattr} variable. Format MUST contain one and only one pattern
variable \term{"\%u"} which will be replaced by user's part of JID. For example,
\term{"\%u@mydomain.org"}. Default value is \term{"\%u"}.
\titem{ldap\_filter} \ind{options!ldap_filter}RFC 2254 LDAP filter. Default is
\term{none}. Example: \term{"(\&(objectClass=shadowAccount)(memberOf=Jabber
Users))"}. Please, don't forget closing brackets and don't use superfluous
whitespaces. Also you MUST NOT use \option{ldap\_uidattr} attribute in filter
because this attribute will be substituted in LDAP filter automatically.
\end{description}
\subsubsection{vCards and Search}
\label{sec:modvcardldap}
\ejabberd{} can map LDAP attributes to vCard fields. This behaviour is
implemented in \modvcardldap{} module. This module doesn't depend on
authentication method. \modvcardldap{} module has it's own optional
parameters. The first group of parameters has the same meaning as top-level
LDAP parameters: \option{ldap\_servers}, \option{ldap\_port},
\option{ldap\_rootdn}, \option{ldap\_password}, \option{ldap\_base},
\option{ldap\_uidattr}, \option{ldap\_uidattr\_format} and
\option{ldap\_filter}. If one of this option is not set \ejabberd{} will look
for top-level option with the same name. The second group of parameters
consists of the following options:
\begin{description}
\hostitem{vjud}
\iqdiscitem{\ns{vcard-temp}}
\titem{search} \ind{options!search}This option specifies whether the search
functionality is enabled (value: \term{true}) or disabled
(value: \term{false}). If disabled, the option \term{hosts} will be
ignored and the \Jabber{} User Directory service will not appear in the
Service Discovery item list. The default value is \term{true}.
\titem{ldap\_vcard\_map} \ind{options!ldap_vcard_map}the table which defines
reflection of LDAP attributes to vCard fields.
Format is:
\term{[{Name\_of\_vcard\_field, Pattern, List\_of\_LDAP\_attributes}, ...]}
where
\term{Name\_of\_vcard\_field} is the type name of vCard as defined
in RFC 2426,
Pattern is a string which contains pattern variables \term{"\%u"}, \term{"\%d"} or \term{"\%s"},
\term{List\_of\_LDAP\_attributes} is the list which contains of LDAP attributes.
Pattern variables \term{"\%s"} will be sequentially replaced with the values of
LDAP attributes from \term{List\_of\_LDAP\_attributes}; \term{"\%u"} will be replaced with
user's part of JID and \term{"\%d"} will be replaced with domain part of JID.
Example:
\begin{verbatim}
{ldap_vcard_map,
[{"NICKNAME", "%u", []},
{"FN", "%s", ["displayName"]},
{"CTRY", "Russia", []},
{"EMAIL", "%u@%d", []},
{"DESC", "%s\n%s", ["title", "description"]}
]},
\end{verbatim}
Default is:
\begin{verbatim}
[{"NICKNAME", "%u", []},
{"FN", "%s", ["displayName"]},
{"FAMILY", "%s", ["sn"]},
{"GIVEN", "%s", ["givenName"]},
{"MIDDLE", "%s", ["initials"]},
{"ORGNAME", "%s", ["o"]},
{"ORGUNIT", "%s", ["ou"]},
{"CTRY", "%s", ["c"]},
{"LOCALITY", "%s", ["l"]},
{"STREET", "%s", ["street"]},
{"REGION", "%s", ["st"]},
{"PCODE", "%s", ["postalCode"]},
{"TITLE", "%s", ["title"]},
{"URL", "%s", ["labeleduri"]},
{"DESC", "%s", ["description"]},
{"TEL", "%s", ["telephoneNumber"]},
{"EMAIL", "%s", ["mail"]},
{"BDAY", "%s", ["birthDay"]},
{"ROLE", "%s", ["employeeType"]},
{"PHOTO", "%s", ["jpegPhoto"]}]
\end{verbatim}
\titem{ldap\_search\_fields} \ind{options!ldap_search_fields}This option defines
search form and LDAP attributes to search.
Format:
\term{[{Name, Attribute}, ...]}
where
\term{Name} is the name of field in the search form. Will be automatically
translated according to definitions in translation files (see
\term{msgs/*.msg} for available words).
Attribute is the LDAP attribute or the pattern \term{"\%u"}
Example:
\begin{verbatim}
{ldap_search_fields,
[{"User", "uid"},
{"Full Name", "displayName"},
{"Email", "mail"}
]},
\end{verbatim}
Default is:
\begin{verbatim}
[{"User", "%u"},
{"Full Name", "displayName"},
{"Given Name", "givenName"},
{"Middle Name", "initials"},
{"Family Name", "sn"},
{"Nickname", "%u"},
{"Birthday", "birthDay"},
{"Country", "c"},
{"City", "l"},
{"Email", "mail"},
{"Organization Name", "o"},
{"Organization Unit", "ou"}]
\end{verbatim}
\titem{ldap\_search\_reported} \ind{options!ldap_search_reported}This option defines search fields to be reported.
Format:
\term{[{Name, VCard\_Name}, ...]}
where
\term{Name} is the name of field in the search form. Will be automatically
translated according to definitions in translation files (see
\term{msgs/*.msg} for available words).
\term{VCard\_Name} is the name of vCard field defined in \option{ldap\_vcard\_map} option.
Example:
\begin{verbatim}
{ldap_search_reported,
[{"Full Name", "FN"},
{"Email", "EMAIL"},
{"Birthday", "BDAY"},
{"Nickname", "NICKNAME"}
]},
\end{verbatim}
Default is:
\begin{verbatim}
[{"Full Name", "FN"},
{"Given Name", "GIVEN"},
{"Middle Name", "MIDDLE"},
{"Family Name", "FAMILY"},
{"Nickname", "NICKNAME"},
{"Birthday", "BDAY"},
{"Country", "CTRY"},
{"City", "LOCALITY"},
{"Email", "EMAIL"},
{"Organization Name", "ORGNAME"},
{"Organization Unit", "ORGUNIT"}]
\end{verbatim}
\end{description}
\subsubsection{Examples}
\label{sec:ldapexamples}
\paragraph{Common example}
Let's say \term{ldap.mydomain.org} is the name of our LDAP server. We have
users with their passwords in \term{"ou=Users,dc=mydomain,dc=org"} directory.
Also we have addressbook, which contains users emails and their additional
infos in \term{"ou=AddressBook,dc=mydomain,dc=org"} directory. Corresponding
authentication section should looks like this:
\begin{verbatim}
%% authentication method
{auth_method, ldap}.
%% DNS name of our LDAP server
{ldap_servers, ["ldap.mydomain.org"]}.
%% Bind to LDAP server as "cn=Manager,dc=mydomain,dc=org" with password "secret"
{ldap_rootdn, "cn=Manager,dc=mydomain,dc=org"}.
{ldap_password, "secret"}.
%% define the user's base
{ldap_base, "ou=Users,dc=mydomain,dc=org"}.
%% We want to authorize users from 'shadowAccount' object class only
{ldap_filter, "(objectClass=shadowAccount)"}.
\end{verbatim}
Now we want to use users LDAP-info as their vCards. We have four attributes
defined in our LDAP schema: \term{"mail"} --- email address, \term{"givenName"}
--- first name, \term{"sn"} --- second name, \term{"birthDay"} --- birthday.
Also we want users to search each other. Let's see how we can set it up:
\begin{verbatim}
{modules,
...
{mod_vcard_ldap,
[
%% We use the same server and port, but want to bind anonymously because
%% our LDAP server accepts anonymous requests to
%% "ou=AddressBook,dc=mydomain,dc=org" subtree.
{ldap_rootdn, ""},
{ldap_password, ""},
%% define the addressbook's base
{ldap_base, "ou=AddressBook,dc=mydomain,dc=org"},
%% user's part of JID is located in the "mail" attribute
{ldap_uidattr, "mail"},
%% common format for our emails
{ldap_uidattr_format, "%u@mail.mydomain.org"},
%% We have to define empty filter here, because entries in addressbook doesn't
%% belong to shadowAccount object class
{ldap_filter, ""},
%% Now we want to define vCard pattern
{ldap_vcard_map,
[{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
{"GIVEN", "%s", ["givenName"]},
{"FAMILY", "%s", ["sn"]},
{"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
{"EMAIL", "%s", ["mail"]},
{"BDAY", "%s", ["birthDay"]}]},
%% Search form
{ldap_search_fields,
[{"User", "%u"},
{"Name", "givenName"},
{"Family Name", "sn"},
{"Email", "mail"},
{"Birthday", "birthDay"}]},
%% vCard fields to be reported
%% Note that JID is always returned with search results
{ldap_search_reported,
[{"Full Name", "FN"},
{"Nickname", "NICKNAME"},
{"Birthday", "BDAY"}]}
]}
...
}.
\end{verbatim}
Note that \modvcardldap{} module checks an existence of the user before
searching his info in LDAP.
\paragraph{Active Directory}
Active Directory is just an LDAP-server with predefined attributes. Sample
config file is listed below:
\begin{verbatim}
{auth_method, ldap}.
{ldap_servers, ["office.org"]}. % List of LDAP servers
{ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory
{ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager
{ldap_password, "*******"}. % Password to LDAP manager
{ldap_uidattr, "sAMAccountName"}.
{ldap_filter, "(memberOf=*)"}.
{mod_vcard_ldap,
[{ldap_vcard_map,
[{"NICKNAME", "%u", []},
{"GIVEN", "%s", ["givenName"]},
{"MIDDLE", "%s", ["initials"]},
{"FAMILY", "%s", ["sn"]},
{"FN", "%s", ["displayName"]},
{"EMAIL", "%s", ["mail"]},
{"ORGNAME", "%s", ["company"]},
{"ORGUNIT", "%s", ["department"]},
{"CTRY", "%s", ["c"]},
{"LOCALITY", "%s", ["l"]},
{"STREET", "%s", ["streetAddress"]},
{"REGION", "%s", ["st"]},
{"PCODE", "%s", ["postalCode"]},
{"TITLE", "%s", ["title"]},
{"URL", "%s", ["wWWHomePage"]},
{"DESC", "%s", ["description"]},
{"TEL", "%s", ["telephoneNumber"]}]},
{ldap_search_fields,
[{"User", "%u"},
{"Name", "givenName"},
{"Family Name", "sn"},
{"Email", "mail"},
{"Company", "company"},
{"Department", "department"},
{"Role", "title"},
{"Description", "description"},
{"Phone", "telephoneNumber"}]},
{ldap_search_reported,
[{"Full Name", "FN"},
{"Nickname", "NICKNAME"},
{"Email", "EMAIL"}]}
]
}.
\end{verbatim}
\subsection{\modversion{}}
\label{sec:modversion}
\ind{modules!\modversion{}}\ind{protocols!JEP-0092: Software Version}

View File

@ -10,8 +10,21 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-behaviour(gen_server).
%% gen_server callbacks
-export([init/1,
handle_info/2,
handle_call/3,
handle_cast/2,
terminate/2,
code_change/3
]).
%% External exports
-export([start/1,
stop/1,
start_link/1,
set_password/3,
check_password/3,
check_password/5,
@ -29,39 +42,84 @@
-include("ejabberd.hrl").
-include("eldap/eldap.hrl").
-record(state, {host,
eldap_id,
servers,
port,
dn,
password,
base,
uidattr,
uidattr_format,
ufilter,
sfilter,
dn_filter,
dn_filter_attrs
}).
%% Unused callbacks.
handle_cast(_Request, State) ->
{noreply, State}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
handle_info(_Info, State) ->
{noreply, State}.
%% -----
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(Host) ->
LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
RootDN = ejabberd_config:get_local_option({ldap_rootdn, Host}),
Password = ejabberd_config:get_local_option({ldap_password, Host}),
eldap:start_link(get_eldap_id(Host, ejabberd),
LDAPServers, 389, RootDN, Password),
eldap:start_link(get_eldap_id(Host, ejabberd_bind),
LDAPServers, 389, RootDN, Password),
Proc = gen_mod:get_module_proc(Host, ?MODULE),
ChildSpec = {
Proc, {?MODULE, start_link, [Host]},
permanent, 1000, worker, [?MODULE]
},
supervisor:start_child(ejabberd_sup, ChildSpec).
stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?MODULE),
gen_server:call(Proc, stop),
supervisor:terminate_child(ejabberd_sup, Proc),
supervisor:delete_child(ejabberd_sup, Proc).
start_link(Host) ->
Proc = gen_mod:get_module_proc(Host, ?MODULE),
gen_server:start_link({local, Proc}, ?MODULE, Host, []).
terminate(_Reason, State) ->
ejabberd_ctl:unregister_commands(
State#state.host,
[{"registered-users", "list all registered users"}],
ejabberd_auth, ctl_process_get_registered).
init(Host) ->
State = parse_options(Host),
eldap:start_link(State#state.eldap_id,
State#state.servers,
State#state.port,
State#state.dn,
State#state.password),
ejabberd_ctl:register_commands(
Host,
[{"registered-users", "list all registered users"}],
ejabberd_auth, ctl_process_get_registered),
ok.
{ok, State}.
-define(REPLY_TIMEOUT, 10000).
plain_password_required() ->
true.
check_password(User, Server, Password) ->
case find_user_dn(User, Server) of
false ->
Proc = gen_mod:get_module_proc(Server, ?MODULE),
case catch gen_server:call(Proc,
{check_pass, User, Password}, ?REPLY_TIMEOUT) of
{'EXIT', _} ->
false;
DN ->
LServer = jlib:nameprep(Server),
case eldap:bind(get_eldap_id(LServer, ejabberd_bind),
DN, Password) of
ok ->
true;
_ ->
false
end
Result ->
Result
end.
check_password(User, Server, Password, _StreamID, _Digest) ->
@ -77,31 +135,13 @@ dirty_get_registered_users() ->
get_vh_registered_users(?MYNAME).
get_vh_registered_users(Server) ->
LServer = jlib:nameprep(Server),
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
Filter = eldap:present(Attr),
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
case eldap:search(get_eldap_id(LServer, ejabberd),
[{base, Base},
{filter, Filter},
{attributes, [Attr]}]) of
#eldap_search_result{entries = Es} ->
lists:flatmap(
fun(E) ->
case lists:keysearch(Attr, 1, E#eldap_entry.attributes) of
{value, {_, [U]}} ->
case jlib:nodeprep(U) of
error ->
[];
LU ->
[{LU, LServer}]
end;
_ ->
[]
end
end, Es);
_ ->
[]
Proc = gen_mod:get_module_proc(Server, ?MODULE),
case catch gen_server:call(Proc,
get_vh_registered_users, ?REPLY_TIMEOUT) of
{'EXIT', _} ->
[];
Result ->
Result
end.
get_password(_User, _Server) ->
@ -111,11 +151,13 @@ get_password_s(_User, _Server) ->
"".
is_user_exists(User, Server) ->
case find_user_dn(User, Server) of
false ->
Proc = gen_mod:get_module_proc(Server, ?MODULE),
case catch gen_server:call(Proc,
{is_user_exists, User}, ?REPLY_TIMEOUT) of
{'EXIT', _} ->
false;
_DN ->
true
Result ->
Result
end.
remove_user(_User, _Server) ->
@ -124,25 +166,212 @@ remove_user(_User, _Server) ->
remove_user(_User, _Server, _Password) ->
not_allowed.
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
handle_call({check_pass, User, Password}, _From, State) ->
Reply = case find_user_dn(User, State) of
false ->
false;
DN ->
case eldap:bind(State#state.eldap_id, DN, Password) of
ok -> true;
_ -> false
end
end,
{reply, Reply, State};
find_user_dn(User, Server) ->
LServer = jlib:nameprep(Server),
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
Filter = eldap:equalityMatch(Attr, User),
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
case eldap:search(get_eldap_id(LServer, ejabberd),
[{base, Base},
{filter, Filter},
{attributes, []}]) of
#eldap_search_result{entries = [E | _]} ->
E#eldap_entry.object_name;
handle_call(get_vh_registered_users, _From, State) ->
UA = State#state.uidattr,
UAF = State#state.uidattr_format,
Eldap_ID = State#state.eldap_id,
Server = State#state.host,
SortedDNAttrs = usort_attrs(State#state.dn_filter_attrs),
Reply = case eldap_filter:parse(State#state.sfilter) of
{ok, EldapFilter} ->
case eldap:search(Eldap_ID, [{base, State#state.base},
{filter, EldapFilter},
{attributes, SortedDNAttrs}]) of
#eldap_search_result{entries = Entries} ->
lists:flatmap(
fun(#eldap_entry{attributes = Attrs,
object_name = DN}) ->
case is_valid_dn(DN, Attrs, State) of
false -> [];
_ ->
case get_ldap_attr(UA, Attrs) of
"" -> [];
User ->
case get_user_part(User, UAF) of
{ok, U} ->
case jlib:nodeprep(U) of
error -> [];
LU -> [{LU, jlib:nameprep(Server)}]
end;
_ -> []
end
end
end
end, Entries);
_ ->
[]
end;
_ ->
[]
end,
{reply, Reply, State};
handle_call({is_user_exists, User}, _From, State) ->
Reply = case find_user_dn(User, State) of
false -> false;
_DN -> true
end,
{reply, Reply, State};
handle_call(stop, _From, State) ->
{stop, normal, ok, State};
handle_call(_Request, _From, State) ->
{reply, bad_request, State}.
find_user_dn(User, State) ->
DNAttrs = usort_attrs(State#state.dn_filter_attrs),
case eldap_filter:parse(State#state.ufilter, [{"%u", User}]) of
{ok, Filter} ->
case eldap:search(State#state.eldap_id, [{base, State#state.base},
{filter, Filter},
{attributes, DNAttrs}]) of
#eldap_search_result{entries = [#eldap_entry{attributes = Attrs,
object_name = DN} | _]} ->
is_valid_dn(DN, Attrs, State);
_ ->
false
end;
_ ->
false
end.
get_eldap_id(Host, Name) ->
atom_to_list(gen_mod:get_module_proc(Host, Name)).
is_valid_dn(DN, _, #state{dn_filter = undefined}) ->
DN;
is_valid_dn(DN, Attrs, State) ->
DNAttrs = State#state.dn_filter_attrs,
UA = State#state.uidattr,
UAF = State#state.uidattr_format,
Values = [{"%s", get_ldap_attr(Attr, Attrs), 1} || Attr <- DNAttrs],
SubstValues = case get_ldap_attr(UA, Attrs) of
"" -> Values;
S ->
case get_user_part(S, UAF) of
{ok, U} -> [{"%u", U} | Values];
_ -> Values
end
end ++ [{"%d", State#state.host}, {"%D", DN}],
case eldap_filter:parse(State#state.dn_filter, SubstValues) of
{ok, EldapFilter} ->
case eldap:search(State#state.eldap_id, [
{base, State#state.base},
{filter, EldapFilter},
{attributes, ["dn"]}]) of
#eldap_search_result{entries = [_|_]} ->
DN;
_ ->
false
end;
_ ->
false
end.
%%%----------------------------------------------------------------------
%%% Auxiliary functions
%%%----------------------------------------------------------------------
get_user_part(String, Pattern) ->
F = fun(S, P) ->
First = string:str(P, "%u"),
TailLength = length(P) - (First+1),
string:sub_string(S, First, length(S) - TailLength)
end,
case catch F(String, Pattern) of
{'EXIT', _} ->
{error, badmatch};
Result ->
case regexp:sub(Pattern, "%u", Result) of
{ok, String, _} -> {ok, Result};
_ -> {error, badmatch}
end
end.
case_insensitive_match(X, Y) ->
X1 = stringprep:tolower(X),
Y1 = stringprep:tolower(Y),
if
X1 == Y1 -> true;
true -> false
end.
get_ldap_attr(LDAPAttr, Attributes) ->
Res = lists:filter(
fun({Name, _}) ->
case_insensitive_match(Name, LDAPAttr)
end, Attributes),
case Res of
[{_, [Value|_]}] -> Value;
_ -> ""
end.
usort_attrs(Attrs) when is_list(Attrs) ->
lists:usort(Attrs);
usort_attrs(_) ->
[].
parse_options(Host) ->
Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?MODULE)),
LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
LDAPPort = case ejabberd_config:get_local_option({ldap_port, Host}) of
undefined -> 389;
P -> P
end,
RootDN = case ejabberd_config:get_local_option({ldap_rootdn, Host}) of
undefined -> "";
RDN -> RDN
end,
Password = case ejabberd_config:get_local_option({ldap_password, Host}) of
undefined -> "";
Pass -> Pass
end,
UIDAttr = case ejabberd_config:get_local_option({ldap_uidattr, Host}) of
undefined -> "uid";
UA -> UA
end,
UIDAttrFormat = case ejabberd_config:get_local_option({ldap_uidattr_format, Host}) of
undefined -> "%u";
UAF -> UAF
end,
SubFilter = "(" ++ UIDAttr ++ "=" ++ UIDAttrFormat ++ ")",
UserFilter = case ejabberd_config:get_local_option({ldap_filter, Host}) of
undefined -> SubFilter;
"" -> SubFilter;
F -> "(&" ++ SubFilter ++ F ++ ")"
end,
SearchFilter = eldap_filter:do_sub(UserFilter, [{"%u", "*"}]),
LDAPBase = ejabberd_config:get_local_option({ldap_base, Host}),
{DNFilter, DNFilterAttrs} =
case ejabberd_config:get_local_option({ldap_dn_filter, Host}) of
undefined -> {undefined, undefined};
{DNF, DNFA} -> {DNF, DNFA}
end,
#state{host = Host,
eldap_id = Eldap_ID,
servers = LDAPServers,
port = LDAPPort,
dn = RootDN,
password = Password,
base = LDAPBase,
uidattr = UIDAttr,
uidattr_format = UIDAttrFormat,
ufilter = UserFilter,
sfilter = SearchFilter,
dn_filter = DNFilter,
dn_filter_attrs = DNFilterAttrs
}.

View File

@ -12,7 +12,8 @@ OUTDIR = ..
EFLAGS = -I .. -pz ..
OBJS = \
$(OUTDIR)/eldap.beam \
$(OUTDIR)/ELDAPv3.beam
$(OUTDIR)/ELDAPv3.beam \
$(OUTDIR)/eldap_filter.beam
all: $(OBJS)

View File

@ -6,7 +6,8 @@ EFLAGS = -I .. -pz ..
OBJS = \
$(OUTDIR)\eldap.beam \
$(OUTDIR)\ELDAPv3.beam
$(OUTDIR)\ELDAPv3.beam \
$(OUTDIR)\eldap_filter.beam
ALL : $(OBJS)

File diff suppressed because it is too large Load Diff