/* gets the list of mechanisms */ int _sasl_load_plugins(const add_plugin_list_t *entrypoints, const sasl_callback_t *getpath_cb, const sasl_callback_t *verifyfile_cb) { int result; char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2]; /* 1 for '\\' 1 for trailing '\0' */ char * pattern; char c; int pos; const char *path=NULL; int position; const add_plugin_list_t *cur_ep; struct stat statbuf; /* filesystem entry information */ intptr_t fhandle; /* file handle for _findnext function */ struct _finddata_t finddata; /* data returned by _findnext() */ size_t prefix_len; if (! entrypoints || ! getpath_cb || getpath_cb->id != SASL_CB_GETPATH || ! getpath_cb->proc || ! verifyfile_cb || verifyfile_cb->id != SASL_CB_VERIFYFILE || ! verifyfile_cb->proc) return SASL_BADPARAM; /* get the path to the plugins */ result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, &path); if (result != SASL_OK) return result; if (! path) return SASL_FAIL; if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */ return SASL_FAIL; } position=0; do { pos=0; do { c=path[position]; position++; cur_dir[pos]=c; pos++; } while ((c!=PATHS_DELIMITER) && (c!=0)); cur_dir[pos-1]='\0'; /* : check to make sure that a valid directory name was passed in */ if (stat (cur_dir, &statbuf) < 0) { continue; } if ((statbuf.st_mode & S_IFDIR) == 0) { continue; } strcpy (prefix, cur_dir); prefix_len = strlen (prefix); /* : Don't append trailing \ unless required */ if (prefix[prefix_len-1] != '\\') { strcat (prefix,"\\"); prefix_len++; } pattern = prefix; /* : Check that we have enough space for "*.dll" */ if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) { _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big"); continue; } strcat (prefix + prefix_len, "*" DLL_SUFFIX); fhandle = _findfirst (pattern, &finddata); if (fhandle == -1) { /* no matching files */ continue; } /* : Truncate "*.dll" */ prefix[prefix_len] = '\0'; do { size_t length; void *library; char *c; char plugname[PATH_MAX]; int entries; length = strlen(finddata.name); if (length < 5) { /* At least <Ch>.dll */ continue; /* can not possibly be what we're looking for */ } /* : Check for overflow */ if (length + prefix_len >= PATH_MAX) continue; /* too big */ if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) { continue; } /* : Check that it is not a directory */ if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) { continue; } /* : Construct full name from prefix and name */ strcpy (full_name, prefix); strcat (full_name, finddata.name); /* cut off .dll suffix -- this only need be approximate */ strcpy (plugname, finddata.name); c = strrchr(plugname, '.'); if (c != NULL) *c = '\0'; result = _sasl_get_plugin (full_name, verifyfile_cb, &library); if (result != SASL_OK) { continue; } entries = 0; for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { result = _sasl_plugin_load(plugname, library, cur_ep->entryname, cur_ep->add_plugin); if (result == SASL_OK) { ++entries; } /* If this fails, it's not the end of the world */ } if (entries == 0) { _sasl_remove_last_plugin(); } } while (_findnext (fhandle, &finddata) == 0); _findclose (fhandle); } while ((c!='=') && (c!=0)); return SASL_OK; }
/* gets the list of mechanisms */ int _sasl_load_plugins(const add_plugin_list_t *entrypoints, const sasl_callback_t *getpath_cb, const sasl_callback_t *verifyfile_cb) { int result; const add_plugin_list_t *cur_ep; #ifdef DO_DLOPEN char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2]; /* 1 for '/' 1 for trailing '\0' */ char c; int pos; const char *path=NULL; int position; DIR *dp; struct dirent *dir; #endif #ifndef PIC add_plugin_t *add_plugin; _sasl_plug_type type; _sasl_plug_rec *p; #endif if (! entrypoints || ! getpath_cb || getpath_cb->id != SASL_CB_GETPATH || ! getpath_cb->proc || ! verifyfile_cb || verifyfile_cb->id != SASL_CB_VERIFYFILE || ! verifyfile_cb->proc) return SASL_BADPARAM; #ifndef PIC /* do all the static plugins first */ for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { /* What type of plugin are we looking for? */ if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) { type = SERVER; add_plugin = (add_plugin_t *)sasl_server_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) { type = CLIENT; add_plugin = (add_plugin_t *)sasl_client_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) { type = AUXPROP; add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) { type = CANONUSER; add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin; } else { /* What are we looking for then? */ return SASL_FAIL; } for (p=_sasl_static_plugins; p->type; p++) { if(type == p->type) result = add_plugin(p->name, p->plug); } } #endif /* !PIC */ /* only do the following if: * * we support dlopen() * AND we are not staticly compiled * OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined */ #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) /* get the path to the plugins */ result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, &path); if (result != SASL_OK) return result; if (! path) return SASL_FAIL; if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */ return SASL_FAIL; } position=0; do { pos=0; do { c=path[position]; position++; str[pos]=c; pos++; } while ((c!=':') && (c!='=') && (c!=0)); str[pos-1]='\0'; strcpy(prefix,str); strcat(prefix,"/"); if ((dp=opendir(str)) !=NULL) /* ignore errors */ { while ((dir=readdir(dp)) != NULL) { size_t length; void *library; char *c; char plugname[PATH_MAX]; char name[PATH_MAX]; length = NAMLEN(dir); if (length < 4) continue; /* can not possibly be what we're looking for */ if (length + pos>=PATH_MAX) continue; /* too big */ if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)), SO_SUFFIX) && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) continue; memcpy(name,dir->d_name,length); name[length]='\0'; result = _parse_la(prefix, name, tmp); if(result != SASL_OK) continue; /* skip "lib" and cut off suffix -- this only need be approximate */ strcpy(plugname, name + 3); c = strchr(plugname, (int)'.'); if(c) *c = '\0'; result = _sasl_get_plugin(tmp, verifyfile_cb, &library); if(result != SASL_OK) continue; for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { _sasl_plugin_load(plugname, library, cur_ep->entryname, cur_ep->add_plugin); /* If this fails, it's not the end of the world */ } } closedir(dp); } else { _sasl_log(NULL, SASL_LOG_DEBUG, "looking for plugins in '%s', failed to open directory, error: %s", str, strerror(errno)); } } while ((c!='=') && (c!=0)); #endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */ return SASL_OK; }
/* gets the list of mechanisms */ int _sasl_load_plugins(const add_plugin_list_t *entrypoints, const sasl_callback_t *getpath_cb, const sasl_callback_t *verifyfile_cb) { int result; TCHAR cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2]; /* 1 for '\\' 1 for trailing '\0' */ TCHAR * pattern; TCHAR c; int pos; int retCode = SASL_OK; char *utf8path = NULL; TCHAR *path=NULL; int position; const add_plugin_list_t *cur_ep; struct _stat statbuf; /* filesystem entry information */ intptr_t fhandle; /* file handle for _findnext function */ struct _tfinddata_t finddata; /* data returned by _findnext() */ size_t prefix_len; /* for static plugins */ add_plugin_t *add_plugin; _sasl_plug_type type; _sasl_plug_rec *p; if (! entrypoints || ! getpath_cb || getpath_cb->id != SASL_CB_GETPATH || ! getpath_cb->proc || ! verifyfile_cb || verifyfile_cb->id != SASL_CB_VERIFYFILE || ! verifyfile_cb->proc) return SASL_BADPARAM; /* do all the static plugins first */ for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { /* What type of plugin are we looking for? */ if (!strcmp(cur_ep->entryname, "sasl_server_plug_init")) { type = SERVER; add_plugin = (add_plugin_t *)sasl_server_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) { type = CLIENT; add_plugin = (add_plugin_t *)sasl_client_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) { type = AUXPROP; add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin; } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) { type = CANONUSER; add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin; } else { /* What are we looking for then? */ return SASL_FAIL; } for (p = _sasl_static_plugins; p->type; p++) { if (type == p->type) result = add_plugin(p->name, p->plug); } } /* get the path to the plugins */ result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, &utf8path); if (result != SASL_OK) return result; if (!utf8path) return SASL_FAIL; if (sizeof(TCHAR) == sizeof(char)) { path = (TCHAR*)utf8path; } else { path = _sasl_utf8_to_wchar(utf8path); if (!path) return SASL_FAIL; } if (_tcslen(path) >= PATH_MAX) { /* no you can't buffer overrun */ retCode = SASL_FAIL; goto cleanup; } position=0; do { pos=0; do { c=path[position]; position++; cur_dir[pos]=c; pos++; } while ((c!=PATHS_DELIMITER) && (c!=0)); cur_dir[pos-1]='\0'; /* : check to make sure that a valid directory name was passed in */ if (_tstat (cur_dir, &statbuf) < 0) { continue; } if ((statbuf.st_mode & S_IFDIR) == 0) { continue; } _tcscpy(prefix, cur_dir); prefix_len = _tcslen (prefix); /* : Don't append trailing \ unless required */ if (prefix[prefix_len-1] != '\\') { _tcscat(prefix,_T("\\")); prefix_len++; } pattern = prefix; /* : Check that we have enough space for "*.dll" */ if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) / sizeof(TCHAR) - 1)) { _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big"); continue; } _tcscat (prefix + prefix_len, _T("*") DLL_SUFFIX); fhandle = _tfindfirst (pattern, &finddata); if (fhandle == -1) { /* no matching files */ continue; } /* : Truncate "*.dll" */ prefix[prefix_len] = '\0'; do { size_t length; void *library; char *c; char plugname[PATH_MAX]; int entries; length = _tcslen(finddata.name); if (length < 5) { /* At least <Ch>.dll */ continue; /* can not possibly be what we're looking for */ } /* : Check for overflow */ if (length + prefix_len >= PATH_MAX) continue; /* too big */ if (_tcscmp(finddata.name + (length - _tcslen(DLL_SUFFIX)), DLL_SUFFIX) != 0) { continue; } /* : Check that it is not a directory */ if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) { continue; } /* : Construct full name from prefix and name */ _tcscpy (full_name, prefix); _tcscat (full_name, finddata.name); /* cut off .dll suffix -- this only need be approximate */ if (sizeof(TCHAR) != sizeof(char)) { if (WideCharToMultiByte(CP_UTF8, 0, finddata.name, -1, plugname, sizeof(plugname), NULL, NULL) == 0) { // in case of unicode use utf8 continue; } } else { _tcscpy((TCHAR*)plugname, finddata.name); // w/o unicode local enconding is fine } c = strchr(plugname, '.'); if (c != NULL) *c = '\0'; result = _tsasl_get_plugin (full_name, verifyfile_cb, &library); if (result != SASL_OK) { continue; } entries = 0; for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { result = _sasl_plugin_load(plugname, library, cur_ep->entryname, cur_ep->add_plugin); if (result == SASL_OK) { ++entries; } /* If this fails, it's not the end of the world */ } if (entries == 0) { _sasl_remove_last_plugin(); } } while (_tfindnext (fhandle, &finddata) == 0); _findclose (fhandle); } while ((c!='=') && (c!=0)); cleanup: if (sizeof(TCHAR) != sizeof(char)) { sasl_FREE(path); /* It's always allocated in coversion to wchar */ } return retCode; }