File: gtm_tls_loadlibrary.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 (130 lines) | stat: -rw-r--r-- 4,066 bytes parent folder | download | duplicates (7)
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
/****************************************************************
 *								*
 *	Copyright 2013, 2014 Fidelity Information Services, Inc	*
 *								*
 *	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.	*
 *								*
 ****************************************************************/
#include "mdef.h"

#include <dlfcn.h>
#include <errno.h>
#ifdef _AIX
#include <sys/ldr.h>
#endif
#include "gtm_stdio.h"
#include "gtm_stdlib.h"
#include "gtm_string.h"
#include "gtm_limits.h"

#include "lv_val.h"
#include "real_len.h"
#include "fgncal.h"	/* needed for COPY_DLLERR_MSG() */
#include "gtmmsg.h"
#include "gtmcrypt.h"

typedef void (*gtm_tls_func_t)();	/* A generic pointer type to the TLS functions exposed by the plugin */

#define TLS_DEF(x) x##_,
enum
{
#include "gtm_tls_funclist.h"	/* BYPASSOK */
gtm_tls_func_n			/* total number of TLS functions that needs to be dlsym()ed */
};
#undef TLS_DEF

#define TLS_DEF(x) GBLDEF gtm_tls_func_t x##_fptr;
#include "gtm_tls_funclist.h"
#undef TLS_DEF

#define GTM_TLS_LIBNAME		"libgtmtls.so"

GBLREF	char		dl_err[MAX_ERRSTR_LEN];
GBLREF	char		gtm_dist[GTM_PATH_MAX];
GBLREF	boolean_t	gtm_dist_ok_to_use;

error_def(ERR_GTMDISTUNVERIF);

/* Cannot include gtm_tls.h in this module due to conflicting GBLDEF/GBLREFs. So, redefine the function prototype here to silent
 * the compiler.
 */
int	gtm_tls_loadlibrary(void);

int	gtm_tls_loadlibrary()
{
	/* Initialize the table of symbol names to be used in dlsym() */
#	define TLS_DEF(x) #x,
	char			*gtm_tls_fname[] = {
#							include "gtm_tls_funclist.h"
							NULL
						   };
#	undef TLS_DEF
	/* Initialize the table of locations of function pointers that are set by dlsym() */
	gtm_tls_func_t		fptr;
#	define TLS_DEF(x) &x##_fptr,
	gtm_tls_func_t		*gtm_tls_fptr[] = {
#							include "gtm_tls_funclist.h"
							NULL
						  };
#	undef TLS_DEF
	void_ptr_t		*handle;
	char			*err_str, libpath[GTM_PATH_MAX], util_libpath[GTM_PATH_MAX];
	int			findx;
#	ifdef _AIX
	char			new_libpath_env[GTM_PATH_MAX], *save_libpath_ptr, plugin_dir_path[GTM_PATH_MAX];
	char			save_libpath[GTM_PATH_MAX];
#	endif

	if(!gtm_dist_ok_to_use)
	{
		SNPRINTF(dl_err, MAX_ERRSTR_LEN, "%%GTM-E-GTMDISTUNVERIF, Environment variable $gtm_dist (%s) "
				"could not be verified against the executables path", gtm_dist);
		return -1;
	}
#	ifdef _AIX
	SNPRINTF(plugin_dir_path, GTM_PATH_MAX, "%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME);
	SNPRINTF(libpath, GTM_PATH_MAX, "%s/%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME, GTM_TLS_LIBNAME);
	/* Prefix LIBPATH with "$gtm_dist/plugin" so that dlopen can find the helper library (libgtmcryptutil.so). */
	if (NULL == (save_libpath_ptr = getenv(LIBPATH_ENV)))
		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s", plugin_dir_path);
	else
	{
		/* Since the setenv below can potentially thrash the save_libpath_ptr, take a copy of it for later restore. */
		strncpy(save_libpath, save_libpath_ptr, SIZEOF(save_libpath));
		save_libpath[SIZEOF(save_libpath) - 1] = '\0';
		SNPRINTF(new_libpath_env, GTM_PATH_MAX, "%s:%s", plugin_dir_path, save_libpath);
	}
	setenv(LIBPATH_ENV, new_libpath_env, TRUE);
#	else
	SNPRINTF(libpath, GTM_PATH_MAX, "%s/%s/%s", gtm_dist, GTMCRYPT_PLUGIN_DIR_NAME, GTM_TLS_LIBNAME);
#	endif
	if (NULL == (handle = dlopen(libpath, RTLD_GLOBAL | RTLD_NOW)))
	{
		COPY_DLLERR_MSG(err_str, dl_err);
		return -1;
	}
#	ifdef _AIX
	/* Restore old LIBPATH. */
	if (NULL == save_libpath_ptr)
		unsetenv(LIBPATH_ENV);
	else
		setenv(LIBPATH_ENV, save_libpath, TRUE);
	/* Now verify that "libgtmcryptutil.so" was really loaded from "$gtm_dist/plugin". */
	if (!verify_lib_loadpath(GTMCRYPT_UTIL_LIBNAME, plugin_dir_path))
		return -1;
#	endif
	for (findx = 0; findx < gtm_tls_func_n; ++findx)
	{
		fptr = (gtm_tls_func_t)dlsym(handle, gtm_tls_fname[findx]);
		if (NULL == fptr)
		{
			COPY_DLLERR_MSG(err_str, dl_err);
			return -1;
		}
		*gtm_tls_fptr[findx] = fptr;
	}
	return 0;
}