summaryrefslogtreecommitdiffstats
path: root/server-client.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2022-04-06 14:28:50 +0100
committerNicholas Marriott <nicholas.marriott@gmail.com>2022-04-06 14:28:50 +0100
commitd6306b634e4a044e3380ed984dc7f5e5d67e69ac (patch)
treeb37630b42c687c2d470529e9c78e3f29d24775e3 /server-client.c
parent6e9a9d265e2c5199566e3890e6763a74b558bf80 (diff)
Add an ACL list for users connecting to the tmux socket. Users may be forbidden
from attaching, forced to attach read-only, or allowed to attach read-write. A new command, server-access, configures the list. tmux gets the user using getpeereid(3) of the client socket. Users must still configure file system permissions manually.
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/server-client.c b/server-client.c
index 2350a982..22c8fa80 100644
--- a/server-client.c
+++ b/server-client.c
@@ -2772,6 +2772,14 @@ server_client_dispatch(struct imsg *imsg, void *arg)
}
}
+/* Callback when command is not allowed. */
+static enum cmd_retval
+server_client_read_only(struct cmdq_item *item, __unused void *data)
+{
+ cmdq_error(item, "client is read-only");
+ return (CMD_RETURN_ERROR);
+}
+
/* Callback when command is done. */
static enum cmd_retval
server_client_command_done(struct cmdq_item *item, __unused void *data)
@@ -2796,6 +2804,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
char **argv, *cause;
struct cmd_parse_result *pr;
struct args_value *values;
+ struct cmdq_item *new_item;
if (c->flags & CLIENT_EXIT)
return;
@@ -2834,7 +2843,12 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
free(values);
cmd_free_argv(argc, argv);
- cmdq_append(c, cmdq_get_command(pr->cmdlist, NULL));
+ if ((c->flags & CLIENT_READONLY) &&
+ !cmd_list_all_have(pr->cmdlist, CMD_READONLY))
+ new_item = cmdq_get_callback(server_client_read_only, NULL);
+ else
+ new_item = cmdq_get_command(pr->cmdlist, NULL);
+ cmdq_append(c, new_item);
cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
cmd_list_free(pr->cmdlist);
@@ -3072,9 +3086,11 @@ server_client_set_flags(struct client *c, const char *flags)
continue;
log_debug("client %s set flag %s", c->name, next);
- if (not)
+ if (not) {
+ if (c->flags & CLIENT_READONLY)
+ flag &= ~CLIENT_READONLY;
c->flags &= ~flag;
- else
+ } else
c->flags |= flag;
if (flag == CLIENT_CONTROL_NOOUTPUT)
control_reset_offsets(c);