aboutsummaryrefslogtreecommitdiffstats
path: root/lib/eldap
diff options
context:
space:
mode:
Diffstat (limited to 'lib/eldap')
-rw-r--r--lib/eldap/asn1/ELDAPv3.asn112
-rw-r--r--lib/eldap/doc/src/eldap.xml46
-rw-r--r--lib/eldap/src/eldap.erl77
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl12
-rw-r--r--lib/eldap/vsn.mk2
5 files changed, 143 insertions, 6 deletions
diff --git a/lib/eldap/asn1/ELDAPv3.asn1 b/lib/eldap/asn1/ELDAPv3.asn1
index 72b87d7221..3fe7e815cc 100644
--- a/lib/eldap/asn1/ELDAPv3.asn1
+++ b/lib/eldap/asn1/ELDAPv3.asn1
@@ -274,5 +274,17 @@ IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
responseName [0] LDAPOID OPTIONAL,
responseValue [1] OCTET STRING OPTIONAL }
+-- Extended syntax for Password Modify (RFC 3062, Section 2)
+
+-- passwdModifyOID OBJECT IDENTIFIER ::= 1.3.6.1.4.1.4203.1.11.1
+
+PasswdModifyRequestValue ::= SEQUENCE {
+ userIdentity [0] OCTET STRING OPTIONAL,
+ oldPasswd [1] OCTET STRING OPTIONAL,
+ newPasswd [2] OCTET STRING OPTIONAL }
+
+PasswdModifyResponseValue ::= SEQUENCE {
+ genPasswd [0] OCTET STRING OPTIONAL }
+
END
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index fbeb4540b7..253ba7c2ff 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -218,6 +218,46 @@ filter() See present/1, substrings/2,
</desc>
</func>
<func>
+ <name>modify_password(Handle, Dn, NewPasswd) -> ok | {ok, GenPasswd} | {error, Reason}</name>
+ <fsummary>Modify the password of a user.</fsummary>
+ <type>
+ <v>Dn = string()</v>
+ <v>NewPasswd = string()</v>
+ </type>
+ <desc>
+ <p>Modify the password of a user. See <seealso marker="#modify_password/4">modify_password/4</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>modify_password(Handle, Dn, NewPasswd, OldPasswd) -> ok | {ok, GenPasswd} | {error, Reason}</name>
+ <fsummary>Modify the password of a user.</fsummary>
+ <type>
+ <v>Dn = string()</v>
+ <v>NewPasswd = string()</v>
+ <v>OldPasswd = string()</v>
+ <v>GenPasswd = string()</v>
+ </type>
+ <desc>
+ <p>Modify the password of a user.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>Dn</c>. The user to modify. Should be "" if the
+ modify request is for the user of the LDAP session.</p>
+ </item>
+ <item>
+ <p><c>NewPasswd</c>. The new password to set. Should be ""
+ if the server is to generate the password. In this case,
+ the result will be <c>{ok, GenPasswd}</c>.</p>
+ </item>
+ <item>
+ <p><c>OldPasswd</c>. Sometimes required by server policy
+ for a user to change their password. If not required, use
+ <seealso marker="#modify_password/3">modify_password/3</seealso>.</p>
+ </item>
+ </list>
+ </desc>
+ </func>
+ <func>
<name>modify_dn(Handle, Dn, NewRDN, DeleteOldRDN, NewSupDN) -> ok | {error, Reason}</name>
<fsummary>Modify the DN of an entry.</fsummary>
<type>
@@ -363,7 +403,11 @@ filter() See present/1, substrings/2,
<v>OptionalAttrs = [Attr]</v>
<v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v>
</type>
- <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
+ <desc> <p>Creates an extensible match filter. For example, </p>
+ <code>
+ eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))
+ </code>
+ <p>creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
</func>
<func>
<name>'and'([Filter]) -> filter()</name>
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 80718bc106..ae47c815c9 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -12,6 +12,7 @@
-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,
@@ -94,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...
@@ -507,6 +525,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);
@@ -797,6 +820,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
%%% --------------------------------------------------------------------
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index 137c61b2d9..8d754e934c 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -896,9 +896,9 @@ client_timeout(Fun, Config) ->
T = 1000,
case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of
{ok,H} ->
- T0 = now(),
+ T0 = erlang:monotonic_time(),
{error,{gen_tcp_error,timeout}} = Fun(H),
- T_op = diff(T0,now()),
+ T_op = ms_passed(T0),
ct:log("Time = ~p, Timeout spec = ~p",[T_op,T]),
if
T_op < T ->
@@ -910,8 +910,12 @@ client_timeout(Fun, Config) ->
Other -> ct:fail("eldap:open failed: ~p",[Other])
end.
-diff({M1,S1,U1},{M2,S2,U2}) ->
- ( ((M2-M1)*1000 + (S2-S1))*1000 + (U2-U1) ).
+%% Help function, elapsed milliseconds since T0
+ms_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) / 1000.
%%%----------------------------------------------------------------
init_ssl_certs_et_al(Config) ->
diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk
index adca41ed63..105a2bcdbb 100644
--- a/lib/eldap/vsn.mk
+++ b/lib/eldap/vsn.mk
@@ -1 +1 @@
-ELDAP_VSN = 1.1.1
+ELDAP_VSN = 1.2