openpam_load.c revision 174832
1/*- 2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc. 3 * Copyright (c) 2004-2007 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 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote 20 * products derived from this software without specific prior written 21 * permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 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_load.c 408 2007-12-21 11:36:24Z des $ 36 */ 37 38#include <dlfcn.h> 39#include <stdlib.h> 40#include <string.h> 41 42#include <security/pam_appl.h> 43 44#include "openpam_impl.h" 45 46const char *_pam_func_name[PAM_NUM_PRIMITIVES] = { 47 "pam_authenticate", 48 "pam_setcred", 49 "pam_acct_mgmt", 50 "pam_open_session", 51 "pam_close_session", 52 "pam_chauthtok" 53}; 54 55const char *_pam_sm_func_name[PAM_NUM_PRIMITIVES] = { 56 "pam_sm_authenticate", 57 "pam_sm_setcred", 58 "pam_sm_acct_mgmt", 59 "pam_sm_open_session", 60 "pam_sm_close_session", 61 "pam_sm_chauthtok" 62}; 63 64/* 65 * Locate a matching dynamic or static module. 66 */ 67 68pam_module_t * 69openpam_load_module(const char *path) 70{ 71 pam_module_t *module; 72 73 module = openpam_dynamic(path); 74 openpam_log(PAM_LOG_DEBUG, "%s dynamic %s", 75 (module == NULL) ? "no" : "using", path); 76 77#ifdef OPENPAM_STATIC_MODULES 78 /* look for a static module */ 79 if (module == NULL && strchr(path, '/') == NULL) { 80 module = openpam_static(path); 81 openpam_log(PAM_LOG_DEBUG, "%s static %s", 82 (module == NULL) ? "no" : "using", path); 83 } 84#endif 85 if (module == NULL) { 86 openpam_log(PAM_LOG_ERROR, "no %s found", path); 87 return (NULL); 88 } 89 return (module); 90} 91 92 93/* 94 * Release a module. 95 * XXX highly thread-unsafe 96 */ 97 98static void 99openpam_release_module(pam_module_t *module) 100{ 101 if (module == NULL) 102 return; 103 if (module->dlh == NULL) 104 /* static module */ 105 return; 106 dlclose(module->dlh); 107 openpam_log(PAM_LOG_DEBUG, "releasing %s", module->path); 108 FREE(module->path); 109 FREE(module); 110} 111 112 113/* 114 * Destroy a chain, freeing all its links and releasing the modules 115 * they point to. 116 */ 117 118static void 119openpam_destroy_chain(pam_chain_t *chain) 120{ 121 if (chain == NULL) 122 return; 123 openpam_destroy_chain(chain->next); 124 chain->next = NULL; 125 while (chain->optc) { 126 --chain->optc; 127 FREE(chain->optv[chain->optc]); 128 } 129 FREE(chain->optv); 130 openpam_release_module(chain->module); 131 chain->module = NULL; 132 FREE(chain); 133} 134 135 136/* 137 * Clear the chains and release the modules 138 */ 139 140void 141openpam_clear_chains(pam_chain_t *policy[]) 142{ 143 int i; 144 145 for (i = 0; i < PAM_NUM_FACILITIES; ++i) { 146 openpam_destroy_chain(policy[i]); 147 policy[i] = NULL; 148 } 149} 150 151/* 152 * NOPARSE 153 */ 154