From: Timo Sirainen Date: Mon, 17 Jan 2022 11:18:00 +0000 (+0100) Subject: doveadm kick: Add -h parameter X-Git-Tag: 2.4.0~4484 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=908c969b291c6ca9e606376e2652a86e2019f81c;p=thirdparty%2Fdovecot%2Fcore.git doveadm kick: Add -h parameter --- diff --git a/src/doveadm/doveadm-kick.c b/src/doveadm/doveadm-kick.c index 2966c80333..2f23e03403 100644 --- a/src/doveadm/doveadm-kick.c +++ b/src/doveadm/doveadm-kick.c @@ -101,22 +101,30 @@ static void kick_users_via_anvil(struct kick_context *ctx) static void cmd_kick(struct doveadm_cmd_context *cctx) { - const char *passdb_field, *const *masks; + const char *passdb_field, *dest_host, *const *masks = NULL; struct kick_context ctx; + struct ip_addr dest_ip; i_zero(&ctx); if (!doveadm_cmd_param_str(cctx, "socket-path", &(ctx.who.anvil_path))) ctx.who.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL); if (!doveadm_cmd_param_str(cctx, "passdb-field", &passdb_field)) passdb_field = NULL; - if (!doveadm_cmd_param_array(cctx, "mask", &masks)) { + + if (!doveadm_cmd_param_str(cctx, "dest-host", &dest_host)) + i_zero(&dest_ip); + else if (net_addr2ip(dest_host, &dest_ip) < 0) + i_fatal("dest-host isn't a valid IP address"); + + if (!doveadm_cmd_param_array(cctx, "mask", &masks) && + dest_ip.family == 0) { help_ver2(&doveadm_cmd_kick_ver2); return; } ctx.conn_type = cctx->conn_type; ctx.who.pool = pool_alloconly_create("kick pids", 10240); - if (who_parse_args(&ctx.who, passdb_field, masks) != 0) { + if (who_parse_args(&ctx.who, passdb_field, &dest_ip, masks) != 0) { pool_unref(&ctx.who.pool); return; } @@ -126,6 +134,7 @@ static void cmd_kick(struct doveadm_cmd_context *cctx) doveadm_print_header_simple("count"); if (ctx.who.filter.net_bits == 0 && + ctx.who.filter.dest_ip.family == 0 && strpbrk(ctx.who.filter.username, "*?") == NULL) { /* kick a single [alternative] user's all connections */ p_array_init(&ctx.kicks, ctx.who.pool, 1); @@ -144,10 +153,11 @@ static void cmd_kick(struct doveadm_cmd_context *cctx) struct doveadm_cmd_ver2 doveadm_cmd_kick_ver2 = { .name = "kick", .cmd = cmd_kick, - .usage = "[-a ] [-f ] [|]", + .usage = "[-a ] [-f ] [-h ] [|]", DOVEADM_CMD_PARAMS_START DOVEADM_CMD_PARAM('a',"socket-path",CMD_PARAM_STR,0) DOVEADM_CMD_PARAM('f',"passdb-field",CMD_PARAM_STR,0) +DOVEADM_CMD_PARAM('h',"dest-host",CMD_PARAM_STR,0) DOVEADM_CMD_PARAM('\0',"mask",CMD_PARAM_ARRAY,CMD_PARAM_FLAG_POSITIONAL) DOVEADM_CMD_PARAMS_END }; diff --git a/src/doveadm/doveadm-who.c b/src/doveadm/doveadm-who.c index 959cd7925f..93cc9188a0 100644 --- a/src/doveadm/doveadm-who.c +++ b/src/doveadm/doveadm-who.c @@ -156,8 +156,8 @@ static void who_aggregate_line(struct who_context *ctx, array_push_back(&user->pids, &line->pid); } -int who_parse_args(struct who_context *ctx, const char *alt_username_field, - const char *const *masks) +static int +who_parse_masks(struct who_context *ctx, const char *const *masks) { struct ip_addr net_ip; unsigned int i, net_bits; @@ -181,6 +181,19 @@ int who_parse_args(struct who_context *ctx, const char *alt_username_field, ctx->filter.username = masks[i]; } } + return 0; +} + +int who_parse_args(struct who_context *ctx, const char *alt_username_field, + const struct ip_addr *dest_ip, const char *const *masks) +{ + if (dest_ip != NULL) + ctx->filter.dest_ip = *dest_ip; + + if (masks != NULL) { + if (who_parse_masks(ctx, masks) < 0) + return -1; + } if (alt_username_field != NULL && ctx->filter.username == NULL) { i_error("Username must be given with passdb-field parameter"); doveadm_exit_code = EX_USAGE; @@ -397,6 +410,10 @@ bool who_line_filter_match(const struct who_line *line, filter->net_bits)) return FALSE; } + if (filter->dest_ip.family != 0) { + if (!net_ip_compare(&line->dest_ip, &filter->dest_ip)) + return FALSE; + } return TRUE; } @@ -438,7 +455,7 @@ static void cmd_who(struct doveadm_cmd_context *cctx) hash_table_create(&ctx.users, ctx.pool, 0, who_user_hash, who_user_cmp); if (doveadm_cmd_param_array(cctx, "mask", &masks)) { - if (who_parse_args(&ctx, passdb_field, masks) != 0) { + if (who_parse_args(&ctx, passdb_field, NULL, masks) != 0) { hash_table_destroy(&ctx.users); pool_unref(&ctx.pool); return; diff --git a/src/doveadm/doveadm-who.h b/src/doveadm/doveadm-who.h index c24c23ffb0..429a39ca8c 100644 --- a/src/doveadm/doveadm-who.h +++ b/src/doveadm/doveadm-who.h @@ -20,6 +20,8 @@ struct who_filter { const char *alt_username_field; unsigned int alt_username_idx; + struct ip_addr dest_ip; + struct ip_addr net_ip; unsigned int net_bits; }; @@ -36,7 +38,7 @@ typedef void who_callback_t(struct who_context *ctx, const struct who_line *line); int who_parse_args(struct who_context *ctx, const char *alt_username_field, - const char *const *masks); + const struct ip_addr *dest_ip, const char *const *masks); bool who_line_filter_match(const struct who_line *line, const struct who_filter *filter);