in LCM/dsc/engine/ca/CAInfrastructure/WebPullClient.c [584:876]
MI_Result GetMetaConfigParameters(_In_ MI_Instance *metaConfig,
_In_ MI_Char* partialConfigName,
_Outptr_opt_result_maybenull_ MI_Instance **credential,
_Inout_ MI_InstanceA *customParam,
_Outptr_result_maybenull_z_ MI_Char **configurationID,
_Outptr_result_maybenull_z_ MI_Char **certificateID,
_Inout_updates_(URL_SIZE) MI_Char *url,
_Inout_updates_(SUBURL_SIZE) MI_Char *subUrl,
_Out_ MI_Uint32 *port,
_Out_ MI_Boolean *bIsHttps,
_Out_ MI_Uint32* getActionStatusCode,
_Outptr_result_maybenull_ MI_Instance **extendedError)
{
MI_Result r = MI_RESULT_OK;
MI_Value value;
MI_Value value2;
MI_Value value3;
MI_Char serverURL[MAX_URL_LENGTH];
MI_Uint32 flags;
MI_Uint32 xCount;
MI_Char* configurationSource = NULL;
MI_Boolean allowUnsecureConnection = MI_FALSE;
MI_InstanceA customData;
*credential = NULL;
*extendedError = NULL;
*getActionStatusCode = Success;
*configurationID = NULL;
*certificateID = NULL;
*bIsHttps = MI_FALSE;
*port = DEFAULT_SERVERPORT;
*getActionStatusCode = Success;
*extendedError = NULL;
*serverURL = '\0';
// 1. Get AgentID
r = MI_Instance_GetElement(metaConfig, MSFT_DSCMetaConfiguration_AgentId, &value, NULL, &flags, NULL);
if( r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
*getActionStatusCode = InvalidConfigurationIdInMetaConfig;
r = GetCimMIError(r, extendedError, ID_PULL_CONFIGURATIONIDNOTSPECIFIED);
return r;
}
*configurationID = (MI_Char*)DSC_malloc((Tcslen(value.string)+1) * sizeof(MI_Char), NitsHere());
if( *configurationID == NULL)
{
*getActionStatusCode = InvalidConfigurationIdInMetaConfig;
r = GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, ID_ENGINEHELPER_MEMORY_ERROR);
return r;
}
memcpy(*configurationID, value.string, Tcslen(value.string)* sizeof(MI_Char));
/* Validate the Uuid.*/
/*
if( !IsValidUuid(*configurationID))
{
*getActionStatusCode = InvalidConfigurationIdFormat;
r = GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_INVALIDCONFIGURATIONIDFORMAT, *configurationID);
DSC_free(*configurationID);
return r;
}
*/
// 2. Get Credential.
r = MI_Instance_GetElement(metaConfig, MetaConfig_Credential, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
*credential = value.instance;
}
// If partialConfigName is defined, get the ConfigurationDownloadManagers, else get the DownloadManagerCustomData
if ( partialConfigName != NULL )
{
// NOTE: Request miType for GetElement calls to aid in debugging schema changes.
MI_Type miType;
r = MI_Instance_GetElement(metaConfig, MSFT_DSCMetaConfiguration_PartialConfigurations, &value, &miType, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
return GetCimMIError(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOPARTIALCONFIGS);
}
for (xCount = 0; xCount < value.instancea.size; ++xCount)
{
MI_Instance_GetElement(value.instancea.data[xCount], OMI_MetaConfigurationResource_ResourceId, &value2, &miType, &flags, NULL);
if ( Tcscasecmp(value2.string, partialConfigName) == 0 )
{
// Found our partial config! Now let's get the configuration source
MI_Instance_GetElement(value.instancea.data[xCount], MSFT_PartialConfiguration_ConfigurationSource, &value2, &miType, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
return GetCimMIError1Param(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOCONFIGURATIONSOURCE, partialConfigName);
}
configurationSource = value2.stringa.data[0];
break;
}
}
if (configurationSource == NULL)
{
// Unable to find partial configuration with this name.
return GetCimMIError1Param(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOCONFIGURATIONSOURCE, partialConfigName);
}
r = MI_Instance_GetElement(metaConfig, MSFT_DSCMetaConfiguration_ConfigurationDownloadManagers, &value, &miType, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
// Unable to get the config download managers
return GetCimMIError(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOCONFIGDOWNLOADMANAGERS);
}
for (xCount = 0; xCount < value.instancea.size; ++xCount)
{
MI_Instance_GetElement(value.instancea.data[xCount], OMI_MetaConfigurationResource_ResourceId, &value2, &miType, &flags, NULL);
if ( Tcscasecmp(value2.string, configurationSource) == 0 )
{
// Found the WebDownloadManager with the proper resource ID.
MI_Instance_GetElement(value.instancea.data[xCount], MI_T("ServerURL"), &value2, &miType, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
return GetCimMIError1Param(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOSERVERURL, value3.string);
}
memcpy(serverURL, value2.string, (Tcslen(value2.string) + 1) * sizeof(MI_Char));
MI_Instance_GetElement(value.instancea.data[xCount], MI_T("CertificateID"), &value2, &miType, &flags, NULL);
if (r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
memcpy(*certificateID, value2.string, Tcslen(value2.string) * sizeof(MI_Char));
}
MI_Instance_GetElement(value.instancea.data[xCount], MI_T("AllowUnsecureConnection"), &value2, &miType, &flags, NULL);
if (r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
allowUnsecureConnection = value2.boolean;
}
//Check if connection is secure and if unsecure user explicitly asks for it.
if( Tcsncasecmp(serverURL, MI_T("https"), 5) != 0 && allowUnsecureConnection == MI_FALSE )
{
*getActionStatusCode = InvalidDownloadManagerCustomDataInMetaConfig;
r = GetCimMIError1Param( MI_RESULT_INVALID_PARAMETER, extendedError, ID_PULL_UNSECURECONNECTIONNOTALLOWED, serverURL);
return r;
}
// Found the WebDownloadManager, stop searching.
break;
}
}
}
else
{
// 3. Get custom arguments.
r = MI_Instance_GetElement(metaConfig, MetaConfigDownloadManagerCustomData, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
customParam->size = value.instancea.size;
customParam->data = value.instancea.data;
}
// 4. Get certificate ID.
for( xCount =0; xCount < customParam->size; xCount++)
{
MI_Value value;
MI_Uint32 flags;
r = MI_Instance_GetElement(customParam->data[xCount], MSFT_KEYVALUEPAIR_CLASS_KEY, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL) && Tcscasecmp(CertificateIdParamName, value.string) == 0 )
{
r = MI_Instance_GetElement(customParam->data[xCount], MSFT_KEYVALUEPAIR_CLASS_VALUE, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL) )
{
*certificateID = (MI_Char*)DSC_malloc((Tcslen(value.string)+1) * sizeof(MI_Char), NitsHere());
if( *certificateID == NULL)
{
*getActionStatusCode = InvalidConfigurationIdInMetaConfig;
r = GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, ID_ENGINEHELPER_MEMORY_ERROR);
if( *configurationID )
DSC_free(*configurationID);
*configurationID = NULL;
return r;
}
memcpy(*certificateID, value.string, Tcslen(value.string)* sizeof(MI_Char));
break;
}
}
}
}
if (*serverURL == '\0')
{
r = MI_Instance_GetElement(metaConfig, MetaConfigDownloadManagerCustomData, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
customData.size = value.instancea.size;
customData.data = value.instancea.data;
// Get Server Url.
for( xCount =0; xCount < customData.size; xCount++)
{
MI_Value value;
MI_Uint32 flags;
r = MI_Instance_GetElement(customData.data[xCount], MSFT_KEYVALUEPAIR_CLASS_KEY, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL) && Tcscasecmp(ServerUrlParamName, value.string) == 0 )
{
r = MI_Instance_GetElement(customData.data[xCount], MSFT_KEYVALUEPAIR_CLASS_VALUE, &value, NULL, &flags, NULL);
if( r == MI_RESULT_OK && !(flags & MI_FLAG_NULL) )
{
// Found ServerUrl in value.string
memcpy(serverURL, value.string, (Tcslen(value.string) + 1) * sizeof(MI_Char));
//Check if connection is secure and if unsecure user explicitly asks for it.
if( !ConnectionAllowed(&customData, serverURL) )
{
*getActionStatusCode = InvalidDownloadManagerCustomDataInMetaConfig;
r = GetCimMIError1Param( MI_RESULT_INVALID_PARAMETER, extendedError, ID_PULL_UNSECURECONNECTIONNOTALLOWED, serverURL);
return r;
}
break;
}
}
}
}
else
{
// There's no DownloadManagerCustomData, AND there's no partial configuration. We should be able to find WebDownloadManager, and only one!
r = MI_Instance_GetElement(metaConfig, MSFT_DSCMetaConfiguration_ConfigurationDownloadManagers, &value, NULL, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL) || value.instancea.size == 0)
{
// Unable to get the config download managers
return GetCimMIError(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOCONFIGDOWNLOADMANAGERS);
}
if (value.instancea.size > 1)
{
// Too many download managers defined, please set up partial configuration for this.
return GetCimMIError(MI_RESULT_FAILED, extendedError, ID_PULL_TOOMANYCONFIGDOWNLOADMANAGERS);
}
MI_Instance_GetElement(value.instancea.data[0], OMI_MetaConfigurationResource_ResourceId, &value3, NULL, &flags, NULL);
// Found the WebDownloadManager with the proper resource ID.
MI_Instance_GetElement(value.instancea.data[0], MI_T("ServerURL"), &value2, NULL, &flags, NULL);
if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
{
return GetCimMIError1Param(MI_RESULT_NO_SUCH_PROPERTY, extendedError, ID_PULL_NOSERVERURL, value3.string);
}
memcpy(serverURL, value2.string, (Tcslen(value2.string) + 1) * sizeof(MI_Char));
MI_Instance_GetElement(value.instancea.data[0], MI_T("CertificateID"), &value2, NULL, &flags, NULL);
if (r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
memcpy(*certificateID, value2.string, Tcslen(value2.string) * sizeof(MI_Char));
}
MI_Instance_GetElement(value.instancea.data[0], MI_T("AllowUnsecureConnection"), &value2, NULL, &flags, NULL);
if (r == MI_RESULT_OK && !(flags & MI_FLAG_NULL))
{
allowUnsecureConnection = value2.boolean;
}
}
}
if (*serverURL != '\0')
{
if( sscanf(serverURL, MI_T("http://%99[^:]:%d/%199[^\n]"), url, port, subUrl) == 3 ||
sscanf(serverURL, MI_T("http://%99[^/]/%199[^\n]"), url, subUrl) == 2 )
{
//success
}
//format is: http://server:port/suburl or http://server/suburl
else if( sscanf(serverURL, MI_T("https://%99[^:]:%d/%199[^\n]"), url, port, subUrl) == 3 ||
sscanf(serverURL, MI_T("https://%99[^/]/%199[^\n]"), url, subUrl) == 2 )
{
//success
*bIsHttps = MI_TRUE;
if (*port == 80)
{
*port = 443;
}
}
}
else
{
// Not found
*getActionStatusCode = InvalidDownloadManagerCustomDataInMetaConfig;
return GetCimMIError(r, extendedError, ID_ENGINEHELPER_MEMORY_ERROR);
}
return MI_RESULT_OK;
}