g_initialize.c revision 2
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * This file contains functions to initialize the gssapi library and 2N/A * load mechanism libraries. 2N/A * It also contain functions requiring direct access to the mechanism's 2N/A * list (gss_inidicate_mechs and gss_release_oid) as well as support 2N/A * functions which translate the mechanism strings to oids and vise versa. 2N/A * The mechanism libraries are loaded on demand. This is triggered 2N/A * through the get_mechanism function call. 2N/A * Updates to the mechList are performed with the following restrictions: 2N/A * - once a library is loaded, none of the fields are updated 2N/A * - existing entiries for non-loaded mechs, will have the 2N/A * library and kernel module names updated only 2N/A * (i.e. the mech oid and mech name will not be updated) 2N/A * This #ifdef mess figures out if we are to be compiled into 2N/A * a sparcv9/lp64 binary for the purposes of figuring the absolute location 2N/A * of gss-api mechanism modules. 2N/A/* Local functions */ 2N/A * list of mechanism libraries and their entry points. 2N/A * the list also maintains state of the mech libraries (loaded or not). 2N/A * function used to reclaim the memory used by a gss_OID structure. 2N/A * This routine requires direct access to the mechList. 2N/A * look through the loaded mechanism libraries for 2N/A * gss_internal_release_oid until one returns success. 2N/A * gss_internal_release_oid will only return success when 2N/A * the OID was recognized as an internal mechanism OID. if no 2N/A * mechanisms recognize the OID, then call the generic version. 2N/A * we can walk the mechanism list without a mutex, because we 2N/A * are only looking at fields which once read will never change. 2N/A * Mechanism entries are always added to the end, and as 2N/A}
/* gss_release_oid */ 2N/A * this function will return an oid set indicating available mechanisms. 2N/A * The set returned is based on configuration file entries and 2N/A * NOT on the loaded mechanisms. This function does not check if any 2N/A * of these can actually be loaded. 2N/A * This routine needs direct access to the mechanism list. 2N/A * To avoid reading the configuration file each call, we will save a 2N/A * a mech oid set, and only update it once the file has changed. 2N/A /* Initialize outputs. */ 2N/A /* Validate arguments. */ 2N/A * If we have already computed the mechanisms supported and if it 2N/A * is still valid; make a copy and return to caller, 2N/A * otherwise build it first. 2N/A * lock the mutex since we will be updating 2N/A * the mechList structure 2N/A * we need to keep the lock while we build the mechanism list 2N/A * since we are accessing parts of the mechList which could be 2N/A * this checks for the case when we need to re-construct the 2N/A * g_mechSet structure, but the mechanism list is upto date 2N/A * (because it has been read by someone calling 2N/A * __gss_get_mechanism) 2N/A * we need to lock the mech set so that no one else will 2N/A * try to read it as we are re-creating it 2N/A /* if the oid list already exists we must free it first */ 2N/A /* determine how many elements to have in the list */ 2N/A /* this should always be true, but.... */ 2N/A /* now copy each oid element */ 2N/A * this is nasty - we must delete the 2N/A * part of the array already copied 2N/A }
/* if g_mechSet is out of date or not initialized */ 2N/A * the mech set is created and it is up to date 2N/A * so just copy it to caller 2N/A * need to lock the g_mechSet in case someone tries to update it while 2N/A /* allocate space for the oid structures */ 2N/A /* now copy the oid structures */ 2N/A /* still need to copy each of the oid elements arrays */ 2N/A * must still free the allocated elements for 2N/A * each allocated gss_OID_desc 2N/A for (j = 0; j < i; j++) {
2N/A}
/* gss_indicate_mechs */ 2N/A * this function has been added for use by modules that need to 2N/A * know what (if any) optional parameters are supplied in the 2N/A * config file (MECH_CONF). 2N/A * It will return the option string for a specified mechanism. 2N/A * caller is responsible for freeing the memory 2N/A /* make sure we have fresh data */ 2N/A /* searching the list does not require a lock */ 2N/A * need to obtain a lock on this structure in case someone else 2N/A * will try to update it during the copy 2N/A}
/* __gss_get_modOptions */ 2N/A * this function has been added for use by gssd. 2N/A * It will return the kernel module name for a specified mechanism. 2N/A * caller is responsible for freeing the memory 2N/A /* make sure we have fresh data */ 2N/A /* searching the list does not require a lock */ 2N/A * need to obtain a lock on this structure in case someone else 2N/A * will try to update it during the copy 2N/A}
/* __gss_get_kmodName */ 2N/A * given a mechanism string return the mechanism oid 2N/A /* ensure we have fresh data */ 2N/A /* no lock required - only looking at fields that are not updated */ 2N/A}
/* __gss_mech_to_oid */ 2N/A * Given the mechanism oid, return the readable mechanism name 2N/A * associated with that oid from the mech config file 2N/A /* ensure we have fresh data */ 2N/A}
/* __gss_oid_to_mech */ 2N/A * return a list of mechanism strings supported 2N/A * upon return the array is terminated with a NULL entry 2N/A /* ensure we have fresh data */ 2N/A /* no lock required - only looking at fields that are not updated */ 2N/A}
/* gss_get_mechanisms */ 2N/A * determines if the mechList needs to be updated from file 2N/A * and performs the update. 2N/A * this functions must be called with a lock of g_mechListLock 2N/A /* check if mechList needs updating */ 2N/A}
/* updateMechList */ 2N/A * given the mechanism type, return the mechanism structure 2N/A * containing the mechanism library entry points. 2N/A * will return NULL if mech type is not found 2N/A * This function will also trigger the loading of the mechanism 2N/A * module if it has not been already loaded. 2N/A /* check if the mechanism is already loaded */ 2N/A * might need to re-read the configuration file before loading 2N/A * the mechanism to ensure we have the latest info. 2N/A /* is the mechanism present in the list ? */ 2N/A /* has another thread loaded the mech */ 2N/A /* we found the mechanism, but it is not loaded */ 2N/A /* Call the symbol to get the mechanism table */ 2N/A}
/* __gss_get_mechanism */ 2N/A /* check if the mechanism is already loaded */ 2N/A /* Load the gss_config_ext struct for this mech */ 2N/A * dlsym() the mech's 'method' functions for the extended APIs 2N/A * NOTE: Until the void *context argument is removed from the 2N/A * SPI method functions' signatures it will be necessary to have 2N/A * different function pointer typedefs and function names for 2N/A * the SPI methods than for the API. When this argument is 2N/A * removed it will be possible to rename gss_*_sfct to gss_*_fct 2N/A * and and gssspi_* to gss_*. 2N/A "gssspi_acquire_cred_with_password");
2N/A /* Set aMech->mech_ext */ 2N/A}
/* __gss_get_mechanism_ext */ 2N/A * this routine is used for searching the list of mechanism data. 2N/A * it needs not be mutex protected because we only add new structures 2N/A * from the end and they are fully initialized before being added. 2N/A /* if oid is null -> then get default which is the first in the list */ 2N/A}
/* searchMechList */ 2N/A * loads the configuration file 2N/A * this is called while having a mutex lock on the mechanism list 2N/A * entries for libraries that have been loaded can't be modified 2N/A * mechNameStr and mech_type fields are not updated during updates 2N/A /* ignore lines beginning with # */ 2N/A * find the first white-space character after 2N/A * the mechanism name 2N/A /* Now find the first non-white-space character */ 2N/A * If that's all, then this is a corrupt entry. Skip it. 2N/A /* Find the end of the oid and make sure it is NULL-ended */ 2N/A * check if an entry for this oid already exists 2N/A * if it does, and the library is already loaded then 2N/A * we can't modify it, so skip it 2N/A " [%s] in configuration file",
oid);
2N/A /* Find the start of the shared lib name */ 2N/A * If that's all, then this is a corrupt entry. Skip it. 2N/A * Find the end of the shared lib name and make sure it is 2N/A /* Find the start of the optional kernel module lib name */ 2N/A * If this item starts with a bracket "[", then 2N/A * it is not a kernel module, but is a list of 2N/A * options for the user module to parse later. 2N/A * Find the end of the shared lib name and make sure 2N/A * it is NULL-terminated. 2N/A /* Find the start of the optional module options list */ 2N/A /* move past the opening bracket */ 2N/A /* Find the closing bracket */ 2N/A * are we creating a new mechanism entry or 2N/A * just modifying existing (non loaded) mechanism entry 2N/A * delete any old values and set new 2N/A * mechNameStr and mech_type are not modified 2N/A /* the oid is already set */ 2N/A /* adding a new entry */ 2N/A /* check if any memory allocations failed - bad news */ 2N/A * add the new entry to the end of the list - make sure 2N/A * that only complete entries are added because other 2N/A * threads might currently be searching the list. 2N/A}
/* loadConfigFile */