/*********************************************************************** * * Copyright (C) 2006 Novell, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, Novell, Inc. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * * Author: Juan Carlos Luciani * ***********************************************************************/ //===[ Include files ]===================================================== #include "internal.h" //===[ Type definitions ]================================================== // // Identity Token Module definition // typedef struct _IdenTokenProviderModule { LIST_ENTRY listEntry; char *pTypeName; int typeNameLen; LIB_HANDLE libHandle; IdenTokenProviderIf *pIdenTokenProviderIf; } IdenTokenProviderModule, *PIdenTokenProviderModule; //===[ Function prototypes ]=============================================== //===[ Global variables ]================================================== // // IdenTokenProviderModule list and syncronization mutex // static LIST_ENTRY g_IdenTokenProviderModuleListHead = {&g_IdenTokenProviderModuleListHead, &g_IdenTokenProviderModuleListHead}; static HANDLE g_idenTokenMutex = NULL; //++======================================================================= CasaStatus GetIdenTokenProviderInterface( IN const char *pIdenTokenTypeName, INOUT IdenTokenProviderIf **ppIdenTokenProviderIf) // // Arguments: // // Returns: // // Abstract: // // Notes: // // Environment: // // L2 //=======================================================================-- { CasaStatus retStatus; ConfigIf *pModuleConfigIf; DbgTrace(2, "-GetIdenTokenProviderInterface- Start\n", 0); // Get the configuration for the module retStatus = GetConfigInterface("/etc/opt/novell/CASA/authtoken.d/modules.d", pIdenTokenTypeName, &pModuleConfigIf); if (CASA_SUCCESS(retStatus) && CasaStatusCode(retStatus) != CASA_STATUS_OBJECT_NOT_FOUND) { LIST_ENTRY *pListEntry; IdenTokenProviderModule *pIdenTokenProviderModule = NULL; int32_t idenTokenTypeNameLen = strlen(pIdenTokenTypeName); // Gain exclusive access to our mutex PlatAcquireMutex(g_idenTokenMutex); // Look if we already have the module in our list pListEntry = g_IdenTokenProviderModuleListHead.Flink; while (pListEntry != &g_IdenTokenProviderModuleListHead) { // Get pointer to the current entry pIdenTokenProviderModule = CONTAINING_RECORD(pListEntry, IdenTokenProviderModule, listEntry); // Check if this is the module that we need if (pIdenTokenProviderModule->typeNameLen == idenTokenTypeNameLen && memcmp(pIdenTokenTypeName, pIdenTokenProviderModule->pTypeName, idenTokenTypeNameLen) == 0) { // This is the module that we need, stop looking. break; } else { // This is not the module that we are looking for pIdenTokenProviderModule = NULL; } // Advance to the next entry pListEntry = pListEntry->Flink; } // Proceed based on whether or not a module was found if (pIdenTokenProviderModule) { // Module found in our list, provide the caller with its IdenTokenProviderIf // instance after we have incremented its reference count. pIdenTokenProviderModule->pIdenTokenProviderIf->addReference(pIdenTokenProviderModule->pIdenTokenProviderIf); *ppIdenTokenProviderIf = pIdenTokenProviderModule->pIdenTokenProviderIf; // Success retStatus = CASA_STATUS_SUCCESS; } else { // Needed module not found in our list, create an entry. pIdenTokenProviderModule = malloc(sizeof(*pIdenTokenProviderModule)); if (pIdenTokenProviderModule) { // Allocate buffer to contain the authentication type name within the module entry pIdenTokenProviderModule->pTypeName = malloc(idenTokenTypeNameLen + 1); if (pIdenTokenProviderModule->pTypeName) { char *pLibraryName; // Initialize the library handle field pIdenTokenProviderModule->libHandle = NULL; // Save the auth type name within the entry strcpy(pIdenTokenProviderModule->pTypeName, pIdenTokenTypeName); pIdenTokenProviderModule->typeNameLen = idenTokenTypeNameLen; // Obtain the name of the library that we must load pLibraryName = pModuleConfigIf->getEntryValue(pModuleConfigIf, "LibraryName"); if (pLibraryName) { // Load the library pIdenTokenProviderModule->libHandle = OpenLibrary(pLibraryName); if (pIdenTokenProviderModule->libHandle) { PFN_GetIdenTokenProviderIfRtn pGetIdenTokenProviderIfRtn; // Library has been loaded, now get a pointer to its GetIdenTokenProviderProviderInterface routine pGetIdenTokenProviderIfRtn = (PFN_GetIdenTokenProviderIfRtn) GetFunctionPtr(pIdenTokenProviderModule->libHandle, GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN_SYMBOL); if (pGetIdenTokenProviderIfRtn) { // Now, obtain the modules IdenTokenProviderIf. retStatus = (pGetIdenTokenProviderIfRtn)(pModuleConfigIf, &pIdenTokenProviderModule->pIdenTokenProviderIf); } else { DbgTrace(0, "-GetIdenTokenProviderInterface- GetFunctionPtr error\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_LIBRARY_LOAD_FAILURE); } } else { DbgTrace(0, "-GetIdenTokenProviderInterface- OpenLibrary error\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_LIBRARY_LOAD_FAILURE); } // Free the buffer holding the library name free(pLibraryName); } else { DbgTrace(0, "-GetIdenTokenProviderInterface- Library name not configured\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_CONFIGURATION_ERROR); } // Check if we were successful at obtaining the IdenTokenProviderIf instance for the // module. if (CASA_SUCCESS(retStatus)) { // Insert the entry in the list, provide the caller with its IdenTokenProviderIf // instance after we have incremented its reference count. InsertTailList(&g_IdenTokenProviderModuleListHead, &pIdenTokenProviderModule->listEntry); pIdenTokenProviderModule->pIdenTokenProviderIf->addReference(pIdenTokenProviderModule->pIdenTokenProviderIf); *ppIdenTokenProviderIf = pIdenTokenProviderModule->pIdenTokenProviderIf; } else { // Failed, free resources. free(pIdenTokenProviderModule->pTypeName); if (pIdenTokenProviderModule->libHandle) CloseLibrary(pIdenTokenProviderModule->libHandle); free(pIdenTokenProviderModule); } } else { DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to allocate buffer\n", 0); // Free buffer allocated for entry free(pIdenTokenProviderModule); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } } else { DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to allocate buffer\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } } // Release exclusive access to our mutex PlatReleaseMutex(g_idenTokenMutex); // Release config interface instance pModuleConfigIf->releaseReference(pModuleConfigIf); } else { DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to obtain config interface\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_CONFIGURATION_ERROR); } DbgTrace(2, "-GetIdenTokenProviderInterface- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= CasaStatus IdenTokenInit(void) // // Arguments: // // Returns: // Casa Status // // Description: // Initializes the identity token complex. // // L2 //=======================================================================-- { CasaStatus retStatus; DbgTrace(1, "-IdenTokenInit- Start\n", 0); // Allocate mutex if ((g_idenTokenMutex = PlatAllocMutex()) != NULL) retStatus = CASA_STATUS_SUCCESS; else retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); DbgTrace(1, "-IdenTokenInit- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= void IdenTokenUninit(void) // // Arguments: // // Returns: // Casa Status // // Description: // Uninitializes the indentity token complex. // // L2 //=======================================================================-- { DbgTrace(1, "-IdenTokenUninit- Start\n", 0); // Free mutex if necessary if (g_idenTokenMutex) { PlatDestroyMutex(g_idenTokenMutex); g_idenTokenMutex = NULL; } DbgTrace(1, "-IdenTokenUninit- End\n", 0); } //++======================================================================= //++======================================================================= //++=======================================================================