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