269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * CDDL HEADER START
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * The contents of this file are subject to the terms of the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Common Development and Distribution License (the "License").
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * You may not use this file except in compliance with the License.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * or http://www.opensolaris.org/os/licensing.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * See the License for the specific language governing permissions
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * and limitations under the License.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * When distributing Covered Code, include this CDDL HEADER in each
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If applicable, add the following below this CDDL HEADER, with the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * fields enclosed by brackets "[]" replaced with your own identifying
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * information: Portions Copyright [yyyy] [name of copyright owner]
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * CDDL HEADER END
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * This file implements the KMF certificate to name mapping framework.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <stdlib.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <string.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <dlfcn.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <libgen.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <kmftypes.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <kmfapiP.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/* Mappers go in the same dir as plugins. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#define DEFAULT_MAPPER_DIR KMF_PLUGIN_PATH
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecstatic void
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneccleanup_mapper(KMF_HANDLE_T handle)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_MAPPER_RECORD *mapper = &handle->policy->mapper;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec void (*finalize)(KMF_HANDLE_T);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (mapper->curpathname != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(mapper->curpathname);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapper->curpathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (mapper->curoptions != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(mapper->curoptions);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapper->curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (mapper->dldesc != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec finalize = (void(*)())dlsym(mapper->dldesc,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec MAPPER_FINISH_FUNCTION);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Optional, not an error if it does not exist. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (finalize != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec finalize(handle);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (void) dlclose(mapper->dldesc);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapper->dldesc = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/* The caller is expected to free the returned string. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecchar *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecget_mapper_pathname(char *name, char *dir)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *pathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec int len;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (name == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (NULL);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (dir == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec dir = DEFAULT_MAPPER_DIR;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * MAPPER_NAME_TEMPLATE has 2 extra characters (%s) which make up for
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * the "/" and the terminating NULL when computing the total length.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec len = strlen(name) + strlen(MAPPER_NAME_TEMPLATE) + strlen(dir);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec pathname = malloc(len);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (pathname == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (NULL);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (void) memset(pathname, 0, len);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Avoid double forward slash if the dir's last character is "/". */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (void) snprintf(pathname, len, "%s%s" MAPPER_NAME_TEMPLATE,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec dir, dir[strlen(dir) - 1] == '/' ? "" : "/", name);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (pathname);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecstatic KMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecopen_mapper_library(KMF_MAPPER_RECORD *map)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN ret = KMF_OK;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->dldesc = dlopen(map->curpathname, RTLD_LAZY | RTLD_PARENT);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->dldesc == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MAPPER_OPEN);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (ret);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * The mapping framework uses either attributes or the policy file. Those two
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * sources are never mixed. We always need a mapper name or a mapper pathname
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * but these two are mutually exclusive. Directory can be set only if name is
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * set.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_cert_to_name_mapping_initialize(KMF_HANDLE_T handle, int numattr,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_ATTRIBUTE *attrlist)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN ret = KMF_OK;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN (*initialize)(KMF_HANDLE_T, char *);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_MAPPER_RECORD *map = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *dir = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *name = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *opts = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *path = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *tmppath = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *old_curpathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *old_curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (handle == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map = &handle->policy->mapper;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec old_curpathname = map->curpathname;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec old_curoptions = map->curoptions;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec name = kmf_get_attr_ptr(KMF_MAPPER_NAME_ATTR, attrlist, numattr);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec dir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec path = kmf_get_attr_ptr(KMF_MAPPER_PATH_ATTR, attrlist, numattr);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts = kmf_get_attr_ptr(KMF_MAPPER_OPTIONS_ATTR, attrlist, numattr);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (path != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Mutually exclusive. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (name != NULL || dir != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec tmppath = strdup(path);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (tmppath == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* If we only have a name and possibly a dir, we can find the path. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (name != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec tmppath = get_mapper_pathname(name, dir);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If we were given name but the returned path is still NULL,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * return an error.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (tmppath == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Can not exist standalone. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (dir != NULL || opts != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* No attributes define the mapper so let's use the policy database. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (map->pathname != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec tmppath = strdup(map->pathname);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (tmppath == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts = map->options;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (map->mapname != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec tmppath = get_mapper_pathname(map->mapname, map->dir);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If we were given name but the returned path is still NULL,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * return an error.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (tmppath == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts = map->options;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Either a name or a full pathname must be provided whether
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * from attributes or the policy database.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Dlopen the mapper specified by the policy. If anything goes wrong
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * just return an error. We do not have to worry about resetting
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * curpathname and curoptions to the previous values since there was no
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * mapper initialized beforehand.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * No mapper was open so stored curoptions and curpathname are
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * already NULL and need not to be freed.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->dldesc == NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curpathname = tmppath;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (opts != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = strdup(opts);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curoptions == NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(map->curpathname);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curpathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((ret = open_mapper_library(map)) != KMF_OK) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(map->curpathname);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curpathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curoptions != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(map->curoptions);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (ret);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec goto end;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * We already have an open mapper, let's see if this is a new mapper
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * library.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curpathname != NULL &&
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* No change in mapper pathname. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec strcmp(map->curpathname, tmppath) == 0) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* New options are empty while we had some before. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curoptions != NULL && opts == NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* We have some options now while we had none before. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (map->curoptions == NULL && opts != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((map->curoptions = strdup(opts)) == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec goto err_mem;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* We got different options. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else if (strcmp(map->curoptions, opts) != 0) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((map->curoptions = strdup(opts)) == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec goto err_mem;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Same options, no free() of current options is
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * required.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec old_curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Free old options if applicable. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (old_curoptions != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(old_curoptions);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * This is a new mapper path, clean up the old data and open the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * new mapper.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cleanup_mapper(handle);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* These two are no longer valid. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec old_curoptions = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec old_curpathname = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curpathname = tmppath;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (opts != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = strdup(opts);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curoptions == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec goto err_mem;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((ret = open_mapper_library(map)) != KMF_OK) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * This will cleanup curoptions and curpathname, and
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * ignores the dldesc since it is NULL. Do not free
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * tmppath, it will be freed through map->curpathname.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cleanup_mapper(handle);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (ret);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecend:
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec initialize = (KMF_RETURN(*)())dlsym(map->dldesc,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec MAPPER_INIT_FUNCTION);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Optional, not an error if it does not exist. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec ret = KMF_OK;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (initialize != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec ret = initialize(handle, map->curoptions);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (ret != KMF_OK)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cleanup_mapper(handle);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (ret);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecerr_mem:
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Try to put the old curpathname and curoptions back there. In theory,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * the application might be able to continue to use the old mapping
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * unless we already called cleanup_mapper(). However, it's neither
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * recommended nor officially supported. The app should initialize the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * old mapping again.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (tmppath != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(tmppath);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curoptions = old_curoptions;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map->curpathname = old_curpathname;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_cert_to_name_mapping_finalize(KMF_HANDLE_T handle)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (handle == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cleanup_mapper(handle);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_map_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, KMF_DATA *name)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_MAPPER_RECORD *map = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (handle == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map = &handle->policy->mapper;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->dldesc == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cert2name = (KMF_RETURN(*)())dlsym(map->dldesc,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec MAP_CERT_TO_NAME_FUNCTION);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (cert2name == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (cert2name(handle, cert, name));
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If mapped_name is non-NULL the caller is later expected to free its Data
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * after use.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_match_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_DATA *name_to_match, KMF_DATA *mapped_name)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_MAPPER_RECORD *map = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_DATA *);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (handle == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map = &handle->policy->mapper;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curpathname == NULL || map->dldesc == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cert2name = (KMF_RETURN(*)())dlsym(map->dldesc,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec MATCH_CERT_TO_NAME_FUNCTION);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (cert2name == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (cert2name(handle, cert, name_to_match, mapped_name));
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * The caller is responsible for freeing the error string (ie., *errstr) when
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * done with it.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_get_mapper_error_str(KMF_HANDLE_T handle, char **errstr)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_HANDLE *h = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_MAPPER_RECORD *map = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN (*err2string)(KMF_HANDLE *, char **);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (handle == NULL || errstr == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_BAD_PARAMETER);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec h = (KMF_HANDLE *)handle;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec map = &(h->policy->mapper);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (map->curpathname == NULL || map->dldesc == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec err2string = (KMF_RETURN(*)())dlsym(map->dldesc,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec MAPPER_ERROR_STRING_FUNCTION);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (err2string == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (err2string(h, errstr));
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecvoid
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_set_mapper_lasterror(KMF_HANDLE_T handle, uint32_t err)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec handle->mapstate->lastmappererr = err;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecuint32_t
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_get_mapper_lasterror(KMF_HANDLE_T handle)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (handle->mapstate->lastmappererr);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecvoid
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_set_mapper_options(KMF_HANDLE_T handle, void *opts)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec handle->mapstate->options = opts;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecvoid *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechaneckmf_get_mapper_options(KMF_HANDLE_T handle)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (handle->mapstate->options);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}