xref: /illumos-gate/usr/src/lib/libsasl/lib/dlopen.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
17c478bd9Sstevel@tonic-gate /*
2*004388ebScasper  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /* dlopen.c--Unix dlopen() dynamic loader interface
77c478bd9Sstevel@tonic-gate  * Rob Siemborski
87c478bd9Sstevel@tonic-gate  * Rob Earhart
97c478bd9Sstevel@tonic-gate  * $Id: dlopen.c,v 1.45 2003/07/14 20:08:50 rbraun Exp $
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate /*
127c478bd9Sstevel@tonic-gate  * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
157c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
167c478bd9Sstevel@tonic-gate  * are met:
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
197c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
227c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
237c478bd9Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
247c478bd9Sstevel@tonic-gate  *    distribution.
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * 3. The name "Carnegie Mellon University" must not be used to
277c478bd9Sstevel@tonic-gate  *    endorse or promote products derived from this software without
287c478bd9Sstevel@tonic-gate  *    prior written permission. For permission or any other legal
297c478bd9Sstevel@tonic-gate  *    details, please contact
307c478bd9Sstevel@tonic-gate  *      Office of Technology Transfer
317c478bd9Sstevel@tonic-gate  *      Carnegie Mellon University
327c478bd9Sstevel@tonic-gate  *      5000 Forbes Avenue
337c478bd9Sstevel@tonic-gate  *      Pittsburgh, PA  15213-3890
347c478bd9Sstevel@tonic-gate  *      (412) 268-4387, fax: (412) 268-7395
357c478bd9Sstevel@tonic-gate  *      tech-transfer@andrew.cmu.edu
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * 4. Redistributions of any form whatsoever must retain the following
387c478bd9Sstevel@tonic-gate  *    acknowledgment:
397c478bd9Sstevel@tonic-gate  *    "This product includes software developed by Computing Services
407c478bd9Sstevel@tonic-gate  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
437c478bd9Sstevel@tonic-gate  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
447c478bd9Sstevel@tonic-gate  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
457c478bd9Sstevel@tonic-gate  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
467c478bd9Sstevel@tonic-gate  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
477c478bd9Sstevel@tonic-gate  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
487c478bd9Sstevel@tonic-gate  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include <config.h>
527c478bd9Sstevel@tonic-gate #ifdef HAVE_DLFCN_H
537c478bd9Sstevel@tonic-gate #include <dlfcn.h>
547c478bd9Sstevel@tonic-gate #endif
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #include <stdlib.h>
577c478bd9Sstevel@tonic-gate #include <errno.h>
587c478bd9Sstevel@tonic-gate #include <stdio.h>
597c478bd9Sstevel@tonic-gate #include <limits.h>
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #include <sasl.h>
627c478bd9Sstevel@tonic-gate #include "saslint.h"
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #ifndef PIC
657c478bd9Sstevel@tonic-gate #include <saslplug.h>
667c478bd9Sstevel@tonic-gate #include "staticopen.h"
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
707c478bd9Sstevel@tonic-gate #include <sys/stat.h>
717c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN
747c478bd9Sstevel@tonic-gate #if HAVE_DIRENT_H
757c478bd9Sstevel@tonic-gate # include <dirent.h>
767c478bd9Sstevel@tonic-gate # define NAMLEN(dirent) strlen((dirent)->d_name)
777c478bd9Sstevel@tonic-gate #else /* HAVE_DIRENT_H */
787c478bd9Sstevel@tonic-gate # define dirent direct
797c478bd9Sstevel@tonic-gate # define NAMLEN(dirent) (dirent)->d_namlen
807c478bd9Sstevel@tonic-gate # if HAVE_SYS_NDIR_H
817c478bd9Sstevel@tonic-gate #  include <sys/ndir.h>
827c478bd9Sstevel@tonic-gate # endif
837c478bd9Sstevel@tonic-gate # if HAVE_SYS_DIR_H
847c478bd9Sstevel@tonic-gate #  include <sys/dir.h>
857c478bd9Sstevel@tonic-gate # endif
867c478bd9Sstevel@tonic-gate # if HAVE_NDIR_H
877c478bd9Sstevel@tonic-gate #  include <ndir.h>
887c478bd9Sstevel@tonic-gate # endif
897c478bd9Sstevel@tonic-gate #endif /* ! HAVE_DIRENT_H */
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #ifndef NAME_MAX
927c478bd9Sstevel@tonic-gate # ifdef _POSIX_NAME_MAX
937c478bd9Sstevel@tonic-gate #  define NAME_MAX _POSIX_NAME_MAX
947c478bd9Sstevel@tonic-gate # else
957c478bd9Sstevel@tonic-gate #  define NAME_MAX 16
967c478bd9Sstevel@tonic-gate # endif
977c478bd9Sstevel@tonic-gate #endif
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate #if NAME_MAX < 8
1007c478bd9Sstevel@tonic-gate #  define NAME_MAX 8
1017c478bd9Sstevel@tonic-gate #endif
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate #ifdef __hpux
1047c478bd9Sstevel@tonic-gate #include <dl.h>
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate typedef shl_t dll_handle;
1077c478bd9Sstevel@tonic-gate typedef void * dll_func;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate dll_handle
dlopen(char * fname,int mode)1107c478bd9Sstevel@tonic-gate dlopen(char *fname, int mode)
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate     shl_t h = shl_load(fname, BIND_DEFERRED, 0L);
1137c478bd9Sstevel@tonic-gate     shl_t *hp = NULL;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate     if (h) {
1167c478bd9Sstevel@tonic-gate 	hp = (shl_t *)malloc(sizeof (shl_t));
1177c478bd9Sstevel@tonic-gate 	if (!hp) {
1187c478bd9Sstevel@tonic-gate 	    shl_unload(h);
1197c478bd9Sstevel@tonic-gate 	} else {
1207c478bd9Sstevel@tonic-gate 	    *hp = h;
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate     }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate     return (dll_handle)hp;
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate int
dlclose(dll_handle h)1287c478bd9Sstevel@tonic-gate dlclose(dll_handle h)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate     shl_t hp = *((shl_t *)h);
1317c478bd9Sstevel@tonic-gate     if (hp != NULL) free(hp);
1327c478bd9Sstevel@tonic-gate     return shl_unload(h);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate dll_func
dlsym(dll_handle h,char * n)1367c478bd9Sstevel@tonic-gate dlsym(dll_handle h, char *n)
1377c478bd9Sstevel@tonic-gate {
1387c478bd9Sstevel@tonic-gate     dll_func handle;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate     if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle))
1417c478bd9Sstevel@tonic-gate 	return NULL;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate     return (dll_func)handle;
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
dlerror()1467c478bd9Sstevel@tonic-gate char *dlerror()
1477c478bd9Sstevel@tonic-gate {
1487c478bd9Sstevel@tonic-gate     if (errno != 0) {
1497c478bd9Sstevel@tonic-gate 	return strerror(errno);
1507c478bd9Sstevel@tonic-gate     }
1517c478bd9Sstevel@tonic-gate     return "Generic shared library error";
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate #define SO_SUFFIX	".sl"
1557c478bd9Sstevel@tonic-gate #else /* __hpux */
1567c478bd9Sstevel@tonic-gate #define SO_SUFFIX	".so"
1577c478bd9Sstevel@tonic-gate #endif /* __hpux */
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate #define LA_SUFFIX       ".la"
1607c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
1637c478bd9Sstevel@tonic-gate typedef struct lib_list
1647c478bd9Sstevel@tonic-gate {
1657c478bd9Sstevel@tonic-gate     struct lib_list *next;
1667c478bd9Sstevel@tonic-gate     void *library;
1677c478bd9Sstevel@tonic-gate } lib_list_t;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
1707c478bd9Sstevel@tonic-gate static lib_list_t *lib_list_head = NULL;
1717c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate DEFINE_STATIC_MUTEX(global_mutex);
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
1767c478bd9Sstevel@tonic-gate 
_sasl_locate_entry(void * library,const char * entryname,void ** entry_point)1777c478bd9Sstevel@tonic-gate int _sasl_locate_entry(void *library, const char *entryname,
1787c478bd9Sstevel@tonic-gate 		       void **entry_point)
1797c478bd9Sstevel@tonic-gate {
1807c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN
1817c478bd9Sstevel@tonic-gate /* note that we still check for known problem systems in
1827c478bd9Sstevel@tonic-gate  * case we are cross-compiling */
1837c478bd9Sstevel@tonic-gate #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__)
1847c478bd9Sstevel@tonic-gate     char adj_entryname[1024];
1857c478bd9Sstevel@tonic-gate #else
1867c478bd9Sstevel@tonic-gate #define adj_entryname entryname
1877c478bd9Sstevel@tonic-gate #endif
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate     if(!entryname) {
1907c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
1917c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_ERR,
1927c478bd9Sstevel@tonic-gate 		  "no entryname in _sasl_locate_entry");
1937c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1947c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
1957c478bd9Sstevel@tonic-gate     }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate     if(!library) {
1987c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
1997c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_ERR,
2007c478bd9Sstevel@tonic-gate 		  "no library in _sasl_locate_entry");
2017c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2027c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
2037c478bd9Sstevel@tonic-gate     }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate     if(!entry_point) {
2067c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
2077c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_ERR,
2087c478bd9Sstevel@tonic-gate 		  "no entrypoint output pointer in _sasl_locate_entry");
2097c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2107c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
2117c478bd9Sstevel@tonic-gate     }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__)
2147c478bd9Sstevel@tonic-gate     snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
2157c478bd9Sstevel@tonic-gate #endif
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate     *entry_point = NULL;
2187c478bd9Sstevel@tonic-gate     *entry_point = dlsym(library, adj_entryname);
2197c478bd9Sstevel@tonic-gate     if (*entry_point == NULL) {
2207c478bd9Sstevel@tonic-gate #if 0 /* This message appears to confuse people */
2217c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_DEBUG,
2227c478bd9Sstevel@tonic-gate 		  "unable to get entry point %s: %s", adj_entryname,
2237c478bd9Sstevel@tonic-gate 		  dlerror());
2247c478bd9Sstevel@tonic-gate #endif
2257c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
2267c478bd9Sstevel@tonic-gate     }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate     return SASL_OK;
2297c478bd9Sstevel@tonic-gate #else
2307c478bd9Sstevel@tonic-gate     return SASL_FAIL;
2317c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@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 *))2377c478bd9Sstevel@tonic-gate static int _sasl_plugin_load(_sasl_global_context_t *gctx,
2387c478bd9Sstevel@tonic-gate 			     char *plugin, void *library,
2397c478bd9Sstevel@tonic-gate 			     const char *entryname,
2407c478bd9Sstevel@tonic-gate 			     int (*add_plugin)(_sasl_global_context_t *gctx,
2417c478bd9Sstevel@tonic-gate 					       const char *, void *))
2427c478bd9Sstevel@tonic-gate #else
2437c478bd9Sstevel@tonic-gate static int _sasl_plugin_load(char *plugin, void *library,
2447c478bd9Sstevel@tonic-gate 			     const char *entryname,
2457c478bd9Sstevel@tonic-gate 			     int (*add_plugin)(const char *, void *))
2467c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate     void *entry_point;
2497c478bd9Sstevel@tonic-gate     int result;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate     result = _sasl_locate_entry(library, entryname, &entry_point);
2527c478bd9Sstevel@tonic-gate     if(result == SASL_OK) {
2537c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2547c478bd9Sstevel@tonic-gate 	result = add_plugin(gctx, plugin, entry_point);
2557c478bd9Sstevel@tonic-gate #else
2567c478bd9Sstevel@tonic-gate 	result = add_plugin(plugin, entry_point);
2577c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2587c478bd9Sstevel@tonic-gate 	if(result != SASL_OK)
2597c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2607c478bd9Sstevel@tonic-gate 	    __sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ?
2617c478bd9Sstevel@tonic-gate 	    	       gctx->client_global_callbacks.callbacks :
2627c478bd9Sstevel@tonic-gate 	    	       gctx->server_global_callbacks.callbacks,
2637c478bd9Sstevel@tonic-gate 	    	       SASL_LOG_DEBUG,
2647c478bd9Sstevel@tonic-gate 		       "_sasl_plugin_load failed on %s for plugin: %s\n",
2657c478bd9Sstevel@tonic-gate 		       entryname, plugin);
2667c478bd9Sstevel@tonic-gate #else
2677c478bd9Sstevel@tonic-gate 	    _sasl_log(NULL, SASL_LOG_DEBUG,
2687c478bd9Sstevel@tonic-gate 		      "_sasl_plugin_load failed on %s for plugin: %s\n",
2697c478bd9Sstevel@tonic-gate 		      entryname, plugin);
2707c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2717c478bd9Sstevel@tonic-gate     }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate     return result;
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
2777c478bd9Sstevel@tonic-gate /* this returns the file to actually open.
2787c478bd9Sstevel@tonic-gate  *  out should be a buffer of size PATH_MAX
2797c478bd9Sstevel@tonic-gate  *  and may be the same as in. */
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate /* We'll use a static buffer for speed unless someone complains */
2827c478bd9Sstevel@tonic-gate #define MAX_LINE 2048
2837c478bd9Sstevel@tonic-gate 
_parse_la(const char * prefix,const char * in,char * out)2847c478bd9Sstevel@tonic-gate static int _parse_la(const char *prefix, const char *in, char *out)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate     FILE *file;
2877c478bd9Sstevel@tonic-gate     size_t length;
2887c478bd9Sstevel@tonic-gate     char line[MAX_LINE];
2897c478bd9Sstevel@tonic-gate     char *ntmp = NULL;
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate     if(!in || !out || !prefix || out == in) return SASL_BADPARAM;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate     /* Set this so we can detect failure */
2947c478bd9Sstevel@tonic-gate     *out = '\0';
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate     length = strlen(in);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate     if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) {
2997c478bd9Sstevel@tonic-gate 	if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) {
3007c478bd9Sstevel@tonic-gate 	    /* check for a .la file */
3017c478bd9Sstevel@tonic-gate 	    strcpy(line, prefix);
3027c478bd9Sstevel@tonic-gate 	    strcat(line, in);
3037c478bd9Sstevel@tonic-gate 	    length = strlen(line);
3047c478bd9Sstevel@tonic-gate 	    *(line + (length - strlen(SO_SUFFIX))) = '\0';
3057c478bd9Sstevel@tonic-gate 	    strcat(line, LA_SUFFIX);
306*004388ebScasper 	    file = fopen(line, "rF");
3077c478bd9Sstevel@tonic-gate 	    if(file) {
3087c478bd9Sstevel@tonic-gate 		/* We'll get it on the .la open */
3097c478bd9Sstevel@tonic-gate 		fclose(file);
3107c478bd9Sstevel@tonic-gate 		return SASL_FAIL;
3117c478bd9Sstevel@tonic-gate 	    }
3127c478bd9Sstevel@tonic-gate 	}
3137c478bd9Sstevel@tonic-gate 	strcpy(out, prefix);
3147c478bd9Sstevel@tonic-gate 	strcat(out, in);
3157c478bd9Sstevel@tonic-gate 	return SASL_OK;
3167c478bd9Sstevel@tonic-gate     }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate     strcpy(line, prefix);
3197c478bd9Sstevel@tonic-gate     strcat(line, in);
3207c478bd9Sstevel@tonic-gate 
321*004388ebScasper     file = fopen(line, "rF");
3227c478bd9Sstevel@tonic-gate     if(!file) {
3237c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_WARN,
3247c478bd9Sstevel@tonic-gate 		  "unable to open LA file: %s", line);
3257c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
3267c478bd9Sstevel@tonic-gate     }
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate     while(!feof(file)) {
3297c478bd9Sstevel@tonic-gate 	if(!fgets(line, MAX_LINE, file)) break;
3307c478bd9Sstevel@tonic-gate 	if(line[strlen(line) - 1] != '\n') {
3317c478bd9Sstevel@tonic-gate 	    _sasl_log(NULL, SASL_LOG_WARN,
3327c478bd9Sstevel@tonic-gate 		      "LA file has too long of a line: %s", in);
3337c478bd9Sstevel@tonic-gate 	    return SASL_BUFOVER;
3347c478bd9Sstevel@tonic-gate 	}
3357c478bd9Sstevel@tonic-gate 	if(line[0] == '\n' || line[0] == '#') continue;
3367c478bd9Sstevel@tonic-gate 	if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) {
3377c478bd9Sstevel@tonic-gate 	    /* We found the line with the name in it */
3387c478bd9Sstevel@tonic-gate 	    char *end;
3397c478bd9Sstevel@tonic-gate 	    char *start;
3407c478bd9Sstevel@tonic-gate 	    size_t len;
3417c478bd9Sstevel@tonic-gate 	    end = strrchr(line, '\'');
3427c478bd9Sstevel@tonic-gate 	    if(!end) continue;
3437c478bd9Sstevel@tonic-gate 	    start = &line[sizeof("dlname=")-1];
3447c478bd9Sstevel@tonic-gate 	    len = strlen(start);
3457c478bd9Sstevel@tonic-gate 	    if(len > 3 && start[0] == '\'') {
3467c478bd9Sstevel@tonic-gate 		ntmp=&start[1];
3477c478bd9Sstevel@tonic-gate 		*end='\0';
3487c478bd9Sstevel@tonic-gate 		/* Do we have dlname="" ? */
3497c478bd9Sstevel@tonic-gate 		if(ntmp == end) {
3507c478bd9Sstevel@tonic-gate 		    _sasl_log(NULL, SASL_LOG_DEBUG,
3517c478bd9Sstevel@tonic-gate 			      "dlname is empty in .la file: %s", in);
3527c478bd9Sstevel@tonic-gate 		    return SASL_FAIL;
3537c478bd9Sstevel@tonic-gate 		}
3547c478bd9Sstevel@tonic-gate 		strcpy(out, prefix);
3557c478bd9Sstevel@tonic-gate 		strcat(out, ntmp);
3567c478bd9Sstevel@tonic-gate 	    }
3577c478bd9Sstevel@tonic-gate 	    break;
3587c478bd9Sstevel@tonic-gate 	}
3597c478bd9Sstevel@tonic-gate     }
3607c478bd9Sstevel@tonic-gate     if(ferror(file) || feof(file)) {
3617c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_WARN,
3627c478bd9Sstevel@tonic-gate 		  "Error reading .la: %s\n", in);
3637c478bd9Sstevel@tonic-gate 	fclose(file);
3647c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
3657c478bd9Sstevel@tonic-gate     }
3667c478bd9Sstevel@tonic-gate     fclose(file);
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate     if(!(*out)) {
3697c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_WARN,
3707c478bd9Sstevel@tonic-gate 		  "Could not find a dlname line in .la file: %s", in);
3717c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
3727c478bd9Sstevel@tonic-gate     }
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate     return SASL_OK;
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
3777c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate /* loads a plugin library */
3807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_get_plugin(_sasl_global_context_t * gctx,const char * file,const sasl_callback_t * verifyfile_cb,void ** libraryptr)3817c478bd9Sstevel@tonic-gate int _sasl_get_plugin(_sasl_global_context_t *gctx,
3827c478bd9Sstevel@tonic-gate 		     const char *file,
3837c478bd9Sstevel@tonic-gate 		     const sasl_callback_t *verifyfile_cb,
3847c478bd9Sstevel@tonic-gate 		     void **libraryptr)
3857c478bd9Sstevel@tonic-gate #else
3867c478bd9Sstevel@tonic-gate int _sasl_get_plugin(const char *file,
3877c478bd9Sstevel@tonic-gate 		     const sasl_callback_t *verifyfile_cb,
3887c478bd9Sstevel@tonic-gate 		     void **libraryptr)
3897c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3907c478bd9Sstevel@tonic-gate {
3917c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN
3927c478bd9Sstevel@tonic-gate     int r = 0;
3937c478bd9Sstevel@tonic-gate     int flag;
3947c478bd9Sstevel@tonic-gate     void *library;
3957c478bd9Sstevel@tonic-gate     lib_list_t *newhead;
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate     r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
3987c478bd9Sstevel@tonic-gate 		    (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
3997c478bd9Sstevel@tonic-gate     if (r != SASL_OK) return r;
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate #ifdef RTLD_NOW
4027c478bd9Sstevel@tonic-gate     flag = RTLD_NOW;
4037c478bd9Sstevel@tonic-gate #else
4047c478bd9Sstevel@tonic-gate     flag = 0;
4057c478bd9Sstevel@tonic-gate #endif
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate     newhead = sasl_ALLOC(sizeof(lib_list_t));
4087c478bd9Sstevel@tonic-gate     if(!newhead) return SASL_NOMEM;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate     if (!(library = dlopen(file, flag))) {
4117c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4127c478bd9Sstevel@tonic-gate 	__sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ?
4137c478bd9Sstevel@tonic-gate 	    	   gctx->client_global_callbacks.callbacks :
4147c478bd9Sstevel@tonic-gate 	    	   gctx->server_global_callbacks.callbacks,
4157c478bd9Sstevel@tonic-gate 		   SASL_LOG_ERR,
4167c478bd9Sstevel@tonic-gate 		   "unable to dlopen %s: %s", file, dlerror());
4177c478bd9Sstevel@tonic-gate #else
4187c478bd9Sstevel@tonic-gate 	_sasl_log(NULL, SASL_LOG_ERR,
4197c478bd9Sstevel@tonic-gate 		  "unable to dlopen %s: %s", file, dlerror());
4207c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4217c478bd9Sstevel@tonic-gate 	sasl_FREE(newhead);
4227c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
4237c478bd9Sstevel@tonic-gate     }
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4267c478bd9Sstevel@tonic-gate     if (LOCK_MUTEX(&global_mutex) < 0) {
4277c478bd9Sstevel@tonic-gate 	sasl_FREE(newhead);
4287c478bd9Sstevel@tonic-gate 	dlclose(library);
4297c478bd9Sstevel@tonic-gate 	return (SASL_FAIL);
4307c478bd9Sstevel@tonic-gate     }
4317c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate     newhead->library = library;
4347c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4357c478bd9Sstevel@tonic-gate     newhead->next = gctx->lib_list_head;
4367c478bd9Sstevel@tonic-gate     gctx->lib_list_head = newhead;
4377c478bd9Sstevel@tonic-gate     UNLOCK_MUTEX(&global_mutex);
4387c478bd9Sstevel@tonic-gate #else
4397c478bd9Sstevel@tonic-gate     newhead->next = lib_list_head;
4407c478bd9Sstevel@tonic-gate     lib_list_head = newhead;
4417c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate     *libraryptr = library;
4447c478bd9Sstevel@tonic-gate     return SASL_OK;
4457c478bd9Sstevel@tonic-gate #else
4467c478bd9Sstevel@tonic-gate     return SASL_FAIL;
4477c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4517c478bd9Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
4527c478bd9Sstevel@tonic-gate 
release_plugin(_sasl_global_context_t * gctx,void * library)4537c478bd9Sstevel@tonic-gate static void release_plugin(_sasl_global_context_t *gctx, void *library)
4547c478bd9Sstevel@tonic-gate {
4557c478bd9Sstevel@tonic-gate     lib_list_t *libptr, *libptr_next = NULL, *libptr_prev = NULL;
4567c478bd9Sstevel@tonic-gate     int r;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate     r = LOCK_MUTEX(&global_mutex);
4597c478bd9Sstevel@tonic-gate     if (r < 0)
4607c478bd9Sstevel@tonic-gate 	return;
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate     for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) {
4637c478bd9Sstevel@tonic-gate 	libptr_next = libptr->next;
4647c478bd9Sstevel@tonic-gate 	if (library == libptr->library) {
4657c478bd9Sstevel@tonic-gate 	    if(libptr->library)
4667c478bd9Sstevel@tonic-gate #if defined DO_DLOPEN /* _SUN_SDK_ */
4677c478bd9Sstevel@tonic-gate 		dlclose(libptr->library);
4687c478bd9Sstevel@tonic-gate #else
4697c478bd9Sstevel@tonic-gate 		FreeLibrary(libptr->library);
4707c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */ /* _SUN_SDK_ */
4717c478bd9Sstevel@tonic-gate 	    sasl_FREE(libptr);
4727c478bd9Sstevel@tonic-gate 	    break;
4737c478bd9Sstevel@tonic-gate 	}
4747c478bd9Sstevel@tonic-gate 	libptr_prev = libptr;
4757c478bd9Sstevel@tonic-gate     }
4767c478bd9Sstevel@tonic-gate     if (libptr_prev == NULL)
4777c478bd9Sstevel@tonic-gate 	gctx->lib_list_head = libptr_next;
4787c478bd9Sstevel@tonic-gate     else
4797c478bd9Sstevel@tonic-gate 	libptr_prev->next = libptr_next;
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate     UNLOCK_MUTEX(&global_mutex);
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
4847c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate /* gets the list of mechanisms */
4877c478bd9Sstevel@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)4887c478bd9Sstevel@tonic-gate int _sasl_load_plugins(_sasl_global_context_t *gctx,
4897c478bd9Sstevel@tonic-gate 		       int server,
4907c478bd9Sstevel@tonic-gate 		       const add_plugin_list_t *entrypoints,
4917c478bd9Sstevel@tonic-gate 		       const sasl_callback_t *getpath_cb,
4927c478bd9Sstevel@tonic-gate 		       const sasl_callback_t *verifyfile_cb)
4937c478bd9Sstevel@tonic-gate #else
4947c478bd9Sstevel@tonic-gate int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
4957c478bd9Sstevel@tonic-gate 		       const sasl_callback_t *getpath_cb,
4967c478bd9Sstevel@tonic-gate 		       const sasl_callback_t *verifyfile_cb)
4977c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4987c478bd9Sstevel@tonic-gate {
4997c478bd9Sstevel@tonic-gate     int result;
5007c478bd9Sstevel@tonic-gate     const add_plugin_list_t *cur_ep;
5017c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5027c478bd9Sstevel@tonic-gate     _sasl_path_info_t *path_info, *p_info;
5037c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5047c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN
5057c478bd9Sstevel@tonic-gate     char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
5067c478bd9Sstevel@tonic-gate 				/* 1 for '/' 1 for trailing '\0' */
5077c478bd9Sstevel@tonic-gate     char c;
5087c478bd9Sstevel@tonic-gate     int pos;
5097c478bd9Sstevel@tonic-gate     const char *path=NULL;
5107c478bd9Sstevel@tonic-gate     int position;
5117c478bd9Sstevel@tonic-gate     DIR *dp;
5127c478bd9Sstevel@tonic-gate     struct dirent *dir;
5137c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5147c478bd9Sstevel@tonic-gate     int plugin_loaded;
5157c478bd9Sstevel@tonic-gate     struct stat b;
5167c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5177c478bd9Sstevel@tonic-gate #endif
5187c478bd9Sstevel@tonic-gate #ifndef PIC
5197c478bd9Sstevel@tonic-gate     add_plugin_t *add_plugin;
5207c478bd9Sstevel@tonic-gate     _sasl_plug_type type;
5217c478bd9Sstevel@tonic-gate     _sasl_plug_rec *p;
5227c478bd9Sstevel@tonic-gate #endif
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate     if (! entrypoints
5257c478bd9Sstevel@tonic-gate 	|| ! getpath_cb
5267c478bd9Sstevel@tonic-gate 	|| getpath_cb->id != SASL_CB_GETPATH
5277c478bd9Sstevel@tonic-gate 	|| ! getpath_cb->proc
5287c478bd9Sstevel@tonic-gate 	|| ! verifyfile_cb
5297c478bd9Sstevel@tonic-gate 	|| verifyfile_cb->id != SASL_CB_VERIFYFILE
5307c478bd9Sstevel@tonic-gate 	|| ! verifyfile_cb->proc)
5317c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate #ifndef PIC
5347c478bd9Sstevel@tonic-gate     /* do all the static plugins first */
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate     for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	/* What type of plugin are we looking for? */
5397c478bd9Sstevel@tonic-gate 	if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
5407c478bd9Sstevel@tonic-gate 	    type = SERVER;
5417c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5427c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)_sasl_server_add_plugin;
5437c478bd9Sstevel@tonic-gate #else
5447c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)sasl_server_add_plugin;
5457c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5467c478bd9Sstevel@tonic-gate 	} else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
5477c478bd9Sstevel@tonic-gate 	    type = CLIENT;
5487c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5497c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)_sasl_client_add_plugin;
5507c478bd9Sstevel@tonic-gate #else
5517c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)sasl_client_add_plugin;
5527c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5537c478bd9Sstevel@tonic-gate 	} else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
5547c478bd9Sstevel@tonic-gate 	    type = AUXPROP;
5557c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5567c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)_sasl_auxprop_add_plugin;
5577c478bd9Sstevel@tonic-gate #else
5587c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
5597c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5607c478bd9Sstevel@tonic-gate 	} else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
5617c478bd9Sstevel@tonic-gate 	    type = CANONUSER;
5627c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5637c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)_sasl_canonuser_add_plugin;
5647c478bd9Sstevel@tonic-gate #else
5657c478bd9Sstevel@tonic-gate 	    add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
5667c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5677c478bd9Sstevel@tonic-gate 	} else {
5687c478bd9Sstevel@tonic-gate 	    /* What are we looking for then? */
5697c478bd9Sstevel@tonic-gate 	    return SASL_FAIL;
5707c478bd9Sstevel@tonic-gate 	}
5717c478bd9Sstevel@tonic-gate 	for (p=_sasl_static_plugins; p->type; p++) {
5727c478bd9Sstevel@tonic-gate 	    if(type == p->type)
5737c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5747c478bd9Sstevel@tonic-gate 	    	result = add_plugin(gctx, p->name, (void *)p->plug);
5757c478bd9Sstevel@tonic-gate #else
5767c478bd9Sstevel@tonic-gate 	    	result = add_plugin(p->name, p->plug);
5777c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5787c478bd9Sstevel@tonic-gate 	}
5797c478bd9Sstevel@tonic-gate     }
5807c478bd9Sstevel@tonic-gate #endif /* !PIC */
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate /* only do the following if:
5837c478bd9Sstevel@tonic-gate  *
5847c478bd9Sstevel@tonic-gate  * we support dlopen()
5857c478bd9Sstevel@tonic-gate  *  AND we are not staticly compiled
5867c478bd9Sstevel@tonic-gate  *      OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
5877c478bd9Sstevel@tonic-gate  */
5887c478bd9Sstevel@tonic-gate #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
5897c478bd9Sstevel@tonic-gate     /* get the path to the plugins */
5907c478bd9Sstevel@tonic-gate     result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
5917c478bd9Sstevel@tonic-gate 						    &path);
5927c478bd9Sstevel@tonic-gate     if (result != SASL_OK) return result;
5937c478bd9Sstevel@tonic-gate     if (! path) return SASL_FAIL;
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate     if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
5967c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
5977c478bd9Sstevel@tonic-gate     }
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate     position=0;
6007c478bd9Sstevel@tonic-gate     do {
6017c478bd9Sstevel@tonic-gate 	pos=0;
6027c478bd9Sstevel@tonic-gate 	do {
6037c478bd9Sstevel@tonic-gate 	    c=path[position];
6047c478bd9Sstevel@tonic-gate 	    position++;
6057c478bd9Sstevel@tonic-gate 	    str[pos]=c;
6067c478bd9Sstevel@tonic-gate 	    pos++;
6077c478bd9Sstevel@tonic-gate 	} while ((c!=':') && (c!='=') && (c!=0));
6087c478bd9Sstevel@tonic-gate 	str[pos-1]='\0';
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	strcpy(prefix,str);
6117c478bd9Sstevel@tonic-gate 	strcat(prefix,"/");
6127c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6137c478bd9Sstevel@tonic-gate 	path_info = server ? gctx->splug_path_info : gctx->cplug_path_info;
6147c478bd9Sstevel@tonic-gate 	while (path_info != NULL) {
6157c478bd9Sstevel@tonic-gate 	    if (strcmp(path_info->path, prefix) == 0)
6167c478bd9Sstevel@tonic-gate 		break;
6177c478bd9Sstevel@tonic-gate 	    path_info = path_info->next;
6187c478bd9Sstevel@tonic-gate 	}
6197c478bd9Sstevel@tonic-gate 	if (stat(prefix, &b) != 0) {
6207c478bd9Sstevel@tonic-gate 	    continue;
6217c478bd9Sstevel@tonic-gate 	}
6227c478bd9Sstevel@tonic-gate 	if ( path_info == NULL) {
6237c478bd9Sstevel@tonic-gate 	    p_info = (_sasl_path_info_t *)
6247c478bd9Sstevel@tonic-gate 		sasl_ALLOC(sizeof (_sasl_path_info_t));
6257c478bd9Sstevel@tonic-gate 	    if (p_info == NULL) {
6267c478bd9Sstevel@tonic-gate 		return SASL_NOMEM;
6277c478bd9Sstevel@tonic-gate 	    }
6287c478bd9Sstevel@tonic-gate 	    if(_sasl_strdup(prefix, &p_info->path, NULL) != SASL_OK) {
6297c478bd9Sstevel@tonic-gate 		sasl_FREE(p_info);
6307c478bd9Sstevel@tonic-gate 		return SASL_NOMEM;
6317c478bd9Sstevel@tonic-gate 	    }
6327c478bd9Sstevel@tonic-gate 	    p_info->last_changed = b.st_mtime;
6337c478bd9Sstevel@tonic-gate 	    if (server) {
6347c478bd9Sstevel@tonic-gate 		p_info->next = gctx->splug_path_info;
6357c478bd9Sstevel@tonic-gate 		gctx->splug_path_info = p_info;
6367c478bd9Sstevel@tonic-gate 	    } else {
6377c478bd9Sstevel@tonic-gate 		p_info->next = gctx->cplug_path_info;
6387c478bd9Sstevel@tonic-gate 		gctx->cplug_path_info = p_info;
6397c478bd9Sstevel@tonic-gate 	    }
6407c478bd9Sstevel@tonic-gate 	} else {
6417c478bd9Sstevel@tonic-gate 	    if (b.st_mtime <= path_info->last_changed) {
6427c478bd9Sstevel@tonic-gate 		continue;
6437c478bd9Sstevel@tonic-gate 	    }
6447c478bd9Sstevel@tonic-gate 	}
6457c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 	if ((dp=opendir(str)) !=NULL) /* ignore errors */
6487c478bd9Sstevel@tonic-gate 	{
6497c478bd9Sstevel@tonic-gate 	    while ((dir=readdir(dp)) != NULL)
6507c478bd9Sstevel@tonic-gate 	    {
6517c478bd9Sstevel@tonic-gate 		size_t length;
6527c478bd9Sstevel@tonic-gate 		void *library;
6537c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
6547c478bd9Sstevel@tonic-gate 		char *c;
6557c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
6567c478bd9Sstevel@tonic-gate 		char plugname[PATH_MAX];
6577c478bd9Sstevel@tonic-gate 		char name[PATH_MAX];
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 		length = NAMLEN(dir);
6607c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
6617c478bd9Sstevel@tonic-gate 		if (length < 4)
6627c478bd9Sstevel@tonic-gate 		    continue; /* can not possibly be what we're looking for */
6637c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 		if (length + pos>=PATH_MAX) continue; /* too big */
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6687c478bd9Sstevel@tonic-gate 		if (dir->d_name[0] == '.')
6697c478bd9Sstevel@tonic-gate 		    continue;
6707c478bd9Sstevel@tonic-gate #else
6717c478bd9Sstevel@tonic-gate 		if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
6727c478bd9Sstevel@tonic-gate 			   SO_SUFFIX)
6737c478bd9Sstevel@tonic-gate 		    && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
6747c478bd9Sstevel@tonic-gate 			   LA_SUFFIX))
6757c478bd9Sstevel@tonic-gate 		    continue;
6767c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 		memcpy(name,dir->d_name,length);
6797c478bd9Sstevel@tonic-gate 		name[length]='\0';
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6827c478bd9Sstevel@tonic-gate 		snprintf(tmp, sizeof (tmp), "%s%s", prefix, name);
6837c478bd9Sstevel@tonic-gate #else
6847c478bd9Sstevel@tonic-gate 		result = _parse_la(prefix, name, tmp);
6857c478bd9Sstevel@tonic-gate 		if(result != SASL_OK)
6867c478bd9Sstevel@tonic-gate 		    continue;
6877c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6907c478bd9Sstevel@tonic-gate 		if (stat(tmp, &b))
6917c478bd9Sstevel@tonic-gate 			continue;	/* Can't stat it */
6927c478bd9Sstevel@tonic-gate 		if (!S_ISREG(b.st_mode))
6937c478bd9Sstevel@tonic-gate 			continue;
6947c478bd9Sstevel@tonic-gate 		/* Sun plugins don't have lib prefix */
6957c478bd9Sstevel@tonic-gate 		strcpy(plugname, name);
6967c478bd9Sstevel@tonic-gate #else
6977c478bd9Sstevel@tonic-gate 		/* skip "lib" and cut off suffix --
6987c478bd9Sstevel@tonic-gate 		   this only need be approximate */
6997c478bd9Sstevel@tonic-gate 		strcpy(plugname, name + 3);
7007c478bd9Sstevel@tonic-gate 		c = strchr(plugname, (int)'.');
7017c478bd9Sstevel@tonic-gate 		if(c) *c = '\0';
7027c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7057c478bd9Sstevel@tonic-gate 		result = _sasl_get_plugin(gctx, tmp, verifyfile_cb,
7067c478bd9Sstevel@tonic-gate                         &library);
7077c478bd9Sstevel@tonic-gate #else
7087c478bd9Sstevel@tonic-gate 		result = _sasl_get_plugin(tmp, verifyfile_cb, &library);
7097c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate 		if(result != SASL_OK)
7127c478bd9Sstevel@tonic-gate 		    continue;
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7157c478bd9Sstevel@tonic-gate 		plugin_loaded = 0;
7167c478bd9Sstevel@tonic-gate 		for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
7177c478bd9Sstevel@tonic-gate 			/* If this fails, it's not the end of the world */
7187c478bd9Sstevel@tonic-gate 			if (_sasl_plugin_load(gctx, plugname, library,
7197c478bd9Sstevel@tonic-gate 					cur_ep->entryname,
7207c478bd9Sstevel@tonic-gate 					cur_ep->add_plugin) == SASL_OK) {
7217c478bd9Sstevel@tonic-gate 			    plugin_loaded = 1;
7227c478bd9Sstevel@tonic-gate 			}
7237c478bd9Sstevel@tonic-gate 		}
7247c478bd9Sstevel@tonic-gate 		if (!plugin_loaded)
7257c478bd9Sstevel@tonic-gate 			release_plugin(gctx, library);
7267c478bd9Sstevel@tonic-gate #else
7277c478bd9Sstevel@tonic-gate 		for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
7287c478bd9Sstevel@tonic-gate 			_sasl_plugin_load(plugname, library, cur_ep->entryname,
7297c478bd9Sstevel@tonic-gate 					  cur_ep->add_plugin);
7307c478bd9Sstevel@tonic-gate 			/* If this fails, it's not the end of the world */
7317c478bd9Sstevel@tonic-gate 		}
7327c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7337c478bd9Sstevel@tonic-gate 	    }
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	    closedir(dp);
7367c478bd9Sstevel@tonic-gate 	}
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate     } while ((c!='=') && (c!=0));
7397c478bd9Sstevel@tonic-gate #elif defined _SUN_SDK_ && defined WIN_PLUG
7407c478bd9Sstevel@tonic-gate     result =
7417c478bd9Sstevel@tonic-gate 	_sasl_load_win_plugins(gctx, entrypoints, getpath_cb, verifyfile_cb);
7427c478bd9Sstevel@tonic-gate     if (result != SASL_OK)
7437c478bd9Sstevel@tonic-gate 	return (result);
7447c478bd9Sstevel@tonic-gate #endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate     return SASL_OK;
7477c478bd9Sstevel@tonic-gate }
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7507c478bd9Sstevel@tonic-gate int
_sasl_done_with_plugins(_sasl_global_context_t * gctx)7517c478bd9Sstevel@tonic-gate _sasl_done_with_plugins(_sasl_global_context_t *gctx)
7527c478bd9Sstevel@tonic-gate #else
7537c478bd9Sstevel@tonic-gate int
7547c478bd9Sstevel@tonic-gate _sasl_done_with_plugins(void)
7557c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7567c478bd9Sstevel@tonic-gate {
7577c478bd9Sstevel@tonic-gate #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */
7587c478bd9Sstevel@tonic-gate     lib_list_t *libptr, *libptr_next;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7617c478bd9Sstevel@tonic-gate     if (LOCK_MUTEX(&global_mutex) < 0)
7627c478bd9Sstevel@tonic-gate 	return (SASL_FAIL);
7637c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7667c478bd9Sstevel@tonic-gate     for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) {
7677c478bd9Sstevel@tonic-gate #else
7687c478bd9Sstevel@tonic-gate     for(libptr = lib_list_head; libptr; libptr = libptr_next) {
7697c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7707c478bd9Sstevel@tonic-gate 	libptr_next = libptr->next;
7717c478bd9Sstevel@tonic-gate 	if(libptr->library)
7727c478bd9Sstevel@tonic-gate #ifdef DO_DLOPEN /* _SUN_SDK_ */
7737c478bd9Sstevel@tonic-gate 	    dlclose(libptr->library);
7747c478bd9Sstevel@tonic-gate #else
7757c478bd9Sstevel@tonic-gate 	    FreeLibrary(libptr->library);
7767c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN */ /* _SUN_SDK_ */
7777c478bd9Sstevel@tonic-gate 	sasl_FREE(libptr);
7787c478bd9Sstevel@tonic-gate     }
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7817c478bd9Sstevel@tonic-gate     gctx->lib_list_head = NULL;
7827c478bd9Sstevel@tonic-gate #else
7837c478bd9Sstevel@tonic-gate     lib_list_head = NULL;
7847c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
7877c478bd9Sstevel@tonic-gate     UNLOCK_MUTEX(&global_mutex);
7887c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
7897c478bd9Sstevel@tonic-gate #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */
7907c478bd9Sstevel@tonic-gate     return SASL_OK;
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate #ifdef WIN_MUTEX
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate static HANDLE global_mutex = NULL;
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate int win_global_mutex_lock()
7987c478bd9Sstevel@tonic-gate {
7997c478bd9Sstevel@tonic-gate     DWORD dwWaitResult;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate     if (global_mutex == NULL) {
8027c478bd9Sstevel@tonic-gate 	global_mutex = CreateMutex(NULL, FALSE, NULL);
8037c478bd9Sstevel@tonic-gate 	if (global_mutex == NULL)
8047c478bd9Sstevel@tonic-gate 	    return (-1);
8057c478bd9Sstevel@tonic-gate     }
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate     dwWaitResult = WaitForSingleObject(global_mutex, INFINITE);
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate     switch (dwWaitResult) {
8107c478bd9Sstevel@tonic-gate 	case WAIT_OBJECT_0:
8117c478bd9Sstevel@tonic-gate 		return (0);
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate            case WAIT_TIMEOUT:
8147c478bd9Sstevel@tonic-gate                return (-1); /* Shouldn't happen */
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate            case WAIT_ABANDONED:
8177c478bd9Sstevel@tonic-gate                return (-1); /* Shouldn't happen */
8187c478bd9Sstevel@tonic-gate     }
8197c478bd9Sstevel@tonic-gate     return (-1); /* Unexpected result */
8207c478bd9Sstevel@tonic-gate }
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate int win_global_mutex_unlock()
8237c478bd9Sstevel@tonic-gate {
8247c478bd9Sstevel@tonic-gate     if (global_mutex == NULL)
8257c478bd9Sstevel@tonic-gate 	return (-1);
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate     return (ReleaseMutex(global_mutex) ? 0 : -1);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate BOOL APIENTRY DllMain(HANDLE hModule,
8317c478bd9Sstevel@tonic-gate                          DWORD  ul_reason_for_call,
8327c478bd9Sstevel@tonic-gate                          LPVOID lpReserved)
8337c478bd9Sstevel@tonic-gate {
8347c478bd9Sstevel@tonic-gate     switch( ul_reason_for_call ) {
8357c478bd9Sstevel@tonic-gate 	case DLL_PROCESS_ATTACH:
8367c478bd9Sstevel@tonic-gate 	    global_mutex = CreateMutex(NULL, FALSE, NULL);
8377c478bd9Sstevel@tonic-gate 	    if (global_mutex == NULL)
8387c478bd9Sstevel@tonic-gate 		return (FALSE);
8397c478bd9Sstevel@tonic-gate 	    break;
8407c478bd9Sstevel@tonic-gate 	case DLL_THREAD_ATTACH:
8417c478bd9Sstevel@tonic-gate 	case DLL_THREAD_DETACH:
8427c478bd9Sstevel@tonic-gate 	case DLL_PROCESS_DETACH:
8437c478bd9Sstevel@tonic-gate 	    break;
8447c478bd9Sstevel@tonic-gate     }
8457c478bd9Sstevel@tonic-gate     return TRUE;
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate #endif
848