1*269e59f9SJan Pechanec /* 2*269e59f9SJan Pechanec * CDDL HEADER START 3*269e59f9SJan Pechanec * 4*269e59f9SJan Pechanec * The contents of this file are subject to the terms of the 5*269e59f9SJan Pechanec * Common Development and Distribution License (the "License"). 6*269e59f9SJan Pechanec * You may not use this file except in compliance with the License. 7*269e59f9SJan Pechanec * 8*269e59f9SJan Pechanec * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*269e59f9SJan Pechanec * or http://www.opensolaris.org/os/licensing. 10*269e59f9SJan Pechanec * See the License for the specific language governing permissions 11*269e59f9SJan Pechanec * and limitations under the License. 12*269e59f9SJan Pechanec * 13*269e59f9SJan Pechanec * When distributing Covered Code, include this CDDL HEADER in each 14*269e59f9SJan Pechanec * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*269e59f9SJan Pechanec * If applicable, add the following below this CDDL HEADER, with the 16*269e59f9SJan Pechanec * fields enclosed by brackets "[]" replaced with your own identifying 17*269e59f9SJan Pechanec * information: Portions Copyright [yyyy] [name of copyright owner] 18*269e59f9SJan Pechanec * 19*269e59f9SJan Pechanec * CDDL HEADER END 20*269e59f9SJan Pechanec * 21*269e59f9SJan Pechanec * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 22*269e59f9SJan Pechanec * 23*269e59f9SJan Pechanec * This file implements the KMF certificate to name mapping framework. 24*269e59f9SJan Pechanec */ 25*269e59f9SJan Pechanec #include <stdlib.h> 26*269e59f9SJan Pechanec #include <string.h> 27*269e59f9SJan Pechanec #include <dlfcn.h> 28*269e59f9SJan Pechanec #include <libgen.h> 29*269e59f9SJan Pechanec #include <kmftypes.h> 30*269e59f9SJan Pechanec #include <kmfapiP.h> 31*269e59f9SJan Pechanec 32*269e59f9SJan Pechanec /* Mappers go in the same dir as plugins. */ 33*269e59f9SJan Pechanec #define DEFAULT_MAPPER_DIR KMF_PLUGIN_PATH 34*269e59f9SJan Pechanec 35*269e59f9SJan Pechanec static void 36*269e59f9SJan Pechanec cleanup_mapper(KMF_HANDLE_T handle) 37*269e59f9SJan Pechanec { 38*269e59f9SJan Pechanec KMF_MAPPER_RECORD *mapper = &handle->policy->mapper; 39*269e59f9SJan Pechanec void (*finalize)(KMF_HANDLE_T); 40*269e59f9SJan Pechanec 41*269e59f9SJan Pechanec if (mapper->curpathname != NULL) { 42*269e59f9SJan Pechanec free(mapper->curpathname); 43*269e59f9SJan Pechanec mapper->curpathname = NULL; 44*269e59f9SJan Pechanec } 45*269e59f9SJan Pechanec if (mapper->curoptions != NULL) { 46*269e59f9SJan Pechanec free(mapper->curoptions); 47*269e59f9SJan Pechanec mapper->curoptions = NULL; 48*269e59f9SJan Pechanec } 49*269e59f9SJan Pechanec if (mapper->dldesc != NULL) { 50*269e59f9SJan Pechanec finalize = (void(*)())dlsym(mapper->dldesc, 51*269e59f9SJan Pechanec MAPPER_FINISH_FUNCTION); 52*269e59f9SJan Pechanec /* Optional, not an error if it does not exist. */ 53*269e59f9SJan Pechanec if (finalize != NULL) 54*269e59f9SJan Pechanec finalize(handle); 55*269e59f9SJan Pechanec 56*269e59f9SJan Pechanec (void) dlclose(mapper->dldesc); 57*269e59f9SJan Pechanec mapper->dldesc = NULL; 58*269e59f9SJan Pechanec } 59*269e59f9SJan Pechanec } 60*269e59f9SJan Pechanec 61*269e59f9SJan Pechanec /* The caller is expected to free the returned string. */ 62*269e59f9SJan Pechanec char * 63*269e59f9SJan Pechanec get_mapper_pathname(char *name, char *dir) 64*269e59f9SJan Pechanec { 65*269e59f9SJan Pechanec char *pathname = NULL; 66*269e59f9SJan Pechanec int len; 67*269e59f9SJan Pechanec 68*269e59f9SJan Pechanec if (name == NULL) 69*269e59f9SJan Pechanec return (NULL); 70*269e59f9SJan Pechanec 71*269e59f9SJan Pechanec if (dir == NULL) 72*269e59f9SJan Pechanec dir = DEFAULT_MAPPER_DIR; 73*269e59f9SJan Pechanec 74*269e59f9SJan Pechanec /* 75*269e59f9SJan Pechanec * MAPPER_NAME_TEMPLATE has 2 extra characters (%s) which make up for 76*269e59f9SJan Pechanec * the "/" and the terminating NULL when computing the total length. 77*269e59f9SJan Pechanec */ 78*269e59f9SJan Pechanec len = strlen(name) + strlen(MAPPER_NAME_TEMPLATE) + strlen(dir); 79*269e59f9SJan Pechanec 80*269e59f9SJan Pechanec pathname = malloc(len); 81*269e59f9SJan Pechanec if (pathname == NULL) 82*269e59f9SJan Pechanec return (NULL); 83*269e59f9SJan Pechanec (void) memset(pathname, 0, len); 84*269e59f9SJan Pechanec /* Avoid double forward slash if the dir's last character is "/". */ 85*269e59f9SJan Pechanec (void) snprintf(pathname, len, "%s%s" MAPPER_NAME_TEMPLATE, 86*269e59f9SJan Pechanec dir, dir[strlen(dir) - 1] == '/' ? "" : "/", name); 87*269e59f9SJan Pechanec 88*269e59f9SJan Pechanec return (pathname); 89*269e59f9SJan Pechanec } 90*269e59f9SJan Pechanec 91*269e59f9SJan Pechanec static KMF_RETURN 92*269e59f9SJan Pechanec open_mapper_library(KMF_MAPPER_RECORD *map) 93*269e59f9SJan Pechanec { 94*269e59f9SJan Pechanec KMF_RETURN ret = KMF_OK; 95*269e59f9SJan Pechanec 96*269e59f9SJan Pechanec map->dldesc = dlopen(map->curpathname, RTLD_LAZY | RTLD_PARENT); 97*269e59f9SJan Pechanec if (map->dldesc == NULL) 98*269e59f9SJan Pechanec return (KMF_ERR_MAPPER_OPEN); 99*269e59f9SJan Pechanec 100*269e59f9SJan Pechanec return (ret); 101*269e59f9SJan Pechanec } 102*269e59f9SJan Pechanec 103*269e59f9SJan Pechanec /* 104*269e59f9SJan Pechanec * The mapping framework uses either attributes or the policy file. Those two 105*269e59f9SJan Pechanec * sources are never mixed. We always need a mapper name or a mapper pathname 106*269e59f9SJan Pechanec * but these two are mutually exclusive. Directory can be set only if name is 107*269e59f9SJan Pechanec * set. 108*269e59f9SJan Pechanec */ 109*269e59f9SJan Pechanec KMF_RETURN 110*269e59f9SJan Pechanec kmf_cert_to_name_mapping_initialize(KMF_HANDLE_T handle, int numattr, 111*269e59f9SJan Pechanec KMF_ATTRIBUTE *attrlist) 112*269e59f9SJan Pechanec { 113*269e59f9SJan Pechanec KMF_RETURN ret = KMF_OK; 114*269e59f9SJan Pechanec KMF_RETURN (*initialize)(KMF_HANDLE_T, char *); 115*269e59f9SJan Pechanec KMF_MAPPER_RECORD *map = NULL; 116*269e59f9SJan Pechanec char *dir = NULL; 117*269e59f9SJan Pechanec char *name = NULL; 118*269e59f9SJan Pechanec char *opts = NULL; 119*269e59f9SJan Pechanec char *path = NULL; 120*269e59f9SJan Pechanec char *tmppath = NULL; 121*269e59f9SJan Pechanec char *old_curpathname = NULL; 122*269e59f9SJan Pechanec char *old_curoptions = NULL; 123*269e59f9SJan Pechanec 124*269e59f9SJan Pechanec if (handle == NULL) 125*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 126*269e59f9SJan Pechanec 127*269e59f9SJan Pechanec map = &handle->policy->mapper; 128*269e59f9SJan Pechanec old_curpathname = map->curpathname; 129*269e59f9SJan Pechanec old_curoptions = map->curoptions; 130*269e59f9SJan Pechanec 131*269e59f9SJan Pechanec name = kmf_get_attr_ptr(KMF_MAPPER_NAME_ATTR, attrlist, numattr); 132*269e59f9SJan Pechanec dir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 133*269e59f9SJan Pechanec path = kmf_get_attr_ptr(KMF_MAPPER_PATH_ATTR, attrlist, numattr); 134*269e59f9SJan Pechanec opts = kmf_get_attr_ptr(KMF_MAPPER_OPTIONS_ATTR, attrlist, numattr); 135*269e59f9SJan Pechanec 136*269e59f9SJan Pechanec if (path != NULL) { 137*269e59f9SJan Pechanec /* Mutually exclusive. */ 138*269e59f9SJan Pechanec if (name != NULL || dir != NULL) 139*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 140*269e59f9SJan Pechanec tmppath = strdup(path); 141*269e59f9SJan Pechanec if (tmppath == NULL) 142*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 143*269e59f9SJan Pechanec /* If we only have a name and possibly a dir, we can find the path. */ 144*269e59f9SJan Pechanec } else if (name != NULL) { 145*269e59f9SJan Pechanec tmppath = get_mapper_pathname(name, dir); 146*269e59f9SJan Pechanec /* 147*269e59f9SJan Pechanec * If we were given name but the returned path is still NULL, 148*269e59f9SJan Pechanec * return an error. 149*269e59f9SJan Pechanec */ 150*269e59f9SJan Pechanec if (tmppath == NULL) 151*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 152*269e59f9SJan Pechanec /* Can not exist standalone. */ 153*269e59f9SJan Pechanec } else if (dir != NULL || opts != NULL) { 154*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 155*269e59f9SJan Pechanec /* No attributes define the mapper so let's use the policy database. */ 156*269e59f9SJan Pechanec } else if (map->pathname != NULL) { 157*269e59f9SJan Pechanec tmppath = strdup(map->pathname); 158*269e59f9SJan Pechanec if (tmppath == NULL) 159*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 160*269e59f9SJan Pechanec opts = map->options; 161*269e59f9SJan Pechanec } else if (map->mapname != NULL) { 162*269e59f9SJan Pechanec tmppath = get_mapper_pathname(map->mapname, map->dir); 163*269e59f9SJan Pechanec /* 164*269e59f9SJan Pechanec * If we were given name but the returned path is still NULL, 165*269e59f9SJan Pechanec * return an error. 166*269e59f9SJan Pechanec */ 167*269e59f9SJan Pechanec if (tmppath == NULL) 168*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 169*269e59f9SJan Pechanec opts = map->options; 170*269e59f9SJan Pechanec } else { 171*269e59f9SJan Pechanec /* 172*269e59f9SJan Pechanec * Either a name or a full pathname must be provided whether 173*269e59f9SJan Pechanec * from attributes or the policy database. 174*269e59f9SJan Pechanec */ 175*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 176*269e59f9SJan Pechanec } 177*269e59f9SJan Pechanec 178*269e59f9SJan Pechanec /* 179*269e59f9SJan Pechanec * Dlopen the mapper specified by the policy. If anything goes wrong 180*269e59f9SJan Pechanec * just return an error. We do not have to worry about resetting 181*269e59f9SJan Pechanec * curpathname and curoptions to the previous values since there was no 182*269e59f9SJan Pechanec * mapper initialized beforehand. 183*269e59f9SJan Pechanec * 184*269e59f9SJan Pechanec * No mapper was open so stored curoptions and curpathname are 185*269e59f9SJan Pechanec * already NULL and need not to be freed. 186*269e59f9SJan Pechanec */ 187*269e59f9SJan Pechanec if (map->dldesc == NULL) { 188*269e59f9SJan Pechanec map->curpathname = tmppath; 189*269e59f9SJan Pechanec if (opts != NULL) { 190*269e59f9SJan Pechanec map->curoptions = strdup(opts); 191*269e59f9SJan Pechanec if (map->curoptions == NULL) { 192*269e59f9SJan Pechanec free(map->curpathname); 193*269e59f9SJan Pechanec map->curpathname = NULL; 194*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 195*269e59f9SJan Pechanec } 196*269e59f9SJan Pechanec } else 197*269e59f9SJan Pechanec map->curoptions = NULL; 198*269e59f9SJan Pechanec 199*269e59f9SJan Pechanec if ((ret = open_mapper_library(map)) != KMF_OK) { 200*269e59f9SJan Pechanec free(map->curpathname); 201*269e59f9SJan Pechanec map->curpathname = NULL; 202*269e59f9SJan Pechanec if (map->curoptions != NULL) { 203*269e59f9SJan Pechanec free(map->curoptions); 204*269e59f9SJan Pechanec map->curoptions = NULL; 205*269e59f9SJan Pechanec } 206*269e59f9SJan Pechanec return (ret); 207*269e59f9SJan Pechanec } 208*269e59f9SJan Pechanec 209*269e59f9SJan Pechanec goto end; 210*269e59f9SJan Pechanec } 211*269e59f9SJan Pechanec 212*269e59f9SJan Pechanec /* 213*269e59f9SJan Pechanec * We already have an open mapper, let's see if this is a new mapper 214*269e59f9SJan Pechanec * library. 215*269e59f9SJan Pechanec */ 216*269e59f9SJan Pechanec if (map->curpathname != NULL && 217*269e59f9SJan Pechanec /* No change in mapper pathname. */ 218*269e59f9SJan Pechanec strcmp(map->curpathname, tmppath) == 0) { 219*269e59f9SJan Pechanec /* New options are empty while we had some before. */ 220*269e59f9SJan Pechanec if (map->curoptions != NULL && opts == NULL) { 221*269e59f9SJan Pechanec map->curoptions = NULL; 222*269e59f9SJan Pechanec /* We have some options now while we had none before. */ 223*269e59f9SJan Pechanec } else if (map->curoptions == NULL && opts != NULL) { 224*269e59f9SJan Pechanec if ((map->curoptions = strdup(opts)) == NULL) 225*269e59f9SJan Pechanec goto err_mem; 226*269e59f9SJan Pechanec /* We got different options. */ 227*269e59f9SJan Pechanec } else if (strcmp(map->curoptions, opts) != 0) { 228*269e59f9SJan Pechanec if ((map->curoptions = strdup(opts)) == NULL) 229*269e59f9SJan Pechanec goto err_mem; 230*269e59f9SJan Pechanec } else { 231*269e59f9SJan Pechanec /* 232*269e59f9SJan Pechanec * Same options, no free() of current options is 233*269e59f9SJan Pechanec * required. 234*269e59f9SJan Pechanec */ 235*269e59f9SJan Pechanec old_curoptions = NULL; 236*269e59f9SJan Pechanec } 237*269e59f9SJan Pechanec 238*269e59f9SJan Pechanec /* Free old options if applicable. */ 239*269e59f9SJan Pechanec if (old_curoptions != NULL) 240*269e59f9SJan Pechanec free(old_curoptions); 241*269e59f9SJan Pechanec } else { 242*269e59f9SJan Pechanec /* 243*269e59f9SJan Pechanec * This is a new mapper path, clean up the old data and open the 244*269e59f9SJan Pechanec * new mapper. 245*269e59f9SJan Pechanec */ 246*269e59f9SJan Pechanec cleanup_mapper(handle); 247*269e59f9SJan Pechanec /* These two are no longer valid. */ 248*269e59f9SJan Pechanec old_curoptions = NULL; 249*269e59f9SJan Pechanec old_curpathname = NULL; 250*269e59f9SJan Pechanec map->curpathname = tmppath; 251*269e59f9SJan Pechanec if (opts != NULL) { 252*269e59f9SJan Pechanec map->curoptions = strdup(opts); 253*269e59f9SJan Pechanec if (map->curoptions == NULL) 254*269e59f9SJan Pechanec goto err_mem; 255*269e59f9SJan Pechanec } 256*269e59f9SJan Pechanec if ((ret = open_mapper_library(map)) != KMF_OK) { 257*269e59f9SJan Pechanec /* 258*269e59f9SJan Pechanec * This will cleanup curoptions and curpathname, and 259*269e59f9SJan Pechanec * ignores the dldesc since it is NULL. Do not free 260*269e59f9SJan Pechanec * tmppath, it will be freed through map->curpathname. 261*269e59f9SJan Pechanec */ 262*269e59f9SJan Pechanec cleanup_mapper(handle); 263*269e59f9SJan Pechanec return (ret); 264*269e59f9SJan Pechanec } 265*269e59f9SJan Pechanec } 266*269e59f9SJan Pechanec 267*269e59f9SJan Pechanec end: 268*269e59f9SJan Pechanec initialize = (KMF_RETURN(*)())dlsym(map->dldesc, 269*269e59f9SJan Pechanec MAPPER_INIT_FUNCTION); 270*269e59f9SJan Pechanec /* Optional, not an error if it does not exist. */ 271*269e59f9SJan Pechanec ret = KMF_OK; 272*269e59f9SJan Pechanec if (initialize != NULL) 273*269e59f9SJan Pechanec ret = initialize(handle, map->curoptions); 274*269e59f9SJan Pechanec 275*269e59f9SJan Pechanec if (ret != KMF_OK) 276*269e59f9SJan Pechanec cleanup_mapper(handle); 277*269e59f9SJan Pechanec 278*269e59f9SJan Pechanec return (ret); 279*269e59f9SJan Pechanec 280*269e59f9SJan Pechanec err_mem: 281*269e59f9SJan Pechanec /* 282*269e59f9SJan Pechanec * Try to put the old curpathname and curoptions back there. In theory, 283*269e59f9SJan Pechanec * the application might be able to continue to use the old mapping 284*269e59f9SJan Pechanec * unless we already called cleanup_mapper(). However, it's neither 285*269e59f9SJan Pechanec * recommended nor officially supported. The app should initialize the 286*269e59f9SJan Pechanec * old mapping again. 287*269e59f9SJan Pechanec */ 288*269e59f9SJan Pechanec if (tmppath != NULL) 289*269e59f9SJan Pechanec free(tmppath); 290*269e59f9SJan Pechanec map->curoptions = old_curoptions; 291*269e59f9SJan Pechanec map->curpathname = old_curpathname; 292*269e59f9SJan Pechanec return (KMF_ERR_MEMORY); 293*269e59f9SJan Pechanec } 294*269e59f9SJan Pechanec 295*269e59f9SJan Pechanec KMF_RETURN 296*269e59f9SJan Pechanec kmf_cert_to_name_mapping_finalize(KMF_HANDLE_T handle) 297*269e59f9SJan Pechanec { 298*269e59f9SJan Pechanec if (handle == NULL) 299*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 300*269e59f9SJan Pechanec 301*269e59f9SJan Pechanec cleanup_mapper(handle); 302*269e59f9SJan Pechanec 303*269e59f9SJan Pechanec return (KMF_OK); 304*269e59f9SJan Pechanec } 305*269e59f9SJan Pechanec 306*269e59f9SJan Pechanec KMF_RETURN 307*269e59f9SJan Pechanec kmf_map_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, KMF_DATA *name) 308*269e59f9SJan Pechanec { 309*269e59f9SJan Pechanec KMF_MAPPER_RECORD *map = NULL; 310*269e59f9SJan Pechanec KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *); 311*269e59f9SJan Pechanec 312*269e59f9SJan Pechanec if (handle == NULL) 313*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 314*269e59f9SJan Pechanec 315*269e59f9SJan Pechanec map = &handle->policy->mapper; 316*269e59f9SJan Pechanec if (map->dldesc == NULL) 317*269e59f9SJan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND); 318*269e59f9SJan Pechanec 319*269e59f9SJan Pechanec cert2name = (KMF_RETURN(*)())dlsym(map->dldesc, 320*269e59f9SJan Pechanec MAP_CERT_TO_NAME_FUNCTION); 321*269e59f9SJan Pechanec if (cert2name == NULL) 322*269e59f9SJan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND); 323*269e59f9SJan Pechanec 324*269e59f9SJan Pechanec return (cert2name(handle, cert, name)); 325*269e59f9SJan Pechanec } 326*269e59f9SJan Pechanec 327*269e59f9SJan Pechanec /* 328*269e59f9SJan Pechanec * If mapped_name is non-NULL the caller is later expected to free its Data 329*269e59f9SJan Pechanec * after use. 330*269e59f9SJan Pechanec */ 331*269e59f9SJan Pechanec KMF_RETURN 332*269e59f9SJan Pechanec kmf_match_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, 333*269e59f9SJan Pechanec KMF_DATA *name_to_match, KMF_DATA *mapped_name) 334*269e59f9SJan Pechanec { 335*269e59f9SJan Pechanec KMF_MAPPER_RECORD *map = NULL; 336*269e59f9SJan Pechanec KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *, 337*269e59f9SJan Pechanec KMF_DATA *); 338*269e59f9SJan Pechanec 339*269e59f9SJan Pechanec if (handle == NULL) 340*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 341*269e59f9SJan Pechanec 342*269e59f9SJan Pechanec map = &handle->policy->mapper; 343*269e59f9SJan Pechanec 344*269e59f9SJan Pechanec if (map->curpathname == NULL || map->dldesc == NULL) 345*269e59f9SJan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND); 346*269e59f9SJan Pechanec 347*269e59f9SJan Pechanec cert2name = (KMF_RETURN(*)())dlsym(map->dldesc, 348*269e59f9SJan Pechanec MATCH_CERT_TO_NAME_FUNCTION); 349*269e59f9SJan Pechanec if (cert2name == NULL) 350*269e59f9SJan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND); 351*269e59f9SJan Pechanec 352*269e59f9SJan Pechanec return (cert2name(handle, cert, name_to_match, mapped_name)); 353*269e59f9SJan Pechanec } 354*269e59f9SJan Pechanec 355*269e59f9SJan Pechanec /* 356*269e59f9SJan Pechanec * The caller is responsible for freeing the error string (ie., *errstr) when 357*269e59f9SJan Pechanec * done with it. 358*269e59f9SJan Pechanec */ 359*269e59f9SJan Pechanec KMF_RETURN 360*269e59f9SJan Pechanec kmf_get_mapper_error_str(KMF_HANDLE_T handle, char **errstr) 361*269e59f9SJan Pechanec { 362*269e59f9SJan Pechanec KMF_HANDLE *h = NULL; 363*269e59f9SJan Pechanec KMF_MAPPER_RECORD *map = NULL; 364*269e59f9SJan Pechanec KMF_RETURN (*err2string)(KMF_HANDLE *, char **); 365*269e59f9SJan Pechanec 366*269e59f9SJan Pechanec if (handle == NULL || errstr == NULL) 367*269e59f9SJan Pechanec return (KMF_ERR_BAD_PARAMETER); 368*269e59f9SJan Pechanec 369*269e59f9SJan Pechanec h = (KMF_HANDLE *)handle; 370*269e59f9SJan Pechanec map = &(h->policy->mapper); 371*269e59f9SJan Pechanec 372*269e59f9SJan Pechanec if (map->curpathname == NULL || map->dldesc == NULL) 373*269e59f9SJan Pechanec return (KMF_ERR_MAPPER_NOT_FOUND); 374*269e59f9SJan Pechanec 375*269e59f9SJan Pechanec err2string = (KMF_RETURN(*)())dlsym(map->dldesc, 376*269e59f9SJan Pechanec MAPPER_ERROR_STRING_FUNCTION); 377*269e59f9SJan Pechanec if (err2string == NULL) 378*269e59f9SJan Pechanec return (KMF_ERR_FUNCTION_NOT_FOUND); 379*269e59f9SJan Pechanec 380*269e59f9SJan Pechanec return (err2string(h, errstr)); 381*269e59f9SJan Pechanec } 382*269e59f9SJan Pechanec 383*269e59f9SJan Pechanec void 384*269e59f9SJan Pechanec kmf_set_mapper_lasterror(KMF_HANDLE_T handle, uint32_t err) 385*269e59f9SJan Pechanec { 386*269e59f9SJan Pechanec handle->mapstate->lastmappererr = err; 387*269e59f9SJan Pechanec } 388*269e59f9SJan Pechanec 389*269e59f9SJan Pechanec uint32_t 390*269e59f9SJan Pechanec kmf_get_mapper_lasterror(KMF_HANDLE_T handle) 391*269e59f9SJan Pechanec { 392*269e59f9SJan Pechanec return (handle->mapstate->lastmappererr); 393*269e59f9SJan Pechanec } 394*269e59f9SJan Pechanec 395*269e59f9SJan Pechanec void 396*269e59f9SJan Pechanec kmf_set_mapper_options(KMF_HANDLE_T handle, void *opts) 397*269e59f9SJan Pechanec { 398*269e59f9SJan Pechanec handle->mapstate->options = opts; 399*269e59f9SJan Pechanec } 400*269e59f9SJan Pechanec 401*269e59f9SJan Pechanec void * 402*269e59f9SJan Pechanec kmf_get_mapper_options(KMF_HANDLE_T handle) 403*269e59f9SJan Pechanec { 404*269e59f9SJan Pechanec return (handle->mapstate->options); 405*269e59f9SJan Pechanec } 406