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
|
/****************************************************************
* *
* Copyright (c) 2001-2021 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. *
* *
****************************************************************/
/************************************************************************************
* Current GT.M operation on Unix depends on $gtm_dist environment variable
* being set correctly or it cannot communicate with gtmsecshr. If this
* communication fails, it can cause many problems.
* This is the startup checking including the following:
* gtm_chk_dist()
*
* 1. $gtm_dist is defined
*
* 2. Ensure that the executable resides in $gtm_dist. This provides enough
* assurance that $gtm_dist is suitable for use.
*
* This comparison is done using the inode of the executable in $gtm_dist
* and the discovered executable path, either from /proc or other OS
* function. Using argv[0] wasn't possible when $gtm_dist is in the $PATH.
*
* The GT.CM servers, OMI and GNP, always defer issuing an error for an
* unverified $gtm_dist. All other executables, MUMPS, MUPIP, DSE, and LKE
* issue the error messages as soon as possible.
*
* 3. Checking that $gtm_dist/gtmsecshr was relocated to secshr_client()
************************************************************************************/
#include "mdef.h"
#include <errno.h>
#include "gtm_string.h"
#include "gtm_stat.h"
#include "gtm_stdlib.h"
#include "gtm_unistd.h"
#include "gtm_limits.h"
#include "gdsroot.h"
#include "error.h"
#include "parse_file.h"
#include "is_file_identical.h"
#include "gtm_startup_chk.h"
#include "gtmimagename.h"
#include "have_crit.h"
#include "gtm_post_startup_check_init.h"
GBLREF char gtm_dist[GTM_PATH_MAX];
GBLREF unsigned int gtm_dist_len;
GBLREF boolean_t gtm_dist_ok_to_use;
LITREF gtmImageName gtmImageNames[];
GBLREF uint4 process_id;
error_def(ERR_DISTPATHMAX);
error_def(ERR_SYSCALL);
error_def(ERR_GTMDISTUNDEF);
error_def(ERR_GTMDISTUNVERIF);
error_def(ERR_FILEPARSE);
error_def(ERR_MAXGTMPATH);
error_def(ERR_IMAGENAME);
error_def(ERR_TEXT);
int gtm_chk_dist(char *image)
{
char *real_dist;
char *imagepath;
char *exename;
int exename_len;
int path_len;
boolean_t status;
boolean_t is_gtcm_image;
char image_real_path[GTM_PATH_MAX];
char real_gtm_dist_path[GTM_PATH_MAX];
char comparison[GTM_PATH_MAX];
unsigned int real_dist_len;
is_gtcm_image = (IS_GTCM_GNP_SERVER_IMAGE || IS_GTCM_SERVER_IMAGE); /* GT.CM servers defer issuing errors until startup */
/* Use the real path while checking the path length. If not valid, let it fail when checking is_file_identical */
real_dist = realpath(gtm_dist, real_gtm_dist_path);
if (real_dist)
{
STRNLEN(real_dist, GTM_PATH_MAX, real_dist_len);
} else
{
# ifdef DEBUG
STRNLEN(gtm_dist, GTM_PATH_MAX, real_dist_len); /* Set real_dist_len */
assert(real_dist_len == gtm_dist_len);
# endif
real_dist_len = gtm_dist_len;
}
if (real_dist_len)
{
assert(IS_VALID_IMAGE && (n_image_types > image_type)); /* assert image_type is initialized */
if (GTM_DIST_PATH_MAX <= real_dist_len)
{
if (is_gtcm_image)
return 0;
RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(3) ERR_DISTPATHMAX, 1, GTM_DIST_PATH_MAX);
}
} else
{
if (is_gtcm_image)
return 0;
RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(1) ERR_GTMDISTUNDEF);
}
/* Get the executable name and length */
exename = strrchr(image, '/');
if (!exename) /* no slash found, then image is just the exe's name */
{
exename = image;
} else /* slash found in the path, advance the pointer by one to get the name */
exename++;
STRNLEN(exename, GTM_PATH_MAX, exename_len);
status = gtm_image_path(image_real_path);
if (status) /* On HP-UX it's possible for the underlying system call to return an error. Fall back to realpath() */
{
/* Use the return of realpath(). If it returns null for argv[0], just use image and let the check fail */
imagepath = realpath(image, image_real_path);
if (NULL == imagepath)
imagepath = image;
} else
imagepath = image_real_path;
/* create the comparison path (gtm_dist + '/' + exename + '\0') and compare it to imagepath */
SNPRINTF(comparison, GTM_PATH_MAX, "%s/%s", gtm_dist, exename);
status = is_file_identical(imagepath, comparison);
if (status)
gtm_dist_ok_to_use = TRUE;
else
{
if (is_gtcm_image)
return 0;
RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(6) ERR_GTMDISTUNVERIF, 4, LEN_AND_STR(gtm_dist), LEN_AND_STR(image));
}
if (IS_GTM_IMAGE && memcmp(exename, GTM_IMAGE_NAME, GTM_IMAGE_NAMELEN))
RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(6) ERR_IMAGENAME, 4, LEN_AND_LIT(GTM_IMAGE_NAME), LEN_AND_STR(exename));
gtm_post_startup_check_init();
return 0;
}
int gtm_image_path(char *realpath)
{
#if defined(__linux__) || defined(__sparc) || defined(_AIX) || defined(__CYGWIN__)
SNPRINTF(realpath, GTM_PATH_MAX, PROCSELF, process_id);
#else
# error "Unsupported platform : no way to determine the true exe path"
#endif
return 0;
}
|