Skip to content

Instantly share code, notes, and snippets.

@chao
Created January 18, 2011 07:32
Show Gist options
  • Select an option

  • Save chao/784095 to your computer and use it in GitHub Desktop.

Select an option

Save chao/784095 to your computer and use it in GitHub Desktop.
Patch CouchDB to add LDAP authentication support
diff --git LICENSE LICENSE
index 20a425b..6a5c617 100644
--- LICENSE
+++ LICENSE
@@ -369,3 +369,25 @@ For the src/etap component:
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+For the src/eldap component:
+
+ Copyright (c) 2010, Torbjorn Tornkvist
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
diff --git NOTICE NOTICE
index d547e55..cbaef4d 100644
--- NOTICE
+++ NOTICE
@@ -30,6 +30,10 @@ This product also includes the following third-party components:
Copyright 2009, Chandrashekhar Mullaparthi
+ * Eldap (http://github.com/etnt/eldap/tree/master)
+
+ Copyright 2009, Torbjorn Tornkvist <etnt@redhoterlang.com>
+
* Erlang OAuth (http://github.com/tim/erlang-oauth/tree/master)
Copyright 2009, Tim Fletcher <http://tfletcher.com/>
diff --git configure.ac configure.ac
index c609a08..a43b79e 100644
--- configure.ac
+++ configure.ac
@@ -398,6 +398,7 @@ AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
AC_CONFIG_FILES([src/couchdb/Makefile])
AC_CONFIG_FILES([src/couchdb/priv/Makefile])
+AC_CONFIG_FILES([src/eldap/Makefile])
AC_CONFIG_FILES([src/erlang-oauth/Makefile])
AC_CONFIG_FILES([src/etap/Makefile])
AC_CONFIG_FILES([src/ibrowse/Makefile])
diff --git license.skip license.skip
index a7aa6ec..66ea237 100644
--- license.skip
+++ license.skip
@@ -82,6 +82,7 @@
^src/couchdb/priv/couchjs
^src/couchdb/priv/couchspawnkillable
^src/couchdb/priv/stat_descriptions.cfg
+^src/eldap/*
^src/erlang-oauth/*
^src/etap/*
^src/ibrowse/*
diff --git src/Makefile.am src/Makefile.am
index b9529f9..525be09 100644
--- src/Makefile.am
+++ src/Makefile.am
@@ -10,4 +10,4 @@
## License for the specific language governing permissions and limitations under
## the License.
-SUBDIRS = couchdb erlang-oauth etap ibrowse mochiweb
+SUBDIRS = couchdb eldap erlang-oauth etap ibrowse mochiweb
diff --git src/couchdb/couch_httpd_auth.erl src/couchdb/couch_httpd_auth.erl
index 7023e7f..4472435 100644
--- src/couchdb/couch_httpd_auth.erl
+++ src/couchdb/couch_httpd_auth.erl
@@ -14,6 +14,7 @@
-include("couch_db.hrl").
-export([default_authentication_handler/1,special_test_authentication_handler/1]).
+-export ([ldap_authentication_handler/1]).
-export([cookie_authentication_handler/1]).
-export([null_authentication_handler/1]).
-export([proxy_authentification_handler/1]).
@@ -347,3 +348,100 @@ to_int(Value) when is_integer(Value) ->
make_cookie_time() ->
{NowMS, NowS, _} = erlang:now(),
NowMS * 1000000 + NowS.
+
+ldap_authentication_handler(Req) ->
+ LDAPUrl = couch_config:get
+ ("couch_httpd_auth", "auth_ldap_url",
+ "false"),
+ case LDAPUrl of
+ "false" ->
+ throw({error, "No auth_ldap_url defined."});
+ _ ->
+ case basic_name_pw(Req) of
+ {User, Pass} ->
+ try eldap:parse_ldap_url(LDAPUrl) of
+ {ok, LDAPServer, LDAPBindname, {attributes, [Attrdesc]}} ->
+ {LDAPHost, LDAPPort} = LDAPServer,
+ case length(LDAPBindname) of
+ 0->
+ throw({error, "LDAP URL is not correct."});
+ _->
+ BaseDN = concat_bindname(LDAPBindname),
+ %?LOG_INFO("Host:~p, Port:~p ~n BaseDN: ~p ~n LDAPAttributes: ~p ~n", [LDAPHost, LDAPPort, BaseDN, Attrdesc]),
+ case eldap:open([LDAPHost], [{port, LDAPPort}]) of
+ {ok, LDAPHandler} ->
+ UserDNList = lists:append([Attrdesc ++ "=" ++ User], BaseDN),
+ UserDN = string_join(",", UserDNList),
+ %?LOG_INFO("UserDN : ~p ~n", [UserDN]),
+ case eldap:simple_bind(LDAPHandler, UserDN, Pass) of
+ ok ->
+ StrBaseDN = string_join(",", BaseDN),
+ %?LOG_INFO("Connected to LDAP Server with UserDN: ~p, Pass: ~p", [UserDN, Pass]),
+ {ok, {eldap_search_result, LDAPSearchResult, []}} = eldap:search(LDAPHandler,
+ [{base, StrBaseDN},
+ {filter, eldap:equalityMatch("member", UserDN)},
+ {attributes, [Attrdesc]}]),
+ %?LOG_INFO("LDAPSearchResult: ~p", [LDAPSearchResult]),
+ case length(LDAPSearchResult) of
+ 0 ->
+ Req#httpd{user_ctx=#user_ctx{name=?l2b(User)}};
+ _ ->
+ Roles = ldap_groups(LDAPSearchResult, []),
+ %?LOG_INFO("User: ~p Roles:~p", [User, Roles]),
+ Req#httpd{user_ctx=#user_ctx{name=?l2b(User), roles=Roles}}
+ end;
+ {error,invalidCredentials} ->
+ throw({unauthorized, <<"Name or password is incorrect.">>});
+ _ ->
+ throw({error, "Unable to validate user on LDAP server."})
+ end;
+ _->
+ ?LOG_ERROR("Unable to connect to LDAP, Host: ~p Port: ~p", [LDAPHost, LDAPPort]),
+ throw({error, "Unable to bind to LDAP server."})
+ end
+ end
+ catch
+ error: _ ->
+ throw({error, "LDAP URL parse error."})
+ end;
+ nil ->
+ case couch_server:has_admins() of
+ true ->
+ %?LOG_INFO("has admins",[]),
+ Req;
+ false ->
+ %?LOG_INFO("has no admin",[]),
+ case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of
+ "true" ->
+ %?LOG_INFO("require valid user",[]),
+ Req;
+ _ ->
+ %?LOG_INFO("don't require valid user",[]),
+ Req#httpd{user_ctx=#user_ctx{roles=[<<"_admin">>]}}
+ end
+ end
+ end
+ end.
+ldap_groups([], Acc) ->
+ [list_to_binary(R) || R<-Acc];
+ldap_groups([C | Rest], Acc) ->
+ {eldap_entry,LDAPRecord, [{_, [GroupAttr]}]} = C,
+ ldap_groups(Rest, [GroupAttr | Acc]).
+
+concat_bindname(Bindname) ->
+ concat_bindname(Bindname, []).
+concat_bindname([], Acc) -> lists:reverse(Acc);
+ %[list_to_binary(R) || R<-lists:reverse(Acc)];
+concat_bindname([C | Rest], Acc) ->
+ [{attribute_type_and_value, Name, Value}] = C,
+ concat_bindname(Rest, [Name ++ "=" ++ Value | Acc]).
+
+string_join(Join, L) ->
+ string_join(Join, L, fun(E) -> E end).
+
+string_join(_Join, L=[], _Conv) ->
+ L;
+string_join(Join, [H|Q], Conv) ->
+ lists:flatten(lists:concat(
+ [Conv(H)|lists:map(fun(E) -> [Join, Conv(E)] end, Q)]
+ )).
\ No newline at end of file
diff --git src/eldap/ELDAPv3.erl src/eldap/ELDAPv3.erl
new file mode 100644
index 0000000..e18ee38
--- /dev/null
+++ src/eldap/ELDAPv3.erl
@@ -0,0 +1,3011 @@
+%% Generated by the Erlang ASN.1 BER-compiler version:1.6.15
+%% Purpose: encoder and decoder to the types in mod ELDAPv3
+
+-module('ELDAPv3').
+-include("ELDAPv3.hrl").
+-define('RT_BER',asn1rt_ber_bin).
+-asn1_info([{vsn,'1.6.15'},
+ {module,'ELDAPv3'},
+ {options,[ber,report_errors,{cwd,[47,85,115,101,114,115,47,99,104,97,111,47,80,114,111,106,101,99,116,115,47,106,117,110,103,101,114,108,47,108,105,98,47,101,108,100,97,112,47,115,114,99]},{outdir,[47,85,115,101,114,115,47,99,104,97,111,47,80,114,111,106,101,99,116,115,47,106,117,110,103,101,114,108,47,108,105,98,47,101,108,100,97,112,47,115,114,99]},{i,[46]},{i,[47,85,115,101,114,115,47,99,104,97,111,47,80,114,111,106,101,99,116,115,47,106,117,110,103,101,114,108,47,108,105,98,47,101,108,100,97,112,47,115,114,99]}]}]).
+
+-export([encoding_rule/0]).
+-export([
+'enc_LDAPMessage'/2,
+'enc_MessageID'/2,
+'enc_LDAPString'/2,
+'enc_LDAPOID'/2,
+'enc_LDAPDN'/2,
+'enc_RelativeLDAPDN'/2,
+'enc_AttributeType'/2,
+'enc_AttributeDescription'/2,
+'enc_AttributeDescriptionList'/2,
+'enc_AttributeValue'/2,
+'enc_AttributeValueAssertion'/2,
+'enc_AssertionValue'/2,
+'enc_Attribute'/2,
+'enc_MatchingRuleId'/2,
+'enc_LDAPResult'/2,
+'enc_Referral'/2,
+'enc_LDAPURL'/2,
+'enc_Controls'/2,
+'enc_Control'/2,
+'enc_BindRequest'/2,
+'enc_AuthenticationChoice'/2,
+'enc_SaslCredentials'/2,
+'enc_BindResponse'/2,
+'enc_UnbindRequest'/2,
+'enc_SearchRequest'/2,
+'enc_Filter'/2,
+'enc_SubstringFilter'/2,
+'enc_MatchingRuleAssertion'/2,
+'enc_SearchResultEntry'/2,
+'enc_PartialAttributeList'/2,
+'enc_SearchResultReference'/2,
+'enc_SearchResultDone'/2,
+'enc_ModifyRequest'/2,
+'enc_AttributeTypeAndValues'/2,
+'enc_ModifyResponse'/2,
+'enc_AddRequest'/2,
+'enc_AttributeList'/2,
+'enc_AddResponse'/2,
+'enc_DelRequest'/2,
+'enc_DelResponse'/2,
+'enc_ModifyDNRequest'/2,
+'enc_ModifyDNResponse'/2,
+'enc_CompareRequest'/2,
+'enc_CompareResponse'/2,
+'enc_AbandonRequest'/2,
+'enc_ExtendedRequest'/2,
+'enc_ExtendedResponse'/2
+]).
+
+-export([
+'dec_LDAPMessage'/2,
+'dec_MessageID'/2,
+'dec_LDAPString'/2,
+'dec_LDAPOID'/2,
+'dec_LDAPDN'/2,
+'dec_RelativeLDAPDN'/2,
+'dec_AttributeType'/2,
+'dec_AttributeDescription'/2,
+'dec_AttributeDescriptionList'/2,
+'dec_AttributeValue'/2,
+'dec_AttributeValueAssertion'/2,
+'dec_AssertionValue'/2,
+'dec_Attribute'/2,
+'dec_MatchingRuleId'/2,
+'dec_LDAPResult'/2,
+'dec_Referral'/2,
+'dec_LDAPURL'/2,
+'dec_Controls'/2,
+'dec_Control'/2,
+'dec_BindRequest'/2,
+'dec_AuthenticationChoice'/2,
+'dec_SaslCredentials'/2,
+'dec_BindResponse'/2,
+'dec_UnbindRequest'/2,
+'dec_SearchRequest'/2,
+'dec_Filter'/2,
+'dec_SubstringFilter'/2,
+'dec_MatchingRuleAssertion'/2,
+'dec_SearchResultEntry'/2,
+'dec_PartialAttributeList'/2,
+'dec_SearchResultReference'/2,
+'dec_SearchResultDone'/2,
+'dec_ModifyRequest'/2,
+'dec_AttributeTypeAndValues'/2,
+'dec_ModifyResponse'/2,
+'dec_AddRequest'/2,
+'dec_AttributeList'/2,
+'dec_AddResponse'/2,
+'dec_DelRequest'/2,
+'dec_DelResponse'/2,
+'dec_ModifyDNRequest'/2,
+'dec_ModifyDNResponse'/2,
+'dec_CompareRequest'/2,
+'dec_CompareResponse'/2,
+'dec_AbandonRequest'/2,
+'dec_ExtendedRequest'/2,
+'dec_ExtendedResponse'/2
+]).
+
+-export([
+'dec_LDAPMessage'/3,
+'dec_MessageID'/3,
+'dec_LDAPString'/3,
+'dec_LDAPOID'/3,
+'dec_LDAPDN'/3,
+'dec_RelativeLDAPDN'/3,
+'dec_AttributeType'/3,
+'dec_AttributeDescription'/3,
+'dec_AttributeDescriptionList'/3,
+'dec_AttributeValue'/3,
+'dec_AttributeValueAssertion'/3,
+'dec_AssertionValue'/3,
+'dec_Attribute'/3,
+'dec_MatchingRuleId'/3,
+'dec_LDAPResult'/3,
+'dec_Referral'/3,
+'dec_LDAPURL'/3,
+'dec_Controls'/3,
+'dec_Control'/3,
+'dec_BindRequest'/3,
+'dec_AuthenticationChoice'/3,
+'dec_SaslCredentials'/3,
+'dec_BindResponse'/3,
+'dec_UnbindRequest'/3,
+'dec_SearchRequest'/3,
+'dec_Filter'/3,
+'dec_SubstringFilter'/3,
+'dec_MatchingRuleAssertion'/3,
+'dec_SearchResultEntry'/3,
+'dec_PartialAttributeList'/3,
+'dec_SearchResultReference'/3,
+'dec_SearchResultDone'/3,
+'dec_ModifyRequest'/3,
+'dec_AttributeTypeAndValues'/3,
+'dec_ModifyResponse'/3,
+'dec_AddRequest'/3,
+'dec_AttributeList'/3,
+'dec_AddResponse'/3,
+'dec_DelRequest'/3,
+'dec_DelResponse'/3,
+'dec_ModifyDNRequest'/3,
+'dec_ModifyDNResponse'/3,
+'dec_CompareRequest'/3,
+'dec_CompareResponse'/3,
+'dec_AbandonRequest'/3,
+'dec_ExtendedRequest'/3,
+'dec_ExtendedResponse'/3
+]).
+
+-export([
+'maxInt'/0
+]).
+
+-export([info/0]).
+
+
+-export([encode/2,decode/2,encode_disp/2,decode_disp/2]).
+
+encoding_rule() ->
+ ber.
+
+encode(Type,Data) ->
+case catch encode_disp(Type,Data) of
+ {'EXIT',{error,Reason}} ->
+ {error,Reason};
+ {'EXIT',Reason} ->
+ {error,{asn1,Reason}};
+ {Bytes,_Len} ->
+ {ok,wrap_encode(Bytes)};
+ Bytes ->
+ {ok,wrap_encode(Bytes)}
+end.
+
+decode(Type,Data) ->
+case catch decode_disp(Type,wrap_decode(Data)) of
+ {'EXIT',{error,Reason}} ->
+ {error,Reason};
+ {'EXIT',Reason} ->
+ {error,{asn1,Reason}};
+ {X,_Rest} ->
+ {ok,X};
+ {X,_Rest,_Len} ->
+ {ok,X}
+end.
+
+encode_disp('LDAPMessage',Data) -> 'enc_LDAPMessage'(Data,[]);
+encode_disp('MessageID',Data) -> 'enc_MessageID'(Data,[]);
+encode_disp('LDAPString',Data) -> 'enc_LDAPString'(Data,[]);
+encode_disp('LDAPOID',Data) -> 'enc_LDAPOID'(Data,[]);
+encode_disp('LDAPDN',Data) -> 'enc_LDAPDN'(Data,[]);
+encode_disp('RelativeLDAPDN',Data) -> 'enc_RelativeLDAPDN'(Data,[]);
+encode_disp('AttributeType',Data) -> 'enc_AttributeType'(Data,[]);
+encode_disp('AttributeDescription',Data) -> 'enc_AttributeDescription'(Data,[]);
+encode_disp('AttributeDescriptionList',Data) -> 'enc_AttributeDescriptionList'(Data,[]);
+encode_disp('AttributeValue',Data) -> 'enc_AttributeValue'(Data,[]);
+encode_disp('AttributeValueAssertion',Data) -> 'enc_AttributeValueAssertion'(Data,[]);
+encode_disp('AssertionValue',Data) -> 'enc_AssertionValue'(Data,[]);
+encode_disp('Attribute',Data) -> 'enc_Attribute'(Data,[]);
+encode_disp('MatchingRuleId',Data) -> 'enc_MatchingRuleId'(Data,[]);
+encode_disp('LDAPResult',Data) -> 'enc_LDAPResult'(Data,[]);
+encode_disp('Referral',Data) -> 'enc_Referral'(Data,[]);
+encode_disp('LDAPURL',Data) -> 'enc_LDAPURL'(Data,[]);
+encode_disp('Controls',Data) -> 'enc_Controls'(Data,[]);
+encode_disp('Control',Data) -> 'enc_Control'(Data,[]);
+encode_disp('BindRequest',Data) -> 'enc_BindRequest'(Data,[]);
+encode_disp('AuthenticationChoice',Data) -> 'enc_AuthenticationChoice'(Data,[]);
+encode_disp('SaslCredentials',Data) -> 'enc_SaslCredentials'(Data,[]);
+encode_disp('BindResponse',Data) -> 'enc_BindResponse'(Data,[]);
+encode_disp('UnbindRequest',Data) -> 'enc_UnbindRequest'(Data,[]);
+encode_disp('SearchRequest',Data) -> 'enc_SearchRequest'(Data,[]);
+encode_disp('Filter',Data) -> 'enc_Filter'(Data,[]);
+encode_disp('SubstringFilter',Data) -> 'enc_SubstringFilter'(Data,[]);
+encode_disp('MatchingRuleAssertion',Data) -> 'enc_MatchingRuleAssertion'(Data,[]);
+encode_disp('SearchResultEntry',Data) -> 'enc_SearchResultEntry'(Data,[]);
+encode_disp('PartialAttributeList',Data) -> 'enc_PartialAttributeList'(Data,[]);
+encode_disp('SearchResultReference',Data) -> 'enc_SearchResultReference'(Data,[]);
+encode_disp('SearchResultDone',Data) -> 'enc_SearchResultDone'(Data,[]);
+encode_disp('ModifyRequest',Data) -> 'enc_ModifyRequest'(Data,[]);
+encode_disp('AttributeTypeAndValues',Data) -> 'enc_AttributeTypeAndValues'(Data,[]);
+encode_disp('ModifyResponse',Data) -> 'enc_ModifyResponse'(Data,[]);
+encode_disp('AddRequest',Data) -> 'enc_AddRequest'(Data,[]);
+encode_disp('AttributeList',Data) -> 'enc_AttributeList'(Data,[]);
+encode_disp('AddResponse',Data) -> 'enc_AddResponse'(Data,[]);
+encode_disp('DelRequest',Data) -> 'enc_DelRequest'(Data,[]);
+encode_disp('DelResponse',Data) -> 'enc_DelResponse'(Data,[]);
+encode_disp('ModifyDNRequest',Data) -> 'enc_ModifyDNRequest'(Data,[]);
+encode_disp('ModifyDNResponse',Data) -> 'enc_ModifyDNResponse'(Data,[]);
+encode_disp('CompareRequest',Data) -> 'enc_CompareRequest'(Data,[]);
+encode_disp('CompareResponse',Data) -> 'enc_CompareResponse'(Data,[]);
+encode_disp('AbandonRequest',Data) -> 'enc_AbandonRequest'(Data,[]);
+encode_disp('ExtendedRequest',Data) -> 'enc_ExtendedRequest'(Data,[]);
+encode_disp('ExtendedResponse',Data) -> 'enc_ExtendedResponse'(Data,[]);
+encode_disp(Type,_Data) -> exit({error,{asn1,{undefined_type,Type}}}).
+
+
+decode_disp('LDAPMessage',Data) -> 'dec_LDAPMessage'(Data,mandatory);
+decode_disp('MessageID',Data) -> 'dec_MessageID'(Data,mandatory);
+decode_disp('LDAPString',Data) -> 'dec_LDAPString'(Data,mandatory);
+decode_disp('LDAPOID',Data) -> 'dec_LDAPOID'(Data,mandatory);
+decode_disp('LDAPDN',Data) -> 'dec_LDAPDN'(Data,mandatory);
+decode_disp('RelativeLDAPDN',Data) -> 'dec_RelativeLDAPDN'(Data,mandatory);
+decode_disp('AttributeType',Data) -> 'dec_AttributeType'(Data,mandatory);
+decode_disp('AttributeDescription',Data) -> 'dec_AttributeDescription'(Data,mandatory);
+decode_disp('AttributeDescriptionList',Data) -> 'dec_AttributeDescriptionList'(Data,mandatory);
+decode_disp('AttributeValue',Data) -> 'dec_AttributeValue'(Data,mandatory);
+decode_disp('AttributeValueAssertion',Data) -> 'dec_AttributeValueAssertion'(Data,mandatory);
+decode_disp('AssertionValue',Data) -> 'dec_AssertionValue'(Data,mandatory);
+decode_disp('Attribute',Data) -> 'dec_Attribute'(Data,mandatory);
+decode_disp('MatchingRuleId',Data) -> 'dec_MatchingRuleId'(Data,mandatory);
+decode_disp('LDAPResult',Data) -> 'dec_LDAPResult'(Data,mandatory);
+decode_disp('Referral',Data) -> 'dec_Referral'(Data,mandatory);
+decode_disp('LDAPURL',Data) -> 'dec_LDAPURL'(Data,mandatory);
+decode_disp('Controls',Data) -> 'dec_Controls'(Data,mandatory);
+decode_disp('Control',Data) -> 'dec_Control'(Data,mandatory);
+decode_disp('BindRequest',Data) -> 'dec_BindRequest'(Data,mandatory);
+decode_disp('AuthenticationChoice',Data) -> 'dec_AuthenticationChoice'(Data,mandatory);
+decode_disp('SaslCredentials',Data) -> 'dec_SaslCredentials'(Data,mandatory);
+decode_disp('BindResponse',Data) -> 'dec_BindResponse'(Data,mandatory);
+decode_disp('UnbindRequest',Data) -> 'dec_UnbindRequest'(Data,mandatory);
+decode_disp('SearchRequest',Data) -> 'dec_SearchRequest'(Data,mandatory);
+decode_disp('Filter',Data) -> 'dec_Filter'(Data,mandatory);
+decode_disp('SubstringFilter',Data) -> 'dec_SubstringFilter'(Data,mandatory);
+decode_disp('MatchingRuleAssertion',Data) -> 'dec_MatchingRuleAssertion'(Data,mandatory);
+decode_disp('SearchResultEntry',Data) -> 'dec_SearchResultEntry'(Data,mandatory);
+decode_disp('PartialAttributeList',Data) -> 'dec_PartialAttributeList'(Data,mandatory);
+decode_disp('SearchResultReference',Data) -> 'dec_SearchResultReference'(Data,mandatory);
+decode_disp('SearchResultDone',Data) -> 'dec_SearchResultDone'(Data,mandatory);
+decode_disp('ModifyRequest',Data) -> 'dec_ModifyRequest'(Data,mandatory);
+decode_disp('AttributeTypeAndValues',Data) -> 'dec_AttributeTypeAndValues'(Data,mandatory);
+decode_disp('ModifyResponse',Data) -> 'dec_ModifyResponse'(Data,mandatory);
+decode_disp('AddRequest',Data) -> 'dec_AddRequest'(Data,mandatory);
+decode_disp('AttributeList',Data) -> 'dec_AttributeList'(Data,mandatory);
+decode_disp('AddResponse',Data) -> 'dec_AddResponse'(Data,mandatory);
+decode_disp('DelRequest',Data) -> 'dec_DelRequest'(Data,mandatory);
+decode_disp('DelResponse',Data) -> 'dec_DelResponse'(Data,mandatory);
+decode_disp('ModifyDNRequest',Data) -> 'dec_ModifyDNRequest'(Data,mandatory);
+decode_disp('ModifyDNResponse',Data) -> 'dec_ModifyDNResponse'(Data,mandatory);
+decode_disp('CompareRequest',Data) -> 'dec_CompareRequest'(Data,mandatory);
+decode_disp('CompareResponse',Data) -> 'dec_CompareResponse'(Data,mandatory);
+decode_disp('AbandonRequest',Data) -> 'dec_AbandonRequest'(Data,mandatory);
+decode_disp('ExtendedRequest',Data) -> 'dec_ExtendedRequest'(Data,mandatory);
+decode_disp('ExtendedResponse',Data) -> 'dec_ExtendedResponse'(Data,mandatory);
+decode_disp(Type,_Data) -> exit({error,{asn1,{undefined_type,Type}}}).
+
+
+
+wrap_encode(Bytes) when is_list(Bytes) ->
+ binary_to_list(list_to_binary(Bytes));
+wrap_encode(Bytes) when is_binary(Bytes) ->
+ binary_to_list(Bytes);
+wrap_encode(Bytes) -> Bytes.
+
+wrap_decode(Bytes) when is_list(Bytes) ->
+ list_to_binary(Bytes);
+wrap_decode(Bytes) -> Bytes.
+
+
+info() ->
+ case ?MODULE:module_info() of
+ MI when is_list(MI) ->
+ case lists:keysearch(attributes,1,MI) of
+ {value,{_,Attributes}} when is_list(Attributes) ->
+ case lists:keysearch(asn1_info,1,Attributes) of
+ {value,{_,Info}} when is_list(Info) ->
+ Info;
+ _ ->
+ []
+ end;
+ _ ->
+ []
+ end
+ end.
+
+
+%%================================
+%% LDAPMessage
+%%================================
+'enc_LDAPMessage'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type INTEGER
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_integer([], ?RT_BER:cindex(2,Val,messageID), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type CHOICE
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_LDAPMessage_protocolOp'(?RT_BER:cindex(3,Val,protocolOp), []),
+
+%%-------------------------------------------------
+%% attribute number 3 External ELDAPv3:Controls OPTIONAL
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = case ?RT_BER:cindex(4,Val,controls) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ 'enc_Controls'(?RT_BER:cindex(4,Val,controls), [{tag,128,0,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% LDAPMessage_protocolOp
+%%================================
+
+'enc_LDAPMessage_protocolOp'({'LDAPMessage_protocolOp',Val}, TagIn) ->
+ 'enc_LDAPMessage_protocolOp'(Val, TagIn);
+
+'enc_LDAPMessage_protocolOp'(Val, TagIn) ->
+ {EncBytes,EncLen} = case element(1,Val) of
+ bindRequest ->
+ 'enc_BindRequest'(element(2,Val), []);
+ bindResponse ->
+ 'enc_BindResponse'(element(2,Val), []);
+ unbindRequest ->
+ ?RT_BER:encode_null(element(2,Val), [{tag,64,2,'IMPLICIT',32}]);
+ searchRequest ->
+ 'enc_SearchRequest'(element(2,Val), []);
+ searchResEntry ->
+ 'enc_SearchResultEntry'(element(2,Val), []);
+ searchResDone ->
+ 'enc_SearchResultDone'(element(2,Val), []);
+ searchResRef ->
+ 'enc_SearchResultReference'(element(2,Val), []);
+ modifyRequest ->
+ 'enc_ModifyRequest'(element(2,Val), []);
+ modifyResponse ->
+ 'enc_ModifyResponse'(element(2,Val), []);
+ addRequest ->
+ 'enc_AddRequest'(element(2,Val), []);
+ addResponse ->
+ 'enc_AddResponse'(element(2,Val), []);
+ delRequest ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,64,10,'IMPLICIT',32}]);
+ delResponse ->
+ 'enc_DelResponse'(element(2,Val), []);
+ modDNRequest ->
+ 'enc_ModifyDNRequest'(element(2,Val), []);
+ modDNResponse ->
+ 'enc_ModifyDNResponse'(element(2,Val), []);
+ compareRequest ->
+ 'enc_CompareRequest'(element(2,Val), []);
+ compareResponse ->
+ 'enc_CompareResponse'(element(2,Val), []);
+ abandonRequest ->
+ ?RT_BER:encode_integer([], element(2,Val), [{tag,64,16,'IMPLICIT',32}]);
+ extendedReq ->
+ 'enc_ExtendedRequest'(element(2,Val), []);
+ extendedResp ->
+ 'enc_ExtendedResponse'(element(2,Val), []);
+ Else ->
+ exit({error,{asn1,{invalid_choice_type,Else}}})
+ end,
+
+?RT_BER:encode_tags(TagIn ++[], EncBytes, EncLen).
+
+
+'dec_LDAPMessage_protocolOp'(Bytes, OptOrMand, TagIn) ->
+ {{_,Len},Bytes1, RbExp} = ?RT_BER:check_tags(TagIn++[], Bytes, OptOrMand),
+ IndefEndBytes = fun(indefinite,<<0,0,R/binary>>)-> R; (_,B)-> B end,
+ IndefEndRb = fun(indefinite,<<0,0,_R/binary>>)-> 2; (_,_)-> 0 end,
+ case Bytes1 of
+
+%% 'bindRequest'
+ <<1:2,_:1,0:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_BindRequest'(Bytes1, mandatory, []),
+ {{bindRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'bindResponse'
+ <<1:2,_:1,1:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_BindResponse'(Bytes1, mandatory, []),
+ {{bindResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'unbindRequest'
+ <<1:2,_:1,2:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_null(Bytes1,[{tag,64,2,'IMPLICIT',32}], mandatory),
+ {{unbindRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'searchRequest'
+ <<1:2,_:1,3:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SearchRequest'(Bytes1, mandatory, []),
+ {{searchRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'searchResEntry'
+ <<1:2,_:1,4:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SearchResultEntry'(Bytes1, mandatory, []),
+ {{searchResEntry, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'searchResDone'
+ <<1:2,_:1,5:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SearchResultDone'(Bytes1, mandatory, []),
+ {{searchResDone, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'searchResRef'
+ <<1:2,_:1,19:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SearchResultReference'(Bytes1, mandatory, []),
+ {{searchResRef, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'modifyRequest'
+ <<1:2,_:1,6:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ModifyRequest'(Bytes1, mandatory, []),
+ {{modifyRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'modifyResponse'
+ <<1:2,_:1,7:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ModifyResponse'(Bytes1, mandatory, []),
+ {{modifyResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'addRequest'
+ <<1:2,_:1,8:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AddRequest'(Bytes1, mandatory, []),
+ {{addRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'addResponse'
+ <<1:2,_:1,9:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AddResponse'(Bytes1, mandatory, []),
+ {{addResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'delRequest'
+ <<1:2,_:1,10:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,64,10,'IMPLICIT',32}], no_length, mandatory),
+ {{delRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'delResponse'
+ <<1:2,_:1,11:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_DelResponse'(Bytes1, mandatory, []),
+ {{delResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'modDNRequest'
+ <<1:2,_:1,12:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ModifyDNRequest'(Bytes1, mandatory, []),
+ {{modDNRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'modDNResponse'
+ <<1:2,_:1,13:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ModifyDNResponse'(Bytes1, mandatory, []),
+ {{modDNResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'compareRequest'
+ <<1:2,_:1,14:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_CompareRequest'(Bytes1, mandatory, []),
+ {{compareRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'compareResponse'
+ <<1:2,_:1,15:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_CompareResponse'(Bytes1, mandatory, []),
+ {{compareResponse, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'abandonRequest'
+ <<1:2,_:1,16:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_integer(Bytes1,{0,2147483647},[{tag,64,16,'IMPLICIT',32}], mandatory),
+ {{abandonRequest, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'extendedReq'
+ <<1:2,_:1,23:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ExtendedRequest'(Bytes1, mandatory, []),
+ {{extendedReq, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'extendedResp'
+ <<1:2,_:1,24:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_ExtendedResponse'(Bytes1, mandatory, []),
+ {{extendedResp, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+ Else ->
+ case OptOrMand of
+ mandatory ->exit({error,{asn1,{invalid_choice_tag,Else}}});
+ _ ->exit({error,{asn1,{no_optional_tag,Else}}})
+ end
+ end.
+
+
+'dec_LDAPMessage'(Bytes, OptOrMand) ->
+ 'dec_LDAPMessage'(Bytes, OptOrMand, []).
+
+'dec_LDAPMessage'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type INTEGER
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_integer(Bytes2,{0,2147483647},[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type CHOICE
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_LDAPMessage_protocolOp'(Bytes3, mandatory, []),
+
+%%-------------------------------------------------
+%% attribute number 3 External ELDAPv3:Controls OPTIONAL
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = case Bytes4 of
+<<2:2,_:1,0:5,_/binary>> ->
+'dec_Controls'(Bytes4, opt_or_default, [{tag,128,0,'IMPLICIT',32}]);
+_ ->
+{ asn1_NOVALUE, Bytes4, 0 }
+end,
+
+ {Bytes6,Rb5} = ?RT_BER:restbytes2(RemBytes, Bytes5,noext),
+ {{'LDAPMessage', Term1, Term2, Term3}, Bytes6, Rb1+Rb2+Rb3+Rb4+Rb5}.
+
+
+%%================================
+%% MessageID
+%%================================
+
+'enc_MessageID'({'MessageID',Val}, TagIn) ->
+ 'enc_MessageID'(Val, TagIn);
+
+'enc_MessageID'(Val, TagIn) ->
+?RT_BER:encode_integer([], Val, TagIn ++ []).
+
+
+'dec_MessageID'(Bytes, OptOrMand) ->
+ 'dec_MessageID'(Bytes, OptOrMand, []).
+
+'dec_MessageID'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_integer(Bytes,{0,2147483647},TagIn++[], OptOrMand).
+
+
+
+%%================================
+%% LDAPString
+%%================================
+
+'enc_LDAPString'({'LDAPString',Val}, TagIn) ->
+ 'enc_LDAPString'(Val, TagIn);
+
+'enc_LDAPString'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_LDAPString'(Bytes, OptOrMand) ->
+ 'dec_LDAPString'(Bytes, OptOrMand, []).
+
+'dec_LDAPString'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% LDAPOID
+%%================================
+
+'enc_LDAPOID'({'LDAPOID',Val}, TagIn) ->
+ 'enc_LDAPOID'(Val, TagIn);
+
+'enc_LDAPOID'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_LDAPOID'(Bytes, OptOrMand) ->
+ 'dec_LDAPOID'(Bytes, OptOrMand, []).
+
+'dec_LDAPOID'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% LDAPDN
+%%================================
+
+'enc_LDAPDN'({'LDAPDN',Val}, TagIn) ->
+ 'enc_LDAPDN'(Val, TagIn);
+
+'enc_LDAPDN'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_LDAPDN'(Bytes, OptOrMand) ->
+ 'dec_LDAPDN'(Bytes, OptOrMand, []).
+
+'dec_LDAPDN'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% RelativeLDAPDN
+%%================================
+
+'enc_RelativeLDAPDN'({'RelativeLDAPDN',Val}, TagIn) ->
+ 'enc_RelativeLDAPDN'(Val, TagIn);
+
+'enc_RelativeLDAPDN'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_RelativeLDAPDN'(Bytes, OptOrMand) ->
+ 'dec_RelativeLDAPDN'(Bytes, OptOrMand, []).
+
+'dec_RelativeLDAPDN'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% AttributeType
+%%================================
+
+'enc_AttributeType'({'AttributeType',Val}, TagIn) ->
+ 'enc_AttributeType'(Val, TagIn);
+
+'enc_AttributeType'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_AttributeType'(Bytes, OptOrMand) ->
+ 'dec_AttributeType'(Bytes, OptOrMand, []).
+
+'dec_AttributeType'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% AttributeDescription
+%%================================
+
+'enc_AttributeDescription'({'AttributeDescription',Val}, TagIn) ->
+ 'enc_AttributeDescription'(Val, TagIn);
+
+'enc_AttributeDescription'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_AttributeDescription'(Bytes, OptOrMand) ->
+ 'dec_AttributeDescription'(Bytes, OptOrMand, []).
+
+'dec_AttributeDescription'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% AttributeDescriptionList
+%%================================
+
+'enc_AttributeDescriptionList'({'AttributeDescriptionList',Val}, TagIn) ->
+ 'enc_AttributeDescriptionList'(Val, TagIn);
+
+'enc_AttributeDescriptionList'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_AttributeDescriptionList_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_AttributeDescriptionList_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_AttributeDescriptionList_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_AttributeDescriptionList_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+'dec_AttributeDescriptionList'(Bytes, OptOrMand) ->
+ 'dec_AttributeDescriptionList'(Bytes, OptOrMand, []).
+
+'dec_AttributeDescriptionList'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+
+
+%%================================
+%% AttributeValue
+%%================================
+
+'enc_AttributeValue'({'AttributeValue',Val}, TagIn) ->
+ 'enc_AttributeValue'(Val, TagIn);
+
+'enc_AttributeValue'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_AttributeValue'(Bytes, OptOrMand) ->
+ 'dec_AttributeValue'(Bytes, OptOrMand, []).
+
+'dec_AttributeValue'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% AttributeValueAssertion
+%%================================
+'enc_AttributeValueAssertion'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,attributeDesc), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,assertionValue), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_AttributeValueAssertion'(Bytes, OptOrMand) ->
+ 'dec_AttributeValueAssertion'(Bytes, OptOrMand, []).
+
+'dec_AttributeValueAssertion'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'AttributeValueAssertion', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% AssertionValue
+%%================================
+
+'enc_AssertionValue'({'AssertionValue',Val}, TagIn) ->
+ 'enc_AssertionValue'(Val, TagIn);
+
+'enc_AssertionValue'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_AssertionValue'(Bytes, OptOrMand) ->
+ 'dec_AssertionValue'(Bytes, OptOrMand, []).
+
+'dec_AssertionValue'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% Attribute
+%%================================
+'enc_Attribute'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,type), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_Attribute_vals'(?RT_BER:cindex(3,Val,vals), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% Attribute_vals
+%%================================
+
+'enc_Attribute_vals'({'Attribute_vals',Val}, TagIn) ->
+ 'enc_Attribute_vals'(Val, TagIn);
+
+'enc_Attribute_vals'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_Attribute_vals_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_Attribute_vals_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_Attribute_vals_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_Attribute_vals_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_Attribute_vals'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+
+
+'dec_Attribute'(Bytes, OptOrMand) ->
+ 'dec_Attribute'(Bytes, OptOrMand, []).
+
+'dec_Attribute'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_Attribute_vals'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'Attribute', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% MatchingRuleId
+%%================================
+
+'enc_MatchingRuleId'({'MatchingRuleId',Val}, TagIn) ->
+ 'enc_MatchingRuleId'(Val, TagIn);
+
+'enc_MatchingRuleId'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_MatchingRuleId'(Bytes, OptOrMand) ->
+ 'dec_MatchingRuleId'(Bytes, OptOrMand, []).
+
+'dec_MatchingRuleId'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% LDAPResult
+%%================================
+'enc_LDAPResult'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = case (case ?RT_BER:cindex(2,Val,resultCode) of {_,Enumval1}->Enumval1;_->?RT_BER:cindex(2,Val,resultCode) end) of
+success -> ?RT_BER:encode_enumerated(0,[]);
+operationsError -> ?RT_BER:encode_enumerated(1,[]);
+protocolError -> ?RT_BER:encode_enumerated(2,[]);
+timeLimitExceeded -> ?RT_BER:encode_enumerated(3,[]);
+sizeLimitExceeded -> ?RT_BER:encode_enumerated(4,[]);
+compareFalse -> ?RT_BER:encode_enumerated(5,[]);
+compareTrue -> ?RT_BER:encode_enumerated(6,[]);
+authMethodNotSupported -> ?RT_BER:encode_enumerated(7,[]);
+strongAuthRequired -> ?RT_BER:encode_enumerated(8,[]);
+referral -> ?RT_BER:encode_enumerated(10,[]);
+adminLimitExceeded -> ?RT_BER:encode_enumerated(11,[]);
+unavailableCriticalExtension -> ?RT_BER:encode_enumerated(12,[]);
+confidentialityRequired -> ?RT_BER:encode_enumerated(13,[]);
+saslBindInProgress -> ?RT_BER:encode_enumerated(14,[]);
+noSuchAttribute -> ?RT_BER:encode_enumerated(16,[]);
+undefinedAttributeType -> ?RT_BER:encode_enumerated(17,[]);
+inappropriateMatching -> ?RT_BER:encode_enumerated(18,[]);
+constraintViolation -> ?RT_BER:encode_enumerated(19,[]);
+attributeOrValueExists -> ?RT_BER:encode_enumerated(20,[]);
+invalidAttributeSyntax -> ?RT_BER:encode_enumerated(21,[]);
+noSuchObject -> ?RT_BER:encode_enumerated(32,[]);
+aliasProblem -> ?RT_BER:encode_enumerated(33,[]);
+invalidDNSyntax -> ?RT_BER:encode_enumerated(34,[]);
+aliasDereferencingProblem -> ?RT_BER:encode_enumerated(36,[]);
+inappropriateAuthentication -> ?RT_BER:encode_enumerated(48,[]);
+invalidCredentials -> ?RT_BER:encode_enumerated(49,[]);
+insufficientAccessRights -> ?RT_BER:encode_enumerated(50,[]);
+busy -> ?RT_BER:encode_enumerated(51,[]);
+unavailable -> ?RT_BER:encode_enumerated(52,[]);
+unwillingToPerform -> ?RT_BER:encode_enumerated(53,[]);
+loopDetect -> ?RT_BER:encode_enumerated(54,[]);
+namingViolation -> ?RT_BER:encode_enumerated(64,[]);
+objectClassViolation -> ?RT_BER:encode_enumerated(65,[]);
+notAllowedOnNonLeaf -> ?RT_BER:encode_enumerated(66,[]);
+notAllowedOnRDN -> ?RT_BER:encode_enumerated(67,[]);
+entryAlreadyExists -> ?RT_BER:encode_enumerated(68,[]);
+objectClassModsProhibited -> ?RT_BER:encode_enumerated(69,[]);
+affectsMultipleDSAs -> ?RT_BER:encode_enumerated(71,[]);
+other -> ?RT_BER:encode_enumerated(80,[]);
+Enumval2 -> exit({error,{asn1, {enumerated_not_in_range,Enumval2}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,matchedDN), []),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(4,Val,errorMessage), []),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = case ?RT_BER:cindex(5,Val,referral) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ 'enc_Referral'(?RT_BER:cindex(5,Val,referral), [{tag,128,3,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_LDAPResult'(Bytes, OptOrMand) ->
+ 'dec_LDAPResult'(Bytes, OptOrMand, []).
+
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_enumerated(Bytes2,[],[{success,0},{operationsError,1},{protocolError,2},{timeLimitExceeded,3},{sizeLimitExceeded,4},{compareFalse,5},{compareTrue,6},{authMethodNotSupported,7},{strongAuthRequired,8},{referral,10},{adminLimitExceeded,11},{unavailableCriticalExtension,12},{confidentialityRequired,13},{saslBindInProgress,14},{noSuchAttribute,16},{undefinedAttributeType,17},{inappropriateMatching,18},{constraintViolation,19},{attributeOrValueExists,20},{invalidAttributeSyntax,21},{noSuchObject,32},{aliasProblem,33},{invalidDNSyntax,34},{aliasDereferencingProblem,36},{inappropriateAuthentication,48},{invalidCredentials,49},{insufficientAccessRights,50},{busy,51},{unavailable,52},{unwillingToPerform,53},{loopDetect,54},{namingViolation,64},{objectClassViolation,65},{notAllowedOnNonLeaf,66},{notAllowedOnRDN,67},{entryAlreadyExists,68},{objectClassModsProhibited,69},{affectsMultipleDSAs,71},{other,80}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_octet_string(Bytes4,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = case Bytes5 of
+<<2:2,_:1,3:5,_/binary>> ->
+'dec_Referral'(Bytes5, opt_or_default, [{tag,128,3,'IMPLICIT',32}]);
+_ ->
+{ asn1_NOVALUE, Bytes5, 0 }
+end,
+
+ {Bytes7,Rb6} = ?RT_BER:restbytes2(RemBytes, Bytes6,noext),
+ {{'LDAPResult', Term1, Term2, Term3, Term4}, Bytes7, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6}.
+
+
+%%================================
+%% Referral
+%%================================
+
+'enc_Referral'({'Referral',Val}, TagIn) ->
+ 'enc_Referral'(Val, TagIn);
+
+'enc_Referral'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_Referral_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_Referral_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_Referral_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_Referral_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+'dec_Referral'(Bytes, OptOrMand) ->
+ 'dec_Referral'(Bytes, OptOrMand, []).
+
+'dec_Referral'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+
+
+%%================================
+%% LDAPURL
+%%================================
+
+'enc_LDAPURL'({'LDAPURL',Val}, TagIn) ->
+ 'enc_LDAPURL'(Val, TagIn);
+
+'enc_LDAPURL'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ []).
+
+
+'dec_LDAPURL'(Bytes, OptOrMand) ->
+ 'dec_LDAPURL'(Bytes, OptOrMand, []).
+
+'dec_LDAPURL'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[], no_length, OptOrMand).
+
+
+
+%%================================
+%% Controls
+%%================================
+
+'enc_Controls'({'Controls',Val}, TagIn) ->
+ 'enc_Controls'(Val, TagIn);
+
+'enc_Controls'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_Controls_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_Controls_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_Controls_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_Control'(H, []),
+ 'enc_Controls_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+'dec_Controls'(Bytes, OptOrMand) ->
+ 'dec_Controls'(Bytes, OptOrMand, []).
+
+'dec_Controls'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_Control'/3, [], []).
+
+
+
+
+%%================================
+%% Control
+%%================================
+'enc_Control'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,controlType), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type BOOLEAN DEFAULT = false
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = case ?RT_BER:cindex(3,Val,criticality) of
+ asn1_DEFAULT -> {<<>>,0};
+ false -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_boolean(?RT_BER:cindex(3,Val,criticality), [])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = case ?RT_BER:cindex(4,Val,controlValue) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(4,Val,controlValue), [])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_Control'(Bytes, OptOrMand) ->
+ 'dec_Control'(Bytes, OptOrMand, []).
+
+'dec_Control'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type BOOLEAN DEFAULT = false
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = case Bytes3 of
+<<0:2,_:1,1:5,_/binary>> ->
+?RT_BER:decode_boolean(Bytes3,[], mandatory);
+_ ->
+{false,Bytes3, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = case Bytes4 of
+<<0:2,_:1,4:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes4,[],[], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes4, 0 }
+end,
+
+ {Bytes6,Rb5} = ?RT_BER:restbytes2(RemBytes, Bytes5,noext),
+ {{'Control', Term1, Term2, Term3}, Bytes6, Rb1+Rb2+Rb3+Rb4+Rb5}.
+
+
+%%================================
+%% BindRequest
+%%================================
+'enc_BindRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type INTEGER
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_integer([], ?RT_BER:cindex(2,Val,version), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,name), []),
+
+%%-------------------------------------------------
+%% attribute number 3 External ELDAPv3:AuthenticationChoice
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = 'enc_AuthenticationChoice'(?RT_BER:cindex(4,Val,authentication), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,0,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_BindRequest'(Bytes, OptOrMand) ->
+ 'dec_BindRequest'(Bytes, OptOrMand, []).
+
+'dec_BindRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,0,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type INTEGER
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_integer(Bytes2,{1,127},[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 External ELDAPv3:AuthenticationChoice
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = 'dec_AuthenticationChoice'(Bytes4, mandatory, []),
+
+ {Bytes6,Rb5} = ?RT_BER:restbytes2(RemBytes, Bytes5,noext),
+ {{'BindRequest', Term1, Term2, Term3}, Bytes6, Rb1+Rb2+Rb3+Rb4+Rb5}.
+
+
+%%================================
+%% AuthenticationChoice
+%%================================
+
+'enc_AuthenticationChoice'({'AuthenticationChoice',Val}, TagIn) ->
+ 'enc_AuthenticationChoice'(Val, TagIn);
+
+'enc_AuthenticationChoice'(Val, TagIn) ->
+ {EncBytes,EncLen} = case element(1,Val) of
+ simple ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,128,0,'IMPLICIT',32}]);
+ sasl ->
+ 'enc_SaslCredentials'(element(2,Val), [{tag,128,3,'IMPLICIT',32}]);
+ Else ->
+ exit({error,{asn1,{invalid_choice_type,Else}}})
+ end,
+
+?RT_BER:encode_tags(TagIn ++[], EncBytes, EncLen).
+
+
+
+
+'dec_AuthenticationChoice'(Bytes, OptOrMand) ->
+ 'dec_AuthenticationChoice'(Bytes, OptOrMand, []).
+
+'dec_AuthenticationChoice'(Bytes, OptOrMand, TagIn) ->
+ {{_,Len},Bytes1, RbExp} = ?RT_BER:check_tags(TagIn++[], Bytes, OptOrMand),
+ IndefEndBytes = fun(indefinite,<<0,0,R/binary>>)-> R; (_,B)-> B end,
+ IndefEndRb = fun(indefinite,<<0,0,_R/binary>>)-> 2; (_,_)-> 0 end,
+ case Bytes1 of
+
+%% 'simple'
+ <<2:2,_:1,0:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,128,0,'IMPLICIT',32}], no_length, mandatory),
+ {{simple, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'sasl'
+ <<2:2,_:1,3:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SaslCredentials'(Bytes1, mandatory, [{tag,128,3,'IMPLICIT',32}]),
+ {{sasl, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+ Else ->
+ case OptOrMand of
+ mandatory ->exit({error,{asn1,{invalid_choice_tag,Else}}});
+ _ ->exit({error,{asn1,{no_optional_tag,Else}}})
+ end
+ end.
+
+
+%%================================
+%% SaslCredentials
+%%================================
+'enc_SaslCredentials'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,mechanism), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = case ?RT_BER:cindex(3,Val,credentials) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,credentials), [])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_SaslCredentials'(Bytes, OptOrMand) ->
+ 'dec_SaslCredentials'(Bytes, OptOrMand, []).
+
+'dec_SaslCredentials'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = case Bytes3 of
+<<0:2,_:1,4:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes3, 0 }
+end,
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'SaslCredentials', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% BindResponse
+%%================================
+'enc_BindResponse'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = case (case ?RT_BER:cindex(2,Val,resultCode) of {_,Enumval1}->Enumval1;_->?RT_BER:cindex(2,Val,resultCode) end) of
+success -> ?RT_BER:encode_enumerated(0,[]);
+operationsError -> ?RT_BER:encode_enumerated(1,[]);
+protocolError -> ?RT_BER:encode_enumerated(2,[]);
+timeLimitExceeded -> ?RT_BER:encode_enumerated(3,[]);
+sizeLimitExceeded -> ?RT_BER:encode_enumerated(4,[]);
+compareFalse -> ?RT_BER:encode_enumerated(5,[]);
+compareTrue -> ?RT_BER:encode_enumerated(6,[]);
+authMethodNotSupported -> ?RT_BER:encode_enumerated(7,[]);
+strongAuthRequired -> ?RT_BER:encode_enumerated(8,[]);
+referral -> ?RT_BER:encode_enumerated(10,[]);
+adminLimitExceeded -> ?RT_BER:encode_enumerated(11,[]);
+unavailableCriticalExtension -> ?RT_BER:encode_enumerated(12,[]);
+confidentialityRequired -> ?RT_BER:encode_enumerated(13,[]);
+saslBindInProgress -> ?RT_BER:encode_enumerated(14,[]);
+noSuchAttribute -> ?RT_BER:encode_enumerated(16,[]);
+undefinedAttributeType -> ?RT_BER:encode_enumerated(17,[]);
+inappropriateMatching -> ?RT_BER:encode_enumerated(18,[]);
+constraintViolation -> ?RT_BER:encode_enumerated(19,[]);
+attributeOrValueExists -> ?RT_BER:encode_enumerated(20,[]);
+invalidAttributeSyntax -> ?RT_BER:encode_enumerated(21,[]);
+noSuchObject -> ?RT_BER:encode_enumerated(32,[]);
+aliasProblem -> ?RT_BER:encode_enumerated(33,[]);
+invalidDNSyntax -> ?RT_BER:encode_enumerated(34,[]);
+aliasDereferencingProblem -> ?RT_BER:encode_enumerated(36,[]);
+inappropriateAuthentication -> ?RT_BER:encode_enumerated(48,[]);
+invalidCredentials -> ?RT_BER:encode_enumerated(49,[]);
+insufficientAccessRights -> ?RT_BER:encode_enumerated(50,[]);
+busy -> ?RT_BER:encode_enumerated(51,[]);
+unavailable -> ?RT_BER:encode_enumerated(52,[]);
+unwillingToPerform -> ?RT_BER:encode_enumerated(53,[]);
+loopDetect -> ?RT_BER:encode_enumerated(54,[]);
+namingViolation -> ?RT_BER:encode_enumerated(64,[]);
+objectClassViolation -> ?RT_BER:encode_enumerated(65,[]);
+notAllowedOnNonLeaf -> ?RT_BER:encode_enumerated(66,[]);
+notAllowedOnRDN -> ?RT_BER:encode_enumerated(67,[]);
+entryAlreadyExists -> ?RT_BER:encode_enumerated(68,[]);
+objectClassModsProhibited -> ?RT_BER:encode_enumerated(69,[]);
+affectsMultipleDSAs -> ?RT_BER:encode_enumerated(71,[]);
+other -> ?RT_BER:encode_enumerated(80,[]);
+Enumval2 -> exit({error,{asn1, {enumerated_not_in_range,Enumval2}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,matchedDN), []),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(4,Val,errorMessage), []),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = case ?RT_BER:cindex(5,Val,referral) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ 'enc_Referral'(?RT_BER:cindex(5,Val,referral), [{tag,128,3,'IMPLICIT',32}])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 5 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes5,EncLen5} = case ?RT_BER:cindex(6,Val,serverSaslCreds) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(6,Val,serverSaslCreds), [{tag,128,7,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4, EncBytes5],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4 + EncLen5,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,1,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_BindResponse'(Bytes, OptOrMand) ->
+ 'dec_BindResponse'(Bytes, OptOrMand, []).
+
+'dec_BindResponse'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,1,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_enumerated(Bytes2,[],[{success,0},{operationsError,1},{protocolError,2},{timeLimitExceeded,3},{sizeLimitExceeded,4},{compareFalse,5},{compareTrue,6},{authMethodNotSupported,7},{strongAuthRequired,8},{referral,10},{adminLimitExceeded,11},{unavailableCriticalExtension,12},{confidentialityRequired,13},{saslBindInProgress,14},{noSuchAttribute,16},{undefinedAttributeType,17},{inappropriateMatching,18},{constraintViolation,19},{attributeOrValueExists,20},{invalidAttributeSyntax,21},{noSuchObject,32},{aliasProblem,33},{invalidDNSyntax,34},{aliasDereferencingProblem,36},{inappropriateAuthentication,48},{invalidCredentials,49},{insufficientAccessRights,50},{busy,51},{unavailable,52},{unwillingToPerform,53},{loopDetect,54},{namingViolation,64},{objectClassViolation,65},{notAllowedOnNonLeaf,66},{notAllowedOnRDN,67},{entryAlreadyExists,68},{objectClassModsProhibited,69},{affectsMultipleDSAs,71},{other,80}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_octet_string(Bytes4,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = case Bytes5 of
+<<2:2,_:1,3:5,_/binary>> ->
+'dec_Referral'(Bytes5, opt_or_default, [{tag,128,3,'IMPLICIT',32}]);
+_ ->
+{ asn1_NOVALUE, Bytes5, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 5 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term5,Bytes7,Rb6} = case Bytes6 of
+<<2:2,_:1,7:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes6,[],[{tag,128,7,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes6, 0 }
+end,
+
+ {Bytes8,Rb7} = ?RT_BER:restbytes2(RemBytes, Bytes7,noext),
+ {{'BindResponse', Term1, Term2, Term3, Term4, Term5}, Bytes8, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6+Rb7}.
+
+
+%%================================
+%% UnbindRequest
+%%================================
+
+'enc_UnbindRequest'({'UnbindRequest',Val}, TagIn) ->
+ 'enc_UnbindRequest'(Val, TagIn);
+
+'enc_UnbindRequest'(Val, TagIn) ->
+?RT_BER:encode_null(Val, TagIn ++ [{tag,64,2,'IMPLICIT',32}]).
+
+
+'dec_UnbindRequest'(Bytes, OptOrMand) ->
+ 'dec_UnbindRequest'(Bytes, OptOrMand, []).
+
+'dec_UnbindRequest'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_null(Bytes,TagIn++[{tag,64,2,'IMPLICIT',32}], OptOrMand).
+
+
+
+%%================================
+%% SearchRequest
+%%================================
+'enc_SearchRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,baseObject), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = case (case ?RT_BER:cindex(3,Val,scope) of {_,Enumval2}->Enumval2;_->?RT_BER:cindex(3,Val,scope) end) of
+baseObject -> ?RT_BER:encode_enumerated(0,[]);
+singleLevel -> ?RT_BER:encode_enumerated(1,[]);
+wholeSubtree -> ?RT_BER:encode_enumerated(2,[]);
+Enumval3 -> exit({error,{asn1, {enumerated_not_in_range,Enumval3}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 3 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = case (case ?RT_BER:cindex(4,Val,derefAliases) of {_,Enumval4}->Enumval4;_->?RT_BER:cindex(4,Val,derefAliases) end) of
+neverDerefAliases -> ?RT_BER:encode_enumerated(0,[]);
+derefInSearching -> ?RT_BER:encode_enumerated(1,[]);
+derefFindingBaseObj -> ?RT_BER:encode_enumerated(2,[]);
+derefAlways -> ?RT_BER:encode_enumerated(3,[]);
+Enumval5 -> exit({error,{asn1, {enumerated_not_in_range,Enumval5}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 4 with type INTEGER
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = ?RT_BER:encode_integer([], ?RT_BER:cindex(5,Val,sizeLimit), []),
+
+%%-------------------------------------------------
+%% attribute number 5 with type INTEGER
+%%-------------------------------------------------
+ {EncBytes5,EncLen5} = ?RT_BER:encode_integer([], ?RT_BER:cindex(6,Val,timeLimit), []),
+
+%%-------------------------------------------------
+%% attribute number 6 with type BOOLEAN
+%%-------------------------------------------------
+ {EncBytes6,EncLen6} = ?RT_BER:encode_boolean(?RT_BER:cindex(7,Val,typesOnly), []),
+
+%%-------------------------------------------------
+%% attribute number 7 External ELDAPv3:Filter
+%%-------------------------------------------------
+ {EncBytes7,EncLen7} = 'enc_Filter'(?RT_BER:cindex(8,Val,filter), []),
+
+%%-------------------------------------------------
+%% attribute number 8 External ELDAPv3:AttributeDescriptionList
+%%-------------------------------------------------
+ {EncBytes8,EncLen8} = 'enc_AttributeDescriptionList'(?RT_BER:cindex(9,Val,attributes), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4, EncBytes5, EncBytes6, EncBytes7, EncBytes8],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4 + EncLen5 + EncLen6 + EncLen7 + EncLen8,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,3,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_SearchRequest'(Bytes, OptOrMand) ->
+ 'dec_SearchRequest'(Bytes, OptOrMand, []).
+
+'dec_SearchRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,3,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type ENUMERATED
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_enumerated(Bytes3,[],[{baseObject,0},{singleLevel,1},{wholeSubtree,2}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 with type ENUMERATED
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_enumerated(Bytes4,[],[{neverDerefAliases,0},{derefInSearching,1},{derefFindingBaseObj,2},{derefAlways,3}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 with type INTEGER
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = ?RT_BER:decode_integer(Bytes5,{0,2147483647},[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 5 with type INTEGER
+%%-------------------------------------------------
+ {Term5,Bytes7,Rb6} = ?RT_BER:decode_integer(Bytes6,{0,2147483647},[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 6 with type BOOLEAN
+%%-------------------------------------------------
+ {Term6,Bytes8,Rb7} = ?RT_BER:decode_boolean(Bytes7,[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 7 External ELDAPv3:Filter
+%%-------------------------------------------------
+ {Term7,Bytes9,Rb8} = 'dec_Filter'(Bytes8, mandatory, []),
+
+%%-------------------------------------------------
+%% attribute number 8 External ELDAPv3:AttributeDescriptionList
+%%-------------------------------------------------
+ {Term8,Bytes10,Rb9} = 'dec_AttributeDescriptionList'(Bytes9, mandatory, []),
+
+ {Bytes11,Rb10} = ?RT_BER:restbytes2(RemBytes, Bytes10,noext),
+ {{'SearchRequest', Term1, Term2, Term3, Term4, Term5, Term6, Term7, Term8}, Bytes11, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6+Rb7+Rb8+Rb9+Rb10}.
+
+
+%%================================
+%% Filter
+%%================================
+
+'enc_Filter'({'Filter',Val}, TagIn) ->
+ 'enc_Filter'(Val, TagIn);
+
+'enc_Filter'(Val, TagIn) ->
+ {EncBytes,EncLen} = case element(1,Val) of
+ 'and' ->
+ 'enc_Filter_and'(element(2,Val), [{tag,128,0,'IMPLICIT',32}]);
+ 'or' ->
+ 'enc_Filter_or'(element(2,Val), [{tag,128,1,'IMPLICIT',32}]);
+ 'not' ->
+ 'enc_Filter'(element(2,Val), [{tag,128,2,'EXPLICIT',32}]);
+ equalityMatch ->
+ 'enc_AttributeValueAssertion'(element(2,Val), [{tag,128,3,'IMPLICIT',32}]);
+ substrings ->
+ 'enc_SubstringFilter'(element(2,Val), [{tag,128,4,'IMPLICIT',32}]);
+ greaterOrEqual ->
+ 'enc_AttributeValueAssertion'(element(2,Val), [{tag,128,5,'IMPLICIT',32}]);
+ lessOrEqual ->
+ 'enc_AttributeValueAssertion'(element(2,Val), [{tag,128,6,'IMPLICIT',32}]);
+ present ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,128,7,'IMPLICIT',32}]);
+ approxMatch ->
+ 'enc_AttributeValueAssertion'(element(2,Val), [{tag,128,8,'IMPLICIT',32}]);
+ extensibleMatch ->
+ 'enc_MatchingRuleAssertion'(element(2,Val), [{tag,128,9,'IMPLICIT',32}]);
+ Else ->
+ exit({error,{asn1,{invalid_choice_type,Else}}})
+ end,
+
+?RT_BER:encode_tags(TagIn ++[], EncBytes, EncLen).
+
+
+
+
+
+%%================================
+%% Filter_and
+%%================================
+
+'enc_Filter_and'({'Filter_and',Val}, TagIn) ->
+ 'enc_Filter_and'(Val, TagIn);
+
+'enc_Filter_and'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_Filter_and_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_Filter_and_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_Filter_and_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_Filter'(H, []),
+ 'enc_Filter_and_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_Filter_and'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_Filter'/3, [], []).
+
+
+
+
+
+%%================================
+%% Filter_or
+%%================================
+
+'enc_Filter_or'({'Filter_or',Val}, TagIn) ->
+ 'enc_Filter_or'(Val, TagIn);
+
+'enc_Filter_or'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_Filter_or_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_Filter_or_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_Filter_or_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_Filter'(H, []),
+ 'enc_Filter_or_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_Filter_or'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_Filter'/3, [], []).
+
+
+
+
+'dec_Filter'(Bytes, OptOrMand) ->
+ 'dec_Filter'(Bytes, OptOrMand, []).
+
+'dec_Filter'(Bytes, OptOrMand, TagIn) ->
+ {{_,Len},Bytes1, RbExp} = ?RT_BER:check_tags(TagIn++[], Bytes, OptOrMand),
+ IndefEndBytes = fun(indefinite,<<0,0,R/binary>>)-> R; (_,B)-> B end,
+ IndefEndRb = fun(indefinite,<<0,0,_R/binary>>)-> 2; (_,_)-> 0 end,
+ case Bytes1 of
+
+%% 'and'
+ <<2:2,_:1,0:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_Filter_and'(Bytes1, mandatory, [{tag,128,0,'IMPLICIT',32}]),
+ {{'and', Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'or'
+ <<2:2,_:1,1:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_Filter_or'(Bytes1, mandatory, [{tag,128,1,'IMPLICIT',32}]),
+ {{'or', Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'not'
+ <<2:2,_:1,2:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_Filter'(Bytes1, mandatory, [{tag,128,2,'EXPLICIT',32}]),
+ {{'not', Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'equalityMatch'
+ <<2:2,_:1,3:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AttributeValueAssertion'(Bytes1, mandatory, [{tag,128,3,'IMPLICIT',32}]),
+ {{equalityMatch, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'substrings'
+ <<2:2,_:1,4:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_SubstringFilter'(Bytes1, mandatory, [{tag,128,4,'IMPLICIT',32}]),
+ {{substrings, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'greaterOrEqual'
+ <<2:2,_:1,5:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AttributeValueAssertion'(Bytes1, mandatory, [{tag,128,5,'IMPLICIT',32}]),
+ {{greaterOrEqual, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'lessOrEqual'
+ <<2:2,_:1,6:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AttributeValueAssertion'(Bytes1, mandatory, [{tag,128,6,'IMPLICIT',32}]),
+ {{lessOrEqual, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'present'
+ <<2:2,_:1,7:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,128,7,'IMPLICIT',32}], no_length, mandatory),
+ {{present, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'approxMatch'
+ <<2:2,_:1,8:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_AttributeValueAssertion'(Bytes1, mandatory, [{tag,128,8,'IMPLICIT',32}]),
+ {{approxMatch, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'extensibleMatch'
+ <<2:2,_:1,9:5,_/binary>> ->
+ {Dec, Rest, RbCho} = 'dec_MatchingRuleAssertion'(Bytes1, mandatory, [{tag,128,9,'IMPLICIT',32}]),
+ {{extensibleMatch, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+ Else ->
+ case OptOrMand of
+ mandatory ->exit({error,{asn1,{invalid_choice_tag,Else}}});
+ _ ->exit({error,{asn1,{no_optional_tag,Else}}})
+ end
+ end.
+
+
+%%================================
+%% SubstringFilter
+%%================================
+'enc_SubstringFilter'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,type), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SEQUENCE OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_SubstringFilter_substrings'(?RT_BER:cindex(3,Val,substrings), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% SubstringFilter_substrings
+%%================================
+
+'enc_SubstringFilter_substrings'({'SubstringFilter_substrings',Val}, TagIn) ->
+ 'enc_SubstringFilter_substrings'(Val, TagIn);
+
+'enc_SubstringFilter_substrings'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_SubstringFilter_substrings_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_SubstringFilter_substrings_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_SubstringFilter_substrings_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_SubstringFilter_substrings_SEQOF'(H, []),
+ 'enc_SubstringFilter_substrings_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+
+%%================================
+%% SubstringFilter_substrings_SEQOF
+%%================================
+
+'enc_SubstringFilter_substrings_SEQOF'({'SubstringFilter_substrings_SEQOF',Val}, TagIn) ->
+ 'enc_SubstringFilter_substrings_SEQOF'(Val, TagIn);
+
+'enc_SubstringFilter_substrings_SEQOF'(Val, TagIn) ->
+ {EncBytes,EncLen} = case element(1,Val) of
+ initial ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,128,0,'IMPLICIT',32}]);
+ any ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,128,1,'IMPLICIT',32}]);
+ final ->
+ ?RT_BER:encode_octet_string([], element(2,Val), [{tag,128,2,'IMPLICIT',32}]);
+ Else ->
+ exit({error,{asn1,{invalid_choice_type,Else}}})
+ end,
+
+?RT_BER:encode_tags(TagIn ++[], EncBytes, EncLen).
+
+
+'dec_SubstringFilter_substrings_SEQOF'(Bytes, OptOrMand, TagIn) ->
+ {{_,Len},Bytes1, RbExp} = ?RT_BER:check_tags(TagIn++[], Bytes, OptOrMand),
+ IndefEndBytes = fun(indefinite,<<0,0,R/binary>>)-> R; (_,B)-> B end,
+ IndefEndRb = fun(indefinite,<<0,0,_R/binary>>)-> 2; (_,_)-> 0 end,
+ case Bytes1 of
+
+%% 'initial'
+ <<2:2,_:1,0:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,128,0,'IMPLICIT',32}], no_length, mandatory),
+ {{initial, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'any'
+ <<2:2,_:1,1:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,128,1,'IMPLICIT',32}], no_length, mandatory),
+ {{any, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+
+%% 'final'
+ <<2:2,_:1,2:5,_/binary>> ->
+ {Dec, Rest, RbCho} = ?RT_BER:decode_octet_string(Bytes1,[],[{tag,128,2,'IMPLICIT',32}], no_length, mandatory),
+ {{final, Dec}, IndefEndBytes(Len,Rest), RbExp + RbCho + IndefEndRb(Len,Rest)};
+
+ Else ->
+ case OptOrMand of
+ mandatory ->exit({error,{asn1,{invalid_choice_tag,Else}}});
+ _ ->exit({error,{asn1,{no_optional_tag,Else}}})
+ end
+ end.
+'dec_SubstringFilter_substrings'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_SubstringFilter_substrings_SEQOF'/3, [], []).
+
+
+
+
+'dec_SubstringFilter'(Bytes, OptOrMand) ->
+ 'dec_SubstringFilter'(Bytes, OptOrMand, []).
+
+'dec_SubstringFilter'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SEQUENCE OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_SubstringFilter_substrings'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'SubstringFilter', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% MatchingRuleAssertion
+%%================================
+'enc_MatchingRuleAssertion'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = case ?RT_BER:cindex(2,Val,matchingRule) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,matchingRule), [{tag,128,1,'IMPLICIT',32}])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = case ?RT_BER:cindex(3,Val,type) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,type), [{tag,128,2,'IMPLICIT',32}])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(4,Val,matchValue), [{tag,128,3,'IMPLICIT',32}]),
+
+%%-------------------------------------------------
+%% attribute number 4 with type BOOLEAN DEFAULT = false
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = case ?RT_BER:cindex(5,Val,dnAttributes) of
+ asn1_DEFAULT -> {<<>>,0};
+ false -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_boolean(?RT_BER:cindex(5,Val,dnAttributes), [{tag,128,4,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_MatchingRuleAssertion'(Bytes, OptOrMand) ->
+ 'dec_MatchingRuleAssertion'(Bytes, OptOrMand, []).
+
+'dec_MatchingRuleAssertion'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = case Bytes2 of
+<<2:2,_:1,1:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes2,[],[{tag,128,1,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes2, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = case Bytes3 of
+<<2:2,_:1,2:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes3,[],[{tag,128,2,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes3, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_octet_string(Bytes4,[],[{tag,128,3,'IMPLICIT',32}], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 with type BOOLEAN DEFAULT = false
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = case Bytes5 of
+<<2:2,_:1,4:5,_/binary>> ->
+?RT_BER:decode_boolean(Bytes5,[{tag,128,4,'IMPLICIT',32}], mandatory);
+_ ->
+{false,Bytes5, 0 }
+end,
+
+ {Bytes7,Rb6} = ?RT_BER:restbytes2(RemBytes, Bytes6,noext),
+ {{'MatchingRuleAssertion', Term1, Term2, Term3, Term4}, Bytes7, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6}.
+
+
+%%================================
+%% SearchResultEntry
+%%================================
+'enc_SearchResultEntry'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,objectName), []),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:PartialAttributeList
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_PartialAttributeList'(?RT_BER:cindex(3,Val,attributes), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,4,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_SearchResultEntry'(Bytes, OptOrMand) ->
+ 'dec_SearchResultEntry'(Bytes, OptOrMand, []).
+
+'dec_SearchResultEntry'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,4,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:PartialAttributeList
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_PartialAttributeList'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'SearchResultEntry', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% PartialAttributeList
+%%================================
+
+'enc_PartialAttributeList'({'PartialAttributeList',Val}, TagIn) ->
+ 'enc_PartialAttributeList'(Val, TagIn);
+
+'enc_PartialAttributeList'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_PartialAttributeList_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_PartialAttributeList_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_PartialAttributeList_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_PartialAttributeList_SEQOF'(H, []),
+ 'enc_PartialAttributeList_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+
+%%================================
+%% PartialAttributeList_SEQOF
+%%================================
+'enc_PartialAttributeList_SEQOF'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,type), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_PartialAttributeList_SEQOF_vals'(?RT_BER:cindex(3,Val,vals), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% PartialAttributeList_SEQOF_vals
+%%================================
+
+'enc_PartialAttributeList_SEQOF_vals'({'PartialAttributeList_SEQOF_vals',Val}, TagIn) ->
+ 'enc_PartialAttributeList_SEQOF_vals'(Val, TagIn);
+
+'enc_PartialAttributeList_SEQOF_vals'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_PartialAttributeList_SEQOF_vals_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_PartialAttributeList_SEQOF_vals_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_PartialAttributeList_SEQOF_vals_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_PartialAttributeList_SEQOF_vals_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_PartialAttributeList_SEQOF_vals'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+'dec_PartialAttributeList_SEQOF'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_PartialAttributeList_SEQOF_vals'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'PartialAttributeList_SEQOF', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+'dec_PartialAttributeList'(Bytes, OptOrMand) ->
+ 'dec_PartialAttributeList'(Bytes, OptOrMand, []).
+
+'dec_PartialAttributeList'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_PartialAttributeList_SEQOF'/3, [], []).
+
+
+
+
+%%================================
+%% SearchResultReference
+%%================================
+
+'enc_SearchResultReference'({'SearchResultReference',Val}, TagIn) ->
+ 'enc_SearchResultReference'(Val, TagIn);
+
+'enc_SearchResultReference'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_SearchResultReference_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,19,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_SearchResultReference_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_SearchResultReference_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_SearchResultReference_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+'dec_SearchResultReference'(Bytes, OptOrMand) ->
+ 'dec_SearchResultReference'(Bytes, OptOrMand, []).
+
+'dec_SearchResultReference'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,19,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+
+
+%%================================
+%% SearchResultDone
+%%================================
+
+'enc_SearchResultDone'({'SearchResultDone',Val}, TagIn) ->
+ 'enc_SearchResultDone'(Val, TagIn);
+
+'enc_SearchResultDone'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,5,'IMPLICIT',32}]).
+
+
+'dec_SearchResultDone'(Bytes, OptOrMand) ->
+ 'dec_SearchResultDone'(Bytes, OptOrMand, []).
+
+'dec_SearchResultDone'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,5,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% ModifyRequest
+%%================================
+'enc_ModifyRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,object), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SEQUENCE OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_ModifyRequest_modification'(?RT_BER:cindex(3,Val,modification), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,6,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% ModifyRequest_modification
+%%================================
+
+'enc_ModifyRequest_modification'({'ModifyRequest_modification',Val}, TagIn) ->
+ 'enc_ModifyRequest_modification'(Val, TagIn);
+
+'enc_ModifyRequest_modification'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_ModifyRequest_modification_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_ModifyRequest_modification_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_ModifyRequest_modification_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_ModifyRequest_modification_SEQOF'(H, []),
+ 'enc_ModifyRequest_modification_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+
+%%================================
+%% ModifyRequest_modification_SEQOF
+%%================================
+'enc_ModifyRequest_modification_SEQOF'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = case (case ?RT_BER:cindex(2,Val,operation) of {_,Enumval1}->Enumval1;_->?RT_BER:cindex(2,Val,operation) end) of
+add -> ?RT_BER:encode_enumerated(0,[]);
+delete -> ?RT_BER:encode_enumerated(1,[]);
+replace -> ?RT_BER:encode_enumerated(2,[]);
+Enumval2 -> exit({error,{asn1, {enumerated_not_in_range,Enumval2}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeTypeAndValues
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_AttributeTypeAndValues'(?RT_BER:cindex(3,Val,modification), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+'dec_ModifyRequest_modification_SEQOF'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_enumerated(Bytes2,[],[{add,0},{delete,1},{replace,2}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeTypeAndValues
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_AttributeTypeAndValues'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'ModifyRequest_modification_SEQOF', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+'dec_ModifyRequest_modification'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_ModifyRequest_modification_SEQOF'/3, [], []).
+
+
+
+
+'dec_ModifyRequest'(Bytes, OptOrMand) ->
+ 'dec_ModifyRequest'(Bytes, OptOrMand, []).
+
+'dec_ModifyRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,6,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SEQUENCE OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_ModifyRequest_modification'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'ModifyRequest', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% AttributeTypeAndValues
+%%================================
+'enc_AttributeTypeAndValues'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,type), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_AttributeTypeAndValues_vals'(?RT_BER:cindex(3,Val,vals), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% AttributeTypeAndValues_vals
+%%================================
+
+'enc_AttributeTypeAndValues_vals'({'AttributeTypeAndValues_vals',Val}, TagIn) ->
+ 'enc_AttributeTypeAndValues_vals'(Val, TagIn);
+
+'enc_AttributeTypeAndValues_vals'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_AttributeTypeAndValues_vals_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_AttributeTypeAndValues_vals_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_AttributeTypeAndValues_vals_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_AttributeTypeAndValues_vals_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_AttributeTypeAndValues_vals'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+
+
+'dec_AttributeTypeAndValues'(Bytes, OptOrMand) ->
+ 'dec_AttributeTypeAndValues'(Bytes, OptOrMand, []).
+
+'dec_AttributeTypeAndValues'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_AttributeTypeAndValues_vals'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'AttributeTypeAndValues', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% ModifyResponse
+%%================================
+
+'enc_ModifyResponse'({'ModifyResponse',Val}, TagIn) ->
+ 'enc_ModifyResponse'(Val, TagIn);
+
+'enc_ModifyResponse'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,7,'IMPLICIT',32}]).
+
+
+'dec_ModifyResponse'(Bytes, OptOrMand) ->
+ 'dec_ModifyResponse'(Bytes, OptOrMand, []).
+
+'dec_ModifyResponse'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,7,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% AddRequest
+%%================================
+'enc_AddRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,entry), []),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeList
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_AttributeList'(?RT_BER:cindex(3,Val,attributes), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,8,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_AddRequest'(Bytes, OptOrMand) ->
+ 'dec_AddRequest'(Bytes, OptOrMand, []).
+
+'dec_AddRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,8,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeList
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_AttributeList'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'AddRequest', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% AttributeList
+%%================================
+
+'enc_AttributeList'({'AttributeList',Val}, TagIn) ->
+ 'enc_AttributeList'(Val, TagIn);
+
+'enc_AttributeList'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_AttributeList_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_AttributeList_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_AttributeList_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = 'enc_AttributeList_SEQOF'(H, []),
+ 'enc_AttributeList_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+
+
+
+%%================================
+%% AttributeList_SEQOF
+%%================================
+'enc_AttributeList_SEQOF'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,type), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_AttributeList_SEQOF_vals'(?RT_BER:cindex(3,Val,vals), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+
+%%================================
+%% AttributeList_SEQOF_vals
+%%================================
+
+'enc_AttributeList_SEQOF_vals'({'AttributeList_SEQOF_vals',Val}, TagIn) ->
+ 'enc_AttributeList_SEQOF_vals'(Val, TagIn);
+
+'enc_AttributeList_SEQOF_vals'(Val, TagIn) ->
+ {EncBytes,EncLen} = 'enc_AttributeList_SEQOF_vals_components'(Val,[],0),
+ ?RT_BER:encode_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], EncBytes, EncLen).
+
+'enc_AttributeList_SEQOF_vals_components'([], AccBytes, AccLen) ->
+ {lists:reverse(AccBytes),AccLen};
+
+'enc_AttributeList_SEQOF_vals_components'([H|T],AccBytes, AccLen) ->
+ {EncBytes,EncLen} = ?RT_BER:encode_octet_string([], H, []),
+ 'enc_AttributeList_SEQOF_vals_components'(T,[EncBytes|AccBytes], AccLen + EncLen).
+
+'dec_AttributeList_SEQOF_vals'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,17,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun(FBytes,_,_)->
+?RT_BER:decode_octet_string(FBytes,[],[], no_length, mandatory)
+end, [], []).
+
+
+'dec_AttributeList_SEQOF'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type SET OF
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_AttributeList_SEQOF_vals'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'AttributeList_SEQOF', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+'dec_AttributeList'(Bytes, OptOrMand) ->
+ 'dec_AttributeList'(Bytes, OptOrMand, []).
+
+'dec_AttributeList'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+ ?RT_BER:decode_components(Rb1, Len, Bytes1, fun 'dec_AttributeList_SEQOF'/3, [], []).
+
+
+
+
+%%================================
+%% AddResponse
+%%================================
+
+'enc_AddResponse'({'AddResponse',Val}, TagIn) ->
+ 'enc_AddResponse'(Val, TagIn);
+
+'enc_AddResponse'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,9,'IMPLICIT',32}]).
+
+
+'dec_AddResponse'(Bytes, OptOrMand) ->
+ 'dec_AddResponse'(Bytes, OptOrMand, []).
+
+'dec_AddResponse'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,9,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% DelRequest
+%%================================
+
+'enc_DelRequest'({'DelRequest',Val}, TagIn) ->
+ 'enc_DelRequest'(Val, TagIn);
+
+'enc_DelRequest'(Val, TagIn) ->
+?RT_BER:encode_octet_string([], Val, TagIn ++ [{tag,64,10,'IMPLICIT',32}]).
+
+
+'dec_DelRequest'(Bytes, OptOrMand) ->
+ 'dec_DelRequest'(Bytes, OptOrMand, []).
+
+'dec_DelRequest'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_octet_string(Bytes,[],TagIn++[{tag,64,10,'IMPLICIT',32}], no_length, OptOrMand).
+
+
+
+%%================================
+%% DelResponse
+%%================================
+
+'enc_DelResponse'({'DelResponse',Val}, TagIn) ->
+ 'enc_DelResponse'(Val, TagIn);
+
+'enc_DelResponse'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,11,'IMPLICIT',32}]).
+
+
+'dec_DelResponse'(Bytes, OptOrMand) ->
+ 'dec_DelResponse'(Bytes, OptOrMand, []).
+
+'dec_DelResponse'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,11,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% ModifyDNRequest
+%%================================
+'enc_ModifyDNRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,entry), []),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,newrdn), []),
+
+%%-------------------------------------------------
+%% attribute number 3 with type BOOLEAN
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = ?RT_BER:encode_boolean(?RT_BER:cindex(4,Val,deleteoldrdn), []),
+
+%%-------------------------------------------------
+%% attribute number 4 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = case ?RT_BER:cindex(5,Val,newSuperior) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(5,Val,newSuperior), [{tag,128,0,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,12,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_ModifyDNRequest'(Bytes, OptOrMand) ->
+ 'dec_ModifyDNRequest'(Bytes, OptOrMand, []).
+
+'dec_ModifyDNRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,12,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 with type BOOLEAN
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_boolean(Bytes4,[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = case Bytes5 of
+<<2:2,_:1,0:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes5,[],[{tag,128,0,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes5, 0 }
+end,
+
+ {Bytes7,Rb6} = ?RT_BER:restbytes2(RemBytes, Bytes6,noext),
+ {{'ModifyDNRequest', Term1, Term2, Term3, Term4}, Bytes7, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6}.
+
+
+%%================================
+%% ModifyDNResponse
+%%================================
+
+'enc_ModifyDNResponse'({'ModifyDNResponse',Val}, TagIn) ->
+ 'enc_ModifyDNResponse'(Val, TagIn);
+
+'enc_ModifyDNResponse'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,13,'IMPLICIT',32}]).
+
+
+'dec_ModifyDNResponse'(Bytes, OptOrMand) ->
+ 'dec_ModifyDNResponse'(Bytes, OptOrMand, []).
+
+'dec_ModifyDNResponse'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,13,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% CompareRequest
+%%================================
+'enc_CompareRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,entry), []),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeValueAssertion
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = 'enc_AttributeValueAssertion'(?RT_BER:cindex(3,Val,ava), []),
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,14,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_CompareRequest'(Bytes, OptOrMand) ->
+ 'dec_CompareRequest'(Bytes, OptOrMand, []).
+
+'dec_CompareRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,14,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 External ELDAPv3:AttributeValueAssertion
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = 'dec_AttributeValueAssertion'(Bytes3, mandatory, []),
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'CompareRequest', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% CompareResponse
+%%================================
+
+'enc_CompareResponse'({'CompareResponse',Val}, TagIn) ->
+ 'enc_CompareResponse'(Val, TagIn);
+
+'enc_CompareResponse'(Val, TagIn) ->
+ 'enc_LDAPResult'(Val, TagIn ++ [{tag,64,15,'IMPLICIT',32}]).
+
+
+'dec_CompareResponse'(Bytes, OptOrMand) ->
+ 'dec_CompareResponse'(Bytes, OptOrMand, []).
+
+'dec_CompareResponse'(Bytes, OptOrMand, TagIn) ->
+'dec_LDAPResult'(Bytes, OptOrMand, TagIn++[{tag,64,15,'IMPLICIT',32}]).
+
+
+
+%%================================
+%% AbandonRequest
+%%================================
+
+'enc_AbandonRequest'({'AbandonRequest',Val}, TagIn) ->
+ 'enc_AbandonRequest'(Val, TagIn);
+
+'enc_AbandonRequest'(Val, TagIn) ->
+?RT_BER:encode_integer([], Val, TagIn ++ [{tag,64,16,'IMPLICIT',32}]).
+
+
+'dec_AbandonRequest'(Bytes, OptOrMand) ->
+ 'dec_AbandonRequest'(Bytes, OptOrMand, []).
+
+'dec_AbandonRequest'(Bytes, OptOrMand, TagIn) ->
+?RT_BER:decode_integer(Bytes,{0,2147483647},TagIn++[{tag,64,16,'IMPLICIT',32}], OptOrMand).
+
+
+
+%%================================
+%% ExtendedRequest
+%%================================
+'enc_ExtendedRequest'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(2,Val,requestName), [{tag,128,0,'IMPLICIT',32}]),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = case ?RT_BER:cindex(3,Val,requestValue) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,requestValue), [{tag,128,1,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2],
+ LenSoFar = EncLen1 + EncLen2,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,23,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_ExtendedRequest'(Bytes, OptOrMand) ->
+ 'dec_ExtendedRequest'(Bytes, OptOrMand, []).
+
+'dec_ExtendedRequest'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,23,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type OCTET STRING
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_octet_string(Bytes2,[],[{tag,128,0,'IMPLICIT',32}], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = case Bytes3 of
+<<2:2,_:1,1:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes3,[],[{tag,128,1,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes3, 0 }
+end,
+
+ {Bytes5,Rb4} = ?RT_BER:restbytes2(RemBytes, Bytes4,noext),
+ {{'ExtendedRequest', Term1, Term2}, Bytes5, Rb1+Rb2+Rb3+Rb4}.
+
+
+%%================================
+%% ExtendedResponse
+%%================================
+'enc_ExtendedResponse'(Val, TagIn) ->
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {EncBytes1,EncLen1} = case (case ?RT_BER:cindex(2,Val,resultCode) of {_,Enumval1}->Enumval1;_->?RT_BER:cindex(2,Val,resultCode) end) of
+success -> ?RT_BER:encode_enumerated(0,[]);
+operationsError -> ?RT_BER:encode_enumerated(1,[]);
+protocolError -> ?RT_BER:encode_enumerated(2,[]);
+timeLimitExceeded -> ?RT_BER:encode_enumerated(3,[]);
+sizeLimitExceeded -> ?RT_BER:encode_enumerated(4,[]);
+compareFalse -> ?RT_BER:encode_enumerated(5,[]);
+compareTrue -> ?RT_BER:encode_enumerated(6,[]);
+authMethodNotSupported -> ?RT_BER:encode_enumerated(7,[]);
+strongAuthRequired -> ?RT_BER:encode_enumerated(8,[]);
+referral -> ?RT_BER:encode_enumerated(10,[]);
+adminLimitExceeded -> ?RT_BER:encode_enumerated(11,[]);
+unavailableCriticalExtension -> ?RT_BER:encode_enumerated(12,[]);
+confidentialityRequired -> ?RT_BER:encode_enumerated(13,[]);
+saslBindInProgress -> ?RT_BER:encode_enumerated(14,[]);
+noSuchAttribute -> ?RT_BER:encode_enumerated(16,[]);
+undefinedAttributeType -> ?RT_BER:encode_enumerated(17,[]);
+inappropriateMatching -> ?RT_BER:encode_enumerated(18,[]);
+constraintViolation -> ?RT_BER:encode_enumerated(19,[]);
+attributeOrValueExists -> ?RT_BER:encode_enumerated(20,[]);
+invalidAttributeSyntax -> ?RT_BER:encode_enumerated(21,[]);
+noSuchObject -> ?RT_BER:encode_enumerated(32,[]);
+aliasProblem -> ?RT_BER:encode_enumerated(33,[]);
+invalidDNSyntax -> ?RT_BER:encode_enumerated(34,[]);
+aliasDereferencingProblem -> ?RT_BER:encode_enumerated(36,[]);
+inappropriateAuthentication -> ?RT_BER:encode_enumerated(48,[]);
+invalidCredentials -> ?RT_BER:encode_enumerated(49,[]);
+insufficientAccessRights -> ?RT_BER:encode_enumerated(50,[]);
+busy -> ?RT_BER:encode_enumerated(51,[]);
+unavailable -> ?RT_BER:encode_enumerated(52,[]);
+unwillingToPerform -> ?RT_BER:encode_enumerated(53,[]);
+loopDetect -> ?RT_BER:encode_enumerated(54,[]);
+namingViolation -> ?RT_BER:encode_enumerated(64,[]);
+objectClassViolation -> ?RT_BER:encode_enumerated(65,[]);
+notAllowedOnNonLeaf -> ?RT_BER:encode_enumerated(66,[]);
+notAllowedOnRDN -> ?RT_BER:encode_enumerated(67,[]);
+entryAlreadyExists -> ?RT_BER:encode_enumerated(68,[]);
+objectClassModsProhibited -> ?RT_BER:encode_enumerated(69,[]);
+affectsMultipleDSAs -> ?RT_BER:encode_enumerated(71,[]);
+other -> ?RT_BER:encode_enumerated(80,[]);
+Enumval2 -> exit({error,{asn1, {enumerated_not_in_range,Enumval2}}})
+end,
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes2,EncLen2} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(3,Val,matchedDN), []),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {EncBytes3,EncLen3} = ?RT_BER:encode_octet_string([], ?RT_BER:cindex(4,Val,errorMessage), []),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {EncBytes4,EncLen4} = case ?RT_BER:cindex(5,Val,referral) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ 'enc_Referral'(?RT_BER:cindex(5,Val,referral), [{tag,128,3,'IMPLICIT',32}])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 5 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes5,EncLen5} = case ?RT_BER:cindex(6,Val,responseName) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(6,Val,responseName), [{tag,128,10,'IMPLICIT',32}])
+ end,
+
+%%-------------------------------------------------
+%% attribute number 6 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {EncBytes6,EncLen6} = case ?RT_BER:cindex(7,Val,response) of
+ asn1_NOVALUE -> {<<>>,0};
+ _ ->
+ ?RT_BER:encode_octet_string([], ?RT_BER:cindex(7,Val,response), [{tag,128,11,'IMPLICIT',32}])
+ end,
+
+ BytesSoFar = [EncBytes1, EncBytes2, EncBytes3, EncBytes4, EncBytes5, EncBytes6],
+ LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4 + EncLen5 + EncLen6,
+ ?RT_BER:encode_tags(TagIn ++ [{tag,64,24,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], BytesSoFar, LenSoFar).
+
+
+'dec_ExtendedResponse'(Bytes, OptOrMand) ->
+ 'dec_ExtendedResponse'(Bytes, OptOrMand, []).
+
+'dec_ExtendedResponse'(Bytes, OptOrMand, TagIn) ->
+ %%-------------------------------------------------
+ %% decode tag and length
+ %%-------------------------------------------------
+ {{_,Len},Bytes1,Rb1} = ?RT_BER:check_tags(TagIn ++ [{tag,64,24,'IMPLICIT',32},{tag,0,16,'IMPLICIT',32}], Bytes, OptOrMand),
+{Bytes2,RemBytes} = ?RT_BER:split_list(Bytes1,Len),
+
+%%-------------------------------------------------
+%% attribute number 1 with type ENUMERATED
+%%-------------------------------------------------
+ {Term1,Bytes3,Rb2} = ?RT_BER:decode_enumerated(Bytes2,[],[{success,0},{operationsError,1},{protocolError,2},{timeLimitExceeded,3},{sizeLimitExceeded,4},{compareFalse,5},{compareTrue,6},{authMethodNotSupported,7},{strongAuthRequired,8},{referral,10},{adminLimitExceeded,11},{unavailableCriticalExtension,12},{confidentialityRequired,13},{saslBindInProgress,14},{noSuchAttribute,16},{undefinedAttributeType,17},{inappropriateMatching,18},{constraintViolation,19},{attributeOrValueExists,20},{invalidAttributeSyntax,21},{noSuchObject,32},{aliasProblem,33},{invalidDNSyntax,34},{aliasDereferencingProblem,36},{inappropriateAuthentication,48},{invalidCredentials,49},{insufficientAccessRights,50},{busy,51},{unavailable,52},{unwillingToPerform,53},{loopDetect,54},{namingViolation,64},{objectClassViolation,65},{notAllowedOnNonLeaf,66},{notAllowedOnRDN,67},{entryAlreadyExists,68},{objectClassModsProhibited,69},{affectsMultipleDSAs,71},{other,80}],[], mandatory),
+
+%%-------------------------------------------------
+%% attribute number 2 with type OCTET STRING
+%%-------------------------------------------------
+ {Term2,Bytes4,Rb3} = ?RT_BER:decode_octet_string(Bytes3,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 3 with type OCTET STRING
+%%-------------------------------------------------
+ {Term3,Bytes5,Rb4} = ?RT_BER:decode_octet_string(Bytes4,[],[], no_length, mandatory),
+
+%%-------------------------------------------------
+%% attribute number 4 External ELDAPv3:Referral OPTIONAL
+%%-------------------------------------------------
+ {Term4,Bytes6,Rb5} = case Bytes5 of
+<<2:2,_:1,3:5,_/binary>> ->
+'dec_Referral'(Bytes5, opt_or_default, [{tag,128,3,'IMPLICIT',32}]);
+_ ->
+{ asn1_NOVALUE, Bytes5, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 5 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term5,Bytes7,Rb6} = case Bytes6 of
+<<2:2,_:1,10:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes6,[],[{tag,128,10,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes6, 0 }
+end,
+
+%%-------------------------------------------------
+%% attribute number 6 with type OCTET STRING OPTIONAL
+%%-------------------------------------------------
+ {Term6,Bytes8,Rb7} = case Bytes7 of
+<<2:2,_:1,11:5,_/binary>> ->
+?RT_BER:decode_octet_string(Bytes7,[],[{tag,128,11,'IMPLICIT',32}], no_length, mandatory);
+_ ->
+{ asn1_NOVALUE, Bytes7, 0 }
+end,
+
+ {Bytes9,Rb8} = ?RT_BER:restbytes2(RemBytes, Bytes8,noext),
+ {{'ExtendedResponse', Term1, Term2, Term3, Term4, Term5, Term6}, Bytes9, Rb1+Rb2+Rb3+Rb4+Rb5+Rb6+Rb7+Rb8}.
+'maxInt'() ->
+2147483647.
+
diff --git src/eldap/ELDAPv3.hrl src/eldap/ELDAPv3.hrl
new file mode 100644
index 0000000..d3fe60c
--- /dev/null
+++ src/eldap/ELDAPv3.hrl
@@ -0,0 +1,74 @@
+%% Generated by the Erlang ASN.1 compiler version:1.6.15
+%% Purpose: Erlang record definitions for each named and unnamed
+%% SEQUENCE and SET, and macro definitions for each value
+%% definition,in module ELDAPv3
+
+
+
+-record('LDAPMessage',{
+messageID, protocolOp, controls = asn1_NOVALUE}).
+
+-record('AttributeValueAssertion',{
+attributeDesc, assertionValue}).
+
+-record('Attribute',{
+type, vals}).
+
+-record('LDAPResult',{
+resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE}).
+
+-record('Control',{
+controlType, criticality = asn1_DEFAULT, controlValue = asn1_NOVALUE}).
+
+-record('BindRequest',{
+version, name, authentication}).
+
+-record('SaslCredentials',{
+mechanism, credentials = asn1_NOVALUE}).
+
+-record('BindResponse',{
+resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE, serverSaslCreds = asn1_NOVALUE}).
+
+-record('SearchRequest',{
+baseObject, scope, derefAliases, sizeLimit, timeLimit, typesOnly, filter, attributes}).
+
+-record('SubstringFilter',{
+type, substrings}).
+
+-record('MatchingRuleAssertion',{
+matchingRule = asn1_NOVALUE, type = asn1_NOVALUE, matchValue, dnAttributes = asn1_DEFAULT}).
+
+-record('SearchResultEntry',{
+objectName, attributes}).
+
+-record('PartialAttributeList_SEQOF',{
+type, vals}).
+
+-record('ModifyRequest',{
+object, modification}).
+
+-record('ModifyRequest_modification_SEQOF',{
+operation, modification}).
+
+-record('AttributeTypeAndValues',{
+type, vals}).
+
+-record('AddRequest',{
+entry, attributes}).
+
+-record('AttributeList_SEQOF',{
+type, vals}).
+
+-record('ModifyDNRequest',{
+entry, newrdn, deleteoldrdn, newSuperior = asn1_NOVALUE}).
+
+-record('CompareRequest',{
+entry, ava}).
+
+-record('ExtendedRequest',{
+requestName, requestValue = asn1_NOVALUE}).
+
+-record('ExtendedResponse',{
+resultCode, matchedDN, errorMessage, referral = asn1_NOVALUE, responseName = asn1_NOVALUE, response = asn1_NOVALUE}).
+
+-define('maxInt', 2147483647).
diff --git src/eldap/Makefile.am src/eldap/Makefile.am
new file mode 100644
index 0000000..948c037
--- /dev/null
+++ src/eldap/Makefile.am
@@ -0,0 +1,35 @@
+## Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+## License for the specific language governing permissions and limitations under
+## the License.
+
+eldapebindir = $(localerlanglibdir)/eldap/ebin
+
+eldap_file_collection = \
+ eldap.erl \
+ ELDAPv3.erl
+
+eldapebin_make_generated_file_list = \
+ eldap.beam \
+ ELDAPv3.beam
+
+eldapebin_DATA = \
+ $(eldapebin_make_generated_file_list)
+
+EXTRA_DIST = \
+ $(eldap_file_collection) \
+ eldap.hrl \
+ ELDAPv3.hrl
+
+CLEANFILES = \
+ $(eldapebin_make_generated_file_list)
+
+%.beam: %.erl
+ $(ERLC) $(ERLC_FLAGS) $<
diff --git src/eldap/eldap.erl src/eldap/eldap.erl
new file mode 100644
index 0000000..ae2aca5
--- /dev/null
+++ src/eldap/eldap.erl
@@ -0,0 +1,1082 @@
+-module(eldap).
+%%% --------------------------------------------------------------------
+%%% Created: 12 Oct 2000 by Tobbe <tnt@home.se>
+%%% Function: Erlang client LDAP implementation according RFC 2251,2253
+%%% and 2255. The interface is based on RFC 1823, and
+%%% draft-ietf-asid-ldap-c-api-00.txt
+%%% --------------------------------------------------------------------
+-vc('$Id$ ').
+-export([open/1,open/2,simple_bind/3,controlling_process/2,
+ 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,parse_dn/1,
+ parse_ldap_url/1]).
+
+-import(lists,[concat/1]).
+
+-include("ELDAPv3.hrl").
+-include("eldap.hrl").
+
+-define(LDAP_VERSION, 3).
+-define(LDAP_PORT, 389).
+-define(LDAPS_PORT, 636).
+
+-record(eldap, {version = ?LDAP_VERSION,
+ host, % Host running LDAP server
+ port = ?LDAP_PORT, % The LDAP server port
+ fd, % Socket filedescriptor.
+ binddn = "", % Name of the entry to bind as
+ passwd, % Password for (above) entry
+ id = 0, % LDAP Request ID
+ log, % User provided log function
+ timeout = infinity, % Request timeout
+ anon_auth = false, % Allow anonymous authentication
+ use_tls = false % LDAP/LDAPS
+ }).
+
+%%% For debug purposes
+%%-define(PRINT(S, A), io:fwrite("~w(~w): " ++ S, [?MODULE,?LINE|A])).
+-define(PRINT(S, A), true).
+
+-define(elog(S, A), error_logger:info_msg("~w(~w): "++S,[?MODULE,?LINE|A])).
+
+%%% ====================================================================
+%%% Exported interface
+%%% ====================================================================
+
+%%% --------------------------------------------------------------------
+%%% open(Hosts [,Opts] )
+%%% --------------------
+%%% Setup a connection to on of the Hosts in the argument
+%%% list. Stop at the first successful connection attempt.
+%%% Valid Opts are: Where:
+%%%
+%%% {port, Port} - Port is the port number
+%%% {log, F} - F(LogLevel, FormatString, ListOfArgs)
+%%% {timeout, milliSec} - request timeout
+%%%
+%%% --------------------------------------------------------------------
+open(Hosts) ->
+ open(Hosts, []).
+
+open(Hosts, Opts) when list(Hosts), list(Opts) ->
+ Self = self(),
+ Pid = spawn_link(fun() -> init(Hosts, Opts, Self) end),
+ recv(Pid).
+
+%%% --------------------------------------------------------------------
+%%% Shutdown connection (and process) asynchronous.
+%%% --------------------------------------------------------------------
+
+close(Handle) when pid(Handle) ->
+ send(Handle, close).
+
+%%% --------------------------------------------------------------------
+%%% Set who we should link ourselves to
+%%% --------------------------------------------------------------------
+
+controlling_process(Handle, Pid) when pid(Handle),pid(Pid) ->
+ link(Pid),
+ send(Handle, {cnt_proc, Pid}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
+%%% Authenticate ourselves to the Directory
+%%% using simple authentication.
+%%%
+%%% Dn - The name of the entry to bind as
+%%% Passwd - The password to be used
+%%%
+%%% Returns: ok | {error, Error}
+%%% --------------------------------------------------------------------
+simple_bind(Handle, Dn, Passwd) when pid(Handle) ->
+ send(Handle, {simple_bind, Dn, Passwd}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
+%%% 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 pid(Handle),list(Entry),list(Attributes) ->
+ send(Handle, {add, Entry, add_attrs(Attributes)}),
+ recv(Handle).
+
+%%% 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 pid(Handle), list(Entry) ->
+ send(Handle, {delete, Entry}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
+%%% 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 pid(Handle), list(Object), list(Mods) ->
+ send(Handle, {modify, Object, Mods}),
+ recv(Handle).
+
+%%%
+%%% 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 pid(Handle),list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) ->
+ send(Handle, {modify_dn, Entry, NewRDN,
+ bool_p(DelOldRDN), optional(NewSup)}),
+ recv(Handle).
+
+%%% 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 pid(Handle), record(A, eldap_search) ->
+ call_search(Handle, A);
+search(Handle, L) when pid(Handle), list(L) ->
+ case catch parse_search_args(L) of
+ {error, Emsg} -> {error, Emsg};
+ A when record(A, eldap_search) -> call_search(Handle, A)
+ end.
+
+call_search(Handle, A) ->
+ send(Handle, {search, A}),
+ recv(Handle).
+
+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|_],_) ->
+ 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}.
+
+
+%%%
+%%% A substring filter seem to be based on a pattern:
+%%%
+%%% InitValue*AnyValue*FinalValue
+%%%
+%%% where all three parts seem to be optional (at least when
+%%% talking with an OpenLDAP server). Thus, the arguments
+%%% to substrings/2 looks like this:
+%%%
+%%% Type ::= string( <attribute> )
+%%% SubStr ::= listof( {initial,Value} | {any,Value}, {final,Value})
+%%%
+%%% Example: substrings("sn",[{initial,"To"},{any,"kv"},{final,"st"}])
+%%% will match entries containing: 'sn: Tornkvist'
+%%%
+substrings(Type, SubStr) when list(Type), list(SubStr) ->
+ Ss = {'SubstringFilter_substrings',v_substr(SubStr)},
+ {substrings,#'SubstringFilter'{type = Type,
+ substrings = Ss}}.
+
+%%% --------------------------------------------------------------------
+%%% Worker process. We keep track of a controlling process to
+%%% be able to terminate together with it.
+%%% --------------------------------------------------------------------
+
+init(Hosts, Opts, Cpid) ->
+ Data = parse_args(Opts, Cpid, #eldap{}),
+ case try_connect(Hosts, Data) of
+ {ok,Data2} ->
+ send(Cpid, {ok,self()}),
+ put(req_timeout, Data#eldap.timeout), % kludge...
+ loop(Cpid, Data2);
+ Else ->
+ send(Cpid, Else),
+ unlink(Cpid),
+ exit(Else)
+ end.
+
+parse_args([{port, Port}|T], Cpid, Data) when integer(Port) ->
+ parse_args(T, Cpid, Data#eldap{port = Port});
+parse_args([{timeout, Timeout}|T], Cpid, Data) when integer(Timeout),Timeout>0 ->
+ parse_args(T, Cpid, Data#eldap{timeout = Timeout});
+parse_args([{anon_auth, true}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data#eldap{anon_auth = false});
+parse_args([{anon_auth, _}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data);
+parse_args([{ssl, true}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data#eldap{use_tls = true});
+parse_args([{ssl, _}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data);
+parse_args([{log, F}|T], Cpid, Data) when function(F) ->
+ parse_args(T, Cpid, Data#eldap{log = F});
+parse_args([{log, _}|T], Cpid, Data) ->
+ parse_args(T, Cpid, Data);
+parse_args([H|_], Cpid, _) ->
+ send(Cpid, {error,{wrong_option,H}}),
+ exit(wrong_option);
+parse_args([], _, Data) ->
+ Data.
+
+%%% Try to connect to the hosts in the listed order,
+%%% and stop with the first one to which a successful
+%%% connection is made.
+
+try_connect([Host|Hosts], Data) ->
+ TcpOpts = [{packet, asn1}, {active,false}],
+ case do_connect(Host, Data, TcpOpts) of
+ {ok,Fd} -> {ok,Data#eldap{host = Host, fd = Fd}};
+ _ -> try_connect(Hosts, Data)
+ end;
+try_connect([],_) ->
+ {error,"connect failed"}.
+
+do_connect(Host, Data, Opts) when Data#eldap.use_tls == false ->
+ gen_tcp:connect(Host, Data#eldap.port, Opts, Data#eldap.timeout);
+do_connect(Host, Data, Opts) when Data#eldap.use_tls == true ->
+ Vsn = erlang:system_info(version),
+ if Vsn >= "5.3" ->
+ %% In R9C, but not in R9B
+ {_,_,X} = erlang:now(),
+ ssl:seed("bkrlnateqqo" ++ integer_to_list(X));
+ true -> true
+ end,
+ ssl:connect(Host, Data#eldap.port, [{verify,0}|Opts]).
+
+
+loop(Cpid, Data) ->
+ receive
+
+ {From, {search, A}} ->
+ {Res,NewData} = do_search(Data, A),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {modify, Obj, Mod}} ->
+ {Res,NewData} = do_modify(Data, Obj, Mod),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {modify_dn, Obj, NewRDN, DelOldRDN, NewSup}} ->
+ {Res,NewData} = do_modify_dn(Data, Obj, NewRDN, DelOldRDN, NewSup),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {add, Entry, Attrs}} ->
+ {Res,NewData} = do_add(Data, Entry, Attrs),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {delete, Entry}} ->
+ {Res,NewData} = do_delete(Data, Entry),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {simple_bind, Dn, Passwd}} ->
+ {Res,NewData} = do_simple_bind(Data, Dn, Passwd),
+ send(From,Res),
+ loop(Cpid, NewData);
+
+ {From, {cnt_proc, NewCpid}} ->
+ unlink(Cpid),
+ send(From,ok),
+ ?PRINT("New Cpid is: ~p~n",[NewCpid]),
+ loop(NewCpid, Data);
+
+ {From, close} ->
+ unlink(Cpid),
+ exit(closed);
+
+ {Cpid, 'EXIT', Reason} ->
+ ?PRINT("Got EXIT from Cpid, reason=~p~n",[Reason]),
+ exit(Reason);
+
+ _XX ->
+ ?PRINT("loop got: ~p~n",[_XX]),
+ loop(Cpid, Data)
+
+ end.
+
+%%% --------------------------------------------------------------------
+%%% bindRequest
+%%% --------------------------------------------------------------------
+
+%%% Authenticate ourselves to the directory using
+%%% simple authentication.
+
+do_simple_bind(Data, anon, anon) -> %% For testing
+ do_the_simple_bind(Data, "", "");
+do_simple_bind(Data, Dn, _Passwd) when Dn=="",Data#eldap.anon_auth==false ->
+ {{error,anonymous_auth},Data};
+do_simple_bind(Data, _Dn, Passwd) when Passwd=="",Data#eldap.anon_auth==false ->
+ {{error,anonymous_auth},Data};
+do_simple_bind(Data, Dn, Passwd) ->
+ do_the_simple_bind(Data, Dn, Passwd).
+
+do_the_simple_bind(Data, Dn, Passwd) ->
+ case catch exec_simple_bind(Data#eldap{binddn = Dn,
+ passwd = Passwd,
+ id = bump_id(Data)}) of
+ {ok,NewData} -> {ok,NewData};
+ {error,Emsg} -> {{error,Emsg},Data};
+ Else -> {{error,Else},Data}
+ end.
+
+exec_simple_bind(Data) ->
+ Req = #'BindRequest'{version = Data#eldap.version,
+ name = Data#eldap.binddn,
+ authentication = {simple, Data#eldap.passwd}},
+ log2(Data, "bind request = ~p~n", [Req]),
+ Reply = request(Data#eldap.fd, Data, Data#eldap.id, {bindRequest, Req}),
+ log2(Data, "bind reply = ~p~n", [Reply]),
+ exec_simple_bind_reply(Data, Reply).
+
+exec_simple_bind_reply(Data, {ok,Msg}) when
+ Msg#'LDAPMessage'.messageID == Data#eldap.id ->
+ case Msg#'LDAPMessage'.protocolOp of
+ {bindResponse, Result} ->
+ case Result#'BindResponse'.resultCode of
+ success -> {ok,Data};
+ Error -> {error, Error}
+ end;
+ Other -> {error, Other}
+ end;
+exec_simple_bind_reply(_, Error) ->
+ {error, Error}.
+
+
+%%% --------------------------------------------------------------------
+%%% searchRequest
+%%% --------------------------------------------------------------------
+
+do_search(Data, A) ->
+ case catch do_search_0(Data, A) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,Res,Ref,NewData} -> {{ok,polish(Res, Ref)},NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+%%%
+%%% Polish the returned search result
+%%%
+
+polish(Res, Ref) ->
+ R = polish_result(Res),
+ %%% No special treatment of referrals at the moment.
+ #eldap_search_result{entries = R,
+ referrals = Ref}.
+
+polish_result([H|T]) when record(H, 'SearchResultEntry') ->
+ ObjectName = H#'SearchResultEntry'.objectName,
+ F = fun({_,A,V}) -> {A,V} end,
+ Attrs = lists:map(F, H#'SearchResultEntry'.attributes),
+ [#eldap_entry{object_name = ObjectName,
+ attributes = Attrs}|
+ polish_result(T)];
+polish_result([]) ->
+ [].
+
+do_search_0(Data, A) ->
+ Req = #'SearchRequest'{baseObject = A#eldap_search.base,
+ scope = v_scope(A#eldap_search.scope),
+ derefAliases = neverDerefAliases,
+ sizeLimit = 0, % no size limit
+ timeLimit = v_timeout(A#eldap_search.timeout),
+ typesOnly = v_bool(A#eldap_search.types_only),
+ filter = v_filter(A#eldap_search.filter),
+ attributes = v_attributes(A#eldap_search.attributes)
+ },
+ Id = bump_id(Data),
+ collect_search_responses(Data#eldap{id=Id}, Req, Id).
+
+%%% The returned answers cames in one packet per entry
+%%% mixed with possible referals
+
+collect_search_responses(Data, Req, ID) ->
+ S = Data#eldap.fd,
+ log2(Data, "search request = ~p~n", [Req]),
+ send_request(S, Data, ID, {searchRequest, Req}),
+ Resp = recv_response(S, Data),
+ log2(Data, "search reply = ~p~n", [Resp]),
+ collect_search_responses(Data, S, ID, Resp, [], []).
+
+collect_search_responses(Data, S, ID, {ok,Msg}, Acc, Ref)
+ when record(Msg,'LDAPMessage') ->
+ case Msg#'LDAPMessage'.protocolOp of
+ {'searchResDone',R} when R#'LDAPResult'.resultCode == success ->
+ log2(Data, "search reply = searchResDone ~n", []),
+ {ok,Acc,Ref,Data};
+ {'searchResEntry',R} when record(R,'SearchResultEntry') ->
+ Resp = recv_response(S, Data),
+ log2(Data, "search reply = ~p~n", [Resp]),
+ collect_search_responses(Data, S, ID, Resp, [R|Acc], Ref);
+ {'searchResRef',R} ->
+ %% At the moment we don't do anyting sensible here since
+ %% I haven't been able to trigger the server to generate
+ %% a response like this.
+ Resp = recv_response(S, Data),
+ log2(Data, "search reply = ~p~n", [Resp]),
+ collect_search_responses(Data, S, ID, Resp, Acc, [R|Ref]);
+ Else ->
+ throw({error,Else})
+ end;
+collect_search_responses(_, _, _, Else, _, _) ->
+ throw({error,Else}).
+
+%%% --------------------------------------------------------------------
+%%% addRequest
+%%% --------------------------------------------------------------------
+
+do_add(Data, Entry, Attrs) ->
+ case catch do_add_0(Data, Entry, Attrs) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_add_0(Data, Entry, Attrs) ->
+ Req = #'AddRequest'{entry = Entry,
+ attributes = Attrs},
+ S = Data#eldap.fd,
+ Id = bump_id(Data),
+ log2(Data, "add request = ~p~n", [Req]),
+ Resp = request(S, Data, Id, {addRequest, Req}),
+ log2(Data, "add reply = ~p~n", [Resp]),
+ check_reply(Data#eldap{id = Id}, Resp, addResponse).
+
+
+%%% --------------------------------------------------------------------
+%%% deleteRequest
+%%% --------------------------------------------------------------------
+
+do_delete(Data, Entry) ->
+ case catch do_delete_0(Data, Entry) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_delete_0(Data, Entry) ->
+ S = Data#eldap.fd,
+ Id = bump_id(Data),
+ log2(Data, "del request = ~p~n", [Entry]),
+ Resp = request(S, Data, Id, {delRequest, Entry}),
+ log2(Data, "del reply = ~p~n", [Resp]),
+ check_reply(Data#eldap{id = Id}, Resp, delResponse).
+
+
+%%% --------------------------------------------------------------------
+%%% modifyRequest
+%%% --------------------------------------------------------------------
+
+do_modify(Data, Obj, Mod) ->
+ case catch do_modify_0(Data, Obj, Mod) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_modify_0(Data, Obj, Mod) ->
+ v_modifications(Mod),
+ Req = #'ModifyRequest'{object = Obj,
+ modification = Mod},
+ S = Data#eldap.fd,
+ Id = bump_id(Data),
+ log2(Data, "modify request = ~p~n", [Req]),
+ Resp = request(S, Data, Id, {modifyRequest, Req}),
+ log2(Data, "modify reply = ~p~n", [Resp]),
+ check_reply(Data#eldap{id = Id}, Resp, modifyResponse).
+
+%%% --------------------------------------------------------------------
+%%% modifyDNRequest
+%%% --------------------------------------------------------------------
+
+do_modify_dn(Data, Entry, NewRDN, DelOldRDN, NewSup) ->
+ case catch do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) ->
+ Req = #'ModifyDNRequest'{entry = Entry,
+ newrdn = NewRDN,
+ deleteoldrdn = DelOldRDN,
+ newSuperior = NewSup},
+ S = Data#eldap.fd,
+ Id = bump_id(Data),
+ log2(Data, "modify DN request = ~p~n", [Req]),
+ Resp = request(S, Data, Id, {modDNRequest, Req}),
+ log2(Data, "modify DN reply = ~p~n", [Resp]),
+ check_reply(Data#eldap{id = Id}, Resp, modDNResponse).
+
+%%% --------------------------------------------------------------------
+%%% Send an LDAP request and receive the answer
+%%% --------------------------------------------------------------------
+
+request(S, Data, ID, Request) ->
+ send_request(S, Data, ID, Request),
+ recv_response(S, Data).
+
+send_request(S, Data, ID, Request) ->
+ Message = #'LDAPMessage'{messageID = ID,
+ protocolOp = Request},
+ {ok,Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
+ case do_send(S, Data, Bytes) of
+ {error,Reason} -> throw({gen_tcp_error,Reason});
+ Else -> Else
+ end.
+
+do_send(S, Data, Bytes) when Data#eldap.use_tls == false ->
+ gen_tcp:send(S, Bytes);
+do_send(S, Data, Bytes) when Data#eldap.use_tls == true ->
+ ssl:send(S, Bytes).
+
+do_recv(S, Data, Len, Timeout) when Data#eldap.use_tls == false ->
+ gen_tcp:recv(S, Len, Timeout);
+do_recv(S, Data, Len, Timeout) when Data#eldap.use_tls == true ->
+ ssl:recv(S, Len, Timeout).
+
+recv_response(S, Data) ->
+ Timeout = get(req_timeout), % kludge...
+ case do_recv(S, Data, 0, Timeout) of
+ {ok, Packet} ->
+ check_tag(Packet),
+ case asn1rt:decode('ELDAPv3', 'LDAPMessage', Packet) of
+ {ok,Resp} -> {ok,Resp};
+ Error -> throw(Error)
+ end;
+ {error,Reason} ->
+ throw({gen_tcp_error, Reason});
+ Error ->
+ throw(Error)
+ end.
+
+%%% Sanity check of received packet
+check_tag(Data) ->
+ case asn1rt_ber_bin:decode_tag(b2l(Data)) of
+ {_Tag, Data1, _Rb} ->
+ case asn1rt_ber_bin:decode_length(b2l(Data1)) of
+ {{_Len, _Data2}, _Rb2} -> ok;
+ _ -> throw({error,decoded_tag_length})
+ end;
+ _ -> throw({error,decoded_tag})
+ end.
+
+%%% Check for expected kind of reply
+check_reply(Data, {ok,Msg}, Op) when
+ Msg#'LDAPMessage'.messageID == Data#eldap.id ->
+ case Msg#'LDAPMessage'.protocolOp of
+ {Op, Result} ->
+ case Result#'LDAPResult'.resultCode of
+ success -> {ok,Data};
+ Error -> {error, Error}
+ end;
+ Other -> {error, Other}
+ end;
+check_reply(_, Error, _) ->
+ {error, Error}.
+
+
+%%% --------------------------------------------------------------------
+%%% Verify the input data
+%%% --------------------------------------------------------------------
+
+v_filter({'and',L}) -> {'and',L};
+v_filter({'or', L}) -> {'or',L};
+v_filter({'not',L}) -> {'not',L};
+v_filter({equalityMatch,AV}) -> {equalityMatch,AV};
+v_filter({greaterOrEqual,AV}) -> {greaterOrEqual,AV};
+v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV};
+v_filter({approxMatch,AV}) -> {approxMatch,AV};
+v_filter({present,A}) -> {present,A};
+v_filter({substrings,S}) when record(S,'SubstringFilter') -> {substrings,S};
+v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}).
+
+v_modifications(Mods) ->
+ F = fun({_,Op,_}) ->
+ case lists:member(Op,[add,delete,replace]) of
+ true -> true;
+ _ -> throw({error,{mod_operation,Op}})
+ end
+ end,
+ lists:foreach(F, Mods).
+
+v_substr([{Key,Str}|T]) when list(Str),Key==initial;Key==any;Key==final ->
+ [{Key,Str}|v_substr(T)];
+v_substr([H|_]) ->
+ throw({error,{substring_arg,H}});
+v_substr([]) ->
+ [].
+v_scope(baseObject) -> baseObject;
+v_scope(singleLevel) -> singleLevel;
+v_scope(wholeSubtree) -> wholeSubtree;
+v_scope(_Scope) -> throw({error,concat(["unknown scope: ",_Scope])}).
+
+v_bool(true) -> true;
+v_bool(false) -> false;
+v_bool(_Bool) -> throw({error,concat(["not Boolean: ",_Bool])}).
+
+v_timeout(I) when integer(I), I>=0 -> I;
+v_timeout(_I) -> throw({error,concat(["timeout not positive integer: ",_I])}).
+
+v_attributes(Attrs) ->
+ F = fun(A) when list(A) -> A;
+ (A) -> throw({error,concat(["attribute not String: ",A])})
+ end,
+ lists:map(F,Attrs).
+
+
+%%% --------------------------------------------------------------------
+%%% Log routines. Call a user provided log routine F.
+%%% --------------------------------------------------------------------
+
+log1(Data, Str, Args) -> log(Data, Str, Args, 1).
+log2(Data, Str, Args) -> log(Data, Str, Args, 2).
+
+log(Data, Str, Args, Level) when function(Data#eldap.log) ->
+ catch (Data#eldap.log)(Level, Str, Args);
+log(_, _, _, _) ->
+ ok.
+
+
+%%% --------------------------------------------------------------------
+%%% Misc. routines
+%%% --------------------------------------------------------------------
+
+send(To,Msg) -> To ! {self(),Msg}.
+recv(From) -> receive {From,Msg} -> Msg end.
+
+ldap_closed_p(Data, Emsg) when Data#eldap.use_tls == true ->
+ %% Check if the SSL socket seems to be alive or not
+ case catch ssl:sockname(Data#eldap.fd) of
+ {error, _} ->
+ ssl:close(Data#eldap.fd),
+ {error, ldap_closed};
+ {ok, _} ->
+ {error, Emsg};
+ _ ->
+ %% sockname crashes if the socket pid is not alive
+ {error, ldap_closed}
+ end;
+ldap_closed_p(Data, Emsg) ->
+ %% non-SSL socket
+ case inet:port(Data#eldap.fd) of
+ {error,_} -> {error, ldap_closed};
+ _ -> {error,Emsg}
+ end.
+
+bump_id(Data) -> Data#eldap.id + 1.
+
+
+%%% --------------------------------------------------------------------
+%%% parse_dn/1 - Implementation of RFC 2253:
+%%%
+%%% "UTF-8 String Representation of Distinguished Names"
+%%%
+%%% Test cases:
+%%%
+%%% The simplest case:
+%%%
+%%% 1> eldap:parse_dn("CN=Steve Kille,O=Isode Limited,C=GB").
+%%% {ok,[[{attribute_type_and_value,"CN","Steve Kille"}],
+%%% [{attribute_type_and_value,"O","Isode Limited"}],
+%%% [{attribute_type_and_value,"C","GB"}]]}
+%%%
+%%% The first RDN is multi-valued:
+%%%
+%%% 2> eldap:parse_dn("OU=Sales+CN=J. Smith,O=Widget Inc.,C=US").
+%%% {ok,[[{attribute_type_and_value,"OU","Sales"},
+%%% {attribute_type_and_value,"CN","J. Smith"}],
+%%% [{attribute_type_and_value,"O","Widget Inc."}],
+%%% [{attribute_type_and_value,"C","US"}]]}
+%%%
+%%% Quoting a comma:
+%%%
+%%% 3> eldap:parse_dn("CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB").
+%%% {ok,[[{attribute_type_and_value,"CN","L. Eagle"}],
+%%% [{attribute_type_and_value,"O","Sue\\, Grabbit and Runn"}],
+%%% [{attribute_type_and_value,"C","GB"}]]}
+%%%
+%%% A value contains a carriage return:
+%%%
+%%% 4> eldap:parse_dn("CN=Before
+%%% 4> After,O=Test,C=GB").
+%%% {ok,[[{attribute_type_and_value,"CN","Before\nAfter"}],
+%%% [{attribute_type_and_value,"O","Test"}],
+%%% [{attribute_type_and_value,"C","GB"}]]}
+%%%
+%%% 5> eldap:parse_dn("CN=Before\\0DAfter,O=Test,C=GB").
+%%% {ok,[[{attribute_type_and_value,"CN","Before\\0DAfter"}],
+%%% [{attribute_type_and_value,"O","Test"}],
+%%% [{attribute_type_and_value,"C","GB"}]]}
+%%%
+%%% An RDN in OID form:
+%%%
+%%% 6> eldap:parse_dn("1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB").
+%%% {ok,[[{attribute_type_and_value,"1.3.6.1.4.1.1466.0","#04024869"}],
+%%% [{attribute_type_and_value,"O","Test"}],
+%%% [{attribute_type_and_value,"C","GB"}]]}
+%%%
+%%%
+%%% --------------------------------------------------------------------
+
+parse_dn("") -> % empty DN string
+ {ok,[]};
+parse_dn([H|_] = Str) when H=/=$, -> % 1:st name-component !
+ case catch parse_name(Str,[]) of
+ {'EXIT',Reason} -> {parse_error,internal_error,Reason};
+ Else -> Else
+ end.
+
+parse_name("",Acc) ->
+ {ok,lists:reverse(Acc)};
+parse_name([$,|T],Acc) -> % N:th name-component !
+ parse_name(T,Acc);
+parse_name(Str,Acc) ->
+ {Rest,NameComponent} = parse_name_component(Str),
+ parse_name(Rest,[NameComponent|Acc]).
+
+parse_name_component(Str) ->
+ parse_name_component(Str,[]).
+
+parse_name_component(Str,Acc) ->
+ case parse_attribute_type_and_value(Str) of
+ {[$+|Rest], ATV} ->
+ parse_name_component(Rest,[ATV|Acc]);
+ {Rest,ATV} ->
+ {Rest,lists:reverse([ATV|Acc])}
+ end.
+
+parse_attribute_type_and_value(Str) ->
+ case parse_attribute_type(Str) of
+ {Rest,[]} ->
+ error(expecting_attribute_type,Str);
+ {Rest,Type} ->
+ Rest2 = parse_equal_sign(Rest),
+ {Rest3,Value} = parse_attribute_value(Rest2),
+ {Rest3,{attribute_type_and_value,Type,Value}}
+ end.
+
+-define(IS_ALPHA(X) , X>=$a,X=<$z;X>=$A,X=<$Z ).
+-define(IS_DIGIT(X) , X>=$0,X=<$9 ).
+-define(IS_SPECIAL(X) , X==$,;X==$=;X==$+;X==$<;X==$>;X==$#;X==$; ).
+-define(IS_QUOTECHAR(X) , X=/=$\\,X=/=$" ).
+-define(IS_STRINGCHAR(X) ,
+ X=/=$,,X=/=$=,X=/=$+,X=/=$<,X=/=$>,X=/=$#,X=/=$;,?IS_QUOTECHAR(X) ).
+-define(IS_HEXCHAR(X) , ?IS_DIGIT(X);X>=$a,X=<$f;X>=$A,X=<$F ).
+
+parse_attribute_type([H|T]) when ?IS_ALPHA(H) ->
+ %% NB: It must be an error in the RFC in the definition
+ %% of 'attributeType', should be: (ALPHA *keychar)
+ {Rest,KeyChars} = parse_keychars(T),
+ {Rest,[H|KeyChars]};
+parse_attribute_type([H|_] = Str) when ?IS_DIGIT(H) ->
+ parse_oid(Str);
+parse_attribute_type(Str) ->
+ error(invalid_attribute_type,Str).
+
+
+
+%%% Is a hexstring !
+parse_attribute_value([$#,X,Y|T]) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) ->
+ {Rest,HexString} = parse_hexstring(T),
+ {Rest,[$#,X,Y|HexString]};
+%%% Is a "quotation-sequence" !
+parse_attribute_value([$"|T]) ->
+ {Rest,Quotation} = parse_quotation(T),
+ {Rest,[$"|Quotation]};
+%%% Is a stringchar , pair or Empty !
+parse_attribute_value(Str) ->
+ parse_string(Str).
+
+parse_hexstring(Str) ->
+ parse_hexstring(Str,[]).
+
+parse_hexstring([X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) ->
+ parse_hexstring(T,[Y,X|Acc]);
+parse_hexstring(T,Acc) ->
+ {T,lists:reverse(Acc)}.
+
+parse_quotation([$"|T]) -> % an empty: "" is ok !
+ {T,[$"]};
+parse_quotation(Str) ->
+ parse_quotation(Str,[]).
+
+%%% Parse to end of quotation
+parse_quotation([$"|T],Acc) ->
+ {T,lists:reverse([$"|Acc])};
+parse_quotation([X|T],Acc) when ?IS_QUOTECHAR(X) ->
+ parse_quotation(T,[X|Acc]);
+parse_quotation([$\\,X|T],Acc) when ?IS_SPECIAL(X) ->
+ parse_quotation(T,[X,$\\|Acc]);
+parse_quotation([$\\,$\\|T],Acc) ->
+ parse_quotation(T,[$\\,$\\|Acc]);
+parse_quotation([$\\,$"|T],Acc) ->
+ parse_quotation(T,[$",$\\|Acc]);
+parse_quotation([$\\,X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) ->
+ parse_quotation(T,[Y,X,$\\|Acc]);
+parse_quotation(T,_) ->
+ error(expecting_double_quote_mark,T).
+
+parse_string(Str) ->
+ parse_string(Str,[]).
+
+parse_string("",Acc) ->
+ {"",lists:reverse(Acc)};
+parse_string([H|T],Acc) when ?IS_STRINGCHAR(H) ->
+ parse_string(T,[H|Acc]);
+parse_string([$\\,X|T],Acc) when ?IS_SPECIAL(X) -> % is a pair !
+ parse_string(T,[X,$\\|Acc]);
+parse_string([$\\,$\\|T],Acc) -> % is a pair !
+ parse_string(T,[$\\,$\\|Acc]);
+parse_string([$\\,$" |T],Acc) -> % is a pair !
+ parse_string(T,[$" ,$\\|Acc]);
+parse_string([$\\,X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) -> % is a pair!
+ parse_string(T,[Y,X,$\\|Acc]);
+parse_string(T,Acc) ->
+ {T,lists:reverse(Acc)}.
+
+parse_equal_sign([$=|T]) -> T;
+parse_equal_sign(T) -> error(expecting_equal_sign,T).
+
+parse_keychars(Str) -> parse_keychars(Str,[]).
+
+parse_keychars([H|T],Acc) when ?IS_ALPHA(H) -> parse_keychars(T,[H|Acc]);
+parse_keychars([H|T],Acc) when ?IS_DIGIT(H) -> parse_keychars(T,[H|Acc]);
+parse_keychars([$-|T],Acc) -> parse_keychars(T,[$-|Acc]);
+parse_keychars(T,Acc) -> {T,lists:reverse(Acc)}.
+
+parse_oid(Str) -> parse_oid(Str,[]).
+
+parse_oid([H,$.|T], Acc) when ?IS_DIGIT(H) ->
+ parse_oid(T,[$.,H|Acc]);
+parse_oid([H|T], Acc) when ?IS_DIGIT(H) ->
+ parse_oid(T,[H|Acc]);
+parse_oid(T, Acc) ->
+ {T,lists:reverse(Acc)}.
+
+error(Emsg,Rest) ->
+ throw({parse_error,Emsg,Rest}).
+
+
+%%% --------------------------------------------------------------------
+%%% Parse LDAP url according to RFC 2255
+%%%
+%%% Test case:
+%%%
+%%% 2> eldap:parse_ldap_url("ldap://10.42.126.33:389/cn=Administrative%20CA,o=Post%20Danmark,c=DK?certificateRevokationList;binary").
+%%% {ok,{{10,42,126,33},389},
+%%% [[{attribute_type_and_value,"cn","Administrative%20CA"}],
+%%% [{attribute_type_and_value,"o","Post%20Danmark"}],
+%%% [{attribute_type_and_value,"c","DK"}]],
+%%% {attributes,["certificateRevokationList;binary"]}}
+%%%
+%%% --------------------------------------------------------------------
+
+parse_ldap_url("ldap://" ++ Rest1 = Str) ->
+ {Rest2,HostPort} = parse_hostport(Rest1),
+ %% Split the string into DN and Attributes+etc
+ {Sdn,Rest3} = split_string(rm_leading_slash(Rest2),$?),
+ case parse_dn(Sdn) of
+ {parse_error,internal_error,_Reason} ->
+ {parse_error,internal_error,{Str,[]}};
+ {parse_error,Emsg,Tail} ->
+ Head = get_head(Str,Tail),
+ {parse_error,Emsg,{Head,Tail}};
+ {ok,DN} ->
+ %% We stop parsing here for now and leave
+ %% 'scope', 'filter' and 'extensions' to
+ %% be implemented later if needed.
+ {_Rest4,Attributes} = parse_attributes(Rest3),
+ {ok,HostPort,DN,Attributes}
+ end.
+
+rm_leading_slash([$/|Tail]) -> Tail;
+rm_leading_slash(Tail) -> Tail.
+
+parse_attributes([$?|Tail]) ->
+ case split_string(Tail,$?) of
+ {[],Attributes} ->
+ {[],{attributes,string:tokens(Attributes,",")}};
+ {Attributes,Rest} ->
+ {Rest,{attributes,string:tokens(Attributes,",")}}
+ end.
+
+parse_hostport(Str) ->
+ {HostPort,Rest} = split_string(Str,$/),
+ case split_string(HostPort,$:) of
+ {Shost,[]} ->
+ {Rest,{parse_host(Rest,Shost),?LDAP_PORT}};
+ {Shost,[$:|Sport]} ->
+ {Rest,{parse_host(Rest,Shost),
+ parse_port(Rest,Sport)}}
+ end.
+
+parse_port(Rest,Sport) ->
+ case list_to_integer(Sport) of
+ Port when integer(Port) -> Port;
+ _ -> error(parsing_port,Rest)
+ end.
+
+parse_host(Rest,Shost) ->
+ case catch validate_host(Shost) of
+ {parse_error,Emsg,_} -> error(Emsg,Rest);
+ Host -> Host
+ end.
+
+validate_host(Shost) ->
+ case inet_parse:address(Shost) of
+ {ok,Host} -> Host;
+ _ ->
+ case inet_parse:domain(Shost) of
+ true -> Shost;
+ _ -> error(parsing_host,Shost)
+ end
+ end.
+
+
+split_string(Str,Key) ->
+ Pred = fun(X) when X==Key -> false; (_) -> true end,
+ lists:splitwith(Pred, Str).
+
+get_head(Str,Tail) ->
+ get_head(Str,Tail,[]).
+
+%%% Should always succeed !
+get_head([H|Tail],Tail,Rhead) -> lists:reverse([H|Rhead]);
+get_head([H|Rest],Tail,Rhead) -> get_head(Rest,Tail,[H|Rhead]).
+
+b2l(B) when binary(B) -> B;
+b2l(L) when list(L) -> list_to_binary(L).
+
diff --git src/eldap/eldap.hrl src/eldap/eldap.hrl
new file mode 100644
index 0000000..ee5ad2f
--- /dev/null
+++ src/eldap/eldap.hrl
@@ -0,0 +1,32 @@
+-ifndef( _ELDAP_HRL ).
+-define( _ELDAP_HRL , 1 ).
+
+%%%
+%%% Search input parameters
+%%%
+-record(eldap_search, {
+ base = [], % Baseobject
+ filter = [], % Search conditions
+ scope, % Search scope
+ attributes = [], % Attributes to be returned
+ types_only = false, % Return types+values or types
+ timeout = 0 % Timelimit for search
+ }).
+
+%%%
+%%% Returned search result
+%%%
+-record(eldap_search_result, {
+ entries = [], % List of #eldap_entry{} records
+ referrals = [] % List of referrals
+ }).
+
+%%%
+%%% LDAP entry
+%%%
+-record(eldap_entry, {
+ object_name = "", % The DN for the entry
+ attributes = [] % List of {Attribute, Value} pairs
+ }).
+
+-endif.
diff --git utils/Makefile.am utils/Makefile.am
index 379c1eb..ed2ecff 100644
--- utils/Makefile.am
+++ utils/Makefile.am
@@ -25,6 +25,7 @@ run: ../bin/couchdb.tpl
-e "s|%localini%|local_dev.ini|g" \
-e "s|%localerlanglibdir%|foo \
-pa $(abs_top_builddir)\/src\/couchdb \
+ -pa $(abs_top_builddir)\/src\/eldap \
-pa $(abs_top_builddir)\/src\/erlang-oauth \
-pa $(abs_top_builddir)\/src\/ibrowse \
-pa $(abs_top_builddir)\/src\/mochiweb|g" \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment