2 * Sandbox helper for CUPS.
4 * Copyright 2007-2014 by Apple Inc.
6 * These coded instructions, statements, and computer programs are the
7 * property of Apple Inc. and are protected by Federal copyright
8 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
9 * which should have been included with this file. If this file is
10 * file is missing or damaged, see the license at "http://www.cups.org/".
14 * cups-exec /path/to/profile [-u UID] [-g GID] [-n NICE] /path/to/program argv0 argv1 ... argvN
18 * Include necessary headers...
21 #include <cups/string-private.h>
22 #include <cups/file.h>
29 # ifndef SANDBOX_NAMED_EXTERNAL
30 # define SANDBOX_NAMED_EXTERNAL 0x0003
31 # endif /* !SANDBOX_NAMED_EXTERNAL */
32 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
33 #endif /* HAVE_SANDBOX_H */
40 static void usage(void) __attribute__((noreturn));
44 * 'main()' - Apply sandbox profile and execute program.
47 int /* O - Exit status */
48 main(int argc, /* I - Number of command-line args */
49 char *argv[]) /* I - Command-line arguments */
51 int i; /* Looping var */
52 const char *opt; /* Current option character */
53 uid_t uid = getuid(); /* UID */
54 gid_t gid = getgid(); /* GID */
55 int niceval = 0; /* Nice value */
57 char *sandbox_error = NULL; /* Sandbox error, if any */
58 #endif /* HAVE_SANDBOX_H */
62 * Parse command-line...
65 for (i = 1; i < argc; i ++)
67 if (argv[i][0] == '-')
69 for (opt = argv[i] + 1; *opt; opt ++)
73 case 'g' : /* -g gid */
78 gid = (gid_t)atoi(argv[i]);
81 case 'n' : /* -n nice-value */
86 niceval = atoi(argv[i]);
89 case 'u' : /* -g gid */
94 uid = (uid_t)atoi(argv[i]);
98 fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
108 * Check that we have enough arguments...
113 fputs("cups-exec: Insufficient arguments.\n", stderr);
118 * Make sure side and back channel FDs are non-blocking...
121 fcntl(3, F_SETFL, O_NDELAY);
122 fcntl(4, F_SETFL, O_NDELAY);
125 * Change UID, GID, and nice value...
136 if (setgroups(1, &gid))
139 if (uid && setuid(uid))
145 #ifdef HAVE_SANDBOX_H
147 * Run in a separate security profile...
150 if (strcmp(argv[i], "none") &&
151 sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
153 cups_file_t *fp; /* File */
154 char line[1024]; /* Line from file */
155 int linenum = 0; /* Line number in file */
157 fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
159 sandbox_free_error(sandbox_error);
161 if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
163 while (cupsFileGets(fp, line, sizeof(line)))
166 fprintf(stderr, "DEBUG: %4d %s\n", linenum, line);
171 return (100 + EINVAL);
173 #endif /* HAVE_SANDBOX_H */
176 * Execute the program...
179 execv(argv[i + 1], argv + i + 2);
182 * If we get here, execv() failed...
185 fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
186 return (errno + 100);
191 * 'usage()' - Show program usage.
197 fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);