1588 lines
41 KiB
C++
1588 lines
41 KiB
C++
//***************************************************************************
|
|
//
|
|
// Copyright (c) 1998-2000 Microsoft Corporation
|
|
//
|
|
// File: parsedn.cxx
|
|
//
|
|
// Description :
|
|
// Parses CIM paths to objects and returns the requested object
|
|
//***************************************************************************
|
|
|
|
#include "precomp.h"
|
|
|
|
#define CURRENTSTR (lpszInputString + *pchEaten)
|
|
|
|
#define SKIPWHITESPACE \
|
|
while (*CURRENTSTR && _istspace( *CURRENTSTR ) ) \
|
|
(*pchEaten)++;
|
|
|
|
#define WBEMS_STR_OWNER L"O"
|
|
#define WBEMS_STR_GROUP L"G"
|
|
#define WBEMS_STR_DACL L"D"
|
|
#define WBEMS_STR_SACL L"S"
|
|
|
|
static void SecureProxy (bool authnSpecified, enum WbemAuthenticationLevelEnum eAuthLevel,
|
|
bool impSpecified, enum WbemImpersonationLevelEnum eImpersonLevel,
|
|
ISWbemServices *pService)
|
|
{
|
|
// Secure the proxy using the specified security settings (if any)
|
|
CComPtr<ISWbemSecurity> pSecurity;
|
|
|
|
if (authnSpecified || impSpecified)
|
|
{
|
|
if (SUCCEEDED(pService->get_Security_(&pSecurity)))
|
|
{
|
|
if (authnSpecified)
|
|
pSecurity->put_AuthenticationLevel (eAuthLevel);
|
|
|
|
if (impSpecified)
|
|
pSecurity->put_ImpersonationLevel (eImpersonLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SecureProxy (bool authnSpecified, enum WbemAuthenticationLevelEnum eAuthLevel,
|
|
bool impSpecified, enum WbemImpersonationLevelEnum eImpersonLevel,
|
|
ISWbemObject *pObject)
|
|
{
|
|
// Secure the proxy using the specified security settings (if any)
|
|
CComPtr<ISWbemSecurity> pSecurity;
|
|
|
|
if (authnSpecified || impSpecified)
|
|
{
|
|
if (SUCCEEDED(pObject->get_Security_(&pSecurity)))
|
|
{
|
|
if (authnSpecified)
|
|
pSecurity->put_AuthenticationLevel (eAuthLevel);
|
|
|
|
if (impSpecified)
|
|
pSecurity->put_ImpersonationLevel (eImpersonLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWbemParseDN::CWbemParseDN
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Constructor.
|
|
//
|
|
//***************************************************************************
|
|
|
|
CWbemParseDN::CWbemParseDN():
|
|
m_cRef(0)
|
|
{
|
|
InterlockedIncrement(&g_cObj);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWbemParseDN::~CWbemParseDN
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Destructor.
|
|
//
|
|
//***************************************************************************
|
|
|
|
CWbemParseDN::~CWbemParseDN(void)
|
|
{
|
|
InterlockedDecrement(&g_cObj);
|
|
}
|
|
|
|
//***************************************************************************
|
|
// HRESULT CWbemParseDN::QueryInterface
|
|
// long CWbemParseDN::AddRef
|
|
// long CWbemParseDN::Release
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Standard Com IUNKNOWN functions.
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDMETHODIMP CWbemParseDN::QueryInterface (
|
|
|
|
IN REFIID riid,
|
|
OUT LPVOID *ppv
|
|
)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
if (IID_IUnknown==riid)
|
|
*ppv = (IUnknown *)this;
|
|
else if (IID_IParseDisplayName==riid)
|
|
*ppv = (IParseDisplayName *)this;
|
|
|
|
if (NULL!=*ppv)
|
|
{
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWbemParseDN::AddRef(void)
|
|
{
|
|
InterlockedIncrement(&m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWbemParseDN::Release(void)
|
|
{
|
|
InterlockedDecrement(&m_cRef);
|
|
if (0L!=m_cRef)
|
|
return m_cRef;
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SCODE CWbemParseDN::ParseDisplayName
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take a CIM object path and return a suitable ISWbem... object
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pCtx The binding context (not used)
|
|
// szDisplayName The display name to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// ppmk On return will address the moniker pointer
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// E_FAIL misery
|
|
//
|
|
// Other CreateMoniker codes are returned.
|
|
//
|
|
//***************************************************************************
|
|
STDMETHODIMP CWbemParseDN::ParseDisplayName(
|
|
IBindCtx* pCtx,
|
|
LPOLESTR szDisplayName,
|
|
ULONG* pchEaten,
|
|
IMoniker** ppmk)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPUNKNOWN pUnknown = NULL;
|
|
ULONG lTemp = 0;
|
|
|
|
enum WbemAuthenticationLevelEnum eAuthLevel;
|
|
enum WbemImpersonationLevelEnum eImpersonLevel;
|
|
bool authnSpecified = false;
|
|
bool impSpecified = false;
|
|
BSTR bsAuthority = NULL;
|
|
|
|
//Check input parameters
|
|
*ppmk = NULL;
|
|
if (NULL != pchEaten)
|
|
*pchEaten = 0;
|
|
|
|
if (NULL == szDisplayName)
|
|
return E_FAIL;
|
|
|
|
/*
|
|
* moniker : wmiMoniker
|
|
*
|
|
* wmiMoniker : ["winmgmts:" | "wmi:"] securitySetting ["[" localeSetting "]"] ["!" objectPath]
|
|
* | ["winmgmts:" | "wmi:"] "[" localeSetting "]" ["!" objectPath]
|
|
* | ["winmgmts:" | "wmi:"] [objectPath]
|
|
* | [nativePath]
|
|
*
|
|
* localeSetting : "locale" <ows> "=" <ows> localeID
|
|
*
|
|
* localeID : a value of the form "ms_xxxx" where xxxx is a hex LCID value e.g. "ms_0x409".
|
|
*
|
|
* objectPath : a valid WMI Object Path
|
|
*
|
|
* securitySetting : "{" <ows> authAndImpersonSettings [<ows> "," <ows> privilegeOverrides]
|
|
* | "{" <ows> authAndImpersonSettings [<ows> "," <ows> privilegeOverrides] <ows> "}" <ows>
|
|
* | "{" <ows> privilegeOverrides <ows> "}" <ows>
|
|
*
|
|
*
|
|
* authAndImpersonSettings :
|
|
* authenticationLevel
|
|
* | impersonationLevel
|
|
* | authority
|
|
* | authenticationLevel <ows> "," <ows> impersonationLevel [<ows> "," <ows> authority]
|
|
* | authenticationLevel <ows> "," <ows> authority [<ows> "," <ows> impersonationLevel]
|
|
* | impersonationLevel <ows> "," <ows> authenticationLevel [<ows> "," <ows> authority]
|
|
* | impersonationLevel <ows> "," <ows> authority [<ows> "," <ows> authenticationLevel]
|
|
* | authority <ows> "," <ows> impersonationLevel [<ows> "," <ows> authenticationLevel]
|
|
* | authority <ows> "," <ows> authenticationLevel [<ows> "," <ows> impersonationLevel]
|
|
*
|
|
*
|
|
* authority : "authority" <ows> "=" <ows> authorityValue
|
|
*
|
|
* authorityValue : Any valid WMI authority string e.g. "kerberos:mydomain\server" or "ntlmdomain:mydomain". Note that backslashes need to be escaped in JScript.
|
|
*
|
|
* authenticationLevel : "authenticationLevel" <ows> "=" <ows> authenticationValue
|
|
*
|
|
* authenticationValue : "default" | "none" | "connect" | "call" | "pkt" | "pktIntegrity" | "pktPrivacy"
|
|
*
|
|
* impersonationLevel : "impersonationLevel" <ows> "=" <ows> impersonationValue
|
|
*
|
|
* impersonationValue : "anonymous" | "identify" | "impersonate" | "delegate"
|
|
*
|
|
* privilegeOverrides : "(" <ows> privileges <ows> ")"
|
|
*
|
|
* privileges : privilege [<ows> "," <ows> privileges <ows>]*
|
|
*
|
|
* privilege : ["!"] privilegeName
|
|
*
|
|
* privilegeName : "CreateToken" | "PrimaryToken" | "LockMemory" | "IncreaseQuota"
|
|
* | "MachineAccount" | "Tcb" | "Security" | "TakeOwnership"
|
|
* | "LoadDriver" | "SystemProfile" | "SystemTime"
|
|
* | "ProfileSingleProcess" | "IncreaseBasePriority"
|
|
* | "CreatePagefile" | "CreatePermanent" | "Backup" | "Restore"
|
|
* | "Shutdown" | "Debug" | "Audit" | "SystemEnvironment" | "ChangeNotify"
|
|
* | "RemoteShutdown"
|
|
*
|
|
*/
|
|
|
|
// It had better start with our scheme name
|
|
bool bCheckContext = false;
|
|
|
|
if (0 == _wcsnicmp (szDisplayName, WBEMS_PDN_SCHEME, wcslen (WBEMS_PDN_SCHEME)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_PDN_SCHEME);
|
|
bCheckContext = (pCtx && (wcslen (szDisplayName) == wcslen (WBEMS_PDN_SCHEME)));
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
|
|
// One more check - if it was just the scheme and no more check for extra info in the context
|
|
if (bCheckContext)
|
|
{
|
|
IUnknown *pUnk = NULL;
|
|
|
|
if (SUCCEEDED (pCtx->GetObjectParam (L"WmiObject", &pUnk)) && pUnk)
|
|
{
|
|
// Is it an IWbemClassObject?
|
|
IWbemClassObject *pIWbemClassObject = NULL;
|
|
// Or is it an IWbemContext?
|
|
IWbemContext *pIWbemContext = NULL;
|
|
// Or is it an IWbemServices?
|
|
IWbemServices *pIWbemServices = NULL;
|
|
|
|
if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemClassObject, (void **) &pIWbemClassObject)))
|
|
{
|
|
CSWbemObject *pSWbemObject = new CSWbemObject (NULL, pIWbemClassObject);
|
|
|
|
if (!pSWbemObject)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
{
|
|
CComPtr<ISWbemObjectEx> pISWbemObjectEx;
|
|
|
|
if (SUCCEEDED (pSWbemObject->QueryInterface (IID_ISWbemObjectEx, (void **) &pISWbemObjectEx)))
|
|
hr = CreatePointerMoniker (pISWbemObjectEx, ppmk);
|
|
}
|
|
|
|
pIWbemClassObject->Release ();
|
|
}
|
|
else if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemContext, (void **) &pIWbemContext)))
|
|
{
|
|
CSWbemNamedValueSet *pSWbemNamedValueSet = new CSWbemNamedValueSet (NULL, pIWbemContext);
|
|
|
|
if (!pSWbemNamedValueSet)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
{
|
|
CComPtr<ISWbemNamedValueSet> pISWbemNamedValueSet;
|
|
|
|
if (SUCCEEDED (pSWbemNamedValueSet->QueryInterface (IID_ISWbemNamedValueSet,
|
|
(PPVOID)&pISWbemNamedValueSet)))
|
|
hr = CreatePointerMoniker (pISWbemNamedValueSet, ppmk);
|
|
}
|
|
|
|
pIWbemContext->Release ();
|
|
}
|
|
else if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemServices, (void **) &pIWbemServices)))
|
|
{
|
|
// In this case we must get passed the object path as well
|
|
CComPtr<IUnknown> pUnkPath;
|
|
|
|
if (SUCCEEDED (pCtx->GetObjectParam (L"WmiObjectPath", &pUnkPath)) && pUnkPath)
|
|
{
|
|
CComPtr<ISWbemObjectPath> pISWbemObjectPath;
|
|
|
|
if (SUCCEEDED (pUnkPath->QueryInterface (IID_ISWbemObjectPath, (void **) &pISWbemObjectPath)))
|
|
{
|
|
// Dig the path out to initialize
|
|
CComBSTR bsNamespace = NULL;
|
|
|
|
pISWbemObjectPath->get_Path (&bsNamespace);
|
|
|
|
CSWbemServices *pSWbemServices = new CSWbemServices (pIWbemServices,
|
|
bsNamespace, (BSTR) NULL, NULL, NULL);
|
|
|
|
if (!pSWbemServices)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
{
|
|
CComQIPtr<ISWbemServicesEx>
|
|
pISWbemServicesEx (pSWbemServices);
|
|
|
|
if (pISWbemServicesEx)
|
|
hr = CreatePointerMoniker (pISWbemServicesEx, ppmk);
|
|
}
|
|
}
|
|
}
|
|
pIWbemServices->Release ();
|
|
}
|
|
|
|
pUnk->Release ();
|
|
}
|
|
|
|
// If this worked return now - o/w revert to regular parsing
|
|
if (SUCCEEDED (hr))
|
|
return hr;
|
|
}
|
|
|
|
// Check for the optional security info
|
|
CSWbemPrivilegeSet privilegeSet;
|
|
|
|
if (ParseSecurity(szDisplayName + *pchEaten, &lTemp, authnSpecified, &eAuthLevel,
|
|
impSpecified, &eImpersonLevel, privilegeSet,
|
|
bsAuthority))
|
|
*pchEaten += lTemp;
|
|
|
|
// If no impersonation level was specified, get the default from the registry
|
|
if (!impSpecified)
|
|
{
|
|
eImpersonLevel = CSWbemSecurity::GetDefaultImpersonationLevel ();
|
|
impSpecified = true;
|
|
}
|
|
|
|
// Create a locator
|
|
CSWbemLocator *pCSWbemLocator = new CSWbemLocator(&privilegeSet);
|
|
|
|
if (!pCSWbemLocator)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
{
|
|
CComQIPtr<ISWbemLocator> pISWbemLocator (pCSWbemLocator);
|
|
|
|
if (pISWbemLocator)
|
|
{
|
|
// Parse the locale information (if present)
|
|
lTemp = 0;
|
|
BSTR bsLocale = NULL;
|
|
|
|
if (ParseLocale (szDisplayName + *pchEaten, &lTemp, bsLocale))
|
|
{
|
|
*pchEaten += lTemp;
|
|
|
|
// Skip over the "!" separator if there is one
|
|
if(*(szDisplayName + *pchEaten) != NULL)
|
|
if (0 == _wcsnicmp (szDisplayName + *pchEaten, WBEMS_EXCLAMATION, wcslen (WBEMS_EXCLAMATION)))
|
|
*pchEaten += wcslen (WBEMS_EXCLAMATION);
|
|
|
|
// Now ready to parse the path - check if we have the degenerate cases
|
|
if (0 == wcslen (szDisplayName + *pchEaten))
|
|
{
|
|
// Need to return connection to default namespace on local machine
|
|
CComPtr<ISWbemServices> pISWbemServices;
|
|
if (SUCCEEDED( hr = pISWbemLocator->ConnectServer (NULL, NULL, NULL, NULL,
|
|
bsLocale, bsAuthority, 0, NULL, &pISWbemServices)) )
|
|
{
|
|
SecureProxy (authnSpecified, eAuthLevel, impSpecified, eImpersonLevel, pISWbemServices);
|
|
hr = CreatePointerMoniker(pISWbemServices, ppmk);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Check the path to see if we are dealing with a class or an instance.
|
|
* Note that we construct the parser with a flag indicating that relative
|
|
* namespace paths are OK (not the default behavior).
|
|
*/
|
|
CWbemPathCracker pathCracker (szDisplayName + *pchEaten);
|
|
|
|
if (CWbemPathCracker::WbemPathType::wbemPathTypeError != pathCracker.GetType ())
|
|
{
|
|
CComBSTR bsNamespacePath, bsServerPath;
|
|
|
|
if (pathCracker.GetNamespacePath (bsNamespacePath)
|
|
&& pathCracker.GetServer (bsServerPath))
|
|
{
|
|
// Success - begin by connecting to the namespace.
|
|
CComPtr<ISWbemServices> pISWbemServices;
|
|
|
|
if (SUCCEEDED( hr = pISWbemLocator->ConnectServer (bsServerPath,
|
|
bsNamespacePath, NULL, NULL, bsLocale, bsAuthority, 0, NULL, &pISWbemServices)) )
|
|
{
|
|
// Secure the proxy using the specified security settings (if any)
|
|
SecureProxy (authnSpecified, eAuthLevel, impSpecified, eImpersonLevel, pISWbemServices);
|
|
|
|
// Successful connection - now work out if we have a class or instance
|
|
// component.
|
|
if (pathCracker.IsClassOrInstance())
|
|
{
|
|
CComPtr<ISWbemObject> pISWbemObject;
|
|
|
|
// Now get it
|
|
CComBSTR bsRelPath;
|
|
|
|
if (pathCracker.GetPathText (bsRelPath, true))
|
|
{
|
|
long lFlags = 0;
|
|
|
|
// Note that when we retrieve the object we will retrieve
|
|
// the localized version if a locale was specified in the moniker
|
|
if ((NULL != bsLocale) && (0 < wcslen (bsLocale)))
|
|
lFlags |= wbemFlagUseAmendedQualifiers;
|
|
|
|
if (SUCCEEDED( hr = pISWbemServices->Get (bsRelPath,
|
|
lFlags, NULL, &pISWbemObject)) )
|
|
hr = CreatePointerMoniker (pISWbemObject, ppmk);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Just a namespace
|
|
hr = CreatePointerMoniker(pISWbemServices, ppmk);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX; // Parse failure - abandon ship
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX; // Parse failure - abandon ship
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Parse failure
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
}
|
|
|
|
SysFreeString (bsLocale);
|
|
}
|
|
}
|
|
|
|
SysFreeString (bsAuthority);
|
|
|
|
if (FAILED (hr))
|
|
*pchEaten = 0;
|
|
else
|
|
*pchEaten = wcslen(szDisplayName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseSecurity
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take an authentication and impersonlation level string as described by the
|
|
// non-terminal authAndImpersonLevel and parse it into the authentication
|
|
// and impersonation levels
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// authnSpecified Whether the Moniker specifies a non-default
|
|
// authn levl
|
|
// lpeAuthLevel The authentication level parsed. This is one of
|
|
// enum WbemAuthenticationLevelEnum.
|
|
// impSpecified Whether the Moniker specifies a non-default imp
|
|
// level
|
|
// lpeImpersonLevel The impersonation level parsed. This is one of
|
|
// enum WbemImpersonationLevelEnum.
|
|
// privilegeSet On return contains the specified privileges
|
|
// bsAuthority On return contains the specified authority
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful. The lpeAuthLevel and
|
|
// lpeImpersonLevel arguments have valid data.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseSecurity (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
bool &authnSpecified,
|
|
enum WbemAuthenticationLevelEnum *lpeAuthLevel,
|
|
bool &impSpecified,
|
|
enum WbemImpersonationLevelEnum *lpeImpersonLevel,
|
|
CSWbemPrivilegeSet &privilegeSet,
|
|
BSTR &bsAuthority)
|
|
{
|
|
bool status = false;
|
|
|
|
// Set the default authentication and impersonation levels.
|
|
*lpeAuthLevel = wbemAuthenticationLevelNone;
|
|
*lpeImpersonLevel = wbemImpersonationLevelImpersonate;
|
|
|
|
// Initialize the number of consumed characters
|
|
*pchEaten = 0;
|
|
|
|
// Parse the contents
|
|
|
|
if (ParseAuthAndImpersonLevel (lpszInputString, pchEaten, authnSpecified, lpeAuthLevel,
|
|
impSpecified, lpeImpersonLevel, privilegeSet, bsAuthority))
|
|
status = true;
|
|
else
|
|
*pchEaten = 0;
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseLocale
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take locale setting string as described by the non-terminal localeSetting
|
|
// and parse it.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// bsLocale Reference to BSTR to hold parsed locale setting
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseLocale (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
BSTR &bsLocale)
|
|
{
|
|
bool status = true;
|
|
|
|
// Initialize the number of consumed characters
|
|
*pchEaten = 0;
|
|
|
|
// The first character should be '[' - if not we are done
|
|
if (0 == _wcsnicmp (lpszInputString, WBEMS_LEFT_SQBRK, wcslen (WBEMS_LEFT_SQBRK)))
|
|
{
|
|
status = false;
|
|
|
|
*pchEaten += wcslen (WBEMS_LEFT_SQBRK);
|
|
|
|
// Parse the locale setting
|
|
SKIPWHITESPACE
|
|
|
|
// The next string should be "locale"
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_LOCALE, wcslen(WBEMS_LOCALE)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_LOCALE);
|
|
|
|
SKIPWHITESPACE
|
|
|
|
// Next should be "="
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EQUALS, wcslen(WBEMS_EQUALS)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_EQUALS);
|
|
|
|
SKIPWHITESPACE
|
|
|
|
// Now we should have a character not equal to "]" (i.e. must specify locale ID string)
|
|
if (0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
|
|
{
|
|
// Consume everything up to the next space or "]"
|
|
LPWSTR cStr = CURRENTSTR;
|
|
ULONG lEaten = 0; // How many characters we consume
|
|
ULONG lLocale = 0; // The actual length of the locale ID
|
|
|
|
while (*(cStr + lEaten))
|
|
{
|
|
if (_istspace(*(cStr + lEaten)))
|
|
{
|
|
lEaten++;
|
|
|
|
// Hit white space - now skip until we find the "]"
|
|
SKIPWHITESPACE
|
|
|
|
// Now we must have a "]"
|
|
if (0 == _wcsnicmp
|
|
(cStr + lEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
|
|
{
|
|
// Success - we are done
|
|
lEaten += wcslen (WBEMS_RIGHT_SQBRK);
|
|
}
|
|
|
|
break;
|
|
}
|
|
else if (0 == _wcsnicmp (cStr + lEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
|
|
{
|
|
// Hit closing "]" - we are done
|
|
lEaten += wcslen (WBEMS_RIGHT_SQBRK);
|
|
break;
|
|
}
|
|
else // Consumed a locale character - keep on truckin'
|
|
{
|
|
lLocale++;
|
|
lEaten++;
|
|
}
|
|
}
|
|
|
|
// If we terminated correctly, save the locale setting
|
|
if ((lEaten > 1) && (lLocale > 0))
|
|
{
|
|
status = true;
|
|
|
|
LPWSTR pLocaleStr = new WCHAR [lLocale + 1];
|
|
|
|
if (pLocaleStr)
|
|
{
|
|
wcsncpy (pLocaleStr, lpszInputString + *pchEaten, lLocale);
|
|
pLocaleStr [lLocale] = NULL;
|
|
bsLocale = SysAllocString (pLocaleStr);
|
|
|
|
delete [] pLocaleStr;
|
|
*pchEaten += lEaten;
|
|
}
|
|
else
|
|
status = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!status)
|
|
*pchEaten = 0;
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseAuthAndImpersonLevel
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take an authentication/impersonlation/authority level string as described by the
|
|
// non-terminal authAndImpersonLevel and parse it into the authentication
|
|
// and impersonation levels and the authority string
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// authnSpecified Whether the Moniker specifies a non-default
|
|
// authn levl
|
|
// lpeAuthLevel The authentication level parsed. This is one of
|
|
// enum WbemAuthenticationLevelEnum.
|
|
// impSpecified Whether the Moniker specifies a non-default imp
|
|
// level
|
|
// lpeImpersonLevel The impersonation level parsed. This is one of
|
|
// enum WbemImpersonationLevelEnum.
|
|
// privilegeSet On return holds the privileges
|
|
// bsAuthority On retunr holds the authority string (if any)
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful. The lpeAuthLevel and
|
|
// lpeImpersonLevel arguments have valid data.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseAuthAndImpersonLevel (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
bool &authnSpecified,
|
|
enum WbemAuthenticationLevelEnum *lpeAuthLevel,
|
|
bool &impSpecified,
|
|
enum WbemImpersonationLevelEnum *lpeImpersonLevel,
|
|
CSWbemPrivilegeSet &privilegeSet,
|
|
BSTR &bsAuthority)
|
|
{
|
|
// The first character should be '{'
|
|
if (0 != _wcsnicmp (lpszInputString, WBEMS_LEFT_CURLY, wcslen (WBEMS_LEFT_CURLY)))
|
|
return FALSE;
|
|
else
|
|
*pchEaten += wcslen (WBEMS_LEFT_CURLY);
|
|
|
|
bool authoritySpecified = false;
|
|
bool privilegeSpecified = false;
|
|
bool done = false;
|
|
bool error = false;
|
|
|
|
while (!done)
|
|
{
|
|
bool parsingAuthenticationLevel = false; // Which token are we parsing?
|
|
bool parsingPrivilegeSet = false;
|
|
bool parsingAuthority = false;
|
|
|
|
SKIPWHITESPACE
|
|
|
|
// The next string should be one of "authenticationLevel", "impersonationLevel",
|
|
// "authority", the privilege collection start marker "(", or the security
|
|
// descriptor start marker "<"
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_LEVEL, wcslen(WBEMS_AUTH_LEVEL)))
|
|
{
|
|
// Error if we have already parsed this or have parsed privilege set
|
|
if (authnSpecified || privilegeSpecified)
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
parsingAuthenticationLevel = true;
|
|
*pchEaten += wcslen (WBEMS_AUTH_LEVEL);
|
|
}
|
|
}
|
|
else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_LEVEL, wcslen(WBEMS_IMPERSON_LEVEL)))
|
|
{
|
|
// Error if we have already parsed this or have parsed privilege set
|
|
if (impSpecified || privilegeSpecified)
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
*pchEaten += wcslen (WBEMS_IMPERSON_LEVEL) ;
|
|
}
|
|
else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTHORITY, wcslen(WBEMS_AUTHORITY)))
|
|
{
|
|
// Error if we have already parsed this or have parsed privilege set
|
|
if (authoritySpecified || privilegeSpecified)
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
parsingAuthority = true;
|
|
*pchEaten += wcslen (WBEMS_AUTHORITY) ;
|
|
}
|
|
}
|
|
else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_LEFT_PAREN, wcslen(WBEMS_LEFT_PAREN)))
|
|
{
|
|
// Error if we have already done this
|
|
if (privilegeSpecified)
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
parsingPrivilegeSet = true;
|
|
*pchEaten += wcslen (WBEMS_LEFT_PAREN);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Unrecognized token or NULL
|
|
error = true;
|
|
break;
|
|
}
|
|
|
|
// Getting here means we have something to parse
|
|
SKIPWHITESPACE
|
|
|
|
if (parsingPrivilegeSet)
|
|
{
|
|
ULONG chEaten = 0;
|
|
|
|
if (ParsePrivilegeSet (lpszInputString + *pchEaten, &chEaten, privilegeSet))
|
|
{
|
|
privilegeSpecified = true;
|
|
*pchEaten += chEaten;
|
|
|
|
// If the next token is "}" we are done
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen(WBEMS_RIGHT_CURLY)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_RIGHT_CURLY);
|
|
done = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Parsing authentication, impersonation or authority. The next character should be '='
|
|
if(0 != _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EQUALS, wcslen(WBEMS_EQUALS)))
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*pchEaten += wcslen (WBEMS_EQUALS);
|
|
SKIPWHITESPACE
|
|
|
|
if (parsingAuthenticationLevel)
|
|
{
|
|
if (!ParseAuthenticationLevel (lpszInputString, pchEaten, lpeAuthLevel))
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
authnSpecified = true;
|
|
}
|
|
else if (parsingAuthority)
|
|
{
|
|
// Get the authority string
|
|
if (!ParseAuthority (lpszInputString, pchEaten, bsAuthority))
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
authoritySpecified = true;
|
|
}
|
|
else
|
|
{
|
|
// Must be parsing impersonation level
|
|
|
|
if (!ParseImpersonationLevel (lpszInputString, pchEaten, lpeImpersonLevel))
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
impSpecified = true;
|
|
}
|
|
|
|
SKIPWHITESPACE
|
|
|
|
// The next token should be "}" or ","
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen(WBEMS_RIGHT_CURLY)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_RIGHT_CURLY);
|
|
done = true;
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_COMMA, wcslen(WBEMS_COMMA)))
|
|
{
|
|
// If we have parsed all expected tokens this is an error
|
|
if (authnSpecified && impSpecified && authoritySpecified && privilegeSpecified)
|
|
{
|
|
error = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*pchEaten += wcslen (WBEMS_COMMA);
|
|
// Loop round again for the next token
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Unrecognized token
|
|
error = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (error)
|
|
{
|
|
impSpecified = authnSpecified = false;
|
|
*pchEaten = 0;
|
|
return false;
|
|
}
|
|
|
|
return true; // success
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseImpersonationLevel
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Parse the string specification of an impersonation level into a
|
|
// symbolic constant value.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// lpeImpersonLevel The impersonation level parsed. This is one of
|
|
// enum WbemImpersonationLevelEnum.
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful. The lpeImpersonLevel
|
|
// argument has valid data.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseImpersonationLevel (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
enum WbemImpersonationLevelEnum *lpeImpersonLevel
|
|
)
|
|
{
|
|
bool status = true;
|
|
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_ANON, wcslen(WBEMS_IMPERSON_ANON)))
|
|
{
|
|
*lpeImpersonLevel = wbemImpersonationLevelAnonymous;
|
|
*pchEaten += wcslen (WBEMS_IMPERSON_ANON);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_IDENTIFY, wcslen(WBEMS_IMPERSON_IDENTIFY)))
|
|
{
|
|
*lpeImpersonLevel = wbemImpersonationLevelIdentify;
|
|
*pchEaten += wcslen (WBEMS_IMPERSON_IDENTIFY);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_IMPERSON, wcslen(WBEMS_IMPERSON_IMPERSON)))
|
|
{
|
|
*lpeImpersonLevel = wbemImpersonationLevelImpersonate;
|
|
*pchEaten += wcslen (WBEMS_IMPERSON_IMPERSON);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_DELEGATE, wcslen(WBEMS_IMPERSON_DELEGATE)))
|
|
{
|
|
*lpeImpersonLevel = wbemImpersonationLevelDelegate;
|
|
*pchEaten += wcslen (WBEMS_IMPERSON_DELEGATE);
|
|
}
|
|
else
|
|
status = false;
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseAuthenticationLevel
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Parse the string specification of an authentication level into a
|
|
// symbolic constant value.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// lpeAuthLevel The authentication level parsed. This is one of
|
|
// enum WbemAuthenticationLevelEnum.
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful. The lpeAuthLevel
|
|
// argument has valid data.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseAuthenticationLevel (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
enum WbemAuthenticationLevelEnum *lpeAuthLevel
|
|
)
|
|
{
|
|
bool status = true;
|
|
|
|
if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_DEFAULT, wcslen(WBEMS_AUTH_DEFAULT)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelDefault;
|
|
*pchEaten += wcslen (WBEMS_AUTH_DEFAULT);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_NONE, wcslen(WBEMS_AUTH_NONE)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelNone;
|
|
*pchEaten += wcslen (WBEMS_AUTH_NONE);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_CONNECT, wcslen(WBEMS_AUTH_CONNECT)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelConnect;
|
|
*pchEaten += wcslen (WBEMS_AUTH_CONNECT);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_CALL, wcslen(WBEMS_AUTH_CALL)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelCall;
|
|
*pchEaten += wcslen (WBEMS_AUTH_CALL);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT_INT, wcslen(WBEMS_AUTH_PKT_INT)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelPktIntegrity;
|
|
*pchEaten += wcslen (WBEMS_AUTH_PKT_INT);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT_PRIV, wcslen(WBEMS_AUTH_PKT_PRIV)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelPktPrivacy;
|
|
*pchEaten += wcslen (WBEMS_AUTH_PKT_PRIV);
|
|
}
|
|
else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT, wcslen(WBEMS_AUTH_PKT)))
|
|
{
|
|
*lpeAuthLevel = wbemAuthenticationLevelPkt;
|
|
*pchEaten += wcslen (WBEMS_AUTH_PKT);
|
|
}
|
|
else
|
|
status = false;
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParseAuthority
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take authority setting string as described by the non-terminal localeSetting
|
|
// and parse it.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// bsAuthority Reference to BSTR to hold parsed authority string
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParseAuthority (
|
|
LPWSTR lpszInputString,
|
|
ULONG* pchEaten,
|
|
BSTR &bsAuthority)
|
|
{
|
|
bool status = false;
|
|
|
|
// Now we should have a character not equal to "," or "}" (i.e. must specify authority string)
|
|
if ((0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_COMMA, wcslen (WBEMS_COMMA))) &&
|
|
(0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen (WBEMS_RIGHT_CURLY))))
|
|
{
|
|
// Consume everything up to the next space, "," or "]"
|
|
LPWSTR cStr = CURRENTSTR;
|
|
ULONG lEaten = 0; // Number of characters consumed
|
|
ULONG lAuthority = 0; // Actual length of the authority string
|
|
|
|
while (*(cStr + lEaten))
|
|
{
|
|
if (_istspace(*(cStr + lEaten)))
|
|
{
|
|
// Hit white space - stop now
|
|
break;
|
|
}
|
|
else if ((0 == _wcsnicmp (cStr + lEaten, WBEMS_RIGHT_CURLY, wcslen (WBEMS_RIGHT_CURLY))) ||
|
|
(0 == _wcsnicmp (cStr + lEaten, WBEMS_COMMA, wcslen (WBEMS_COMMA))))
|
|
{
|
|
// Hit closing "}" or "," - we are done; unpop the "}" or "," as that will be handled
|
|
// in the calling function
|
|
break;
|
|
}
|
|
else // Keep on truckin'
|
|
{
|
|
lAuthority++;
|
|
lEaten++;
|
|
}
|
|
}
|
|
|
|
// If we terminated correctly, save the locale setting
|
|
if ((lEaten > 1) && (lAuthority > 0))
|
|
{
|
|
status = true;
|
|
|
|
LPWSTR pAuthorityStr = new WCHAR [lAuthority + 1];
|
|
|
|
if (pAuthorityStr)
|
|
{
|
|
wcsncpy (pAuthorityStr, lpszInputString + *pchEaten, lAuthority);
|
|
pAuthorityStr [lAuthority] = NULL;
|
|
bsAuthority = SysAllocString (pAuthorityStr);
|
|
|
|
delete [] pAuthorityStr;
|
|
*pchEaten += lEaten;
|
|
}
|
|
else
|
|
status = false;
|
|
}
|
|
}
|
|
|
|
if (!status)
|
|
*pchEaten = 0;
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::ParsePrivilegeSet
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Parse the string specification of privilege settings.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// lpszInputString The string to be parsed
|
|
// pchEaten On return identifies how much of the DN has been
|
|
// consumed
|
|
// privilegeSet The container into which the parsed privileges
|
|
// are stored.
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
// TRUE Parsing was successful.
|
|
// FALSE Parsing failed.
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
bool CWbemParseDN::ParsePrivilegeSet (
|
|
LPWSTR lpszInputString,
|
|
ULONG *pchEaten,
|
|
CSWbemPrivilegeSet &privilegeSet
|
|
)
|
|
{
|
|
// We have consumed the initial "(". Now we are looking for
|
|
// a list of privileges, followed by a final ")"
|
|
|
|
bool status = true;
|
|
ULONG chEaten = *pchEaten; // In case we need to roll back
|
|
bool done = false;
|
|
bool firstPrivilege = true;
|
|
|
|
SKIPWHITESPACE
|
|
|
|
while (!done)
|
|
{
|
|
VARIANT_BOOL bEnabled = VARIANT_TRUE;
|
|
|
|
// If not the first privilege we are expecting a ","
|
|
if (!firstPrivilege)
|
|
{
|
|
if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_COMMA, wcslen(WBEMS_COMMA)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_COMMA);
|
|
SKIPWHITESPACE
|
|
}
|
|
else
|
|
{
|
|
status = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Next token may be a "!" to indicate a disabled privilege
|
|
if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EXCLAMATION, wcslen(WBEMS_EXCLAMATION)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_EXCLAMATION);
|
|
bEnabled = VARIANT_FALSE;
|
|
SKIPWHITESPACE
|
|
}
|
|
|
|
// Next token must be a valid privilege moniker name
|
|
WbemPrivilegeEnum iPrivilege;
|
|
|
|
if (CSWbemPrivilege::GetIdFromMonikerName (lpszInputString + *pchEaten, iPrivilege))
|
|
{
|
|
ISWbemPrivilege *pDummy = NULL;
|
|
|
|
if (SUCCEEDED (privilegeSet.Add (iPrivilege, bEnabled, &pDummy)))
|
|
{
|
|
*pchEaten += wcslen (CSWbemPrivilege::GetMonikerNameFromId (iPrivilege));
|
|
pDummy->Release ();
|
|
}
|
|
else
|
|
{
|
|
status = false;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Didn't recognize the privilege name
|
|
status = false;
|
|
break;
|
|
}
|
|
|
|
SKIPWHITESPACE
|
|
|
|
// Finally if we meet a ")" we are truly done with no error
|
|
if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_PAREN, wcslen(WBEMS_RIGHT_PAREN)))
|
|
{
|
|
*pchEaten += wcslen (WBEMS_RIGHT_PAREN);
|
|
done = true;
|
|
SKIPWHITESPACE
|
|
}
|
|
|
|
firstPrivilege = false;
|
|
SKIPWHITESPACE
|
|
}
|
|
|
|
if (!status)
|
|
{
|
|
// Misery - blow away any privileges we might have accrued
|
|
*pchEaten = chEaten;
|
|
privilegeSet.DeleteAll ();
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::GetSecurityString
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take an authentication and impersonlation level and convert it into
|
|
// a security specifier string.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// authnSpecified Whether a nondefault authn levl is specified.
|
|
// authnLevel The authentication level.
|
|
// impSpecified Whether a non-default imp level is specified.
|
|
// impLevel The impersonation level.
|
|
// privilegeSet Privileges
|
|
// bsAuthority Authority
|
|
//
|
|
//
|
|
// RETURN VALUES:
|
|
// the newly created string (which the caller must free) or NULL
|
|
//
|
|
//***************************************************************************
|
|
|
|
wchar_t *CWbemParseDN::GetSecurityString (
|
|
bool authnSpecified,
|
|
enum WbemAuthenticationLevelEnum authnLevel,
|
|
bool impSpecified,
|
|
enum WbemImpersonationLevelEnum impLevel,
|
|
CSWbemPrivilegeSet &privilegeSet,
|
|
BSTR &bsAuthority
|
|
)
|
|
{
|
|
wchar_t *pResult = NULL;
|
|
long lPrivilegeCount = 0;
|
|
privilegeSet.get_Count (&lPrivilegeCount);
|
|
ULONG lNumDisabled = privilegeSet.GetNumberOfDisabledElements ();
|
|
PrivilegeMap privMap = privilegeSet.GetPrivilegeMap ();
|
|
bool authoritySpecified = ((NULL != bsAuthority) && (0 < wcslen (bsAuthority)));
|
|
|
|
// Degenerate case - no security info
|
|
if (!authnSpecified && !impSpecified && (0 == lPrivilegeCount)
|
|
&& !authoritySpecified)
|
|
return NULL;
|
|
|
|
// Must have at least these 2 tokens
|
|
size_t len = wcslen (WBEMS_LEFT_CURLY) + wcslen (WBEMS_RIGHT_CURLY);
|
|
|
|
if (authnSpecified)
|
|
{
|
|
len += wcslen(WBEMS_AUTH_LEVEL) + wcslen (WBEMS_EQUALS);
|
|
|
|
switch (authnLevel)
|
|
{
|
|
case wbemAuthenticationLevelDefault:
|
|
len += wcslen (WBEMS_AUTH_DEFAULT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelNone:
|
|
len += wcslen (WBEMS_AUTH_NONE);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelConnect:
|
|
len += wcslen (WBEMS_AUTH_CONNECT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelCall:
|
|
len += wcslen (WBEMS_AUTH_CALL);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPkt:
|
|
len += wcslen (WBEMS_AUTH_PKT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPktIntegrity:
|
|
len += wcslen (WBEMS_AUTH_PKT_INT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPktPrivacy:
|
|
len += wcslen (WBEMS_AUTH_PKT_PRIV);
|
|
break;
|
|
|
|
default:
|
|
return NULL; // Bad level
|
|
}
|
|
|
|
if (impSpecified || authoritySpecified)
|
|
len += wcslen (WBEMS_COMMA);
|
|
}
|
|
|
|
if (impSpecified)
|
|
{
|
|
len += wcslen(WBEMS_IMPERSON_LEVEL) + wcslen (WBEMS_EQUALS);
|
|
|
|
switch (impLevel)
|
|
{
|
|
case wbemImpersonationLevelAnonymous:
|
|
len += wcslen (WBEMS_IMPERSON_ANON);
|
|
break;
|
|
|
|
case wbemImpersonationLevelIdentify:
|
|
len += wcslen (WBEMS_IMPERSON_IDENTIFY);
|
|
break;
|
|
|
|
case wbemImpersonationLevelImpersonate:
|
|
len += wcslen (WBEMS_IMPERSON_IMPERSON);
|
|
break;
|
|
|
|
case wbemImpersonationLevelDelegate:
|
|
len += wcslen (WBEMS_IMPERSON_DELEGATE);
|
|
break;
|
|
|
|
default:
|
|
return NULL; // Bad level
|
|
}
|
|
|
|
if (authoritySpecified)
|
|
len += wcslen (WBEMS_COMMA);
|
|
}
|
|
|
|
if (authoritySpecified)
|
|
len += wcslen(WBEMS_AUTHORITY) + wcslen (WBEMS_EQUALS) + wcslen (bsAuthority);
|
|
|
|
if (0 < lPrivilegeCount)
|
|
{
|
|
// If imp, authn or authority also specified, we need another separator
|
|
if (authnSpecified || impSpecified || authoritySpecified)
|
|
len += wcslen (WBEMS_COMMA);
|
|
|
|
// Need these boundary tokens
|
|
len += wcslen (WBEMS_LEFT_PAREN) + wcslen (WBEMS_RIGHT_PAREN);
|
|
|
|
// Need a separator between each privilege
|
|
if (1 < lPrivilegeCount)
|
|
len += (lPrivilegeCount - 1) * wcslen (WBEMS_COMMA);
|
|
|
|
// Need to specify false values with "!"
|
|
if (lNumDisabled)
|
|
len += lNumDisabled * wcslen (WBEMS_EXCLAMATION);
|
|
|
|
// Now add the privilege strings
|
|
PrivilegeMap::iterator next = privMap.begin ();
|
|
|
|
while (next != privMap.end ())
|
|
{
|
|
OLECHAR *sMonikerName = CSWbemPrivilege::GetMonikerNameFromId ((*next).first);
|
|
|
|
if (sMonikerName)
|
|
len += wcslen (sMonikerName);
|
|
|
|
next++;
|
|
}
|
|
}
|
|
|
|
pResult = new wchar_t [len + 1];
|
|
|
|
if (pResult)
|
|
{
|
|
// Now build the string
|
|
wcscpy (pResult, WBEMS_LEFT_CURLY);
|
|
|
|
if (authnSpecified)
|
|
{
|
|
wcscat (pResult, WBEMS_AUTH_LEVEL);
|
|
wcscat (pResult, WBEMS_EQUALS);
|
|
|
|
switch (authnLevel)
|
|
{
|
|
case wbemAuthenticationLevelDefault:
|
|
wcscat (pResult, WBEMS_AUTH_DEFAULT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelNone:
|
|
wcscat (pResult, WBEMS_AUTH_NONE);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelConnect:
|
|
wcscat (pResult, WBEMS_AUTH_CONNECT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelCall:
|
|
wcscat (pResult, WBEMS_AUTH_CALL);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPkt:
|
|
wcscat (pResult, WBEMS_AUTH_PKT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPktIntegrity:
|
|
wcscat (pResult, WBEMS_AUTH_PKT_INT);
|
|
break;
|
|
|
|
case wbemAuthenticationLevelPktPrivacy:
|
|
wcscat (pResult, WBEMS_AUTH_PKT_PRIV);
|
|
break;
|
|
}
|
|
|
|
if (impSpecified || authoritySpecified || (0 < lPrivilegeCount))
|
|
wcscat (pResult, WBEMS_COMMA);
|
|
}
|
|
|
|
if (impSpecified)
|
|
{
|
|
wcscat (pResult, WBEMS_IMPERSON_LEVEL);
|
|
wcscat (pResult, WBEMS_EQUALS);
|
|
|
|
switch (impLevel)
|
|
{
|
|
case wbemImpersonationLevelAnonymous:
|
|
wcscat (pResult, WBEMS_IMPERSON_ANON);
|
|
break;
|
|
|
|
case wbemImpersonationLevelIdentify:
|
|
wcscat (pResult, WBEMS_IMPERSON_IDENTIFY);
|
|
break;
|
|
|
|
case wbemImpersonationLevelImpersonate:
|
|
wcscat (pResult, WBEMS_IMPERSON_IMPERSON);
|
|
break;
|
|
|
|
case wbemImpersonationLevelDelegate:
|
|
wcscat (pResult, WBEMS_IMPERSON_DELEGATE);
|
|
break;
|
|
|
|
default:
|
|
return NULL; // Bad level
|
|
}
|
|
|
|
if (authoritySpecified || (0 < lPrivilegeCount))
|
|
wcscat (pResult, WBEMS_COMMA);
|
|
}
|
|
|
|
if (authoritySpecified)
|
|
{
|
|
wcscat (pResult, WBEMS_AUTHORITY);
|
|
wcscat (pResult, WBEMS_EQUALS);
|
|
wcscat (pResult, bsAuthority);
|
|
|
|
if ((0 < lPrivilegeCount))
|
|
wcscat (pResult, WBEMS_COMMA);
|
|
}
|
|
|
|
if (lPrivilegeCount)
|
|
{
|
|
wcscat (pResult, WBEMS_LEFT_PAREN);
|
|
|
|
// Now add the privilege strings
|
|
PrivilegeMap::iterator next = privMap.begin ();
|
|
bool firstPrivilege = true;
|
|
|
|
while (next != privMap.end ())
|
|
{
|
|
if (!firstPrivilege)
|
|
wcscat (pResult, WBEMS_COMMA);
|
|
|
|
firstPrivilege = false;
|
|
|
|
CSWbemPrivilege *pPrivilege = (*next).second;
|
|
VARIANT_BOOL bValue;
|
|
if (SUCCEEDED (pPrivilege->get_IsEnabled (&bValue)) &&
|
|
(VARIANT_FALSE == bValue))
|
|
wcscat (pResult, WBEMS_EXCLAMATION);
|
|
|
|
OLECHAR *sMonikerName = CSWbemPrivilege::GetMonikerNameFromId ((*next).first);
|
|
wcscat (pResult, sMonikerName);
|
|
|
|
next++;
|
|
}
|
|
|
|
wcscat (pResult, WBEMS_RIGHT_PAREN);
|
|
}
|
|
|
|
wcscat (pResult, WBEMS_RIGHT_CURLY);
|
|
|
|
pResult [len] = NULL;
|
|
}
|
|
|
|
return pResult;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// BOOLEAN CWbemParseDN::GetLocaleString
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Take a locale value and convert it into a locale specifier string.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// bsLocale The value (if any)
|
|
//
|
|
// RETURN VALUES:
|
|
// the newly created string (which the caller must free) or NULL
|
|
//
|
|
//***************************************************************************
|
|
|
|
wchar_t *CWbemParseDN::GetLocaleString (
|
|
BSTR bsLocale
|
|
)
|
|
{
|
|
wchar_t *pResult = NULL;
|
|
|
|
// Degenerate case - no locale info
|
|
if (!bsLocale || (0 == wcslen (bsLocale)))
|
|
return NULL;
|
|
|
|
// Calculate length of string
|
|
size_t len = wcslen (WBEMS_LEFT_SQBRK) + wcslen (WBEMS_LOCALE) +
|
|
wcslen (WBEMS_EQUALS) + wcslen (bsLocale) + wcslen (WBEMS_RIGHT_SQBRK);
|
|
|
|
pResult = new wchar_t [len + 1];
|
|
|
|
if (pResult)
|
|
{
|
|
// Now build the string
|
|
wcscpy (pResult, WBEMS_LEFT_SQBRK);
|
|
wcscat (pResult, WBEMS_LOCALE);
|
|
wcscat (pResult, WBEMS_EQUALS);
|
|
wcscat (pResult, bsLocale);
|
|
wcscat (pResult, WBEMS_RIGHT_SQBRK);
|
|
|
|
pResult [len] = NULL;
|
|
}
|
|
|
|
return pResult;
|
|
}
|
|
|
|
|
|
#undef CURRENTSTR
|
|
#undef SKIPWHITESPACE
|
|
|