54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/*
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * util/support/plugins.c
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * Copyright 2006 by the Massachusetts Institute of Technology.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * All Rights Reserved.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * Export of this software from the United States of America may
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * require a specific license from the United States Government.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * It is the responsibility of any person or organization contemplating
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * export to obtain such a license before exporting.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * distribute this software and its documentation for any purpose and
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * without fee is hereby granted, provided that the above copyright
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * notice appear in all copies and that both that copyright notice and
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * this permission notice appear in supporting documentation, and that
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * the name of M.I.T. not be used in advertising or publicity pertaining
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * to distribution of the software without specific, written prior
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * permission. Furthermore if you modify this software you must label
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * your software as modified software and not distribute it in such a
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * fashion that it might be confused with the original M.I.T. software.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * M.I.T. makes no representations about the suitability of
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * this software for any purpose. It is provided "as is" without express
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * or implied warranty.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * Plugin module support, and shims around dlopen/whatever.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Use is subject to license terms.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include "k5-plugin.h"
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_DLOPEN
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <dlfcn.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_CFBUNDLE
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <CoreFoundation/CoreFoundation.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <stdio.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <sys/types.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef HAVE_SYS_STAT_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <sys/stat.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef HAVE_SYS_PARAM_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <sys/param.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <errno.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <stdlib.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <string.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef HAVE_UNISTD_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <unistd.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <stdarg.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/*ARGSUSED*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic void Tprintf (const char *fmt, ...)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef DEBUG
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf va_list va;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf va_start (va, fmt);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf vfprintf (stderr, fmt, va);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf va_end (va);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstruct plugin_file_handle {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_DLOPEN
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void *dlhandle;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_CFBUNDLE
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf CFBundleRef bundle;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if !defined (USE_DLOPEN) && !defined (USE_CFBUNDLE)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf char dummy;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf};
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/*ARGSUSED2*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct stat statbuf;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle *htmp = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int got_plugin = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (stat (filepath, &statbuf) < 0) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf Tprintf ("stat(%s): %s\n", filepath, strerror (errno));
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (htmp == NULL) { err = errno; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_DLOPEN
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void *handle = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef RTLD_GROUP
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#else
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (handle == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char *e = dlerror();
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf Tprintf ("dlopen(%s): %s\n", filepath, e);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = ENOENT; /* XXX */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf krb5int_set_error (ep, err, "%s", e);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf got_plugin = 1;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf htmp->dlhandle = handle;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf handle = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (handle != NULL) { dlclose (handle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_CFBUNDLE
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf CFStringRef pluginPath = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf CFURLRef pluginURL = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf CFBundleRef pluginBundle = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf pluginPath = CFStringCreateWithCString (kCFAllocatorDefault, filepath,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf kCFStringEncodingASCII);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginPath == NULL) { err = ENOMEM; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pluginPath,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf kCFURLPOSIXPathStyle, true);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginURL == NULL) { err = ENOMEM; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!CFBundleIsExecutableLoaded (pluginBundle)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int loaded = CFBundleLoadExecutable (pluginBundle);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!loaded) { err = ENOENT; } /* XXX need better error */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf got_plugin = 1;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf htmp->bundle = pluginBundle;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf pluginBundle = NULL; /* htmp->bundle takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginBundle != NULL) { CFRelease (pluginBundle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginURL != NULL) { CFRelease (pluginURL); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (pluginPath != NULL) { CFRelease (pluginPath); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && !got_plugin) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = ENOENT; /* no plugin or no way to load plugins */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *h = htmp;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf htmp = NULL; /* h takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (htmp != NULL) { free (htmp); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/*ARGSUSED*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic long
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_sym (struct plugin_file_handle *h,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char *csymname, int isfunc, void **ptr,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void *sym = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_DLOPEN
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && !sym && (h->dlhandle != NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* XXX Do we need to add a leading "_" to the symbol name on any
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf modern platforms? */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sym = dlsym (h->dlhandle, csymname);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (sym == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char *e = dlerror (); /* XXX copy and save away */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf Tprintf ("dlsym(%s): %s\n", csymname, e);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = ENOENT; /* XXX */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf krb5int_set_error(ep, err, "%s", e);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_CFBUNDLE
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && !sym && (h->bundle != NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf CFStringRef cfsymname = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf cfsymname = CFStringCreateWithCString (kCFAllocatorDefault, csymname,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf kCFStringEncodingASCII);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (cfsymname == NULL) { err = ENOMEM; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (isfunc) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sym = CFBundleGetFunctionPointerForName (h->bundle, cfsymname);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sym = CFBundleGetDataPointerForName (h->bundle, cfsymname);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (sym == NULL) { err = ENOENT; } /* XXX */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (cfsymname != NULL) { CFRelease (cfsymname); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (sym == NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = ENOENT; /* unimplemented */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *ptr = sym;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_data (struct plugin_file_handle *h, const char *csymname,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void **ptr, struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return krb5int_get_plugin_sym (h, csymname, 0, ptr, ep);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_func (struct plugin_file_handle *h, const char *csymname,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void (**ptr)(), struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void *dptr = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = krb5int_get_plugin_sym (h, csymname, 1, &dptr, ep);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* Cast function pointers to avoid code duplication */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *ptr = (void (*)()) dptr;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfvoid KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_close_plugin (struct plugin_file_handle *h)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_DLOPEN
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (h->dlhandle != NULL) { dlclose(h->dlhandle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if USE_CFBUNDLE
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* Do not call CFBundleUnloadExecutable because it's not ref counted.
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * CFRelease will unload the bundle if the internal refcount goes to zero. */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (h->bundle != NULL) { CFRelease (h->bundle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free (h);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/* autoconf docs suggest using this preference order */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if HAVE_DIRENT_H || USE_DIRENT_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#include <dirent.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define NAMELEN(D) strlen((D)->d_name)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#else
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define dirent direct
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define NAMELEN(D) ((D)->d->namlen)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if HAVE_SYS_NDIR_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf# include <sys/ndir.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#elif HAVE_SYS_DIR_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf# include <sys/dir.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#elif HAVE_NDIR_H
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf# include <ndir.h>
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifdef HAVE_STRERROR_R
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define ERRSTR(ERR, BUF) \
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf (strerror_r (ERR, BUF, sizeof(BUF)) == 0 ? BUF : strerror (ERR))
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#else
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define ERRSTR(ERR, BUF) \
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf (strerror (ERR))
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic long
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_plugin_file_handle_array_init (struct plugin_file_handle ***harray)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *harray = calloc (1, sizeof (**harray)); /* calloc initializes to NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (*harray == NULL) { err = errno; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic long
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_plugin_file_handle_array_add (struct plugin_file_handle ***harray, int *count,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle *p)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle **newharray = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int newcount = *count + 1;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf newharray = realloc (*harray, ((newcount + 1) * sizeof (**harray))); /* +1 for NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (newharray == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf newharray[newcount - 1] = p;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf newharray[newcount] = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *count = newcount;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *harray = newharray;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic void
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_plugin_file_handle_array_free (struct plugin_file_handle **harray)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (harray != NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; harray[i] != NULL; i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf krb5int_close_plugin (harray[i]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free (harray);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#if TARGET_OS_MAC
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define FILEEXTS { "", ".bundle", ".so", NULL }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#elif defined(_WIN32)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define FILEEXTS { "", ".dll", NULL }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#else
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#define FILEEXTS { "", ".so", NULL }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic void
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_free_plugin_filenames (char **filenames)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filenames != NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; filenames[i] != NULL; i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free (filenames[i]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free (filenames);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfstatic long
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_filenames (const char * const *filebases, char ***filenames)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf static const char *const fileexts[] = FILEEXTS;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf char **tempnames = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf size_t count = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; filebases[i] != NULL; i++, count++);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; fileexts[i] != NULL; i++, count++);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf tempnames = calloc (count, sizeof (char *));
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (tempnames == NULL) { err = errno; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int j;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; !err && (filebases[i] != NULL); i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf size_t baselen = strlen (filebases[i]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (j = 0; !err && (fileexts[j] != NULL); j++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf size_t len = baselen + strlen (fileexts[j]) + 2; /* '.' + NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf tempnames[i+j] = malloc (len * sizeof (char));
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (tempnames[i+j] == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /*LINTED*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sprintf (tempnames[i+j], "%s%s", filebases[i], fileexts[j]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *filenames = tempnames;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf tempnames = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (tempnames != NULL) { krb5int_free_plugin_filenames (tempnames); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf/* Takes a NULL-terminated list of directories. If filebases is NULL, filebases is ignored
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * all plugins in the directories are loaded. If filebases is a NULL-terminated array of names,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf * only plugins in the directories with those name (plus any platform extension) are loaded. */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_open_plugin_dirs (const char * const *dirnames,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char * const *filebases,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_dir_handle *dirhandle,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle **h = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int count = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf char **filenames = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = krb5int_plugin_file_handle_array_init (&h);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (filebases != NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = krb5int_get_plugin_filenames (filebases, &filenames);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; !err && dirnames[i] != NULL; i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf size_t dirnamelen = strlen (dirnames[i]) + 1; /* '/' */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filenames != NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* load plugins with names from filenames from each directory */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int j;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (j = 0; !err && filenames[j] != NULL; j++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle *handle = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf char *filepath = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf filepath = malloc (dirnamelen + strlen (filenames[j]) + 1); /* NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filepath == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /*LINTED*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sprintf (filepath, "%s/%s", dirnames[i], filenames[j]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (krb5int_open_plugin (filepath, &handle, ep) == 0) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = krb5int_plugin_file_handle_array_add (&h, &count, handle);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) { handle = NULL; } /* h takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filepath != NULL) { free (filepath); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (handle != NULL) { krb5int_close_plugin (handle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* load all plugins in each directory */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#ifndef _WIN32
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DIR *dir = opendir (dirnames[i]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while (dir != NULL && !err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct dirent *d = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf char *filepath = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct plugin_file_handle *handle = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int len;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf d = readdir (dir);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (d == NULL) { break; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if ((strcmp (d->d_name, ".") == 0) ||
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf (strcmp (d->d_name, "..") == 0)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf continue;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Only open files with a .so extension */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = NAMELEN (d);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (len < 3 || strcmp(".so", d->d_name + len - 3 ) != 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf filepath = malloc (dirnamelen + len + 1); /* NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filepath == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /*LINTED*/
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf sprintf (filepath, "%s/%*s", dirnames[i], len, d->d_name);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (krb5int_open_plugin (filepath, &handle, ep) == 0) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = krb5int_plugin_file_handle_array_add (&h, &count, handle);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) { handle = NULL; } /* h takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filepath != NULL) { free (filepath); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (handle != NULL) { krb5int_close_plugin (handle); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (dir != NULL) { closedir (dir); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#else
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* Until a Windows implementation of this code is implemented */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = ENOENT;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf#endif /* _WIN32 */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (err == ENOENT) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = 0; /* ran out of plugins -- do nothing */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf dirhandle->files = h;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf h = NULL; /* dirhandle->files takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (filenames != NULL) { krb5int_free_plugin_filenames (filenames); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (h != NULL) { krb5int_plugin_file_handle_array_free (h); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfvoid KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_close_plugin_dirs (struct plugin_dir_handle *dirhandle)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (dirhandle->files != NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; dirhandle->files[i] != NULL; i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf krb5int_close_plugin (dirhandle->files[i]);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free (dirhandle->files);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf dirhandle->files = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfvoid KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_free_plugin_dir_data (void **ptrs)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* Nothing special to be done per pointer. */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free(ptrs);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_dir_data (struct plugin_dir_handle *dirhandle,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char *symname,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void ***ptrs,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void **p = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int count = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* XXX Do we need to add a leading "_" to the symbol name on any
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf modern platforms? */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf Tprintf("get_plugin_data_sym(%s)\n", symname);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = calloc (1, sizeof (*p)); /* calloc initializes to NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (p == NULL) { err = errno; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (dirhandle != NULL) && (dirhandle->files != NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; !err && (dirhandle->files[i] != NULL); i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void *sym = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (krb5int_get_plugin_data (dirhandle->files[i], symname, &sym, ep) == 0) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void **newp = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf count++;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf newp = realloc (p, ((count + 1) * sizeof (*p))); /* +1 for NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (newp == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = newp;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p[count - 1] = sym;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p[count] = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *ptrs = p;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = NULL; /* ptrs takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (p != NULL) { free (p); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfvoid KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_free_plugin_dir_func (void (**ptrs)(void))
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* Nothing special to be done per pointer. */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf free(ptrs);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillflong KRB5_CALLCONV
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillfkrb5int_get_plugin_dir_func (struct plugin_dir_handle *dirhandle,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf const char *symname,
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void (***ptrs)(void),
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf struct errinfo *ep)
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf{
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf long err = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void (**p)() = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int count = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf /* XXX Do we need to add a leading "_" to the symbol name on any
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf modern platforms? */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf Tprintf("get_plugin_data_sym(%s)\n", symname);
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = calloc (1, sizeof (*p)); /* calloc initializes to NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (p == NULL) { err = errno; }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err && (dirhandle != NULL) && (dirhandle->files != NULL)) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf int i = 0;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf for (i = 0; !err && (dirhandle->files[i] != NULL); i++) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void (*sym)() = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (krb5int_get_plugin_func (dirhandle->files[i], symname, &sym, ep) == 0) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf void (**newp)() = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf count++;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf newp = realloc (p, ((count + 1) * sizeof (*p))); /* +1 for NULL */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (newp == NULL) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf err = errno;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf } else {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = newp;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p[count - 1] = sym;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p[count] = NULL;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (!err) {
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf *ptrs = p;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf p = NULL; /* ptrs takes ownership */
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf if (p != NULL) { free (p); }
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf return err;
54925bf60766fbb4f1f2d7c843721406a7b7a3fbwillf}