aboutsummaryrefslogtreecommitdiffstats
path: root/lib/eldap/src/eldap.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/eldap/src/eldap.erl')
-rw-r--r--lib/eldap/src/eldap.erl100
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 416334e365..66f80d8d8f 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -12,9 +12,11 @@
-vc('$Id$ ').
-export([open/1,open/2,simple_bind/3,controlling_process/2,
start_tls/2, start_tls/3,
+ modify_password/3, modify_password/4,
getopts/2,
baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
+ extensibleMatch/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,
@@ -93,6 +95,23 @@ start_tls(Handle, TlsOptions, Timeout) ->
recv(Handle).
%%% --------------------------------------------------------------------
+%%% Modify the password of a user.
+%%%
+%%% Dn - Name of the entry to modify. If empty, the session user.
+%%% NewPasswd - New password. If empty, the server returns a new password.
+%%% OldPasswd - Original password for server verification, may be empty.
+%%%
+%%% Returns: ok | {ok, GenPasswd} | {error, term()}
+%%% --------------------------------------------------------------------
+modify_password(Handle, Dn, NewPasswd) ->
+ modify_password(Handle, Dn, NewPasswd, []).
+
+modify_password(Handle, Dn, NewPasswd, OldPasswd)
+ when is_pid(Handle), is_list(Dn), is_list(NewPasswd), is_list(OldPasswd) ->
+ send(Handle, {passwd_modify,optional(Dn),optional(NewPasswd),optional(OldPasswd)}),
+ recv(Handle).
+
+%%% --------------------------------------------------------------------
%%% Ask for option values on the socket.
%%% Warning: This is an undocumented function for testing purposes only.
%%% Use at own risk...
@@ -350,6 +369,27 @@ substrings(Type, SubStr) when is_list(Type), is_list(SubStr) ->
{substrings,#'SubstringFilter'{type = Type,
substrings = Ss}}.
+%%%
+%%% Filter for extensibleMatch
+%%%
+extensibleMatch(MatchValue, OptArgs) ->
+ MatchingRuleAssertion =
+ mra(OptArgs, #'MatchingRuleAssertion'{matchValue = MatchValue}),
+ {extensibleMatch, MatchingRuleAssertion}.
+
+mra([{matchingRule,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{matchingRule=Val});
+mra([{type,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{type=Val});
+mra([{dnAttributes,true}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"});
+mra([{dnAttributes,false}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"});
+mra([H|_], _) ->
+ throw({error,{extensibleMatch_arg,H}});
+mra([], Ack) ->
+ Ack.
+
%%% --------------------------------------------------------------------
%%% Worker process. We keep track of a controlling process to
%%% be able to terminate together with it.
@@ -483,6 +523,11 @@ loop(Cpid, Data) ->
send(From,Res),
?MODULE:loop(Cpid, NewData);
+ {From, {passwd_modify,Dn,NewPasswd,OldPasswd}} ->
+ {Res,NewData} = do_passwd_modify(Data, Dn, NewPasswd, OldPasswd),
+ send(From, Res),
+ ?MODULE:loop(Cpid, NewData);
+
{_From, close} ->
unlink(Cpid),
exit(closed);
@@ -773,6 +818,60 @@ do_modify_0(Data, Obj, Mod) ->
check_reply(Data#eldap{id = Id}, Resp, modifyResponse).
%%% --------------------------------------------------------------------
+%%% PasswdModifyRequest
+%%% --------------------------------------------------------------------
+
+-define(PASSWD_MODIFY_OID, "1.3.6.1.4.1.4203.1.11.1").
+
+do_passwd_modify(Data, Dn, NewPasswd, OldPasswd) ->
+ case catch do_passwd_modify_0(Data, Dn, NewPasswd, OldPasswd) of
+ {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data};
+ {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data};
+ {ok,NewData} -> {ok,NewData};
+ {ok,Passwd,NewData} -> {{ok, Passwd},NewData};
+ Else -> {ldap_closed_p(Data, Else),Data}
+ end.
+
+do_passwd_modify_0(Data, Dn, NewPasswd, OldPasswd) ->
+ Req = #'PasswdModifyRequestValue'{userIdentity = Dn,
+ oldPasswd = OldPasswd,
+ newPasswd = NewPasswd},
+ log2(Data, "modify password request = ~p~n", [Req]),
+ {ok, Bytes} = 'ELDAPv3':encode('PasswdModifyRequestValue', Req),
+ ExtReq = #'ExtendedRequest'{requestName = ?PASSWD_MODIFY_OID,
+ requestValue = Bytes},
+ Id = bump_id(Data),
+ log2(Data, "extended request = ~p~n", [ExtReq]),
+ Reply = request(Data#eldap.fd, Data, Id, {extendedReq, ExtReq}),
+ log2(Data, "modify password reply = ~p~n", [Reply]),
+ exec_passwd_modify_reply(Data#eldap{id = Id}, Reply).
+
+exec_passwd_modify_reply(Data, {ok,Msg}) when
+ Msg#'LDAPMessage'.messageID == Data#eldap.id ->
+ case Msg#'LDAPMessage'.protocolOp of
+ {extendedResp, Result} ->
+ case Result#'ExtendedResponse'.resultCode of
+ success ->
+ case Result#'ExtendedResponse'.responseValue of
+ asn1_NOVALUE ->
+ {ok, Data};
+ Value ->
+ case 'ELDAPv3':decode('PasswdModifyResponseValue', Value) of
+ {ok,#'PasswdModifyResponseValue'{genPasswd = Passwd}} ->
+ {ok, Passwd, Data};
+ Error ->
+ throw(Error)
+ end
+ end;
+ Error ->
+ {error, {response,Error}}
+ end;
+ Other -> {error, Other}
+ end;
+exec_passwd_modify_reply(_, Error) ->
+ {error, Error}.
+
+%%% --------------------------------------------------------------------
%%% modifyDNRequest
%%% --------------------------------------------------------------------
@@ -862,6 +961,7 @@ v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV};
v_filter({approxMatch,AV}) -> {approxMatch,AV};
v_filter({present,A}) -> {present,A};
v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S};
+v_filter({extensibleMatch,S}) when is_record(S,'MatchingRuleAssertion') -> {extensibleMatch,S};
v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}).
v_modifications(Mods) ->