1 /* 2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 #pragma ident "%Z%%M% %I% %E% SMI" 6 7 /* dlopen.c--Unix dlopen() dynamic loader interface 8 * Rob Siemborski 9 * Rob Earhart 10 * $Id: dlopen.c,v 1.45 2003/07/14 20:08:50 rbraun Exp $ 11 */ 12 /* 13 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in 24 * the documentation and/or other materials provided with the 25 * distribution. 26 * 27 * 3. The name "Carnegie Mellon University" must not be used to 28 * endorse or promote products derived from this software without 29 * prior written permission. For permission or any other legal 30 * details, please contact 31 * Office of Technology Transfer 32 * Carnegie Mellon University 33 * 5000 Forbes Avenue 34 * Pittsburgh, PA 15213-3890 35 * (412) 268-4387, fax: (412) 268-7395 36 * tech-transfer@andrew.cmu.edu 37 * 38 * 4. Redistributions of any form whatsoever must retain the following 39 * acknowledgment: 40 * "This product includes software developed by Computing Services 41 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 42 * 43 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 44 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 45 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 46 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 47 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 48 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 49 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 50 */ 51 52 #include <config.h> 53 #ifdef HAVE_DLFCN_H 54 #include <dlfcn.h> 55 #endif 56 57 #include <stdlib.h> 58 #include <errno.h> 59 #include <stdio.h> 60 #include <limits.h> 61 62 #include <sasl.h> 63 #include "saslint.h" 64 65 #ifndef PIC 66 #include <saslplug.h> 67 #include "staticopen.h" 68 #endif 69 70 #ifdef _SUN_SDK_ 71 #include <sys/stat.h> 72 #endif /* _SUN_SDK_ */ 73 74 #ifdef DO_DLOPEN 75 #if HAVE_DIRENT_H 76 # include <dirent.h> 77 # define NAMLEN(dirent) strlen((dirent)->d_name) 78 #else /* HAVE_DIRENT_H */ 79 # define dirent direct 80 # define NAMLEN(dirent) (dirent)->d_namlen 81 # if HAVE_SYS_NDIR_H 82 # include <sys/ndir.h> 83 # endif 84 # if HAVE_SYS_DIR_H 85 # include <sys/dir.h> 86 # endif 87 # if HAVE_NDIR_H 88 # include <ndir.h> 89 # endif 90 #endif /* ! HAVE_DIRENT_H */ 91 92 #ifndef NAME_MAX 93 # ifdef _POSIX_NAME_MAX 94 # define NAME_MAX _POSIX_NAME_MAX 95 # else 96 # define NAME_MAX 16 97 # endif 98 #endif 99 100 #if NAME_MAX < 8 101 # define NAME_MAX 8 102 #endif 103 104 #ifdef __hpux 105 #include <dl.h> 106 107 typedef shl_t dll_handle; 108 typedef void * dll_func; 109 110 dll_handle 111 dlopen(char *fname, int mode) 112 { 113 shl_t h = shl_load(fname, BIND_DEFERRED, 0L); 114 shl_t *hp = NULL; 115 116 if (h) { 117 hp = (shl_t *)malloc(sizeof (shl_t)); 118 if (!hp) { 119 shl_unload(h); 120 } else { 121 *hp = h; 122 } 123 } 124 125 return (dll_handle)hp; 126 } 127 128 int 129 dlclose(dll_handle h) 130 { 131 shl_t hp = *((shl_t *)h); 132 if (hp != NULL) free(hp); 133 return shl_unload(h); 134 } 135 136 dll_func 137 dlsym(dll_handle h, char *n) 138 { 139 dll_func handle; 140 141 if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle)) 142 return NULL; 143 144 return (dll_func)handle; 145 } 146 147 char *dlerror() 148 { 149 if (errno != 0) { 150 return strerror(errno); 151 } 152 return "Generic shared library error"; 153 } 154 155 #define SO_SUFFIX ".sl" 156 #else /* __hpux */ 157 #define SO_SUFFIX ".so" 158 #endif /* __hpux */ 159 160 #define LA_SUFFIX ".la" 161 #endif /* DO_DLOPEN */ 162 163 #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */ 164 typedef struct lib_list 165 { 166 struct lib_list *next; 167 void *library; 168 } lib_list_t; 169 170 #ifndef _SUN_SDK_ 171 static lib_list_t *lib_list_head = NULL; 172 #endif /* !_SUN_SDK_ */ 173 174 DEFINE_STATIC_MUTEX(global_mutex); 175 176 #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */ 177 178 int _sasl_locate_entry(void *library, const char *entryname, 179 void **entry_point) 180 { 181 #ifdef DO_DLOPEN 182 /* note that we still check for known problem systems in 183 * case we are cross-compiling */ 184 #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__) 185 char adj_entryname[1024]; 186 #else 187 #define adj_entryname entryname 188 #endif 189 190 if(!entryname) { 191 #ifndef _SUN_SDK_ 192 _sasl_log(NULL, SASL_LOG_ERR, 193 "no entryname in _sasl_locate_entry"); 194 #endif /* _SUN_SDK_ */ 195 return SASL_BADPARAM; 196 } 197 198 if(!library) { 199 #ifndef _SUN_SDK_ 200 _sasl_log(NULL, SASL_LOG_ERR, 201 "no library in _sasl_locate_entry"); 202 #endif /* _SUN_SDK_ */ 203 return SASL_BADPARAM; 204 } 205 206 if(!entry_point) { 207 #ifndef _SUN_SDK_ 208 _sasl_log(NULL, SASL_LOG_ERR, 209 "no entrypoint output pointer in _sasl_locate_entry"); 210 #endif /* _SUN_SDK_ */ 211 return SASL_BADPARAM; 212 } 213 214 #if defined(DLSYM_NEEDS_UNDERSCORE) || defined(__OpenBSD__) 215 snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname); 216 #endif 217 218 *entry_point = NULL; 219 *entry_point = dlsym(library, adj_entryname); 220 if (*entry_point == NULL) { 221 #if 0 /* This message appears to confuse people */ 222 _sasl_log(NULL, SASL_LOG_DEBUG, 223 "unable to get entry point %s: %s", adj_entryname, 224 dlerror()); 225 #endif 226 return SASL_FAIL; 227 } 228 229 return SASL_OK; 230 #else 231 return SASL_FAIL; 232 #endif /* DO_DLOPEN */ 233 } 234 235 #ifdef DO_DLOPEN 236 237 #ifdef _SUN_SDK_ 238 static int _sasl_plugin_load(_sasl_global_context_t *gctx, 239 char *plugin, void *library, 240 const char *entryname, 241 int (*add_plugin)(_sasl_global_context_t *gctx, 242 const char *, void *)) 243 #else 244 static int _sasl_plugin_load(char *plugin, void *library, 245 const char *entryname, 246 int (*add_plugin)(const char *, void *)) 247 #endif /* _SUN_SDK_ */ 248 { 249 void *entry_point; 250 int result; 251 252 result = _sasl_locate_entry(library, entryname, &entry_point); 253 if(result == SASL_OK) { 254 #ifdef _SUN_SDK_ 255 result = add_plugin(gctx, plugin, entry_point); 256 #else 257 result = add_plugin(plugin, entry_point); 258 #endif /* _SUN_SDK_ */ 259 if(result != SASL_OK) 260 #ifdef _SUN_SDK_ 261 __sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ? 262 gctx->client_global_callbacks.callbacks : 263 gctx->server_global_callbacks.callbacks, 264 SASL_LOG_DEBUG, 265 "_sasl_plugin_load failed on %s for plugin: %s\n", 266 entryname, plugin); 267 #else 268 _sasl_log(NULL, SASL_LOG_DEBUG, 269 "_sasl_plugin_load failed on %s for plugin: %s\n", 270 entryname, plugin); 271 #endif /* _SUN_SDK_ */ 272 } 273 274 return result; 275 } 276 277 #ifndef _SUN_SDK_ 278 /* this returns the file to actually open. 279 * out should be a buffer of size PATH_MAX 280 * and may be the same as in. */ 281 282 /* We'll use a static buffer for speed unless someone complains */ 283 #define MAX_LINE 2048 284 285 static int _parse_la(const char *prefix, const char *in, char *out) 286 { 287 FILE *file; 288 size_t length; 289 char line[MAX_LINE]; 290 char *ntmp = NULL; 291 292 if(!in || !out || !prefix || out == in) return SASL_BADPARAM; 293 294 /* Set this so we can detect failure */ 295 *out = '\0'; 296 297 length = strlen(in); 298 299 if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) { 300 if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) { 301 /* check for a .la file */ 302 strcpy(line, prefix); 303 strcat(line, in); 304 length = strlen(line); 305 *(line + (length - strlen(SO_SUFFIX))) = '\0'; 306 strcat(line, LA_SUFFIX); 307 file = fopen(line, "rF"); 308 if(file) { 309 /* We'll get it on the .la open */ 310 fclose(file); 311 return SASL_FAIL; 312 } 313 } 314 strcpy(out, prefix); 315 strcat(out, in); 316 return SASL_OK; 317 } 318 319 strcpy(line, prefix); 320 strcat(line, in); 321 322 file = fopen(line, "rF"); 323 if(!file) { 324 _sasl_log(NULL, SASL_LOG_WARN, 325 "unable to open LA file: %s", line); 326 return SASL_FAIL; 327 } 328 329 while(!feof(file)) { 330 if(!fgets(line, MAX_LINE, file)) break; 331 if(line[strlen(line) - 1] != '\n') { 332 _sasl_log(NULL, SASL_LOG_WARN, 333 "LA file has too long of a line: %s", in); 334 return SASL_BUFOVER; 335 } 336 if(line[0] == '\n' || line[0] == '#') continue; 337 if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) { 338 /* We found the line with the name in it */ 339 char *end; 340 char *start; 341 size_t len; 342 end = strrchr(line, '\''); 343 if(!end) continue; 344 start = &line[sizeof("dlname=")-1]; 345 len = strlen(start); 346 if(len > 3 && start[0] == '\'') { 347 ntmp=&start[1]; 348 *end='\0'; 349 /* Do we have dlname="" ? */ 350 if(ntmp == end) { 351 _sasl_log(NULL, SASL_LOG_DEBUG, 352 "dlname is empty in .la file: %s", in); 353 return SASL_FAIL; 354 } 355 strcpy(out, prefix); 356 strcat(out, ntmp); 357 } 358 break; 359 } 360 } 361 if(ferror(file) || feof(file)) { 362 _sasl_log(NULL, SASL_LOG_WARN, 363 "Error reading .la: %s\n", in); 364 fclose(file); 365 return SASL_FAIL; 366 } 367 fclose(file); 368 369 if(!(*out)) { 370 _sasl_log(NULL, SASL_LOG_WARN, 371 "Could not find a dlname line in .la file: %s", in); 372 return SASL_FAIL; 373 } 374 375 return SASL_OK; 376 } 377 #endif /* !_SUN_SDK_ */ 378 #endif /* DO_DLOPEN */ 379 380 /* loads a plugin library */ 381 #ifdef _SUN_SDK_ 382 int _sasl_get_plugin(_sasl_global_context_t *gctx, 383 const char *file, 384 const sasl_callback_t *verifyfile_cb, 385 void **libraryptr) 386 #else 387 int _sasl_get_plugin(const char *file, 388 const sasl_callback_t *verifyfile_cb, 389 void **libraryptr) 390 #endif /* _SUN_SDK_ */ 391 { 392 #ifdef DO_DLOPEN 393 int r = 0; 394 int flag; 395 void *library; 396 lib_list_t *newhead; 397 398 r = ((sasl_verifyfile_t *)(verifyfile_cb->proc)) 399 (verifyfile_cb->context, file, SASL_VRFY_PLUGIN); 400 if (r != SASL_OK) return r; 401 402 #ifdef RTLD_NOW 403 flag = RTLD_NOW; 404 #else 405 flag = 0; 406 #endif 407 408 newhead = sasl_ALLOC(sizeof(lib_list_t)); 409 if(!newhead) return SASL_NOMEM; 410 411 if (!(library = dlopen(file, flag))) { 412 #ifdef _SUN_SDK_ 413 __sasl_log(gctx, gctx->server_global_callbacks.callbacks == NULL ? 414 gctx->client_global_callbacks.callbacks : 415 gctx->server_global_callbacks.callbacks, 416 SASL_LOG_ERR, 417 "unable to dlopen %s: %s", file, dlerror()); 418 #else 419 _sasl_log(NULL, SASL_LOG_ERR, 420 "unable to dlopen %s: %s", file, dlerror()); 421 #endif /* _SUN_SDK_ */ 422 sasl_FREE(newhead); 423 return SASL_FAIL; 424 } 425 426 #ifdef _SUN_SDK_ 427 if (LOCK_MUTEX(&global_mutex) < 0) { 428 sasl_FREE(newhead); 429 dlclose(library); 430 return (SASL_FAIL); 431 } 432 #endif /* _SUN_SDK_ */ 433 434 newhead->library = library; 435 #ifdef _SUN_SDK_ 436 newhead->next = gctx->lib_list_head; 437 gctx->lib_list_head = newhead; 438 UNLOCK_MUTEX(&global_mutex); 439 #else 440 newhead->next = lib_list_head; 441 lib_list_head = newhead; 442 #endif /* _SUN_SDK_ */ 443 444 *libraryptr = library; 445 return SASL_OK; 446 #else 447 return SASL_FAIL; 448 #endif /* DO_DLOPEN */ 449 } 450 451 #ifdef _SUN_SDK_ 452 #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */ 453 454 static void release_plugin(_sasl_global_context_t *gctx, void *library) 455 { 456 lib_list_t *libptr, *libptr_next = NULL, *libptr_prev = NULL; 457 int r; 458 459 r = LOCK_MUTEX(&global_mutex); 460 if (r < 0) 461 return; 462 463 for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) { 464 libptr_next = libptr->next; 465 if (library == libptr->library) { 466 if(libptr->library) 467 #if defined DO_DLOPEN /* _SUN_SDK_ */ 468 dlclose(libptr->library); 469 #else 470 FreeLibrary(libptr->library); 471 #endif /* DO_DLOPEN */ /* _SUN_SDK_ */ 472 sasl_FREE(libptr); 473 break; 474 } 475 libptr_prev = libptr; 476 } 477 if (libptr_prev == NULL) 478 gctx->lib_list_head = libptr_next; 479 else 480 libptr_prev->next = libptr_next; 481 482 UNLOCK_MUTEX(&global_mutex); 483 } 484 #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */ 485 #endif /* _SUN_SDK_ */ 486 487 /* gets the list of mechanisms */ 488 #ifdef _SUN_SDK_ 489 int _sasl_load_plugins(_sasl_global_context_t *gctx, 490 int server, 491 const add_plugin_list_t *entrypoints, 492 const sasl_callback_t *getpath_cb, 493 const sasl_callback_t *verifyfile_cb) 494 #else 495 int _sasl_load_plugins(const add_plugin_list_t *entrypoints, 496 const sasl_callback_t *getpath_cb, 497 const sasl_callback_t *verifyfile_cb) 498 #endif /* _SUN_SDK_ */ 499 { 500 int result; 501 const add_plugin_list_t *cur_ep; 502 #ifdef _SUN_SDK_ 503 _sasl_path_info_t *path_info, *p_info; 504 #endif /* _SUN_SDK_ */ 505 #ifdef DO_DLOPEN 506 char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2]; 507 /* 1 for '/' 1 for trailing '\0' */ 508 char c; 509 int pos; 510 const char *path=NULL; 511 int position; 512 DIR *dp; 513 struct dirent *dir; 514 #ifdef _SUN_SDK_ 515 int plugin_loaded; 516 struct stat b; 517 #endif /* _SUN_SDK_ */ 518 #endif 519 #ifndef PIC 520 add_plugin_t *add_plugin; 521 _sasl_plug_type type; 522 _sasl_plug_rec *p; 523 #endif 524 525 if (! entrypoints 526 || ! getpath_cb 527 || getpath_cb->id != SASL_CB_GETPATH 528 || ! getpath_cb->proc 529 || ! verifyfile_cb 530 || verifyfile_cb->id != SASL_CB_VERIFYFILE 531 || ! verifyfile_cb->proc) 532 return SASL_BADPARAM; 533 534 #ifndef PIC 535 /* do all the static plugins first */ 536 537 for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { 538 539 /* What type of plugin are we looking for? */ 540 if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) { 541 type = SERVER; 542 #ifdef _SUN_SDK_ 543 add_plugin = (add_plugin_t *)_sasl_server_add_plugin; 544 #else 545 add_plugin = (add_plugin_t *)sasl_server_add_plugin; 546 #endif /* _SUN_SDK_ */ 547 } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) { 548 type = CLIENT; 549 #ifdef _SUN_SDK_ 550 add_plugin = (add_plugin_t *)_sasl_client_add_plugin; 551 #else 552 add_plugin = (add_plugin_t *)sasl_client_add_plugin; 553 #endif /* _SUN_SDK_ */ 554 } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) { 555 type = AUXPROP; 556 #ifdef _SUN_SDK_ 557 add_plugin = (add_plugin_t *)_sasl_auxprop_add_plugin; 558 #else 559 add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin; 560 #endif /* _SUN_SDK_ */ 561 } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) { 562 type = CANONUSER; 563 #ifdef _SUN_SDK_ 564 add_plugin = (add_plugin_t *)_sasl_canonuser_add_plugin; 565 #else 566 add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin; 567 #endif /* _SUN_SDK_ */ 568 } else { 569 /* What are we looking for then? */ 570 return SASL_FAIL; 571 } 572 for (p=_sasl_static_plugins; p->type; p++) { 573 if(type == p->type) 574 #ifdef _SUN_SDK_ 575 result = add_plugin(gctx, p->name, (void *)p->plug); 576 #else 577 result = add_plugin(p->name, p->plug); 578 #endif /* _SUN_SDK_ */ 579 } 580 } 581 #endif /* !PIC */ 582 583 /* only do the following if: 584 * 585 * we support dlopen() 586 * AND we are not staticly compiled 587 * OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined 588 */ 589 #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) 590 /* get the path to the plugins */ 591 result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, 592 &path); 593 if (result != SASL_OK) return result; 594 if (! path) return SASL_FAIL; 595 596 if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */ 597 return SASL_FAIL; 598 } 599 600 position=0; 601 do { 602 pos=0; 603 do { 604 c=path[position]; 605 position++; 606 str[pos]=c; 607 pos++; 608 } while ((c!=':') && (c!='=') && (c!=0)); 609 str[pos-1]='\0'; 610 611 strcpy(prefix,str); 612 strcat(prefix,"/"); 613 #ifdef _SUN_SDK_ 614 path_info = server ? gctx->splug_path_info : gctx->cplug_path_info; 615 while (path_info != NULL) { 616 if (strcmp(path_info->path, prefix) == 0) 617 break; 618 path_info = path_info->next; 619 } 620 if (stat(prefix, &b) != 0) { 621 continue; 622 } 623 if ( path_info == NULL) { 624 p_info = (_sasl_path_info_t *) 625 sasl_ALLOC(sizeof (_sasl_path_info_t)); 626 if (p_info == NULL) { 627 return SASL_NOMEM; 628 } 629 if(_sasl_strdup(prefix, &p_info->path, NULL) != SASL_OK) { 630 sasl_FREE(p_info); 631 return SASL_NOMEM; 632 } 633 p_info->last_changed = b.st_mtime; 634 if (server) { 635 p_info->next = gctx->splug_path_info; 636 gctx->splug_path_info = p_info; 637 } else { 638 p_info->next = gctx->cplug_path_info; 639 gctx->cplug_path_info = p_info; 640 } 641 } else { 642 if (b.st_mtime <= path_info->last_changed) { 643 continue; 644 } 645 } 646 #endif /* _SUN_SDK_ */ 647 648 if ((dp=opendir(str)) !=NULL) /* ignore errors */ 649 { 650 while ((dir=readdir(dp)) != NULL) 651 { 652 size_t length; 653 void *library; 654 #ifndef _SUN_SDK_ 655 char *c; 656 #endif /* !_SUN_SDK_ */ 657 char plugname[PATH_MAX]; 658 char name[PATH_MAX]; 659 660 length = NAMLEN(dir); 661 #ifndef _SUN_SDK_ 662 if (length < 4) 663 continue; /* can not possibly be what we're looking for */ 664 #endif /* !_SUN_SDK_ */ 665 666 if (length + pos>=PATH_MAX) continue; /* too big */ 667 668 #ifdef _SUN_SDK_ 669 if (dir->d_name[0] == '.') 670 continue; 671 #else 672 if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)), 673 SO_SUFFIX) 674 && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)), 675 LA_SUFFIX)) 676 continue; 677 #endif /* _SUN_SDK_ */ 678 679 memcpy(name,dir->d_name,length); 680 name[length]='\0'; 681 682 #ifdef _SUN_SDK_ 683 snprintf(tmp, sizeof (tmp), "%s%s", prefix, name); 684 #else 685 result = _parse_la(prefix, name, tmp); 686 if(result != SASL_OK) 687 continue; 688 #endif /* _SUN_SDK_ */ 689 690 #ifdef _SUN_SDK_ 691 if (stat(tmp, &b)) 692 continue; /* Can't stat it */ 693 if (!S_ISREG(b.st_mode)) 694 continue; 695 /* Sun plugins don't have lib prefix */ 696 strcpy(plugname, name); 697 #else 698 /* skip "lib" and cut off suffix -- 699 this only need be approximate */ 700 strcpy(plugname, name + 3); 701 c = strchr(plugname, (int)'.'); 702 if(c) *c = '\0'; 703 #endif /* _SUN_SDK_ */ 704 705 #ifdef _SUN_SDK_ 706 result = _sasl_get_plugin(gctx, tmp, verifyfile_cb, 707 &library); 708 #else 709 result = _sasl_get_plugin(tmp, verifyfile_cb, &library); 710 #endif /* _SUN_SDK_ */ 711 712 if(result != SASL_OK) 713 continue; 714 715 #ifdef _SUN_SDK_ 716 plugin_loaded = 0; 717 for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { 718 /* If this fails, it's not the end of the world */ 719 if (_sasl_plugin_load(gctx, plugname, library, 720 cur_ep->entryname, 721 cur_ep->add_plugin) == SASL_OK) { 722 plugin_loaded = 1; 723 } 724 } 725 if (!plugin_loaded) 726 release_plugin(gctx, library); 727 #else 728 for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { 729 _sasl_plugin_load(plugname, library, cur_ep->entryname, 730 cur_ep->add_plugin); 731 /* If this fails, it's not the end of the world */ 732 } 733 #endif /* _SUN_SDK_ */ 734 } 735 736 closedir(dp); 737 } 738 739 } while ((c!='=') && (c!=0)); 740 #elif defined _SUN_SDK_ && defined WIN_PLUG 741 result = 742 _sasl_load_win_plugins(gctx, entrypoints, getpath_cb, verifyfile_cb); 743 if (result != SASL_OK) 744 return (result); 745 #endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */ 746 747 return SASL_OK; 748 } 749 750 #ifdef _SUN_SDK_ 751 int 752 _sasl_done_with_plugins(_sasl_global_context_t *gctx) 753 #else 754 int 755 _sasl_done_with_plugins(void) 756 #endif /* _SUN_SDK_ */ 757 { 758 #if defined DO_DLOPEN || defined WIN_PLUG /* _SUN_SDK_ */ 759 lib_list_t *libptr, *libptr_next; 760 761 #ifdef _SUN_SDK_ 762 if (LOCK_MUTEX(&global_mutex) < 0) 763 return (SASL_FAIL); 764 #endif /* _SUN_SDK_ */ 765 766 #ifdef _SUN_SDK_ 767 for(libptr = gctx->lib_list_head; libptr; libptr = libptr_next) { 768 #else 769 for(libptr = lib_list_head; libptr; libptr = libptr_next) { 770 #endif /* _SUN_SDK_ */ 771 libptr_next = libptr->next; 772 if(libptr->library) 773 #ifdef DO_DLOPEN /* _SUN_SDK_ */ 774 dlclose(libptr->library); 775 #else 776 FreeLibrary(libptr->library); 777 #endif /* DO_DLOPEN */ /* _SUN_SDK_ */ 778 sasl_FREE(libptr); 779 } 780 781 #ifdef _SUN_SDK_ 782 gctx->lib_list_head = NULL; 783 #else 784 lib_list_head = NULL; 785 #endif /* _SUN_SDK_ */ 786 787 #ifdef _SUN_SDK_ 788 UNLOCK_MUTEX(&global_mutex); 789 #endif /* _SUN_SDK_ */ 790 #endif /* DO_DLOPEN || WIN_PLUG */ /* _SUN_SDK_ */ 791 return SASL_OK; 792 } 793 794 #ifdef WIN_MUTEX 795 796 static HANDLE global_mutex = NULL; 797 798 int win_global_mutex_lock() 799 { 800 DWORD dwWaitResult; 801 802 if (global_mutex == NULL) { 803 global_mutex = CreateMutex(NULL, FALSE, NULL); 804 if (global_mutex == NULL) 805 return (-1); 806 } 807 808 dwWaitResult = WaitForSingleObject(global_mutex, INFINITE); 809 810 switch (dwWaitResult) { 811 case WAIT_OBJECT_0: 812 return (0); 813 814 case WAIT_TIMEOUT: 815 return (-1); /* Shouldn't happen */ 816 817 case WAIT_ABANDONED: 818 return (-1); /* Shouldn't happen */ 819 } 820 return (-1); /* Unexpected result */ 821 } 822 823 int win_global_mutex_unlock() 824 { 825 if (global_mutex == NULL) 826 return (-1); 827 828 return (ReleaseMutex(global_mutex) ? 0 : -1); 829 } 830 831 BOOL APIENTRY DllMain(HANDLE hModule, 832 DWORD ul_reason_for_call, 833 LPVOID lpReserved) 834 { 835 switch( ul_reason_for_call ) { 836 case DLL_PROCESS_ATTACH: 837 global_mutex = CreateMutex(NULL, FALSE, NULL); 838 if (global_mutex == NULL) 839 return (FALSE); 840 break; 841 case DLL_THREAD_ATTACH: 842 case DLL_THREAD_DETACH: 843 case DLL_PROCESS_DETACH: 844 break; 845 } 846 return TRUE; 847 } 848 #endif 849