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