2
* Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
#include "krb5_locl.h"
44
struct krb5_plugin *next;
48
enum krb5_plugin_type type;
54
static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER;
55
static struct plugin *registered = NULL;
57
static const char *plugin_dir = LIBDIR "/plugin/krb5";
64
_krb5_plugin_get_symbol(struct krb5_plugin *p)
70
_krb5_plugin_get_next(struct krb5_plugin *p)
81
static krb5_error_code
82
loadlib(krb5_context context,
83
enum krb5_plugin_type type,
86
struct krb5_plugin **e)
88
*e = calloc(1, sizeof(**e));
90
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
98
(*e)->dsohandle = dlopen(lib, RTLD_LAZY);
99
if ((*e)->dsohandle == NULL) {
102
krb5_set_error_message(context, ENOMEM, "Failed to load %s: %s",
107
/* dlsym doesn't care about the type */
108
(*e)->symbol = dlsym((*e)->dsohandle, name);
109
if ((*e)->symbol == NULL) {
110
dlclose((*e)->dsohandle);
112
krb5_clear_error_message(context);
118
#endif /* HAVE_DLOPEN */
121
* Register a plugin symbol name of specific type.
122
* @param context a Keberos context
123
* @param type type of plugin symbol
124
* @param name name of plugin symbol
125
* @param symbol a pointer to the named symbol
126
* @return In case of error a non zero error com_err error is returned
127
* and the Kerberos error string is set.
129
* @ingroup krb5_support
133
krb5_plugin_register(krb5_context context,
134
enum krb5_plugin_type type,
140
/* check for duplicates */
141
for (e = registered; e != NULL; e = e->next)
142
if (e->type == type && strcmp(e->name,name)== 0 && e->symbol == symbol)
145
e = calloc(1, sizeof(*e));
147
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
151
e->name = strdup(name);
152
if (e->name == NULL) {
154
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
159
HEIMDAL_MUTEX_lock(&plugin_mutex);
160
e->next = registered;
162
HEIMDAL_MUTEX_unlock(&plugin_mutex);
168
_krb5_plugin_find(krb5_context context,
169
enum krb5_plugin_type type,
171
struct krb5_plugin **list)
173
struct krb5_plugin *e;
176
char *sysdirs[2] = { NULL, NULL };
177
char **dirs = NULL, **di;
178
struct dirent *entry;
184
HEIMDAL_MUTEX_lock(&plugin_mutex);
186
for (p = registered; p != NULL; p = p->next) {
187
if (p->type != type || strcmp(p->name, name) != 0)
190
e = calloc(1, sizeof(*e));
192
HEIMDAL_MUTEX_unlock(&plugin_mutex);
194
krb5_set_error_message(context, ret, "malloc: out of memory");
197
e->symbol = p->symbol;
202
HEIMDAL_MUTEX_unlock(&plugin_mutex);
206
dirs = krb5_config_get_strings(context, NULL, "libdefaults",
209
sysdirs[0] = rk_UNCONST(plugin_dir);
213
for (di = dirs; *di != NULL; di++) {
218
rk_cloexec(dirfd(d));
220
while ((entry = readdir(d)) != NULL) {
221
asprintf(&path, "%s/%s", *di, entry->d_name);
224
krb5_set_error_message(context, ret, "malloc: out of memory");
227
ret = loadlib(context, type, name, path, &e);
238
krb5_config_free_strings(dirs);
239
#endif /* HAVE_DLOPEN */
242
krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name);
249
if (dirs && dirs != sysdirs)
250
krb5_config_free_strings(dirs);
253
_krb5_plugin_free(*list);
260
_krb5_plugin_free(struct krb5_plugin *list)
262
struct krb5_plugin *next;
266
dlclose(list->dsohandle);