• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Environment management routines for the CUPS scheduler.
3  *
4  * Copyright © 2020-2024 by OpenPrinting.
5  * Copyright © 2007-2016 by Apple Inc.
6  * Copyright © 1997-2006 by Easy Software Products, all rights reserved.
7  *
8  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
9  * information.
10  */
11 
12 /*
13  * Include necessary headers...
14  */
15 
16 #include "cupsd.h"
17 
18 
19 /*
20  * Local globals...
21  */
22 
23 static int	num_common_env = 0;	/* Number of common env vars */
24 static char	*common_env[MAX_ENV];	/* Common env vars */
25 
26 
27 /*
28  * Local functions...
29  */
30 
31 static void	clear_env(void);
32 static int	find_env(const char *name);
33 
34 
35 /*
36  * 'cupsdInitEnv()' - Initialize the current environment with standard variables.
37  */
38 
39 void
cupsdInitEnv(void)40 cupsdInitEnv(void)
41 {
42  /*
43   * Clear existing environment variables...
44   */
45 
46   clear_env();
47 
48 #if defined(__APPLE__)
49  /*
50   * Add special voodoo magic for macOS - this allows macOS
51   * programs to access their bundle resources properly...
52   *
53   * This string is replaced in cupsdStartProcess()...
54   */
55 
56   cupsdSetString(common_env, "<CFProcessPath>");
57   num_common_env = 1;
58 #endif	/* __APPLE__ */
59 }
60 
61 
62 /*
63  * 'cupsdLoadEnv()' - Copy common environment variables into an array.
64  */
65 
66 int					/* O - Number of environment variables */
cupsdLoadEnv(char * envp[],int envmax)67 cupsdLoadEnv(char *envp[],		/* I - Environment array */
68              int  envmax)		/* I - Maximum number of elements */
69 {
70   int	i;				/* Looping var */
71 
72 
73  /*
74   * Leave room for a NULL pointer at the end...
75   */
76 
77   envmax --;
78 
79  /*
80   * Copy pointers to the environment...
81   */
82 
83   for (i = 0; i < num_common_env && i < envmax; i ++)
84     envp[i] = common_env[i];
85 
86  /*
87   * NULL terminate the environment array and return the number of
88   * elements we added...
89   */
90 
91   envp[i] = NULL;
92 
93   return (i);
94 }
95 
96 
97 /*
98  * 'cupsdSetEnv()' - Set a common environment variable.
99  */
100 
101 void
cupsdSetEnv(const char * name,const char * value)102 cupsdSetEnv(const char *name,		/* I - Name of variable */
103             const char *value)		/* I - Value of variable */
104 {
105   int	i;				/* Index into environment array */
106 
107 
108  /*
109   * If "value" is NULL, try getting value from current environment...
110   */
111 
112   if (!value)
113     value = getenv(name);
114 
115   if (!value)
116     return;
117 
118  /*
119   * Do not allow dynamic linker variables when running as root outside a Snap...
120   */
121 
122 #if !CUPS_SNAP
123   if (!RunUser && (!strncmp(name, "DYLD_", 5) || !strncmp(name, "LD_", 3)))
124     return;
125 #endif /* !CUPS_SNAP */
126 
127  /*
128   * See if this variable has already been defined...
129   */
130 
131   if ((i = find_env(name)) < 0)
132   {
133    /*
134     * Check for room...
135     */
136 
137     if (num_common_env >= (int)(sizeof(common_env) / sizeof(common_env[0])))
138     {
139       cupsdLogMessage(CUPSD_LOG_ERROR,
140                       "cupsdSetEnv: Too many environment variables set!");
141       return;
142     }
143 
144     i = num_common_env;
145     num_common_env ++;
146   }
147 
148  /*
149   * Set the new environment variable...
150   */
151 
152   cupsdSetStringf(common_env + i, "%s=%s", name, value);
153 
154   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSetEnv: %s", common_env[i]);
155 }
156 
157 
158 /*
159  * 'cupsdSetEnvf()' - Set a formatted common environment variable.
160  */
161 
162 void
cupsdSetEnvf(const char * name,const char * value,...)163 cupsdSetEnvf(const char *name,		/* I - Name of variable */
164              const char *value,		/* I - Printf-style value of variable */
165 	     ...)			/* I - Additional args as needed */
166 {
167   char		v[4096];		/* Formatting string value */
168   va_list	ap;			/* Argument pointer */
169 
170 
171  /*
172   * Format the value string...
173   */
174 
175   va_start(ap, value);
176   vsnprintf(v, sizeof(v), value, ap);
177   va_end(ap);
178 
179  /*
180   * Set the env variable...
181   */
182 
183   cupsdSetEnv(name, v);
184 }
185 
186 
187 /*
188  * 'cupsdUpdateEnv()' - Update the environment for the configured directories.
189  */
190 
191 void
cupsdUpdateEnv(void)192 cupsdUpdateEnv(void)
193 {
194  /*
195   * Set common variables...
196   */
197 
198 #define set_if_undefined(name,value) if (find_env(name) < 0) cupsdSetEnv(name,value)
199 
200   set_if_undefined("CUPS_CACHEDIR", CacheDir);
201   set_if_undefined("CUPS_DATADIR", DataDir);
202   set_if_undefined("CUPS_DOCROOT", DocumentRoot);
203   set_if_undefined("CUPS_REQUESTROOT", RequestRoot);
204   set_if_undefined("CUPS_SERVERBIN", ServerBin);
205   set_if_undefined("CUPS_SERVERROOT", ServerRoot);
206   set_if_undefined("CUPS_STATEDIR", StateDir);
207   set_if_undefined("DYLD_INSERT_LIBRARIES", NULL);
208   set_if_undefined("DYLD_LIBRARY_PATH", NULL);
209   set_if_undefined("HOME", TempDir);
210   set_if_undefined("LD_ASSUME_KERNEL", NULL);
211   set_if_undefined("LD_LIBRARY_PATH", NULL);
212   set_if_undefined("LD_PRELOAD", NULL);
213   set_if_undefined("NLSPATH", NULL);
214   if (find_env("PATH") < 0)
215   {
216 #if CUPS_SNAP
217     const char	*path;			// PATH environment variable
218 
219     if ((path = getenv("PATH")) != NULL)
220       cupsdSetEnvf("PATH", "%s/filter:%s", ServerBin, path);
221     else
222 #endif /* CUPS_SNAP */
223     cupsdSetEnvf("PATH", "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin", ServerBin);
224   }
225   set_if_undefined("SERVER_ADMIN", ServerAdmin);
226   set_if_undefined("SHLIB_PATH", NULL);
227   set_if_undefined("SOFTWARE", CUPS_MINIMAL);
228   set_if_undefined("TMPDIR", TempDir);
229   set_if_undefined("TZ", NULL);
230   set_if_undefined("USER", "root");
231   set_if_undefined("VG_ARGS", NULL);
232 
233   cupsdSetEnvf("CUPS_MAX_MESSAGE", "%d", CUPSD_SB_BUFFER_SIZE - 1);
234 }
235 
236 
237 /*
238  * 'clear_env()' - Clear common environment variables.
239  */
240 
241 static void
clear_env(void)242 clear_env(void)
243 {
244   int	i;				/* Looping var */
245 
246 
247   for (i = 0; i < num_common_env; i ++)
248     cupsdClearString(common_env + i);
249 
250   num_common_env = 0;
251 }
252 
253 
254 /*
255  * 'find_env()' - Find a common environment variable.
256  */
257 
258 static int				/* O - Index or -1 if not found */
find_env(const char * name)259 find_env(const char *name)		/* I - Variable name */
260 {
261   int		i;			/* Looping var */
262   size_t	namelen;		/* Length of name */
263 
264 
265   for (i = 0, namelen = strlen(name); i < num_common_env; i ++)
266     if (!strncmp(common_env[i], name, namelen) && common_env[i][namelen] == '=')
267       return (i);
268 
269   return (-1);
270 }
271