Leaked source code of windows server 2003
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.

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