347 lines
10 KiB
C
347 lines
10 KiB
C
/***********************************************************************
|
|
*
|
|
* 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 <jluciani@novell.com>
|
|
*
|
|
***********************************************************************/
|
|
|
|
//===[ 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;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|