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