1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Process management routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2017 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
15*5e7646d2SAndroid Build Coastguard Worker #include <grp.h>
16*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
17*5e7646d2SAndroid Build Coastguard Worker # include <libgen.h>
18*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
19*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_POSIX_SPAWN
20*5e7646d2SAndroid Build Coastguard Worker # include <spawn.h>
21*5e7646d2SAndroid Build Coastguard Worker extern char **environ;
22*5e7646d2SAndroid Build Coastguard Worker /* Don't use posix_spawn on systems with bugs in their implementations... */
23*5e7646d2SAndroid Build Coastguard Worker # if defined(OpenBSD) && OpenBSD < 201505
24*5e7646d2SAndroid Build Coastguard Worker # define USE_POSIX_SPAWN 0
25*5e7646d2SAndroid Build Coastguard Worker # elif defined(__UCLIBC__) && __UCLIBC_MAJOR__ == 1 && __UCLIBC_MINOR__ == 0 && __UCLIBC_SUBLEVEL__ < 27
26*5e7646d2SAndroid Build Coastguard Worker # define USE_POSIX_SPAWN 0
27*5e7646d2SAndroid Build Coastguard Worker # elif defined(__UCLIBC__) && __UCLIBC_MAJOR__ < 1
28*5e7646d2SAndroid Build Coastguard Worker # define USE_POSIX_SPAWN 0
29*5e7646d2SAndroid Build Coastguard Worker # else /* All other platforms */
30*5e7646d2SAndroid Build Coastguard Worker # define USE_POSIX_SPAWN 1
31*5e7646d2SAndroid Build Coastguard Worker # endif /* ... */
32*5e7646d2SAndroid Build Coastguard Worker #else
33*5e7646d2SAndroid Build Coastguard Worker # define USE_POSIX_SPAWN 0
34*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_POSIX_SPAWN */
35*5e7646d2SAndroid Build Coastguard Worker
36*5e7646d2SAndroid Build Coastguard Worker
37*5e7646d2SAndroid Build Coastguard Worker /*
38*5e7646d2SAndroid Build Coastguard Worker * Process structure...
39*5e7646d2SAndroid Build Coastguard Worker */
40*5e7646d2SAndroid Build Coastguard Worker
41*5e7646d2SAndroid Build Coastguard Worker typedef struct
42*5e7646d2SAndroid Build Coastguard Worker {
43*5e7646d2SAndroid Build Coastguard Worker int pid, /* Process ID */
44*5e7646d2SAndroid Build Coastguard Worker job_id; /* Job associated with process */
45*5e7646d2SAndroid Build Coastguard Worker char name[1]; /* Name of process */
46*5e7646d2SAndroid Build Coastguard Worker } cupsd_proc_t;
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker /*
50*5e7646d2SAndroid Build Coastguard Worker * Local globals...
51*5e7646d2SAndroid Build Coastguard Worker */
52*5e7646d2SAndroid Build Coastguard Worker
53*5e7646d2SAndroid Build Coastguard Worker static cups_array_t *process_array = NULL;
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker
56*5e7646d2SAndroid Build Coastguard Worker /*
57*5e7646d2SAndroid Build Coastguard Worker * Local functions...
58*5e7646d2SAndroid Build Coastguard Worker */
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker static int compare_procs(cupsd_proc_t *a, cupsd_proc_t *b);
61*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SANDBOX_H
62*5e7646d2SAndroid Build Coastguard Worker static char *cupsd_requote(char *dst, const char *src, size_t dstsize);
63*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SANDBOX_H */
64*5e7646d2SAndroid Build Coastguard Worker
65*5e7646d2SAndroid Build Coastguard Worker
66*5e7646d2SAndroid Build Coastguard Worker /*
67*5e7646d2SAndroid Build Coastguard Worker * 'cupsdCreateProfile()' - Create an execution profile for a subprocess.
68*5e7646d2SAndroid Build Coastguard Worker */
69*5e7646d2SAndroid Build Coastguard Worker
70*5e7646d2SAndroid Build Coastguard Worker void * /* O - Profile or NULL on error */
cupsdCreateProfile(int job_id,int allow_networking)71*5e7646d2SAndroid Build Coastguard Worker cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */
72*5e7646d2SAndroid Build Coastguard Worker int allow_networking)/* I - Allow networking off machine? */
73*5e7646d2SAndroid Build Coastguard Worker {
74*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SANDBOX_H
75*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* File pointer */
76*5e7646d2SAndroid Build Coastguard Worker char profile[1024], /* File containing the profile */
77*5e7646d2SAndroid Build Coastguard Worker bin[1024], /* Quoted ServerBin */
78*5e7646d2SAndroid Build Coastguard Worker cache[1024], /* Quoted CacheDir */
79*5e7646d2SAndroid Build Coastguard Worker domain[1024], /* Domain socket, if any */
80*5e7646d2SAndroid Build Coastguard Worker request[1024], /* Quoted RequestRoot */
81*5e7646d2SAndroid Build Coastguard Worker root[1024], /* Quoted ServerRoot */
82*5e7646d2SAndroid Build Coastguard Worker state[1024], /* Quoted StateDir */
83*5e7646d2SAndroid Build Coastguard Worker temp[1024]; /* Quoted TempDir */
84*5e7646d2SAndroid Build Coastguard Worker const char *nodebug; /* " (with no-log)" for no debug */
85*5e7646d2SAndroid Build Coastguard Worker cupsd_listener_t *lis; /* Current listening socket */
86*5e7646d2SAndroid Build Coastguard Worker
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker if (!UseSandboxing || Sandboxing == CUPSD_SANDBOXING_OFF)
89*5e7646d2SAndroid Build Coastguard Worker {
90*5e7646d2SAndroid Build Coastguard Worker /*
91*5e7646d2SAndroid Build Coastguard Worker * Only use sandbox profiles as root...
92*5e7646d2SAndroid Build Coastguard Worker */
93*5e7646d2SAndroid Build Coastguard Worker
94*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker return (NULL);
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL)
100*5e7646d2SAndroid Build Coastguard Worker {
101*5e7646d2SAndroid Build Coastguard Worker /*
102*5e7646d2SAndroid Build Coastguard Worker * This should never happen, and is fatal when sandboxing is enabled.
103*5e7646d2SAndroid Build Coastguard Worker */
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
106*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to create security profile: %s", strerror(errno));
107*5e7646d2SAndroid Build Coastguard Worker kill(getpid(), SIGTERM);
108*5e7646d2SAndroid Build Coastguard Worker return (NULL);
109*5e7646d2SAndroid Build Coastguard Worker }
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker fchown(cupsFileNumber(fp), RunUser, Group);
112*5e7646d2SAndroid Build Coastguard Worker fchmod(cupsFileNumber(fp), 0640);
113*5e7646d2SAndroid Build Coastguard Worker
114*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(bin, ServerBin, sizeof(bin));
115*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(cache, CacheDir, sizeof(cache));
116*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(request, RequestRoot, sizeof(request));
117*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(root, ServerRoot, sizeof(root));
118*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(state, StateDir, sizeof(state));
119*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(temp, TempDir, sizeof(temp));
120*5e7646d2SAndroid Build Coastguard Worker
121*5e7646d2SAndroid Build Coastguard Worker nodebug = LogLevel < CUPSD_LOG_DEBUG ? " (with no-log)" : "";
122*5e7646d2SAndroid Build Coastguard Worker
123*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(version 1)\n");
124*5e7646d2SAndroid Build Coastguard Worker if (Sandboxing == CUPSD_SANDBOXING_STRICT)
125*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(deny default)\n");
126*5e7646d2SAndroid Build Coastguard Worker else
127*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow default)\n");
128*5e7646d2SAndroid Build Coastguard Worker if (LogLevel >= CUPSD_LOG_DEBUG)
129*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(debug deny)\n");
130*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(import \"system.sb\")\n");
131*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(import \"com.apple.corefoundation.sb\")\n");
132*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(system-network)\n");
133*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow mach-per-user-lookup)\n");
134*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow ipc-posix-sem)\n");
135*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow ipc-posix-shm)\n");
136*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow ipc-sysv-shm)\n");
137*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow mach-lookup)\n");
138*5e7646d2SAndroid Build Coastguard Worker if (!RunUser)
139*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
140*5e7646d2SAndroid Build Coastguard Worker "(deny file-write* file-read-data file-read-metadata\n"
141*5e7646d2SAndroid Build Coastguard Worker " (regex"
142*5e7646d2SAndroid Build Coastguard Worker " #\"^/Users$\""
143*5e7646d2SAndroid Build Coastguard Worker " #\"^/Users/\""
144*5e7646d2SAndroid Build Coastguard Worker ")%s)\n", nodebug);
145*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
146*5e7646d2SAndroid Build Coastguard Worker "(deny file-write*\n"
147*5e7646d2SAndroid Build Coastguard Worker " (regex"
148*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* ServerRoot */
149*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* ServerRoot/... */
150*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/etc$\""
151*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/etc/\""
152*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/local/etc$\""
153*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/local/etc/\""
154*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library$\""
155*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/\""
156*5e7646d2SAndroid Build Coastguard Worker " #\"^/System$\""
157*5e7646d2SAndroid Build Coastguard Worker " #\"^/System/\""
158*5e7646d2SAndroid Build Coastguard Worker ")%s)\n",
159*5e7646d2SAndroid Build Coastguard Worker root, root, nodebug);
160*5e7646d2SAndroid Build Coastguard Worker /* Specifically allow applications to stat RequestRoot and some other system folders */
161*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
162*5e7646d2SAndroid Build Coastguard Worker "(allow file-read-metadata\n"
163*5e7646d2SAndroid Build Coastguard Worker " (regex"
164*5e7646d2SAndroid Build Coastguard Worker " #\"^/$\"" /* / */
165*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr$\"" /* /usr */
166*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library$\"" /* /Library */
167*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers$\"" /* /Library/Printers */
168*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* RequestRoot */
169*5e7646d2SAndroid Build Coastguard Worker "))\n",
170*5e7646d2SAndroid Build Coastguard Worker request);
171*5e7646d2SAndroid Build Coastguard Worker /* Read and write TempDir, CacheDir, and other common folders */
172*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp,
173*5e7646d2SAndroid Build Coastguard Worker "(allow file-write* file-read-data file-read-metadata\n"
174*5e7646d2SAndroid Build Coastguard Worker " (regex"
175*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/db/\""
176*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/folders/\""
177*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/lib/\""
178*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/log/\""
179*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/mysql/\""
180*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/run/\""
181*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/spool/\""
182*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Application Support/\""
183*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Caches/\""
184*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Logs/\""
185*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Preferences/\""
186*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/WebServer/\""
187*5e7646d2SAndroid Build Coastguard Worker " #\"^/Users/Shared/\""
188*5e7646d2SAndroid Build Coastguard Worker "))\n");
189*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
190*5e7646d2SAndroid Build Coastguard Worker "(deny file-write*\n"
191*5e7646d2SAndroid Build Coastguard Worker " (regex #\"^%s$\")%s)\n",
192*5e7646d2SAndroid Build Coastguard Worker request, nodebug);
193*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
194*5e7646d2SAndroid Build Coastguard Worker "(deny file-write* file-read-data file-read-metadata\n"
195*5e7646d2SAndroid Build Coastguard Worker " (regex #\"^%s/\")%s)\n",
196*5e7646d2SAndroid Build Coastguard Worker request, nodebug);
197*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
198*5e7646d2SAndroid Build Coastguard Worker "(allow file-write* file-read-data file-read-metadata\n"
199*5e7646d2SAndroid Build Coastguard Worker " (regex"
200*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* TempDir */
201*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* TempDir/... */
202*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* CacheDir */
203*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* CacheDir/... */
204*5e7646d2SAndroid Build Coastguard Worker "))\n",
205*5e7646d2SAndroid Build Coastguard Worker temp, temp, cache, cache);
206*5e7646d2SAndroid Build Coastguard Worker /* Read common folders */
207*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
208*5e7646d2SAndroid Build Coastguard Worker "(allow file-read-data file-read-metadata\n"
209*5e7646d2SAndroid Build Coastguard Worker " (regex"
210*5e7646d2SAndroid Build Coastguard Worker " #\"^/AppleInternal$\""
211*5e7646d2SAndroid Build Coastguard Worker " #\"^/AppleInternal/\""
212*5e7646d2SAndroid Build Coastguard Worker " #\"^/bin$\"" /* /bin */
213*5e7646d2SAndroid Build Coastguard Worker " #\"^/bin/\"" /* /bin/... */
214*5e7646d2SAndroid Build Coastguard Worker " #\"^/private$\""
215*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/etc$\""
216*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/etc/\""
217*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/tmp$\""
218*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/tmp/\""
219*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var$\""
220*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/db$\""
221*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/folders$\""
222*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/lib$\""
223*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/log$\""
224*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/mysql$\""
225*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/run$\""
226*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/spool$\""
227*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/tmp$\""
228*5e7646d2SAndroid Build Coastguard Worker " #\"^/private/var/tmp/\""
229*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/bin$\"" /* /usr/bin */
230*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/bin/\"" /* /usr/bin/... */
231*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/libexec/cups$\"" /* /usr/libexec/cups */
232*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/libexec/cups/\"" /* /usr/libexec/cups/... */
233*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/libexec/fax$\"" /* /usr/libexec/fax */
234*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/libexec/fax/\"" /* /usr/libexec/fax/... */
235*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/sbin$\"" /* /usr/sbin */
236*5e7646d2SAndroid Build Coastguard Worker " #\"^/usr/sbin/\"" /* /usr/sbin/... */
237*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library$\"" /* /Library */
238*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/\"" /* /Library/... */
239*5e7646d2SAndroid Build Coastguard Worker " #\"^/System$\"" /* /System */
240*5e7646d2SAndroid Build Coastguard Worker " #\"^/System/\"" /* /System/... */
241*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/Library$\"" /* RequestRoot/Library */
242*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/Library/\"" /* RequestRoot/Library/... */
243*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* ServerBin */
244*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* ServerBin/... */
245*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* ServerRoot */
246*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* ServerRoot/... */
247*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* StateDir */
248*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* StateDir/... */
249*5e7646d2SAndroid Build Coastguard Worker "))\n",
250*5e7646d2SAndroid Build Coastguard Worker request, request, bin, bin, root, root, state, state);
251*5e7646d2SAndroid Build Coastguard Worker if (Sandboxing == CUPSD_SANDBOXING_RELAXED)
252*5e7646d2SAndroid Build Coastguard Worker {
253*5e7646d2SAndroid Build Coastguard Worker /* Limited write access to /Library/Printers/... */
254*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp,
255*5e7646d2SAndroid Build Coastguard Worker "(allow file-write*\n"
256*5e7646d2SAndroid Build Coastguard Worker " (regex"
257*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers/.*/\""
258*5e7646d2SAndroid Build Coastguard Worker "))\n");
259*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
260*5e7646d2SAndroid Build Coastguard Worker "(deny file-write*\n"
261*5e7646d2SAndroid Build Coastguard Worker " (regex"
262*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers/PPDs$\""
263*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers/PPDs/\""
264*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers/PPD Plugins$\""
265*5e7646d2SAndroid Build Coastguard Worker " #\"^/Library/Printers/PPD Plugins/\""
266*5e7646d2SAndroid Build Coastguard Worker ")%s)\n", nodebug);
267*5e7646d2SAndroid Build Coastguard Worker }
268*5e7646d2SAndroid Build Coastguard Worker /* Allow execution of child processes as long as the programs are not in a user directory */
269*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow process*)\n");
270*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(deny process-exec (regex #\"^/Users/\"))\n");
271*5e7646d2SAndroid Build Coastguard Worker if (RunUser && getenv("CUPS_TESTROOT"))
272*5e7646d2SAndroid Build Coastguard Worker {
273*5e7646d2SAndroid Build Coastguard Worker /* Allow source directory access in "make test" environment */
274*5e7646d2SAndroid Build Coastguard Worker char testroot[1024]; /* Root directory of test files */
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(testroot, getenv("CUPS_TESTROOT"), sizeof(testroot));
277*5e7646d2SAndroid Build Coastguard Worker
278*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
279*5e7646d2SAndroid Build Coastguard Worker "(allow file-write* file-read-data file-read-metadata\n"
280*5e7646d2SAndroid Build Coastguard Worker " (regex"
281*5e7646d2SAndroid Build Coastguard Worker " #\"^%s$\"" /* CUPS_TESTROOT */
282*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* CUPS_TESTROOT/... */
283*5e7646d2SAndroid Build Coastguard Worker "))\n",
284*5e7646d2SAndroid Build Coastguard Worker testroot, testroot);
285*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
286*5e7646d2SAndroid Build Coastguard Worker "(allow process-exec\n"
287*5e7646d2SAndroid Build Coastguard Worker " (regex"
288*5e7646d2SAndroid Build Coastguard Worker " #\"^%s/\"" /* CUPS_TESTROOT/... */
289*5e7646d2SAndroid Build Coastguard Worker "))\n",
290*5e7646d2SAndroid Build Coastguard Worker testroot);
291*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "(allow sysctl*)\n");
292*5e7646d2SAndroid Build Coastguard Worker }
293*5e7646d2SAndroid Build Coastguard Worker if (job_id)
294*5e7646d2SAndroid Build Coastguard Worker {
295*5e7646d2SAndroid Build Coastguard Worker /* Allow job filters to read the current job files... */
296*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp,
297*5e7646d2SAndroid Build Coastguard Worker "(allow file-read-data file-read-metadata\n"
298*5e7646d2SAndroid Build Coastguard Worker " (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
299*5e7646d2SAndroid Build Coastguard Worker request, job_id, job_id);
300*5e7646d2SAndroid Build Coastguard Worker }
301*5e7646d2SAndroid Build Coastguard Worker else
302*5e7646d2SAndroid Build Coastguard Worker {
303*5e7646d2SAndroid Build Coastguard Worker /* Allow email notifications from notifiers... */
304*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp,
305*5e7646d2SAndroid Build Coastguard Worker "(allow process-exec\n"
306*5e7646d2SAndroid Build Coastguard Worker " (literal \"/usr/sbin/sendmail\")\n"
307*5e7646d2SAndroid Build Coastguard Worker " (with no-sandbox))\n");
308*5e7646d2SAndroid Build Coastguard Worker }
309*5e7646d2SAndroid Build Coastguard Worker /* Allow access to Bluetooth, USB, and notify_post. */
310*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow iokit*)\n");
311*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow distributed-notification-post)\n");
312*5e7646d2SAndroid Build Coastguard Worker /* Allow outbound networking to local services */
313*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow network-outbound"
314*5e7646d2SAndroid Build Coastguard Worker "\n (regex #\"^/private/var/run/\" #\"^/private/tmp/\" #\"^/private/var/tmp/\")");
315*5e7646d2SAndroid Build Coastguard Worker for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
316*5e7646d2SAndroid Build Coastguard Worker lis;
317*5e7646d2SAndroid Build Coastguard Worker lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
318*5e7646d2SAndroid Build Coastguard Worker {
319*5e7646d2SAndroid Build Coastguard Worker if (httpAddrFamily(&(lis->address)) == AF_LOCAL)
320*5e7646d2SAndroid Build Coastguard Worker {
321*5e7646d2SAndroid Build Coastguard Worker httpAddrString(&(lis->address), domain, sizeof(domain));
322*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "\n (literal \"%s\")", domain);
323*5e7646d2SAndroid Build Coastguard Worker }
324*5e7646d2SAndroid Build Coastguard Worker }
325*5e7646d2SAndroid Build Coastguard Worker if (allow_networking)
326*5e7646d2SAndroid Build Coastguard Worker {
327*5e7646d2SAndroid Build Coastguard Worker /* Allow TCP and UDP networking off the machine... */
328*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "\n (remote tcp))\n");
329*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow network-bind)\n"); /* for LPD resvport */
330*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow network*\n"
331*5e7646d2SAndroid Build Coastguard Worker " (local udp \"*:*\")\n"
332*5e7646d2SAndroid Build Coastguard Worker " (remote udp \"*:*\"))\n");
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker /* Also allow access to device files... */
335*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow file-write* file-read-data file-read-metadata file-ioctl\n"
336*5e7646d2SAndroid Build Coastguard Worker " (regex #\"^/dev/\"))\n");
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker /* And allow kernel extensions to be loaded, e.g., SMB */
339*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow system-kext-load)\n");
340*5e7646d2SAndroid Build Coastguard Worker }
341*5e7646d2SAndroid Build Coastguard Worker else
342*5e7646d2SAndroid Build Coastguard Worker {
343*5e7646d2SAndroid Build Coastguard Worker /* Only allow SNMP (UDP) and LPD (TCP) off the machine... */
344*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, ")\n");
345*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow network-outbound\n"
346*5e7646d2SAndroid Build Coastguard Worker " (remote udp \"*:161\")\n"
347*5e7646d2SAndroid Build Coastguard Worker " (remote tcp \"*:515\"))\n");
348*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "(allow network-inbound\n"
349*5e7646d2SAndroid Build Coastguard Worker " (local udp \"localhost:*\"))\n");
350*5e7646d2SAndroid Build Coastguard Worker }
351*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
352*5e7646d2SAndroid Build Coastguard Worker
353*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d,allow_networking=%d) = \"%s\"", job_id, allow_networking, profile);
354*5e7646d2SAndroid Build Coastguard Worker return ((void *)strdup(profile));
355*5e7646d2SAndroid Build Coastguard Worker
356*5e7646d2SAndroid Build Coastguard Worker #else
357*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
358*5e7646d2SAndroid Build Coastguard Worker
359*5e7646d2SAndroid Build Coastguard Worker return (NULL);
360*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SANDBOX_H */
361*5e7646d2SAndroid Build Coastguard Worker }
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker
364*5e7646d2SAndroid Build Coastguard Worker /*
365*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDestroyProfile()' - Delete an execution profile.
366*5e7646d2SAndroid Build Coastguard Worker */
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker void
cupsdDestroyProfile(void * profile)369*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(void *profile) /* I - Profile */
370*5e7646d2SAndroid Build Coastguard Worker {
371*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeleteProfile(profile=\"%s\")",
372*5e7646d2SAndroid Build Coastguard Worker profile ? (char *)profile : "(null)");
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SANDBOX_H
375*5e7646d2SAndroid Build Coastguard Worker if (profile)
376*5e7646d2SAndroid Build Coastguard Worker {
377*5e7646d2SAndroid Build Coastguard Worker unlink((char *)profile);
378*5e7646d2SAndroid Build Coastguard Worker free(profile);
379*5e7646d2SAndroid Build Coastguard Worker }
380*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SANDBOX_H */
381*5e7646d2SAndroid Build Coastguard Worker }
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker
384*5e7646d2SAndroid Build Coastguard Worker /*
385*5e7646d2SAndroid Build Coastguard Worker * 'cupsdEndProcess()' - End a process.
386*5e7646d2SAndroid Build Coastguard Worker */
387*5e7646d2SAndroid Build Coastguard Worker
388*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
cupsdEndProcess(int pid,int force)389*5e7646d2SAndroid Build Coastguard Worker cupsdEndProcess(int pid, /* I - Process ID */
390*5e7646d2SAndroid Build Coastguard Worker int force) /* I - Force child to die */
391*5e7646d2SAndroid Build Coastguard Worker {
392*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdEndProcess(pid=%d, force=%d)", pid,
393*5e7646d2SAndroid Build Coastguard Worker force);
394*5e7646d2SAndroid Build Coastguard Worker
395*5e7646d2SAndroid Build Coastguard Worker if (!pid)
396*5e7646d2SAndroid Build Coastguard Worker return (0);
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker if (!RunUser)
399*5e7646d2SAndroid Build Coastguard Worker {
400*5e7646d2SAndroid Build Coastguard Worker /*
401*5e7646d2SAndroid Build Coastguard Worker * When running as root, cupsd puts child processes in their own process
402*5e7646d2SAndroid Build Coastguard Worker * group. Using "-pid" sends a signal to all processes in the group.
403*5e7646d2SAndroid Build Coastguard Worker */
404*5e7646d2SAndroid Build Coastguard Worker
405*5e7646d2SAndroid Build Coastguard Worker pid = -pid;
406*5e7646d2SAndroid Build Coastguard Worker }
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker if (force)
409*5e7646d2SAndroid Build Coastguard Worker return (kill(pid, SIGKILL));
410*5e7646d2SAndroid Build Coastguard Worker else
411*5e7646d2SAndroid Build Coastguard Worker return (kill(pid, SIGTERM));
412*5e7646d2SAndroid Build Coastguard Worker }
413*5e7646d2SAndroid Build Coastguard Worker
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker /*
416*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFinishProcess()' - Finish a process and get its name.
417*5e7646d2SAndroid Build Coastguard Worker */
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Process name */
cupsdFinishProcess(int pid,char * name,size_t namelen,int * job_id)420*5e7646d2SAndroid Build Coastguard Worker cupsdFinishProcess(int pid, /* I - Process ID */
421*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
422*5e7646d2SAndroid Build Coastguard Worker size_t namelen, /* I - Size of name buffer */
423*5e7646d2SAndroid Build Coastguard Worker int *job_id) /* O - Job ID pointer or NULL */
424*5e7646d2SAndroid Build Coastguard Worker {
425*5e7646d2SAndroid Build Coastguard Worker cupsd_proc_t key, /* Search key */
426*5e7646d2SAndroid Build Coastguard Worker *proc; /* Matching process */
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker key.pid = pid;
430*5e7646d2SAndroid Build Coastguard Worker
431*5e7646d2SAndroid Build Coastguard Worker if ((proc = (cupsd_proc_t *)cupsArrayFind(process_array, &key)) != NULL)
432*5e7646d2SAndroid Build Coastguard Worker {
433*5e7646d2SAndroid Build Coastguard Worker if (job_id)
434*5e7646d2SAndroid Build Coastguard Worker *job_id = proc->job_id;
435*5e7646d2SAndroid Build Coastguard Worker
436*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, proc->name, namelen);
437*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(process_array, proc);
438*5e7646d2SAndroid Build Coastguard Worker free(proc);
439*5e7646d2SAndroid Build Coastguard Worker }
440*5e7646d2SAndroid Build Coastguard Worker else
441*5e7646d2SAndroid Build Coastguard Worker {
442*5e7646d2SAndroid Build Coastguard Worker if (job_id)
443*5e7646d2SAndroid Build Coastguard Worker *job_id = 0;
444*5e7646d2SAndroid Build Coastguard Worker
445*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "unknown", namelen);
446*5e7646d2SAndroid Build Coastguard Worker }
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFinishProcess(pid=%d, name=%p, namelen=" CUPS_LLFMT ", job_id=%p(%d)) = \"%s\"", pid, name, CUPS_LLCAST namelen, job_id, job_id ? *job_id : 0, name);
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker return (name);
451*5e7646d2SAndroid Build Coastguard Worker }
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker /*
455*5e7646d2SAndroid Build Coastguard Worker * 'cupsdStartProcess()' - Start a process.
456*5e7646d2SAndroid Build Coastguard Worker */
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker int /* O - Process ID or 0 */
cupsdStartProcess(const char * command,char * argv[],char * envp[],int infd,int outfd,int errfd,int backfd,int sidefd,int root,void * profile,cupsd_job_t * job,int * pid)459*5e7646d2SAndroid Build Coastguard Worker cupsdStartProcess(
460*5e7646d2SAndroid Build Coastguard Worker const char *command, /* I - Full path to command */
461*5e7646d2SAndroid Build Coastguard Worker char *argv[], /* I - Command-line arguments */
462*5e7646d2SAndroid Build Coastguard Worker char *envp[], /* I - Environment */
463*5e7646d2SAndroid Build Coastguard Worker int infd, /* I - Standard input file descriptor */
464*5e7646d2SAndroid Build Coastguard Worker int outfd, /* I - Standard output file descriptor */
465*5e7646d2SAndroid Build Coastguard Worker int errfd, /* I - Standard error file descriptor */
466*5e7646d2SAndroid Build Coastguard Worker int backfd, /* I - Backchannel file descriptor */
467*5e7646d2SAndroid Build Coastguard Worker int sidefd, /* I - Sidechannel file descriptor */
468*5e7646d2SAndroid Build Coastguard Worker int root, /* I - Run as root? */
469*5e7646d2SAndroid Build Coastguard Worker void *profile, /* I - Security profile to use */
470*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job, /* I - Job associated with process */
471*5e7646d2SAndroid Build Coastguard Worker int *pid) /* O - Process ID */
472*5e7646d2SAndroid Build Coastguard Worker {
473*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
474*5e7646d2SAndroid Build Coastguard Worker const char *exec_path = command; /* Command to be exec'd */
475*5e7646d2SAndroid Build Coastguard Worker char *real_argv[110], /* Real command-line arguments */
476*5e7646d2SAndroid Build Coastguard Worker cups_exec[1024], /* Path to "cups-exec" program */
477*5e7646d2SAndroid Build Coastguard Worker user_str[16], /* User string */
478*5e7646d2SAndroid Build Coastguard Worker group_str[16], /* Group string */
479*5e7646d2SAndroid Build Coastguard Worker nice_str[16]; /* FilterNice string */
480*5e7646d2SAndroid Build Coastguard Worker uid_t user; /* Command UID */
481*5e7646d2SAndroid Build Coastguard Worker cupsd_proc_t *proc; /* New process record */
482*5e7646d2SAndroid Build Coastguard Worker #if USE_POSIX_SPAWN
483*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_t actions; /* Spawn file actions */
484*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_t attrs; /* Spawn attributes */
485*5e7646d2SAndroid Build Coastguard Worker sigset_t defsignals; /* Default signals */
486*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
487*5e7646d2SAndroid Build Coastguard Worker struct sigaction action; /* POSIX signal handler */
488*5e7646d2SAndroid Build Coastguard Worker #endif /* USE_POSIX_SPAWN */
489*5e7646d2SAndroid Build Coastguard Worker #if defined(__APPLE__)
490*5e7646d2SAndroid Build Coastguard Worker char processPath[1024], /* CFProcessPath environment variable */
491*5e7646d2SAndroid Build Coastguard Worker linkpath[1024]; /* Link path for symlinks... */
492*5e7646d2SAndroid Build Coastguard Worker int linkbytes; /* Bytes for link path */
493*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker
496*5e7646d2SAndroid Build Coastguard Worker *pid = 0;
497*5e7646d2SAndroid Build Coastguard Worker
498*5e7646d2SAndroid Build Coastguard Worker /*
499*5e7646d2SAndroid Build Coastguard Worker * Figure out the UID for the child process...
500*5e7646d2SAndroid Build Coastguard Worker */
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker if (RunUser)
503*5e7646d2SAndroid Build Coastguard Worker user = RunUser;
504*5e7646d2SAndroid Build Coastguard Worker else if (root)
505*5e7646d2SAndroid Build Coastguard Worker user = 0;
506*5e7646d2SAndroid Build Coastguard Worker else
507*5e7646d2SAndroid Build Coastguard Worker user = User;
508*5e7646d2SAndroid Build Coastguard Worker
509*5e7646d2SAndroid Build Coastguard Worker /*
510*5e7646d2SAndroid Build Coastguard Worker * Check the permissions of the command we are running...
511*5e7646d2SAndroid Build Coastguard Worker */
512*5e7646d2SAndroid Build Coastguard Worker
513*5e7646d2SAndroid Build Coastguard Worker if (_cupsFileCheck(command, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
514*5e7646d2SAndroid Build Coastguard Worker cupsdLogFCMessage, job ? job->printer : NULL))
515*5e7646d2SAndroid Build Coastguard Worker return (0);
516*5e7646d2SAndroid Build Coastguard Worker
517*5e7646d2SAndroid Build Coastguard Worker #if defined(__APPLE__)
518*5e7646d2SAndroid Build Coastguard Worker if (envp)
519*5e7646d2SAndroid Build Coastguard Worker {
520*5e7646d2SAndroid Build Coastguard Worker /*
521*5e7646d2SAndroid Build Coastguard Worker * Add special voodoo magic for macOS - this allows macOS programs to access
522*5e7646d2SAndroid Build Coastguard Worker * their bundle resources properly...
523*5e7646d2SAndroid Build Coastguard Worker */
524*5e7646d2SAndroid Build Coastguard Worker
525*5e7646d2SAndroid Build Coastguard Worker if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0)
526*5e7646d2SAndroid Build Coastguard Worker {
527*5e7646d2SAndroid Build Coastguard Worker /*
528*5e7646d2SAndroid Build Coastguard Worker * Yes, this is a symlink to the actual program, nul-terminate and
529*5e7646d2SAndroid Build Coastguard Worker * use it...
530*5e7646d2SAndroid Build Coastguard Worker */
531*5e7646d2SAndroid Build Coastguard Worker
532*5e7646d2SAndroid Build Coastguard Worker linkpath[linkbytes] = '\0';
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker if (linkpath[0] == '/')
535*5e7646d2SAndroid Build Coastguard Worker snprintf(processPath, sizeof(processPath), "CFProcessPath=%s",
536*5e7646d2SAndroid Build Coastguard Worker linkpath);
537*5e7646d2SAndroid Build Coastguard Worker else
538*5e7646d2SAndroid Build Coastguard Worker snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s",
539*5e7646d2SAndroid Build Coastguard Worker dirname((char *)command), linkpath);
540*5e7646d2SAndroid Build Coastguard Worker }
541*5e7646d2SAndroid Build Coastguard Worker else
542*5e7646d2SAndroid Build Coastguard Worker snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", command);
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker envp[0] = processPath; /* Replace <CFProcessPath> string */
545*5e7646d2SAndroid Build Coastguard Worker }
546*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker /*
549*5e7646d2SAndroid Build Coastguard Worker * Use helper program when we have a sandbox profile...
550*5e7646d2SAndroid Build Coastguard Worker */
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker #if !USE_POSIX_SPAWN
553*5e7646d2SAndroid Build Coastguard Worker if (profile)
554*5e7646d2SAndroid Build Coastguard Worker #endif /* !USE_POSIX_SPAWN */
555*5e7646d2SAndroid Build Coastguard Worker {
556*5e7646d2SAndroid Build Coastguard Worker snprintf(cups_exec, sizeof(cups_exec), "%s/daemon/cups-exec", ServerBin);
557*5e7646d2SAndroid Build Coastguard Worker snprintf(user_str, sizeof(user_str), "%d", user);
558*5e7646d2SAndroid Build Coastguard Worker snprintf(group_str, sizeof(group_str), "%d", Group);
559*5e7646d2SAndroid Build Coastguard Worker snprintf(nice_str, sizeof(nice_str), "%d", FilterNice);
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker real_argv[0] = cups_exec;
562*5e7646d2SAndroid Build Coastguard Worker real_argv[1] = (char *)"-g";
563*5e7646d2SAndroid Build Coastguard Worker real_argv[2] = group_str;
564*5e7646d2SAndroid Build Coastguard Worker real_argv[3] = (char *)"-n";
565*5e7646d2SAndroid Build Coastguard Worker real_argv[4] = nice_str;
566*5e7646d2SAndroid Build Coastguard Worker real_argv[5] = (char *)"-u";
567*5e7646d2SAndroid Build Coastguard Worker real_argv[6] = user_str;
568*5e7646d2SAndroid Build Coastguard Worker real_argv[7] = profile ? profile : "none";
569*5e7646d2SAndroid Build Coastguard Worker real_argv[8] = (char *)command;
570*5e7646d2SAndroid Build Coastguard Worker
571*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
572*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 10) && argv[i];
573*5e7646d2SAndroid Build Coastguard Worker i ++)
574*5e7646d2SAndroid Build Coastguard Worker real_argv[i + 9] = argv[i];
575*5e7646d2SAndroid Build Coastguard Worker
576*5e7646d2SAndroid Build Coastguard Worker real_argv[i + 9] = NULL;
577*5e7646d2SAndroid Build Coastguard Worker
578*5e7646d2SAndroid Build Coastguard Worker argv = real_argv;
579*5e7646d2SAndroid Build Coastguard Worker exec_path = cups_exec;
580*5e7646d2SAndroid Build Coastguard Worker }
581*5e7646d2SAndroid Build Coastguard Worker
582*5e7646d2SAndroid Build Coastguard Worker if (LogLevel == CUPSD_LOG_DEBUG2)
583*5e7646d2SAndroid Build Coastguard Worker {
584*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Preparing to start \"%s\", arguments:", command);
585*5e7646d2SAndroid Build Coastguard Worker
586*5e7646d2SAndroid Build Coastguard Worker for (i = 0; argv[i]; i ++)
587*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: argv[%d] = \"%s\"", i, argv[i]);
588*5e7646d2SAndroid Build Coastguard Worker }
589*5e7646d2SAndroid Build Coastguard Worker
590*5e7646d2SAndroid Build Coastguard Worker #if USE_POSIX_SPAWN
591*5e7646d2SAndroid Build Coastguard Worker /*
592*5e7646d2SAndroid Build Coastguard Worker * Setup attributes and file actions for the spawn...
593*5e7646d2SAndroid Build Coastguard Worker */
594*5e7646d2SAndroid Build Coastguard Worker
595*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting spawn attributes.");
596*5e7646d2SAndroid Build Coastguard Worker sigemptyset(&defsignals);
597*5e7646d2SAndroid Build Coastguard Worker sigaddset(&defsignals, SIGTERM);
598*5e7646d2SAndroid Build Coastguard Worker sigaddset(&defsignals, SIGCHLD);
599*5e7646d2SAndroid Build Coastguard Worker sigaddset(&defsignals, SIGPIPE);
600*5e7646d2SAndroid Build Coastguard Worker
601*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_init(&attrs);
602*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_setflags(&attrs, POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF);
603*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_setpgroup(&attrs, 0);
604*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_setsigdefault(&attrs, &defsignals);
605*5e7646d2SAndroid Build Coastguard Worker
606*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting file actions.");
607*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_init(&actions);
608*5e7646d2SAndroid Build Coastguard Worker if (infd != 0)
609*5e7646d2SAndroid Build Coastguard Worker {
610*5e7646d2SAndroid Build Coastguard Worker if (infd < 0)
611*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDONLY, 0);
612*5e7646d2SAndroid Build Coastguard Worker else
613*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_adddup2(&actions, infd, 0);
614*5e7646d2SAndroid Build Coastguard Worker }
615*5e7646d2SAndroid Build Coastguard Worker
616*5e7646d2SAndroid Build Coastguard Worker if (outfd != 1)
617*5e7646d2SAndroid Build Coastguard Worker {
618*5e7646d2SAndroid Build Coastguard Worker if (outfd < 0)
619*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0);
620*5e7646d2SAndroid Build Coastguard Worker else
621*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_adddup2(&actions, outfd, 1);
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker if (errfd != 2)
625*5e7646d2SAndroid Build Coastguard Worker {
626*5e7646d2SAndroid Build Coastguard Worker if (errfd < 0)
627*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0);
628*5e7646d2SAndroid Build Coastguard Worker else
629*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_adddup2(&actions, errfd, 2);
630*5e7646d2SAndroid Build Coastguard Worker }
631*5e7646d2SAndroid Build Coastguard Worker
632*5e7646d2SAndroid Build Coastguard Worker if (backfd != 3 && backfd >= 0)
633*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_adddup2(&actions, backfd, 3);
634*5e7646d2SAndroid Build Coastguard Worker
635*5e7646d2SAndroid Build Coastguard Worker if (sidefd != 4 && sidefd >= 0)
636*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_adddup2(&actions, sidefd, 4);
637*5e7646d2SAndroid Build Coastguard Worker
638*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Calling posix_spawn.");
639*5e7646d2SAndroid Build Coastguard Worker
640*5e7646d2SAndroid Build Coastguard Worker if (posix_spawn(pid, exec_path, &actions, &attrs, argv, envp ? envp : environ))
641*5e7646d2SAndroid Build Coastguard Worker {
642*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork %s - %s.", command, strerror(errno));
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker *pid = 0;
645*5e7646d2SAndroid Build Coastguard Worker }
646*5e7646d2SAndroid Build Coastguard Worker else
647*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: pid=%d", (int)*pid);
648*5e7646d2SAndroid Build Coastguard Worker
649*5e7646d2SAndroid Build Coastguard Worker posix_spawn_file_actions_destroy(&actions);
650*5e7646d2SAndroid Build Coastguard Worker posix_spawnattr_destroy(&attrs);
651*5e7646d2SAndroid Build Coastguard Worker
652*5e7646d2SAndroid Build Coastguard Worker #else
653*5e7646d2SAndroid Build Coastguard Worker /*
654*5e7646d2SAndroid Build Coastguard Worker * Block signals before forking...
655*5e7646d2SAndroid Build Coastguard Worker */
656*5e7646d2SAndroid Build Coastguard Worker
657*5e7646d2SAndroid Build Coastguard Worker cupsdHoldSignals();
658*5e7646d2SAndroid Build Coastguard Worker
659*5e7646d2SAndroid Build Coastguard Worker if ((*pid = fork()) == 0)
660*5e7646d2SAndroid Build Coastguard Worker {
661*5e7646d2SAndroid Build Coastguard Worker /*
662*5e7646d2SAndroid Build Coastguard Worker * Child process goes here; update stderr as needed...
663*5e7646d2SAndroid Build Coastguard Worker */
664*5e7646d2SAndroid Build Coastguard Worker
665*5e7646d2SAndroid Build Coastguard Worker if (errfd != 2)
666*5e7646d2SAndroid Build Coastguard Worker {
667*5e7646d2SAndroid Build Coastguard Worker if (errfd < 0)
668*5e7646d2SAndroid Build Coastguard Worker errfd = open("/dev/null", O_WRONLY);
669*5e7646d2SAndroid Build Coastguard Worker
670*5e7646d2SAndroid Build Coastguard Worker if (errfd != 2)
671*5e7646d2SAndroid Build Coastguard Worker {
672*5e7646d2SAndroid Build Coastguard Worker dup2(errfd, 2);
673*5e7646d2SAndroid Build Coastguard Worker close(errfd);
674*5e7646d2SAndroid Build Coastguard Worker }
675*5e7646d2SAndroid Build Coastguard Worker }
676*5e7646d2SAndroid Build Coastguard Worker
677*5e7646d2SAndroid Build Coastguard Worker /*
678*5e7646d2SAndroid Build Coastguard Worker * Put this process in its own process group so that we can kill any child
679*5e7646d2SAndroid Build Coastguard Worker * processes it creates.
680*5e7646d2SAndroid Build Coastguard Worker */
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_SETPGID
683*5e7646d2SAndroid Build Coastguard Worker if (!RunUser && setpgid(0, 0))
684*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
685*5e7646d2SAndroid Build Coastguard Worker # else
686*5e7646d2SAndroid Build Coastguard Worker if (!RunUser && setpgrp())
687*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
688*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_SETPGID */
689*5e7646d2SAndroid Build Coastguard Worker
690*5e7646d2SAndroid Build Coastguard Worker /*
691*5e7646d2SAndroid Build Coastguard Worker * Update the remaining file descriptors as needed...
692*5e7646d2SAndroid Build Coastguard Worker */
693*5e7646d2SAndroid Build Coastguard Worker
694*5e7646d2SAndroid Build Coastguard Worker if (infd != 0)
695*5e7646d2SAndroid Build Coastguard Worker {
696*5e7646d2SAndroid Build Coastguard Worker if (infd < 0)
697*5e7646d2SAndroid Build Coastguard Worker infd = open("/dev/null", O_RDONLY);
698*5e7646d2SAndroid Build Coastguard Worker
699*5e7646d2SAndroid Build Coastguard Worker if (infd != 0)
700*5e7646d2SAndroid Build Coastguard Worker {
701*5e7646d2SAndroid Build Coastguard Worker dup2(infd, 0);
702*5e7646d2SAndroid Build Coastguard Worker close(infd);
703*5e7646d2SAndroid Build Coastguard Worker }
704*5e7646d2SAndroid Build Coastguard Worker }
705*5e7646d2SAndroid Build Coastguard Worker
706*5e7646d2SAndroid Build Coastguard Worker if (outfd != 1)
707*5e7646d2SAndroid Build Coastguard Worker {
708*5e7646d2SAndroid Build Coastguard Worker if (outfd < 0)
709*5e7646d2SAndroid Build Coastguard Worker outfd = open("/dev/null", O_WRONLY);
710*5e7646d2SAndroid Build Coastguard Worker
711*5e7646d2SAndroid Build Coastguard Worker if (outfd != 1)
712*5e7646d2SAndroid Build Coastguard Worker {
713*5e7646d2SAndroid Build Coastguard Worker dup2(outfd, 1);
714*5e7646d2SAndroid Build Coastguard Worker close(outfd);
715*5e7646d2SAndroid Build Coastguard Worker }
716*5e7646d2SAndroid Build Coastguard Worker }
717*5e7646d2SAndroid Build Coastguard Worker
718*5e7646d2SAndroid Build Coastguard Worker if (backfd != 3 && backfd >= 0)
719*5e7646d2SAndroid Build Coastguard Worker {
720*5e7646d2SAndroid Build Coastguard Worker dup2(backfd, 3);
721*5e7646d2SAndroid Build Coastguard Worker close(backfd);
722*5e7646d2SAndroid Build Coastguard Worker fcntl(3, F_SETFL, O_NDELAY);
723*5e7646d2SAndroid Build Coastguard Worker }
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker if (sidefd != 4 && sidefd >= 0)
726*5e7646d2SAndroid Build Coastguard Worker {
727*5e7646d2SAndroid Build Coastguard Worker dup2(sidefd, 4);
728*5e7646d2SAndroid Build Coastguard Worker close(sidefd);
729*5e7646d2SAndroid Build Coastguard Worker fcntl(4, F_SETFL, O_NDELAY);
730*5e7646d2SAndroid Build Coastguard Worker }
731*5e7646d2SAndroid Build Coastguard Worker
732*5e7646d2SAndroid Build Coastguard Worker /*
733*5e7646d2SAndroid Build Coastguard Worker * Change the priority of the process based on the FilterNice setting.
734*5e7646d2SAndroid Build Coastguard Worker * (this is not done for root processes...)
735*5e7646d2SAndroid Build Coastguard Worker */
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker if (!root)
738*5e7646d2SAndroid Build Coastguard Worker nice(FilterNice);
739*5e7646d2SAndroid Build Coastguard Worker
740*5e7646d2SAndroid Build Coastguard Worker /*
741*5e7646d2SAndroid Build Coastguard Worker * Reset group membership to just the main one we belong to.
742*5e7646d2SAndroid Build Coastguard Worker */
743*5e7646d2SAndroid Build Coastguard Worker
744*5e7646d2SAndroid Build Coastguard Worker if (!RunUser && setgid(Group))
745*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
746*5e7646d2SAndroid Build Coastguard Worker
747*5e7646d2SAndroid Build Coastguard Worker if (!RunUser && setgroups(1, &Group))
748*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
749*5e7646d2SAndroid Build Coastguard Worker
750*5e7646d2SAndroid Build Coastguard Worker /*
751*5e7646d2SAndroid Build Coastguard Worker * Change user to something "safe"...
752*5e7646d2SAndroid Build Coastguard Worker */
753*5e7646d2SAndroid Build Coastguard Worker
754*5e7646d2SAndroid Build Coastguard Worker if (!RunUser && user && setuid(user))
755*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
756*5e7646d2SAndroid Build Coastguard Worker
757*5e7646d2SAndroid Build Coastguard Worker /*
758*5e7646d2SAndroid Build Coastguard Worker * Change umask to restrict permissions on created files...
759*5e7646d2SAndroid Build Coastguard Worker */
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker umask(077);
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker /*
764*5e7646d2SAndroid Build Coastguard Worker * Unblock signals before doing the exec...
765*5e7646d2SAndroid Build Coastguard Worker */
766*5e7646d2SAndroid Build Coastguard Worker
767*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_SIGSET
768*5e7646d2SAndroid Build Coastguard Worker sigset(SIGTERM, SIG_DFL);
769*5e7646d2SAndroid Build Coastguard Worker sigset(SIGCHLD, SIG_DFL);
770*5e7646d2SAndroid Build Coastguard Worker sigset(SIGPIPE, SIG_DFL);
771*5e7646d2SAndroid Build Coastguard Worker # elif defined(HAVE_SIGACTION)
772*5e7646d2SAndroid Build Coastguard Worker memset(&action, 0, sizeof(action));
773*5e7646d2SAndroid Build Coastguard Worker
774*5e7646d2SAndroid Build Coastguard Worker sigemptyset(&action.sa_mask);
775*5e7646d2SAndroid Build Coastguard Worker action.sa_handler = SIG_DFL;
776*5e7646d2SAndroid Build Coastguard Worker
777*5e7646d2SAndroid Build Coastguard Worker sigaction(SIGTERM, &action, NULL);
778*5e7646d2SAndroid Build Coastguard Worker sigaction(SIGCHLD, &action, NULL);
779*5e7646d2SAndroid Build Coastguard Worker sigaction(SIGPIPE, &action, NULL);
780*5e7646d2SAndroid Build Coastguard Worker # else
781*5e7646d2SAndroid Build Coastguard Worker signal(SIGTERM, SIG_DFL);
782*5e7646d2SAndroid Build Coastguard Worker signal(SIGCHLD, SIG_DFL);
783*5e7646d2SAndroid Build Coastguard Worker signal(SIGPIPE, SIG_DFL);
784*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_SIGSET */
785*5e7646d2SAndroid Build Coastguard Worker
786*5e7646d2SAndroid Build Coastguard Worker cupsdReleaseSignals();
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker /*
789*5e7646d2SAndroid Build Coastguard Worker * Execute the command; if for some reason this doesn't work, log an error
790*5e7646d2SAndroid Build Coastguard Worker * exit with a non-zero value...
791*5e7646d2SAndroid Build Coastguard Worker */
792*5e7646d2SAndroid Build Coastguard Worker
793*5e7646d2SAndroid Build Coastguard Worker if (envp)
794*5e7646d2SAndroid Build Coastguard Worker execve(exec_path, argv, envp);
795*5e7646d2SAndroid Build Coastguard Worker else
796*5e7646d2SAndroid Build Coastguard Worker execv(exec_path, argv);
797*5e7646d2SAndroid Build Coastguard Worker
798*5e7646d2SAndroid Build Coastguard Worker exit(errno + 100);
799*5e7646d2SAndroid Build Coastguard Worker }
800*5e7646d2SAndroid Build Coastguard Worker else if (*pid < 0)
801*5e7646d2SAndroid Build Coastguard Worker {
802*5e7646d2SAndroid Build Coastguard Worker /*
803*5e7646d2SAndroid Build Coastguard Worker * Error - couldn't fork a new process!
804*5e7646d2SAndroid Build Coastguard Worker */
805*5e7646d2SAndroid Build Coastguard Worker
806*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork %s - %s.", command,
807*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
808*5e7646d2SAndroid Build Coastguard Worker
809*5e7646d2SAndroid Build Coastguard Worker *pid = 0;
810*5e7646d2SAndroid Build Coastguard Worker }
811*5e7646d2SAndroid Build Coastguard Worker
812*5e7646d2SAndroid Build Coastguard Worker cupsdReleaseSignals();
813*5e7646d2SAndroid Build Coastguard Worker #endif /* USE_POSIX_SPAWN */
814*5e7646d2SAndroid Build Coastguard Worker
815*5e7646d2SAndroid Build Coastguard Worker if (*pid)
816*5e7646d2SAndroid Build Coastguard Worker {
817*5e7646d2SAndroid Build Coastguard Worker if (!process_array)
818*5e7646d2SAndroid Build Coastguard Worker process_array = cupsArrayNew((cups_array_func_t)compare_procs, NULL);
819*5e7646d2SAndroid Build Coastguard Worker
820*5e7646d2SAndroid Build Coastguard Worker if (process_array)
821*5e7646d2SAndroid Build Coastguard Worker {
822*5e7646d2SAndroid Build Coastguard Worker if ((proc = calloc(1, sizeof(cupsd_proc_t) + strlen(command))) != NULL)
823*5e7646d2SAndroid Build Coastguard Worker {
824*5e7646d2SAndroid Build Coastguard Worker proc->pid = *pid;
825*5e7646d2SAndroid Build Coastguard Worker proc->job_id = job ? job->id : 0;
826*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(proc->name, command);
827*5e7646d2SAndroid Build Coastguard Worker
828*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(process_array, proc);
829*5e7646d2SAndroid Build Coastguard Worker }
830*5e7646d2SAndroid Build Coastguard Worker }
831*5e7646d2SAndroid Build Coastguard Worker }
832*5e7646d2SAndroid Build Coastguard Worker
833*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
834*5e7646d2SAndroid Build Coastguard Worker "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, "
835*5e7646d2SAndroid Build Coastguard Worker "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, "
836*5e7646d2SAndroid Build Coastguard Worker "profile=%p, job=%p(%d), pid=%p) = %d",
837*5e7646d2SAndroid Build Coastguard Worker command, argv, envp, infd, outfd, errfd, backfd, sidefd,
838*5e7646d2SAndroid Build Coastguard Worker root, profile, job, job ? job->id : 0, pid, *pid);
839*5e7646d2SAndroid Build Coastguard Worker
840*5e7646d2SAndroid Build Coastguard Worker return (*pid);
841*5e7646d2SAndroid Build Coastguard Worker }
842*5e7646d2SAndroid Build Coastguard Worker
843*5e7646d2SAndroid Build Coastguard Worker
844*5e7646d2SAndroid Build Coastguard Worker /*
845*5e7646d2SAndroid Build Coastguard Worker * 'compare_procs()' - Compare two processes.
846*5e7646d2SAndroid Build Coastguard Worker */
847*5e7646d2SAndroid Build Coastguard Worker
848*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
compare_procs(cupsd_proc_t * a,cupsd_proc_t * b)849*5e7646d2SAndroid Build Coastguard Worker compare_procs(cupsd_proc_t *a, /* I - First process */
850*5e7646d2SAndroid Build Coastguard Worker cupsd_proc_t *b) /* I - Second process */
851*5e7646d2SAndroid Build Coastguard Worker {
852*5e7646d2SAndroid Build Coastguard Worker return (a->pid - b->pid);
853*5e7646d2SAndroid Build Coastguard Worker }
854*5e7646d2SAndroid Build Coastguard Worker
855*5e7646d2SAndroid Build Coastguard Worker
856*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SANDBOX_H
857*5e7646d2SAndroid Build Coastguard Worker /*
858*5e7646d2SAndroid Build Coastguard Worker * 'cupsd_requote()' - Make a regular-expression version of a string.
859*5e7646d2SAndroid Build Coastguard Worker */
860*5e7646d2SAndroid Build Coastguard Worker
861*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Quoted string */
cupsd_requote(char * dst,const char * src,size_t dstsize)862*5e7646d2SAndroid Build Coastguard Worker cupsd_requote(char *dst, /* I - Destination buffer */
863*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source string */
864*5e7646d2SAndroid Build Coastguard Worker size_t dstsize) /* I - Size of destination buffer */
865*5e7646d2SAndroid Build Coastguard Worker {
866*5e7646d2SAndroid Build Coastguard Worker int ch; /* Current character */
867*5e7646d2SAndroid Build Coastguard Worker char *dstptr, /* Current position in buffer */
868*5e7646d2SAndroid Build Coastguard Worker *dstend; /* End of destination buffer */
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker
871*5e7646d2SAndroid Build Coastguard Worker dstptr = dst;
872*5e7646d2SAndroid Build Coastguard Worker dstend = dst + dstsize - 2;
873*5e7646d2SAndroid Build Coastguard Worker
874*5e7646d2SAndroid Build Coastguard Worker while (*src && dstptr < dstend)
875*5e7646d2SAndroid Build Coastguard Worker {
876*5e7646d2SAndroid Build Coastguard Worker ch = *src++;
877*5e7646d2SAndroid Build Coastguard Worker
878*5e7646d2SAndroid Build Coastguard Worker if (ch == '/' && !*src)
879*5e7646d2SAndroid Build Coastguard Worker break; /* Don't add trailing slash */
880*5e7646d2SAndroid Build Coastguard Worker
881*5e7646d2SAndroid Build Coastguard Worker if (strchr(".?*()[]^$\\\"", ch))
882*5e7646d2SAndroid Build Coastguard Worker *dstptr++ = '\\';
883*5e7646d2SAndroid Build Coastguard Worker
884*5e7646d2SAndroid Build Coastguard Worker *dstptr++ = (char)ch;
885*5e7646d2SAndroid Build Coastguard Worker }
886*5e7646d2SAndroid Build Coastguard Worker
887*5e7646d2SAndroid Build Coastguard Worker *dstptr = '\0';
888*5e7646d2SAndroid Build Coastguard Worker
889*5e7646d2SAndroid Build Coastguard Worker return (dst);
890*5e7646d2SAndroid Build Coastguard Worker }
891*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SANDBOX_H */
892