10Sstevel@tonic-gate /*
2*1914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
30Sstevel@tonic-gate * Use is subject to license terms.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
60Sstevel@tonic-gate
70Sstevel@tonic-gate /* dlopen.c--Unix dlopen() dynamic loader interface
80Sstevel@tonic-gate * Rob Siemborski
90Sstevel@tonic-gate * Rob Earhart
100Sstevel@tonic-gate * $Id: dlopen.c,v 1.45 2003/07/14 20:08:50 rbraun Exp $
110Sstevel@tonic-gate */
120Sstevel@tonic-gate /*
130Sstevel@tonic-gate * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
160Sstevel@tonic-gate * modification, are permitted provided that the following conditions
170Sstevel@tonic-gate * are met:
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
200Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
210Sstevel@tonic-gate *
220Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
230Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
240Sstevel@tonic-gate * the documentation and/or other materials provided with the
250Sstevel@tonic-gate * distribution.
260Sstevel@tonic-gate *
270Sstevel@tonic-gate * 3. The name "Carnegie Mellon University" must not be used to
280Sstevel@tonic-gate * endorse or promote products derived from this software without
290Sstevel@tonic-gate * prior written permission. For permission or any other legal
300Sstevel@tonic-gate * details, please contact
310Sstevel@tonic-gate * Office of Technology Transfer
320Sstevel@tonic-gate * Carnegie Mellon University
330Sstevel@tonic-gate * 5000 Forbes Avenue
340Sstevel@tonic-gate * Pittsburgh, PA 15213-3890
350Sstevel@tonic-gate * (412) 268-4387, fax: (412) 268-7395
360Sstevel@tonic-gate * tech-transfer@andrew.cmu.edu
370Sstevel@tonic-gate *
380Sstevel@tonic-gate * 4. Redistributions of any form whatsoever must retain the following
390Sstevel@tonic-gate * acknowledgment:
400Sstevel@tonic-gate * "This product includes software developed by Computing Services
410Sstevel@tonic-gate * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
420Sstevel@tonic-gate *
430Sstevel@tonic-gate * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
440Sstevel@tonic-gate * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
450Sstevel@tonic-gate * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
460Sstevel@tonic-gate * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
470Sstevel@tonic-gate * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
480Sstevel@tonic-gate * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
490Sstevel@tonic-gate * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
500Sstevel@tonic-gate */
510Sstevel@tonic-gate
520Sstevel@tonic-gate #include <config.h>
530Sstevel@tonic-gate #ifdef HAVE_DLFCN_H
540Sstevel@tonic-gate #include <dlfcn.h>
550Sstevel@tonic-gate #endif
560Sstevel@tonic-gate
570Sstevel@tonic-gate #include <stdlib.h>
580Sstevel@tonic-gate #include <errno.h>
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <limits.h>
610Sstevel@tonic-gate
620Sstevel@tonic-gate #include <sasl.h>
630Sstevel@tonic-gate #include "saslint.h"
640Sstevel@tonic-gate
650Sstevel@tonic-gate #ifndef PIC
660Sstevel@tonic-gate #include <saslplug.h>
670Sstevel@tonic-gate #include "staticopen.h"
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate
700Sstevel@tonic-gate #ifdef _SUN_SDK_
710Sstevel@tonic-gate #include <sys/stat.h>
720Sstevel@tonic-gate #endif /* _SUN_SDK_ */
730Sstevel@tonic-gate
740Sstevel@tonic-gate #ifdef DO_DLOPEN
750Sstevel@tonic-gate #if HAVE_DIRENT_H
760Sstevel@tonic-gate # include <dirent.h>
770Sstevel@tonic-gate # define NAMLEN(dirent) strlen((dirent)->d_name)
780Sstevel@tonic-gate #else /* HAVE_DIRENT_H */
790Sstevel@tonic-gate # define dirent direct
800Sstevel@tonic-gate # define NAMLEN(dirent) (dirent)->d_namlen
810Sstevel@tonic-gate # if HAVE_SYS_NDIR_H
820Sstevel@tonic-gate # include <sys/ndir.h>
830Sstevel@tonic-gate # endif
840Sstevel@tonic-gate # if HAVE_SYS_DIR_H
850Sstevel@tonic-gate # include <sys/dir.h>
860Sstevel@tonic-gate # endif
870Sstevel@tonic-gate # if HAVE_NDIR_H
880Sstevel@tonic-gate # include <ndir.h>
890Sstevel@tonic-gate # endif
900Sstevel@tonic-gate #endif /* ! HAVE_DIRENT_H */
910Sstevel@tonic-gate
920Sstevel@tonic-gate #ifndef NAME_MAX
930Sstevel@tonic-gate # ifdef _POSIX_NAME_MAX
940Sstevel@tonic-gate # define NAME_MAX _POSIX_NAME_MAX
950Sstevel@tonic-gate # else
960Sstevel@tonic-gate # define NAME_MAX 16
970Sstevel@tonic-gate # endif
980Sstevel@tonic-gate #endif
990Sstevel@tonic-gate
1000Sstevel@tonic-gate #if NAME_MAX < 8
1010Sstevel@tonic-gate # define NAME_MAX 8
1020Sstevel@tonic-gate #endif
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate #ifdef __hpux
1050Sstevel@tonic-gate #include <dl.h>
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate typedef shl_t dll_handle;
1080Sstevel@tonic-gate typedef void * dll_func;
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate dll_handle
dlopen(char * fname,int mode)1110Sstevel@tonic-gate dlopen(char *fname, int mode)
1120Sstevel@tonic-gate {
1130Sstevel@tonic-gate shl_t h = shl_load(fname, BIND_DEFERRED, 0L);
1140Sstevel@tonic-gate shl_t *hp = NULL;
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate if (h) {
1170Sstevel@tonic-gate hp = (shl_t *)malloc(sizeof (shl_t));
1180Sstevel@tonic-gate if (!hp) {
1190Sstevel@tonic-gate shl_unload(h);
1200Sstevel@tonic-gate } else {
1210Sstevel@tonic-gate *hp = h;
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate return (dll_handle)hp;
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate int
dlclose(dll_handle h)1290Sstevel@tonic-gate dlclose(dll_handle h)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate shl_t hp = *((shl_t *)h);
1320Sstevel@tonic-gate if (hp != NULL) free(hp);
1330Sstevel@tonic-gate return shl_unload(h);
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate dll_func
dlsym(dll_handle h,char * n)1370Sstevel@tonic-gate dlsym(dll_handle h, char *n)
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate dll_func handle;
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle))
1420Sstevel@tonic-gate return NULL;
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate return (dll_func)handle;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
dlerror()1470Sstevel@tonic-gate char *dlerror()
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate if (errno != 0) {
1500Sstevel@tonic-gate return strerror(errno);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate return "Generic shared library error";
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate #define SO_SUFFIX ".sl"
1560Sstevel@tonic-gate #else /* __hpux */
1570Sstevel@tonic-gate #define SO_SUFFIX ".so"
1580Sstevel@tonic-gate #endif /* __hpux */
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate #define LA_SUFFIX ".la"
1610Sstevel@tonic-gate #endif /* DO_DLOPEN */
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
1640Sstevel@tonic-gate typedef struct lib_list
1650Sstevel@tonic-gate {
1660Sstevel@tonic-gate struct lib_list *next;
1670Sstevel@tonic-gate void *library;
1680Sstevel@tonic-gate } lib_list_t;
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate #ifndef _SUN_SDK_
1710Sstevel@tonic-gate static lib_list_t *lib_list_head = NULL;
1720Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate DEFINE_STATIC_MUTEX(global_mutex);
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
1770Sstevel@tonic-gate
_sasl_locate_entry(void * library,const char * entryname,void ** entry_point)1780Sstevel@tonic-gate int _sasl_locate_entry(void *library, const char *entryname,
1790Sstevel@tonic-gate void **entry_point)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate #ifdef DO_DLOPEN
1820Sstevel@tonic-gate /* note that we still check for known problem systems in
1830Sstevel@tonic-gate * case we are cross-compiling */
1840Sstevel@tonic-gate #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__)
1850Sstevel@tonic-gate char adj_entryname[1024];
1860Sstevel@tonic-gate #else
1870Sstevel@tonic-gate #define adj_entryname entryname
1880Sstevel@tonic-gate #endif
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate if(!entryname) {
1910Sstevel@tonic-gate #ifndef _SUN_SDK_
1920Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_ERR,
1930Sstevel@tonic-gate "no entryname in _sasl_locate_entry");
1940Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1950Sstevel@tonic-gate return SASL_BADPARAM;
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate if(!library) {
1990Sstevel@tonic-gate #ifndef _SUN_SDK_
2000Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_ERR,
2010Sstevel@tonic-gate "no library in _sasl_locate_entry");
2020Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2030Sstevel@tonic-gate return SASL_BADPARAM;
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate if(!entry_point) {
2070Sstevel@tonic-gate #ifndef _SUN_SDK_
2080Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_ERR,
2090Sstevel@tonic-gate "no entrypoint output pointer in _sasl_locate_entry");
2100Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2110Sstevel@tonic-gate return SASL_BADPARAM;
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__)
2150Sstevel@tonic-gate snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
2160Sstevel@tonic-gate #endif
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate *entry_point = NULL;
2190Sstevel@tonic-gate *entry_point = dlsym(library, adj_entryname);
2200Sstevel@tonic-gate if (*entry_point == NULL) {
2210Sstevel@tonic-gate #if 0 /* This message appears to confuse people */
2220Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_DEBUG,
2230Sstevel@tonic-gate "unable to get entry point %s: %s", adj_entryname,
2240Sstevel@tonic-gate dlerror());
2250Sstevel@tonic-gate #endif
2260Sstevel@tonic-gate return SASL_FAIL;
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate return SASL_OK;
2300Sstevel@tonic-gate #else
2310Sstevel@tonic-gate return SASL_FAIL;
2320Sstevel@tonic-gate #endif /* DO_DLOPEN */
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate #ifdef DO_DLOPEN
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_plugin_load(_sasl_global_context_t * gctx,char * plugin,void * library,const char * entryname,int (* add_plugin)(_sasl_global_context_t * gctx,const char *,void *))2380Sstevel@tonic-gate static int _sasl_plugin_load(_sasl_global_context_t *gctx,
2390Sstevel@tonic-gate char *plugin, void *library,
2400Sstevel@tonic-gate const char *entryname,
2410Sstevel@tonic-gate int (*add_plugin)(_sasl_global_context_t *gctx,
2420Sstevel@tonic-gate const char *, void *))
2430Sstevel@tonic-gate #else
2440Sstevel@tonic-gate static int _sasl_plugin_load(char *plugin, void *library,
2450Sstevel@tonic-gate const char *entryname,
2460Sstevel@tonic-gate int (*add_plugin)(const char *, void *))
2470Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2480Sstevel@tonic-gate {
2490Sstevel@tonic-gate void *entry_point;
2500Sstevel@tonic-gate int result;
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate result = _sasl_locate_entry(library, entryname, &entry_point);
2530Sstevel@tonic-gate if(result == SASL_OK) {
2540Sstevel@tonic-gate #ifdef _SUN_SDK_
2550Sstevel@tonic-gate result = add_plugin(gctx, plugin, entry_point);
2560Sstevel@tonic-gate #else
2570Sstevel@tonic-gate result = add_plugin(plugin, entry_point);
2580Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2590Sstevel@tonic-gate if(result != SASL_OK)
2600Sstevel@tonic-gate #ifdef _SUN_SDK_
2610Sstevel@tonic-gate __sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ?
2620Sstevel@tonic-gate gctx->client_global_callbacks.callbacks :
2630Sstevel@tonic-gate gctx->server_global_callbacks.callbacks,
2640Sstevel@tonic-gate SASL_LOG_DEBUG,
2650Sstevel@tonic-gate "_sasl_plugin_load failed on %s for plugin: %s\n",
2660Sstevel@tonic-gate entryname, plugin);
2670Sstevel@tonic-gate #else
2680Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_DEBUG,
2690Sstevel@tonic-gate "_sasl_plugin_load failed on %s for plugin: %s\n",
2700Sstevel@tonic-gate entryname, plugin);
2710Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate return result;
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate #ifndef _SUN_SDK_
2780Sstevel@tonic-gate /* this returns the file to actually open.
2790Sstevel@tonic-gate * out should be a buffer of size PATH_MAX
2800Sstevel@tonic-gate * and may be the same as in. */
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /* We'll use a static buffer for speed unless someone complains */
2830Sstevel@tonic-gate #define MAX_LINE 2048
2840Sstevel@tonic-gate
_parse_la(const char * prefix,const char * in,char * out)2850Sstevel@tonic-gate static int _parse_la(const char *prefix, const char *in, char *out)
2860Sstevel@tonic-gate {
2870Sstevel@tonic-gate FILE *file;
2880Sstevel@tonic-gate size_t length;
2890Sstevel@tonic-gate char line[MAX_LINE];
2900Sstevel@tonic-gate char *ntmp = NULL;
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate if(!in || !out || !prefix || out == in) return SASL_BADPARAM;
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate /* Set this so we can detect failure */
2950Sstevel@tonic-gate *out = '\0';
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate length = strlen(in);
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) {
3000Sstevel@tonic-gate if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) {
3010Sstevel@tonic-gate /* check for a .la file */
3020Sstevel@tonic-gate strcpy(line, prefix);
3030Sstevel@tonic-gate strcat(line, in);
3040Sstevel@tonic-gate length = strlen(line);
3050Sstevel@tonic-gate *(line + (length - strlen(SO_SUFFIX))) = '\0';
3060Sstevel@tonic-gate strcat(line, LA_SUFFIX);
307*1914Scasper file = fopen(line, "rF");
3080Sstevel@tonic-gate if(file) {
3090Sstevel@tonic-gate /* We'll get it on the .la open */
3100Sstevel@tonic-gate fclose(file);
3110Sstevel@tonic-gate return SASL_FAIL;
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate strcpy(out, prefix);
3150Sstevel@tonic-gate strcat(out, in);
3160Sstevel@tonic-gate return SASL_OK;
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate strcpy(line, prefix);
3200Sstevel@tonic-gate strcat(line, in);
3210Sstevel@tonic-gate
322*1914Scasper file = fopen(line, "rF");
3230Sstevel@tonic-gate if(!file) {
3240Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_WARN,
3250Sstevel@tonic-gate "unable to open LA file: %s", line);
3260Sstevel@tonic-gate return SASL_FAIL;
3270Sstevel@tonic-gate }
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate while(!feof(file)) {
3300Sstevel@tonic-gate if(!fgets(line, MAX_LINE, file)) break;
3310Sstevel@tonic-gate if(line[strlen(line) - 1] != '\n') {
3320Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_WARN,
3330Sstevel@tonic-gate "LA file has too long of a line: %s", in);
3340Sstevel@tonic-gate return SASL_BUFOVER;
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate if(line[0] == '\n' || line[0] == '#') continue;
3370Sstevel@tonic-gate if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) {
3380Sstevel@tonic-gate /* We found the line with the name in it */
3390Sstevel@tonic-gate char *end;
3400Sstevel@tonic-gate char *start;
3410Sstevel@tonic-gate size_t len;
3420Sstevel@tonic-gate end = strrchr(line, '\'');
3430Sstevel@tonic-gate if(!end) continue;
3440Sstevel@tonic-gate start = &line[sizeof("dlname=")-1];
3450Sstevel@tonic-gate len = strlen(start);
3460Sstevel@tonic-gate if(len > 3 && start[0] == '\'') {
3470Sstevel@tonic-gate ntmp=&start[1];
3480Sstevel@tonic-gate *end='\0';
3490Sstevel@tonic-gate /* Do we have dlname="" ? */
3500Sstevel@tonic-gate if(ntmp == end) {
3510Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_DEBUG,
3520Sstevel@tonic-gate "dlname is empty in .la file: %s", in);
3530Sstevel@tonic-gate return SASL_FAIL;
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate strcpy(out, prefix);
3560Sstevel@tonic-gate strcat(out, ntmp);
3570Sstevel@tonic-gate }
3580Sstevel@tonic-gate break;
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate if(ferror(file) || feof(file)) {
3620Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_WARN,
3630Sstevel@tonic-gate "Error reading .la: %s\n", in);
3640Sstevel@tonic-gate fclose(file);
3650Sstevel@tonic-gate return SASL_FAIL;
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate fclose(file);
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate if(!(*out)) {
3700Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_WARN,
3710Sstevel@tonic-gate "Could not find a dlname line in .la file: %s", in);
3720Sstevel@tonic-gate return SASL_FAIL;
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate return SASL_OK;
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
3780Sstevel@tonic-gate #endif /* DO_DLOPEN */
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate /* loads a plugin library */
3810Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_get_plugin(_sasl_global_context_t * gctx,const char * file,const sasl_callback_t * verifyfile_cb,void ** libraryptr)3820Sstevel@tonic-gate int _sasl_get_plugin(_sasl_global_context_t *gctx,
3830Sstevel@tonic-gate const char *file,
3840Sstevel@tonic-gate const sasl_callback_t *verifyfile_cb,
3850Sstevel@tonic-gate void **libraryptr)
3860Sstevel@tonic-gate #else
3870Sstevel@tonic-gate int _sasl_get_plugin(const char *file,
3880Sstevel@tonic-gate const sasl_callback_t *verifyfile_cb,
3890Sstevel@tonic-gate void **libraryptr)
3900Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3910Sstevel@tonic-gate {
3920Sstevel@tonic-gate #ifdef DO_DLOPEN
3930Sstevel@tonic-gate int r = 0;
3940Sstevel@tonic-gate int flag;
3950Sstevel@tonic-gate void *library;
3960Sstevel@tonic-gate lib_list_t *newhead;
3970Sstevel@tonic-gate
3980Sstevel@tonic-gate r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
3990Sstevel@tonic-gate (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
4000Sstevel@tonic-gate if (r != SASL_OK) return r;
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate #ifdef RTLD_NOW
4030Sstevel@tonic-gate flag = RTLD_NOW;
4040Sstevel@tonic-gate #else
4050Sstevel@tonic-gate flag = 0;
4060Sstevel@tonic-gate #endif
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate newhead = sasl_ALLOC(sizeof(lib_list_t));
4090Sstevel@tonic-gate if(!newhead) return SASL_NOMEM;
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate if (!(library = dlopen(file, flag))) {
4120Sstevel@tonic-gate #ifdef _SUN_SDK_
4130Sstevel@tonic-gate __sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ?
4140Sstevel@tonic-gate gctx->client_global_callbacks.callbacks :
4150Sstevel@tonic-gate gctx->server_global_callbacks.callbacks,
4160Sstevel@tonic-gate SASL_LOG_ERR,
4170Sstevel@tonic-gate "unable to dlopen %s: %s", file, dlerror());
4180Sstevel@tonic-gate #else
4190Sstevel@tonic-gate _sasl_log(NULL, SASL_LOG_ERR,
4200Sstevel@tonic-gate "unable to dlopen %s: %s", file, dlerror());
4210Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4220Sstevel@tonic-gate sasl_FREE(newhead);
4230Sstevel@tonic-gate return SASL_FAIL;
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate #ifdef _SUN_SDK_
4270Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) {
4280Sstevel@tonic-gate sasl_FREE(newhead);
4290Sstevel@tonic-gate dlclose(library);
4300Sstevel@tonic-gate return (SASL_FAIL);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate newhead->library = library;
4350Sstevel@tonic-gate #ifdef _SUN_SDK_
4360Sstevel@tonic-gate newhead->next = gctx->lib_list_head;
4370Sstevel@tonic-gate gctx->lib_list_head = newhead;
4380Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex);
4390Sstevel@tonic-gate #else
4400Sstevel@tonic-gate newhead->next = lib_list_head;
4410Sstevel@tonic-gate lib_list_head = newhead;
4420Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate *libraryptr = library;
4450Sstevel@tonic-gate return SASL_OK;
4460Sstevel@tonic-gate #else
4470Sstevel@tonic-gate return SASL_FAIL;
4480Sstevel@tonic-gate #endif /* DO_DLOPEN */
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate #ifdef _SUN_SDK_
4520Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
4530Sstevel@tonic-gate
release_plugin(_sasl_global_context_t * gctx,void * library)4540Sstevel@tonic-gate static void release_plugin(_sasl_global_context_t *gctx, void *library)
4550Sstevel@tonic-gate {
4560Sstevel@tonic-gate lib_list_t *libptr, *libptr_next = NULL, *libptr_prev = NULL;
4570Sstevel@tonic-gate int r;
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate r = LOCK_MUTEX(&global_mutex);
4600Sstevel@tonic-gate if (r < 0)
4610Sstevel@tonic-gate return;
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) {
4640Sstevel@tonic-gate libptr_next = libptr->next;
4650Sstevel@tonic-gate if (library == libptr->library) {
4660Sstevel@tonic-gate if(libptr->library)
4670Sstevel@tonic-gate #if defined DO_DLOPEN /* _SUN_SDK_ */
4680Sstevel@tonic-gate dlclose(libptr->library);
4690Sstevel@tonic-gate #else
4700Sstevel@tonic-gate FreeLibrary(libptr->library);
4710Sstevel@tonic-gate #endif /* DO_DLOPEN */ /* _SUN_SDK_ */
4720Sstevel@tonic-gate sasl_FREE(libptr);
4730Sstevel@tonic-gate break;
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate libptr_prev = libptr;
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate if (libptr_prev == NULL)
4780Sstevel@tonic-gate gctx->lib_list_head = libptr_next;
4790Sstevel@tonic-gate else
4800Sstevel@tonic-gate libptr_prev->next = libptr_next;
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex);
4830Sstevel@tonic-gate }
4840Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
4850Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate /* gets the list of mechanisms */
4880Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_load_plugins(_sasl_global_context_t * gctx,int server,const add_plugin_list_t * entrypoints,const sasl_callback_t * getpath_cb,const sasl_callback_t * verifyfile_cb)4890Sstevel@tonic-gate int _sasl_load_plugins(_sasl_global_context_t *gctx,
4900Sstevel@tonic-gate int server,
4910Sstevel@tonic-gate const add_plugin_list_t *entrypoints,
4920Sstevel@tonic-gate const sasl_callback_t *getpath_cb,
4930Sstevel@tonic-gate const sasl_callback_t *verifyfile_cb)
4940Sstevel@tonic-gate #else
4950Sstevel@tonic-gate int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
4960Sstevel@tonic-gate const sasl_callback_t *getpath_cb,
4970Sstevel@tonic-gate const sasl_callback_t *verifyfile_cb)
4980Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4990Sstevel@tonic-gate {
5000Sstevel@tonic-gate int result;
5010Sstevel@tonic-gate const add_plugin_list_t *cur_ep;
5020Sstevel@tonic-gate #ifdef _SUN_SDK_
5030Sstevel@tonic-gate _sasl_path_info_t *path_info, *p_info;
5040Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5050Sstevel@tonic-gate #ifdef DO_DLOPEN
5060Sstevel@tonic-gate char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
5070Sstevel@tonic-gate /* 1 for '/' 1 for trailing '\0' */
5080Sstevel@tonic-gate char c;
5090Sstevel@tonic-gate int pos;
5100Sstevel@tonic-gate const char *path=NULL;
5110Sstevel@tonic-gate int position;
5120Sstevel@tonic-gate DIR *dp;
5130Sstevel@tonic-gate struct dirent *dir;
5140Sstevel@tonic-gate #ifdef _SUN_SDK_
5150Sstevel@tonic-gate int plugin_loaded;
5160Sstevel@tonic-gate struct stat b;
5170Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5180Sstevel@tonic-gate #endif
5190Sstevel@tonic-gate #ifndef PIC
5200Sstevel@tonic-gate add_plugin_t *add_plugin;
5210Sstevel@tonic-gate _sasl_plug_type type;
5220Sstevel@tonic-gate _sasl_plug_rec *p;
5230Sstevel@tonic-gate #endif
5240Sstevel@tonic-gate
5250Sstevel@tonic-gate if (! entrypoints
5260Sstevel@tonic-gate || ! getpath_cb
5270Sstevel@tonic-gate || getpath_cb->id != SASL_CB_GETPATH
5280Sstevel@tonic-gate || ! getpath_cb->proc
5290Sstevel@tonic-gate || ! verifyfile_cb
5300Sstevel@tonic-gate || verifyfile_cb->id != SASL_CB_VERIFYFILE
5310Sstevel@tonic-gate || ! verifyfile_cb->proc)
5320Sstevel@tonic-gate return SASL_BADPARAM;
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate #ifndef PIC
5350Sstevel@tonic-gate /* do all the static plugins first */
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate /* What type of plugin are we looking for? */
5400Sstevel@tonic-gate if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
5410Sstevel@tonic-gate type = SERVER;
5420Sstevel@tonic-gate #ifdef _SUN_SDK_
5430Sstevel@tonic-gate add_plugin = (add_plugin_t *)_sasl_server_add_plugin;
5440Sstevel@tonic-gate #else
5450Sstevel@tonic-gate add_plugin = (add_plugin_t *)sasl_server_add_plugin;
5460Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5470Sstevel@tonic-gate } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
5480Sstevel@tonic-gate type = CLIENT;
5490Sstevel@tonic-gate #ifdef _SUN_SDK_
5500Sstevel@tonic-gate add_plugin = (add_plugin_t *)_sasl_client_add_plugin;
5510Sstevel@tonic-gate #else
5520Sstevel@tonic-gate add_plugin = (add_plugin_t *)sasl_client_add_plugin;
5530Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5540Sstevel@tonic-gate } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
5550Sstevel@tonic-gate type = AUXPROP;
5560Sstevel@tonic-gate #ifdef _SUN_SDK_
5570Sstevel@tonic-gate add_plugin = (add_plugin_t *)_sasl_auxprop_add_plugin;
5580Sstevel@tonic-gate #else
5590Sstevel@tonic-gate add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
5600Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5610Sstevel@tonic-gate } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
5620Sstevel@tonic-gate type = CANONUSER;
5630Sstevel@tonic-gate #ifdef _SUN_SDK_
5640Sstevel@tonic-gate add_plugin = (add_plugin_t *)_sasl_canonuser_add_plugin;
5650Sstevel@tonic-gate #else
5660Sstevel@tonic-gate add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
5670Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5680Sstevel@tonic-gate } else {
5690Sstevel@tonic-gate /* What are we looking for then? */
5700Sstevel@tonic-gate return SASL_FAIL;
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate for (p=_sasl_static_plugins; p->type; p++) {
5730Sstevel@tonic-gate if(type == p->type)
5740Sstevel@tonic-gate #ifdef _SUN_SDK_
5750Sstevel@tonic-gate result = add_plugin(gctx, p->name, (void *)p->plug);
5760Sstevel@tonic-gate #else
5770Sstevel@tonic-gate result = add_plugin(p->name, p->plug);
5780Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate }
5810Sstevel@tonic-gate #endif /* !PIC */
5820Sstevel@tonic-gate
5830Sstevel@tonic-gate /* only do the following if:
5840Sstevel@tonic-gate *
5850Sstevel@tonic-gate * we support dlopen()
5860Sstevel@tonic-gate * AND we are not staticly compiled
5870Sstevel@tonic-gate * OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
5880Sstevel@tonic-gate */
5890Sstevel@tonic-gate #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
5900Sstevel@tonic-gate /* get the path to the plugins */
5910Sstevel@tonic-gate result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
5920Sstevel@tonic-gate &path);
5930Sstevel@tonic-gate if (result != SASL_OK) return result;
5940Sstevel@tonic-gate if (! path) return SASL_FAIL;
5950Sstevel@tonic-gate
5960Sstevel@tonic-gate if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
5970Sstevel@tonic-gate return SASL_FAIL;
5980Sstevel@tonic-gate }
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate position=0;
6010Sstevel@tonic-gate do {
6020Sstevel@tonic-gate pos=0;
6030Sstevel@tonic-gate do {
6040Sstevel@tonic-gate c=path[position];
6050Sstevel@tonic-gate position++;
6060Sstevel@tonic-gate str[pos]=c;
6070Sstevel@tonic-gate pos++;
6080Sstevel@tonic-gate } while ((c!=':') && (c!='=') && (c!=0));
6090Sstevel@tonic-gate str[pos-1]='\0';
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate strcpy(prefix,str);
6120Sstevel@tonic-gate strcat(prefix,"/");
6130Sstevel@tonic-gate #ifdef _SUN_SDK_
6140Sstevel@tonic-gate path_info = server ? gctx->splug_path_info : gctx->cplug_path_info;
6150Sstevel@tonic-gate while (path_info != NULL) {
6160Sstevel@tonic-gate if (strcmp(path_info->path, prefix) == 0)
6170Sstevel@tonic-gate break;
6180Sstevel@tonic-gate path_info = path_info->next;
6190Sstevel@tonic-gate }
6200Sstevel@tonic-gate if (stat(prefix, &b) != 0) {
6210Sstevel@tonic-gate continue;
6220Sstevel@tonic-gate }
6230Sstevel@tonic-gate if ( path_info == NULL) {
6240Sstevel@tonic-gate p_info = (_sasl_path_info_t *)
6250Sstevel@tonic-gate sasl_ALLOC(sizeof (_sasl_path_info_t));
6260Sstevel@tonic-gate if (p_info == NULL) {
6270Sstevel@tonic-gate return SASL_NOMEM;
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate if(_sasl_strdup(prefix, &p_info->path, NULL) != SASL_OK) {
6300Sstevel@tonic-gate sasl_FREE(p_info);
6310Sstevel@tonic-gate return SASL_NOMEM;
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate p_info->last_changed = b.st_mtime;
6340Sstevel@tonic-gate if (server) {
6350Sstevel@tonic-gate p_info->next = gctx->splug_path_info;
6360Sstevel@tonic-gate gctx->splug_path_info = p_info;
6370Sstevel@tonic-gate } else {
6380Sstevel@tonic-gate p_info->next = gctx->cplug_path_info;
6390Sstevel@tonic-gate gctx->cplug_path_info = p_info;
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate } else {
6420Sstevel@tonic-gate if (b.st_mtime <= path_info->last_changed) {
6430Sstevel@tonic-gate continue;
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate if ((dp=opendir(str)) !=NULL) /* ignore errors */
6490Sstevel@tonic-gate {
6500Sstevel@tonic-gate while ((dir=readdir(dp)) != NULL)
6510Sstevel@tonic-gate {
6520Sstevel@tonic-gate size_t length;
6530Sstevel@tonic-gate void *library;
6540Sstevel@tonic-gate #ifndef _SUN_SDK_
6550Sstevel@tonic-gate char *c;
6560Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
6570Sstevel@tonic-gate char plugname[PATH_MAX];
6580Sstevel@tonic-gate char name[PATH_MAX];
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate length = NAMLEN(dir);
6610Sstevel@tonic-gate #ifndef _SUN_SDK_
6620Sstevel@tonic-gate if (length < 4)
6630Sstevel@tonic-gate continue; /* can not possibly be what we're looking for */
6640Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate if (length + pos>=PATH_MAX) continue; /* too big */
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate #ifdef _SUN_SDK_
6690Sstevel@tonic-gate if (dir->d_name[0] == '.')
6700Sstevel@tonic-gate continue;
6710Sstevel@tonic-gate #else
6720Sstevel@tonic-gate if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
6730Sstevel@tonic-gate SO_SUFFIX)
6740Sstevel@tonic-gate && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
6750Sstevel@tonic-gate LA_SUFFIX))
6760Sstevel@tonic-gate continue;
6770Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate memcpy(name,dir->d_name,length);
6800Sstevel@tonic-gate name[length]='\0';
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate #ifdef _SUN_SDK_
6830Sstevel@tonic-gate snprintf(tmp, sizeof (tmp), "%s%s", prefix, name);
6840Sstevel@tonic-gate #else
6850Sstevel@tonic-gate result = _parse_la(prefix, name, tmp);
6860Sstevel@tonic-gate if(result != SASL_OK)
6870Sstevel@tonic-gate continue;
6880Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate #ifdef _SUN_SDK_
6910Sstevel@tonic-gate if (stat(tmp, &b))
6920Sstevel@tonic-gate continue; /* Can't stat it */
6930Sstevel@tonic-gate if (!S_ISREG(b.st_mode))
6940Sstevel@tonic-gate continue;
6950Sstevel@tonic-gate /* Sun plugins don't have lib prefix */
6960Sstevel@tonic-gate strcpy(plugname, name);
6970Sstevel@tonic-gate #else
6980Sstevel@tonic-gate /* skip "lib" and cut off suffix --
6990Sstevel@tonic-gate this only need be approximate */
7000Sstevel@tonic-gate strcpy(plugname, name + 3);
7010Sstevel@tonic-gate c = strchr(plugname, (int)'.');
7020Sstevel@tonic-gate if(c) *c = '\0';
7030Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7040Sstevel@tonic-gate
7050Sstevel@tonic-gate #ifdef _SUN_SDK_
7060Sstevel@tonic-gate result = _sasl_get_plugin(gctx, tmp, verifyfile_cb,
7070Sstevel@tonic-gate &library);
7080Sstevel@tonic-gate #else
7090Sstevel@tonic-gate result = _sasl_get_plugin(tmp, verifyfile_cb, &library);
7100Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate if(result != SASL_OK)
7130Sstevel@tonic-gate continue;
7140Sstevel@tonic-gate
7150Sstevel@tonic-gate #ifdef _SUN_SDK_
7160Sstevel@tonic-gate plugin_loaded = 0;
7170Sstevel@tonic-gate for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
7180Sstevel@tonic-gate /* If this fails, it's not the end of the world */
7190Sstevel@tonic-gate if (_sasl_plugin_load(gctx, plugname, library,
7200Sstevel@tonic-gate cur_ep->entryname,
7210Sstevel@tonic-gate cur_ep->add_plugin) == SASL_OK) {
7220Sstevel@tonic-gate plugin_loaded = 1;
7230Sstevel@tonic-gate }
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate if (!plugin_loaded)
7260Sstevel@tonic-gate release_plugin(gctx, library);
7270Sstevel@tonic-gate #else
7280Sstevel@tonic-gate for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
7290Sstevel@tonic-gate _sasl_plugin_load(plugname, library, cur_ep->entryname,
7300Sstevel@tonic-gate cur_ep->add_plugin);
7310Sstevel@tonic-gate /* If this fails, it's not the end of the world */
7320Sstevel@tonic-gate }
7330Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7340Sstevel@tonic-gate }
7350Sstevel@tonic-gate
7360Sstevel@tonic-gate closedir(dp);
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate } while ((c!='=') && (c!=0));
7400Sstevel@tonic-gate #elif defined _SUN_SDK_ && defined WIN_PLUG
7410Sstevel@tonic-gate result =
7420Sstevel@tonic-gate _sasl_load_win_plugins(gctx, entrypoints, getpath_cb, verifyfile_cb);
7430Sstevel@tonic-gate if (result != SASL_OK)
7440Sstevel@tonic-gate return (result);
7450Sstevel@tonic-gate #endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate return SASL_OK;
7480Sstevel@tonic-gate }
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate #ifdef _SUN_SDK_
7510Sstevel@tonic-gate int
_sasl_done_with_plugins(_sasl_global_context_t * gctx)7520Sstevel@tonic-gate _sasl_done_with_plugins(_sasl_global_context_t *gctx)
7530Sstevel@tonic-gate #else
7540Sstevel@tonic-gate int
7550Sstevel@tonic-gate _sasl_done_with_plugins(void)
7560Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7570Sstevel@tonic-gate {
7580Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
7590Sstevel@tonic-gate lib_list_t *libptr, *libptr_next;
7600Sstevel@tonic-gate
7610Sstevel@tonic-gate #ifdef _SUN_SDK_
7620Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0)
7630Sstevel@tonic-gate return (SASL_FAIL);
7640Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7650Sstevel@tonic-gate
7660Sstevel@tonic-gate #ifdef _SUN_SDK_
7670Sstevel@tonic-gate for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) {
7680Sstevel@tonic-gate #else
7690Sstevel@tonic-gate for(libptr = lib_list_head; libptr; libptr = libptr_next) {
7700Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7710Sstevel@tonic-gate libptr_next = libptr->next;
7720Sstevel@tonic-gate if(libptr->library)
7730Sstevel@tonic-gate #ifdef DO_DLOPEN /* _SUN_SDK_ */
7740Sstevel@tonic-gate dlclose(libptr->library);
7750Sstevel@tonic-gate #else
7760Sstevel@tonic-gate FreeLibrary(libptr->library);
7770Sstevel@tonic-gate #endif /* DO_DLOPEN */ /* _SUN_SDK_ */
7780Sstevel@tonic-gate sasl_FREE(libptr);
7790Sstevel@tonic-gate }
7800Sstevel@tonic-gate
7810Sstevel@tonic-gate #ifdef _SUN_SDK_
7820Sstevel@tonic-gate gctx->lib_list_head = NULL;
7830Sstevel@tonic-gate #else
7840Sstevel@tonic-gate lib_list_head = NULL;
7850Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate #ifdef _SUN_SDK_
7880Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex);
7890Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7900Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
7910Sstevel@tonic-gate return SASL_OK;
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate
7940Sstevel@tonic-gate #ifdef WIN_MUTEX
7950Sstevel@tonic-gate
7960Sstevel@tonic-gate static HANDLE global_mutex = NULL;
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate int win_global_mutex_lock()
7990Sstevel@tonic-gate {
8000Sstevel@tonic-gate DWORD dwWaitResult;
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate if (global_mutex == NULL) {
8030Sstevel@tonic-gate global_mutex = CreateMutex(NULL, FALSE, NULL);
8040Sstevel@tonic-gate if (global_mutex == NULL)
8050Sstevel@tonic-gate return (-1);
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate dwWaitResult = WaitForSingleObject(global_mutex, INFINITE);
8090Sstevel@tonic-gate
8100Sstevel@tonic-gate switch (dwWaitResult) {
8110Sstevel@tonic-gate case WAIT_OBJECT_0:
8120Sstevel@tonic-gate return (0);
8130Sstevel@tonic-gate
8140Sstevel@tonic-gate case WAIT_TIMEOUT:
8150Sstevel@tonic-gate return (-1); /* Shouldn't happen */
8160Sstevel@tonic-gate
8170Sstevel@tonic-gate case WAIT_ABANDONED:
8180Sstevel@tonic-gate return (-1); /* Shouldn't happen */
8190Sstevel@tonic-gate }
8200Sstevel@tonic-gate return (-1); /* Unexpected result */
8210Sstevel@tonic-gate }
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate int win_global_mutex_unlock()
8240Sstevel@tonic-gate {
8250Sstevel@tonic-gate if (global_mutex == NULL)
8260Sstevel@tonic-gate return (-1);
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate return (ReleaseMutex(global_mutex) ? 0 : -1);
8290Sstevel@tonic-gate }
8300Sstevel@tonic-gate
8310Sstevel@tonic-gate BOOL APIENTRY DllMain(HANDLE hModule,
8320Sstevel@tonic-gate DWORD ul_reason_for_call,
8330Sstevel@tonic-gate LPVOID lpReserved)
8340Sstevel@tonic-gate {
8350Sstevel@tonic-gate switch( ul_reason_for_call ) {
8360Sstevel@tonic-gate case DLL_PROCESS_ATTACH:
8370Sstevel@tonic-gate global_mutex = CreateMutex(NULL, FALSE, NULL);
8380Sstevel@tonic-gate if (global_mutex == NULL)
8390Sstevel@tonic-gate return (FALSE);
8400Sstevel@tonic-gate break;
8410Sstevel@tonic-gate case DLL_THREAD_ATTACH:
8420Sstevel@tonic-gate case DLL_THREAD_DETACH:
8430Sstevel@tonic-gate case DLL_PROCESS_DETACH:
8440Sstevel@tonic-gate break;
8450Sstevel@tonic-gate }
8460Sstevel@tonic-gate return TRUE;
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate #endif
849