Index: trunk/switchboard/swexec.c |
— | — | @@ -1,3 +1,5 @@ |
| 2 | +/* Copyright 2008 The Apache Software Foundation. */ |
| 3 | +/* Copyright 2008 River Tarnell <river@wikimedia.org */ |
2 | 4 | /* Licensed to the Apache Software Foundation (ASF) under one or more |
3 | 5 | * contributor license agreements. See the NOTICE file distributed with |
4 | 6 | * this work for additional information regarding copyright ownership. |
— | — | @@ -16,36 +18,34 @@ |
17 | 19 | |
18 | 20 | /* |
19 | 21 | * suexec.c -- "Wrapper" support program for suEXEC behaviour for Apache |
20 | | - * |
21 | | - *********************************************************************** |
22 | | - * |
23 | | - * NOTE! : DO NOT edit this code!!! Unless you know what you are doing, |
24 | | - * editing this code might open up your system in unexpected |
25 | | - * ways to would-be crackers. Every precaution has been taken |
26 | | - * to make this code as safe as possible; alter it at your own |
27 | | - * risk. |
28 | | - * |
29 | | - *********************************************************************** |
30 | | - * |
31 | | - * |
32 | 22 | */ |
33 | 23 | |
| 24 | +#if defined(__sun) && defined(__svr4__) |
| 25 | +/* Solaris */ |
| 26 | +# define USE_PROJECTS |
| 27 | +#endif |
| 28 | + |
34 | 29 | #define SB_SUEXEC_UMASK 022 |
35 | 30 | |
36 | | -#include <sys/param.h> |
37 | | -#include <sys/stat.h> |
38 | | -#include <sys/types.h> |
39 | | -#include <string.h> |
40 | | -#include <time.h> |
41 | | -#include <unistd.h> |
42 | | -#include <stdio.h> |
43 | | -#include <stdarg.h> |
44 | | -#include <stdlib.h> |
45 | | -#include <errno.h> |
| 31 | +#include <sys/param.h> |
| 32 | +#include <sys/stat.h> |
| 33 | +#include <sys/types.h> |
| 34 | +#include <string.h> |
| 35 | +#include <time.h> |
| 36 | +#include <unistd.h> |
| 37 | +#include <stdio.h> |
| 38 | +#include <stdarg.h> |
| 39 | +#include <stdlib.h> |
| 40 | +#include <errno.h> |
46 | 41 | |
47 | | -#include <pwd.h> |
48 | | -#include <grp.h> |
| 42 | +#ifdef USE_PROJECTS |
| 43 | +# include <sys/task.h> |
| 44 | +# include <project.h> |
| 45 | +#endif |
49 | 46 | |
| 47 | +#include <pwd.h> |
| 48 | +#include <grp.h> |
| 49 | + |
50 | 50 | #if defined(PATH_MAX) |
51 | 51 | #define SB_MAXPATH PATH_MAX |
52 | 52 | #elif defined(MAXPATHLEN) |
— | — | @@ -66,9 +66,9 @@ |
67 | 67 | }; |
68 | 68 | |
69 | 69 | |
70 | | -static void err_output(int is_error, const char *fmt, va_list ap) |
| 70 | +static void |
| 71 | +err_output(int is_error, const char *fmt, va_list ap) |
71 | 72 | { |
72 | | -#ifdef SB_LOG_EXEC |
73 | 73 | time_t timevar; |
74 | 74 | struct tm *lt; |
75 | 75 | |
— | — | @@ -95,262 +95,274 @@ |
96 | 96 | vfprintf(log, fmt, ap); |
97 | 97 | |
98 | 98 | fflush(log); |
99 | | -#endif /* SB_LOG_EXEC */ |
100 | | - return; |
101 | 99 | } |
102 | 100 | |
103 | | -static void log_err(const char *fmt,...) |
| 101 | +static void |
| 102 | +log_err(const char *fmt,...) |
104 | 103 | { |
105 | | -#ifdef SB_LOG_EXEC |
106 | 104 | va_list ap; |
107 | 105 | |
108 | 106 | va_start(ap, fmt); |
109 | 107 | err_output(1, fmt, ap); /* 1 == is_error */ |
110 | 108 | va_end(ap); |
111 | | -#endif /* SB_LOG_EXEC */ |
112 | | - return; |
113 | 109 | } |
114 | 110 | |
115 | | -static void log_no_err(const char *fmt,...) |
| 111 | +static void |
| 112 | +log_no_err(const char *fmt,...) |
116 | 113 | { |
117 | | -#ifdef SB_LOG_EXEC |
118 | 114 | va_list ap; |
119 | 115 | |
120 | 116 | va_start(ap, fmt); |
121 | 117 | err_output(0, fmt, ap); /* 0 == !is_error */ |
122 | 118 | va_end(ap); |
123 | | -#endif /* SB_LOG_EXEC */ |
124 | | - return; |
125 | 119 | } |
126 | 120 | |
127 | | -static void clean_env(void) |
| 121 | +static void |
| 122 | +clean_env(void) |
128 | 123 | { |
129 | | - char envbuf[512]; |
130 | | - char **cleanenv; |
131 | | - char **ep; |
132 | | - int cidx = 0; |
133 | | - int idx; |
| 124 | + char envbuf[512]; |
| 125 | + char **cleanenv; |
| 126 | + char **ep; |
| 127 | + int cidx = 0; |
| 128 | + int idx; |
134 | 129 | |
135 | | - /* While cleaning the environment, the environment should be clean. |
136 | | - * (e.g. malloc() may get the name of a file for writing debugging info. |
137 | | - * Bad news if MALLOC_DEBUG_FILE is set to /etc/passwd. Sprintf() may be |
138 | | - * susceptible to bad locale settings....) |
139 | | - * (from PR 2790) |
140 | | - */ |
141 | | - char **envp = environ; |
142 | | - char *empty_ptr = NULL; |
| 130 | + /* While cleaning the environment, the environment should be clean. |
| 131 | + * (e.g. malloc() may get the name of a file for writing debugging info. |
| 132 | + * Bad news if MALLOC_DEBUG_FILE is set to /etc/passwd. Sprintf() may be |
| 133 | + * susceptible to bad locale settings....) |
| 134 | + * (from PR 2790) |
| 135 | + */ |
| 136 | + char **envp = environ; |
| 137 | + char *empty_ptr = NULL; |
143 | 138 | |
144 | | - environ = &empty_ptr; /* VERY safe environment */ |
| 139 | + environ = &empty_ptr; /* VERY safe environment */ |
145 | 140 | |
146 | | - if ((cleanenv = (char **) calloc(SB_ENVBUF, sizeof(char *))) == NULL) { |
147 | | - log_err("failed to malloc memory for environment\n"); |
148 | | - exit(120); |
149 | | - } |
| 141 | + if ((cleanenv = (char **) calloc(SB_ENVBUF, sizeof(char *))) == NULL) { |
| 142 | + log_err("failed to malloc memory for environment\n"); |
| 143 | + exit(120); |
| 144 | + } |
150 | 145 | |
151 | | - sprintf(envbuf, "PATH=%s", SB_SAFE_PATH); |
152 | | - cleanenv[cidx] = strdup(envbuf); |
153 | | - cidx++; |
154 | | - sprintf(envbuf, "PHP_FCGI_MAX_REQUESTS=5000"); |
155 | | - cleanenv[cidx] = strdup(envbuf); |
156 | | - cidx++; |
| 146 | + sprintf(envbuf, "PATH=%s", SB_SAFE_PATH); |
| 147 | + cleanenv[cidx] = strdup(envbuf); |
| 148 | + cidx++; |
| 149 | + sprintf(envbuf, "PHP_FCGI_MAX_REQUESTS=5000"); |
| 150 | + cleanenv[cidx] = strdup(envbuf); |
| 151 | + cidx++; |
157 | 152 | |
158 | | - for (ep = envp; *ep && cidx < SB_ENVBUF-1; ep++) { |
159 | | - for (idx = 0; safe_env_lst[idx]; idx++) { |
160 | | - if (!strncmp(*ep, safe_env_lst[idx], |
161 | | - strlen(safe_env_lst[idx]))) { |
162 | | - cleanenv[cidx] = *ep; |
163 | | - cidx++; |
164 | | - break; |
165 | | - } |
166 | | - } |
167 | | - } |
| 153 | + for (ep = envp; *ep && cidx < SB_ENVBUF-1; ep++) { |
| 154 | + for (idx = 0; safe_env_lst[idx]; idx++) { |
| 155 | + if (!strncmp(*ep, safe_env_lst[idx], |
| 156 | + strlen(safe_env_lst[idx]))) { |
| 157 | + cleanenv[cidx] = *ep; |
| 158 | + cidx++; |
| 159 | + break; |
| 160 | + } |
| 161 | + } |
| 162 | + } |
168 | 163 | |
169 | | - cleanenv[cidx] = NULL; |
| 164 | + cleanenv[cidx] = NULL; |
170 | 165 | |
171 | | - environ = cleanenv; |
| 166 | + environ = cleanenv; |
172 | 167 | } |
173 | 168 | |
174 | | -int main(int argc, char *argv[]) |
| 169 | +int |
| 170 | +main(int argc, char *argv[]) |
175 | 171 | { |
176 | | - int userdir = 0; /* ~userdir flag */ |
177 | | - uid_t uid; /* user information */ |
178 | | - gid_t gid; /* target group placeholder */ |
179 | | - char *target_uname; /* target user name */ |
180 | | - char *target_gname; /* target group name */ |
181 | | - char *target_homedir; /* target home directory */ |
182 | | - char *actual_uname; /* actual user name */ |
183 | | - char *actual_gname; /* actual group name */ |
184 | | - char *prog; /* name of this program */ |
185 | | - struct passwd *pw; /* password entry holder */ |
186 | | - struct group *gr; /* group entry holder */ |
| 172 | + int userdir = 0; /* ~userdir flag */ |
| 173 | + uid_t uid; /* user information */ |
| 174 | + gid_t gid; /* target group placeholder */ |
| 175 | + char *target_uname; /* target user name */ |
| 176 | + char *target_gname; /* target group name */ |
| 177 | + char *target_homedir; /* target home directory */ |
| 178 | + char *actual_uname; /* actual user name */ |
| 179 | + char *actual_gname; /* actual group name */ |
| 180 | + char *prog; /* name of this program */ |
| 181 | + struct passwd *pw; /* password entry holder */ |
| 182 | + struct group *gr; /* group entry holder */ |
| 183 | +#ifdef USE_PROJECTS |
| 184 | + struct project proj; |
| 185 | + char nssbuf[PROJECT_BUFSZ]; |
| 186 | +#endif |
187 | 187 | |
188 | | - /* |
189 | | - * Start with a "clean" environment |
190 | | - */ |
191 | | - clean_env(); |
| 188 | + /* |
| 189 | + * Start with a "clean" environment |
| 190 | + */ |
| 191 | + clean_env(); |
192 | 192 | |
193 | | - prog = argv[0]; |
194 | | - /* |
195 | | - * Check existence/validity of the UID of the user |
196 | | - * running this program. Error out if invalid. |
197 | | - */ |
198 | | - uid = getuid(); |
199 | | - if ((pw = getpwuid(uid)) == NULL) { |
200 | | - log_err("crit: invalid uid: (%ld)\n", uid); |
201 | | - exit(102); |
202 | | - } |
| 193 | + prog = argv[0]; |
| 194 | + /* |
| 195 | + * Check existence/validity of the UID of the user |
| 196 | + * running this program. Error out if invalid. |
| 197 | + */ |
| 198 | + uid = getuid(); |
| 199 | + if ((pw = getpwuid(uid)) == NULL) { |
| 200 | + log_err("crit: invalid uid: (%ld)\n", (long) uid); |
| 201 | + exit(102); |
| 202 | + } |
203 | 203 | |
204 | | - /* |
205 | | - * If there are a proper number of arguments, set |
206 | | - * all of them to variables. Otherwise, error out. |
207 | | - */ |
208 | | - if (argc < 3) { |
209 | | - log_err("too few arguments\n"); |
210 | | - exit(101); |
211 | | - } |
212 | | - target_uname = argv[1]; |
213 | | - target_gname = argv[2]; |
| 204 | + /* |
| 205 | + * If there are a proper number of arguments, set |
| 206 | + * all of them to variables. Otherwise, error out. |
| 207 | + */ |
| 208 | + if (argc < 3) { |
| 209 | + log_err("too few arguments\n"); |
| 210 | + exit(101); |
| 211 | + } |
| 212 | + target_uname = argv[1]; |
| 213 | + target_gname = argv[2]; |
214 | 214 | |
215 | | - /* |
216 | | - * Check to see if the user running this program |
217 | | - * is the user allowed to do so as defined in |
218 | | - * suexec.h. If not the allowed user, error out. |
219 | | - */ |
220 | | - if (strcmp(SB_USER, pw->pw_name)) { |
221 | | - log_err("user mismatch (%s instead of %s)\n", pw->pw_name, SB_USER); |
222 | | - exit(103); |
223 | | - } |
| 215 | + /* |
| 216 | + * Check to see if the user running this program |
| 217 | + * is the user allowed to do so as defined in |
| 218 | + * suexec.h. If not the allowed user, error out. |
| 219 | + */ |
| 220 | + if (strcmp(SB_USER, pw->pw_name)) { |
| 221 | + log_err("user mismatch (%s instead of %s)\n", pw->pw_name, SB_USER); |
| 222 | + exit(103); |
| 223 | + } |
224 | 224 | |
225 | | - /* |
226 | | - * Error out if the target username is invalid. |
227 | | - */ |
228 | | - if (strspn(target_uname, "1234567890") != strlen(target_uname)) { |
229 | | - if ((pw = getpwnam(target_uname)) == NULL) { |
230 | | - log_err("invalid target user name: (%s)\n", target_uname); |
231 | | - exit(105); |
232 | | - } |
233 | | - } |
234 | | - else { |
235 | | - if ((pw = getpwuid(atoi(target_uname))) == NULL) { |
236 | | - log_err("invalid target user id: (%s)\n", target_uname); |
237 | | - exit(121); |
238 | | - } |
239 | | - } |
| 225 | + /* |
| 226 | + * Error out if the target username is invalid. |
| 227 | + */ |
| 228 | + if (strspn(target_uname, "1234567890") != strlen(target_uname)) { |
| 229 | + if ((pw = getpwnam(target_uname)) == NULL) { |
| 230 | + log_err("invalid target user name: (%s)\n", target_uname); |
| 231 | + exit(105); |
| 232 | + } |
| 233 | + } else { |
| 234 | + if ((pw = getpwuid(atoi(target_uname))) == NULL) { |
| 235 | + log_err("invalid target user id: (%s)\n", target_uname); |
| 236 | + exit(121); |
| 237 | + } |
| 238 | + } |
240 | 239 | |
241 | | - /* |
242 | | - * Error out if the target group name is invalid. |
243 | | - */ |
244 | | - if (strspn(target_gname, "1234567890") != strlen(target_gname)) { |
245 | | - if ((gr = getgrnam(target_gname)) == NULL) { |
246 | | - log_err("invalid target group name: (%s)\n", target_gname); |
247 | | - exit(106); |
248 | | - } |
249 | | - } |
250 | | - else { |
251 | | - if ((gr = getgrgid(atoi(target_gname))) == NULL) { |
252 | | - log_err("invalid target group id: (%s)\n", target_gname); |
253 | | - exit(106); |
254 | | - } |
255 | | - } |
256 | | - gid = gr->gr_gid; |
257 | | - actual_gname = strdup(gr->gr_name); |
| 240 | + /* |
| 241 | + * Error out if the target group name is invalid. |
| 242 | + */ |
| 243 | + if (strspn(target_gname, "1234567890") != strlen(target_gname)) { |
| 244 | + if ((gr = getgrnam(target_gname)) == NULL) { |
| 245 | + log_err("invalid target group name: (%s)\n", target_gname); |
| 246 | + exit(106); |
| 247 | + } |
| 248 | + } else { |
| 249 | + if ((gr = getgrgid(atoi(target_gname))) == NULL) { |
| 250 | + log_err("invalid target group id: (%s)\n", target_gname); |
| 251 | + exit(106); |
| 252 | + } |
| 253 | + } |
| 254 | + gid = gr->gr_gid; |
| 255 | + actual_gname = strdup(gr->gr_name); |
258 | 256 | |
259 | | - /* |
260 | | - * Save these for later since initgroups will hose the struct |
261 | | - */ |
262 | | - uid = pw->pw_uid; |
263 | | - actual_uname = strdup(pw->pw_name); |
264 | | - target_homedir = strdup(pw->pw_dir); |
| 257 | + /* |
| 258 | + * Save these for later since initgroups will hose the struct |
| 259 | + */ |
| 260 | + uid = pw->pw_uid; |
| 261 | + actual_uname = strdup(pw->pw_name); |
| 262 | + target_homedir = strdup(pw->pw_dir); |
265 | 263 | |
266 | | - /* |
267 | | - * Log the transaction here to be sure we have an open log |
268 | | - * before we setuid(). |
269 | | - */ |
270 | | - log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", |
271 | | - target_uname, actual_uname, |
272 | | - target_gname, actual_gname, |
273 | | - PHP_BIN); |
| 264 | + /* |
| 265 | + * Log the transaction here to be sure we have an open log |
| 266 | + * before we setuid(). |
| 267 | + */ |
| 268 | + log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", |
| 269 | + target_uname, actual_uname, |
| 270 | + target_gname, actual_gname, |
| 271 | + PHP_BIN); |
274 | 272 | |
275 | | - /* |
276 | | - * Error out if attempt is made to execute as root or as |
277 | | - * a UID less than SB_UID_MIN. Tsk tsk. |
278 | | - */ |
279 | | - if ((uid == 0) || (uid < SB_UID_MIN)) { |
280 | | - log_err("cannot run as forbidden uid (%d/%s)\n", uid, PHP_BIN); |
281 | | - exit(107); |
282 | | - } |
| 273 | + /* |
| 274 | + * Error out if attempt is made to execute as root or as |
| 275 | + * a UID less than SB_UID_MIN. Tsk tsk. |
| 276 | + */ |
| 277 | + if ((uid == 0) || (uid < SB_UID_MIN)) { |
| 278 | + log_err("cannot run as forbidden uid (%d/%s)\n", uid, PHP_BIN); |
| 279 | + exit(107); |
| 280 | + } |
283 | 281 | |
284 | | - /* |
285 | | - * Error out if attempt is made to execute as root group |
286 | | - * or as a GID less than SB_GID_MIN. Tsk tsk. |
287 | | - */ |
288 | | - if ((gid == 0) || (gid < SB_GID_MIN)) { |
289 | | - log_err("cannot run as forbidden gid (%d/%s)\n", gid, PHP_BIN); |
290 | | - exit(108); |
291 | | - } |
| 282 | + /* |
| 283 | + * Error out if attempt is made to execute as root group |
| 284 | + * or as a GID less than SB_GID_MIN. Tsk tsk. |
| 285 | + */ |
| 286 | + if ((gid == 0) || (gid < SB_GID_MIN)) { |
| 287 | + log_err("cannot run as forbidden gid (%d/%s)\n", gid, PHP_BIN); |
| 288 | + exit(108); |
| 289 | + } |
292 | 290 | |
293 | | - /* |
294 | | - * Change UID/GID here so that the following tests work over NFS. |
295 | | - * |
296 | | - * Initialize the group access list for the target user, |
297 | | - * and setgid() to the target group. If unsuccessful, error out. |
298 | | - */ |
299 | | - if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0)) { |
300 | | - log_err("failed to setgid (%ld: %s)\n", gid, PHP_BIN); |
301 | | - exit(109); |
302 | | - } |
| 291 | +#ifdef USE_PROJECTS |
| 292 | + if (getdefaultproj(actual_uname, &proj, nssbuf, sizeof(nssbuf)) == NULL) { |
| 293 | + log_err("failed to get default project (%s: %s)", |
| 294 | + actual_uname, strerror(errno)); |
| 295 | + exit(113); |
| 296 | + } |
303 | 297 | |
304 | | - /* |
305 | | - * setuid() to the target user. Error out on fail. |
306 | | - */ |
307 | | - if ((setuid(uid)) != 0) { |
308 | | - log_err("failed to setuid (%ld: %s)\n", uid, PHP_BIN); |
309 | | - exit(110); |
310 | | - } |
| 298 | + if (setproject(proj.pj_name, actual_uname, TASK_FINAL) != 0) { |
| 299 | + log_err("failed to set project (%s: %s)", |
| 300 | + actual_uname, strerror(errno)); |
| 301 | + exit(114); |
| 302 | + } |
| 303 | +#endif |
| 304 | + |
| 305 | + /* |
| 306 | + * Change UID/GID here so that the following tests work over NFS. |
| 307 | + * |
| 308 | + * Initialize the group access list for the target user, |
| 309 | + * and setgid() to the target group. If unsuccessful, error out. |
| 310 | + */ |
| 311 | + if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0)) { |
| 312 | + log_err("failed to setgid (%ld: %s)\n", (long) gid, PHP_BIN); |
| 313 | + exit(109); |
| 314 | + } |
311 | 315 | |
312 | | - if (chdir(target_homedir) != 0) { |
313 | | - log_err("cannot chdir to home directory (%s)\n", target_homedir); |
314 | | - exit(112); |
315 | | - } |
| 316 | + /* |
| 317 | + * setuid() to the target user. Error out on fail. |
| 318 | + */ |
| 319 | + if ((setuid(uid)) != 0) { |
| 320 | + log_err("failed to setuid (%ld: %s)\n", (long) uid, PHP_BIN); |
| 321 | + exit(110); |
| 322 | + } |
316 | 323 | |
| 324 | + if (chdir(target_homedir) != 0) { |
| 325 | + log_err("cannot chdir to home directory (%s)\n", target_homedir); |
| 326 | + exit(112); |
| 327 | + } |
| 328 | + |
317 | 329 | #ifdef SB_SUEXEC_UMASK |
318 | | - /* |
319 | | - * umask() uses inverse logic; bits are CLEAR for allowed access. |
320 | | - */ |
321 | | - if ((~SB_SUEXEC_UMASK) & 0022) { |
322 | | - log_err("notice: SB_SUEXEC_UMASK of %03o allows " |
323 | | - "write permission to group and/or other\n", SB_SUEXEC_UMASK); |
324 | | - } |
325 | | - umask(SB_SUEXEC_UMASK); |
| 330 | + /* |
| 331 | + * umask() uses inverse logic; bits are CLEAR for allowed access. |
| 332 | + */ |
| 333 | + if ((~SB_SUEXEC_UMASK) & 0022) { |
| 334 | + log_err("notice: SB_SUEXEC_UMASK of %03o allows " |
| 335 | + "write permission to group and/or other\n", SB_SUEXEC_UMASK); |
| 336 | + } |
| 337 | + umask(SB_SUEXEC_UMASK); |
326 | 338 | #endif /* SB_SUEXEC_UMASK */ |
327 | 339 | |
328 | | - /* |
329 | | - * Be sure to close the log file so the CGI can't |
330 | | - * mess with it. If the exec fails, it will be reopened |
331 | | - * automatically when log_err is called. Note that the log |
332 | | - * might not actually be open if SB_LOG_EXEC isn't defined. |
333 | | - * However, the "log" cell isn't ifdef'd so let's be defensive |
334 | | - * and assume someone might have done something with it |
335 | | - * outside an ifdef'd SB_LOG_EXEC block. |
336 | | - */ |
337 | | - if (log != NULL) { |
338 | | - fclose(log); |
339 | | - log = NULL; |
340 | | - } |
| 340 | + /* |
| 341 | + * Be sure to close the log file so the CGI can't |
| 342 | + * mess with it. If the exec fails, it will be reopened |
| 343 | + * automatically when log_err is called. Note that the log |
| 344 | + * might not actually be open if SB_LOG_EXEC isn't defined. |
| 345 | + * However, the "log" call isn't ifdef'd so let's be defensive |
| 346 | + * and assume someone might have done something with it |
| 347 | + * outside an ifdef'd SB_LOG_EXEC block. |
| 348 | + */ |
| 349 | + if (log != NULL) { |
| 350 | + fclose(log); |
| 351 | + log = NULL; |
| 352 | + } |
341 | 353 | |
342 | | - /* |
343 | | - * Execute the command, replacing our image with its own. |
344 | | - */ |
345 | | - execl(PHP_BIN, PHP_BIN, NULL); |
| 354 | + /* |
| 355 | + * Execute the command, replacing our image with its own. |
| 356 | + */ |
| 357 | + execl(PHP_BIN, PHP_BIN, NULL); |
346 | 358 | |
347 | | - /* |
348 | | - * (I can't help myself...sorry.) |
349 | | - * |
350 | | - * Uh oh. Still here. Where's the kaboom? There was supposed to be an |
351 | | - * EARTH-shattering kaboom! |
352 | | - * |
353 | | - * Oh well, log the failure and error out. |
354 | | - */ |
355 | | - log_err("(%d)%s: exec failed (%s)\n", errno, strerror(errno), PHP_BIN); |
356 | | - exit(255); |
| 359 | + /* |
| 360 | + * (I can't help myself...sorry.) |
| 361 | + * |
| 362 | + * Uh oh. Still here. Where's the kaboom? There was supposed to be an |
| 363 | + * EARTH-shattering kaboom! |
| 364 | + * |
| 365 | + * Oh well, log the failure and error out. |
| 366 | + */ |
| 367 | + log_err("(%d)%s: exec failed (%s)\n", errno, strerror(errno), PHP_BIN); |
| 368 | + exit(255); |
357 | 369 | } |
Index: trunk/switchboard/Makefile.config.example |
— | — | @@ -31,8 +31,11 @@ |
32 | 32 | EXTRA_LIBS= |
33 | 33 | |
34 | 34 | # For Solaris: |
35 | | -EXTRA_LIBS+=-lsocket -lnsl |
| 35 | +EXTRA_LIBS+=-lsocket -lnsl -lproject |
36 | 36 | |
| 37 | +# swexec needs this for project support on solaris |
| 38 | +SWEXEC_EXTRA_LIBS = -lproject |
| 39 | + |
37 | 40 | # install program, /usr/ucb/install for Solaris, otherwise /usr/bin/install |
38 | 41 | INSTALL=/usr/ucb/install |
39 | 42 | |
Index: trunk/switchboard/Makefile |
— | — | @@ -49,7 +49,7 @@ |
50 | 50 | $(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o $(PROG) $(LIBS) |
51 | 51 | |
52 | 52 | $(SWEXEC): swexec.o |
53 | | - $(CC) $(CFLAGS) $(LDFLAGS) swexec.o -o $(SWEXEC) |
| 53 | + $(CC) $(CFLAGS) $(LDFLAGS) swexec.o -o $(SWEXEC) $(SWEXEC_EXTRA_LIBS) |
54 | 54 | |
55 | 55 | $(SWKILL): swkill.o |
56 | 56 | $(CC) $(CFLAGS) $(LDFLAGS) swkill.o -o $(SWKILL) |