1 /* windlopen.c--Windows dynamic loader interface
3 * $Id: windlopen.c,v 1.16 2003/10/20 15:19:59 rjs3 Exp $
6 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. The name "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any other legal
23 * details, please contact
24 * Office of Technology Transfer
25 * Carnegie Mellon University
27 * Pittsburgh, PA 15213-3890
28 * (412) 268-4387, fax: (412) 268-7395
29 * tech-transfer@andrew.cmu.edu
31 * 4. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by Computing Services
34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
53 #define DLL_SUFFIX ".dll"
54 #define DLL_MASK "*" DLL_SUFFIX
55 #define DLL_MASK_LEN 5
57 const int _is_sasl_server_static = 0;
59 /* : inefficient representation, but works */
60 typedef struct lib_list
62 struct lib_list *next;
66 static lib_list_t *lib_list_head = NULL;
68 int _sasl_locate_entry(void *library,
69 const char *entryname,
72 if(entryname == NULL) {
73 _sasl_log(NULL, SASL_LOG_ERR,
74 "no entryname in _sasl_locate_entry");
79 _sasl_log(NULL, SASL_LOG_ERR,
80 "no library in _sasl_locate_entry");
84 if(entry_point == NULL) {
85 _sasl_log(NULL, SASL_LOG_ERR,
86 "no entrypoint output pointer in _sasl_locate_entry");
90 *entry_point = GetProcAddress(library, entryname);
92 if (*entry_point == NULL) {
93 #if 0 /* This message appears to confuse people */
94 _sasl_log(NULL, SASL_LOG_DEBUG,
95 "unable to get entry point %s: %s", entryname,
104 static int _sasl_plugin_load(char *plugin, void *library,
105 const char *entryname,
106 int (*add_plugin)(const char *, void *))
111 result = _sasl_locate_entry(library, entryname, &entry_point);
112 if(result == SASL_OK) {
113 result = add_plugin(plugin, entry_point);
114 if(result != SASL_OK)
115 _sasl_log(NULL, SASL_LOG_DEBUG,
116 "_sasl_plugin_load failed on %s for plugin: %s\n",
123 /* loads a plugin library */
124 int _sasl_get_plugin(const char *file,
125 const sasl_callback_t *verifyfile_cb,
132 r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
133 (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
134 if (r != SASL_OK) return r;
136 newhead = sasl_ALLOC(sizeof(lib_list_t));
137 if(!newhead) return SASL_NOMEM;
139 if (!(library = LoadLibrary (file))) {
140 _sasl_log(NULL, SASL_LOG_ERR,
141 "unable to LoadLibrary %s: %s", file, GetLastError());
146 newhead->library = library;
147 newhead->next = lib_list_head;
148 lib_list_head = newhead;
150 *libraryptr = library;
156 /* gets the list of mechanisms */
157 int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
158 const sasl_callback_t *getpath_cb,
159 const sasl_callback_t *verifyfile_cb)
162 char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2];
163 /* 1 for '\\' 1 for trailing '\0' */
167 const char *path=NULL;
169 const add_plugin_list_t *cur_ep;
170 struct stat statbuf; /* filesystem entry information */
171 intptr_t fhandle; /* file handle for _findnext function */
172 struct _finddata_t finddata; /* data returned by _findnext() */
177 || getpath_cb->id != SASL_CB_GETPATH
178 || ! getpath_cb->proc
180 || verifyfile_cb->id != SASL_CB_VERIFYFILE
181 || ! verifyfile_cb->proc)
182 return SASL_BADPARAM;
184 /* get the path to the plugins */
185 result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
187 if (result != SASL_OK) return result;
188 if (! path) return SASL_FAIL;
190 if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
202 } while ((c!=PATHS_DELIMITER) && (c!=0));
206 /* : check to make sure that a valid directory name was passed in */
207 if (stat (cur_dir, &statbuf) < 0) {
210 if ((statbuf.st_mode & S_IFDIR) == 0) {
214 strcpy (prefix, cur_dir);
215 prefix_len = strlen (prefix);
217 /* : Don't append trailing \ unless required */
218 if (prefix[prefix_len-1] != '\\') {
219 strcat (prefix,"\\");
225 /* : Check that we have enough space for "*.dll" */
226 if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) {
227 _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big");
231 strcat (prefix + prefix_len, "*" DLL_SUFFIX);
233 fhandle = _findfirst (pattern, &finddata);
234 if (fhandle == -1) { /* no matching files */
238 /* : Truncate "*.dll" */
239 prefix[prefix_len] = '\0';
245 char plugname[PATH_MAX];
247 length = strlen(finddata.name);
248 if (length < 5) { /* At least <Ch>.dll */
249 continue; /* can not possibly be what we're looking for */
252 /* : Check for overflow */
253 if (length + prefix_len >= PATH_MAX) continue; /* too big */
255 if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) {
259 /* : Check that it is not a directory */
260 if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) {
264 /* : Construct full name from prefix and name */
266 strcpy (full_name, prefix);
267 strcat (full_name, finddata.name);
269 /* cut off .dll suffix -- this only need be approximate */
270 strcpy (plugname, finddata.name);
271 c = strrchr(plugname, '.');
272 if (c != NULL) *c = '\0';
274 result = _sasl_get_plugin (full_name, verifyfile_cb, &library);
276 if (result != SASL_OK) {
280 for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
281 _sasl_plugin_load(plugname, library, cur_ep->entryname,
283 /* If this fails, it's not the end of the world */
285 } while (_findnext (fhandle, &finddata) == 0);
287 _findclose (fhandle);
289 } while ((c!='=') && (c!=0));
295 _sasl_done_with_plugins(void)
297 lib_list_t *libptr, *libptr_next;
299 for(libptr = lib_list_head; libptr; libptr = libptr_next) {
300 libptr_next = libptr->next;
301 if (libptr->library != NULL) {
302 FreeLibrary(libptr->library);
307 lib_list_head = NULL;