openpam_dynamic.c (186063) | openpam_dynamic.c (228690) |
---|---|
1/*- 2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc. | 1/*- 2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc. |
3 * Copyright (c) 2004-2007 Dag-Erling Sm��rgrav | 3 * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav |
4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by ThinkSec AS and 7 * Network Associates Laboratories, the Security Research Division of 8 * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 9 * ("CBOSS"), as part of the DARPA CHATS research program. 10 * 11 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * | 4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by ThinkSec AS and 7 * Network Associates Laboratories, the Security Research Division of 8 * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 9 * ("CBOSS"), as part of the DARPA CHATS research program. 10 * 11 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * |
35 * $Id: openpam_dynamic.c 408 2007-12-21 11:36:24Z des $ | 35 * $Id: openpam_dynamic.c 502 2011-12-18 13:59:22Z des $ |
36 */ 37 | 36 */ 37 |
38#ifdef HAVE_CONFIG_H 39# include "config.h" 40#endif 41 |
|
38#include <dlfcn.h> | 42#include <dlfcn.h> |
43#include <errno.h> |
|
39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> | 44#include <stdio.h> 45#include <stdlib.h> 46#include <string.h> |
47#include <unistd.h> |
|
42 43#include <security/pam_appl.h> 44 45#include "openpam_impl.h" 46 47#ifndef RTLD_NOW 48#define RTLD_NOW RTLD_LAZY 49#endif 50 51/* 52 * OpenPAM internal 53 * | 48 49#include <security/pam_appl.h> 50 51#include "openpam_impl.h" 52 53#ifndef RTLD_NOW 54#define RTLD_NOW RTLD_LAZY 55#endif 56 57/* 58 * OpenPAM internal 59 * |
60 * Perform sanity checks and attempt to load a module 61 */ 62 63static void * 64try_dlopen(const char *modfn) 65{ 66 67 if (openpam_check_path_owner_perms(modfn) != 0) 68 return (NULL); 69 return (dlopen(modfn, RTLD_NOW)); 70} 71 72/* 73 * OpenPAM internal 74 * |
|
54 * Locate a dynamically linked module 55 */ 56 57pam_module_t * 58openpam_dynamic(const char *path) 59{ | 75 * Locate a dynamically linked module 76 */ 77 78pam_module_t * 79openpam_dynamic(const char *path) 80{ |
81 const pam_module_t *dlmodule; |
|
60 pam_module_t *module; 61 const char *prefix; 62 char *vpath; 63 void *dlh; | 82 pam_module_t *module; 83 const char *prefix; 84 char *vpath; 85 void *dlh; |
64 int i; | 86 int i, serrno; |
65 66 dlh = NULL; | 87 88 dlh = NULL; |
67 if ((module = calloc(1, sizeof *module)) == NULL) 68 goto buf_err; | |
69 70 /* Prepend the standard prefix if not an absolute pathname. */ 71 if (path[0] != '/') 72 prefix = OPENPAM_MODULES_DIR; 73 else 74 prefix = ""; 75 76 /* try versioned module first, then unversioned module */ 77 if (asprintf(&vpath, "%s%s.%d", prefix, path, LIB_MAJ) < 0) | 89 90 /* Prepend the standard prefix if not an absolute pathname. */ 91 if (path[0] != '/') 92 prefix = OPENPAM_MODULES_DIR; 93 else 94 prefix = ""; 95 96 /* try versioned module first, then unversioned module */ 97 if (asprintf(&vpath, "%s%s.%d", prefix, path, LIB_MAJ) < 0) |
78 goto buf_err; 79 if ((dlh = dlopen(vpath, RTLD_NOW)) == NULL) { 80 openpam_log(PAM_LOG_DEBUG, "%s: %s", vpath, dlerror()); | 98 goto err; 99 if ((dlh = try_dlopen(vpath)) == NULL && errno == ENOENT) { |
81 *strrchr(vpath, '.') = '\0'; | 100 *strrchr(vpath, '.') = '\0'; |
82 if ((dlh = dlopen(vpath, RTLD_NOW)) == NULL) { 83 openpam_log(PAM_LOG_DEBUG, "%s: %s", vpath, dlerror()); 84 FREE(vpath); 85 FREE(module); 86 return (NULL); 87 } | 101 dlh = try_dlopen(vpath); |
88 } | 102 } |
103 serrno = errno; |
|
89 FREE(vpath); | 104 FREE(vpath); |
105 errno = serrno; 106 if (dlh == NULL) 107 goto err; 108 if ((module = calloc(1, sizeof *module)) == NULL) 109 goto buf_err; |
|
90 if ((module->path = strdup(path)) == NULL) 91 goto buf_err; 92 module->dlh = dlh; | 110 if ((module->path = strdup(path)) == NULL) 111 goto buf_err; 112 module->dlh = dlh; |
113 dlmodule = dlsym(dlh, "_pam_module"); |
|
93 for (i = 0; i < PAM_NUM_PRIMITIVES; ++i) { | 114 for (i = 0; i < PAM_NUM_PRIMITIVES; ++i) { |
94 module->func[i] = (pam_func_t)dlsym(dlh, _pam_sm_func_name[i]); | 115 module->func[i] = dlmodule ? dlmodule->func[i] : 116 (pam_func_t)dlsym(dlh, pam_sm_func_name[i]); |
95 if (module->func[i] == NULL) 96 openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", | 117 if (module->func[i] == NULL) 118 openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", |
97 path, _pam_sm_func_name[i], dlerror()); | 119 path, pam_sm_func_name[i], dlerror()); |
98 } 99 return (module); | 120 } 121 return (module); |
100 buf_err: 101 openpam_log(PAM_LOG_ERROR, "%m"); | 122buf_err: |
102 if (dlh != NULL) 103 dlclose(dlh); 104 FREE(module); | 123 if (dlh != NULL) 124 dlclose(dlh); 125 FREE(module); |
126err: 127 openpam_log(PAM_LOG_ERROR, "%m"); |
|
105 return (NULL); 106} 107 108/* 109 * NOPARSE 110 */ | 128 return (NULL); 129} 130 131/* 132 * NOPARSE 133 */ |