]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/cups-exec.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / cups-exec.c
CommitLineData
0268488e 1/*
c82f05ea 2 * Sandbox helper for CUPS.
0268488e 3 *
c82f05ea 4 * Copyright 2007-2014 by Apple Inc.
0268488e 5 *
c82f05ea
MS
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
57b7b66b 10 * missing or damaged, see the license at "http://www.cups.org/".
0268488e
MS
11 *
12 * Usage:
13 *
7131e285 14 * cups-exec /path/to/profile [-u UID] [-g GID] [-n NICE] /path/to/program argv0 argv1 ... argvN
0268488e
MS
15 */
16
17/*
18 * Include necessary headers...
19 */
20
21#include <cups/string-private.h>
8fe0183a 22#include <cups/file.h>
0268488e 23#include <unistd.h>
c82f05ea 24#include <fcntl.h>
07623986 25#include <grp.h>
c82f05ea 26#include <sys/stat.h>
0268488e 27#ifdef HAVE_SANDBOX_H
0268488e 28# include <sandbox.h>
a4845881
MS
29# ifndef SANDBOX_NAMED_EXTERNAL
30# define SANDBOX_NAMED_EXTERNAL 0x0003
31# endif /* !SANDBOX_NAMED_EXTERNAL */
6961465f 32# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0268488e
MS
33#endif /* HAVE_SANDBOX_H */
34
35
28c194b0
MS
36/*
37 * Local functions...
38 */
39
40static void usage(void) __attribute__((noreturn));
41
42
0268488e
MS
43/*
44 * 'main()' - Apply sandbox profile and execute program.
45 */
46
47int /* O - Exit status */
48main(int argc, /* I - Number of command-line args */
49 char *argv[]) /* I - Command-line arguments */
50{
28c194b0
MS
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 */
0268488e 56#ifdef HAVE_SANDBOX_H
28c194b0 57 char *sandbox_error = NULL; /* Sandbox error, if any */
0268488e
MS
58#endif /* HAVE_SANDBOX_H */
59
60
28c194b0
MS
61 /*
62 * Parse command-line...
63 */
64
65 for (i = 1; i < argc; i ++)
66 {
67 if (argv[i][0] == '-')
68 {
69 for (opt = argv[i] + 1; *opt; opt ++)
70 {
71 switch (*opt)
72 {
73 case 'g' : /* -g gid */
74 i ++;
75 if (i >= argc)
76 usage();
77
78 gid = (gid_t)atoi(argv[i]);
79 break;
80
81 case 'n' : /* -n nice-value */
82 i ++;
83 if (i >= argc)
84 usage();
85
86 niceval = atoi(argv[i]);
87 break;
88
89 case 'u' : /* -g gid */
90 i ++;
91 if (i >= argc)
92 usage();
93
94 uid = (uid_t)atoi(argv[i]);
95 break;
96
97 default :
98 fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
99 usage();
100 }
101 }
102 }
103 else
104 break;
105 }
106
0268488e
MS
107 /*
108 * Check that we have enough arguments...
109 */
110
28c194b0 111 if ((i + 3) > argc)
0268488e 112 {
28c194b0
MS
113 fputs("cups-exec: Insufficient arguments.\n", stderr);
114 usage();
0268488e
MS
115 }
116
c82f05ea
MS
117 /*
118 * Make sure side and back channel FDs are non-blocking...
119 */
120
121 fcntl(3, F_SETFL, O_NDELAY);
122 fcntl(4, F_SETFL, O_NDELAY);
123
c82f05ea
MS
124 /*
125 * Change UID, GID, and nice value...
126 */
127
c82f05ea
MS
128 if (uid)
129 nice(niceval);
130
131 if (!getuid())
132 {
133 if (setgid(gid))
134 exit(errno + 100);
135
136 if (setgroups(1, &gid))
137 exit(errno + 100);
138
139 if (uid && setuid(uid))
140 exit(errno + 100);
141 }
142
143 umask(077);
144
8fe0183a 145#ifdef HAVE_SANDBOX_H
0268488e 146 /*
8fe0183a 147 * Run in a separate security profile...
0268488e
MS
148 */
149
28c194b0
MS
150 if (strcmp(argv[i], "none") &&
151 sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
8fe0183a
MS
152 {
153 cups_file_t *fp; /* File */
154 char line[1024]; /* Line from file */
155 int linenum = 0; /* Line number in file */
156
157 fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
158 strerror(errno));
159 sandbox_free_error(sandbox_error);
160
28c194b0 161 if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
8fe0183a
MS
162 {
163 while (cupsFileGets(fp, line, sizeof(line)))
164 {
165 linenum ++;
166 fprintf(stderr, "DEBUG: %4d %s\n", linenum, line);
167 }
168 cupsFileClose(fp);
169 }
170
171 return (100 + EINVAL);
172 }
173#endif /* HAVE_SANDBOX_H */
0268488e 174
28c194b0
MS
175 /*
176 * Execute the program...
177 */
178
179 execv(argv[i + 1], argv + i + 2);
180
0268488e
MS
181 /*
182 * If we get here, execv() failed...
183 */
184
185 fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
8fe0183a 186 return (errno + 100);
0268488e
MS
187}
188
189
28c194b0
MS
190/*
191 * 'usage()' - Show program usage.
192 */
193
194static void
195usage(void)
196{
197 fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);
198 exit(1);
199}