allow inband password change (EJAB-199)

This commit is contained in:
Evgeniy Khramtsov 2010-04-19 20:57:24 +10:00
parent 1405e9d375
commit c2362db03d
4 changed files with 55 additions and 5 deletions

View File

@ -153,8 +153,14 @@ check_password(User, Server, Password) ->
check_password(User, Server, Password, _Digest, _DigestGen) ->
check_password(User, Server, Password).
set_password(_User, _Server, _Password) ->
{error, not_allowed}.
set_password(User, Server, Password) ->
{ok, State} = eldap_utils:get_state(Server, ?MODULE),
case find_user_dn(User, State) of
false ->
{error, user_not_found};
DN ->
eldap_pool:modify_passwd(State#state.eldap_id, DN, Password)
end.
%% @spec (User, Server, Password) -> {error, not_allowed}
try_register(_User, _Server, _Password) ->

View File

@ -286,6 +286,16 @@ ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
responseName [10] LDAPOID OPTIONAL,
response [11] OCTET STRING OPTIONAL }
passwdModifyOID LDAPOID ::= "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

View File

@ -33,9 +33,11 @@
%%% Modified by Alexey Shchepin <alexey@sevcom.net>
%%% Modified by Evgeniy Khramtsov <xram@jabber.ru>
%%% Modified by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%% Implemented queue for bind() requests to prevent pending binds.
%%% Implemented extensibleMatch/2 function.
%%% Implemented LDAP Extended Operations (currently only Password Modify
%%% is supported - RFC 3062).
%%% Modified by Christophe Romain <christophe.romain@process-one.net>
%%% Improve error case handling
@ -74,7 +76,7 @@
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
approxMatch/2,search/2,substrings/2,present/1,extensibleMatch/2,
'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
mod_replace/2, add/3, delete/2, modify_dn/5, bind/3]).
mod_replace/2, add/3, delete/2, modify_dn/5, modify_passwd/3, bind/3]).
-export([get_status/1]).
%% gen_fsm callbacks
@ -240,6 +242,10 @@ modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)
{modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)},
?CALL_TIMEOUT).
modify_passwd(Handle, DN, Passwd) when is_list(DN), is_list(Passwd) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(
Handle1, {modify_passwd, DN, Passwd}, ?CALL_TIMEOUT).
%%% --------------------------------------------------------------------
%%% Bind.
@ -695,6 +701,16 @@ gen_req({modify_dn, Entry, NewRDN, DelOldRDN, NewSup}) ->
deleteoldrdn = DelOldRDN,
newSuperior = NewSup}};
gen_req({modify_passwd, DN, Passwd}) ->
{ok, ReqVal} = asn1rt:encode(
'ELDAPv3', 'PasswdModifyRequestValue',
#'PasswdModifyRequestValue'{
userIdentity = DN,
newPasswd = Passwd}),
{extendedReq,
#'ExtendedRequest'{requestName = ?passwdModifyOID,
requestValue = list_to_binary(ReqVal)}};
gen_req({bind, RootDN, Passwd}) ->
{bindRequest,
#'BindRequest'{version = ?LDAP_VERSION,
@ -769,6 +785,11 @@ recvd_packet(Pkt, S) ->
cancel_timer(Timer),
Reply = check_bind_reply(Result, From),
{reply, Reply, From, S#eldap{dict = New_dict}};
{extendedReq, {extendedResp, Result}} ->
New_dict = dict:erase(Id, Dict),
cancel_timer(Timer),
Reply = check_extended_reply(Result, From),
{reply, Reply, From, S#eldap{dict = New_dict}};
{OtherName, OtherResult} ->
New_dict = dict:erase(Id, Dict),
cancel_timer(Timer),
@ -793,6 +814,15 @@ check_bind_reply(#'BindResponse'{resultCode = Reason}, _From) ->
check_bind_reply(Other, _From) ->
{error, Other}.
%% TODO: process reply depending on requestName:
%% this requires BER-decoding of #'ExtendedResponse'.response
check_extended_reply(#'ExtendedResponse'{resultCode = success}, _From) ->
ok;
check_extended_reply(#'ExtendedResponse'{resultCode = Reason}, _From) ->
{error, Reason};
check_extended_reply(Other, _From) ->
{error, Other}.
get_op_rec(Id, Dict) ->
case dict:find(Id, Dict) of
{ok, [{Timer, _Command, From, Name}|Res]} ->

View File

@ -31,7 +31,8 @@
-export([
start_link/7,
bind/3,
search/2
search/2,
modify_passwd/3
]).
-include("ejabberd.hrl").
@ -45,6 +46,9 @@ bind(PoolName, DN, Passwd) ->
search(PoolName, Opts) ->
do_request(PoolName, {search, [Opts]}).
modify_passwd(PoolName, DN, Passwd) ->
do_request(PoolName, {modify_passwd, [DN, Passwd]}).
start_link(Name, Hosts, Backups, Port, Rootdn, Passwd, Encrypt) ->
PoolName = make_id(Name),
pg2:create(PoolName),