/*********************************************************************** * * 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 Provider Interface instance data // typedef struct _IdenTokenProviderIfInstance { int refCount; IdenTokenProviderIf idenTokenProviderIf; } IdenTokenProviderIfInstance, *PIdenTokenProviderIfInstance; //===[ Function prototypes ]=============================================== //===[ Global variables ]================================================== // IdenTokenProviderIf variables static int g_numIdenTokenProviderIfObjs = 0; // Debug Level int DebugLevel = 0; // // Initialization variables // static bool g_moduleInitialized = false; // Synchronization mutex static HANDLE g_idenTokenProviderIfMutex = NULL; //++======================================================================= static int SSCS_CALL AddReference( IN const void *pIfInstance) // // Arguments: // pIfInstance - // Pointer to interface object. // // Returns: // Interface reference count. // // Description: // Increases interface reference count. // // L2 //=======================================================================-- { int refCount; IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf); DbgTrace(2, "-AddReference- Start\n", 0); // Increment the reference count on the object PlatAcquireMutex(g_idenTokenProviderIfMutex); pIdenTokenProviderIfInstance->refCount ++; refCount = pIdenTokenProviderIfInstance->refCount; PlatReleaseMutex(g_idenTokenProviderIfMutex); DbgTrace(2, "-AddReference- End, refCount = %0X\n", refCount); return refCount; } //++======================================================================= static void SSCS_CALL ReleaseReference( IN const void *pIfInstance) // // Arguments: // pIfInstance - // Pointer to interface object. // // Returns: // Nothing. // // Description: // Decreases interface reference count. The interface is deallocated if // the reference count becomes zero. // // L2 //=======================================================================-- { bool freeObj = false; IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf); DbgTrace(2, "-ReleaseReference- Start\n", 0); // Decrement the reference count on the object and determine if it needs to // be released. PlatAcquireMutex(g_idenTokenProviderIfMutex); pIdenTokenProviderIfInstance->refCount --; if (pIdenTokenProviderIfInstance->refCount == 0) { // The object needs to be released, forget about it. freeObj = true; g_numIdenTokenProviderIfObjs --; } PlatReleaseMutex(g_idenTokenProviderIfMutex); // Free object if necessary if (freeObj) free(pIdenTokenProviderIfInstance); DbgTrace(2, "-ReleaseReference- End\n", 0); } //++======================================================================= static CasaStatus GetIdentityTokenIf( IN const void *pIfInstance, IN const char *pTokenBuf, IN const int tokenLen, INOUT IdenTokenIf **ppIdenTokenIf) // // Arguments: // pIfInstance - // Pointer to interface object. // // pTokenBuf - // Pointer to null terminated string containing an identity token. // // tokenLen - // Length of the token contained in the token buffer. // // ppIdenTokenIf - // Pointer to variable that will receive pointer to identity // token interface. // // Returns: // Casa Status // // Description: // Get identity token interface instance for the specified token. // // L2 //=======================================================================-- { CasaStatus retStatus; char *pDecodedTokenBuf; int decodedTokenBufLen; DbgTrace(2, "-GetIdentityTokenIf- Start\n", 0); // Validate input parameters if (pIfInstance == NULL || pTokenBuf == NULL || tokenLen == 0 || ppIdenTokenIf == NULL) { DbgTrace(0, "-GetIdentityTokenIf- Invalid input parameter\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INVALID_PARAMETER); goto exit; } // First decode the token string retStatus = DecodeData(pTokenBuf, tokenLen, (void**) &pDecodedTokenBuf, &decodedTokenBufLen); if (CASA_SUCCESS(retStatus)) { // Get the identity token interface retStatus = GetIdenTokenInterface(pDecodedTokenBuf, decodedTokenBufLen, ppIdenTokenIf); // Free the decoded token buffer free(pDecodedTokenBuf); } else { DbgTrace(0, "-GetIdentityTokenIf- Token decode failure\n", 0); } exit: DbgTrace(2, "-GetIdentityTokenIf- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= CasaStatus SSCS_CALL GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN( IN const ConfigIf *pModuleConfigIf, INOUT IdenTokenProviderIf **ppIdenTokenProviderIf) // // Arguments: // pModuleConfigIf - // Pointer to configuration interface instance for the module. // // ppIdenTokenProviderIf - // Pointer to variable that will receive pointer to // IdentityTokenProviderIf instance. // // Returns: // Casa Status // // Description: // Gets identity token provider interface instance. // // L2 //=======================================================================-- { CasaStatus retStatus; IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance; DbgTrace(1, "-GetIdenTokenProviderInterface- Start\n", 0); // Validate input parameters if (pModuleConfigIf == NULL || ppIdenTokenProviderIf == NULL) { DbgTrace(0, "-GetIdenTokenProviderInterface- Invalid input parameter\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_KRB5TOKEN, CASA_STATUS_INVALID_PARAMETER); goto exit; } // Make sure that the module has been initialized if (g_moduleInitialized == false) { // The module has not been initialized, synchronize access thought this section // to avoid having two threads performing initialization. AcquireModuleMutex; // Assume success retStatus = CASA_STATUS_SUCCESS; // Check again in case another thread pre-empted us. if (g_moduleInitialized == false) { // Initialize the IdenTokenIf complex retStatus = IdenTokenIfInit(); if (CASA_SUCCESS(retStatus)) { // Allocate mutex if ((g_idenTokenProviderIfMutex = PlatAllocMutex()) != NULL) { // Success g_moduleInitialized = true; } else { IdenTokenIfUninit(); retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } } } // Stop synchronization ReleaseModuleMutex; // Exit if we failed if (g_moduleInitialized == false) goto exit; } // Allocate space for the interface instance pIdenTokenProviderIfInstance = malloc(sizeof(*pIdenTokenProviderIfInstance)); if (pIdenTokenProviderIfInstance) { // Initialize the interface instance data pIdenTokenProviderIfInstance->refCount = 1; pIdenTokenProviderIfInstance->idenTokenProviderIf.addReference = AddReference; pIdenTokenProviderIfInstance->idenTokenProviderIf.releaseReference = ReleaseReference; pIdenTokenProviderIfInstance->idenTokenProviderIf.getIdentityTokenIf = GetIdentityTokenIf; // Keep track of this object PlatAcquireMutex(g_idenTokenProviderIfMutex); g_numIdenTokenProviderIfObjs ++; PlatReleaseMutex(g_idenTokenProviderIfMutex); // Return the interface to the caller *ppIdenTokenProviderIf = &pIdenTokenProviderIfInstance->idenTokenProviderIf; // Success retStatus = CASA_STATUS_SUCCESS; } else { DbgTrace(0, "-GetIdenTokenProviderInterface- Buffer allocation failure\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_KRB5TOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } exit: DbgTrace(1, "-GetIdenTokenProviderInterface- End, retStatus = %0X\n", retStatus); return retStatus; } //++======================================================================= //++======================================================================= //++=======================================================================