From 0a8f356c7278dba34a526adea03561f2063df359 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 30 May 2022 12:55:25 +0000 Subject: [PATCH] Spacing/style nits. --- cmd-command-prompt.c | 2 +- cmd-refresh-client.c | 2 +- format.c | 2 +- log.c | 2 +- notify.c | 2 +- screen.c | 4 +- server-acl.c | 186 +++++++++++++++++++++++++++++++++++++++++++ server-client.c | 24 +++++- window-buffer.c | 4 +- window-client.c | 2 +- window-tree.c | 2 +- window.c | 2 +- 12 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 server-acl.c diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index a7a02702..4455856b 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -112,7 +112,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) } next_prompt = prompts; } else - next_prompt = prompts = xstrdup (s); + next_prompt = prompts = xstrdup(s); if ((s = args_get(args, 'I')) != NULL) next_input = inputs = xstrdup(s); else diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index b2665ad9..6b947280 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -185,7 +185,7 @@ cmd_refresh_client_clipboard(struct cmd *self, struct cmdq_item *item) } if (i != tc->clipboard_npanes) return (CMD_RETURN_NORMAL); - tc->clipboard_panes = xreallocarray (tc->clipboard_panes, + tc->clipboard_panes = xreallocarray(tc->clipboard_panes, tc->clipboard_npanes + 1, sizeof *tc->clipboard_panes); tc->clipboard_panes[tc->clipboard_npanes++] = fs.wp->id; } diff --git a/format.c b/format.c index 981161b3..24d03af0 100644 --- a/format.c +++ b/format.c @@ -2597,7 +2597,7 @@ format_cb_user(__unused struct format_tree *ft) if ((pw = getpwuid(getuid())) != NULL) return (xstrdup(pw->pw_name)); - return NULL; + return (NULL); } /* Format table type. */ diff --git a/log.c b/log.c index abc097dc..ede6e257 100644 --- a/log.c +++ b/log.c @@ -144,7 +144,7 @@ fatal(const char *msg, ...) va_list ap; if (snprintf(tmp, sizeof tmp, "fatal: %s: ", strerror(errno)) < 0) - exit (1); + exit(1); va_start(ap, msg); log_vwrite(msg, ap, tmp); diff --git a/notify.c b/notify.c index f5342710..619bd933 100644 --- a/notify.c +++ b/notify.c @@ -47,7 +47,7 @@ notify_insert_one_hook(struct cmdq_item *item, struct notify_entry *ne, if (log_get_level() != 0) { s = cmd_list_print(cmdlist, 0); log_debug("%s: hook %s is: %s", __func__, ne->name, s); - free (s); + free(s); } new_item = cmdq_get_command(cmdlist, state); return (cmdq_insert_after(item, new_item)); diff --git a/screen.c b/screen.c index 912ab126..87b3330a 100644 --- a/screen.c +++ b/screen.c @@ -662,9 +662,9 @@ screen_mode_to_string(int mode) static char tmp[1024]; if (mode == 0) - return "NONE"; + return ("NONE"); if (mode == ALL_MODES) - return "ALL"; + return ("ALL"); *tmp = '\0'; if (mode & MODE_CURSOR) diff --git a/server-acl.c b/server-acl.c new file mode 100644 index 00000000..26f2490d --- /dev/null +++ b/server-acl.c @@ -0,0 +1,186 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2021 Holland Schutte, Jayson Morberg + * Copyright (c) 2021 Dallas Lyons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tmux.h" + +struct server_acl_user { + uid_t uid; + + int flags; +#define SERVER_ACL_READONLY 0x1 + + RB_ENTRY(server_acl_user) entry; +}; + +static int +server_acl_cmp(struct server_acl_user *user1, struct server_acl_user *user2) +{ + if (user1->uid < user2->uid) + return (-1); + return (user1->uid > user2->uid); +} + +RB_HEAD(server_acl_entries, server_acl_user) server_acl_entries; +RB_GENERATE_STATIC(server_acl_entries, server_acl_user, entry, server_acl_cmp); + +/* Initialize server_acl tree. */ +void +server_acl_init(void) +{ + RB_INIT(&server_acl_entries); + + if (getuid() != 0) + server_acl_user_allow(0); + server_acl_user_allow(getuid()); +} + +/* Find user entry. */ +struct server_acl_user* +server_acl_user_find(uid_t uid) +{ + struct server_acl_user find = { .uid = uid }; + + return (RB_FIND(server_acl_entries, &server_acl_entries, &find)); +} + +/* Display the tree. */ +void +server_acl_display(struct cmdq_item *item) +{ + struct server_acl_user *loop; + struct passwd *pw; + const char *name; + + RB_FOREACH(loop, server_acl_entries, &server_acl_entries) { + if (loop->uid == 0) + continue; + if ((pw = getpwuid(loop->uid)) != NULL) + name = pw->pw_name; + else + name = "unknown"; + if (loop->flags == SERVER_ACL_READONLY) + cmdq_print(item, "%s (R)", name); + else + cmdq_print(item, "%s (W)", name); + } +} + +/* Allow a user. */ +void +server_acl_user_allow(uid_t uid) +{ + struct server_acl_user *user; + + user = server_acl_user_find(uid); + if (user == NULL) { + user = xcalloc(1, sizeof *user); + user->uid = uid; + RB_INSERT(server_acl_entries, &server_acl_entries, user); + } +} + +/* Deny a user (remove from the tree). */ +void +server_acl_user_deny(uid_t uid) +{ + struct server_acl_user *user; + + user = server_acl_user_find(uid); + if (user != NULL) { + RB_REMOVE(server_acl_entries, &server_acl_entries, user); + free(user); + } +} + +/* Allow this user write access. */ +void +server_acl_user_allow_write(uid_t uid) +{ + struct server_acl_user *user; + struct client *c; + + user = server_acl_user_find(uid); + if (user == NULL) + return; + user->flags &= ~SERVER_ACL_READONLY; + + TAILQ_FOREACH(c, &clients, entry) { + uid = proc_get_peer_uid(c->peer); + if (uid != (uid_t)-1 && uid == user->uid) + c->flags &= ~CLIENT_READONLY; + } +} + +/* Deny this user write access. */ +void +server_acl_user_deny_write(uid_t uid) +{ + struct server_acl_user *user; + struct client *c; + + user = server_acl_user_find(uid); + if (user == NULL) + return; + user->flags |= SERVER_ACL_READONLY; + + TAILQ_FOREACH(c, &clients, entry) { + uid = proc_get_peer_uid(c->peer); + if (uid != (uid_t)-1 && uid == user->uid) + c->flags |= CLIENT_READONLY; + } +} + +/* + * Check if the client's UID exists in the ACL list and if so, set as read only + * if needed. Return false if the user does not exist. + */ +int +server_acl_join(struct client *c) +{ + struct server_acl_user *user; + uid_t uid; + + uid = proc_get_peer_uid(c->peer); + if (uid == (uid_t)-1) + return (0); + + user = server_acl_user_find(uid); + if (user == NULL) + return (0); + if (user->flags & SERVER_ACL_READONLY) + c->flags |= CLIENT_READONLY; + return (1); +} + +/* Get UID for user entry. */ +uid_t +server_acl_get_uid(struct server_acl_user *user) +{ + return (user->uid); +} diff --git a/server-client.c b/server-client.c index a2a367be..7c4c2fdd 100644 --- a/server-client.c +++ b/server-client.c @@ -2775,6 +2775,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) @@ -2799,6 +2807,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; @@ -2837,7 +2846,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); @@ -3071,9 +3085,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); @@ -3141,7 +3157,7 @@ server_client_add_client_window(struct client *c, u_int id) cw->window = id; RB_INSERT(client_windows, &c->windows, cw); } - return cw; + return (cw); } /* Get client active pane. */ diff --git a/window-buffer.c b/window-buffer.c index a2fa08ad..544a1155 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -308,7 +308,7 @@ window_buffer_get_key(void *modedata, void *itemdata, u_int line) } pb = paste_get_name(item->name); if (pb == NULL) - return KEYC_NONE; + return (KEYC_NONE); ft = format_create(NULL, NULL, FORMAT_NONE, 0); format_defaults(ft, NULL, NULL, 0, NULL); @@ -320,7 +320,7 @@ window_buffer_get_key(void *modedata, void *itemdata, u_int line) key = key_string_lookup_string(expanded); free(expanded); format_free(ft); - return key; + return (key); } static struct screen * diff --git a/window-client.c b/window-client.c index 00f36c7c..8d501b0d 100644 --- a/window-client.c +++ b/window-client.c @@ -281,7 +281,7 @@ window_client_get_key(void *modedata, void *itemdata, u_int line) key = key_string_lookup_string(expanded); free(expanded); format_free(ft); - return key; + return (key); } static struct screen * diff --git a/window-tree.c b/window-tree.c index b594edd9..fc21af43 100644 --- a/window-tree.c +++ b/window-tree.c @@ -895,7 +895,7 @@ window_tree_get_key(void *modedata, void *itemdata, u_int line) key = key_string_lookup_string(expanded); free(expanded); format_free(ft); - return key; + return (key); } static struct screen * diff --git a/window.c b/window.c index b14a9c60..f14c3bc7 100644 --- a/window.c +++ b/window.c @@ -1046,7 +1046,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy) if (sx == wp->sx && sy == wp->sy) return; - r = xmalloc (sizeof *r); + r = xmalloc(sizeof *r); r->sx = sx; r->sy = sy; r->osx = wp->sx;