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_string(context
, "out of memory");
98 (*e
)->dsohandle
= dlopen(lib
, RTLD_LAZY
);
99 if ((*e
)->dsohandle
== NULL
) {
102 krb5_set_error_string(context
, "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_string(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 e
= calloc(1, sizeof(*e
));
142 krb5_set_error_string(context
, "out of memory");
146 e
->name
= strdup(name
);
147 if (e
->name
== NULL
) {
149 krb5_set_error_string(context
, "out of memory");
154 HEIMDAL_MUTEX_lock(&plugin_mutex
);
155 e
->next
= registered
;
157 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
163 _krb5_plugin_find(krb5_context context
,
164 enum krb5_plugin_type type
,
166 struct krb5_plugin
**list
)
168 struct krb5_plugin
*e
;
171 char *sysdirs
[2] = { NULL
, NULL
};
172 char **dirs
= NULL
, **di
;
173 struct dirent
*entry
;
179 HEIMDAL_MUTEX_lock(&plugin_mutex
);
181 for (p
= registered
; p
!= NULL
; p
= p
->next
) {
182 if (p
->type
!= type
|| strcmp(p
->name
, name
) != 0)
185 e
= calloc(1, sizeof(*e
));
187 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
188 krb5_set_error_string(context
, "out of memory");
192 e
->symbol
= p
->symbol
;
197 HEIMDAL_MUTEX_unlock(&plugin_mutex
);
201 dirs
= krb5_config_get_strings(context
, NULL
, "libdefaults",
204 sysdirs
[0] = rk_UNCONST(plugin_dir
);
208 for (di
= dirs
; *di
!= NULL
; di
++) {
214 while ((entry
= readdir(d
)) != NULL
) {
215 asprintf(&path
, "%s/%s", *di
, entry
->d_name
);
217 krb5_set_error_string(context
, "out of memory");
221 ret
= loadlib(context
, type
, name
, path
, &e
);
232 krb5_config_free_strings(dirs
);
233 #endif /* HAVE_DLOPEN */
236 krb5_set_error_string(context
, "Did not find a plugin for %s", name
);
243 if (dirs
&& dirs
!= sysdirs
)
244 krb5_config_free_strings(dirs
);
247 _krb5_plugin_free(*list
);
254 _krb5_plugin_free(struct krb5_plugin
*list
)
256 struct krb5_plugin
*next
;
260 dlclose(list
->dsohandle
);