#include <commonp.h>
#include <com.h>
#include <comprot.h>
#include <comnaf.h>
#include <comp.h>
#include <cominitp.h>
#include <npnaf.h>
#include <ipnaf.h>
#include <dg.h>
#if defined(AUTH_GSS_NEGOTIATE) && AUTH_GSS_NEGOTIATE
#include <gssauth.h>
#endif
#define ALLOW_LOADABLE_MODULES 0
#if (defined(_HPUX) || defined (__hpux)) && defined (__hppa)
#define DSO_EXT ".sl"
#else
#define DSO_EXT ".so"
#endif
#if HAVE_DLFCN_H
#include <dirent.h>
#include <dlfcn.h>
#ifndef HAVE_SCANDIR
static int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const void *, const void *));
#endif
#if ALLOW_LOADABLE_MODULES
static int sort_modules(const void* a, const void *b);
static int select_module(const struct dirent * dirent);
static int sort_modules(const void* a, const void* b)
{
int pri_a, pri_b;
switch((*(const struct dirent**)a)->d_name[3]) {
case 'p': pri_a = 1; break;
case 'n': pri_a = 2; break;
case 'a': pri_a = 3; break;
default: pri_a = 4;
}
switch((*(const struct dirent**)b)->d_name[3]) {
case 'p': pri_b = 1; break;
case 'n': pri_b = 2; break;
case 'a': pri_b = 3; break;
default: pri_b = 4;
}
if (pri_a == pri_b)
return 0;
if (pri_a < pri_b)
return -1;
return 1;
}
static int select_module(const struct dirent * dirent)
{
size_t len = strlen(dirent->d_name);
const char * module_types[] = {"libnaf_", "libauth_", "libprot_", NULL};
int i;
for (i = 0; module_types[i] != NULL; i++) {
if (strncmp(dirent->d_name, module_types[i], strlen(module_types[i])) == 0) {
if (strcmp(&dirent->d_name[len - 3], DSO_EXT) == 0)
return 1;
}
}
return 0;
}
#endif
#endif
PRIVATE void rpc__register_authn_protocol(rpc_authn_protocol_id_elt_p_t auth, int number)
{
int i;
for (i = 0; i < number; i++) {
RPC_DBG_PRINTF(rpc_es_dbg_general, 1, ("Register authn protocol 0x%0x\n", auth[i].authn_protocol_id));
memcpy(&rpc_g_authn_protocol_id[auth[i].authn_protocol_id],
&auth[i],
sizeof(rpc_authn_protocol_id_elt_t)
);
}
}
PRIVATE void rpc__register_protseq(rpc_protseq_id_elt_p_t elt, int number)
{
int i;
for (i = 0; i < number; i++) {
RPC_DBG_PRINTF(rpc_es_dbg_general, 1, ("Register protseq 0x%0x %s\n", elt[i].rpc_protseq_id, elt[i].rpc_protseq));
memcpy(&rpc_g_protseq_id[elt[i].rpc_protseq_id],
&elt[i],
sizeof(rpc_protseq_id_elt_t));
}
}
PRIVATE void rpc__register_tower_prot_id(rpc_tower_prot_ids_p_t tower_prot, int number)
{
int i;
for (i = 0; i < number; i++) {
rpc_tower_prot_ids_p_t tower = &tower_prot[i];
RPC_DBG_PRINTF(rpc_es_dbg_general, 1,
("Register tower protocol for %s\n",
rpc_g_protseq_id[tower->rpc_protseq_id].rpc_protseq)
);
memcpy(&rpc_g_tower_prot_ids[rpc_g_tower_prot_id_number],
tower, sizeof(rpc_tower_prot_ids_t));
rpc_g_tower_prot_id_number++;
}
}
PRIVATE void rpc__register_protocol_id(rpc_protocol_id_elt_p_t prot, int number)
{
int i;
for (i = 0; i < number; i++) {
RPC_DBG_PRINTF(rpc_es_dbg_general, 1,
("Register protocol id 0x%x\n", prot[i].rpc_protocol_id));
memcpy(&rpc_g_protocol_id[prot[i].rpc_protocol_id],
&prot[i],
sizeof(rpc_protocol_id_elt_t));
}
}
PRIVATE void rpc__register_naf_id(rpc_naf_id_elt_p_t naf, int number)
{
int i;
for (i = 0; i < number; i++) {
RPC_DBG_PRINTF(rpc_es_dbg_general, 1,
("Register network address family id 0x%x\n", naf[i].naf_id));
memcpy(&rpc_g_naf_id[naf[i].naf_id],
&naf[i],
sizeof(rpc_naf_id_elt_t));
}
}
void rpc__schnauth_init_func(void);
static void (*rpc__g_static_modules[])(void) =
{
#ifdef ENABLE_PROT_NCACN
rpc__cn_init_func,
#endif
#ifdef ENABLE_PROT_NCADG
rpc__dg_init_func,
#endif
#ifdef ENABLE_NAF_IP
rpc__ip_naf_init_func,
#endif
#ifdef ENABLE_NAF_NP
rpc__np_naf_init_func,
#endif
#ifdef ENABLE_AUTH_GSS_NEGOTIATE
rpc__gssauth_init_func,
#endif
#ifdef ENABLE_AUTH_SCHANNEL
rpc__schnauth_init_func
#endif
};
PRIVATE void rpc__load_modules(void)
{
#if HAVE_DLFCN_H
int i;
#if ALLOW_LOADABLE_MODULES
struct dirent **namelist = NULL;
int n;
void * image;
char buf[PATH_MAX];
#endif
memset(rpc_g_protseq_id, 0, sizeof(rpc_g_protseq_id));
memset(rpc_g_naf_id, 0, sizeof(rpc_g_naf_id));
memset(rpc_g_authn_protocol_id, 0, sizeof(rpc_g_authn_protocol_id));
rpc_g_authn_protocol_id[rpc_c_authn_none].authn_protocol_id = rpc_c_authn_none;
rpc_g_authn_protocol_id[rpc_c_authn_none].dce_rpc_authn_protocol_id = dce_c_rpc_authn_protocol_none;
for (i = 0; i < (int) (sizeof(rpc__g_static_modules) / sizeof(rpc__g_static_modules[0])); i++) {
rpc__g_static_modules[i]();
}
#if ALLOW_LOADABLE_MODULES
n = scandir(IMAGE_DIR, &namelist, (void*) select_module, (void*) sort_modules);
for (i = 0; i < n; i++) {
int flags = 0;
sprintf(buf, "%s/%s", IMAGE_DIR, namelist[i]->d_name);
RPC_DBG_PRINTF(rpc_es_dbg_general, 1, ("Loading module %s\n", buf));
#ifdef RTLD_LAZY
flags |= RTLD_LAZY;
#endif
#ifdef RTLD_MEMBER
flags |= RTLD_MEMBER;
#endif
image = dlopen(buf, flags);
if (image != NULL) {
void (*init_func)(void);
init_func = dlsym(image, "rpc__module_init_func");
if (init_func != NULL) {
(*init_func)();
}
else {
RPC_DBG_GPRINTF ((
"%s: dlsym error: %s\n", __func__, dlerror()));
dlclose(image);
}
}
else {
RPC_DBG_GPRINTF ((
"%s: dlopen error: %s\n", __func__, dlerror()));
}
free(namelist[i]);
}
if (namelist != NULL) {
free(namelist);
}
#endif
#endif
}
PRIVATE rpc_naf_init_fn_t rpc__load_naf
(
rpc_naf_id_elt_p_t naf ATTRIBUTE_UNUSED,
unsigned32 *status
)
{
*status = rpc_s_ok;
return((rpc_naf_init_fn_t)NULL);
}
PRIVATE rpc_prot_init_fn_t rpc__load_prot
(
rpc_protocol_id_elt_p_t prot ATTRIBUTE_UNUSED,
unsigned32 *status
)
{
*status = rpc_s_ok;
return((rpc_prot_init_fn_t)NULL);
}
PRIVATE rpc_auth_init_fn_t rpc__load_auth
(
rpc_authn_protocol_id_elt_p_t auth ATTRIBUTE_UNUSED,
unsigned32 *status
)
{
*status = rpc_s_ok;
return((rpc_auth_init_fn_t)NULL);
}
#if HAVE_DLFCN_H
#ifndef HAVE_SCANDIR
static int
scandir(dirname, namelist, selectfn, dcomp)
const char *dirname;
struct dirent ***namelist;
int (*selectfn)(const struct dirent *);
int (*dcomp)(const void *, const void *);
{
struct dirent *d, *p, **names = NULL;
size_t nitems = 0;
struct stat stb;
unsigned long arraysz;
DIR *dirp;
size_t len;
if ((dirp = opendir(dirname)) == NULL)
return(-1);
if (stat(dirname, &stb))
return(-1);
arraysz = (stb.st_size / 24);
names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
if (names == NULL)
goto fail;
while ((d = readdir(dirp)) != NULL) {
if (selectfn != NULL && !(*selectfn)(d))
continue;
len = strlen(d->d_name) + 1);
p = (struct dirent *)malloc(sizeof(*p) + len);
if (p == NULL)
goto fail;
p->d_ino = d->d_ino;
p->d_off = d->d_off;
p->d_reclen = d->d_reclen;
strlcpy(p->d_name, d->d_name, len);
if (nitems >= arraysz) {
const int inc = 10;
struct dirent **names2;
names2 = (struct dirent **)realloc((char *)names,
(arraysz + inc) * sizeof(struct dirent *));
if (names2 == NULL) {
free(p);
goto fail;
}
names = names2;
arraysz += inc;
}
names[nitems++] = p;
}
closedir(dirp);
if (nitems && dcomp != NULL)
qsort(names, nitems, sizeof(struct dirent *), dcomp);
*namelist = names;
return(nitems);
fail:
while (nitems > 0)
free(names[--nitems]);
free(names);
closedir(dirp);
return -1;
}
#endif
#endif