24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-16 22:05:29 +02:00

* src/ejabberd_ctl.erl: New option to require auth in ejabberdctl

and restrict what commands and arguments can execute (EJAB-910)
* src/ejabberd_config.erl: Likewise

SVN Revision: 2024
This commit is contained in:
Badlop 2009-04-17 13:48:59 +00:00
parent b451f07801
commit fd967d6976
3 changed files with 38 additions and 15 deletions

View File

@ -1,5 +1,9 @@
2009-04-17 Badlop <badlop@process-one.net>
* src/ejabberd_ctl.erl: New option to require auth in ejabberdctl
and restrict what commands and arguments can execute (EJAB-910)
* src/ejabberd_config.erl: Likewise
* src/ejabberd_commands.erl: API to restrict who can execute what
commands and arguments (EJAB-910)

View File

@ -376,6 +376,8 @@ process_term(Term, State) ->
add_option(watchdog_large_heap, LH, State);
{registration_timeout, Timeout} ->
add_option(registration_timeout, Timeout, State);
{ejabberdctl_access_commands, ACs} ->
add_option(ejabberdctl_access_commands, ACs, State);
{loglevel, Loglevel} ->
ejabberd_loglevel:set(Loglevel),
State;

View File

@ -50,7 +50,7 @@
-export([start/0,
init/0,
process/1,
process2/1,
process2/2,
register_commands/3,
unregister_commands/3]).
@ -194,14 +194,20 @@ process(["help" | Mode]) ->
end;
process(Args) ->
{String, Code} = process2(Args),
AccessCommands = get_accesscommands(),
{String, Code} = process2(Args, AccessCommands),
io:format(String),
io:format("\n"),
Code.
%% @spec (Args::[string()]) -> {String::string(), Code::integer()}
process2(Args) ->
case try_run_ctp(Args) of
%% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()}
process2(["--auth", User, Server, Pass | Args], AccessCommands) ->
process2(Args, {User, Server, Pass}, AccessCommands);
process2(Args, AccessCommands) ->
process2(Args, noauth, AccessCommands).
process2(Args, Auth, AccessCommands) ->
case try_run_ctp(Args, Auth, AccessCommands) of
{String, wrong_command_arguments}
when is_list(String) ->
io:format(lists:flatten(["\n" | String]++["\n"])),
@ -221,16 +227,22 @@ process2(Args) ->
{"Erroneous result: " ++ io_lib:format("~p", [Other]), ?STATUS_ERROR}
end.
get_accesscommands() ->
case ejabberd_config:get_local_option(ejabberdctl_access_commands) of
ACs when is_list(ACs) -> ACs;
_ -> []
end.
%%-----------------------------
%% Command calling
%%-----------------------------
%% @spec (Args::[string()]) -> string() | integer() | {string(), integer()}
try_run_ctp(Args) ->
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()}
try_run_ctp(Args, Auth, AccessCommands) ->
try ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of
false when Args /= [] ->
try_call_command(Args);
try_call_command(Args, Auth, AccessCommands);
false ->
print_usage(),
{"", ?STATUS_USAGE};
@ -247,9 +259,9 @@ try_run_ctp(Args) ->
{io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE}
end.
%% @spec (Args::[string()]) -> string() | integer() | {string(), integer()}
try_call_command(Args) ->
try call_command(Args) of
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()}
try_call_command(Args, Auth, AccessCommands) ->
try call_command(Args, Auth, AccessCommands) of
{error, command_unknown} ->
{io_lib:format("Error: command ~p not known.", [hd(Args)]), ?STATUS_ERROR};
{error, wrong_number_parameters} ->
@ -262,8 +274,8 @@ try_call_command(Args) ->
{io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p", [A, Why, Stack]), ?STATUS_ERROR}
end.
%% @spec (Args::[string()]) -> string() | integer() | {string(), integer()} | {error, ErrorType}
call_command([CmdString | Args]) ->
%% @spec (Args::[string()], Auth) -> string() | integer() | {string(), integer()} | {error, ErrorType}
call_command([CmdString | Args], Auth, AccessCommands) ->
{ok, CmdStringU, _} = regexp:gsub(CmdString, "-", "_"),
Command = list_to_atom(CmdStringU),
case ejabberd_commands:get_command_format(Command) of
@ -272,7 +284,7 @@ call_command([CmdString | Args]) ->
{ArgsFormat, ResultFormat} ->
case (catch format_args(Args, ArgsFormat)) of
ArgsFormatted when is_list(ArgsFormatted) ->
Result = ejabberd_commands:execute_command(Command,
Result = ejabberd_commands:execute_command(AccessCommands, Auth, Command,
ArgsFormatted),
format_result(Result, ResultFormat);
{'EXIT', {function_clause,[{lists,zip,[A1, A2]} | _]}} ->
@ -317,6 +329,9 @@ format_arg(Arg, Format) ->
%% Format result
%%-----------------------------
format_result({error, ErrorAtom}, _) ->
{io_lib:format("Error: ~p", [ErrorAtom]), make_status(error)};
format_result(Atom, {_Name, atom}) ->
io_lib:format("~p", [Atom]);
@ -430,7 +445,9 @@ print_usage(HelpMode, MaxC, ShCode) ->
get_list_ctls(),
?PRINT(
["Usage: ", ?B("ejabberdctl"), " [--node ", ?U("nodename"), "] ", ?U("command"), " [options]\n"
["Usage: ", ?B("ejabberdctl"), " [--node ", ?U("nodename"), "] [--auth ",
?U("user"), " ", ?U("host"), " ", ?U("password"), "] ",
?U("command"), " [", ?U("options"), "]\n"
"\n"
"Available commands in this ejabberd node:\n"], []),
print_usage_commands(HelpMode, MaxC, ShCode, AllCommands),