Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1587 lines
41 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // File: parsedn.cxx
  6. //
  7. // Description :
  8. // Parses CIM paths to objects and returns the requested object
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #define CURRENTSTR (lpszInputString + *pchEaten)
  12. #define SKIPWHITESPACE \
  13. while (*CURRENTSTR && _istspace( *CURRENTSTR ) ) \
  14. (*pchEaten)++;
  15. #define WBEMS_STR_OWNER L"O"
  16. #define WBEMS_STR_GROUP L"G"
  17. #define WBEMS_STR_DACL L"D"
  18. #define WBEMS_STR_SACL L"S"
  19. static void SecureProxy (bool authnSpecified, enum WbemAuthenticationLevelEnum eAuthLevel,
  20. bool impSpecified, enum WbemImpersonationLevelEnum eImpersonLevel,
  21. ISWbemServices *pService)
  22. {
  23. // Secure the proxy using the specified security settings (if any)
  24. CComPtr<ISWbemSecurity> pSecurity;
  25. if (authnSpecified || impSpecified)
  26. {
  27. if (SUCCEEDED(pService->get_Security_(&pSecurity)))
  28. {
  29. if (authnSpecified)
  30. pSecurity->put_AuthenticationLevel (eAuthLevel);
  31. if (impSpecified)
  32. pSecurity->put_ImpersonationLevel (eImpersonLevel);
  33. }
  34. }
  35. }
  36. static void SecureProxy (bool authnSpecified, enum WbemAuthenticationLevelEnum eAuthLevel,
  37. bool impSpecified, enum WbemImpersonationLevelEnum eImpersonLevel,
  38. ISWbemObject *pObject)
  39. {
  40. // Secure the proxy using the specified security settings (if any)
  41. CComPtr<ISWbemSecurity> pSecurity;
  42. if (authnSpecified || impSpecified)
  43. {
  44. if (SUCCEEDED(pObject->get_Security_(&pSecurity)))
  45. {
  46. if (authnSpecified)
  47. pSecurity->put_AuthenticationLevel (eAuthLevel);
  48. if (impSpecified)
  49. pSecurity->put_ImpersonationLevel (eImpersonLevel);
  50. }
  51. }
  52. }
  53. //***************************************************************************
  54. //
  55. // CWbemParseDN::CWbemParseDN
  56. //
  57. // DESCRIPTION:
  58. //
  59. // Constructor.
  60. //
  61. //***************************************************************************
  62. CWbemParseDN::CWbemParseDN():
  63. m_cRef(0)
  64. {
  65. InterlockedIncrement(&g_cObj);
  66. }
  67. //***************************************************************************
  68. //
  69. // CWbemParseDN::~CWbemParseDN
  70. //
  71. // DESCRIPTION:
  72. //
  73. // Destructor.
  74. //
  75. //***************************************************************************
  76. CWbemParseDN::~CWbemParseDN(void)
  77. {
  78. InterlockedDecrement(&g_cObj);
  79. }
  80. //***************************************************************************
  81. // HRESULT CWbemParseDN::QueryInterface
  82. // long CWbemParseDN::AddRef
  83. // long CWbemParseDN::Release
  84. //
  85. // DESCRIPTION:
  86. //
  87. // Standard Com IUNKNOWN functions.
  88. //
  89. //***************************************************************************
  90. STDMETHODIMP CWbemParseDN::QueryInterface (
  91. IN REFIID riid,
  92. OUT LPVOID *ppv
  93. )
  94. {
  95. *ppv=NULL;
  96. if (IID_IUnknown==riid)
  97. *ppv = (IUnknown *)this;
  98. else if (IID_IParseDisplayName==riid)
  99. *ppv = (IParseDisplayName *)this;
  100. if (NULL!=*ppv)
  101. {
  102. ((LPUNKNOWN)*ppv)->AddRef();
  103. return NOERROR;
  104. }
  105. return E_NOINTERFACE;
  106. }
  107. STDMETHODIMP_(ULONG) CWbemParseDN::AddRef(void)
  108. {
  109. InterlockedIncrement(&m_cRef);
  110. return m_cRef;
  111. }
  112. STDMETHODIMP_(ULONG) CWbemParseDN::Release(void)
  113. {
  114. InterlockedDecrement(&m_cRef);
  115. if (0L!=m_cRef)
  116. return m_cRef;
  117. delete this;
  118. return 0;
  119. }
  120. //***************************************************************************
  121. //
  122. // SCODE CWbemParseDN::ParseDisplayName
  123. //
  124. // DESCRIPTION:
  125. //
  126. // Take a CIM object path and return a suitable ISWbem... object
  127. //
  128. // PARAMETERS:
  129. //
  130. // pCtx The binding context (not used)
  131. // szDisplayName The display name to be parsed
  132. // pchEaten On return identifies how much of the DN has been
  133. // consumed
  134. // ppmk On return will address the moniker pointer
  135. //
  136. // RETURN VALUES:
  137. //
  138. // E_FAIL misery
  139. //
  140. // Other CreateMoniker codes are returned.
  141. //
  142. //***************************************************************************
  143. STDMETHODIMP CWbemParseDN::ParseDisplayName(
  144. IBindCtx* pCtx,
  145. LPOLESTR szDisplayName,
  146. ULONG* pchEaten,
  147. IMoniker** ppmk)
  148. {
  149. HRESULT hr = E_FAIL;
  150. LPUNKNOWN pUnknown = NULL;
  151. ULONG lTemp = 0;
  152. enum WbemAuthenticationLevelEnum eAuthLevel;
  153. enum WbemImpersonationLevelEnum eImpersonLevel;
  154. bool authnSpecified = false;
  155. bool impSpecified = false;
  156. BSTR bsAuthority = NULL;
  157. //Check input parameters
  158. *ppmk = NULL;
  159. if (NULL != pchEaten)
  160. *pchEaten = 0;
  161. if (NULL == szDisplayName)
  162. return E_FAIL;
  163. /*
  164. * moniker : wmiMoniker
  165. *
  166. * wmiMoniker : ["winmgmts:" | "wmi:"] securitySetting ["[" localeSetting "]"] ["!" objectPath]
  167. * | ["winmgmts:" | "wmi:"] "[" localeSetting "]" ["!" objectPath]
  168. * | ["winmgmts:" | "wmi:"] [objectPath]
  169. * | [nativePath]
  170. *
  171. * localeSetting : "locale" <ows> "=" <ows> localeID
  172. *
  173. * localeID : a value of the form "ms_xxxx" where xxxx is a hex LCID value e.g. "ms_0x409".
  174. *
  175. * objectPath : a valid WMI Object Path
  176. *
  177. * securitySetting : "{" <ows> authAndImpersonSettings [<ows> "," <ows> privilegeOverrides]
  178. * | "{" <ows> authAndImpersonSettings [<ows> "," <ows> privilegeOverrides] <ows> "}" <ows>
  179. * | "{" <ows> privilegeOverrides <ows> "}" <ows>
  180. *
  181. *
  182. * authAndImpersonSettings :
  183. * authenticationLevel
  184. * | impersonationLevel
  185. * | authority
  186. * | authenticationLevel <ows> "," <ows> impersonationLevel [<ows> "," <ows> authority]
  187. * | authenticationLevel <ows> "," <ows> authority [<ows> "," <ows> impersonationLevel]
  188. * | impersonationLevel <ows> "," <ows> authenticationLevel [<ows> "," <ows> authority]
  189. * | impersonationLevel <ows> "," <ows> authority [<ows> "," <ows> authenticationLevel]
  190. * | authority <ows> "," <ows> impersonationLevel [<ows> "," <ows> authenticationLevel]
  191. * | authority <ows> "," <ows> authenticationLevel [<ows> "," <ows> impersonationLevel]
  192. *
  193. *
  194. * authority : "authority" <ows> "=" <ows> authorityValue
  195. *
  196. * authorityValue : Any valid WMI authority string e.g. "kerberos:mydomain\server" or "ntlmdomain:mydomain". Note that backslashes need to be escaped in JScript.
  197. *
  198. * authenticationLevel : "authenticationLevel" <ows> "=" <ows> authenticationValue
  199. *
  200. * authenticationValue : "default" | "none" | "connect" | "call" | "pkt" | "pktIntegrity" | "pktPrivacy"
  201. *
  202. * impersonationLevel : "impersonationLevel" <ows> "=" <ows> impersonationValue
  203. *
  204. * impersonationValue : "anonymous" | "identify" | "impersonate" | "delegate"
  205. *
  206. * privilegeOverrides : "(" <ows> privileges <ows> ")"
  207. *
  208. * privileges : privilege [<ows> "," <ows> privileges <ows>]*
  209. *
  210. * privilege : ["!"] privilegeName
  211. *
  212. * privilegeName : "CreateToken" | "PrimaryToken" | "LockMemory" | "IncreaseQuota"
  213. * | "MachineAccount" | "Tcb" | "Security" | "TakeOwnership"
  214. * | "LoadDriver" | "SystemProfile" | "SystemTime"
  215. * | "ProfileSingleProcess" | "IncreaseBasePriority"
  216. * | "CreatePagefile" | "CreatePermanent" | "Backup" | "Restore"
  217. * | "Shutdown" | "Debug" | "Audit" | "SystemEnvironment" | "ChangeNotify"
  218. * | "RemoteShutdown"
  219. *
  220. */
  221. // It had better start with our scheme name
  222. bool bCheckContext = false;
  223. if (0 == _wcsnicmp (szDisplayName, WBEMS_PDN_SCHEME, wcslen (WBEMS_PDN_SCHEME)))
  224. {
  225. *pchEaten += wcslen (WBEMS_PDN_SCHEME);
  226. bCheckContext = (pCtx && (wcslen (szDisplayName) == wcslen (WBEMS_PDN_SCHEME)));
  227. }
  228. else
  229. return E_FAIL;
  230. // One more check - if it was just the scheme and no more check for extra info in the context
  231. if (bCheckContext)
  232. {
  233. IUnknown *pUnk = NULL;
  234. if (SUCCEEDED (pCtx->GetObjectParam (L"WmiObject", &pUnk)) && pUnk)
  235. {
  236. // Is it an IWbemClassObject?
  237. IWbemClassObject *pIWbemClassObject = NULL;
  238. // Or is it an IWbemContext?
  239. IWbemContext *pIWbemContext = NULL;
  240. // Or is it an IWbemServices?
  241. IWbemServices *pIWbemServices = NULL;
  242. if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemClassObject, (void **) &pIWbemClassObject)))
  243. {
  244. CSWbemObject *pSWbemObject = new CSWbemObject (NULL, pIWbemClassObject);
  245. if (!pSWbemObject)
  246. hr = E_OUTOFMEMORY;
  247. else
  248. {
  249. CComPtr<ISWbemObjectEx> pISWbemObjectEx;
  250. if (SUCCEEDED (pSWbemObject->QueryInterface (IID_ISWbemObjectEx, (void **) &pISWbemObjectEx)))
  251. hr = CreatePointerMoniker (pISWbemObjectEx, ppmk);
  252. }
  253. pIWbemClassObject->Release ();
  254. }
  255. else if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemContext, (void **) &pIWbemContext)))
  256. {
  257. CSWbemNamedValueSet *pSWbemNamedValueSet = new CSWbemNamedValueSet (NULL, pIWbemContext);
  258. if (!pSWbemNamedValueSet)
  259. hr = E_OUTOFMEMORY;
  260. else
  261. {
  262. CComPtr<ISWbemNamedValueSet> pISWbemNamedValueSet;
  263. if (SUCCEEDED (pSWbemNamedValueSet->QueryInterface (IID_ISWbemNamedValueSet,
  264. (PPVOID)&pISWbemNamedValueSet)))
  265. hr = CreatePointerMoniker (pISWbemNamedValueSet, ppmk);
  266. }
  267. pIWbemContext->Release ();
  268. }
  269. else if (SUCCEEDED (pUnk->QueryInterface (IID_IWbemServices, (void **) &pIWbemServices)))
  270. {
  271. // In this case we must get passed the object path as well
  272. CComPtr<IUnknown> pUnkPath;
  273. if (SUCCEEDED (pCtx->GetObjectParam (L"WmiObjectPath", &pUnkPath)) && pUnkPath)
  274. {
  275. CComPtr<ISWbemObjectPath> pISWbemObjectPath;
  276. if (SUCCEEDED (pUnkPath->QueryInterface (IID_ISWbemObjectPath, (void **) &pISWbemObjectPath)))
  277. {
  278. // Dig the path out to initialize
  279. CComBSTR bsNamespace = NULL;
  280. pISWbemObjectPath->get_Path (&bsNamespace);
  281. CSWbemServices *pSWbemServices = new CSWbemServices (pIWbemServices,
  282. bsNamespace, (BSTR) NULL, NULL, NULL);
  283. if (!pSWbemServices)
  284. hr = E_OUTOFMEMORY;
  285. else
  286. {
  287. CComQIPtr<ISWbemServicesEx>
  288. pISWbemServicesEx (pSWbemServices);
  289. if (pISWbemServicesEx)
  290. hr = CreatePointerMoniker (pISWbemServicesEx, ppmk);
  291. }
  292. }
  293. }
  294. pIWbemServices->Release ();
  295. }
  296. pUnk->Release ();
  297. }
  298. // If this worked return now - o/w revert to regular parsing
  299. if (SUCCEEDED (hr))
  300. return hr;
  301. }
  302. // Check for the optional security info
  303. CSWbemPrivilegeSet privilegeSet;
  304. if (ParseSecurity(szDisplayName + *pchEaten, &lTemp, authnSpecified, &eAuthLevel,
  305. impSpecified, &eImpersonLevel, privilegeSet,
  306. bsAuthority))
  307. *pchEaten += lTemp;
  308. // If no impersonation level was specified, get the default from the registry
  309. if (!impSpecified)
  310. {
  311. eImpersonLevel = CSWbemSecurity::GetDefaultImpersonationLevel ();
  312. impSpecified = true;
  313. }
  314. // Create a locator
  315. CSWbemLocator *pCSWbemLocator = new CSWbemLocator(&privilegeSet);
  316. if (!pCSWbemLocator)
  317. hr = E_OUTOFMEMORY;
  318. else
  319. {
  320. CComQIPtr<ISWbemLocator> pISWbemLocator (pCSWbemLocator);
  321. if (pISWbemLocator)
  322. {
  323. // Parse the locale information (if present)
  324. lTemp = 0;
  325. BSTR bsLocale = NULL;
  326. if (ParseLocale (szDisplayName + *pchEaten, &lTemp, bsLocale))
  327. {
  328. *pchEaten += lTemp;
  329. // Skip over the "!" separator if there is one
  330. if(*(szDisplayName + *pchEaten) != NULL)
  331. if (0 == _wcsnicmp (szDisplayName + *pchEaten, WBEMS_EXCLAMATION, wcslen (WBEMS_EXCLAMATION)))
  332. *pchEaten += wcslen (WBEMS_EXCLAMATION);
  333. // Now ready to parse the path - check if we have the degenerate cases
  334. if (0 == wcslen (szDisplayName + *pchEaten))
  335. {
  336. // Need to return connection to default namespace on local machine
  337. CComPtr<ISWbemServices> pISWbemServices;
  338. if (SUCCEEDED( hr = pISWbemLocator->ConnectServer (NULL, NULL, NULL, NULL,
  339. bsLocale, bsAuthority, 0, NULL, &pISWbemServices)) )
  340. {
  341. SecureProxy (authnSpecified, eAuthLevel, impSpecified, eImpersonLevel, pISWbemServices);
  342. hr = CreatePointerMoniker(pISWbemServices, ppmk);
  343. }
  344. }
  345. else
  346. {
  347. /*
  348. * Check the path to see if we are dealing with a class or an instance.
  349. * Note that we construct the parser with a flag indicating that relative
  350. * namespace paths are OK (not the default behavior).
  351. */
  352. CWbemPathCracker pathCracker (szDisplayName + *pchEaten);
  353. if (CWbemPathCracker::WbemPathType::wbemPathTypeError != pathCracker.GetType ())
  354. {
  355. CComBSTR bsNamespacePath, bsServerPath;
  356. if (pathCracker.GetNamespacePath (bsNamespacePath)
  357. && pathCracker.GetServer (bsServerPath))
  358. {
  359. // Success - begin by connecting to the namespace.
  360. CComPtr<ISWbemServices> pISWbemServices;
  361. if (SUCCEEDED( hr = pISWbemLocator->ConnectServer (bsServerPath,
  362. bsNamespacePath, NULL, NULL, bsLocale, bsAuthority, 0, NULL, &pISWbemServices)) )
  363. {
  364. // Secure the proxy using the specified security settings (if any)
  365. SecureProxy (authnSpecified, eAuthLevel, impSpecified, eImpersonLevel, pISWbemServices);
  366. // Successful connection - now work out if we have a class or instance
  367. // component.
  368. if (pathCracker.IsClassOrInstance())
  369. {
  370. CComPtr<ISWbemObject> pISWbemObject;
  371. // Now get it
  372. CComBSTR bsRelPath;
  373. if (pathCracker.GetPathText (bsRelPath, true))
  374. {
  375. long lFlags = 0;
  376. // Note that when we retrieve the object we will retrieve
  377. // the localized version if a locale was specified in the moniker
  378. if ((NULL != bsLocale) && (0 < wcslen (bsLocale)))
  379. lFlags |= wbemFlagUseAmendedQualifiers;
  380. if (SUCCEEDED( hr = pISWbemServices->Get (bsRelPath,
  381. lFlags, NULL, &pISWbemObject)) )
  382. hr = CreatePointerMoniker (pISWbemObject, ppmk);
  383. }
  384. }
  385. else
  386. {
  387. // Just a namespace
  388. hr = CreatePointerMoniker(pISWbemServices, ppmk);
  389. }
  390. }
  391. }
  392. else
  393. hr = WBEM_E_INVALID_SYNTAX; // Parse failure - abandon ship
  394. }
  395. else
  396. hr = WBEM_E_INVALID_SYNTAX; // Parse failure - abandon ship
  397. }
  398. }
  399. else
  400. {
  401. // Parse failure
  402. hr = WBEM_E_INVALID_SYNTAX;
  403. }
  404. SysFreeString (bsLocale);
  405. }
  406. }
  407. SysFreeString (bsAuthority);
  408. if (FAILED (hr))
  409. *pchEaten = 0;
  410. else
  411. *pchEaten = wcslen(szDisplayName);
  412. return hr;
  413. }
  414. //***************************************************************************
  415. //
  416. // BOOLEAN CWbemParseDN::ParseSecurity
  417. //
  418. // DESCRIPTION:
  419. //
  420. // Take an authentication and impersonlation level string as described by the
  421. // non-terminal authAndImpersonLevel and parse it into the authentication
  422. // and impersonation levels
  423. //
  424. // PARAMETERS:
  425. //
  426. // lpszInputString The string to be parsed
  427. // pchEaten On return identifies how much of the DN has been
  428. // consumed
  429. // authnSpecified Whether the Moniker specifies a non-default
  430. // authn levl
  431. // lpeAuthLevel The authentication level parsed. This is one of
  432. // enum WbemAuthenticationLevelEnum.
  433. // impSpecified Whether the Moniker specifies a non-default imp
  434. // level
  435. // lpeImpersonLevel The impersonation level parsed. This is one of
  436. // enum WbemImpersonationLevelEnum.
  437. // privilegeSet On return contains the specified privileges
  438. // bsAuthority On return contains the specified authority
  439. //
  440. // RETURN VALUES:
  441. //
  442. // TRUE Parsing was successful. The lpeAuthLevel and
  443. // lpeImpersonLevel arguments have valid data.
  444. // FALSE Parsing failed.
  445. //
  446. //
  447. //***************************************************************************
  448. bool CWbemParseDN::ParseSecurity (
  449. LPWSTR lpszInputString,
  450. ULONG* pchEaten,
  451. bool &authnSpecified,
  452. enum WbemAuthenticationLevelEnum *lpeAuthLevel,
  453. bool &impSpecified,
  454. enum WbemImpersonationLevelEnum *lpeImpersonLevel,
  455. CSWbemPrivilegeSet &privilegeSet,
  456. BSTR &bsAuthority)
  457. {
  458. bool status = false;
  459. // Set the default authentication and impersonation levels.
  460. *lpeAuthLevel = wbemAuthenticationLevelNone;
  461. *lpeImpersonLevel = wbemImpersonationLevelImpersonate;
  462. // Initialize the number of consumed characters
  463. *pchEaten = 0;
  464. // Parse the contents
  465. if (ParseAuthAndImpersonLevel (lpszInputString, pchEaten, authnSpecified, lpeAuthLevel,
  466. impSpecified, lpeImpersonLevel, privilegeSet, bsAuthority))
  467. status = true;
  468. else
  469. *pchEaten = 0;
  470. return status;
  471. }
  472. //***************************************************************************
  473. //
  474. // BOOLEAN CWbemParseDN::ParseLocale
  475. //
  476. // DESCRIPTION:
  477. //
  478. // Take locale setting string as described by the non-terminal localeSetting
  479. // and parse it.
  480. //
  481. // PARAMETERS:
  482. //
  483. // lpszInputString The string to be parsed
  484. // pchEaten On return identifies how much of the DN has been
  485. // consumed
  486. // bsLocale Reference to BSTR to hold parsed locale setting
  487. //
  488. // RETURN VALUES:
  489. //
  490. // TRUE Parsing was successful.
  491. // FALSE Parsing failed.
  492. //
  493. //
  494. //***************************************************************************
  495. bool CWbemParseDN::ParseLocale (
  496. LPWSTR lpszInputString,
  497. ULONG* pchEaten,
  498. BSTR &bsLocale)
  499. {
  500. bool status = true;
  501. // Initialize the number of consumed characters
  502. *pchEaten = 0;
  503. // The first character should be '[' - if not we are done
  504. if (0 == _wcsnicmp (lpszInputString, WBEMS_LEFT_SQBRK, wcslen (WBEMS_LEFT_SQBRK)))
  505. {
  506. status = false;
  507. *pchEaten += wcslen (WBEMS_LEFT_SQBRK);
  508. // Parse the locale setting
  509. SKIPWHITESPACE
  510. // The next string should be "locale"
  511. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_LOCALE, wcslen(WBEMS_LOCALE)))
  512. {
  513. *pchEaten += wcslen (WBEMS_LOCALE);
  514. SKIPWHITESPACE
  515. // Next should be "="
  516. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EQUALS, wcslen(WBEMS_EQUALS)))
  517. {
  518. *pchEaten += wcslen (WBEMS_EQUALS);
  519. SKIPWHITESPACE
  520. // Now we should have a character not equal to "]" (i.e. must specify locale ID string)
  521. if (0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
  522. {
  523. // Consume everything up to the next space or "]"
  524. LPWSTR cStr = CURRENTSTR;
  525. ULONG lEaten = 0; // How many characters we consume
  526. ULONG lLocale = 0; // The actual length of the locale ID
  527. while (*(cStr + lEaten))
  528. {
  529. if (_istspace(*(cStr + lEaten)))
  530. {
  531. lEaten++;
  532. // Hit white space - now skip until we find the "]"
  533. SKIPWHITESPACE
  534. // Now we must have a "]"
  535. if (0 == _wcsnicmp
  536. (cStr + lEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
  537. {
  538. // Success - we are done
  539. lEaten += wcslen (WBEMS_RIGHT_SQBRK);
  540. }
  541. break;
  542. }
  543. else if (0 == _wcsnicmp (cStr + lEaten, WBEMS_RIGHT_SQBRK, wcslen (WBEMS_RIGHT_SQBRK)))
  544. {
  545. // Hit closing "]" - we are done
  546. lEaten += wcslen (WBEMS_RIGHT_SQBRK);
  547. break;
  548. }
  549. else // Consumed a locale character - keep on truckin'
  550. {
  551. lLocale++;
  552. lEaten++;
  553. }
  554. }
  555. // If we terminated correctly, save the locale setting
  556. if ((lEaten > 1) && (lLocale > 0))
  557. {
  558. status = true;
  559. LPWSTR pLocaleStr = new WCHAR [lLocale + 1];
  560. if (pLocaleStr)
  561. {
  562. wcsncpy (pLocaleStr, lpszInputString + *pchEaten, lLocale);
  563. pLocaleStr [lLocale] = NULL;
  564. bsLocale = SysAllocString (pLocaleStr);
  565. delete [] pLocaleStr;
  566. *pchEaten += lEaten;
  567. }
  568. else
  569. status = false;
  570. }
  571. }
  572. }
  573. }
  574. }
  575. if (!status)
  576. *pchEaten = 0;
  577. return status;
  578. }
  579. //***************************************************************************
  580. //
  581. // BOOLEAN CWbemParseDN::ParseAuthAndImpersonLevel
  582. //
  583. // DESCRIPTION:
  584. //
  585. // Take an authentication/impersonlation/authority level string as described by the
  586. // non-terminal authAndImpersonLevel and parse it into the authentication
  587. // and impersonation levels and the authority string
  588. //
  589. // PARAMETERS:
  590. //
  591. // lpszInputString The string to be parsed
  592. // pchEaten On return identifies how much of the DN has been
  593. // consumed
  594. // authnSpecified Whether the Moniker specifies a non-default
  595. // authn levl
  596. // lpeAuthLevel The authentication level parsed. This is one of
  597. // enum WbemAuthenticationLevelEnum.
  598. // impSpecified Whether the Moniker specifies a non-default imp
  599. // level
  600. // lpeImpersonLevel The impersonation level parsed. This is one of
  601. // enum WbemImpersonationLevelEnum.
  602. // privilegeSet On return holds the privileges
  603. // bsAuthority On retunr holds the authority string (if any)
  604. //
  605. // RETURN VALUES:
  606. //
  607. // TRUE Parsing was successful. The lpeAuthLevel and
  608. // lpeImpersonLevel arguments have valid data.
  609. // FALSE Parsing failed.
  610. //
  611. //
  612. //***************************************************************************
  613. bool CWbemParseDN::ParseAuthAndImpersonLevel (
  614. LPWSTR lpszInputString,
  615. ULONG* pchEaten,
  616. bool &authnSpecified,
  617. enum WbemAuthenticationLevelEnum *lpeAuthLevel,
  618. bool &impSpecified,
  619. enum WbemImpersonationLevelEnum *lpeImpersonLevel,
  620. CSWbemPrivilegeSet &privilegeSet,
  621. BSTR &bsAuthority)
  622. {
  623. // The first character should be '{'
  624. if (0 != _wcsnicmp (lpszInputString, WBEMS_LEFT_CURLY, wcslen (WBEMS_LEFT_CURLY)))
  625. return FALSE;
  626. else
  627. *pchEaten += wcslen (WBEMS_LEFT_CURLY);
  628. bool authoritySpecified = false;
  629. bool privilegeSpecified = false;
  630. bool done = false;
  631. bool error = false;
  632. while (!done)
  633. {
  634. bool parsingAuthenticationLevel = false; // Which token are we parsing?
  635. bool parsingPrivilegeSet = false;
  636. bool parsingAuthority = false;
  637. SKIPWHITESPACE
  638. // The next string should be one of "authenticationLevel", "impersonationLevel",
  639. // "authority", the privilege collection start marker "(", or the security
  640. // descriptor start marker "<"
  641. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_LEVEL, wcslen(WBEMS_AUTH_LEVEL)))
  642. {
  643. // Error if we have already parsed this or have parsed privilege set
  644. if (authnSpecified || privilegeSpecified)
  645. {
  646. error = true;
  647. break;
  648. }
  649. else
  650. {
  651. parsingAuthenticationLevel = true;
  652. *pchEaten += wcslen (WBEMS_AUTH_LEVEL);
  653. }
  654. }
  655. else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_LEVEL, wcslen(WBEMS_IMPERSON_LEVEL)))
  656. {
  657. // Error if we have already parsed this or have parsed privilege set
  658. if (impSpecified || privilegeSpecified)
  659. {
  660. error = true;
  661. break;
  662. }
  663. else
  664. *pchEaten += wcslen (WBEMS_IMPERSON_LEVEL) ;
  665. }
  666. else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTHORITY, wcslen(WBEMS_AUTHORITY)))
  667. {
  668. // Error if we have already parsed this or have parsed privilege set
  669. if (authoritySpecified || privilegeSpecified)
  670. {
  671. error = true;
  672. break;
  673. }
  674. else
  675. {
  676. parsingAuthority = true;
  677. *pchEaten += wcslen (WBEMS_AUTHORITY) ;
  678. }
  679. }
  680. else if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_LEFT_PAREN, wcslen(WBEMS_LEFT_PAREN)))
  681. {
  682. // Error if we have already done this
  683. if (privilegeSpecified)
  684. {
  685. error = true;
  686. break;
  687. }
  688. else
  689. {
  690. parsingPrivilegeSet = true;
  691. *pchEaten += wcslen (WBEMS_LEFT_PAREN);
  692. }
  693. }
  694. else
  695. {
  696. // Unrecognized token or NULL
  697. error = true;
  698. break;
  699. }
  700. // Getting here means we have something to parse
  701. SKIPWHITESPACE
  702. if (parsingPrivilegeSet)
  703. {
  704. ULONG chEaten = 0;
  705. if (ParsePrivilegeSet (lpszInputString + *pchEaten, &chEaten, privilegeSet))
  706. {
  707. privilegeSpecified = true;
  708. *pchEaten += chEaten;
  709. // If the next token is "}" we are done
  710. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen(WBEMS_RIGHT_CURLY)))
  711. {
  712. *pchEaten += wcslen (WBEMS_RIGHT_CURLY);
  713. done = true;
  714. }
  715. }
  716. else
  717. {
  718. error = true;
  719. break;
  720. }
  721. }
  722. else
  723. {
  724. // Parsing authentication, impersonation or authority. The next character should be '='
  725. if(0 != _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EQUALS, wcslen(WBEMS_EQUALS)))
  726. {
  727. error = true;
  728. break;
  729. }
  730. else
  731. {
  732. *pchEaten += wcslen (WBEMS_EQUALS);
  733. SKIPWHITESPACE
  734. if (parsingAuthenticationLevel)
  735. {
  736. if (!ParseAuthenticationLevel (lpszInputString, pchEaten, lpeAuthLevel))
  737. {
  738. error = true;
  739. break;
  740. }
  741. else
  742. authnSpecified = true;
  743. }
  744. else if (parsingAuthority)
  745. {
  746. // Get the authority string
  747. if (!ParseAuthority (lpszInputString, pchEaten, bsAuthority))
  748. {
  749. error = true;
  750. break;
  751. }
  752. else
  753. authoritySpecified = true;
  754. }
  755. else
  756. {
  757. // Must be parsing impersonation level
  758. if (!ParseImpersonationLevel (lpszInputString, pchEaten, lpeImpersonLevel))
  759. {
  760. error = true;
  761. break;
  762. }
  763. else
  764. impSpecified = true;
  765. }
  766. SKIPWHITESPACE
  767. // The next token should be "}" or ","
  768. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen(WBEMS_RIGHT_CURLY)))
  769. {
  770. *pchEaten += wcslen (WBEMS_RIGHT_CURLY);
  771. done = true;
  772. }
  773. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_COMMA, wcslen(WBEMS_COMMA)))
  774. {
  775. // If we have parsed all expected tokens this is an error
  776. if (authnSpecified && impSpecified && authoritySpecified && privilegeSpecified)
  777. {
  778. error = true;
  779. break;
  780. }
  781. else
  782. {
  783. *pchEaten += wcslen (WBEMS_COMMA);
  784. // Loop round again for the next token
  785. }
  786. }
  787. else
  788. {
  789. // Unrecognized token
  790. error = true;
  791. break;
  792. }
  793. }
  794. }
  795. }
  796. if (error)
  797. {
  798. impSpecified = authnSpecified = false;
  799. *pchEaten = 0;
  800. return false;
  801. }
  802. return true; // success
  803. }
  804. //***************************************************************************
  805. //
  806. // BOOLEAN CWbemParseDN::ParseImpersonationLevel
  807. //
  808. // DESCRIPTION:
  809. //
  810. // Parse the string specification of an impersonation level into a
  811. // symbolic constant value.
  812. //
  813. // PARAMETERS:
  814. //
  815. // lpszInputString The string to be parsed
  816. // pchEaten On return identifies how much of the DN has been
  817. // consumed
  818. // lpeImpersonLevel The impersonation level parsed. This is one of
  819. // enum WbemImpersonationLevelEnum.
  820. //
  821. // RETURN VALUES:
  822. //
  823. // TRUE Parsing was successful. The lpeImpersonLevel
  824. // argument has valid data.
  825. // FALSE Parsing failed.
  826. //
  827. //
  828. //***************************************************************************
  829. bool CWbemParseDN::ParseImpersonationLevel (
  830. LPWSTR lpszInputString,
  831. ULONG* pchEaten,
  832. enum WbemImpersonationLevelEnum *lpeImpersonLevel
  833. )
  834. {
  835. bool status = true;
  836. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_ANON, wcslen(WBEMS_IMPERSON_ANON)))
  837. {
  838. *lpeImpersonLevel = wbemImpersonationLevelAnonymous;
  839. *pchEaten += wcslen (WBEMS_IMPERSON_ANON);
  840. }
  841. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_IDENTIFY, wcslen(WBEMS_IMPERSON_IDENTIFY)))
  842. {
  843. *lpeImpersonLevel = wbemImpersonationLevelIdentify;
  844. *pchEaten += wcslen (WBEMS_IMPERSON_IDENTIFY);
  845. }
  846. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_IMPERSON, wcslen(WBEMS_IMPERSON_IMPERSON)))
  847. {
  848. *lpeImpersonLevel = wbemImpersonationLevelImpersonate;
  849. *pchEaten += wcslen (WBEMS_IMPERSON_IMPERSON);
  850. }
  851. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_IMPERSON_DELEGATE, wcslen(WBEMS_IMPERSON_DELEGATE)))
  852. {
  853. *lpeImpersonLevel = wbemImpersonationLevelDelegate;
  854. *pchEaten += wcslen (WBEMS_IMPERSON_DELEGATE);
  855. }
  856. else
  857. status = false;
  858. return status;
  859. }
  860. //***************************************************************************
  861. //
  862. // BOOLEAN CWbemParseDN::ParseAuthenticationLevel
  863. //
  864. // DESCRIPTION:
  865. //
  866. // Parse the string specification of an authentication level into a
  867. // symbolic constant value.
  868. //
  869. // PARAMETERS:
  870. //
  871. // lpszInputString The string to be parsed
  872. // pchEaten On return identifies how much of the DN has been
  873. // consumed
  874. // lpeAuthLevel The authentication level parsed. This is one of
  875. // enum WbemAuthenticationLevelEnum.
  876. //
  877. // RETURN VALUES:
  878. //
  879. // TRUE Parsing was successful. The lpeAuthLevel
  880. // argument has valid data.
  881. // FALSE Parsing failed.
  882. //
  883. //
  884. //***************************************************************************
  885. bool CWbemParseDN::ParseAuthenticationLevel (
  886. LPWSTR lpszInputString,
  887. ULONG* pchEaten,
  888. enum WbemAuthenticationLevelEnum *lpeAuthLevel
  889. )
  890. {
  891. bool status = true;
  892. if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_DEFAULT, wcslen(WBEMS_AUTH_DEFAULT)))
  893. {
  894. *lpeAuthLevel = wbemAuthenticationLevelDefault;
  895. *pchEaten += wcslen (WBEMS_AUTH_DEFAULT);
  896. }
  897. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_NONE, wcslen(WBEMS_AUTH_NONE)))
  898. {
  899. *lpeAuthLevel = wbemAuthenticationLevelNone;
  900. *pchEaten += wcslen (WBEMS_AUTH_NONE);
  901. }
  902. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_CONNECT, wcslen(WBEMS_AUTH_CONNECT)))
  903. {
  904. *lpeAuthLevel = wbemAuthenticationLevelConnect;
  905. *pchEaten += wcslen (WBEMS_AUTH_CONNECT);
  906. }
  907. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_CALL, wcslen(WBEMS_AUTH_CALL)))
  908. {
  909. *lpeAuthLevel = wbemAuthenticationLevelCall;
  910. *pchEaten += wcslen (WBEMS_AUTH_CALL);
  911. }
  912. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT_INT, wcslen(WBEMS_AUTH_PKT_INT)))
  913. {
  914. *lpeAuthLevel = wbemAuthenticationLevelPktIntegrity;
  915. *pchEaten += wcslen (WBEMS_AUTH_PKT_INT);
  916. }
  917. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT_PRIV, wcslen(WBEMS_AUTH_PKT_PRIV)))
  918. {
  919. *lpeAuthLevel = wbemAuthenticationLevelPktPrivacy;
  920. *pchEaten += wcslen (WBEMS_AUTH_PKT_PRIV);
  921. }
  922. else if(0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_AUTH_PKT, wcslen(WBEMS_AUTH_PKT)))
  923. {
  924. *lpeAuthLevel = wbemAuthenticationLevelPkt;
  925. *pchEaten += wcslen (WBEMS_AUTH_PKT);
  926. }
  927. else
  928. status = false;
  929. return status;
  930. }
  931. //***************************************************************************
  932. //
  933. // BOOLEAN CWbemParseDN::ParseAuthority
  934. //
  935. // DESCRIPTION:
  936. //
  937. // Take authority setting string as described by the non-terminal localeSetting
  938. // and parse it.
  939. //
  940. // PARAMETERS:
  941. //
  942. // lpszInputString The string to be parsed
  943. // pchEaten On return identifies how much of the DN has been
  944. // consumed
  945. // bsAuthority Reference to BSTR to hold parsed authority string
  946. //
  947. // RETURN VALUES:
  948. //
  949. // TRUE Parsing was successful.
  950. // FALSE Parsing failed.
  951. //
  952. //
  953. //***************************************************************************
  954. bool CWbemParseDN::ParseAuthority (
  955. LPWSTR lpszInputString,
  956. ULONG* pchEaten,
  957. BSTR &bsAuthority)
  958. {
  959. bool status = false;
  960. // Now we should have a character not equal to "," or "}" (i.e. must specify authority string)
  961. if ((0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_COMMA, wcslen (WBEMS_COMMA))) &&
  962. (0 != _wcsnicmp (lpszInputString + *pchEaten, WBEMS_RIGHT_CURLY, wcslen (WBEMS_RIGHT_CURLY))))
  963. {
  964. // Consume everything up to the next space, "," or "]"
  965. LPWSTR cStr = CURRENTSTR;
  966. ULONG lEaten = 0; // Number of characters consumed
  967. ULONG lAuthority = 0; // Actual length of the authority string
  968. while (*(cStr + lEaten))
  969. {
  970. if (_istspace(*(cStr + lEaten)))
  971. {
  972. // Hit white space - stop now
  973. break;
  974. }
  975. else if ((0 == _wcsnicmp (cStr + lEaten, WBEMS_RIGHT_CURLY, wcslen (WBEMS_RIGHT_CURLY))) ||
  976. (0 == _wcsnicmp (cStr + lEaten, WBEMS_COMMA, wcslen (WBEMS_COMMA))))
  977. {
  978. // Hit closing "}" or "," - we are done; unpop the "}" or "," as that will be handled
  979. // in the calling function
  980. break;
  981. }
  982. else // Keep on truckin'
  983. {
  984. lAuthority++;
  985. lEaten++;
  986. }
  987. }
  988. // If we terminated correctly, save the locale setting
  989. if ((lEaten > 1) && (lAuthority > 0))
  990. {
  991. status = true;
  992. LPWSTR pAuthorityStr = new WCHAR [lAuthority + 1];
  993. if (pAuthorityStr)
  994. {
  995. wcsncpy (pAuthorityStr, lpszInputString + *pchEaten, lAuthority);
  996. pAuthorityStr [lAuthority] = NULL;
  997. bsAuthority = SysAllocString (pAuthorityStr);
  998. delete [] pAuthorityStr;
  999. *pchEaten += lEaten;
  1000. }
  1001. else
  1002. status = false;
  1003. }
  1004. }
  1005. if (!status)
  1006. *pchEaten = 0;
  1007. return status;
  1008. }
  1009. //***************************************************************************
  1010. //
  1011. // BOOLEAN CWbemParseDN::ParsePrivilegeSet
  1012. //
  1013. // DESCRIPTION:
  1014. //
  1015. // Parse the string specification of privilege settings.
  1016. //
  1017. // PARAMETERS:
  1018. //
  1019. // lpszInputString The string to be parsed
  1020. // pchEaten On return identifies how much of the DN has been
  1021. // consumed
  1022. // privilegeSet The container into which the parsed privileges
  1023. // are stored.
  1024. //
  1025. // RETURN VALUES:
  1026. //
  1027. // TRUE Parsing was successful.
  1028. // FALSE Parsing failed.
  1029. //
  1030. //
  1031. //***************************************************************************
  1032. bool CWbemParseDN::ParsePrivilegeSet (
  1033. LPWSTR lpszInputString,
  1034. ULONG *pchEaten,
  1035. CSWbemPrivilegeSet &privilegeSet
  1036. )
  1037. {
  1038. // We have consumed the initial "(". Now we are looking for
  1039. // a list of privileges, followed by a final ")"
  1040. bool status = true;
  1041. ULONG chEaten = *pchEaten; // In case we need to roll back
  1042. bool done = false;
  1043. bool firstPrivilege = true;
  1044. SKIPWHITESPACE
  1045. while (!done)
  1046. {
  1047. VARIANT_BOOL bEnabled = VARIANT_TRUE;
  1048. // If not the first privilege we are expecting a ","
  1049. if (!firstPrivilege)
  1050. {
  1051. if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_COMMA, wcslen(WBEMS_COMMA)))
  1052. {
  1053. *pchEaten += wcslen (WBEMS_COMMA);
  1054. SKIPWHITESPACE
  1055. }
  1056. else
  1057. {
  1058. status = false;
  1059. break;
  1060. }
  1061. }
  1062. // Next token may be a "!" to indicate a disabled privilege
  1063. if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_EXCLAMATION, wcslen(WBEMS_EXCLAMATION)))
  1064. {
  1065. *pchEaten += wcslen (WBEMS_EXCLAMATION);
  1066. bEnabled = VARIANT_FALSE;
  1067. SKIPWHITESPACE
  1068. }
  1069. // Next token must be a valid privilege moniker name
  1070. WbemPrivilegeEnum iPrivilege;
  1071. if (CSWbemPrivilege::GetIdFromMonikerName (lpszInputString + *pchEaten, iPrivilege))
  1072. {
  1073. ISWbemPrivilege *pDummy = NULL;
  1074. if (SUCCEEDED (privilegeSet.Add (iPrivilege, bEnabled, &pDummy)))
  1075. {
  1076. *pchEaten += wcslen (CSWbemPrivilege::GetMonikerNameFromId (iPrivilege));
  1077. pDummy->Release ();
  1078. }
  1079. else
  1080. {
  1081. status = false;
  1082. break;
  1083. }
  1084. }
  1085. else
  1086. {
  1087. // Didn't recognize the privilege name
  1088. status = false;
  1089. break;
  1090. }
  1091. SKIPWHITESPACE
  1092. // Finally if we meet a ")" we are truly done with no error
  1093. if (0 == _wcsnicmp(lpszInputString + *pchEaten, WBEMS_RIGHT_PAREN, wcslen(WBEMS_RIGHT_PAREN)))
  1094. {
  1095. *pchEaten += wcslen (WBEMS_RIGHT_PAREN);
  1096. done = true;
  1097. SKIPWHITESPACE
  1098. }
  1099. firstPrivilege = false;
  1100. SKIPWHITESPACE
  1101. }
  1102. if (!status)
  1103. {
  1104. // Misery - blow away any privileges we might have accrued
  1105. *pchEaten = chEaten;
  1106. privilegeSet.DeleteAll ();
  1107. }
  1108. return status;
  1109. }
  1110. //***************************************************************************
  1111. //
  1112. // BOOLEAN CWbemParseDN::GetSecurityString
  1113. //
  1114. // DESCRIPTION:
  1115. //
  1116. // Take an authentication and impersonlation level and convert it into
  1117. // a security specifier string.
  1118. //
  1119. // PARAMETERS:
  1120. //
  1121. // authnSpecified Whether a nondefault authn levl is specified.
  1122. // authnLevel The authentication level.
  1123. // impSpecified Whether a non-default imp level is specified.
  1124. // impLevel The impersonation level.
  1125. // privilegeSet Privileges
  1126. // bsAuthority Authority
  1127. //
  1128. //
  1129. // RETURN VALUES:
  1130. // the newly created string (which the caller must free) or NULL
  1131. //
  1132. //***************************************************************************
  1133. wchar_t *CWbemParseDN::GetSecurityString (
  1134. bool authnSpecified,
  1135. enum WbemAuthenticationLevelEnum authnLevel,
  1136. bool impSpecified,
  1137. enum WbemImpersonationLevelEnum impLevel,
  1138. CSWbemPrivilegeSet &privilegeSet,
  1139. BSTR &bsAuthority
  1140. )
  1141. {
  1142. wchar_t *pResult = NULL;
  1143. long lPrivilegeCount = 0;
  1144. privilegeSet.get_Count (&lPrivilegeCount);
  1145. ULONG lNumDisabled = privilegeSet.GetNumberOfDisabledElements ();
  1146. PrivilegeMap privMap = privilegeSet.GetPrivilegeMap ();
  1147. bool authoritySpecified = ((NULL != bsAuthority) && (0 < wcslen (bsAuthority)));
  1148. // Degenerate case - no security info
  1149. if (!authnSpecified && !impSpecified && (0 == lPrivilegeCount)
  1150. && !authoritySpecified)
  1151. return NULL;
  1152. // Must have at least these 2 tokens
  1153. size_t len = wcslen (WBEMS_LEFT_CURLY) + wcslen (WBEMS_RIGHT_CURLY);
  1154. if (authnSpecified)
  1155. {
  1156. len += wcslen(WBEMS_AUTH_LEVEL) + wcslen (WBEMS_EQUALS);
  1157. switch (authnLevel)
  1158. {
  1159. case wbemAuthenticationLevelDefault:
  1160. len += wcslen (WBEMS_AUTH_DEFAULT);
  1161. break;
  1162. case wbemAuthenticationLevelNone:
  1163. len += wcslen (WBEMS_AUTH_NONE);
  1164. break;
  1165. case wbemAuthenticationLevelConnect:
  1166. len += wcslen (WBEMS_AUTH_CONNECT);
  1167. break;
  1168. case wbemAuthenticationLevelCall:
  1169. len += wcslen (WBEMS_AUTH_CALL);
  1170. break;
  1171. case wbemAuthenticationLevelPkt:
  1172. len += wcslen (WBEMS_AUTH_PKT);
  1173. break;
  1174. case wbemAuthenticationLevelPktIntegrity:
  1175. len += wcslen (WBEMS_AUTH_PKT_INT);
  1176. break;
  1177. case wbemAuthenticationLevelPktPrivacy:
  1178. len += wcslen (WBEMS_AUTH_PKT_PRIV);
  1179. break;
  1180. default:
  1181. return NULL; // Bad level
  1182. }
  1183. if (impSpecified || authoritySpecified)
  1184. len += wcslen (WBEMS_COMMA);
  1185. }
  1186. if (impSpecified)
  1187. {
  1188. len += wcslen(WBEMS_IMPERSON_LEVEL) + wcslen (WBEMS_EQUALS);
  1189. switch (impLevel)
  1190. {
  1191. case wbemImpersonationLevelAnonymous:
  1192. len += wcslen (WBEMS_IMPERSON_ANON);
  1193. break;
  1194. case wbemImpersonationLevelIdentify:
  1195. len += wcslen (WBEMS_IMPERSON_IDENTIFY);
  1196. break;
  1197. case wbemImpersonationLevelImpersonate:
  1198. len += wcslen (WBEMS_IMPERSON_IMPERSON);
  1199. break;
  1200. case wbemImpersonationLevelDelegate:
  1201. len += wcslen (WBEMS_IMPERSON_DELEGATE);
  1202. break;
  1203. default:
  1204. return NULL; // Bad level
  1205. }
  1206. if (authoritySpecified)
  1207. len += wcslen (WBEMS_COMMA);
  1208. }
  1209. if (authoritySpecified)
  1210. len += wcslen(WBEMS_AUTHORITY) + wcslen (WBEMS_EQUALS) + wcslen (bsAuthority);
  1211. if (0 < lPrivilegeCount)
  1212. {
  1213. // If imp, authn or authority also specified, we need another separator
  1214. if (authnSpecified || impSpecified || authoritySpecified)
  1215. len += wcslen (WBEMS_COMMA);
  1216. // Need these boundary tokens
  1217. len += wcslen (WBEMS_LEFT_PAREN) + wcslen (WBEMS_RIGHT_PAREN);
  1218. // Need a separator between each privilege
  1219. if (1 < lPrivilegeCount)
  1220. len += (lPrivilegeCount - 1) * wcslen (WBEMS_COMMA);
  1221. // Need to specify false values with "!"
  1222. if (lNumDisabled)
  1223. len += lNumDisabled * wcslen (WBEMS_EXCLAMATION);
  1224. // Now add the privilege strings
  1225. PrivilegeMap::iterator next = privMap.begin ();
  1226. while (next != privMap.end ())
  1227. {
  1228. OLECHAR *sMonikerName = CSWbemPrivilege::GetMonikerNameFromId ((*next).first);
  1229. if (sMonikerName)
  1230. len += wcslen (sMonikerName);
  1231. next++;
  1232. }
  1233. }
  1234. pResult = new wchar_t [len + 1];
  1235. if (pResult)
  1236. {
  1237. // Now build the string
  1238. wcscpy (pResult, WBEMS_LEFT_CURLY);
  1239. if (authnSpecified)
  1240. {
  1241. wcscat (pResult, WBEMS_AUTH_LEVEL);
  1242. wcscat (pResult, WBEMS_EQUALS);
  1243. switch (authnLevel)
  1244. {
  1245. case wbemAuthenticationLevelDefault:
  1246. wcscat (pResult, WBEMS_AUTH_DEFAULT);
  1247. break;
  1248. case wbemAuthenticationLevelNone:
  1249. wcscat (pResult, WBEMS_AUTH_NONE);
  1250. break;
  1251. case wbemAuthenticationLevelConnect:
  1252. wcscat (pResult, WBEMS_AUTH_CONNECT);
  1253. break;
  1254. case wbemAuthenticationLevelCall:
  1255. wcscat (pResult, WBEMS_AUTH_CALL);
  1256. break;
  1257. case wbemAuthenticationLevelPkt:
  1258. wcscat (pResult, WBEMS_AUTH_PKT);
  1259. break;
  1260. case wbemAuthenticationLevelPktIntegrity:
  1261. wcscat (pResult, WBEMS_AUTH_PKT_INT);
  1262. break;
  1263. case wbemAuthenticationLevelPktPrivacy:
  1264. wcscat (pResult, WBEMS_AUTH_PKT_PRIV);
  1265. break;
  1266. }
  1267. if (impSpecified || authoritySpecified || (0 < lPrivilegeCount))
  1268. wcscat (pResult, WBEMS_COMMA);
  1269. }
  1270. if (impSpecified)
  1271. {
  1272. wcscat (pResult, WBEMS_IMPERSON_LEVEL);
  1273. wcscat (pResult, WBEMS_EQUALS);
  1274. switch (impLevel)
  1275. {
  1276. case wbemImpersonationLevelAnonymous:
  1277. wcscat (pResult, WBEMS_IMPERSON_ANON);
  1278. break;
  1279. case wbemImpersonationLevelIdentify:
  1280. wcscat (pResult, WBEMS_IMPERSON_IDENTIFY);
  1281. break;
  1282. case wbemImpersonationLevelImpersonate:
  1283. wcscat (pResult, WBEMS_IMPERSON_IMPERSON);
  1284. break;
  1285. case wbemImpersonationLevelDelegate:
  1286. wcscat (pResult, WBEMS_IMPERSON_DELEGATE);
  1287. break;
  1288. default:
  1289. return NULL; // Bad level
  1290. }
  1291. if (authoritySpecified || (0 < lPrivilegeCount))
  1292. wcscat (pResult, WBEMS_COMMA);
  1293. }
  1294. if (authoritySpecified)
  1295. {
  1296. wcscat (pResult, WBEMS_AUTHORITY);
  1297. wcscat (pResult, WBEMS_EQUALS);
  1298. wcscat (pResult, bsAuthority);
  1299. if ((0 < lPrivilegeCount))
  1300. wcscat (pResult, WBEMS_COMMA);
  1301. }
  1302. if (lPrivilegeCount)
  1303. {
  1304. wcscat (pResult, WBEMS_LEFT_PAREN);
  1305. // Now add the privilege strings
  1306. PrivilegeMap::iterator next = privMap.begin ();
  1307. bool firstPrivilege = true;
  1308. while (next != privMap.end ())
  1309. {
  1310. if (!firstPrivilege)
  1311. wcscat (pResult, WBEMS_COMMA);
  1312. firstPrivilege = false;
  1313. CSWbemPrivilege *pPrivilege = (*next).second;
  1314. VARIANT_BOOL bValue;
  1315. if (SUCCEEDED (pPrivilege->get_IsEnabled (&bValue)) &&
  1316. (VARIANT_FALSE == bValue))
  1317. wcscat (pResult, WBEMS_EXCLAMATION);
  1318. OLECHAR *sMonikerName = CSWbemPrivilege::GetMonikerNameFromId ((*next).first);
  1319. wcscat (pResult, sMonikerName);
  1320. next++;
  1321. }
  1322. wcscat (pResult, WBEMS_RIGHT_PAREN);
  1323. }
  1324. wcscat (pResult, WBEMS_RIGHT_CURLY);
  1325. pResult [len] = NULL;
  1326. }
  1327. return pResult;
  1328. }
  1329. //***************************************************************************
  1330. //
  1331. // BOOLEAN CWbemParseDN::GetLocaleString
  1332. //
  1333. // DESCRIPTION:
  1334. //
  1335. // Take a locale value and convert it into a locale specifier string.
  1336. //
  1337. // PARAMETERS:
  1338. //
  1339. // bsLocale The value (if any)
  1340. //
  1341. // RETURN VALUES:
  1342. // the newly created string (which the caller must free) or NULL
  1343. //
  1344. //***************************************************************************
  1345. wchar_t *CWbemParseDN::GetLocaleString (
  1346. BSTR bsLocale
  1347. )
  1348. {
  1349. wchar_t *pResult = NULL;
  1350. // Degenerate case - no locale info
  1351. if (!bsLocale || (0 == wcslen (bsLocale)))
  1352. return NULL;
  1353. // Calculate length of string
  1354. size_t len = wcslen (WBEMS_LEFT_SQBRK) + wcslen (WBEMS_LOCALE) +
  1355. wcslen (WBEMS_EQUALS) + wcslen (bsLocale) + wcslen (WBEMS_RIGHT_SQBRK);
  1356. pResult = new wchar_t [len + 1];
  1357. if (pResult)
  1358. {
  1359. // Now build the string
  1360. wcscpy (pResult, WBEMS_LEFT_SQBRK);
  1361. wcscat (pResult, WBEMS_LOCALE);
  1362. wcscat (pResult, WBEMS_EQUALS);
  1363. wcscat (pResult, bsLocale);
  1364. wcscat (pResult, WBEMS_RIGHT_SQBRK);
  1365. pResult [len] = NULL;
  1366. }
  1367. return pResult;
  1368. }
  1369. #undef CURRENTSTR
  1370. #undef SKIPWHITESPACE