Annotation of src/usr.bin/tmux/cmd-server-access.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: cmd-server-access.c,v 1.1 2022/05/30 12:48:57 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2021 Dallas Lyons <dallasdlyons@gmail.com>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/stat.h>
20: #include <sys/types.h>
21:
22: #include <pwd.h>
23: #include <stdio.h>
24: #include <string.h>
25: #include <stdlib.h>
26: #include <unistd.h>
27:
28: #include "tmux.h"
29:
30: /*
31: * Controls access to session.
32: */
33:
34: static enum cmd_retval cmd_server_access_exec(struct cmd *, struct cmdq_item *);
35:
36: const struct cmd_entry cmd_server_access_entry = {
37: .name = "server-access",
38: .alias = NULL,
39:
40: .args = { "adlrw", 0, 1, NULL },
41: .usage = "[-adlrw]" CMD_TARGET_PANE_USAGE " [user]",
42:
43: .flags = CMD_CLIENT_CANFAIL,
44: .exec = cmd_server_access_exec
45: };
46:
47: static enum cmd_retval
48: cmd_server_access_deny(struct cmdq_item *item, struct passwd *pw)
49: {
50: struct client *loop;
51: struct server_acl_user *user;
52: uid_t uid;
53:
54: if ((user = server_acl_user_find(pw->pw_uid)) == NULL) {
55: cmdq_error(item, "user %s not found", pw->pw_name);
56: return (CMD_RETURN_ERROR);
57: }
58: TAILQ_FOREACH(loop, &clients, entry) {
59: uid = proc_get_peer_uid(loop->peer);
60: if (uid == server_acl_get_uid(user)) {
61: loop->exit_message = xstrdup("access not allowed");
62: loop->flags |= CLIENT_EXIT;
63: }
64: }
65: server_acl_user_deny(pw->pw_uid);
66:
67: return (CMD_RETURN_NORMAL);
68: }
69:
70: static enum cmd_retval
71: cmd_server_access_exec(struct cmd *self, struct cmdq_item *item)
72: {
73:
74: struct args *args = cmd_get_args(self);
75: struct client *c = cmdq_get_target_client(item);
76: char *name;
77: struct passwd *pw = NULL;
78:
79: if (args_has(args, 'l')) {
80: server_acl_display(item);
81: return (CMD_RETURN_NORMAL);
82: }
83: if (args_count(args) == 0) {
1.2 ! nicm 84: cmdq_error(item, "missing user argument");
1.1 nicm 85: return (CMD_RETURN_ERROR);
86: }
87:
88: name = format_single(item, args_string(args, 0), c, NULL, NULL, NULL);
89: if (*name != '\0')
90: pw = getpwnam(name);
91: if (pw == NULL) {
92: cmdq_error(item, "unknown user: %s", name);
93: return (CMD_RETURN_ERROR);
94: }
95: free(name);
96:
97: if (pw->pw_uid == 0 || pw->pw_uid == getuid()) {
98: cmdq_error(item, "%s owns the server, can't change access",
99: pw->pw_name);
100: return (CMD_RETURN_ERROR);
101: }
102:
103: if (args_has(args, 'a') && args_has(args, 'd')) {
104: cmdq_error(item, "-a and -d cannot be used together");
105: return (CMD_RETURN_ERROR);
106: }
107: if (args_has(args, 'w') && args_has(args, 'r')) {
108: cmdq_error(item, "-r and -w cannot be used together");
109: return (CMD_RETURN_ERROR);
110: }
111:
112: if (args_has(args, 'd'))
113: return (cmd_server_access_deny(item, pw));
114: if (args_has(args, 'a')) {
115: if (server_acl_user_find(pw->pw_uid) != NULL) {
116: cmdq_error(item, "user %s is already added",
117: pw->pw_name);
118: return (CMD_RETURN_ERROR);
119: }
120: server_acl_user_allow(pw->pw_uid);
121: /* Do not return - allow -r or -w with -a. */
122: } else if (args_has(args, 'r') || args_has(args, 'w')) {
123: /* -r or -w implies -a if user does not exist. */
124: if (server_acl_user_find(pw->pw_uid) == NULL)
125: server_acl_user_allow(pw->pw_uid);
126: }
127:
128: if (args_has(args, 'w')) {
129: if (server_acl_user_find(pw->pw_uid) == NULL) {
130: cmdq_error(item, "user %s not found", pw->pw_name);
131: return (CMD_RETURN_ERROR);
132: }
133: server_acl_user_allow_write(pw->pw_uid);
134: return (CMD_RETURN_NORMAL);
135: }
136:
137: if (args_has(args, 'r')) {
138: if (server_acl_user_find(pw->pw_uid) == NULL) {
139: cmdq_error(item, "user %s not found", pw->pw_name);
140: return (CMD_RETURN_ERROR);
141: }
142: server_acl_user_deny_write(pw->pw_uid);
143: return (CMD_RETURN_NORMAL);
144: }
145:
146: return (CMD_RETURN_NORMAL);
147: }