1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
|
/****************************************************************
* *
* Copyright (c) 2008-2023 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
/********************************************************************************************
* W A R N I N G --- W A R N I N G --- W A R N I N G --- W A R N I N G --- W A R N I N G *
* *
* This routine (gtmsecshr_wrapper) runs as setuid to root to perform "environmental *
* cleanup" prior to invoking gtmsecshr proper. Extreme care must be taken to prevent all *
* forms of deceptive access, linking with unauthorized libraries, etc. Same applies to *
* anything it calls. *
* *
* W A R N I N G --- W A R N I N G --- W A R N I N G --- W A R N I N G --- W A R N I N G *
********************************************************************************************/
#include "mdef.h"
#define BYPASS_MEMCPY_OVERRIDE /* Signals gtm_string.h to not override memcpy(). This causes linking problems when libmumps.a
* is not available.
*/
/* We want system malloc, not gtm_malloc (which comes from mdef.h --> mdefsp.h). Since gtmsecshr_wrapper runs as root,
* using the system malloc will increase security over using gtm_malloc. Additionally, by not using gtm_malloc, we
* are reducing code bloat.
*/
#undef malloc
#undef free
#include "gtm_unistd.h"
#include "gtm_stat.h"
#include "gtm_stdlib.h"
#include "gtm_stdio.h"
#include "gtm_string.h"
#include "gtm_syslog.h"
#include "main_pragma.h"
#include "gtm_signal.h"
#ifndef __MVS__
# include <malloc.h>
#endif
#include <errno.h>
#define WBOX_GBLDEF /* Causes whitebox global vars to be GBLDEF'd instead of GBLREF'd thus keeping gbldefs.c out
* of gtmsecshr_wrapper the executable.
*/
#include "wbox_test_init.h"
#include "gtm_limits.h"
#define ROOTUID 0
#define ROOTGID 0
#define MAX_ENV_VAR_VAL_LEN 1024
#define MAX_ALLOWABLE_LEN 256
#define ASCIICTLMAX 32 /* space character */
#define ASCIICTLMIN 0 /* NULL character */
#define GTM_TMP "gtm_tmp"
#define GTM_DIST "gtm_dist"
#define GTM_WHITE_BOX_TEST_CASE_ENABLE "gtm_white_box_test_case_enable"
#define GTM_WHITE_BOX_TEST_CASE_NUMBER "gtm_white_box_test_case_number"
#define SUB_PATH_TO_GTMSECSHRDIR "/gtmsecshrdir"
#define REL_PATH_TO_CURDIR "."
#define REL_PATH_TO_GTMSECSHR "./gtmsecshr"
#define GTMSECSHR_BASENAME "/gtmsecshr"
#define MAX_ENV_NAME_LEN 2048
#define PERMALL 07777
/* Build up some defines for use with AIX and reading /etc/environment to pick up a default TZ value plus some defines
* for testing AIX errors in this wrapper with white box test cases.
*/
#ifdef _AIX
#define GTM_TZ "TZ"
#define TZLOCATOR "TZ="
#define NEWLINE 0x0a
#define GTMETCDIRPATH "/etc"
#define BADGTMETCDIRPATH "/bogusdirnotetc"
#define GTMENVIRONFILE "environment"
#define BADGTMENVIRONFILE "bogusfilenotenvironment"
#endif
typedef char **environptr_t;
extern char **environ;
/* Since gtmsecshr_wrapper.c is a stand-alone module, we cannot use error_def-style definitions, so use simple macro defines to
* initialize all error types used along with their respective mnemonics. Note that we need two '%' to ensure the '%' prefix
* in the syslog.
*/
#define ERR_SECSHRCLEARENVFAILED \
"%%GTM-E-SECSHRCLEARENVFAILED, clearenv failed. gtmsecshr will not be started\n"
#define ERR_SECSHRCHDIRFAILED1 \
"%%GTM-E-SECSHRCHDIRFAILED1, chdir failed on %s, errno %d. gtmsecshr will not be started\n"
#define ERR_SECSHRCHDIRFAILED2 \
"%%GTM-W-SECSHRCHDIRFAILED2, chdir failed on %s, errno %d. gtmsecshr will be started with GMT timezone\n"
#define ERR_SECSHREXECLFAILED \
"%%GTM-E-SECSHREXECLFAILED, execl of %s failed\n"
#define ERR_SECSHRGTMDIST2LONG \
"%%GTM-E-SECSHRGTMDIST2LONG, gtm_dist env var too long. gtmsecshr will not be started\n"
#define ERR_SECSHRGTMTMP2LONG \
"%%GTM-E-SECSHRGTMTMP2LONG, gtm_tmp env var too long. gtmsecshr will not be started\n"
#define ERR_SECSHRNOGTMDIST \
"%%GTM-E-SECSHRNOGTMDIST, gtm_dist env var does not exist. gtmsecshr will not be started\n"
#define ERR_SECSHRNOTOWNEDBYROOT \
"%%GTM-E-SECSHRNOTOWNEDBYROOT, %s not owned by root. gtmsecshr will not be started\n"
#define ERR_SECSHRNOTSETUID \
"%%GTM-E-SECSHRNOTSETUID, %s not set-uid. gtmsecshr will not be started\n"
#define ERR_SECSHRPERMINCRCT \
"%%GTM-E-SECSHRPERMINCRCT, %s permissions incorrect (%04o). gtmsecshr will not be started\n"
#define ERR_SECSHRSETGTMDISTFAILED \
"%%GTM-E-SECSHRSETGTMDISTFAILED, setenv for gtm_dist failed. gtmsecshr will not be started\n"
#define ERR_SECSHRSETGTMTMPFAILED \
"%%GTM-E-SECSHRSETGTMTMPFAILED, setenv for gtm_tmp failed. gtmsecshr will not be started\n"
#define ERR_SECSHRSETUIDFAILED \
"%%GTM-E-SECSHRSETUIDFAILED, setuid failed. gtmsecshr will not be started\n"
#define ERR_SECSHRSTATFAILED \
"%%GTM-E-SECSHRSTATFAILED, stat failed on %s, errno %d. gtmsecshr will not be started\n"
#define ERR_SECSHRTZFAIL \
"%%GTM-W-SECSHRTZFAIL, %s %d. gtmsecshr will start with TZ set to GMT\n"
#define ERR_SECSHRWRITABLE \
"%%GTM-E-SECSHRWRITABLE, %s writable. gtmsecshr will not be started\n"
/*
Make sure these are synced with the above. We need this comment for the InfoHub tools to generate message
information for gtmsecshr_wrapper.c, since it does not have a stand-alone .msg file.
.FACILITY GTMSECSHRINIT,251/PREFIX=ERR_
SECSHRCHDIRFAILED1 <chdir failed on !AD, errno !UL. gtmsecshr will not be started>/error/fao=3!/ansi=0
SECSHRCHDIRFAILED2 <chdir failed on !AD, errno !UL. gtmsecshr will be started with GMT timezone>/warning/fao=3!/ansi=0
SECSHRCLEARENVFAILED <clearenv failed. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHREXECLFAILED <execl of !AD failed>/error/fao=2!/ansi=0
SECSHRGTMDIST2LONG <gtm_dist env var too long. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRGTMTMP2LONG <gtm_tmp env var too long. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRNOGTMDIST <gtm_dist env var does not exist. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRNOTOWNEDBYROOT <!AD not owned by root. gtmsecshr will not be started>/error/fao=3!/ansi=0
SECSHRNOTSETUID <!AD not set-uid. gtmsecshr will not be started>/error/fao=2!/ansi=0
SECSHRPERMINCRCT <!AD permissions incorrect (0!UL). gtmsecshr will not be started>/error/fao=3!/ansi=0
SECSHRSETGTMDISTFAILED <setenv for gtm_dist failed. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRSETGTMTMPFAILED <setenv for gtm_tmp failed. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRSETUIDFAILED <setuid failed. gtmsecshr will not be started>/error/fao=0!/ansi=0
SECSHRSTATFAILED <stat failed on !AD, errno !UL. gtmsecshr will not be started>/error/fao=3!/ansi=0
SECSHRTZFAIL <!AD !UL. gtmsecshr will start with TZ set to GMT>/warning/fao=3!/ansi=0
SECSHRWRITABLE <!AD writable. gtmsecshr will not be started>/error/fao=2!/ansi=0
! the following line stops getmsginfo.m
.end
*/
void strsanitize(char *src, char *dst);
/**
* @brief Sanitize a file path for display purposes
*
* In practice, this is used only from this source file and to remove spaces & control characters
* from paths involving gtmsecshr.
*
* SCA complains if we copy the input directly to the output, even if we consider each byte.
* Using a translation table gets around that, and gives us some flexibility to add other
* mappings later if needed. Currently the table is built on each call. This could be
* changed, but doesn't seem worthwhile given the infrequent use of this function.
*
* @param src The input path buffer to be 'sanitized'. Must be a null terminated C string.
* @param dst The output path buffer with the 'sanitized' path. Must be as large as src
* @return None
*
*/
void strsanitize(char *src, char *dst)
{
int i, srclen;
unsigned char trans_tab[256];
/* Our translation table is largely an identity table except for spaces and control chars */
for(i = 0; i < 256; i++)
{
trans_tab[i] = ((ASCIICTLMAX > i) && (ASCIICTLMIN < i)) ? '*' : i;
}
/* The calling function already validates the string length. */
srclen = strlen(src);
for (i = 0; (i <= srclen) && (MAX_ENV_VAR_VAL_LEN > i); i++)
dst[i] = trans_tab[(unsigned char)src[i]];
}
int main()
{
int ret, status;
char *env_var_ptr;
struct stat gtm_secshrdir_stat;
struct stat gtm_secshr_stat;
char gtm_dist_val[MAX_ENV_VAR_VAL_LEN];
char gtm_tmp_val[MAX_ENV_VAR_VAL_LEN];
char gtm_secshrdir_path[MAX_ENV_VAR_VAL_LEN];
char gtm_secshrdir_path_display[MAX_ENV_VAR_VAL_LEN];
char gtm_secshr_path[MAX_ENV_VAR_VAL_LEN];
char gtm_secshr_path_display[MAX_ENV_VAR_VAL_LEN];
char gtm_secshr_orig_path[MAX_ENV_VAR_VAL_LEN];
boolean_t gtm_tmp_exists = FALSE;
boolean_t gtm_white_box_test_case_pass_envvars = FALSE;
char gtm_white_box_test_case_enable_val[MAX_ENV_VAR_VAL_LEN];
char gtm_white_box_test_case_number_val[MAX_ENV_VAR_VAL_LEN];
int rc;
sigset_t mask;
# ifdef _AIX
FILE *envfile;
int recnum, reclen, save_errno;
char *fgets_rc;
boolean_t gtm_TZ_found;
char gtm_TZ_val[MAX_ENV_VAR_VAL_LEN + 1], *gtm_TZ_val_ptr;
char *etcdirpath, *environfile;
# endif
/* Reset the signal mask (since the one inherited from the invoking process might have signals such as SIGALRM or SIGTERM
* blocked) to let gtmsecshr manage its own signals using sig_init.
*/
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, NULL); /* BYPASSOK(sigprocmask) */
OPENLOG("GTMSECSHRINIT", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_USER);
# ifdef _AIX
# ifdef DEBUG
/* Use some very simplistic processing to obtain values for $gtm_white_box_test_case_enable/number since we are basically
* standalone in this routine without the ability to call into other mumps routines. We fetch the value and convert it
* numerically as best as possible. For the boolean enable flag, If it's non-zero - it's true else false. No errors raised
* here for conversions.
*/
env_var_ptr = getenv(GTM_WHITE_BOX_TEST_CASE_ENABLE);
if (NULL != env_var_ptr)
{
gtm_white_box_test_case_enabled = atoi(env_var_ptr);
if (gtm_white_box_test_case_enabled)
{
env_var_ptr = getenv(GTM_WHITE_BOX_TEST_CASE_NUMBER);
if (NULL != env_var_ptr)
gtm_white_box_test_case_number = atoi(env_var_ptr);
}
}
# endif /* DEBUG */
etcdirpath = !(WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOETC)) ? GTMETCDIRPATH : BADGTMETCDIRPATH;
environfile = !(WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOENVIRON)) ? GTMENVIRONFILE : BADGTMENVIRONFILE;
/* Note syslog timestamps are handled somewhat differently on AIX. If one undefines the TZ environment variable (such as
* our wrapper does to prevent reporting time in the timezone of the process that started gtmsecshr, process time reverts
* to GMT. So to prevent that, lookup the default timezone in /etc/environment and use it to prevent whacky time reporting
* by gtmsecshr in the operator log. Secure file read method is to switch dir first, then do relative open.
*/
gtm_TZ_found = FALSE;
if (-1 == CHDIR(etcdirpath)) /* Note chdir is changed again below so this is only temporary */
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRCHDIRFAILED2, etcdirpath, errno);
else
{
envfile = fopen(environfile, "r");
if (NULL == envfile)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "Unable to open /etc/environment errno:", errno);
else
{ /* /etc/environments is open, locate TZ= record */
for (recnum = 0; ; recnum++)
{
FGETS(gtm_TZ_val, MAX_ENV_VAR_VAL_LEN, envfile, fgets_rc);
if (NULL == fgets_rc)
break;
if (STRLEN(TZLOCATOR) >= (reclen = STRLEN(gtm_TZ_val))) /* Note assignment */
continue;
if (0 == memcmp(TZLOCATOR, gtm_TZ_val, STRLEN(TZLOCATOR)))
{
gtm_TZ_found = TRUE;
break;
}
}
if (!gtm_TZ_found DEBUG_ONLY(|| WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOTZREC_READERR)
|| WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOTZREC_EOF)))
{ /* We didn't find the TZ record - report it depending if we just hit EOF or something more
* severe.
*/
save_errno = errno;
# if DEBUG
/* Since we may have come here via the white box tests, let's ensure gtm_TZ_found is FALSE */
gtm_TZ_found = FALSE;
/* Separately test for some white box conditions before testing the real return codes */
if (WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOTZREC_READERR))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "FGETS() failure reading /etc/environment "
"errno:", 999);
else if (WBTEST_ENABLED(WBTEST_SECSHRWRAP_NOTZREC_EOF))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "File /etc/environment has no default TZ ",
0); /* This puts a spurious 0 out with the message but this condition should
* be so rare as to be irrelevant and not worth a separate message.
*/
else
# endif
if (!feof(envfile))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "FGETS() failure reading /etc/environment "
"errno:", save_errno);
else
/* Have EOF - didn't find TZ */
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "File /etc/environment has no default TZ ",
0); /* This puts a spurious 0 out with the message but this condition should
* be so rare as to be irrelevant and not worth a separate message.
*/
} else
{ /* TZ record acquired - isolate TZ value. Note we don't allocate storage for it like we would if
* this were a long(er) running process but this process's sole job is to call the real gtmsecshr
* so the stack storage flavor of the buffer is fine.
*/
if (NEWLINE == gtm_TZ_val[reclen - 1])
gtm_TZ_val[--reclen] = '\0'; /* Overwrite nl with null and decr length */
/* Set pointer to point past the TZ= part of the value pair as we use setenv() to set this value */
gtm_TZ_val_ptr = gtm_TZ_val + STRLEN(TZLOCATOR);
/* In case this default TZ is different from the process that started gtmsecshr, go ahead and
* establish this version now for any remaining messages that happen before we do a clearenv().
* We will re-establish the value again after the clear. Until we establish the default value
* here, gtmsecshr wrapper messages will have the timezone of the invoking process.
*/
status = setenv(GTM_TZ, gtm_TZ_val_ptr, TRUE);
if ((0 != status) || WBTEST_ENABLED(WBTEST_SECSHRWRAP_SETENVFAIL1))
{
save_errno = errno;
# ifdef DEBUG
if (WBTEST_ENABLED(WBTEST_SECSHRWRAP_SETENVFAIL1))
save_errno = 999;
# endif
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "TZ reset with setenv() failed (1) errno:",
save_errno);
}
}
fclose(envfile);
}
}
# endif /* _AIX */
ret = 0; /* start positive */
/* get the ones we need */
if ((env_var_ptr = getenv(GTM_DIST))) /* Warning - assignment */
{
if (MAX_ALLOWABLE_LEN <
(strlen(env_var_ptr) + STR_LIT_LEN(SUB_PATH_TO_GTMSECSHRDIR) + STR_LIT_LEN(GTMSECSHR_BASENAME)))
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRGTMDIST2LONG);
ret = -1;
} else
{
snprintf(gtm_dist_val, MAX_ENV_VAR_VAL_LEN, "%s", env_var_ptr);
/* point the path to the real gtmsecshr - for display purposes only */
snprintf(gtm_secshr_path, MAX_ENV_VAR_VAL_LEN, "%s%s%s",
env_var_ptr, SUB_PATH_TO_GTMSECSHRDIR, GTMSECSHR_BASENAME);
strsanitize(gtm_secshr_path, gtm_secshr_path_display);
/* point the path to the real gtmsecshrdir */
snprintf(gtm_secshrdir_path, MAX_ENV_VAR_VAL_LEN, "%s%s", env_var_ptr, SUB_PATH_TO_GTMSECSHRDIR);
strsanitize(gtm_secshrdir_path, gtm_secshrdir_path_display);
/* the path to gtmsecshr wrapper that we want to display in a PS listing */
snprintf(gtm_secshr_orig_path, MAX_ENV_VAR_VAL_LEN, "%s%s", env_var_ptr, GTMSECSHR_BASENAME);
}
} else
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRNOGTMDIST);
ret = -1;
}
if ((env_var_ptr = getenv(GTM_TMP))) /* Warning - assignment */
{
if (MAX_ALLOWABLE_LEN < strlen(env_var_ptr))
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRGTMTMP2LONG);
ret = -1;
} else
{
gtm_tmp_exists = TRUE;
strcpy(gtm_tmp_val, env_var_ptr);
}
}
# ifdef DEBUG
/* Normally, all non-essential environment variables are cleared before calling the real
* GTMSECSHR executable. For a very specific white box case, WBTEST_FORCE_SEMGETERROR,
* the two environment variables used for the white box case are passed. This is only done
* in debug and they are length checked. If another white box case is ever needed by GTMSECSHR
* it needs to be added here and in gtmsecshr.c.
*/
if ((env_var_ptr = getenv(GTM_WHITE_BOX_TEST_CASE_NUMBER))) /* Warning - assignment */
{
if (MAX_ALLOWABLE_LEN >= strlen(env_var_ptr))
{
strcpy(gtm_white_box_test_case_number_val, env_var_ptr);
if (WBTEST_FORCE_SEMGETERROR == atoi(gtm_white_box_test_case_number_val))
if ((env_var_ptr = getenv(GTM_WHITE_BOX_TEST_CASE_ENABLE))) /* Warning - assignment */
if (MAX_ALLOWABLE_LEN >= strlen(env_var_ptr))
{
gtm_white_box_test_case_pass_envvars = TRUE;
strcpy(gtm_white_box_test_case_enable_val, env_var_ptr);
}
}
}
# endif
if (!ret)
{ /* clear all */
# if defined(SUNOS) || defined(__CYGWIN__)
environ = NULL;
status = 0;
# else
status = clearenv();
# endif
if (status)
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRCLEARENVFAILED);
ret = -1;
}
/* add the ones we need */
status = setenv(GTM_DIST, gtm_dist_val, TRUE);
if (status)
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRSETGTMDISTFAILED);
ret = -1;
}
if (gtm_tmp_exists)
{
status = setenv(GTM_TMP, gtm_tmp_val, TRUE);
if (status)
{
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRSETGTMTMPFAILED);
ret = -1;
}
}
# ifdef DEBUG
/* This is only for debugging with a white box case so no need to check the status */
if (gtm_white_box_test_case_pass_envvars)
{
setenv(GTM_WHITE_BOX_TEST_CASE_ENABLE, gtm_white_box_test_case_enable_val, TRUE);
setenv(GTM_WHITE_BOX_TEST_CASE_NUMBER, gtm_white_box_test_case_number_val, TRUE);
}
# endif
# ifdef _AIX
if (gtm_TZ_found DEBUG_ONLY(|| WBTEST_ENABLED(WBTEST_SECSHRWRAP_SETENVFAIL2)))
{
# ifdef DEBUG
if (gtm_TZ_found) /* Want to run setenv even if WBOX if TZ was found so we can find log entries */
status = setenv(GTM_TZ, gtm_TZ_val_ptr, TRUE);
if (WBTEST_ENABLED(WBTEST_SECSHRWRAP_SETENVFAIL2))
status = -1;
# else
status = setenv(GTM_TZ, gtm_TZ_val_ptr, TRUE);
# endif
if (0 != status)
{
save_errno = errno;
# ifdef DEBUG
if (WBTEST_ENABLED(WBTEST_SECSHRWRAP_SETENVFAIL2))
save_errno = 999;
# endif
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRTZFAIL, "TZ reset with setenv() failed (2) errno:",
save_errno);
}
}
# endif
}
if (!ret)
{ /* go to root */
if (-1 == CHDIR(gtm_secshrdir_path))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRCHDIRFAILED1, gtm_secshrdir_path_display, errno);
else if (-1 == Stat(REL_PATH_TO_CURDIR, >m_secshrdir_stat))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRSTATFAILED, gtm_secshrdir_path_display, errno);
else if (ROOTUID != gtm_secshrdir_stat.st_uid)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRNOTOWNEDBYROOT, gtm_secshrdir_path_display);
else if (gtm_secshrdir_stat.st_mode & 0277)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRPERMINCRCT, gtm_secshrdir_path_display,
gtm_secshrdir_stat.st_mode & PERMALL);
else if (-1 == Stat(REL_PATH_TO_GTMSECSHR, >m_secshr_stat))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRSTATFAILED, gtm_secshr_path_display, errno);
else if (ROOTUID != gtm_secshr_stat.st_uid)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRNOTOWNEDBYROOT, gtm_secshr_path_display);
else if (gtm_secshr_stat.st_mode & 022)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRWRITABLE, gtm_secshr_path_display);
else if (!(gtm_secshr_stat.st_mode & 04000))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRNOTSETUID, gtm_secshr_path_display);
else if (-1 == setuid(ROOTUID))
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHRSETUIDFAILED);
else
{ /* call the real gtmsecshr, but have ps display the original gtmsecshr location */
ret = execl(REL_PATH_TO_GTMSECSHR, gtm_secshr_orig_path, NULL);
if (-1 == ret)
SYSLOG(LOG_USER | LOG_INFO, ERR_SECSHREXECLFAILED, gtm_secshr_path_display);
}
}
CLOSELOG();
return ret;
}
|