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