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"
35 __RCSID("$Heimdal: plugin.c 22033 2007-11-10 10:39:47Z lha $"
45 struct krb5_plugin
*next
;
49 enum krb5_plugin_type type
;
55 static HEIMDAL_MUTEX plugin_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
56 static struct plugin
*registered
= NULL
;
58 static const char *plugin_dir
= LIBDIR
"/plugin/krb5";
65 _krb5_plugin_get_symbol(struct krb5_plugin
*p
)
71 _krb5_plugin_get_next(struct krb5_plugin
*p
)
82 static krb5_error_code
83 loadlib(krb5_context context
,
84 enum krb5_plugin_type type
,
87 struct krb5_plugin
**e
)
89 *e
= calloc(1, sizeof(**e
));
91 krb5_set_error_string(context
, "out of memory");
99 (*e
)->dsohandle
= dlopen(lib
, RTLD_LAZY
);
100 if ((*e
)->dsohandle
== NULL
) {
103 krb5_set_error_string(context
, "Failed to load %s: %s",
108 /* dlsym doesn't care about the type */
109 (*e
)->symbol
= dlsym((*e
)->dsohandle
, name
);
110 if ((*e
)->symbol
== NULL
) {
111 dlclose((*e
)->dsohandle
);
113 krb5_clear_error_string(context
);
119 #endif /* HAVE_DLOPEN */
122 * Register a plugin symbol name of specific type.
123 * @param context a Keberos context
124 * @param type type of plugin symbol
125 * @param name name of plugin symbol
126 * @param symbol a pointer to the named symbol
127 * @return In case of error a non zero error com_err error is returned
128 * and the Kerberos error string is set.
130 * @ingroup krb5_support
134 krb5_plugin_register(krb5_context context
,
135 enum krb5_plugin_type type
,
141 e
= calloc(1, sizeof(*e
));
143 krb5_set_error_string(context
, "out of memory");
147 e
->name
= strdup(name
);
148 if (e
->name
== NULL
) {
150 krb5_set_error_string(context
, "out of memory");
155 HEIMDAL_MUTEX_lock(&plugin_mutex
);
156 e
->next
= registered
;
158 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
164 _krb5_plugin_find(krb5_context context
,
165 enum krb5_plugin_type type
,
167 struct krb5_plugin
**list
)
169 struct krb5_plugin
*e
;
172 char *sysdirs
[2] = { NULL
, NULL
};
173 char **dirs
= NULL
, **di
;
174 struct dirent
*entry
;
180 HEIMDAL_MUTEX_lock(&plugin_mutex
);
182 for (p
= registered
; p
!= NULL
; p
= p
->next
) {
183 if (p
->type
!= type
|| strcmp(p
->name
, name
) != 0)
186 e
= calloc(1, sizeof(*e
));
188 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
189 krb5_set_error_string(context
, "out of memory");
193 e
->symbol
= p
->symbol
;
198 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
202 dirs
= krb5_config_get_strings(context
, NULL
, "libdefaults",
205 sysdirs
[0] = rk_UNCONST(plugin_dir
);
209 for (di
= dirs
; *di
!= NULL
; di
++) {
215 while ((entry
= readdir(d
)) != NULL
) {
216 asprintf(&path
, "%s/%s", *di
, entry
->d_name
);
218 krb5_set_error_string(context
, "out of memory");
222 ret
= loadlib(context
, type
, name
, path
, &e
);
233 krb5_config_free_strings(dirs
);
234 #endif /* HAVE_DLOPEN */
237 krb5_set_error_string(context
, "Did not find a plugin for %s", name
);
244 if (dirs
&& dirs
!= sysdirs
)
245 krb5_config_free_strings(dirs
);
248 _krb5_plugin_free(*list
);
255 _krb5_plugin_free(struct krb5_plugin
*list
)
257 struct krb5_plugin
*next
;
261 dlclose(list
->dsohandle
);