bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk bool kick_me; /* true if username and/or ip[/mask] matches.
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ignored when the -f switch is given. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkkick_aggregate_line(struct who_context *_ctx, const struct who_line *line)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct kick_context *ctx = (struct kick_context *)_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk const bool user_match = who_line_filter_match(line, &ctx->who.filter);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen k_pid = hash_table_lookup(ctx->pids, POINTER_CAST(line->pid));
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk k_pid = p_new(ctx->who.pool, struct kick_pid, 1);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen hash_table_insert(ctx->pids, POINTER_CAST(line->pid), k_pid);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (strcmp(line->username, user->username) == 0) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk new_user.username = p_strdup(ctx->who.pool, line->username);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkkick_pid_want_kicked(struct kick_context *ctx, const struct kick_pid *k_pid,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkkick_print_kicked(struct kick_context *ctx, const bool show_warning)
6fc40674e5a33787ae7fcd47a77a77ea20977994Aki Tuomi bool cli = (ctx->conn_type == DOVEADM_CONNECTION_TYPE_CLI);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi printf("warning: other connections would also be "
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi "kicked from following users:\n");
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi printf("kicked connections from the following users:\n");
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk printf("Use the '-f' option to enforce the disconnect.\n");
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk p_array_init(&ctx->kicked_users, ctx->who.pool, 10);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, ctx->pids, &key, &k_pid)) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (kick_pid_want_kicked(ctx, k_pid, &show_enforce_warning))
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, ctx->pids, &key, &k_pid)) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (kill(k_pid->pid, SIGTERM) < 0 && errno != ESRCH) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk fprintf(stderr, "kill(%s, SIGTERM) failed: %m\n",
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomistatic void cmd_kick(struct doveadm_cmd_context *cctx)
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi if (!doveadm_cmd_param_str(cctx, "socket-path", &(ctx.who.anvil_path)))
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi ctx.who.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi (void)doveadm_cmd_param_bool(cctx, "force", &(ctx.force_kick));
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi if (!doveadm_cmd_param_array(cctx, "mask", &masks)) {
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi i_error("user and/or ip[/bits] must be specified.");
6fc40674e5a33787ae7fcd47a77a77ea20977994Aki Tuomi if (ctx.conn_type != DOVEADM_CONNECTION_TYPE_CLI) {
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi /* force-kick is a pretty ugly option. its output can't be
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi nicely translated to an API reply. it also wouldn't be very
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi useful in scripts, only for preventing a new admin from
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi accidentally kicking too many users. it's also useful only
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi in a non-recommended setup where processes are handling
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi multiple connections. so for now we'll preserve the option
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi for CLI, but always do a force-kick with non-CLI. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx.who.pool = pool_alloconly_create("kick pids", 10240);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create_direct(&ctx.pids, ctx.who.pool, 0);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi .usage = "[-a <anvil socket path>] <user mask>[|]<ip/bits>",
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki TuomiDOVEADM_CMD_PARAM('a',"socket-path",CMD_PARAM_STR,0)