/*********************************************************************** * * 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 ]================================================== // // AuthMechMod definition // typedef struct _AuthMechMod { LIST_ENTRY listEntry; char *pAuthTypeName; int authTypeNameLen; LIB_HANDLE libHandle; AuthTokenIf *pAuthTokenIf; } AuthMechMod, *PAuthMechMod; //===[ Function prototypes ]=============================================== //===[ Global variables ]================================================== // AuthMechModule List and syncronizing mutex static LIST_ENTRY g_authMechModuleListHead = {&g_authMechModuleListHead, &g_authMechModuleListHead}; //++======================================================================= static CasaStatus GetAuthTokenIf( IN const char *pAuthTypeName, INOUT AuthTokenIf **ppAuthTokenIf) // // Arguments: // // Returns: // // Abstract: // // Notes: // // Environment: // // L2 //=======================================================================-- { CasaStatus retStatus; ConfigIf *pModuleConfigIf; DbgTrace(2, "-GetAuthTokenIf- Start\n", 0); // Get the configuration for the module retStatus = GetConfigInterface(mechConfigFolder, pAuthTypeName, &pModuleConfigIf); if (CASA_SUCCESS(retStatus) && CasaStatusCode(retStatus) != CASA_STATUS_OBJECT_NOT_FOUND) { LIST_ENTRY *pListEntry; AuthMechMod *pAuthMechMod = NULL; int authTypeNameLen = strlen(pAuthTypeName); // Look if we already have the module in our list pListEntry = g_authMechModuleListHead.Flink; while (pListEntry != &g_authMechModuleListHead) { // Get pointer to the current entry pAuthMechMod = CONTAINING_RECORD(pListEntry, AuthMechMod, listEntry); // Check if this is the module that we need if (pAuthMechMod->authTypeNameLen == authTypeNameLen && memcmp(pAuthTypeName, pAuthMechMod->pAuthTypeName, authTypeNameLen) == 0) { // This is the module that we need, stop looking. break; } else { // This is not the module that we are looking for pAuthMechMod = NULL; } // Advance to the next entry pListEntry = pListEntry->Flink; } // Proceed based on whether or not a module was found if (pAuthMechMod) { // Module found in our list, provide the caller with its AuthTokenIf // instance after we have incremented its reference count. pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf); *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf; // Success retStatus = CASA_STATUS_SUCCESS; } else { // Needed module not found in our list, create an entry. pAuthMechMod = (AuthMechMod*) malloc(sizeof(*pAuthMechMod)); if (pAuthMechMod) { // Allocate buffer to contain the authentication type name within the module entry pAuthMechMod->pAuthTypeName = (char*) malloc(authTypeNameLen + 1); if (pAuthMechMod->pAuthTypeName) { char *pLibraryName; // Initialize the library handle field pAuthMechMod->libHandle = NULL; // Save the auth type name within the entry strcpy(pAuthMechMod->pAuthTypeName, pAuthTypeName); pAuthMechMod->authTypeNameLen = authTypeNameLen; // Obtain the name of the library that we must load pLibraryName = pModuleConfigIf->getEntryValue(pModuleConfigIf, "LibraryName"); if (pLibraryName) { // Load the library pAuthMechMod->libHandle = OpenLibrary(pLibraryName); if (pAuthMechMod->libHandle) { PFN_GetAuthTokenIfRtn pGetAuthTokenIfRtn; // Library has been loaded, now get a pointer to its GetAuthTokenInterface routine pGetAuthTokenIfRtn = (PFN_GetAuthTokenIfRtn) GetFunctionPtr(pAuthMechMod->libHandle, GET_AUTH_TOKEN_INTERFACE_RTN_SYMBOL); if (pGetAuthTokenIfRtn) { // Now, obtain the modules AuthTokenIf. retStatus = (pGetAuthTokenIfRtn)(pModuleConfigIf, &pAuthMechMod->pAuthTokenIf); } else { DbgTrace(0, "-GetAuthTokenIf- GetFunctionPtr\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_LIBRARY_LOAD_FAILURE); } } else { DbgTrace(0, "-GetAuthTokenIf- OpenLibrary error\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_UNSUCCESSFUL); } // Free the buffer holding the library name free(pLibraryName); } else { DbgTrace(0, "-GetAuthTokenIf- 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 AuthTokenIf instance for the // module. if (CASA_SUCCESS(retStatus)) { // Insert the entry in the list, provide the caller with its AuthTokenIf // instance after we have incremented its reference count. InsertTailList(&g_authMechModuleListHead, &pAuthMechMod->listEntry); pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf); *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf; } else { // Failed, free resources. free(pAuthMechMod->pAuthTypeName); if (pAuthMechMod->libHandle) CloseLibrary(pAuthMechMod->libHandle); free(pAuthMechMod); } } else { DbgTrace(0, "GetAuthTokenIf-GetAuthTokenIf- Unable to allocate buffer\n", 0); // Free buffer allocated for entry free(pAuthMechMod); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } } else { DbgTrace(0, "-GetAuthTokenIf- Unable to allocate buffer\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_INSUFFICIENT_RESOURCES); } } // Release config interface instance pModuleConfigIf->releaseReference(pModuleConfigIf); } else { DbgTrace(0, "-GetAuthTokenIf- Unable to obtain config interface\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_CONFIGURATION_ERROR); } DbgTrace(2, "-GetAuthTokenIf- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= CasaStatus GetAuthMechToken( IN AuthContext *pAuthContext, IN const char *pHostName, IN void *pCredStoreScope, INOUT char **ppAuthToken) // // Arguments: // // Returns: // // Abstract: // // Notes: // // L2 //=======================================================================-- { CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_UNSUCCESSFUL); AuthTokenIf *pAuthTokenIf = NULL; DbgTrace(1, "-GetAuthMechToken- Start\n", 0); // Initialize output parameter *ppAuthToken = NULL; // Obtain the appropriate token interface for the authentication type retStatus = GetAuthTokenIf(pAuthContext->pMechanism, &pAuthTokenIf); if (CASA_SUCCESS(retStatus)) { char *pAuthToken = NULL; int authTokenBufLen = 0; // We found a provider for the service, query it for the buffer size // needed to obtain the authentication token. retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf, pAuthContext->pContext, pAuthContext->pMechInfo, pHostName, pCredStoreScope, pAuthToken, &authTokenBufLen); if (CasaStatusCode(retStatus) == CASA_STATUS_BUFFER_OVERFLOW) { // Allocate buffer to hold the authentication token pAuthToken = (char*) malloc(authTokenBufLen); if (pAuthToken) { // Request the token from the provider retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf, pAuthContext->pContext, pAuthContext->pMechInfo, pHostName, pCredStoreScope, pAuthToken, &authTokenBufLen); if (CASA_SUCCESS(retStatus)) { // Return the buffer containing the token to the caller *ppAuthToken = pAuthToken; } else { // Free the allocated buffer free(pAuthToken); } } else { DbgTrace(0, "-GetAuthMechToken- Buffer allocation failure\n", 0); } } // Release token interface pAuthTokenIf->releaseReference(pAuthTokenIf); } else { // No authentication token interface available for authentication type DbgTrace(0, "-GetAuthMechToken- Failed to obtain auth mech token interface\n", 0); } DbgTrace(1, "-GetAuthMechToken- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= //++======================================================================= //++=======================================================================