This works for all the user_* passdb fields.
return TRUE;
}
+static bool
+director_cmd_user_kick_alt(struct director_connection *conn,
+ const char *const *args)
+{
+ struct director_host *dir_host;
+ int ret;
+
+ if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0)
+ return ret > 0;
+
+ if (str_array_length(args) != 2) {
+ director_cmd_error(conn, "Invalid parameters");
+ return FALSE;
+ }
+
+ director_kick_user_alt(conn->dir, conn->host, dir_host, args[0], args[1]);
+ return TRUE;
+}
+
static bool
director_cmd_user_kick_hash(struct director_connection *conn,
const char *const *args)
return director_cmd_user_move(conn, args);
if (strcmp(cmd, "USER-KICK") == 0)
return director_cmd_user_kick(conn, args);
+ if (strcmp(cmd, "USER-KICK-ALT") == 0)
+ return director_cmd_user_kick_alt(conn, args);
if (strcmp(cmd, "USER-KICK-HASH") == 0)
return director_cmd_user_kick_hash(conn, args);
if (strcmp(cmd, "USER-KILLED") == 0)
director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK, str_c(cmd));
}
+void director_kick_user_alt(struct director *dir, struct director_host *src,
+ struct director_host *orig_src,
+ const char *field, const char *value)
+{
+ string_t *cmd = t_str_new(64);
+
+ str_append(cmd, "proxy\t*\tKICK-ALT\t");
+ str_append_tabescaped(cmd, field);
+ str_append_c(cmd, '\t');
+ str_append_tabescaped(cmd, value);
+ ipc_client_cmd(dir->ipc_proxy, str_c(cmd),
+ director_kick_user_callback, (void *)NULL);
+
+ if (orig_src == NULL) {
+ orig_src = dir->self_host;
+ orig_src->last_seq++;
+ }
+ str_printfa(cmd, "USER-KICK-ALT\t%s\t%u\t%u\t",
+ net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq);
+ str_append_tabescaped(cmd, field);
+ str_append_c(cmd, '\t');
+ str_append_tabescaped(cmd, value);
+ str_append_c(cmd, '\n');
+ director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK_ALT, str_c(cmd));
+}
+
void director_kick_user_hash(struct director *dir, struct director_host *src,
struct director_host *orig_src,
unsigned int username_hash,
#define DIRECTOR_VERSION_NAME "director"
#define DIRECTOR_VERSION_MAJOR 1
-#define DIRECTOR_VERSION_MINOR 7
+#define DIRECTOR_VERSION_MINOR 8
/* weak users supported in protocol */
#define DIRECTOR_VERSION_WEAK_USERS 1
#define DIRECTOR_VERSION_UPDOWN 6
/* user tag version 2 supported */
#define DIRECTOR_VERSION_TAGS_V2 7
+/* user-kick-alt supported */
+#define DIRECTOR_VERSION_USER_KICK_ALT 8
/* Minimum time between even attempting to communicate with a director that
failed due to a protocol error. */
void director_kick_user(struct director *dir, struct director_host *src,
struct director_host *orig_src, const char *username)
ATTR_NULL(3);
+void director_kick_user_alt(struct director *dir, struct director_host *src,
+ struct director_host *orig_src,
+ const char *field, const char *value)
+ ATTR_NULL(3);
void director_kick_user_hash(struct director *dir, struct director_host *src,
struct director_host *orig_src,
unsigned int username_hash,
const char *ip;
const char *port;
const char *vhost_count;
+ const char *passdb_field;
struct istream *users_input;
struct istream *input;
ctx->port = NULL;
if (!doveadm_cmd_param_str(cctx, "vhost-count", &(ctx->vhost_count)))
ctx->vhost_count = NULL;
+ if (!doveadm_cmd_param_str(cctx, "passdb-field", &(ctx->passdb_field)))
+ ctx->passdb_field = NULL;
if (!ctx->user_map)
director_connect(ctx);
return ctx;
return;
}
- str_append(cmd, "USER-KICK\t");
- str_append_tabescaped(cmd, ctx->user);
- str_append_c(cmd, '\n');
-
+ if (ctx->passdb_field == NULL) {
+ str_append(cmd, "USER-KICK\t");
+ str_append_tabescaped(cmd, ctx->user);
+ str_append_c(cmd, '\n');
+ } else {
+ str_append(cmd, "USER-KICK-ALT\t");
+ str_append_tabescaped(cmd, ctx->passdb_field);
+ str_append_c(cmd, '\t');
+ str_append_tabescaped(cmd, ctx->user);
+ str_append_c(cmd, '\n');
+ }
director_send(ctx, str_c(cmd));
+
line = i_stream_read_next_line(ctx->input);
if (line == NULL) {
i_error("failed");
{
.name = "director kick",
.cmd = cmd_director_kick,
- .usage = "[-a <director socket path>] <user>",
+ .usage = "[-a <director socket path>] [-f <passdb field>] <user>",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
+DOVEADM_CMD_PARAM('\0', "passdb-field", CMD_PARAM_STR, 0)
DOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
},