diff --git a/auth_token/server/AuthTokenValidate/identoken.c b/auth_token/server/AuthTokenValidate/identoken.c new file mode 100644 index 00000000..25de3cef --- /dev/null +++ b/auth_token/server/AuthTokenValidate/identoken.c @@ -0,0 +1,265 @@ +/*********************************************************************** + * + * 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 ]================================================== + +// +// Module synchronization mutex +// +pthread_mutex_t g_hModuleMutex = PTHREAD_MUTEX_INITIALIZER; + + +// +// IdenTokenProviderModule list and syncronization mutex +// +static +LIST_ENTRY g_IdenTokenProviderModuleListHead = {&g_IdenTokenProviderModuleListHead, &g_IdenTokenProviderModuleListHead}; + +static +pthread_mutex_t g_IdenTokenProviderModuleMutex = PTHREAD_MUTEX_INITIALIZER; + + +//++======================================================================= +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 + pthread_mutex_lock(&g_IdenTokenProviderModuleMutex); + + // 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 + pthread_mutex_unlock(&g_IdenTokenProviderModuleMutex); + + // 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/auth_token/server/AuthTokenValidate/internal.h b/auth_token/server/AuthTokenValidate/internal.h index fb8e4bb8..1d522f0c 100644 --- a/auth_token/server/AuthTokenValidate/internal.h +++ b/auth_token/server/AuthTokenValidate/internal.h @@ -86,7 +86,7 @@ void ConfigIfUninit(void); // -// Functions exported by platform.c +// Functions exported by identoken.c // extern @@ -95,6 +95,10 @@ GetIdenTokenProviderInterface( IN const char *pIdenTokenTypeName, INOUT IdenTokenProviderIf **ppIdenTokenProviderIf); +// +// Functions exported by platform.c +// + extern HANDLE PlatAllocMutex(void); @@ -111,6 +115,22 @@ extern void PlatReleaseMutex(HANDLE hMutex); +extern +LIB_HANDLE +OpenLibrary( + IN char *pFileName); + +extern +void +CloseLibrary( + IN LIB_HANDLE libHandle); + +extern +void* +GetFunctionPtr( + IN LIB_HANDLE libHandle, + IN char *pFunctionName); + // // Functions exported by principal.c //