summaryrefslogtreecommitdiff
path: root/scheduler/cups-exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'scheduler/cups-exec.c')
-rw-r--r--scheduler/cups-exec.c160
1 files changed, 136 insertions, 24 deletions
diff --git a/scheduler/cups-exec.c b/scheduler/cups-exec.c
index 3474c6e39..e63b163b3 100644
--- a/scheduler/cups-exec.c
+++ b/scheduler/cups-exec.c
@@ -1,23 +1,19 @@
/*
- * "$Id: cups-exec.c 11144 2013-07-17 02:45:55Z msweet $"
+ * "$Id: cups-exec.c 11817 2014-04-15 16:31:11Z msweet $"
*
- * Sandbox helper for CUPS.
+ * Sandbox helper for CUPS.
*
- * Copyright 2007-2013 by Apple Inc.
+ * Copyright 2007-2014 by Apple Inc.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* Usage:
*
- * cups-exec /path/to/profile /path/to/program argv0 argv1 ... argvN
- *
- * Contents:
- *
- * main() - Apply sandbox profile and execute program.
+ * cups-exec /path/to/profile [-u UID] [-g GID] [-n NICE] /path/to/program argv0 argv1 ... argvN
*/
/*
@@ -25,7 +21,11 @@
*/
#include <cups/string-private.h>
+#include <cups/file.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/stat.h>
#ifdef HAVE_SANDBOX_H
# include <sandbox.h>
# ifndef SANDBOX_NAMED_EXTERNAL
@@ -36,6 +36,13 @@
/*
+ * Local functions...
+ */
+
+static void usage(void) __attribute__((noreturn));
+
+
+/*
* 'main()' - Apply sandbox profile and execute program.
*/
@@ -43,34 +50,127 @@ int /* O - Exit status */
main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line arguments */
{
+ int i; /* Looping var */
+ const char *opt; /* Current option character */
+ uid_t uid = getuid(); /* UID */
+ gid_t gid = getgid(); /* GID */
+ int niceval = 0; /* Nice value */
#ifdef HAVE_SANDBOX_H
- char *sandbox_error = NULL; /* Sandbox error, if any */
+ char *sandbox_error = NULL; /* Sandbox error, if any */
#endif /* HAVE_SANDBOX_H */
/*
+ * Parse command-line...
+ */
+
+ for (i = 1; i < argc; i ++)
+ {
+ if (argv[i][0] == '-')
+ {
+ for (opt = argv[i] + 1; *opt; opt ++)
+ {
+ switch (*opt)
+ {
+ case 'g' : /* -g gid */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ gid = (gid_t)atoi(argv[i]);
+ break;
+
+ case 'n' : /* -n nice-value */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ niceval = atoi(argv[i]);
+ break;
+
+ case 'u' : /* -g gid */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ uid = (uid_t)atoi(argv[i]);
+ break;
+
+ default :
+ fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
+ usage();
+ }
+ }
+ }
+ else
+ break;
+ }
+
+ /*
* Check that we have enough arguments...
*/
- if (argc < 4)
+ if ((i + 3) > argc)
+ {
+ fputs("cups-exec: Insufficient arguments.\n", stderr);
+ usage();
+ }
+
+ /*
+ * Make sure side and back channel FDs are non-blocking...
+ */
+
+ fcntl(3, F_SETFL, O_NDELAY);
+ fcntl(4, F_SETFL, O_NDELAY);
+
+ /*
+ * Change UID, GID, and nice value...
+ */
+
+ if (uid)
+ nice(niceval);
+
+ if (!getuid())
{
- puts("Usage: cups-exec /path/to/profile /path/to/program argv0 argv1 ... "
- "argvN");
- return (1);
+ if (setgid(gid))
+ exit(errno + 100);
+
+ if (setgroups(1, &gid))
+ exit(errno + 100);
+
+ if (uid && setuid(uid))
+ exit(errno + 100);
}
+ umask(077);
+
#ifdef HAVE_SANDBOX_H
/*
* Run in a separate security profile...
*/
- if (strcmp(argv[1], "none") &&
- sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
+ if (strcmp(argv[i], "none") &&
+ sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
{
+ cups_file_t *fp; /* File */
+ char line[1024]; /* Line from file */
+ int linenum = 0; /* Line number in file */
+
fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
strerror(errno));
sandbox_free_error(sandbox_error);
- return (1);
+
+ if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
+ {
+ while (cupsFileGets(fp, line, sizeof(line)))
+ {
+ linenum ++;
+ fprintf(stderr, "DEBUG: %4d %s\n", linenum, line);
+ }
+ cupsFileClose(fp);
+ }
+
+ return (100 + EINVAL);
}
#endif /* HAVE_SANDBOX_H */
@@ -78,17 +178,29 @@ main(int argc, /* I - Number of command-line args */
* Execute the program...
*/
- execv(argv[2], argv + 3);
+ execv(argv[i + 1], argv + i + 2);
/*
* If we get here, execv() failed...
*/
fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
- return (1);
+ return (errno + 100);
+}
+
+
+/*
+ * 'usage()' - Show program usage.
+ */
+
+static void
+usage(void)
+{
+ fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);
+ exit(1);
}
/*
- * End of "$Id: cups-exec.c 11144 2013-07-17 02:45:55Z msweet $".
+ * End of "$Id: cups-exec.c 11817 2014-04-15 16:31:11Z msweet $".
*/