static long krb5int_get_plugin_filenames (const char * const *filebases, char ***filenames) { long err = 0; static const char *const fileexts[] = FILEEXTS; char **tempnames = NULL; size_t bases_count = 0; size_t exts_count = 0; size_t i; if (!filebases) { err = EINVAL; } if (!filenames) { err = EINVAL; } if (!err) { for (i = 0; filebases[i]; i++) { bases_count++; } for (i = 0; fileexts[i]; i++) { exts_count++; } tempnames = calloc ((bases_count * exts_count)+1, sizeof (char *)); if (!tempnames) { err = ENOMEM; } } if (!err) { size_t j; for (i = 0; !err && filebases[i]; i++) { for (j = 0; !err && fileexts[j]; j++) { if (asprintf(&tempnames[(i*exts_count)+j], "%s%s", filebases[i], fileexts[j]) < 0) { tempnames[(i*exts_count)+j] = NULL; err = ENOMEM; } } } tempnames[bases_count * exts_count] = NULL; /* NUL-terminate */ } if (!err) { *filenames = tempnames; tempnames = NULL; } krb5int_free_plugin_filenames(tempnames); return err; }
static long krb5int_get_plugin_filenames (const char * const *filebases, char ***filenames) { long err = 0; static const char *const fileexts[] = FILEEXTS; char **tempnames = NULL; int i; if (!err) { size_t count = 0; for (i = 0; filebases[i] != NULL; i++, count++); for (i = 0; fileexts[i] != NULL; i++, count++); tempnames = calloc (count, sizeof (char *)); if (tempnames == NULL) { err = errno; } } if (!err) { int j; for (i = 0; !err && (filebases[i] != NULL); i++) { size_t baselen = strlen (filebases[i]); for (j = 0; !err && (fileexts[j] != NULL); j++) { size_t len = baselen + strlen (fileexts[j]) + 2; /* '.' + NULL */ tempnames[i+j] = malloc (len * sizeof (char)); if (tempnames[i+j] == NULL) { err = errno; } else { /*LINTED*/ sprintf (tempnames[i+j], "%s%s", filebases[i], fileexts[j]); } } } } if (!err) { *filenames = tempnames; tempnames = NULL; } if (tempnames != NULL) { krb5int_free_plugin_filenames (tempnames); } return err; }
long KRB5_CALLCONV krb5int_open_plugin_dirs (const char * const *dirnames, const char * const *filebases, struct plugin_dir_handle *dirhandle, struct errinfo *ep) { long err = 0; struct plugin_file_handle **h = NULL; int count = 0; char **filenames = NULL; int i; if (!err) { err = krb5int_plugin_file_handle_array_init (&h); } if (!err && (filebases != NULL)) { err = krb5int_get_plugin_filenames (filebases, &filenames); } for (i = 0; !err && dirnames[i] != NULL; i++) { size_t dirnamelen = strlen (dirnames[i]) + 1; /* '/' */ if (filenames != NULL) { /* load plugins with names from filenames from each directory */ int j; for (j = 0; !err && filenames[j] != NULL; j++) { struct plugin_file_handle *handle = NULL; char *filepath = NULL; if (!err) { filepath = malloc (dirnamelen + strlen (filenames[j]) + 1); /* NULL */ if (filepath == NULL) { err = errno; } else { /*LINTED*/ sprintf (filepath, "%s/%s", dirnames[i], filenames[j]); } } if (krb5int_open_plugin (filepath, &handle, ep) == 0) { err = krb5int_plugin_file_handle_array_add (&h, &count, handle); if (!err) { handle = NULL; } /* h takes ownership */ } if (filepath != NULL) { free (filepath); } if (handle != NULL) { krb5int_close_plugin (handle); } } } else { /* load all plugins in each directory */ #ifndef _WIN32 DIR *dir = opendir (dirnames[i]); while (dir != NULL && !err) { struct dirent *d = NULL; char *filepath = NULL; struct plugin_file_handle *handle = NULL; int len; d = readdir (dir); if (d == NULL) { break; } if ((strcmp (d->d_name, ".") == 0) || (strcmp (d->d_name, "..") == 0)) { continue; } /* Solaris Kerberos: Only open files with a .so extension */ len = NAMELEN (d); if (len < 3 || strcmp(".so", d->d_name + len - 3 ) != 0) continue; if (!err) { filepath = malloc (dirnamelen + len + 1); /* NULL */ if (filepath == NULL) { err = errno; } else { /*LINTED*/ sprintf (filepath, "%s/%*s", dirnames[i], len, d->d_name); } } if (!err) { if (krb5int_open_plugin (filepath, &handle, ep) == 0) { err = krb5int_plugin_file_handle_array_add (&h, &count, handle); if (!err) { handle = NULL; } /* h takes ownership */ } } if (filepath != NULL) { free (filepath); } if (handle != NULL) { krb5int_close_plugin (handle); } } if (dir != NULL) { closedir (dir); } #else /* Until a Windows implementation of this code is implemented */ err = ENOENT; #endif /* _WIN32 */ } } if (err == ENOENT) { err = 0; /* ran out of plugins -- do nothing */ } if (!err) { dirhandle->files = h; h = NULL; /* dirhandle->files takes ownership */ } if (filenames != NULL) { krb5int_free_plugin_filenames (filenames); } if (h != NULL) { krb5int_plugin_file_handle_array_free (h); } return err; }
long KRB5_CALLCONV krb5int_open_plugin_dirs (const char * const *dirnames, const char * const *filebases, struct plugin_dir_handle *dirhandle, struct errinfo *ep) { long err = 0; struct plugin_file_handle **h = NULL; size_t count = 0; char **filenames = NULL; int i; if (!err) { err = krb5int_plugin_file_handle_array_init (&h); } if (!err && (filebases != NULL)) { err = krb5int_get_plugin_filenames (filebases, &filenames); } for (i = 0; !err && dirnames[i] != NULL; i++) { if (filenames != NULL) { /* load plugins with names from filenames from each directory */ int j; for (j = 0; !err && filenames[j] != NULL; j++) { struct plugin_file_handle *handle = NULL; char *filepath = NULL; if (!err) { if (asprintf(&filepath, "%s/%s", dirnames[i], filenames[j]) < 0) { filepath = NULL; err = ENOMEM; } } if (krb5int_open_plugin (filepath, &handle, ep) == 0) { err = krb5int_plugin_file_handle_array_add (&h, &count, handle); if (!err) { handle = NULL; } /* h takes ownership */ } free(filepath); if (handle != NULL) { krb5int_close_plugin (handle); } } } else { /* load all plugins in each directory */ DIR *dir = opendir (dirnames[i]); while (dir != NULL && !err) { struct dirent *d = NULL; char *filepath = NULL; struct plugin_file_handle *handle = NULL; d = readdir (dir); if (d == NULL) { break; } if ((strcmp (d->d_name, ".") == 0) || (strcmp (d->d_name, "..") == 0)) { continue; } if (!err) { int len = NAMELEN (d); if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) { filepath = NULL; err = ENOMEM; } } if (!err) { if (krb5int_open_plugin (filepath, &handle, ep) == 0) { err = krb5int_plugin_file_handle_array_add (&h, &count, handle); if (!err) { handle = NULL; } /* h takes ownership */ } } free(filepath); if (handle != NULL) { krb5int_close_plugin (handle); } } if (dir != NULL) { closedir (dir); } } } if (err == ENOENT) { err = 0; /* ran out of plugins -- do nothing */ } if (!err) { dirhandle->files = h; h = NULL; /* dirhandle->files takes ownership */ } if (filenames != NULL) { krb5int_free_plugin_filenames (filenames); } if (h != NULL) { krb5int_plugin_file_handle_array_free (h); } return err; }