1/*
2 * This was written by Andrew G. Morgan <morgan@kernel.org>
3 *
4 * This is a program that is intended to exec a subsequent program.
5 * The purpose of this 'execcap' wrapper is to limit the inheritable
6 * capabilities of the exec()'d program.  All environment variables
7 * are inherited.
8 */
9
10#include <sys/types.h>
11#include <errno.h>
12#include <stdio.h>
13#include <sys/capability.h>
14#include <unistd.h>
15#include <string.h>
16#include <stdlib.h>
17
18static void usage(void)
19{
20    fprintf(stderr,
21"usage: execcap <caps> <command-path> [command-args...]\n\n"
22"  This program is a wrapper that can be used to limit the Inheritable\n"
23"  capabilities of a program to be executed.  Note, this wrapper is\n"
24"  intended to assist in overcoming a lack of support for filesystem\n"
25"  capability attributes and should be used to launch other files.\n"
26"  This program should _NOT_ be made setuid-0.\n\n"
27"[Copyright (c) 1998 Andrew G. Morgan <morgan@kernel.org>]\n");
28
29    exit(1);
30}
31
32int main(int argc, char **argv)
33{
34    cap_t new_caps;
35
36    /* this program should not be made setuid-0 */
37    if (getuid() && !geteuid()) {
38	usage();
39    }
40
41    /* check that we have at least 2 arguments */
42    if (argc < 3) {
43	usage();
44    }
45
46    /* parse the first argument to obtain a set of capabilities */
47    new_caps = cap_from_text(argv[1]);
48    if (new_caps == NULL) {
49	fprintf(stderr, "requested capabilities were not recognized\n");
50	usage();
51    }
52
53    /* set these capabilities for the current process */
54    if (cap_set_proc(new_caps) != 0) {
55	fprintf(stderr, "unable to set capabilities: %s\n", strerror(errno));
56	usage();
57    }
58
59    /* exec the program indicated by args 2 ... */
60    execvp(argv[2], argv+2);
61
62    /* if we fall through to here, our exec failed -- announce the fact */
63    fprintf(stderr, "Unable to execute command: %s\n", strerror(errno));
64
65    usage();
66
67    return 0;
68}
69