/*----------------------------------------------------------------------- * File: MAF_MDS.C * * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. *----------------------------------------------------------------------- */ #include #define CSSM_LEAN #include "cssm.h" #include "mds.h" #include "mds_schema.h" #ifdef VMS #include #include #else #include "port/cssmport.h" #include "port/cssmlock.h" #endif #include "maf_mds.h" #include "maf_collectn.h" #include "maf_util.h" #ifdef VMS #include #else #include "util/maf_misc.h" #endif static MDS_HANDLE MDSHandle = CSSM_INVALID_HANDLE; static MDS_DB_HANDLE MDSObjectDb = { CSSM_INVALID_HANDLE, CSSM_INVALID_HANDLE }; static MDS_DB_HANDLE MDSCdsaDb = { CSSM_INVALID_HANDLE, CSSM_INVALID_HANDLE }; static MDS_FUNCS MDSFunctions; CSSM_RETURN Addin_MDSInit() { CSSM_RETURN rv = CSSM_OK; assert( MDSHandle == CSSM_INVALID_HANDLE ); /* Start an MDS connection */ if ( ( MDS_Initialize( NULL, NULL, &Addin_APIMemFuncs, &MDSFunctions, &MDSHandle ) ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_MDS_ERROR ); } else { /* Open the object directory */ if ( MDSFunctions.DbOpen( MDSHandle, MDS_OBJECT_DIRECTORY, NULL, CSSM_DB_ACCESS_READ, NULL, NULL, &MDSObjectDb.DBHandle ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_MDS_ERROR ); } else { /* Complete the object directory handle */ MDSObjectDb.DLHandle = MDSHandle; /* Open the CDSA directory */ if ( MDSFunctions.DbOpen( MDSHandle, MDS_CDSA_DIRECTORY, NULL, CSSM_DB_ACCESS_READ, NULL, NULL, &MDSCdsaDb.DBHandle ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_MDS_ERROR ); } else { /* Complete the CDSA directory handle */ MDSCdsaDb.DLHandle = MDSHandle; } /* Close the object directory if an error happened */ if ( rv != CSSM_OK ) { MDSFunctions.DbClose( MDSObjectDb ); MDSObjectDb.DLHandle = CSSM_INVALID_HANDLE; MDSObjectDb.DBHandle = CSSM_INVALID_HANDLE; } } /* Terminate the MDS connection if an error happened */ if ( rv != CSSM_OK ) { MDS_Terminate( MDSHandle ); MDSHandle = CSSM_INVALID_HANDLE; } } return rv; } CSSM_RETURN Addin_MDSTerm() { CSSM_RETURN rv = CSSM_OK; assert( MDSHandle != CSSM_INVALID_HANDLE ); /* Close the object database */ MDSFunctions.DbClose( MDSObjectDb ); MDSObjectDb.DLHandle = CSSM_INVALID_HANDLE; MDSObjectDb.DBHandle = CSSM_INVALID_HANDLE; /* Close the CDSA database */ MDSFunctions.DbClose( MDSCdsaDb ); MDSCdsaDb.DLHandle = CSSM_INVALID_HANDLE; MDSCdsaDb.DBHandle = CSSM_INVALID_HANDLE; /* Terminate the MDS connection */ MDS_Terminate( MDSHandle ); MDSHandle = CSSM_INVALID_HANDLE; return rv; } CSSM_RETURN Addin_MDSGetCredentialInfo( const CSSM_GUID *pGuid, CSSM_DB_RECORDTYPE Schema, CSSM_DATA *Credential, CSSM_DATA *ModuleName, CSSM_DATA *ModulePath ) { CSSM_RETURN rv = CSSM_OK; CSSM_QUERY Query; CSSM_SELECTION_PREDICATE GuidPredicate = { CSSM_DB_EQUAL, /* DbOperator */ { /* Attribute */ MDS_ATTRINFO_MODULEID, /* Info */ 0, /* NumberOfValues */ NULL /* Value */ } }; CSSM_DB_RECORD_ATTRIBUTE_DATA AttributeList; CSSM_DB_ATTRIBUTE_DATA Attributes[] = { { #define _MANIFEST_INDEX 0 MDS_ATTRINFO_MANIFEST, /* Info */ 0, /* NumberOfValues */ NULL /* Value */ }, { #define _NAME_INDEX 1 MDS_ATTRINFO_MODULENAME, /* Info */ 0, /* NumberOfValues */ NULL /* Value */ }, { #define _PATH_INDEX 2 MDS_ATTRINFO_PATH, /* Info */ 0, /* NumberOfValues */ NULL /* Value */ } }; CSSM_DATA TextGuidValue = { 0, NULL }; char TextGuid[MAF_PRINTABLE_GUID_LENGTH]; MDS_DB_HANDLE DBHandle; CSSM_HANDLE ResultsHandle = CSSM_INVALID_HANDLE; CSSM_BOOL bEndOfStore = CSSM_FALSE; CSSM_DB_UNIQUE_RECORD_PTR RecordId = NULL; assert( MDSHandle != CSSM_INVALID_HANDLE ); /* Fill the query structure */ Query.RecordType = Schema; Query.Conjunctive = CSSM_DB_AND; Query.QueryLimits.TimeLimit = CSSM_QUERY_TIMELIMIT_NONE; Query.QueryLimits.SizeLimit = CSSM_QUERY_SIZELIMIT_NONE; Query.SelectionPredicate = &GuidPredicate; Query.NumSelectionPredicates = 1; Query.QueryFlags = 0; /* Format the text version of the GUID */ MAF_GetPrintableGUID( pGuid, TextGuid ); /* Set the predicate value */ TextGuidValue.Data = (uint8*)TextGuid; TextGuidValue.Length = strlen(TextGuid) + 1; GuidPredicate.Attribute.NumberOfValues = 1; GuidPredicate.Attribute.Value = &TextGuidValue; /* Build the attributes to return */ AttributeList.DataRecordType = Schema; AttributeList.SemanticInformation = 0; AttributeList.NumberOfAttributes = sizeof(Attributes)/sizeof(Attributes[0]); AttributeList.AttributeData = Attributes; /* Determine the DBHandle to use */ if ( Schema == MDS_OBJECT_RECORDTYPE ) { DBHandle = MDSObjectDb; } else { DBHandle = MDSCdsaDb; } /* Fetch the record */ if ( MDSFunctions.DataGetFirst( DBHandle, &Query, &ResultsHandle, &AttributeList, NULL, &RecordId ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_MDS_ERROR ); } else { MDSFunctions.FreeUniqueRecord( DBHandle, RecordId ); if ( !bEndOfStore ) { MDSFunctions.DataAbortQuery( DBHandle, ResultsHandle ); } *Credential = *(Attributes[_MANIFEST_INDEX].Value); *ModuleName = *(Attributes[_NAME_INDEX].Value); *ModulePath = *(Attributes[_PATH_INDEX].Value); if ( Attributes[_MANIFEST_INDEX].Value ) Addin_free( Attributes[_MANIFEST_INDEX].Value, NULL ); if ( Attributes[_NAME_INDEX].Value ) Addin_free( Attributes[_NAME_INDEX].Value, NULL ); if ( Attributes[_PATH_INDEX].Value ) Addin_free( Attributes[_PATH_INDEX].Value, NULL ); } return rv; } CSSM_RETURN Addin_MDSReleaseCredentialInfo( CSSM_DATA *Credential, CSSM_DATA *ModuleName, CSSM_DATA *ModulePath ) { CSSM_RETURN rv = CSSM_OK; assert( Credential && ModuleName && ModulePath ); if ( Credential->Data ) { Addin_free( Credential->Data, NULL ); Credential->Data = NULL; } if ( ModuleName->Data ) { Addin_free( ModuleName->Data, NULL ); ModuleName->Data = NULL; } if ( ModulePath->Data ) { Addin_free( ModulePath->Data, NULL ); ModulePath->Data = NULL; } return rv; } #if 0 void object_schema_GetAttributes( cssm_MDS_OBJECT_RECORD_PTR Record, CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes) { Attributes->DataRecordType = MDS_OBJECT_RECORDTYPE; Attributes->SemanticInformation = 0; Attributes->NumberOfAttributes = MDS_OBJECT_NUM_ATTRIBUTES; /* Guid */ Attributes->AttributeData[0].Info = s_MdsAttrInfo_ModuleId; Attributes->AttributeData[0].Value.Data = Record->guid.Data; Attributes->AttributeData[0].Value.Length = Record->guid.Length; /* Manifest */ Attributes->AttributeData[1].Info = s_MdsAttrInfo_Manifest; Attributes->AttributeData[1].Value.Data = Record->Manifest.Data; Attributes->AttributeData[1].Value.Length = Record->Manifest.Length; /* ModuleName */ Attributes->AttributeData[2].Info = s_MdsAttrInfo_ModuleName; Attributes->AttributeData[2].Value.Data = Record->ModuleName.Data; Attributes->AttributeData[2].Value.Length = Record->ModuleName.Length; /* Filepath */ Attributes->AttributeData[3].Info = s_MdsAttrInfo_Path; Attributes->AttributeData[3].Value.Data = Record->Path.Data; Attributes->AttributeData[3].Value.Length = Record->Path.Length; return; } void common_schema_GetAttributes( cssm_MDS_CDSADIR_COMMON_PTR Record, CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes) { Attributes->DataRecordType = MDS_CDSADIR_COMMON_RECORDTYPE; Attributes->SemanticInformation = 0; Attributes->NumberOfAttributes = MDS_CDSADIR_COMMON_NUM_ATTRIBUTES; /* Guid */ Attributes->AttributeData[0].Info = s_MdsAttrInfo_ModuleId; Attributes->AttributeData[0].Value.Data = Record->guid.Data; Attributes->AttributeData[0].Value.Length = Record->guid.Length; /* Manifest */ Attributes->AttributeData[1].Info = s_MdsAttrInfo_Manifest; Attributes->AttributeData[1].Value.Data = Record->Manifest.Data; Attributes->AttributeData[1].Value.Length = Record->Manifest.Length; /* ModuleName */ Attributes->AttributeData[2].Info = s_MdsAttrInfo_ModuleName; Attributes->AttributeData[2].Value.Data = Record->ModuleName.Data; Attributes->AttributeData[2].Value.Length = Record->ModuleName.Length; /* Filepath */ Attributes->AttributeData[3].Info = s_MdsAttrInfo_Path; Attributes->AttributeData[3].Value.Data = Record->Path.Data; Attributes->AttributeData[3].Value.Length = Record->Path.Length; Attributes->AttributeData[4].Info = s_MdsAttrInfo_Version; Attributes->AttributeData[4].Value.Data = Record->Version.Data; Attributes->AttributeData[4].Value.Length = Record->Version.Length; Attributes->AttributeData[5].Info = s_MdsAttrInfo_Desc; Attributes->AttributeData[5].Value.Data = Record->Desc.Data; Attributes->AttributeData[5].Value.Length = Record->Desc.Length; Attributes->AttributeData[6].Info = s_MdsAttrInfo_DynamicFlag; Attributes->AttributeData[6].Value.Data = Record->Dynamic.Data; Attributes->AttributeData[6].Value.Length = Record->Dynamic.Length; Attributes->AttributeData[7].Info = s_MdsAttrInfo_MultiThreadFlag; Attributes->AttributeData[7].Value.Data = Record->MultiThreadFlag.Data; Attributes->AttributeData[7].Value.Length = Record->MultiThreadFlag.Length; Attributes->AttributeData[8].Info = s_MdsAttrInfo_ServiceMaskFlag; Attributes->AttributeData[8].Value.Data = Record->ServiceMask.Data; Attributes->AttributeData[8].Value.Length = Record->ServiceMask.Length; return; } CSSM_RETURN maf_open_mds_directory (CSSM_DL_DB_HANDLE *hDLDBObject, CSSM_DL_DB_HANDLE *hDLDBCdsa, MDS_FUNCS *MDSFunctions) { CSSM_DL_HANDLE Handle; CSSM_DB_HANDLE dbHandle; CSSM_DB_ACCESS_TYPE access = CSSM_DB_ACCESS_READ; MDS_ERROR_FUNCS pErrorFuncs; CSSM_MEMORY_FUNCS cssm_pMemoryFunctions = {Addin_malloc, Addin_free, Addin_realloc, Addin_calloc}; pErrorFuncs.SetError = Addin_SetErrorEx; pErrorFuncs.GetError = Addin_GetError; pErrorFuncs.ClearError = Addin_ClearError; if ((Handle = MDS_Initialize( NULL, &cssm_pMemoryFunctions, &pErrorFuncs, MDSFunctions)) == 0) return (CSSM_FAIL); Addin_ClearError (); if ((dbHandle = MDSFunctions->DbOpen (Handle, MDS_OBJECT_DIRECTORY, NULL, &access, NULL, NULL)) == 0) { MDS_Terminate (Handle, NULL); return (CSSM_FAIL); } hDLDBObject->DLHandle = Handle; hDLDBObject->DBHandle = dbHandle; if ((dbHandle = MDSFunctions->DbOpen (Handle, MDS_CDSA_DIRECTORY, NULL, &access, NULL, NULL)) == 0) { MDSFunctions->DbClose (*hDLDBObject); MDS_Terminate (Handle, NULL); return (CSSM_FAIL); } hDLDBCdsa->DLHandle = Handle; hDLDBCdsa->DBHandle = dbHandle; return (CSSM_OK); } void maf_close_mds_directory (CSSM_DL_DB_HANDLE hDLDBObject, CSSM_DL_DB_HANDLE hDLDBCdsa) { MDSFunctions.DbClose (hDLDBObject); MDSFunctions.DbClose (hDLDBCdsa); MDS_Terminate (hDLDBObject.DLHandle, NULL); } CSSM_RETURN maf_GetRecord( CSSM_DL_DB_HANDLE hDLDB, CSSM_QUERY Query, CSSM_DB_RECORDTYPE RecordType, uint32 NumAttributes, CSSM_HANDLE_PTR ResultsHandle, CSSM_BOOL *EndOfDataStore, CSSM_DB_ATTRIBUTE_DATA *OutputAttributeData) { CSSM_DB_UNIQUE_RECORD_PTR RecordId; CSSM_DB_RECORD_ATTRIBUTE_DATA OutputAttributes; CSSM_ERROR_PTR Error; memset (&OutputAttributes, 0, sizeof (CSSM_DB_RECORD_ATTRIBUTE_DATA)); /* We want to get NumAttributes back */ OutputAttributes.DataRecordType = RecordType; OutputAttributes.NumberOfAttributes = NumAttributes; OutputAttributes.AttributeData = OutputAttributeData; if (0 == *ResultsHandle) { RecordId = MDSFunctions.DataGetFirst (hDLDB, /* DLDBHandle */ &Query, ResultsHandle, EndOfDataStore, &OutputAttributes, NULL); } else { RecordId = MDSFunctions.DataGetNext (hDLDB, /* DLDBHandle */ *ResultsHandle, EndOfDataStore, &OutputAttributes, NULL); } Error = Addin_GetError(); if (!RecordId || *EndOfDataStore != CSSM_FALSE || (Error && Error->error != CSSM_OK)) return CSSM_FAIL; MDSFunctions.FreeUniqueRecord(hDLDB, RecordId); return CSSM_OK; } CSSM_RETURN maf_GetRecordByGuid( CSSM_DL_DB_HANDLE hDLDB, CSSM_GUID_PTR guid, CSSM_DB_RECORDTYPE RecordType, uint32 NumAttributes, CSSM_HANDLE_PTR ResultsHandle, CSSM_BOOL *EndOfDataStore, CSSM_DB_ATTRIBUTE_DATA *OutputAttributeData) { CSSM_QUERY Query; CSSM_SELECTION_PREDICATE Predicate; char GuidStr[CSSM_MAX_REG]; /* * Convert the Guid to a string. */ maf_GUIDToStr (guid, GuidStr); memset (&Query, 0, sizeof (CSSM_QUERY)); memset (&Predicate, 0, sizeof (CSSM_SELECTION_PREDICATE)); Query.RecordType = RecordType; Query.Conjunctive = CSSM_DB_NONE; Query.NumSelectionPredicates = 1; Query.SelectionPredicate = &Predicate; Query.QueryLimits.TimeLimit = CSSM_QUERY_TIMELIMIT_NONE; Query.QueryLimits.SizeLimit = CSSM_QUERY_SIZELIMIT_NONE; Query.QueryFlags = 0; Predicate.DbOperator = CSSM_DB_EQUAL; /* NOTE: The first attribute *NEEDS* to be an index */ Predicate.Attribute.Info = s_MdsAttrInfo_ModuleId; Predicate.Attribute.NumberOfValues = 1; Predicate.Attribute.Value.Data = (unsigned char *)GuidStr; Predicate.Attribute.Value.Length = strlen (GuidStr) + 1; return maf_GetRecord(hDLDB, Query, RecordType, NumAttributes, ResultsHandle, EndOfDataStore, OutputAttributeData); } CSSM_RETURN maf_GetObjectRecord (CSSM_DL_DB_HANDLE hDLDB, CSSM_GUID_PTR Guid, cssm_MDS_OBJECT_RECORD_PTR Record, CSSM_DB_ATTRIBUTE_DATA_PTR ObjectAttributes) { CSSM_DB_RECORD_ATTRIBUTE_DATA Attributes; CSSM_HANDLE ResultsHandle = 0; CSSM_BOOL EndOfDataStore = CSSM_FALSE; Attributes.AttributeData = ObjectAttributes; object_schema_GetAttributes (Record, &Attributes); if (maf_GetRecordByGuid( hDLDB, Guid, MDS_OBJECT_RECORDTYPE, MDS_OBJECT_NUM_ATTRIBUTES, &ResultsHandle, &EndOfDataStore, ObjectAttributes) != CSSM_OK) return CSSM_FAIL; MDSFunctions.DataAbortQuery( hDLDB, ResultsHandle ); Record->guid = ObjectAttributes[0].Value; Record->Manifest = ObjectAttributes[1].Value; Record->ModuleName = ObjectAttributes[2].Value; Record->Path = ObjectAttributes[3].Value; return (CSSM_OK); } CSSM_RETURN maf_GetCommonRecord(CSSM_DL_DB_HANDLE hDLDB, CSSM_GUID_PTR Guid, cssm_MDS_CDSADIR_COMMON_PTR Record, CSSM_DB_ATTRIBUTE_DATA_PTR CommonAttributes) { CSSM_DB_RECORD_ATTRIBUTE_DATA Attributes; CSSM_HANDLE ResultsHandle = 0; CSSM_BOOL EndOfDataStore = CSSM_FALSE; Attributes.AttributeData = CommonAttributes; common_schema_GetAttributes (Record, &Attributes); if (maf_GetRecordByGuid( hDLDB, Guid, MDS_CDSADIR_COMMON_RECORDTYPE, MDS_CDSADIR_COMMON_NUM_ATTRIBUTES, &ResultsHandle, &EndOfDataStore, CommonAttributes) != CSSM_OK) return CSSM_FAIL; MDSFunctions.DataAbortQuery( hDLDB, ResultsHandle ); Record->guid = CommonAttributes[0].Value; Record->Manifest = CommonAttributes[1].Value; Record->ModuleName = CommonAttributes[2].Value; Record->Path = CommonAttributes[3].Value; Record->Version = CommonAttributes[4].Value; Record->Desc = CommonAttributes[5].Value; Record->Dynamic = CommonAttributes[6].Value; Record->MultiThreadFlag = CommonAttributes[7].Value; Record->ServiceMask = CommonAttributes[8].Value; return (CSSM_OK); } CSSM_RETURN maf_GetObjectCredentialInfo (CSSM_GUID_PTR guid, CSSM_DATA_PTR Credential, CSSM_DATA_PTR ModuleName, CSSM_DATA_PTR ModulePath) { cssm_MDS_OBJECT_RECORD Record; CSSM_DB_ATTRIBUTE_DATA ObjectAttributes[MDS_OBJECT_NUM_ATTRIBUTES]; if (maf_GetObjectRecord (hDLDBObject, guid, &Record, ObjectAttributes) != CSSM_OK) return CSSM_FAIL; if (Credential) *Credential = Record.Manifest; else Addin_free (Record.Manifest.Data, NULL); if (ModuleName) *ModuleName = Record.ModuleName; else Addin_free (Record.ModuleName.Data, NULL); if (ModulePath) *ModulePath = Record.Path; else Addin_free (Record.Path.Data, NULL); Addin_free (Record.guid.Data, NULL); return CSSM_OK; } CSSM_RETURN maf_GetCommonCredentialInfo (CSSM_GUID_PTR guid, CSSM_DATA_PTR Credential, CSSM_DATA_PTR ModuleName, CSSM_DATA_PTR ModulePath) { cssm_MDS_CDSADIR_COMMON Record; CSSM_DB_ATTRIBUTE_DATA CommonAttributes[MDS_CDSADIR_COMMON_NUM_ATTRIBUTES]; if (maf_GetCommonRecord (hDLDBCdsa, guid, &Record, CommonAttributes) != CSSM_OK) return CSSM_FAIL; if (Credential) *Credential = Record.Manifest; else Addin_free (Record.Manifest.Data, NULL); if (ModuleName) *ModuleName = Record.ModuleName; else Addin_free (Record.ModuleName.Data, NULL); if (ModulePath) *ModulePath = Record.Path; else Addin_free (Record.Path.Data, NULL); Addin_free (Record.guid.Data, NULL); Addin_free (Record.Version.Data, NULL); Addin_free (Record.Desc.Data, NULL); Addin_free (Record.Dynamic.Data, NULL); Addin_free (Record.MultiThreadFlag.Data, NULL); Addin_free (Record.ServiceMask.Data, NULL); return CSSM_OK; } CSSM_RETURN maf_GetModuleCredentialInfo (CSSM_GUID_PTR guid, CSSM_DATA_PTR Credential, CSSM_DATA_PTR ModuleName, CSSM_DATA_PTR ModulePath) { if (maf_GetObjectCredentialInfo (guid, Credential, ModuleName, ModulePath) == CSSM_OK) return CSSM_OK; return maf_GetCommonCredentialInfo (guid, Credential, ModuleName, ModulePath); } CSSM_RETURN maf_GetModulePath (CSSM_DATA ModuleName, CSSM_DATA ModuleSearchPath, CSSM_DATA_PTR ModulePath) { uint8 *SearchPtr; uint8 *ptr; uint32 len; CSSM_DATA tmpPath; struct _stat st; len = ModuleSearchPath.Length + ModuleName.Length + 2; if ((ptr = Addin_malloc (len, NULL)) == NULL) return CSSM_FAIL; SearchPtr = ModuleSearchPath.Data; tmpPath.Data = ModuleSearchPath.Data; tmpPath.Length = ModuleSearchPath.Length; while (SearchPtr) { SearchPtr = memchr (tmpPath.Data, PATH_SEPARATOR, tmpPath.Length); if (SearchPtr != NULL) { tmpPath.Length = SearchPtr - tmpPath.Data; SearchPtr++; /* Skip the PATH_SEPARATOR */ } else { /* * get rid of the null character at the end of search path, if any. */ if (tmpPath.Data[tmpPath.Length-1] == '\0') tmpPath.Length--; } ModulePath->Data = ptr; memcpy(ptr, tmpPath.Data, tmpPath.Length); ptr = ptr + tmpPath.Length; *ptr++ = DIRECTORY_SEPARATOR; memcpy(ptr, ModuleName.Data, ModuleName.Length); /* copy relative path */ ptr = ptr + ModuleName.Length; /* move to end of string */ *ptr = '\0'; /* null terminate */ ModulePath->Length = ptr - ModulePath->Data; /* * stat the file and find out if we have found it. * If yes, then return else continue searching the * search path. */ if ((_stat((const char *)ModulePath->Data, &st)) == 0) return CSSM_OK; tmpPath.Data = SearchPtr; tmpPath.Length = ModuleSearchPath.Length - (SearchPtr - ModuleSearchPath.Data); } return CSSM_FAIL; } #endif