Skip to content

Instantly share code, notes, and snippets.

@posilva
Created March 5, 2018 09:32
Show Gist options
  • Save posilva/a83eb94a13375137a94350dcb6300bd8 to your computer and use it in GitHub Desktop.
Save posilva/a83eb94a13375137a94350dcb6300bd8 to your computer and use it in GitHub Desktop.
Simple LDAP Authentication in Erlang (escript)
-module(ldapc).
%% API exports
-export([main/1]).
-include_lib("eldap/include/eldap.hrl").
%%====================================================================
%% API functions
%%====================================================================
usage() ->
io:format("Usage: ~s <host> <base_dn> <user_grp> ~n", [escript:script_name()]),
halt(1).
authenticate(Conn, Login, Password) ->
case eldap:simple_bind(Conn, Login, Password) of
ok ->
ok;
{error, Reason} ->
{error, Reason}
end.
mail_or_username_filter(Login) ->
eldap:'or'([
eldap:equalityMatch("userPrincipalName", Login),
eldap:equalityMatch("sAMAccountName", Login)]).
belongs_to_group(Conn, Login, GroupDN, BaseDN) ->
SearchOpts = [
{filter, mail_or_username_filter(Login)},
{base, BaseDN },
{scope, wholeSubtree},
{attributes, ["MemberOf"]}
],
case eldap:search(Conn, SearchOpts) of
{ok, #eldap_search_result{
entries=[#eldap_entry{attributes=Att}|_]}} ->
% io:format("Search result: ~p ~n", [Att]),
Groups = proplists:get_value("memberOf", Att),
member_of(Groups, GroupDN);
{error, _Reason} = Err ->
Err
end.
member_of0([], _Group) ->
false;
member_of0([H|T], Group) ->
case string:to_lower(H) =:= Group of
true -> true;
false -> member_of0(T, Group)
end.
member_of(ListOfGroups, Group, true) ->
member_of0(ListOfGroups, string:to_lower(Group));
member_of(ListOfGroups, Group, false) ->
lists:member(Group, ListOfGroups).
member_of(ListOfGroups, Group) ->
member_of(ListOfGroups, Group, false).
%% escript Entry point
main([Host, BaseDN, UserGroup]) ->
% io:format("Args: ~p~n", [Args]),
Options = [{ssl, false}, {timeout, 5000}],
{ok, Conn} = eldap:open([Host], Options),
% io:format("Connected to server ~n"),
{ok, [Login]} = io:fread("Username: ", "~s"),
{ok, [Password]} = io:fread("Password: ", "~s"),
ok = authenticate(Conn, Login, Password),
R = belongs_to_group(Conn, Login, UserGroup, BaseDN),
io:format("User [~p] is Authorized to access resources from group [~p] : ~p ~n", [Login, UserGroup, R]),
halt(0);
main(_Args) ->
usage().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment