⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eldap.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 3 页
字号:
-module(eldap).%%% --------------------------------------------------------------------%%% Created:  12 Oct 2000 by Tobbe <tnt@home.se>%%% Function: Erlang client LDAP implementation according RFC 2251.%%%           The interface is based on RFC 1823, and%%%           draft-ietf-asid-ldap-c-api-00.txt%%%%%% Copyright (C) 2000  Torbj鰎n T鰎nkvist, tnt@home.se%%% %%% This program is free software; you can redistribute it and/or modify%%% it under the terms of the GNU General Public License as published by%%% the Free Software Foundation; either version 2 of the License, or%%% (at your option) any later version.%%%%%% This program is distributed in the hope that it will be useful,%%% but WITHOUT ANY WARRANTY; without even the implied warranty of%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the%%% GNU General Public License for more details.%%%%%% You should have received a copy of the GNU General Public License%%% along with this program; if not, write to the Free Software%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA%%% Modified by Sean Hinde <shinde@iee.org> 7th Dec 2000%%% Turned into gen_fsm, made non-blocking, added timers etc to support this.%%% Now has the concept of a name (string() or atom()) per instance which allows%%% multiple users to call by name if so desired.%%%%%% Can be configured with start_link parameters or use a config file to get%%% host to connect to, dn, password, log function etc.%%% Modified by Alexey Shchepin <alexey@sevcom.net>%%% ---------------------------------------------------------------------vc('$Id: eldap.erl,v 1.2 2004/07/23 14:24:09 aleksey Exp $ ').%%%----------------------------------------------------------------------%%% LDAP Client state machine.%%% Possible states are:%%%     connecting - actually disconnected, but retrying periodically%%%     wait_bind_response  - connected and sent bind request%%%     active - bound to LDAP Server and ready to handle commands%%%----------------------------------------------------------------------%%-compile(export_all).%%-export([Function/Arity, ...]).-behaviour(gen_fsm).%% External exports-export([start_link/1, start_link/5, start_link/6]).-export([baseObject/0,singleLevel/0,wholeSubtree/0,close/1,	 equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,	 approxMatch/2,search/2,substrings/2,present/1,	 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,	 mod_replace/2, add/3, delete/2, modify_dn/5, bind/3]).-export([debug_level/2, get_status/1]).%% gen_fsm callbacks-export([init/1, connecting/2,	 connecting/3, wait_bind_response/3, active/3, handle_event/3,	 handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).-import(lists,[concat/1]).-include("ELDAPv3.hrl").-include("eldap.hrl").-define(LDAP_VERSION, 3).-define(RETRY_TIMEOUT, 5000).-define(BIND_TIMEOUT, 10000).-define(CMD_TIMEOUT, 5000).-define(MAX_TRANSACTION_ID, 65535).-define(MIN_TRANSACTION_ID, 0).-record(eldap, {version = ?LDAP_VERSION,		hosts,	      % Possible hosts running LDAP servers		host = null,  % Connected Host LDAP server		port = 389 ,  % The LDAP server port		fd = null,    % Socket filedescriptor.		rootdn = "",  % Name of the entry to bind as		passwd,       % Password for (above) entry		id = 0,       % LDAP Request ID 		log,          % User provided log function		bind_timer,   % Ref to bind timeout		dict,         % dict holding operation params and results		debug_level   % Integer debug/logging level	       }).%%%----------------------------------------------------------------------%%% API%%%----------------------------------------------------------------------start_link(Name) ->    Reg_name = list_to_atom("eldap_" ++ Name),    gen_fsm:start_link({local, Reg_name}, ?MODULE, [], []).start_link(Name, Hosts, Port, Rootdn, Passwd) ->    Log = fun(N, Fmt, Args) -> io:format("---- " ++ Fmt, [Args]) end,    Reg_name = list_to_atom("eldap_" ++ Name),    gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).start_link(Name, Hosts, Port, Rootdn, Passwd, Log) ->    Reg_name = list_to_atom("eldap_" ++ Name),    gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).%%% --------------------------------------------------------------------%%% Set Debug Level. 0 - none, 1 - errors, 2 - ldap events%%% --------------------------------------------------------------------debug_level(Handle, N) when integer(N) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_all_state_event(Handle1, {debug_level,N}).%%% --------------------------------------------------------------------%%% Get status of connection.%%% --------------------------------------------------------------------get_status(Handle) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_all_state_event(Handle1, get_status).%%% --------------------------------------------------------------------%%% Shutdown connection (and process) asynchronous.%%% --------------------------------------------------------------------close(Handle) ->    Handle1 = get_handle(Handle),    gen_fsm:send_all_state_event(Handle1, close).%%% --------------------------------------------------------------------%%% Add an entry. The entry field MUST NOT exist for the AddRequest%%% to succeed. The parent of the entry MUST exist.%%% Example:%%%%%%  add(Handle, %%%         "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",%%%         [{"objectclass", ["person"]},%%%          {"cn", ["Bill Valentine"]},%%%          {"sn", ["Valentine"]},%%%          {"telephoneNumber", ["545 555 00"]}]%%%     )%%% --------------------------------------------------------------------add(Handle, Entry, Attributes) when list(Entry),list(Attributes) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}).%%% Do sanity check !add_attrs(Attrs) ->    F = fun({Type,Vals}) when list(Type),list(Vals) -> 		%% Confused ? Me too... :-/		{'AddRequest_attributes',Type, Vals} 	end,    case catch lists:map(F, Attrs) of	{'EXIT', _} -> throw({error, attribute_values});	Else        -> Else    end.%%% --------------------------------------------------------------------%%% Delete an entry. The entry consists of the DN of %%% the entry to be deleted.%%% Example:%%%%%%  delete(Handle, %%%         "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com"%%%        )%%% --------------------------------------------------------------------delete(Handle, Entry) when list(Entry) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {delete, Entry}).%%% --------------------------------------------------------------------%%% Modify an entry. Given an entry a number of modification%%% operations can be performed as one atomic operation.%%% Example:%%%%%%  modify(Handle, %%%         "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com",%%%         [replace("telephoneNumber", ["555 555 00"]),%%%          add("description", ["LDAP hacker"])] %%%        )%%% --------------------------------------------------------------------modify(Handle, Object, Mods) when list(Object), list(Mods) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}).%%%%%% Modification operations. %%% Example:%%%            replace("telephoneNumber", ["555 555 00"])%%%mod_add(Type, Values) when list(Type), list(Values)     -> m(add, Type, Values).mod_delete(Type, Values) when list(Type), list(Values)  -> m(delete, Type, Values).mod_replace(Type, Values) when list(Type), list(Values) -> m(replace, Type, Values).m(Operation, Type, Values) ->    #'ModifyRequest_modification_SEQOF'{       operation = Operation,       modification = #'AttributeTypeAndValues'{	 type = Type,	 vals = Values}}.%%% --------------------------------------------------------------------%%% Modify an entry. Given an entry a number of modification%%% operations can be performed as one atomic operation.%%% Example:%%%%%%  modify_dn(Handle, %%%    "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",%%%    "cn=Ben Emerson",%%%    true,%%%    ""%%%        )%%% --------------------------------------------------------------------modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)   when list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}).%%% --------------------------------------------------------------------%%% Bind.%%% Example:%%%%%%  bind(Handle, %%%    "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com",%%%    "secret")%%% --------------------------------------------------------------------bind(Handle, RootDN, Passwd)   when list(RootDN),list(Passwd) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}).%%% Sanity checks !bool_p(Bool) when Bool==true;Bool==false -> Bool.optional([])    -> asn1_NOVALUE;optional(Value) -> Value.%%% --------------------------------------------------------------------%%% Synchronous search of the Directory returning a %%% requested set of attributes.%%%%%%  Example:%%%%%%	Filter = eldap:substrings("sn", [{any,"o"}]),%%%	eldap:search(S, [{base, "dc=bluetail, dc=com"},%%%	                 {filter, Filter},%%%			 {attributes,["cn"]}])),%%%%%% Returned result:  {ok, #eldap_search_result{}}%%%%%% Example:%%%%%%  {ok,{eldap_search_result,%%%        [{eldap_entry,%%%           "cn=Magnus Froberg, dc=bluetail, dc=com",%%%           [{"cn",["Magnus Froberg"]}]},%%%         {eldap_entry,%%%           "cn=Torbjorn Tornkvist, dc=bluetail, dc=com",%%%           [{"cn",["Torbjorn Tornkvist"]}]}],%%%        []}}%%%%%% --------------------------------------------------------------------search(Handle, A) when record(A, eldap_search) ->    call_search(Handle, A);search(Handle, L) when list(Handle), list(L) ->    case catch parse_search_args(L) of	{error, Emsg}                  -> {error, Emsg};	{'EXIT', Emsg}                 -> {error, Emsg};	A when record(A, eldap_search) -> call_search(Handle, A)    end.call_search(Handle, A) ->    Handle1 = get_handle(Handle),    gen_fsm:sync_send_event(Handle1, {search, A}).parse_search_args(Args) ->    parse_search_args(Args, #eldap_search{scope = wholeSubtree}).		       parse_search_args([{base, Base}|T],A) ->    parse_search_args(T,A#eldap_search{base = Base});parse_search_args([{filter, Filter}|T],A) ->    parse_search_args(T,A#eldap_search{filter = Filter});parse_search_args([{scope, Scope}|T],A) ->    parse_search_args(T,A#eldap_search{scope = Scope});parse_search_args([{attributes, Attrs}|T],A) ->    parse_search_args(T,A#eldap_search{attributes = Attrs});parse_search_args([{types_only, TypesOnly}|T],A) ->    parse_search_args(T,A#eldap_search{types_only = TypesOnly});parse_search_args([{timeout, Timeout}|T],A) when integer(Timeout) ->    parse_search_args(T,A#eldap_search{timeout = Timeout});parse_search_args([H|T],A) ->    throw({error,{unknown_arg, H}});parse_search_args([],A) ->    A.%%%%%% The Scope parameter%%%baseObject()   -> baseObject.singleLevel()  -> singleLevel.wholeSubtree() -> wholeSubtree.%%%%%% Boolean filter operations%%%'and'(ListOfFilters) when list(ListOfFilters) -> {'and',ListOfFilters}.'or'(ListOfFilters)  when list(ListOfFilters) -> {'or', ListOfFilters}.'not'(Filter)        when tuple(Filter)       -> {'not',Filter}.%%%%%% The following Filter parameters consist of an attribute%%% and an attribute value. Example: F("uid","tobbe")%%%equalityMatch(Desc, Value)   -> {equalityMatch, av_assert(Desc, Value)}.greaterOrEqual(Desc, Value)  -> {greaterOrEqual, av_assert(Desc, Value)}.lessOrEqual(Desc, Value)     -> {lessOrEqual, av_assert(Desc, Value)}.approxMatch(Desc, Value)     -> {approxMatch, av_assert(Desc, Value)}.av_assert(Desc, Value) ->    #'AttributeValueAssertion'{attributeDesc  = Desc,			       assertionValue = Value}.%%%%%% Filter to check for the presence of an attribute%%%present(Attribute) when list(Attribute) ->     {present, Attribute}.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -