xref: /aosp_15_r20/external/libcups/scheduler/process.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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