File: gtm_startup_chk.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (155 lines) | stat: -rw-r--r-- 5,271 bytes parent folder | download | duplicates (3)
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;
}