ejabberd 储存离线消息 判断用户密码是否为空

ejabberd 存储离线消息 判断用户密码是否为空

今天对ejabberd服务器做了一个小小的测试,发现后台抛出

 

=ERROR REPORT==== 2011-03-29 16:53:30 ===

E(<0.18276.0>:ejabberd_auth:256) : The authentication module ejabberd_auth_odbc returned an error

when checking user "server_test_user_65475" in server "servertest.igrslabdns.com"

Error message: {noproc,

                   {p1_fsm,sync_send_event,

                       [<0.12307.1>,

                        {sql_cmd,

                            {sql_query,

                                ["select password from users where username='",

                                 "server_test_user_65475","';"]},

                            {1301,383421,845044}},

                        60000]}}



提示,我一开始不明白server_test_user_65475 我没有登录此用户,但为什么查询此用户密码了?
惯性思维害惨我了,以为查询密码 只有会在用户登录和权限判断的时候才会用。

原因:我在tsung测试脚本中添加了发现chat  offline消息。 因为离线消息是需要存储的,顺着代码看了一下,在存储离线消息调用hooks时会判断用户存在不存在, 判断条件是查询密码 是否为空。
ejabberd_sm 代码片段
 case ejabberd_auth:is_user_exists(LUser, LServer) of
                        true ->
                            is_privacy_allow(From, To, Packet) andalso
                                ejabberd_hooks:run(offline_message_hook,
                                                   LServer,
                                                   [From, To, Packet]);
                        _ ->
                            Err = jlib:make_error_reply(
                                    Packet, ?ERR_SERVICE_UNAVAILABLE),
                            ejabberd_router:route(To, From, Err)
                    end
 
ejabberd_auth 代码片段
%% Returns true if the user exists in the DB or if an anonymous user is logged
%% under the given name
is_user_exists(User, Server) ->
    lists:any(
      fun(M) ->
              case M:is_user_exists(User, Server) of
                  {error, Error} ->
                      ?ERROR_MSG("The authentication module ~p returned an "
                                 "error~nwhen checking user ~p in server ~p~n"
                                 "Error message: ~p",
                                 [M, User, Server, Error]),
                      false;
                  Else ->
                      Else
              end
      end, auth_modules(Server)).

ejabberd_auth_odbc 代码片段
%% @spec (User, Server) -> true | false | {error, Error}
is_user_exists(User, Server) ->
    case jlib:nodeprep(User) of
        error ->
            false;
        LUser ->
            Username = ejabberd_odbc:escape(LUser),
            LServer = jlib:nameprep(Server),
            try odbc_queries:get_password(LServer, Username) of
                {selected, ["password"], [{_Password}]} ->
                    true; %% Account exists
                {selected, ["password"], []} ->
                    false; %% Account does not exist
                {error, Error} ->
                    {error, Error} %% Typical error is that table doesn't exist
            catch
                _:B ->
                    {error, B} %% Typical error is database not accessible
            end
    end. 
  

D