2 * Copyright (c) 2006 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"
35 RCSID("$Id: plugin.c,v 1.2 2006/11/12 21:39:43 lha Exp $");
44 struct krb5_plugin
*next
;
48 enum 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
)
79 static krb5_error_code
80 loadlib(krb5_context context
,
81 enum plugin_type type
,
84 struct krb5_plugin
**e
)
86 *e
= calloc(1, sizeof(**e
));
88 krb5_set_error_string(context
, "out of memory");
92 (*e
)->dsohandle
= dlopen(lib
, 0);
93 if ((*e
)->dsohandle
== NULL
) {
95 krb5_set_error_string(context
, "Failed to load %s: %s",
100 /* dlsym doesn't care about the type */
101 (*e
)->symbol
= dlsym((*e
)->dsohandle
, name
);
102 if ((*e
)->symbol
== NULL
) {
103 dlclose((*e
)->dsohandle
);
105 krb5_clear_error_string(context
);
113 _krb5_plugin_register(krb5_context context
,
114 enum plugin_type type
,
120 e
= calloc(1, sizeof(*e
));
122 krb5_set_error_string(context
, "out of memory");
126 e
->name
= strdup(name
);
127 if (e
->name
== NULL
) {
129 krb5_set_error_string(context
, "out of memory");
134 HEIMDAL_MUTEX_lock(&plugin_mutex
);
135 e
->next
= registered
;
137 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
143 _krb5_plugin_find(krb5_context context
,
144 enum plugin_type type
,
146 struct krb5_plugin
**list
)
148 struct krb5_plugin
*e
;
151 char *sysdirs
[2] = { NULL
, NULL
};
152 char **dirs
= NULL
, **di
;
153 struct dirent
*entry
;
159 HEIMDAL_MUTEX_lock(&plugin_mutex
);
161 for (p
= registered
; p
!= NULL
; p
= p
->next
) {
162 if (p
->type
!= type
|| strcmp(p
->name
, name
) != 0)
165 e
= calloc(1, sizeof(*e
));
167 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
168 krb5_set_error_string(context
, "out of memory");
172 e
->symbol
= p
->symbol
;
177 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
179 dirs
= krb5_config_get_strings(context
, NULL
, "libdefaults",
182 sysdirs
[0] = rk_UNCONST(plugin_dir
);
186 for (di
= dirs
; *di
!= NULL
; di
++) {
192 while ((entry
= readdir(d
)) != NULL
) {
193 asprintf(&path
, "%s/%s", *di
, entry
->d_name
);
195 krb5_set_error_string(context
, "out of memory");
199 ret
= loadlib(context
, type
, name
, path
, &e
);
210 krb5_config_free_strings(dirs
);
213 krb5_set_error_string(context
, "Did not find a plugin for %s", name
);
220 if (dirs
&& dirs
!= sysdirs
)
221 krb5_config_free_strings(dirs
);
224 _krb5_plugin_free(*list
);
231 _krb5_plugin_free(struct krb5_plugin
*list
)
233 struct krb5_plugin
*next
;
237 dlclose(list
->dsohandle
);