Beispiel #1
0
/* If map is for a dynamic module which hasn't been loaded yet, attempt to load
 * it.  Only try to load a module once. */
static void
load_if_needed(krb5_context context, struct plugin_mapping *map,
               const char *iname)
{
    char *symname = NULL;
    struct plugin_file_handle *handle = NULL;
    void (*initvt_fn)();

    if (map->module != NULL || map->dyn_path == NULL)
        return;
    if (asprintf(&symname, "%s_%s_initvt", iname, map->modname) < 0)
        return;
    if (krb5int_open_plugin(map->dyn_path, &handle, &context->err))
        goto err;
    if (krb5int_get_plugin_func(handle, symname, &initvt_fn, &context->err))
        goto err;
    free(symname);
    map->dyn_handle = handle;
    map->module = (krb5_plugin_initvt_fn)initvt_fn;
    return;

err:
    /* Clean up, and also null out map->dyn_path so we don't try again. */
    if (handle != NULL)
        krb5int_close_plugin(handle);
    free(symname);
    free(map->dyn_path);
    map->dyn_path = NULL;
}
Beispiel #2
0
void KRB5_CALLCONV
profile_abandon(profile_t profile)
{
    prf_file_t      p, next;
    errcode_t       err;

    if (!profile || profile->magic != PROF_MAGIC_PROFILE)
        return;

    if (profile->vt) {
        if (profile->vt->cleanup)
            profile->vt->cleanup(profile->cbdata);
        if (profile->lib_handle) {
            /* Decrement the refcount on the handle and maybe free it. */
            err = k5_mutex_lock(&profile->lib_handle->lock);
            if (!err && --profile->lib_handle->refcount == 0) {
                krb5int_close_plugin(profile->lib_handle->plugin_handle);
                k5_mutex_unlock(&profile->lib_handle->lock);
                k5_mutex_destroy(&profile->lib_handle->lock);
                free(profile->lib_handle);
            } else if (!err)
                k5_mutex_unlock(&profile->lib_handle->lock);
        }
        free(profile->vt);
    } else {
        for (p = profile->first_file; p; p = next) {
            next = p->next;
            profile_free_file(p);
        }
    }
    profile->magic = 0;
    free(profile);
}
Beispiel #3
0
static void
krb5int_plugin_file_handle_array_free (struct plugin_file_handle **harray)
{
    if (harray != NULL) {
        int i;
        for (i = 0; harray[i] != NULL; i++) {
            krb5int_close_plugin (harray[i]);
        }
        free (harray);
    }
}
Beispiel #4
0
/* Release the memory associated with the mapping list entry map. */
static void
free_plugin_mapping(struct plugin_mapping *map)
{
    if (map == NULL)
        return;
    free(map->modname);
    free(map->dyn_path);
    if (map->dyn_handle != NULL)
        krb5int_close_plugin(map->dyn_handle);
    free(map);
}
Beispiel #5
0
void KRB5_CALLCONV
krb5int_close_plugin_dirs (struct plugin_dir_handle *dirhandle)
{
    if (dirhandle->files != NULL) {
        int i;
        for (i = 0; dirhandle->files[i] != NULL; i++) {
            krb5int_close_plugin (dirhandle->files[i]);
        }
        free (dirhandle->files);
        dirhandle->files = NULL;
    }
}
Beispiel #6
0
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;
}
Beispiel #7
0
/* Load a dynamic profile module as specified by modspec and create a vtable
 * profile for it in *ret_profile. */
static errcode_t
init_load_module(const char *modspec, profile_t *ret_profile)
{
    char *modpath = NULL, *residual = NULL;
    struct errinfo einfo = { 0 };
    prf_lib_handle_t lib_handle = NULL;
    struct plugin_file_handle *plhandle = NULL;
    void *cbdata = NULL, (*fptr)();
    int have_lock = 0, have_cbdata = 0;
    struct profile_vtable vtable = { 1 };  /* Set minor_ver to 1, rest null. */
    errcode_t err;
    profile_module_init_fn initfn;

    err = parse_modspec(modspec, &modpath, &residual);
    if (err)
        goto cleanup;

    /* Allocate a reference-counted library handle container. */
    lib_handle = malloc(sizeof(*lib_handle));
    if (lib_handle == NULL)
        goto cleanup;
    err = k5_mutex_init(&lib_handle->lock);
    if (err)
        goto cleanup;
    have_lock = 1;

    /* Open the module and get its initializer. */
    err = krb5int_open_plugin(modpath, &plhandle, &einfo);
    if (err)
        goto cleanup;
    err = krb5int_get_plugin_func(plhandle, "profile_module_init", &fptr,
                                  &einfo);
    if (err == ENOENT)
        err = PROF_MODULE_INVALID;
    if (err)
        goto cleanup;

    /* Get the profile vtable and callback data pointer. */
    initfn = (profile_module_init_fn)fptr;
    err = (*initfn)(residual, &vtable, &cbdata);
    if (err)
        goto cleanup;
    have_cbdata = 1;

    /* Create a vtable profile with the information obtained. */
    lib_handle->plugin_handle = plhandle;
    lib_handle->refcount = 1;
    err = init_module(&vtable, cbdata, lib_handle, ret_profile);

cleanup:
    free(modpath);
    free(residual);
    k5_clear_error(&einfo);
    if (err) {
        if (have_cbdata && vtable.cleanup)
            vtable.cleanup(cbdata);
        if (have_lock)
            k5_mutex_destroy(&lib_handle->lock);
        free(lib_handle);
        if (plhandle)
            krb5int_close_plugin(plhandle);
    }
    return err;
}
Beispiel #8
0
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;
}