aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-30 21:23:26 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-30 21:23:26 +0000
commitb35714986721a6f36ecb87034e6024138f6c0b6e (patch)
treed715bf54d18c2d72b883af8053b363db347aeebd
parentc90e1be01b76aed12ef1cd77c789c842bda26ba6 (diff)
downloadbusybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.tar.gz
busybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.tar.bz2
busybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.zip
chpst: large code shrink by Vladimir
function old new delta chpst_main 1058 1357 +299 euidgid 56 - -56 suidgid 59 - -59 slimit 208 - -208 packed_usage 24638 24420 -218 edir 375 - -375 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 1/1 up/down: 299/-916) Total: -617 bytes
-rw-r--r--include/usage.h67
-rw-r--r--runit/chpst.c373
2 files changed, 209 insertions, 231 deletions
diff --git a/include/usage.h b/include/usage.h
index 110fbf641..466dfac11 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -365,27 +365,26 @@
365 "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n" 365 "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n"
366 366
367#define chpst_trivial_usage \ 367#define chpst_trivial_usage \
368 "[-vP012] [-u user[:group]] [-U user[:group]] [-e dir] " \ 368 "[-vP012] [-u USER[:GRP]] [-U USER[:GRP]] [-e DIR]\n" \
369 "[-/ dir] [-n nice] [-m bytes] [-d bytes] [-o files] " \ 369 " [-/ DIR] [-n NICE] [-m BYTES] [-d BYTES] [-o N]\n" \
370 "[-p processes] [-f bytes] [-c bytes] prog args" 370 " [-p N] [-f BYTES] [-c BYTES] PROG ARGS"
371#define chpst_full_usage "\n\n" \ 371#define chpst_full_usage "\n\n" \
372 "Change the process state and run specified program\n" \ 372 "Change the process state and run PROG\n" \
373 "\nOptions:" \ 373 "\nOptions:" \
374 "\n -u USER[:GRP] Set uid and gid" \ 374 "\n -u USER[:GRP] Set uid and gid" \
375 "\n -U USER[:GRP] Set $UID and $GID in environment" \ 375 "\n -U USER[:GRP] Set $UID and $GID in environment" \
376 "\n -e DIR Set environment variables as specified by files" \ 376 "\n -e DIR Set environment variables as specified by files" \
377 "\n in DIR: file=1st_line_of_file" \ 377 "\n in DIR: file=1st_line_of_file" \
378 "\n -/ DIR Chroot to DIR" \ 378 "\n -/ DIR Chroot to DIR" \
379 "\n -n INC Add INC to nice value" \ 379 "\n -n NICE Add NICE to nice value" \
380 "\n -m BYTES Limit data segment, stack segment, locked physical pages," \ 380 "\n -m BYTES Same as -d BYTES -s BYTES -l BYTES" \
381 "\n and total of all segment per process to BYTES each" \
382 "\n -d BYTES Limit data segment" \ 381 "\n -d BYTES Limit data segment" \
383 "\n -o N Limit the number of open file descriptors per process to N" \ 382 "\n -o N Limit number of open files per process" \
384 "\n -p N Limit number of processes per uid to N" \ 383 "\n -p N Limit number of processes per uid" \
385 "\n -f BYTES Limit output file size to BYTES" \ 384 "\n -f BYTES Limit output file sizes" \
386 "\n -c BYTES Limit core file size to BYTES" \ 385 "\n -c BYTES Limit core file size" \
387 "\n -v Verbose" \ 386 "\n -v Verbose" \
388 "\n -P Run prog in a new process group" \ 387 "\n -P Create new process group" \
389 "\n -0 Close standard input" \ 388 "\n -0 Close standard input" \
390 "\n -1 Close standard output" \ 389 "\n -1 Close standard output" \
391 "\n -2 Close standard error" \ 390 "\n -2 Close standard error" \
@@ -394,41 +393,37 @@
394 "account prog args" 393 "account prog args"
395#define setuidgid_full_usage "\n\n" \ 394#define setuidgid_full_usage "\n\n" \
396 "Set uid and gid to account's uid and gid, removing all supplementary\n" \ 395 "Set uid and gid to account's uid and gid, removing all supplementary\n" \
397 "groups, then run prog" 396 "groups and run PROG"
398#define envuidgid_trivial_usage \ 397#define envuidgid_trivial_usage \
399 "account prog args" 398 "account prog args"
400#define envuidgid_full_usage "\n\n" \ 399#define envuidgid_full_usage "\n\n" \
401 "Set $UID to account's uid and $GID to account's gid, then run prog" 400 "Set $UID to account's uid and $GID to account's gid and run PROG"
402#define envdir_trivial_usage \ 401#define envdir_trivial_usage \
403 "dir prog args" 402 "dir prog args"
404#define envdir_full_usage "\n\n" \ 403#define envdir_full_usage "\n\n" \
405 "Set various environment variables as specified by files\n" \ 404 "Set various environment variables as specified by files\n" \
406 "in the directory dir, then run prog" 405 "in the directory dir and run PROG"
407#define softlimit_trivial_usage \ 406#define softlimit_trivial_usage \
408 "[-a allbytes] [-c corebytes] [-d databytes] [-f filebytes] " \ 407 "[-a BYTES] [-m BYTES] [-d BYTES] [-s BYTES] [-l BYTES]\n" \
409 "[-l lockbytes] [-m membytes] [-o openfiles] [-p processes] " \ 408 " [-f BYTES] [-c BYTES] [-r BYTES] [-o N] [-p N] [-t N]\n" \
410 "[-r residentbytes] [-s stackbytes] [-t cpusecs] prog args" 409 " PROG ARGS"
411#define softlimit_full_usage "\n\n" \ 410#define softlimit_full_usage "\n\n" \
412 "Set soft resource limits, then run prog\n" \ 411 "Set soft resource limits, then run PROG\n" \
413 "\nOptions:" \ 412 "\nOptions:" \
414 "\n -m n Same as -d n -s n -l n -a n" \ 413 "\n -a BYTES Limit total size of all segments" \
415 "\n -d n Limit the data segment per process to n bytes" \ 414 "\n -m BYTES Same as -d BYTES -s BYTES -l BYTES -a BYTES" \
416 "\n -s n Limit the stack segment per process to n bytes" \ 415 "\n -d BYTES Limit data segment" \
417 "\n -l n Limit the locked physical pages per process to n bytes" \ 416 "\n -s BYTES Limit stack segment" \
418 "\n -a n Limit the total of all segments per process to n bytes" \ 417 "\n -l BYTES Limit locked memory size" \
419 "\n -o n Limit the number of open file descriptors per process to n" \ 418 "\n -o N Limit number of open files per process" \
420 "\n -p n Limit the number of processes per uid to n" \ 419 "\n -p N Limit number of processes per uid" \
421 "\nOptions controlling file sizes:" \ 420 "\nOptions controlling file sizes:" \
422 "\n -f n Limit output file sizes to n bytes" \ 421 "\n -f BYTES Limit output file sizes" \
423 "\n -c n Limit core file sizes to n bytes" \ 422 "\n -c BYTES Limit core file size" \
424 "\nEfficiency opts:" \ 423 "\nEfficiency opts:" \
425 "\n -r n Limit the resident set size to n bytes. This limit is not" \ 424 "\n -r BYTES Limit resident set size" \
426 "\n enforced unless physical memory is full" \ 425 "\n -t N Limit CPU time, process receives" \
427 "\n -t n Limit the CPU time to n seconds. This limit is not enforced" \ 426 "\n a SIGXCPU after N seconds" \
428 "\n except that the process receives a SIGXCPU signal after n seconds" \
429 "\n" \
430 "\nSome options may have no effect on some operating systems" \
431 "\nn may be =, indicating that soft limit should be set equal to hard limit" \
432 427
433#define chroot_trivial_usage \ 428#define chroot_trivial_usage \
434 "NEWROOT [COMMAND...]" 429 "NEWROOT [COMMAND...]"
diff --git a/runit/chpst.c b/runit/chpst.c
index 3c841ddbb..24d1d6e2c 100644
--- a/runit/chpst.c
+++ b/runit/chpst.c
@@ -29,73 +29,68 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29/* Dependencies on runit_lib.c removed */ 29/* Dependencies on runit_lib.c removed */
30 30
31#include "libbb.h" 31#include "libbb.h"
32
33#include <dirent.h> 32#include <dirent.h>
34 33
35// Must match constants in chpst_main! 34/*
36#define OPT_verbose (option_mask32 & 0x2000) 35Five applets here: chpst, envdir, envuidgid, setuidgid, softlimit.
37#define OPT_pgrp (option_mask32 & 0x4000)
38#define OPT_nostdin (option_mask32 & 0x8000)
39#define OPT_nostdout (option_mask32 & 0x10000)
40#define OPT_nostderr (option_mask32 & 0x20000)
41 36
42struct globals { 37Only softlimit and chpst are taking options:
43 char *set_user;
44 char *env_user;
45 const char *env_dir;
46 const char *root;
47 long limitd; /* limitX are initialized to -2 */
48 long limits;
49 long limitl;
50 long limita;
51 long limito;
52 long limitp;
53 long limitf;
54 long limitc;
55 long limitr;
56 long limitt;
57 int nicelvl;
58};
59#define G (*(struct globals*)&bb_common_bufsiz1)
60#define set_user (G.set_user)
61#define env_user (G.env_user)
62#define env_dir (G.env_dir )
63#define root (G.root )
64#define limitd (G.limitd )
65#define limits (G.limits )
66#define limitl (G.limitl )
67#define limita (G.limita )
68#define limito (G.limito )
69#define limitp (G.limitp )
70#define limitf (G.limitf )
71#define limitc (G.limitc )
72#define limitr (G.limitr )
73#define limitt (G.limitt )
74#define nicelvl (G.nicelvl )
75#define INIT_G() do { \
76 long *p = &limitd; \
77 do *p++ = -2; while (p <= &limitt); \
78} while (0)
79
80static void suidgid(char *user)
81{
82 struct bb_uidgid_t ugid;
83 38
84 xget_uidgid(&ugid, user); 39# common
85 if (setgroups(1, &ugid.gid) == -1) 40-o N Limit number of open files per process
86 bb_perror_msg_and_die("setgroups"); 41-p N Limit number of processes per uid
87 xsetgid(ugid.gid); 42-m BYTES Same as -d BYTES -s BYTES -l BYTES [-a BYTES]
88 xsetuid(ugid.uid); 43-d BYTES Limit data segment
89} 44-f BYTES Limit output file sizes
45-c BYTES Limit core file size
46# softlimit
47-a BYTES Limit total size of all segments
48-s BYTES Limit stack segment
49-l BYTES Limit locked memory size
50-r BYTES Limit resident set size
51-t N Limit CPU time
52# chpst
53-u USER[:GRP] Set uid and gid
54-U USER[:GRP] Set $UID and $GID in environment
55-e DIR Set environment variables as specified by files in DIR
56-/ DIR Chroot to DIR
57-n NICE Add NICE to nice value
58-v Verbose
59-P Create new process group
60-0 -1 -2 Close fd 0,1,2
90 61
91static void euidgid(char *user) 62Even though we accept all these options for both softlimit and chpst,
92{ 63they are not to be advertised on their help texts.
93 struct bb_uidgid_t ugid; 64We have enough problems with feature creep in other people's
65software, don't want to add our own.
94 66
95 xget_uidgid(&ugid, user); 67envdir, envuidgid, setuidgid take no options, but they reuse code which
96 xsetenv("GID", utoa(ugid.gid)); 68handles -e, -U and -u.
97 xsetenv("UID", utoa(ugid.uid)); 69*/
98} 70
71enum {
72 OPT_a = (1 << 0) * ENABLE_SOFTLIMIT,
73 OPT_c = (1 << 1) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
74 OPT_d = (1 << 2) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
75 OPT_f = (1 << 3) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
76 OPT_l = (1 << 4) * ENABLE_SOFTLIMIT,
77 OPT_m = (1 << 5) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
78 OPT_o = (1 << 6) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
79 OPT_p = (1 << 7) * (ENABLE_SOFTLIMIT || ENABLE_CHPST),
80 OPT_r = (1 << 8) * ENABLE_SOFTLIMIT,
81 OPT_s = (1 << 9) * ENABLE_SOFTLIMIT,
82 OPT_t = (1 << 10) * ENABLE_SOFTLIMIT,
83 OPT_u = (1 << 11) * (ENABLE_CHPST || ENABLE_SETUIDGID),
84 OPT_U = (1 << 12) * (ENABLE_CHPST || ENABLE_ENVUIDGID),
85 OPT_e = (1 << 13) * (ENABLE_CHPST || ENABLE_ENVDIR),
86 OPT_root = (1 << 14) * ENABLE_CHPST,
87 OPT_n = (1 << 15) * ENABLE_CHPST,
88 OPT_v = (1 << 16) * ENABLE_CHPST,
89 OPT_P = (1 << 17) * ENABLE_CHPST,
90 OPT_0 = (1 << 18) * ENABLE_CHPST,
91 OPT_1 = (1 << 19) * ENABLE_CHPST,
92 OPT_2 = (1 << 20) * ENABLE_CHPST,
93};
99 94
100static void edir(const char *directory_name) 95static void edir(const char *directory_name)
101{ 96{
@@ -126,8 +121,8 @@ static void edir(const char *directory_name)
126 continue; 121 continue;
127 fd = open(d->d_name, O_RDONLY | O_NDELAY); 122 fd = open(d->d_name, O_RDONLY | O_NDELAY);
128 if (fd < 0) { 123 if (fd < 0) {
129 if ((errno == EISDIR) && env_dir) { 124 if ((errno == EISDIR) && directory_name) {
130 if (OPT_verbose) 125 if (option_mask32 & OPT_v)
131 bb_perror_msg("warning: %s/%s is a directory", 126 bb_perror_msg("warning: %s/%s is a directory",
132 directory_name, d->d_name); 127 directory_name, d->d_name);
133 continue; 128 continue;
@@ -175,229 +170,217 @@ static void limit(int what, long l)
175 bb_perror_msg_and_die("setrlimit"); 170 bb_perror_msg_and_die("setrlimit");
176} 171}
177 172
178static void slimit(void) 173int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
174int chpst_main(int argc UNUSED_PARAM, char **argv)
179{ 175{
180 if (limitd >= -1) { 176 struct bb_uidgid_t ugid;
177 char *set_user;
178 char *env_user;
179 char *env_dir;
180 char *root;
181 char *nicestr;
182 unsigned limita;
183 unsigned limitc;
184 unsigned limitd;
185 unsigned limitf;
186 unsigned limitl;
187 unsigned limitm;
188 unsigned limito;
189 unsigned limitp;
190 unsigned limitr;
191 unsigned limits;
192 unsigned limitt;
193 unsigned opt;
194
195 if ((ENABLE_CHPST && applet_name[0] == 'c')
196 || (ENABLE_SOFTLIMIT && applet_name[1] == 'o')
197 ) {
198 // FIXME: can we live with int-sized limits?
199 // can we live with 40000 days?
200 // if yes -> getopt converts strings to numbers for us
201 opt_complementary = "-1:a+:c+:d+:f+:l+:m+:o+:p+:r+:s+:t+";
202 opt = getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:u:U:e:"
203 USE_CHPST("/:n:vP012"),
204 &limita, &limitc, &limitd, &limitf, &limitl,
205 &limitm, &limito, &limitp, &limitr, &limits, &limitt,
206 &set_user, &env_user, &env_dir
207 USE_CHPST(, &root, &nicestr));
208 argv += optind;
209 if (opt & OPT_m) { // -m means -asld
210 limita = limits = limitl = limitd = limitm;
211 opt |= (OPT_s | OPT_l | OPT_a | OPT_d);
212 }
213 } else {
214 option_mask32 = opt = 0;
215 argv++;
216 }
217
218 // envdir?
219 if (ENABLE_ENVDIR && applet_name[3] == 'd') {
220 env_dir = *argv++;
221 opt |= OPT_e;
222 }
223
224 // setuidgid?
225 if (ENABLE_SETUIDGID && applet_name[0] == 's') {
226 set_user = *argv++;
227 opt |= OPT_u;
228 }
229
230 // envuidgid?
231 if (ENABLE_ENVUIDGID && applet_name[0] == 'e') {
232 env_user = *argv++;
233 opt |= OPT_U;
234 }
235
236 // we must have PROG [ARGS]
237 if (!*argv)
238 bb_show_usage();
239
240 // set limits
241 if (opt & OPT_d) {
181#ifdef RLIMIT_DATA 242#ifdef RLIMIT_DATA
182 limit(RLIMIT_DATA, limitd); 243 limit(RLIMIT_DATA, limitd);
183#else 244#else
184 if (OPT_verbose) 245 if (opt & OPT_v)
185 bb_error_msg("system does not support RLIMIT_%s", 246 bb_error_msg("system does not support RLIMIT_%s",
186 "DATA"); 247 "DATA");
187#endif 248#endif
188 } 249 }
189 if (limits >= -1) { 250 if (opt & OPT_s) {
190#ifdef RLIMIT_STACK 251#ifdef RLIMIT_STACK
191 limit(RLIMIT_STACK, limits); 252 limit(RLIMIT_STACK, limits);
192#else 253#else
193 if (OPT_verbose) 254 if (opt & OPT_v)
194 bb_error_msg("system does not support RLIMIT_%s", 255 bb_error_msg("system does not support RLIMIT_%s",
195 "STACK"); 256 "STACK");
196#endif 257#endif
197 } 258 }
198 if (limitl >= -1) { 259 if (opt & OPT_l) {
199#ifdef RLIMIT_MEMLOCK 260#ifdef RLIMIT_MEMLOCK
200 limit(RLIMIT_MEMLOCK, limitl); 261 limit(RLIMIT_MEMLOCK, limitl);
201#else 262#else
202 if (OPT_verbose) 263 if (opt & OPT_v)
203 bb_error_msg("system does not support RLIMIT_%s", 264 bb_error_msg("system does not support RLIMIT_%s",
204 "MEMLOCK"); 265 "MEMLOCK");
205#endif 266#endif
206 } 267 }
207 if (limita >= -1) { 268 if (opt & OPT_a) {
208#ifdef RLIMIT_VMEM 269#ifdef RLIMIT_VMEM
209 limit(RLIMIT_VMEM, limita); 270 limit(RLIMIT_VMEM, limita);
210#else 271#else
211#ifdef RLIMIT_AS 272#ifdef RLIMIT_AS
212 limit(RLIMIT_AS, limita); 273 limit(RLIMIT_AS, limita);
213#else 274#else
214 if (OPT_verbose) 275 if (opt & OPT_v)
215 bb_error_msg("system does not support RLIMIT_%s", 276 bb_error_msg("system does not support RLIMIT_%s",
216 "VMEM"); 277 "VMEM");
217#endif 278#endif
218#endif 279#endif
219 } 280 }
220 if (limito >= -1) { 281 if (opt & OPT_o) {
221#ifdef RLIMIT_NOFILE 282#ifdef RLIMIT_NOFILE
222 limit(RLIMIT_NOFILE, limito); 283 limit(RLIMIT_NOFILE, limito);
223#else 284#else
224#ifdef RLIMIT_OFILE 285#ifdef RLIMIT_OFILE
225 limit(RLIMIT_OFILE, limito); 286 limit(RLIMIT_OFILE, limito);
226#else 287#else
227 if (OPT_verbose) 288 if (opt & OPT_v)
228 bb_error_msg("system does not support RLIMIT_%s", 289 bb_error_msg("system does not support RLIMIT_%s",
229 "NOFILE"); 290 "NOFILE");
230#endif 291#endif
231#endif 292#endif
232 } 293 }
233 if (limitp >= -1) { 294 if (opt & OPT_p) {
234#ifdef RLIMIT_NPROC 295#ifdef RLIMIT_NPROC
235 limit(RLIMIT_NPROC, limitp); 296 limit(RLIMIT_NPROC, limitp);
236#else 297#else
237 if (OPT_verbose) 298 if (opt & OPT_v)
238 bb_error_msg("system does not support RLIMIT_%s", 299 bb_error_msg("system does not support RLIMIT_%s",
239 "NPROC"); 300 "NPROC");
240#endif 301#endif
241 } 302 }
242 if (limitf >= -1) { 303 if (opt & OPT_f) {
243#ifdef RLIMIT_FSIZE 304#ifdef RLIMIT_FSIZE
244 limit(RLIMIT_FSIZE, limitf); 305 limit(RLIMIT_FSIZE, limitf);
245#else 306#else
246 if (OPT_verbose) 307 if (opt & OPT_v)
247 bb_error_msg("system does not support RLIMIT_%s", 308 bb_error_msg("system does not support RLIMIT_%s",
248 "FSIZE"); 309 "FSIZE");
249#endif 310#endif
250 } 311 }
251 if (limitc >= -1) { 312 if (opt & OPT_c) {
252#ifdef RLIMIT_CORE 313#ifdef RLIMIT_CORE
253 limit(RLIMIT_CORE, limitc); 314 limit(RLIMIT_CORE, limitc);
254#else 315#else
255 if (OPT_verbose) 316 if (opt & OPT_v)
256 bb_error_msg("system does not support RLIMIT_%s", 317 bb_error_msg("system does not support RLIMIT_%s",
257 "CORE"); 318 "CORE");
258#endif 319#endif
259 } 320 }
260 if (limitr >= -1) { 321 if (opt & OPT_r) {
261#ifdef RLIMIT_RSS 322#ifdef RLIMIT_RSS
262 limit(RLIMIT_RSS, limitr); 323 limit(RLIMIT_RSS, limitr);
263#else 324#else
264 if (OPT_verbose) 325 if (opt & OPT_v)
265 bb_error_msg("system does not support RLIMIT_%s", 326 bb_error_msg("system does not support RLIMIT_%s",
266 "RSS"); 327 "RSS");
267#endif 328#endif
268 } 329 }
269 if (limitt >= -1) { 330 if (opt & OPT_t) {
270#ifdef RLIMIT_CPU 331#ifdef RLIMIT_CPU
271 limit(RLIMIT_CPU, limitt); 332 limit(RLIMIT_CPU, limitt);
272#else 333#else
273 if (OPT_verbose) 334 if (opt & OPT_v)
274 bb_error_msg("system does not support RLIMIT_%s", 335 bb_error_msg("system does not support RLIMIT_%s",
275 "CPU"); 336 "CPU");
276#endif 337#endif
277 } 338 }
278}
279 339
280/* argv[0] */ 340 if (opt & OPT_P)
281static void setuidgid(int, char **) NORETURN; 341 setsid();
282static void envuidgid(int, char **) NORETURN;
283static void envdir(int, char **) NORETURN;
284static void softlimit(int, char **) NORETURN;
285 342
286int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 343 if (opt & OPT_e)
287int chpst_main(int argc UNUSED_PARAM, char **argv) 344 edir(env_dir);
288{ 345
289 INIT_G(); 346 // FIXME: chrooted jail must have /etc/passwd if we move this after chroot!
290 347 // OTOH chroot fails for non-roots!
291 if (applet_name[3] == 'd') envdir(argc, argv); 348 // SOLUTION: cache uid/gid before chroot, apply uid/gid after
292 if (applet_name[1] == 'o') softlimit(argc, argv); 349 if (opt & OPT_U) {
293 if (applet_name[0] == 's') setuidgid(argc, argv); 350 xget_uidgid(&ugid, env_user);
294 if (applet_name[0] == 'e') envuidgid(argc, argv); 351 xsetenv("GID", utoa(ugid.gid));
295 // otherwise we are chpst 352 xsetenv("UID", utoa(ugid.uid));
296
297 {
298 char *m,*d,*o,*p,*f,*c,*r,*t,*n;
299 getopt32(argv, "+u:U:e:m:d:o:p:f:c:r:t:/:n:vP012",
300 &set_user,&env_user,&env_dir,
301 &m,&d,&o,&p,&f,&c,&r,&t,&root,&n);
302 // if (option_mask32 & 0x1) // -u
303 // if (option_mask32 & 0x2) // -U
304 // if (option_mask32 & 0x4) // -e
305 if (option_mask32 & 0x8) limits = limitl = limita = limitd = xatoul(m); // -m
306 if (option_mask32 & 0x10) limitd = xatoul(d); // -d
307 if (option_mask32 & 0x20) limito = xatoul(o); // -o
308 if (option_mask32 & 0x40) limitp = xatoul(p); // -p
309 if (option_mask32 & 0x80) limitf = xatoul(f); // -f
310 if (option_mask32 & 0x100) limitc = xatoul(c); // -c
311 if (option_mask32 & 0x200) limitr = xatoul(r); // -r
312 if (option_mask32 & 0x400) limitt = xatoul(t); // -t
313 // if (option_mask32 & 0x800) // -/
314 if (option_mask32 & 0x1000) nicelvl = xatoi(n); // -n
315 // The below consts should match #defines at top!
316 //if (option_mask32 & 0x2000) OPT_verbose = 1; // -v
317 //if (option_mask32 & 0x4000) OPT_pgrp = 1; // -P
318 //if (option_mask32 & 0x8000) OPT_nostdin = 1; // -0
319 //if (option_mask32 & 0x10000) OPT_nostdout = 1; // -1
320 //if (option_mask32 & 0x20000) OPT_nostderr = 1; // -2
321 } 353 }
322 argv += optind;
323 if (!argv || !*argv) bb_show_usage();
324 354
325 if (OPT_pgrp) setsid(); 355 if (opt & OPT_u) {
326 if (env_dir) edir(env_dir); 356 xget_uidgid(&ugid, set_user);
327 if (root) { 357 }
358
359 if (opt & OPT_root) {
328 xchdir(root); 360 xchdir(root);
329 xchroot("."); 361 xchroot(".");
330 } 362 }
331 slimit(); 363
332 if (nicelvl) { 364 if (opt & OPT_u) {
365 if (setgroups(1, &ugid.gid) == -1)
366 bb_perror_msg_and_die("setgroups");
367 xsetgid(ugid.gid);
368 xsetuid(ugid.uid);
369 }
370
371 if (opt & OPT_n) {
333 errno = 0; 372 errno = 0;
334 if (nice(nicelvl) == -1) 373 if (nice(xatoi(nicestr)) == -1)
335 bb_perror_msg_and_die("nice"); 374 bb_perror_msg_and_die("nice");
336 } 375 }
337 if (env_user) euidgid(env_user);
338 if (set_user) suidgid(set_user);
339 if (OPT_nostdin) close(0);
340 if (OPT_nostdout) close(1);
341 if (OPT_nostderr) close(2);
342 BB_EXECVP(argv[0], argv);
343 bb_perror_msg_and_die("exec %s", argv[0]);
344}
345
346static void setuidgid(int argc UNUSED_PARAM, char **argv)
347{
348 const char *account;
349
350 account = *++argv;
351 if (!account) bb_show_usage();
352 if (!*++argv) bb_show_usage();
353 suidgid((char*)account);
354 BB_EXECVP(argv[0], argv);
355 bb_perror_msg_and_die("exec %s", argv[0]);
356}
357
358static void envuidgid(int argc UNUSED_PARAM, char **argv)
359{
360 const char *account;
361 376
362 account = *++argv; 377 if (opt & OPT_0)
363 if (!account) bb_show_usage(); 378 close(STDIN_FILENO);
364 if (!*++argv) bb_show_usage(); 379 if (opt & OPT_1)
365 euidgid((char*)account); 380 close(STDOUT_FILENO);
366 BB_EXECVP(argv[0], argv); 381 if (opt & OPT_2)
367 bb_perror_msg_and_die("exec %s", argv[0]); 382 close(STDERR_FILENO);
368}
369 383
370static void envdir(int argc UNUSED_PARAM, char **argv)
371{
372 const char *dir;
373
374 dir = *++argv;
375 if (!dir) bb_show_usage();
376 if (!*++argv) bb_show_usage();
377 edir(dir);
378 BB_EXECVP(argv[0], argv);
379 bb_perror_msg_and_die("exec %s", argv[0]);
380}
381
382static void softlimit(int argc UNUSED_PARAM, char **argv)
383{
384 char *a,*c,*d,*f,*l,*m,*o,*p,*r,*s,*t;
385 getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:",
386 &a,&c,&d,&f,&l,&m,&o,&p,&r,&s,&t);
387 if (option_mask32 & 0x001) limita = xatoul(a); // -a
388 if (option_mask32 & 0x002) limitc = xatoul(c); // -c
389 if (option_mask32 & 0x004) limitd = xatoul(d); // -d
390 if (option_mask32 & 0x008) limitf = xatoul(f); // -f
391 if (option_mask32 & 0x010) limitl = xatoul(l); // -l
392 if (option_mask32 & 0x020) limits = limitl = limita = limitd = xatoul(m); // -m
393 if (option_mask32 & 0x040) limito = xatoul(o); // -o
394 if (option_mask32 & 0x080) limitp = xatoul(p); // -p
395 if (option_mask32 & 0x100) limitr = xatoul(r); // -r
396 if (option_mask32 & 0x200) limits = xatoul(s); // -s
397 if (option_mask32 & 0x400) limitt = xatoul(t); // -t
398 argv += optind;
399 if (!argv[0]) bb_show_usage();
400 slimit();
401 BB_EXECVP(argv[0], argv); 384 BB_EXECVP(argv[0], argv);
402 bb_perror_msg_and_die("exec %s", argv[0]); 385 bb_perror_msg_and_die("exec %s", argv[0]);
403} 386}