3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on reducecap.cc by Jacques Gelinas
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <sys/param.h>
35 #define ENSC_WRAPPERS_PREFIX "reducecap: "
36 #define ENSC_WRAPPERS_VSERVER 1
37 #define ENSC_WRAPPERS_UNISTD 1
42 #define __u32 uint32_t
44 #include "linuxcaps.h"
48 #define CMD_HELP 0x1000
49 #define CMD_VERSION 0x1001
51 #define CMD_SHOW 0x2000
52 #define CMD_PID 0x2001
54 #define CMD_CAP 0x4000
55 #define CMD_FLAG 0x4004
56 #define CMD_SECURE 0x4006
58 #ifdef VC_ENABLE_API_LEGACY
59 # define CMD_OBSOLETE_CHOWN 0x8000
60 # define CMD_OBSOLETE_DAC_OVERRIDE 0x8001
61 # define CMD_OBSOLETE_DAC_READ_SEARCH 0x8002
62 # define CMD_OBSOLETE_FOWNER 0x8003
63 # define CMD_OBSOLETE_FSETID 0x8004
64 # define CMD_OBSOLETE_KILL 0x8005
65 # define CMD_OBSOLETE_SETGID 0x8006
66 # define CMD_OBSOLETE_SETUID 0x8007
67 # define CMD_OBSOLETE_SETPCAP 0x8008
68 # define CMD_OBSOLETE_SYS_TTY_CONFIG 0x8009
69 # define CMD_OBSOLETE_LEASE 0x800a
70 # define CMD_OBSOLETE_SYS_CHROOT 0x800b
71 # define CMD_OBSOLETE_X_LINUX_IMMUTABLE 0x800c
72 # define CMD_OBSOLETE_X_NET_BIND_SERVICE 0x800d
73 # define CMD_OBSOLETE_X_NET_BROADCAST 0x800e
74 # define CMD_OBSOLETE_X_NET_ADMIN 0x800f
75 # define CMD_OBSOLETE_X_NET_RAW 0x8010
76 # define CMD_OBSOLETE_X_IPC_LOCK 0x8011
77 # define CMD_OBSOLETE_X_IPC_OWNER 0x8012
78 # define CMD_OBSOLETE_X_SYS_MODULE 0x8013
79 # define CMD_OBSOLETE_X_SYS_RAWIO 0x8014
80 # define CMD_OBSOLETE_X_SYS_PACCT 0x8015
81 # define CMD_OBSOLETE_X_SYS_ADMIN 0x8016
82 # define CMD_OBSOLETE_X_SYS_BOOT 0x8017
83 # define CMD_OBSOLETE_X_SYS_NICE 0x8018
84 # define CMD_OBSOLETE_X_SYS_RESOURCE 0x8019
85 # define CMD_OBSOLETE_X_SYS_TIME 0x801a
86 # define CMD_OBSOLETE_X_MKNOD 0x801b
87 # define CMD_OBSOLETE_X_QUOTACTL 0x801c
89 static char const * const OBSOLETE_MAPPING[] = {
91 "CHOWN", "DAC_OVERRIDE", "DAC_READ_SEARCH", "FOWNER",
92 "FSETID", "KILL", "SETGID", "SETUID",
93 "SETPCAP", "SYS_TTY_CONFIG", "LEASE", "SYS_CHROOT",
94 "LINUX_IMMUTABLE", "NET_BIND_SERVICE", "NET_BROADCAST", "NET_ADMIN",
95 "NET_RAW", "IPC_LOCK", "IPC_OWNER", "SYS_MODULE",
96 "SYS_RAWIO", "SYS_PACCT", "SYS_ADMIN", "SYS_BOOT",
97 "SYS_NICE", "SYS_RESOURCE", "SYS_TIME", "MKNOD",
102 CMDLINE_OPTIONS[] = {
103 { "help", no_argument, 0, CMD_HELP },
104 { "version", no_argument, 0, CMD_VERSION },
105 { "cap", required_argument, 0, CMD_CAP },
106 { "flag", required_argument, 0, CMD_FLAG },
107 { "secure", no_argument, 0, CMD_SECURE },
108 { "show", no_argument, 0, CMD_SHOW },
109 { "pid", required_argument, 0, CMD_PID },
110 #ifdef VC_ENABLE_API_LEGACY
111 { "CAP_CHOWN", no_argument, 0, CMD_OBSOLETE_CHOWN },
112 { "CAP_DAC_OVERRIDE", no_argument, 0, CMD_OBSOLETE_DAC_OVERRIDE },
113 { "CAP_DAC_READ_SEARCH", no_argument, 0, CMD_OBSOLETE_DAC_READ_SEARCH },
114 { "CAP_FOWNER", no_argument, 0, CMD_OBSOLETE_FOWNER },
115 { "CAP_FSETID", no_argument, 0, CMD_OBSOLETE_FSETID },
116 { "CAP_KILL", no_argument, 0, CMD_OBSOLETE_KILL },
117 { "CAP_SETGID", no_argument, 0, CMD_OBSOLETE_SETGID },
118 { "CAP_SETUID", no_argument, 0, CMD_OBSOLETE_SETUID },
119 { "CAP_SETPCAP", no_argument, 0, CMD_OBSOLETE_SETPCAP },
120 { "CAP_SYS_TTY_CONFIG", no_argument, 0, CMD_OBSOLETE_SYS_TTY_CONFIG },
121 { "CAP_LEASE", no_argument, 0, CMD_OBSOLETE_LEASE },
122 { "CAP_SYS_CHROOT", no_argument, 0, CMD_OBSOLETE_SYS_CHROOT },
123 { "--CAP_LINUX_IMMUTABLE", no_argument, 0, CMD_OBSOLETE_X_LINUX_IMMUTABLE },
124 { "--CAP_NET_BIND_SERVICE", no_argument, 0, CMD_OBSOLETE_X_NET_BIND_SERVICE },
125 { "--CAP_NET_BROADCAST", no_argument, 0, CMD_OBSOLETE_X_NET_BROADCAST },
126 { "--CAP_NET_ADMIN", no_argument, 0, CMD_OBSOLETE_X_NET_ADMIN },
127 { "--CAP_NET_RAW", no_argument, 0, CMD_OBSOLETE_X_NET_RAW },
128 { "--CAP_IPC_LOCK", no_argument, 0, CMD_OBSOLETE_X_IPC_LOCK },
129 { "--CAP_IPC_OWNER", no_argument, 0, CMD_OBSOLETE_X_IPC_OWNER },
130 { "--CAP_SYS_MODULE", no_argument, 0, CMD_OBSOLETE_X_SYS_MODULE },
131 { "--CAP_SYS_RAWIO", no_argument, 0, CMD_OBSOLETE_X_SYS_RAWIO },
132 { "--CAP_SYS_PACCT", no_argument, 0, CMD_OBSOLETE_X_SYS_PACCT },
133 { "--CAP_SYS_ADMIN", no_argument, 0, CMD_OBSOLETE_X_SYS_ADMIN },
134 { "--CAP_SYS_BOOT", no_argument, 0, CMD_OBSOLETE_X_SYS_BOOT },
135 { "--CAP_SYS_NICE", no_argument, 0, CMD_OBSOLETE_X_SYS_NICE },
136 { "--CAP_SYS_RESOURCE", no_argument, 0, CMD_OBSOLETE_X_SYS_RESOURCE },
137 { "--CAP_SYS_TIME", no_argument, 0, CMD_OBSOLETE_X_SYS_TIME },
138 { "--CAP_MKNOD", no_argument, 0, CMD_OBSOLETE_X_MKNOD },
139 { "--CAP_QUOTACTL", no_argument, 0, CMD_OBSOLETE_X_QUOTACTL },
144 int wrapper_exit_code = 255;
146 extern int capget (struct __user_cap_header_struct *, struct __user_cap_data_struct *);
147 extern int capset (struct __user_cap_header_struct *, struct __user_cap_data_struct *);
150 showHelp(int fd, char const *cmd, int res)
152 WRITE_MSG(fd, "Usage:\n ");
155 " [--show] [--secure] [--flag <flag>] [--cap <capability>] [--] <cmd> <args>*\n ");
158 " --show [--pid <pid>]\n\n"
159 "Please report bugs to " PACKAGE_BUGREPORT "\n");
168 "reducecap " VERSION " -- starts programs with reduced capabilities\n"
169 "This program is part of " PACKAGE_STRING "\n\n"
170 "Copyright (C) 2003,2004 Enrico Scholz\n"
171 VERSION_COPYRIGHT_DISCLAIMER);
176 printReducecap(struct __user_cap_data_struct *user)
179 WRITE_MSG(1, " Capability Effective Permitted Inheritable\n");
182 size_t const len = 23 + 10*2 + 4+2;
183 char const * text = vc_cap2text(i);
189 memset(buf, ' ', sizeof buf);
191 l = MIN(strlen(text), 22);
192 memcpy(buf, text, l);
193 buf[23 + 10*0 + 4] = (user->effective & bit) ? 'X' : ' ';
194 buf[23 + 10*1 + 4] = (user->permitted & bit) ? 'X' : ' ';
195 buf[23 + 10*2 + 4] = (user->inheritable & bit) ? 'X' : ' ';
203 struct __user_cap_header_struct header;
204 struct __user_cap_data_struct user;
205 header.version = _LINUX_CAPABILITY_VERSION;
207 if (capget(&header,&user)==-1){
208 perror ("reducecap: capget()");
209 exit(wrapper_exit_code);
212 printReducecap(&user);
216 getCap(char const *cap)
218 int bit = vc_text2cap(cap);
220 WRITE_MSG(2, "Unknown capability '");
221 WRITE_STR(2, optarg);
222 WRITE_MSG(2, "'; try '--help' for more information\n");
223 exit(wrapper_exit_code);
229 int main (int argc, char *argv[])
232 bool do_show = false;
235 #ifdef VC_ENABLE_API_LEGACY
236 bool show_obsolete_warning = true;
240 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
243 #ifdef VC_ENABLE_API_LEGACY
244 if (c>=CMD_OBSOLETE_CHOWN && c<=CMD_OBSOLETE_X_QUOTACTL) {
245 if (show_obsolete_warning) {
246 WRITE_MSG(2, "reducecap: warning, obsolete CLI used\n");
247 show_obsolete_warning = false;
250 remove = getCap(OBSOLETE_MAPPING[c-CMD_OBSOLETE_CHOWN]);
255 case CMD_HELP : showHelp(1, argv[0], 0);
256 case CMD_VERSION : showVersion();
257 case CMD_SECURE : remove = vc_get_insecurebcaps(); break;
258 case CMD_SHOW : do_show = true; break;
259 case CMD_PID : pid = atoi(optarg); break;
260 case CMD_CAP : remove = getCap(optarg); break;
262 struct vc_err_listparser err;
264 flags = vc_list2cflag_compat(optarg, 0, &err);
266 WRITE_MSG(2, "Unknown flag '");
267 write(2, err.ptr, err.len);
269 exit(wrapper_exit_code);
276 if (!do_show && optind==argc) {
277 WRITE_MSG(2, "No command given; use '--help' for more information\n");
278 exit(wrapper_exit_code);
281 if (!do_show && pid!=0) {
282 WRITE_MSG(2, "A pid can be specified in '--show' mode only; use '--help' for more information\n");
283 exit(wrapper_exit_code);
286 if (do_show && optind==argc)
289 Evc_new_s_context(VC_SAMECTX, remove, flags);
290 if (do_show) show(pid);
292 WRITE_MSG(2, "Executing\n");
293 Eexecvp(argv[optind], argv+optind);