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.

3402 lines
78 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. crmap.cxx
  5. Abstract:
  6. ADSIIS cert mapper object
  7. Certificate mappings storage has changed for IIS6.
  8. ADSI however has to support downlevel admin of
  9. IIS5, IIS5.1
  10. NSEPM support was removed from IIS6 and 1to1 client certificate
  11. mapping information is now stored under <site>/Cert11/Mappings
  12. node directly in the metabase
  13. Functions with IIS6 postfix access new location
  14. for 1to1 client certificate mappings storage
  15. Author:
  16. Philippe Choquier (phillich) 10-Apr-1997
  17. --*/
  18. #include "iisext.hxx"
  19. #pragma hdrstop
  20. #include <nsepname.hxx>
  21. #include <dbgutil.h>
  22. DEFINE_IPrivateDispatch_Implementation(CIISDsCrMap)
  23. DEFINE_DELEGATING_IDispatch_Implementation(CIISDsCrMap)
  24. DEFINE_CONTAINED_IADs_Implementation(CIISDsCrMap)
  25. DEFINE_IADsExtension_Implementation(CIISDsCrMap)
  26. #define LOCAL_MAX_SIZE METADATA_MAX_NAME_LEN + 1
  27. const int SHA1_HASH_SIZE = 20;
  28. //Local functions used only for IIS6
  29. HRESULT
  30. GetStringAFromBSTR(
  31. BSTR bstr,
  32. LPSTR* psz,
  33. LPDWORD pdwLen,
  34. BOOL fAddDelimInCount = TRUE
  35. );
  36. HRESULT
  37. GetBlobFromVariant(
  38. VARIANT* pVar,
  39. PBYTE* ppbOut,
  40. LPDWORD pcbOut
  41. );
  42. HRESULT
  43. SetVariantAsBSTRFromStringW(
  44. VARIANT* pvarReturn,
  45. DWORD cbLen,
  46. LPBYTE pbIn
  47. );
  48. HRESULT
  49. SetBSTRFromStringW(
  50. BSTR* pbstrRet,
  51. DWORD cb,
  52. LPBYTE sz
  53. );
  54. //
  55. // Local functions used for IIS5 and IIS6
  56. //
  57. HRESULT
  58. GetStringFromBSTR(
  59. BSTR bstr,
  60. LPSTR* psz,
  61. LPDWORD pdwLen,
  62. BOOL fAddDelimInCount = TRUE
  63. );
  64. HRESULT
  65. GetStringFromVariant(
  66. VARIANT* pVar,
  67. LPSTR* psz,
  68. LPDWORD pdwLen,
  69. BOOL fAddDelimInCount = TRUE
  70. );
  71. VOID
  72. FreeString(
  73. LPSTR psz
  74. );
  75. HRESULT
  76. SetBSTR(
  77. BSTR* pbstrRet,
  78. DWORD cch,
  79. LPBYTE sz
  80. );
  81. HRESULT
  82. SetVariantAsByteArray(
  83. VARIANT* pvarReturn,
  84. DWORD cbLen,
  85. LPBYTE pbIn
  86. );
  87. HRESULT
  88. SetVariantAsBSTR(
  89. VARIANT* pvarReturn,
  90. DWORD cbLen,
  91. LPBYTE pbIn
  92. );
  93. HRESULT
  94. SetVariantAsLong(
  95. VARIANT* pvarReturn,
  96. DWORD dwV
  97. );
  98. HRESULT
  99. VariantResolveDispatch(
  100. VARIANT * pVarOut,
  101. VARIANT * pVarIn
  102. );
  103. HRESULT
  104. GetCertificateHashString(
  105. PBYTE pbCert,
  106. DWORD cbCert,
  107. WCHAR *pwszCertHash,
  108. DWORD cchCertHashBuffer)
  109. /*++
  110. Routine Description:
  111. verifies validity of cert blob by creating cert context
  112. and retrieves SHA1 hash and converts it to WCHAR *
  113. Used for IIS6 only
  114. Arguments:
  115. pbCert - X.509 certificate blob
  116. cbCert - size of the cert blob in bytes
  117. pwszCertHash - buffer must be big enough to fit SHA1 hash in hex string form
  118. (40 WCHAR + terminating 0 )
  119. cchCertHashBuffer - size of the CertHash buffer in WCHARS (includes terminating 0)
  120. Returns:
  121. HRESULT
  122. --*/
  123. {
  124. HRESULT hr = E_FAIL;
  125. BYTE rgbHash[ SHA1_HASH_SIZE ];
  126. DWORD cbSize = SHA1_HASH_SIZE;
  127. #ifndef HEX_DIGIT
  128. #define HEX_DIGIT( nDigit ) \
  129. (WCHAR)((nDigit) > 9 ? \
  130. (nDigit) - 10 + L'a' \
  131. : (nDigit) + L'0')
  132. #endif
  133. PCCERT_CONTEXT pCertContext = NULL;
  134. pCertContext = CertCreateCertificateContext(
  135. X509_ASN_ENCODING,
  136. (const BYTE *)pbCert,
  137. cbCert );
  138. if ( pCertContext == NULL )
  139. {
  140. hr = HRESULT_FROM_WIN32( GetLastError() );
  141. return hr;
  142. }
  143. //
  144. // get hash of the certificate to be verified
  145. //
  146. if ( !CertGetCertificateContextProperty( pCertContext,
  147. CERT_SHA1_HASH_PROP_ID,
  148. rgbHash,
  149. &cbSize ) )
  150. {
  151. hr = HRESULT_FROM_WIN32( GetLastError() );
  152. CertFreeCertificateContext( pCertContext );
  153. pCertContext=NULL;
  154. return hr;
  155. }
  156. CertFreeCertificateContext( pCertContext );
  157. pCertContext = NULL;
  158. if ( cchCertHashBuffer < SHA1_HASH_SIZE * 2 + 1 )
  159. {
  160. // we don't have big enough buffer to store
  161. // hex string of the SHA1 hash each byte takes 2 chars + terminating 0
  162. hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  163. DBG_ASSERT( FALSE );
  164. return hr;
  165. }
  166. //
  167. // convert to text
  168. //
  169. for (int i = 0; i < sizeof(rgbHash); i ++ )
  170. {
  171. *(pwszCertHash++) = HEX_DIGIT( ( rgbHash[ i ] >> 4 ) );
  172. *(pwszCertHash++) = HEX_DIGIT( ( rgbHash[ i ] & 0x0F ) );
  173. }
  174. *(pwszCertHash) = L'\0';
  175. #undef HEX_DIGIT
  176. return S_OK;
  177. }
  178. //
  179. // Mapping functins for IIS6
  180. //
  181. HRESULT
  182. CIISDsCrMap::CreateMappingIIS6(
  183. VARIANT vCert,
  184. BSTR bstrNtAcct,
  185. BSTR bstrNtPwd,
  186. BSTR bstrName,
  187. LONG lEnabled
  188. )
  189. /*++
  190. Routine Description:
  191. Create a mapping entry
  192. Arguments:
  193. vCert - X.509 certificate
  194. bstrNtAcct - NT acct to map to
  195. bstrNtPwd - NT pwd
  196. bstrName - friendly name for mapping entry
  197. lEnabled - 1 to enable mapping entry, 0 to disable it
  198. Returns:
  199. COM status
  200. --*/
  201. {
  202. HRESULT hres;
  203. LPBYTE pbCert = NULL;
  204. DWORD cbCert;
  205. LPBYTE pRes;
  206. DWORD cRes;
  207. VARIANT vOldAcct;
  208. VARIANT vOldCert;
  209. VARIANT vOldPwd;
  210. VARIANT vOldName;
  211. VARIANT vOldEnabledFlag;
  212. PCCERT_CONTEXT pcCert = NULL;
  213. WCHAR wszCertHash[ 2*SHA1_HASH_SIZE + 1];
  214. BOOL fFoundExisting = FALSE;
  215. //
  216. // Do some sanity checks on the cert
  217. //
  218. if ( SUCCEEDED( hres = GetBlobFromVariant( &vCert,
  219. &pbCert,
  220. &cbCert ) ) )
  221. {
  222. //
  223. // verify validity of certificate blob
  224. // and retrieve certificate hash
  225. //
  226. if ( FAILED( hres = GetCertificateHashString(
  227. pbCert,
  228. cbCert,
  229. wszCertHash,
  230. sizeof( wszCertHash )/sizeof( WCHAR ) ) ) )
  231. {
  232. DBGPRINTF((DBG_CONTEXT,
  233. "Invalid cert passed to CreateMapping() 0x%x\n", hres));
  234. //
  235. // If the decoding fails, GetLastError() returns an ASN1 decoding
  236. // error that is obtained by subtracting CRYPT_E_OSS_ERROR from the returned
  237. // error and looking in file asn1code.h for the actual error. To avoid the
  238. // cryptic ASN1 errors, we'll just return a general "invalid arg" error
  239. //
  240. goto Exit;
  241. }
  242. }
  243. else
  244. {
  245. goto Exit;
  246. }
  247. //
  248. // check if we already have a mapping for this cert; if we do, we'll replace that mapping
  249. // with the new one
  250. //
  251. WCHAR achIndex[METADATA_MAX_NAME_LEN + 1];
  252. if ( SUCCEEDED( hres = OpenMd( L"Cert11/Mappings",
  253. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  254. {
  255. if ( SUCCEEDED(hres = Locate( IISMAPPER_LOCATE_BY_CERT,
  256. vCert,
  257. achIndex )) )
  258. {
  259. fFoundExisting = TRUE;
  260. DBGPRINTF((DBG_CONTEXT,
  261. "Replacing old 1-1 cert mapping with new mapping\n"));
  262. if ( FAILED( hres = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA,
  263. sizeof(DWORD), (LPBYTE)&lEnabled ) ) ||
  264. FAILED( hres = SetMdData( achIndex, MD_MAPNAME, STRING_METADATA,
  265. sizeof(WCHAR) * (SysStringLen(bstrName) + 1 ),
  266. (LPBYTE)bstrName ) ) ||
  267. FAILED( hres = SetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA,
  268. sizeof(WCHAR) * (SysStringLen(bstrNtPwd) + 1 ),
  269. (LPBYTE)bstrNtPwd ) ) ||
  270. FAILED( hres = SetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA,
  271. sizeof(WCHAR) * (SysStringLen(bstrNtAcct) + 1 ),
  272. (LPBYTE)bstrNtAcct ) ) ||
  273. FAILED( hres = SetMdData( achIndex, MD_MAPCERT, BINARY_METADATA,
  274. cbCert, (LPBYTE)pbCert ) ) )
  275. {
  276. //NOP - Something failed
  277. }
  278. }
  279. CloseMd( SUCCEEDED( hres ) );
  280. }
  281. //
  282. // New mapping
  283. //
  284. if ( !fFoundExisting )
  285. {
  286. //
  287. // check mapping exists, create if not
  288. //
  289. hres = OpenMd( L"Cert11/Mappings", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  290. if ( hres == RETURNCODETOHRESULT( ERROR_PATH_NOT_FOUND ) )
  291. {
  292. if ( SUCCEEDED( hres = OpenMd( L"",
  293. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  294. {
  295. hres = CreateMdObject( L"Cert11/Mappings" );
  296. CloseMd( FALSE );
  297. // Reopen to the correct node.
  298. hres = OpenMd( L"Cert11/Mappings", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  299. }
  300. }
  301. // failed to open metabase
  302. if ( FAILED( hres ) )
  303. {
  304. goto Exit;
  305. }
  306. //
  307. // adding the new mapping under it's CertHash node
  308. //
  309. if ( SUCCEEDED( hres = CreateMdObject( wszCertHash ) ) )
  310. {
  311. if ( FAILED( hres = SetMdData( wszCertHash, MD_MAPENABLED, DWORD_METADATA,
  312. sizeof(DWORD), (LPBYTE)&lEnabled ) ) ||
  313. FAILED( hres = SetMdData( wszCertHash, MD_MAPNAME, STRING_METADATA,
  314. sizeof(WCHAR) * (SysStringLen(bstrName) + 1 ),
  315. (LPBYTE)bstrName ) ) ||
  316. FAILED( hres = SetMdData( wszCertHash, MD_MAPNTPWD, STRING_METADATA,
  317. sizeof(WCHAR) * (SysStringLen(bstrNtPwd) + 1 ),
  318. (LPBYTE)bstrNtPwd ) ) ||
  319. FAILED( hres = SetMdData( wszCertHash, MD_MAPNTACCT, STRING_METADATA,
  320. sizeof(WCHAR) * (SysStringLen(bstrNtAcct) + 1 ),
  321. (LPBYTE)bstrNtAcct ) ) ||
  322. FAILED( hres = SetMdData( wszCertHash, MD_MAPCERT, BINARY_METADATA,
  323. cbCert, (LPBYTE)pbCert ) ) )
  324. {
  325. }
  326. }
  327. CloseMd( SUCCEEDED( hres ) );
  328. }
  329. Exit:
  330. if( pbCert != NULL )
  331. {
  332. LocalFree( pbCert );
  333. pbCert = NULL;
  334. }
  335. return hres;
  336. }
  337. HRESULT
  338. CIISDsCrMap::GetMappingIIS6(
  339. LONG lMethod,
  340. VARIANT vKey,
  341. VARIANT* pvCert,
  342. VARIANT* pbstrNtAcct,
  343. VARIANT* pbstrNtPwd,
  344. VARIANT* pbstrName,
  345. VARIANT* plEnabled
  346. )
  347. /*++
  348. Routine Description:
  349. Get a mapping entry using key
  350. Arguments:
  351. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  352. vKey - key to use to locate mapping
  353. pvCert - X.509 certificate
  354. pbstrNtAcct - NT acct to map to
  355. pbstrNtPwd - NT pwd
  356. pbstrName - friendly name for mapping entry
  357. plEnabled - 1 to enable mapping entry, 0 to disable it
  358. Returns:
  359. COM status
  360. --*/
  361. {
  362. WCHAR achIndex[METADATA_MAX_NAME_LEN + 1];
  363. HRESULT hres;
  364. DWORD dwLen;
  365. LPBYTE pbData = NULL;
  366. VariantInit( pvCert );
  367. VariantInit( pbstrNtAcct );
  368. VariantInit( pbstrNtPwd );
  369. VariantInit( pbstrName );
  370. VariantInit( plEnabled );
  371. if ( SUCCEEDED( hres = OpenMd( L"Cert11/Mappings",
  372. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  373. {
  374. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  375. {
  376. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPCERT, BINARY_METADATA, &dwLen,
  377. &pbData ) ) )
  378. {
  379. if ( FAILED( hres = SetVariantAsByteArray( pvCert, dwLen, pbData ) ) )
  380. {
  381. goto Done;
  382. }
  383. LocalFree( pbData );
  384. }
  385. else
  386. {
  387. if ( hres != MD_ERROR_DATA_NOT_FOUND ||
  388. FAILED( hres = SetVariantAsByteArray( pvCert, 0, (PBYTE)"" ) ) )
  389. {
  390. goto Done;
  391. }
  392. }
  393. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA, &dwLen,
  394. &pbData ) ) )
  395. {
  396. if ( FAILED( hres = SetVariantAsBSTRFromStringW(
  397. pbstrNtAcct,
  398. dwLen, pbData ) ) )
  399. {
  400. goto Done;
  401. }
  402. LocalFree( pbData );
  403. pbData = NULL;
  404. }
  405. else
  406. {
  407. if ( hres != MD_ERROR_DATA_NOT_FOUND ||
  408. FAILED ( hres = SetVariantAsBSTRFromStringW(
  409. pbstrNtAcct,
  410. sizeof(L""), (LPBYTE)L"" ) ) )
  411. {
  412. goto Done;
  413. }
  414. }
  415. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA, &dwLen,
  416. &pbData ) ) )
  417. {
  418. if ( FAILED( hres = SetVariantAsBSTRFromStringW(
  419. pbstrNtPwd,
  420. dwLen, pbData ) ) )
  421. {
  422. goto Done;
  423. }
  424. LocalFree( pbData );
  425. pbData = NULL;
  426. }
  427. else
  428. {
  429. if ( hres != MD_ERROR_DATA_NOT_FOUND ||
  430. FAILED( hres = SetVariantAsBSTRFromStringW(
  431. pbstrNtPwd,
  432. sizeof(L""), (LPBYTE)L"" ) ) )
  433. {
  434. goto Done;
  435. }
  436. }
  437. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNAME, STRING_METADATA, &dwLen,
  438. &pbData ) ) )
  439. {
  440. if ( FAILED( hres = SetVariantAsBSTRFromStringW(
  441. pbstrName,
  442. dwLen, pbData ) ) )
  443. {
  444. goto Done;
  445. }
  446. LocalFree( pbData );
  447. pbData = NULL;
  448. }
  449. else
  450. {
  451. if ( hres != MD_ERROR_DATA_NOT_FOUND ||
  452. FAILED( hres = SetVariantAsBSTRFromStringW(
  453. pbstrName,
  454. sizeof(L""), (LPBYTE)L"" ) ) )
  455. {
  456. goto Done;
  457. }
  458. }
  459. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA, &dwLen,
  460. &pbData ) ) )
  461. {
  462. if ( FAILED( hres = SetVariantAsLong( plEnabled, *(LPDWORD)pbData ) ) )
  463. {
  464. goto Done;
  465. }
  466. LocalFree( pbData );
  467. pbData = NULL;
  468. }
  469. else
  470. {
  471. if ( hres != MD_ERROR_DATA_NOT_FOUND ||
  472. FAILED( hres = SetVariantAsLong( plEnabled, FALSE ) ) )
  473. {
  474. goto Done;
  475. }
  476. hres = S_OK;
  477. }
  478. }
  479. Done:
  480. if ( pbData != NULL )
  481. {
  482. LocalFree( pbData );
  483. pbData = NULL;
  484. }
  485. CloseMd( FALSE );
  486. }
  487. return hres;
  488. }
  489. HRESULT
  490. CIISDsCrMap::DeleteMappingIIS6(
  491. LONG lMethod,
  492. VARIANT vKey
  493. )
  494. /*++
  495. Routine Description:
  496. Delete a mapping entry using key
  497. Arguments:
  498. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  499. vKey - key to use to locate mapping
  500. Returns:
  501. COM status
  502. --*/
  503. {
  504. WCHAR achIndex[METADATA_MAX_NAME_LEN + 1];
  505. HRESULT hres;
  506. if ( SUCCEEDED( hres = OpenMd( L"Cert11/Mappings",
  507. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  508. {
  509. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  510. {
  511. hres = DeleteMdObject( achIndex );
  512. }
  513. CloseMd( TRUE );
  514. }
  515. return hres;
  516. }
  517. HRESULT
  518. CIISDsCrMap::SetEnabledIIS6(
  519. LONG lMethod,
  520. VARIANT vKey,
  521. LONG lEnabled
  522. )
  523. /*++
  524. Routine Description:
  525. Set the enable flag on a mapping entry using key
  526. Arguments:
  527. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  528. vKey - key to use to locate mapping
  529. lEnabled - 1 to enable, 0 to disable
  530. Returns:
  531. COM status
  532. --*/
  533. {
  534. WCHAR achIndex[METADATA_MAX_NAME_LEN + 1];
  535. HRESULT hres;
  536. if ( SUCCEEDED( hres = OpenMd( L"Cert11/Mappings",
  537. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  538. {
  539. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  540. {
  541. hres = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA, sizeof(DWORD), (LPBYTE)&lEnabled );
  542. }
  543. CloseMd( TRUE );
  544. }
  545. return hres;
  546. }
  547. HRESULT
  548. CIISDsCrMap::SetNameIIS6(
  549. LONG lMethod,
  550. VARIANT vKey,
  551. BSTR bstrName
  552. )
  553. /*++
  554. Routine Description:
  555. Set the Name on a mapping entry using key
  556. Arguments:
  557. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  558. vKey - key to use to locate mapping
  559. bstrName - name to assign to mapping entry
  560. Returns:
  561. COM status
  562. --*/
  563. {
  564. return SetStringIIS6( lMethod, vKey, bstrName, MD_MAPNAME );
  565. }
  566. HRESULT
  567. CIISDsCrMap::SetStringIIS6(
  568. LONG lMethod,
  569. VARIANT vKey,
  570. BSTR bstrName,
  571. DWORD dwProp
  572. )
  573. /*++
  574. Routine Description:
  575. Set a string property on a mapping entry using key
  576. Arguments:
  577. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  578. vKey - key to use to locate mapping
  579. bstrName - string content to assign to mapping entry
  580. dwProp - property ID to assign to
  581. Returns:
  582. COM status
  583. --*/
  584. {
  585. WCHAR achIndex[METADATA_MAX_NAME_LEN + 1];
  586. LPSTR pszName = NULL;
  587. HRESULT hres;
  588. DWORD dwLen;
  589. if ( SUCCEEDED( hres = OpenMd( L"Cert11/Mappings",
  590. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  591. {
  592. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  593. {
  594. hres = SetMdData( achIndex, dwProp, STRING_METADATA,
  595. sizeof(WCHAR) * (SysStringLen(bstrName) + 1 ),
  596. (LPBYTE)bstrName );
  597. }
  598. CloseMd( TRUE );
  599. }
  600. return hres;
  601. }
  602. HRESULT
  603. CIISDsCrMap::SetPwdIIS6(
  604. LONG lMethod,
  605. VARIANT vKey,
  606. BSTR bstrPwd
  607. )
  608. /*++
  609. Routine Description:
  610. Set the Password on a mapping entry using key
  611. Arguments:
  612. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  613. vKey - key to use to locate mapping
  614. bstrPwd - password to assign to mapping entry
  615. Returns:
  616. COM status
  617. --*/
  618. {
  619. // Password must be saved with METADATA_SECURE flag
  620. // SetMdData() is used by SetStringIIS6() and it will take care of it
  621. //
  622. return SetStringIIS6( lMethod, vKey, bstrPwd, MD_MAPNTPWD );
  623. }
  624. HRESULT
  625. CIISDsCrMap::SetAcctIIS6(
  626. LONG lMethod,
  627. VARIANT vKey,
  628. BSTR bstrAcct
  629. )
  630. /*++
  631. Routine Description:
  632. Set the NT account name on a mapping entry using key
  633. Arguments:
  634. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  635. vKey - key to use to locate mapping
  636. bstrAcct - NT account name to assign to mapping entry
  637. Returns:
  638. COM status
  639. --*/
  640. {
  641. return SetStringIIS6( lMethod, vKey, bstrAcct, MD_MAPNTACCT );
  642. }
  643. //////
  644. HRESULT
  645. CIISDsCrMap::LocateIIS6(
  646. LONG lMethod,
  647. VARIANT vKey,
  648. LPWSTR pszResKey
  649. )
  650. /*++
  651. Routine Description:
  652. Locate a mapping entry based on key
  653. OpenMd() must be called 1st
  654. Arguments:
  655. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  656. vKey - key to use to locate mapping
  657. pszResKey - must be METADATA_MAX_NAME_LEN + 1 WCHARs long
  658. Returns:
  659. COM status
  660. --*/
  661. {
  662. HRESULT hres;
  663. PBYTE pbKeyData = NULL;
  664. DWORD cbKeyData =0;
  665. PBYTE pbCert = NULL;
  666. DWORD cbCert =0;
  667. DWORD dwProp;
  668. LPSTR pRes;
  669. DWORD cRes;
  670. BOOL fAddDelim = TRUE;
  671. VARIANT vKeyUI4;
  672. VARIANT vKeyBSTR;
  673. WCHAR achIndex[ METADATA_MAX_NAME_LEN + 1 ];
  674. DWORD dwIndex = 0;
  675. DWORD cbData = 0;
  676. PBYTE pbData = NULL;
  677. VariantInit( &vKeyUI4 );
  678. VariantInit( &vKeyBSTR );
  679. if ( lMethod == IISMAPPER_LOCATE_BY_INDEX )
  680. {
  681. //
  682. // Convert index to numeric value VT_UI4 (within variant)
  683. //
  684. if ( FAILED( hres = VariantChangeType( &vKeyUI4, &vKey, 0, VT_UI4 ) ) )
  685. {
  686. goto Exit;
  687. }
  688. if ( V_UI4( &vKeyUI4 ) == 0 )
  689. {
  690. // Error PATH_NOT_FOUND chosen for backward compatibility
  691. // with version IIS5.1 and older
  692. //
  693. hres = HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND );
  694. goto Exit;
  695. }
  696. hres = m_pcAdmCom->EnumKeys( m_hmd,
  697. L"",
  698. achIndex,
  699. V_UI4( &vKeyUI4 ) - 1
  700. );
  701. if ( hres == HRESULT_FROM_WIN32( ERROR_NO_MORE_ITEMS ) )
  702. {
  703. // Error PATH_NOT_FOUND chosen for backward compatibility
  704. // with version IIS5.1 and older
  705. //
  706. hres = HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND );
  707. }
  708. goto Exit;
  709. }
  710. //
  711. // get ptr to data
  712. //
  713. if ( lMethod == IISMAPPER_LOCATE_BY_CERT )
  714. {
  715. // Now this is really wacky. Because of the legacy of the bad
  716. // decision in the past the CERT is not enforced to be byte array
  717. // It can be passed as string. That causes problems with
  718. // conversions between byte array and UNICODE and back
  719. // but we got to stick with it for compatibility with previous versions.
  720. //
  721. if ( FAILED( hres = GetBlobFromVariant( &vKey, &pbCert, &cbCert ) ) )
  722. {
  723. goto Exit;
  724. }
  725. pbKeyData = pbCert;
  726. cbKeyData = cbCert;
  727. }
  728. else
  729. {
  730. //
  731. // the rest of the lookups (by mapping, name or by account name)
  732. // assumes string
  733. //
  734. if ( FAILED( hres = VariantChangeType( &vKeyBSTR, &vKey, 0, VT_BSTR ) ) )
  735. {
  736. goto Exit;
  737. }
  738. pbKeyData = (PBYTE) V_BSTR( &vKeyBSTR );
  739. cbKeyData = ( SysStringLen(V_BSTR( &vKeyBSTR )) + 1 ) * sizeof(WCHAR);
  740. }
  741. //
  742. // enumerate all entries to find match
  743. // Now this is really slooow if many mappings are configured
  744. //
  745. for(;;)
  746. {
  747. hres = m_pcAdmCom->EnumKeys( m_hmd,
  748. L"",
  749. achIndex,
  750. dwIndex
  751. );
  752. if ( FAILED( hres ) )
  753. {
  754. if ( hres == HRESULT_FROM_WIN32( ERROR_NO_MORE_ITEMS ) )
  755. {
  756. // Error PATH_NOT_FOUND chosen for backward compatibility
  757. // with version IIS5.1 and older
  758. //
  759. hres = HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND );
  760. }
  761. goto Exit;
  762. }
  763. switch ( lMethod )
  764. {
  765. case IISMAPPER_LOCATE_BY_CERT:
  766. hres = GetMdData( achIndex, MD_MAPCERT, BINARY_METADATA, &cbData,
  767. &pbData );
  768. if ( hres == MD_ERROR_DATA_NOT_FOUND )
  769. {
  770. cbData = 0;
  771. pbData = NULL;
  772. }
  773. else if ( FAILED( hres ) )
  774. {
  775. // goto next entry
  776. break;
  777. }
  778. //
  779. // compare if key is matching value read from metabase
  780. //
  781. if ( cbData == cbKeyData )
  782. {
  783. if ( ( cbData == 0 ) ||
  784. memcmp( pbKeyData, pbData, cbData ) == 0 )
  785. {
  786. // we found match
  787. hres = S_OK;
  788. goto Exit;
  789. }
  790. }
  791. break;
  792. case IISMAPPER_LOCATE_BY_ACCT:
  793. hres = GetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA, &cbData,
  794. &pbData );
  795. if ( hres == MD_ERROR_DATA_NOT_FOUND )
  796. {
  797. cbData = sizeof(L"");
  798. pbData = (PBYTE) L"";
  799. }
  800. else if ( FAILED( hres ) )
  801. {
  802. // goto next entry
  803. break;
  804. }
  805. if ( cbData == cbKeyData )
  806. {
  807. if ( _wcsicmp( (WCHAR *) pbKeyData, (WCHAR *) pbData ) == 0 )
  808. {
  809. // we found match
  810. hres = S_OK;
  811. goto Exit;
  812. }
  813. }
  814. break;
  815. case IISMAPPER_LOCATE_BY_NAME:
  816. hres = GetMdData( achIndex, MD_MAPNAME, STRING_METADATA, &cbData,
  817. &pbData );
  818. if ( hres == MD_ERROR_DATA_NOT_FOUND )
  819. {
  820. cbData = sizeof(L"");
  821. pbData = (PBYTE) L"";
  822. }
  823. else if ( FAILED( hres ) )
  824. {
  825. // goto next entry
  826. break;
  827. }
  828. if ( cbData == cbKeyData )
  829. {
  830. if ( _wcsicmp( (WCHAR *) pbKeyData, (WCHAR *) pbData ) == 0 )
  831. {
  832. // we found match
  833. hres = S_OK;
  834. goto Exit;
  835. }
  836. }
  837. break;
  838. }
  839. if ( pbData != NULL )
  840. {
  841. LocalFree( pbData );
  842. pbData = NULL;
  843. }
  844. dwIndex++;
  845. }
  846. Exit:
  847. if ( pbData != NULL )
  848. {
  849. LocalFree( pbData );
  850. pbData = NULL;
  851. }
  852. if ( pbCert != NULL )
  853. {
  854. LocalFree( pbCert );
  855. pbCert = NULL;
  856. }
  857. if ( SUCCEEDED( hres ) )
  858. {
  859. wcsncpy( pszResKey, achIndex, METADATA_MAX_NAME_LEN + 1 );
  860. pszResKey[ METADATA_MAX_NAME_LEN ] ='\0';
  861. }
  862. VariantClear( &vKeyUI4 );
  863. VariantClear( &vKeyBSTR );
  864. return hres;
  865. }
  866. //
  867. // IIS5, IIS51 mapping functions
  868. // They call IIS6 mapping function when connecting to IIS6 box
  869. //
  870. HRESULT
  871. CIISDsCrMap::CreateMapping(
  872. VARIANT vCert,
  873. BSTR bstrNtAcct,
  874. BSTR bstrNtPwd,
  875. BSTR bstrName,
  876. LONG lEnabled
  877. )
  878. /*++
  879. Routine Description:
  880. Create a mapping entry
  881. Arguments:
  882. vCert - X.509 certificate
  883. bstrNtAcct - NT acct to map to
  884. bstrNtPwd - NT pwd
  885. bstrName - friendly name for mapping entry
  886. lEnabled - 1 to enable mapping entry, 0 to disable it
  887. Returns:
  888. COM status
  889. --*/
  890. {
  891. if ( m_fIsIIS6 )
  892. {
  893. return CreateMappingIIS6( vCert,
  894. bstrNtAcct,
  895. bstrNtPwd,
  896. bstrName,
  897. lEnabled );
  898. }
  899. HRESULT hres;
  900. LPBYTE pbCert = NULL;
  901. DWORD cCert;
  902. LPSTR pszNtAcct = NULL;
  903. LPSTR pszNtPwd = NULL;
  904. LPSTR pszName = NULL;
  905. LPBYTE pRes;
  906. DWORD cRes;
  907. DWORD cName;
  908. DWORD cNtAcct;
  909. DWORD cNtPwd;
  910. WCHAR achIndex[LOCAL_MAX_SIZE];
  911. VARIANT vOldAcct;
  912. VARIANT vOldCert;
  913. VARIANT vOldPwd;
  914. VARIANT vOldName;
  915. VARIANT vOldEnabledFlag;
  916. PCCERT_CONTEXT pcCert = NULL;
  917. //
  918. // Do some sanity checks on the cert
  919. //
  920. if ( SUCCEEDED( hres = GetStringFromVariant( &vCert,
  921. (LPSTR*)&pbCert,
  922. &cCert,
  923. FALSE ) ) )
  924. {
  925. //
  926. // try to construct a cert context
  927. //
  928. if ( !( pcCert = CertCreateCertificateContext( X509_ASN_ENCODING,
  929. pbCert,
  930. cCert ) ) )
  931. {
  932. DBGPRINTF((DBG_CONTEXT,
  933. "Invalid cert passed to CreateMapping()\n"));
  934. //
  935. // If the decoding fails, GetLastError() returns an ASN1 decoding
  936. // error that is obtained by subtracting CRYPT_E_OSS_ERROR from the returned
  937. // error and looking in file asn1code.h for the actual error. To avoid the
  938. // cryptic ASN1 errors, we'll just return a general "invalid arg" error
  939. //
  940. hres = RETURNCODETOHRESULT( E_INVALIDARG );
  941. FreeString( (LPSTR) pbCert );
  942. goto Exit;
  943. }
  944. CertFreeCertificateContext( pcCert );
  945. }
  946. else
  947. {
  948. goto Exit;
  949. }
  950. //
  951. // check if we already have a mapping for this cert; if we do, we'll replace that mapping
  952. // with the new one
  953. //
  954. if ( SUCCEEDED( hres = GetMapping( IISMAPPER_LOCATE_BY_CERT,
  955. vCert,
  956. &vOldCert,
  957. &vOldAcct,
  958. &vOldPwd,
  959. &vOldName,
  960. &vOldEnabledFlag ) ) )
  961. {
  962. DBGPRINTF((DBG_CONTEXT,
  963. "Replacing old 1-1 cert mapping with new mapping\n"));
  964. if ( FAILED( hres = SetName( IISMAPPER_LOCATE_BY_CERT,
  965. vCert,
  966. bstrName ) ) ||
  967. FAILED( hres = SetAcct( IISMAPPER_LOCATE_BY_CERT,
  968. vCert,
  969. bstrNtAcct ) ) ||
  970. FAILED( hres = SetPwd( IISMAPPER_LOCATE_BY_CERT,
  971. vCert,
  972. bstrNtPwd ) ) ||
  973. FAILED( hres = SetEnabled( IISMAPPER_LOCATE_BY_CERT,
  974. vCert,
  975. lEnabled ) ) )
  976. {
  977. hres; //NOP - Something failed
  978. }
  979. }
  980. //
  981. // New mapping
  982. //
  983. else if ( hres == RETURNCODETOHRESULT( ERROR_PATH_NOT_FOUND ) )
  984. {
  985. //
  986. // check mapping exists, create if not
  987. //
  988. hres = OpenMd( L"Cert11", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  989. if ( hres == RETURNCODETOHRESULT( ERROR_PATH_NOT_FOUND ) )
  990. {
  991. if ( SUCCEEDED( hres = OpenMd( L"",
  992. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  993. {
  994. hres = CreateMdObject( L"Cert11" );
  995. CloseMd( FALSE );
  996. // Reopen to the correct node.
  997. hres = OpenMd( L"Cert11", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  998. }
  999. }
  1000. if ( FAILED( hres ) )
  1001. {
  1002. goto Exit;
  1003. }
  1004. //
  1005. // adding mapping cert "0" means add @ end of list
  1006. //
  1007. if ( SUCCEEDED( hres = CreateMdObject( L"mappings/0" ) ) )
  1008. {
  1009. if ( SUCCEEDED( hres = GetMdData( L"", MD_NSEPM_ACCESS_CERT, DWORD_METADATA, &
  1010. cRes, &pRes ) ) )
  1011. {
  1012. if ( cRes == sizeof(DWORD ) )
  1013. {
  1014. wsprintfW( achIndex, L"mappings/%u", *(LPDWORD)pRes );
  1015. if ( FAILED( hres = GetStringFromBSTR( bstrNtAcct, &pszNtAcct, &cNtAcct ) ) ||
  1016. FAILED( hres = GetStringFromBSTR( bstrNtPwd, &pszNtPwd, &cNtPwd ) ) ||
  1017. FAILED( hres = GetStringFromBSTR( bstrName, &pszName, &cName ) ) ||
  1018. FAILED( hres = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA,
  1019. sizeof(DWORD), (LPBYTE)&lEnabled ) ) ||
  1020. FAILED( hres = SetMdData( achIndex, MD_MAPNAME, STRING_METADATA,
  1021. cName, (LPBYTE)pszName ) ) ||
  1022. FAILED( hres = SetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA,
  1023. cNtPwd, (LPBYTE)pszNtPwd ) ) ||
  1024. FAILED( hres = SetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA,
  1025. cNtAcct, (LPBYTE)pszNtAcct ) ) ||
  1026. FAILED( hres = SetMdData( achIndex, MD_MAPCERT, BINARY_METADATA,
  1027. cCert, (LPBYTE)pbCert ) ) )
  1028. {
  1029. }
  1030. }
  1031. else
  1032. {
  1033. hres = E_FAIL;
  1034. }
  1035. }
  1036. }
  1037. }
  1038. CloseMd( SUCCEEDED( hres ) );
  1039. FreeString( (LPSTR)pbCert );
  1040. FreeString( pszNtAcct );
  1041. FreeString( pszNtPwd );
  1042. FreeString( pszName );
  1043. Exit:
  1044. return hres;
  1045. }
  1046. HRESULT
  1047. CIISDsCrMap::GetMapping(
  1048. LONG lMethod,
  1049. VARIANT vKey,
  1050. VARIANT* pvCert,
  1051. VARIANT* pbstrNtAcct,
  1052. VARIANT* pbstrNtPwd,
  1053. VARIANT* pbstrName,
  1054. VARIANT* plEnabled
  1055. )
  1056. /*++
  1057. Routine Description:
  1058. Get a mapping entry using key
  1059. Arguments:
  1060. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1061. vKey - key to use to locate mapping
  1062. pvCert - X.509 certificate
  1063. pbstrNtAcct - NT acct to map to
  1064. pbstrNtPwd - NT pwd
  1065. pbstrName - friendly name for mapping entry
  1066. plEnabled - 1 to enable mapping entry, 0 to disable it
  1067. Returns:
  1068. COM status
  1069. --*/
  1070. {
  1071. if ( m_fIsIIS6 )
  1072. {
  1073. return GetMappingIIS6( lMethod,
  1074. vKey,
  1075. pvCert,
  1076. pbstrNtAcct,
  1077. pbstrNtPwd,
  1078. pbstrName,
  1079. plEnabled );
  1080. }
  1081. WCHAR achIndex[LOCAL_MAX_SIZE];
  1082. HRESULT hres;
  1083. DWORD dwLen;
  1084. LPBYTE pbData;
  1085. VariantInit( pvCert );
  1086. VariantInit( pbstrNtAcct );
  1087. VariantInit( pbstrNtPwd );
  1088. VariantInit( pbstrName );
  1089. VariantInit( plEnabled );
  1090. if ( SUCCEEDED( hres = OpenMd( L"Cert11",
  1091. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  1092. {
  1093. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  1094. {
  1095. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPCERT, BINARY_METADATA, &dwLen,
  1096. &pbData ) ) )
  1097. {
  1098. hres = SetVariantAsByteArray( pvCert, dwLen, pbData );
  1099. LocalFree( pbData );
  1100. }
  1101. else
  1102. {
  1103. goto Done;
  1104. }
  1105. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA, &dwLen,
  1106. &pbData ) ) )
  1107. {
  1108. hres = SetVariantAsBSTR( pbstrNtAcct, dwLen, pbData );
  1109. LocalFree( pbData );
  1110. }
  1111. else
  1112. {
  1113. goto Done;
  1114. }
  1115. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA, &dwLen,
  1116. &pbData ) ) )
  1117. {
  1118. hres = SetVariantAsBSTR( pbstrNtPwd, dwLen, pbData );
  1119. LocalFree( pbData );
  1120. }
  1121. else
  1122. {
  1123. goto Done;
  1124. }
  1125. if ( SUCCEEDED( hres = GetMdData( achIndex, MD_MAPNAME, STRING_METADATA, &dwLen,
  1126. &pbData ) ) )
  1127. {
  1128. hres = SetVariantAsBSTR( pbstrName, dwLen, pbData );
  1129. LocalFree( pbData );
  1130. }
  1131. else
  1132. {
  1133. goto Done;
  1134. }
  1135. if ( FAILED( hres = GetMdData( achIndex, MD_MAPENABLED, STRING_METADATA, &dwLen,
  1136. &pbData ) ) )
  1137. {
  1138. SetVariantAsLong( plEnabled, FALSE );
  1139. }
  1140. else
  1141. {
  1142. SetVariantAsLong( plEnabled, *(LPDWORD)pbData );
  1143. LocalFree( pbData );
  1144. }
  1145. }
  1146. Done:
  1147. CloseMd( FALSE );
  1148. }
  1149. return hres;
  1150. }
  1151. HRESULT
  1152. CIISDsCrMap::DeleteMapping(
  1153. LONG lMethod,
  1154. VARIANT vKey
  1155. )
  1156. /*++
  1157. Routine Description:
  1158. Delete a mapping entry using key
  1159. Arguments:
  1160. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1161. vKey - key to use to locate mapping
  1162. Returns:
  1163. COM status
  1164. --*/
  1165. {
  1166. if ( m_fIsIIS6 )
  1167. {
  1168. return DeleteMappingIIS6( lMethod,
  1169. vKey );
  1170. }
  1171. WCHAR achIndex[LOCAL_MAX_SIZE];
  1172. HRESULT hres;
  1173. if ( SUCCEEDED( hres = OpenMd( L"Cert11",
  1174. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  1175. {
  1176. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  1177. {
  1178. hres = DeleteMdObject( achIndex );
  1179. }
  1180. CloseMd( TRUE );
  1181. }
  1182. return hres;
  1183. }
  1184. HRESULT
  1185. CIISDsCrMap::SetEnabled(
  1186. LONG lMethod,
  1187. VARIANT vKey,
  1188. LONG lEnabled
  1189. )
  1190. /*++
  1191. Routine Description:
  1192. Set the enable flag on a mapping entry using key
  1193. Arguments:
  1194. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1195. vKey - key to use to locate mapping
  1196. lEnabled - 1 to enable, 0 to disable
  1197. Returns:
  1198. COM status
  1199. --*/
  1200. {
  1201. if ( m_fIsIIS6 )
  1202. {
  1203. return SetEnabledIIS6( lMethod,
  1204. vKey,
  1205. lEnabled );
  1206. }
  1207. WCHAR achIndex[LOCAL_MAX_SIZE];
  1208. HRESULT hres;
  1209. if ( SUCCEEDED( hres = OpenMd( L"Cert11",
  1210. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  1211. {
  1212. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  1213. {
  1214. hres = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA, sizeof(DWORD), (LPBYTE)&lEnabled );
  1215. }
  1216. CloseMd( TRUE );
  1217. }
  1218. return hres;
  1219. }
  1220. HRESULT
  1221. CIISDsCrMap::SetName(
  1222. LONG lMethod,
  1223. VARIANT vKey,
  1224. BSTR bstrName
  1225. )
  1226. /*++
  1227. Routine Description:
  1228. Set the Name on a mapping entry using key
  1229. Arguments:
  1230. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1231. vKey - key to use to locate mapping
  1232. bstrName - name to assign to mapping entry
  1233. Returns:
  1234. COM status
  1235. --*/
  1236. {
  1237. if ( m_fIsIIS6 )
  1238. {
  1239. return SetNameIIS6( lMethod,
  1240. vKey,
  1241. bstrName );
  1242. }
  1243. return SetString( lMethod, vKey, bstrName, MD_MAPNAME );
  1244. }
  1245. HRESULT
  1246. CIISDsCrMap::SetString(
  1247. LONG lMethod,
  1248. VARIANT vKey,
  1249. BSTR bstrName,
  1250. DWORD dwProp
  1251. )
  1252. /*++
  1253. Routine Description:
  1254. Set a string property on a mapping entry using key
  1255. Arguments:
  1256. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1257. vKey - key to use to locate mapping
  1258. bstrName - string content to assign to mapping entry
  1259. dwProp - property ID to assign to
  1260. Returns:
  1261. COM status
  1262. --*/
  1263. {
  1264. WCHAR achIndex[LOCAL_MAX_SIZE];
  1265. LPSTR pszName = NULL;
  1266. HRESULT hres;
  1267. DWORD dwLen;
  1268. if ( FAILED( hres = GetStringFromBSTR( bstrName, &pszName, &dwLen, TRUE ) ) )
  1269. {
  1270. return hres;
  1271. }
  1272. if ( SUCCEEDED( hres = OpenMd( L"Cert11",
  1273. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  1274. {
  1275. if ( SUCCEEDED(hres = Locate( lMethod, vKey, achIndex )) )
  1276. {
  1277. hres = SetMdData( achIndex, dwProp, STRING_METADATA, dwLen, (LPBYTE)pszName );
  1278. }
  1279. CloseMd( TRUE );
  1280. }
  1281. FreeString( pszName );
  1282. return hres;
  1283. }
  1284. HRESULT
  1285. CIISDsCrMap::SetPwd(
  1286. LONG lMethod,
  1287. VARIANT vKey,
  1288. BSTR bstrPwd
  1289. )
  1290. /*++
  1291. Routine Description:
  1292. Set the Password on a mapping entry using key
  1293. Arguments:
  1294. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1295. vKey - key to use to locate mapping
  1296. bstrPwd - password to assign to mapping entry
  1297. Returns:
  1298. COM status
  1299. --*/
  1300. {
  1301. if ( m_fIsIIS6 )
  1302. {
  1303. return SetPwdIIS6( lMethod,
  1304. vKey,
  1305. bstrPwd );
  1306. }
  1307. return SetString( lMethod, vKey, bstrPwd, MD_MAPNTPWD );
  1308. }
  1309. HRESULT
  1310. CIISDsCrMap::SetAcct(
  1311. LONG lMethod,
  1312. VARIANT vKey,
  1313. BSTR bstrAcct
  1314. )
  1315. /*++
  1316. Routine Description:
  1317. Set the NT account name on a mapping entry using key
  1318. Arguments:
  1319. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1320. vKey - key to use to locate mapping
  1321. bstrAcct - NT account name to assign to mapping entry
  1322. Returns:
  1323. COM status
  1324. --*/
  1325. {
  1326. if ( m_fIsIIS6 )
  1327. {
  1328. return SetAcctIIS6( lMethod,
  1329. vKey,
  1330. bstrAcct );
  1331. }
  1332. return SetString( lMethod, vKey, bstrAcct, MD_MAPNTACCT );
  1333. }
  1334. ////
  1335. HRESULT
  1336. CIISDsCrMap::OpenMd(
  1337. LPWSTR pszOpenPath,
  1338. DWORD dwPermission
  1339. )
  1340. /*++
  1341. Routine Description:
  1342. Open metabase using path & permission
  1343. path is relative to the top of the name space extension ( i.e. /.../<nsepm> )
  1344. Arguments:
  1345. pszOpenPath - path to open inside name space extension
  1346. dwPermission - metabase permission ( read/write )
  1347. Returns:
  1348. COM status
  1349. --*/
  1350. {
  1351. HRESULT hres;
  1352. LPWSTR pszPath;
  1353. UINT cL = wcslen( m_pszMetabasePath );
  1354. pszPath = (LPWSTR)LocalAlloc( LMEM_FIXED, (wcslen(pszOpenPath) + 1 + cL + 1)*sizeof(WCHAR) );
  1355. if ( pszPath == NULL )
  1356. {
  1357. return E_OUTOFMEMORY;
  1358. }
  1359. memcpy( pszPath, m_pszMetabasePath, cL * sizeof(WCHAR) );
  1360. if ( cL && m_pszMetabasePath[cL-1] != L'/' && *pszOpenPath && *pszOpenPath != L'/' )
  1361. {
  1362. pszPath[cL++] = L'/';
  1363. }
  1364. wcscpy( pszPath + cL, pszOpenPath );
  1365. hres = OpenAdminBaseKey(
  1366. m_pszServerName,
  1367. pszPath,
  1368. dwPermission,
  1369. &m_pcAdmCom,
  1370. &m_hmd
  1371. );
  1372. LocalFree( pszPath );
  1373. if ( FAILED(hres) )
  1374. {
  1375. m_hmd = NULL;
  1376. }
  1377. return hres;
  1378. }
  1379. HRESULT
  1380. CIISDsCrMap::CloseMd(
  1381. BOOL fSave
  1382. )
  1383. /*++
  1384. Routine Description:
  1385. close metabase
  1386. Arguments:
  1387. fSave - TRUE to save data immediatly
  1388. Returns:
  1389. COM status
  1390. --*/
  1391. {
  1392. CloseAdminBaseKey( m_pcAdmCom, m_hmd );
  1393. m_hmd = NULL;
  1394. if ( m_pcAdmCom && fSave )
  1395. {
  1396. m_pcAdmCom->SaveData();
  1397. }
  1398. return S_OK;
  1399. }
  1400. HRESULT
  1401. CIISDsCrMap::DeleteMdObject(
  1402. LPWSTR pszKey
  1403. )
  1404. /*++
  1405. Routine Description:
  1406. Delete metabase object in an opened tree
  1407. OpenMd() must be called 1st
  1408. Arguments:
  1409. pszKey - key to delete in opened metabase
  1410. Returns:
  1411. COM status
  1412. --*/
  1413. {
  1414. return m_pcAdmCom->DeleteKey( m_hmd, pszKey );
  1415. }
  1416. HRESULT
  1417. CIISDsCrMap::CreateMdObject(
  1418. LPWSTR pszKey
  1419. )
  1420. /*++
  1421. Routine Description:
  1422. Create metabase object in an opened tree
  1423. OpenMd() must be called 1st
  1424. Arguments:
  1425. pszKey - key to create in opened metabase
  1426. Returns:
  1427. COM status
  1428. --*/
  1429. {
  1430. return m_pcAdmCom->AddKey( m_hmd, pszKey );
  1431. }
  1432. HRESULT
  1433. CIISDsCrMap::SetMdData(
  1434. LPWSTR achIndex,
  1435. DWORD dwProp,
  1436. DWORD dwDataType,
  1437. DWORD dwDataLen,
  1438. LPBYTE pbData
  1439. )
  1440. /*++
  1441. Routine Description:
  1442. Set a metabase property
  1443. OpenMd() must be called 1st
  1444. Property will be stored with NULL attribute, except for MD_MAPPWD
  1445. which will be stored with METADATA_SECURE
  1446. Arguments:
  1447. achIndex - key name where to store property
  1448. dwProp - property ID
  1449. dwDataType - property data type
  1450. dwDataLen - property length
  1451. pbData - property value
  1452. Returns:
  1453. COM status
  1454. --*/
  1455. {
  1456. METADATA_RECORD md;
  1457. md.dwMDDataLen = dwDataLen;
  1458. md.dwMDDataType = dwDataType;
  1459. md.dwMDIdentifier = dwProp;
  1460. md.dwMDAttributes = (dwProp == MD_MAPNTPWD) ? METADATA_SECURE : 0;
  1461. md.pbMDData = pbData;
  1462. return m_pcAdmCom->SetData( m_hmd, achIndex, &md );
  1463. }
  1464. HRESULT
  1465. CIISDsCrMap::GetMdData(
  1466. LPWSTR achIndex,
  1467. DWORD dwProp,
  1468. DWORD dwDataType,
  1469. LPDWORD pdwDataLen,
  1470. LPBYTE* ppbData
  1471. )
  1472. /*++
  1473. Routine Description:
  1474. Get a metabase property
  1475. OpenMd() must be called 1st
  1476. Arguments:
  1477. achIndex - key name where to get property
  1478. dwProp - property ID
  1479. dwDataType - property data type
  1480. pdwDataLen - property length
  1481. ppData - property value, to be freed using LocalFree() on successfull return
  1482. Returns:
  1483. COM status
  1484. --*/
  1485. {
  1486. HRESULT hres;
  1487. METADATA_RECORD md;
  1488. DWORD dwRequired;
  1489. md.dwMDDataLen = 0;
  1490. md.dwMDDataType = dwDataType;
  1491. md.dwMDIdentifier = dwProp;
  1492. md.dwMDAttributes = 0;
  1493. md.pbMDData = NULL;
  1494. if ( FAILED(hres = m_pcAdmCom->GetData( m_hmd, achIndex, &md, &dwRequired )) )
  1495. {
  1496. if ( hres == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER) )
  1497. {
  1498. if ( (*ppbData = (LPBYTE)LocalAlloc( LMEM_FIXED, dwRequired )) == NULL )
  1499. {
  1500. return E_OUTOFMEMORY;
  1501. }
  1502. md.pbMDData = *ppbData;
  1503. md.dwMDDataLen = dwRequired;
  1504. hres = m_pcAdmCom->GetData( m_hmd, achIndex, &md, &dwRequired );
  1505. *pdwDataLen = md.dwMDDataLen;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. *pdwDataLen = 0;
  1511. *ppbData = NULL;
  1512. }
  1513. return hres;
  1514. }
  1515. //////
  1516. HRESULT
  1517. CIISDsCrMap::Locate(
  1518. LONG lMethod,
  1519. VARIANT vKey,
  1520. LPWSTR pszResKey
  1521. )
  1522. /*++
  1523. Routine Description:
  1524. Locate a mapping entry based on key
  1525. OpenMd() must be called 1st
  1526. Arguments:
  1527. lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  1528. vKey - key to use to locate mapping
  1529. pszResKey -
  1530. Returns:
  1531. COM status
  1532. --*/
  1533. {
  1534. if ( m_fIsIIS6 )
  1535. {
  1536. return LocateIIS6( lMethod,
  1537. vKey,
  1538. pszResKey );
  1539. }
  1540. HRESULT hres;
  1541. LPSTR pV = NULL;
  1542. DWORD cV;
  1543. DWORD dwProp;
  1544. LPSTR pRes;
  1545. DWORD cRes;
  1546. BOOL fAddDelim = TRUE;
  1547. //
  1548. // determine method
  1549. //
  1550. switch ( lMethod )
  1551. {
  1552. case IISMAPPER_LOCATE_BY_CERT:
  1553. dwProp = MD_NSEPM_ACCESS_CERT;
  1554. fAddDelim = FALSE;
  1555. break;
  1556. case IISMAPPER_LOCATE_BY_NAME:
  1557. dwProp = MD_NSEPM_ACCESS_NAME;
  1558. break;
  1559. case IISMAPPER_LOCATE_BY_ACCT:
  1560. dwProp = MD_NSEPM_ACCESS_ACCOUNT;
  1561. break;
  1562. case IISMAPPER_LOCATE_BY_INDEX:
  1563. if ( SUCCEEDED( hres = GetStringFromVariant( &vKey, &pV, &cV, TRUE ) ) )
  1564. {
  1565. WCHAR pwV[LOCAL_MAX_SIZE];
  1566. int i = MultiByteToWideChar(CP_ACP, 0, pV, cV, pwV, LOCAL_MAX_SIZE);
  1567. if (i ==0)
  1568. return E_FAIL; // MultiByteToWideChar failure
  1569. if (i >= (int)(LOCAL_MAX_SIZE - wcslen(L"mappings/")))
  1570. return E_FAIL; //pwV is too big for pszResKey
  1571. wsprintfW( pszResKey, L"mappings/%s", pwV );
  1572. }
  1573. goto Exit;
  1574. default:
  1575. return E_FAIL;
  1576. }
  1577. //
  1578. // get ptr to data
  1579. //
  1580. if ( SUCCEEDED( hres = GetStringFromVariant( &vKey, &pV, &cV, fAddDelim ) ) )
  1581. {
  1582. //
  1583. // set search prop, get result
  1584. //
  1585. if ( SUCCEEDED( hres = SetMdData( L"", dwProp, BINARY_METADATA, cV, (LPBYTE)pV ) ) )
  1586. {
  1587. if ( SUCCEEDED( hres = GetMdData( L"", dwProp, DWORD_METADATA, &cRes, (LPBYTE*)&pRes ) ) )
  1588. {
  1589. if ( cRes == sizeof(DWORD ) )
  1590. {
  1591. wsprintfW( pszResKey, L"mappings/%u", *(LPDWORD)pRes );
  1592. }
  1593. else
  1594. {
  1595. hres = E_FAIL;
  1596. }
  1597. LocalFree( pRes );
  1598. }
  1599. }
  1600. }
  1601. Exit:
  1602. FreeString( pV );
  1603. return hres;
  1604. }
  1605. HRESULT
  1606. GetStringFromBSTR(
  1607. BSTR bstr,
  1608. LPSTR* psz,
  1609. LPDWORD pdwLen,
  1610. BOOL fAddDelimInCount
  1611. )
  1612. /*++
  1613. Routine Description:
  1614. Allocate string buffer from BSTR
  1615. Arguments:
  1616. bstr - bstr to convert from
  1617. psz - updated with ptr to buffer, to be freed with FreeString()
  1618. pdwLen - updated with strlen(string), incremented by 1 if fAddDelimInCount is TRUE
  1619. fAddDelimInCount - TRUE to increment *pdwLen
  1620. Returns:
  1621. COM status
  1622. --*/
  1623. {
  1624. UINT cch = SysStringLen(bstr);
  1625. UINT cchT;
  1626. // include NULL terminator
  1627. *pdwLen = cch + (fAddDelimInCount ? 1 : 0);
  1628. CHAR *szNew = (CHAR*)LocalAlloc( LMEM_FIXED, (2 * cch) + 1); // * 2 for worst case DBCS string
  1629. if (szNew == NULL)
  1630. {
  1631. return E_OUTOFMEMORY;
  1632. }
  1633. cchT = WideCharToMultiByte(CP_ACP, 0, bstr, cch + 1, szNew, (2 * cch) + 1, NULL, NULL);
  1634. *psz = szNew;
  1635. return NOERROR;
  1636. }
  1637. HRESULT
  1638. GetStringFromVariant(
  1639. VARIANT* pVar,
  1640. LPSTR* psz,
  1641. LPDWORD pdwLen,
  1642. BOOL fAddDelim
  1643. )
  1644. /*++
  1645. Routine Description:
  1646. Allocate string buffer from BSTR
  1647. Arguments:
  1648. pVar - variant to convert from. Recognizes BSTR, VT_ARRAY|VT_UI1, ByRef or ByVal
  1649. psz - updated with ptr to buffer, to be freed with FreeString()
  1650. pdwLen - updated with size of input, incremented by 1 if fAddDelimInCount is TRUE
  1651. fAddDelimInCount - TRUE to increment *pdwLen
  1652. Returns:
  1653. COM status
  1654. --*/
  1655. {
  1656. LPBYTE pbV;
  1657. UINT cV;
  1658. HRESULT hres;
  1659. WORD vt = V_VT(pVar);
  1660. BOOL fByRef = FALSE;
  1661. VARIANT vOut;
  1662. VariantInit( &vOut );
  1663. if ( vt & VT_BYREF )
  1664. {
  1665. vt &= ~VT_BYREF;
  1666. fByRef = TRUE;
  1667. }
  1668. if ( vt == VT_DISPATCH )
  1669. {
  1670. if ( FAILED(hres = VariantResolveDispatch( &vOut, pVar )) )
  1671. {
  1672. return hres;
  1673. }
  1674. pVar = &vOut;
  1675. vt = V_VT(pVar);
  1676. if ( fByRef = vt & VT_BYREF )
  1677. {
  1678. vt &= ~VT_BYREF;
  1679. }
  1680. }
  1681. // if pVar is BSTR, convert to multibytes
  1682. if ( vt == VT_VARIANT )
  1683. {
  1684. pVar = (VARIANT*)V_BSTR(pVar);
  1685. vt = V_VT(pVar);
  1686. if ( fByRef = vt & VT_BYREF )
  1687. {
  1688. vt &= ~VT_BYREF;
  1689. }
  1690. }
  1691. if ( vt == VT_BSTR )
  1692. {
  1693. hres = GetStringFromBSTR( fByRef ?
  1694. *(BSTR*)V_BSTR(pVar) :
  1695. V_BSTR(pVar),
  1696. psz,
  1697. pdwLen,
  1698. fAddDelim );
  1699. }
  1700. else if( vt == (VT_ARRAY | VT_UI1) )
  1701. {
  1702. long lBound, uBound, lItem;
  1703. BYTE bValue;
  1704. SAFEARRAY* pSafeArray;
  1705. // array of VT_UI1 (probably OctetString)
  1706. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  1707. hres = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  1708. hres = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  1709. cV = uBound - lBound + 1;
  1710. if ( !(pbV = (LPBYTE)LocalAlloc( LMEM_FIXED, cV )) )
  1711. {
  1712. hres = E_OUTOFMEMORY;
  1713. goto Exit;
  1714. }
  1715. hres = S_OK;
  1716. for( lItem = lBound; lItem <= uBound ; lItem++ )
  1717. {
  1718. hres = SafeArrayGetElement( pSafeArray, &lItem, &bValue );
  1719. if( FAILED( hres ) )
  1720. {
  1721. break;
  1722. }
  1723. pbV[lItem-lBound] = bValue;
  1724. }
  1725. *psz = (LPSTR)pbV;
  1726. *pdwLen = cV;
  1727. }
  1728. else if( vt == (VT_ARRAY | VT_VARIANT) )
  1729. {
  1730. long lBound, uBound, lItem;
  1731. VARIANT vValue;
  1732. BYTE bValue;
  1733. SAFEARRAY* pSafeArray;
  1734. // array of VT_VARIANT (probably VT_I4 )
  1735. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  1736. hres = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  1737. hres = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  1738. cV = uBound - lBound + 1;
  1739. if ( !(pbV = (LPBYTE)LocalAlloc( LMEM_FIXED, cV )) )
  1740. {
  1741. hres = E_OUTOFMEMORY;
  1742. goto Exit;
  1743. }
  1744. hres = S_OK;
  1745. for( lItem = lBound; lItem <= uBound ; lItem++ )
  1746. {
  1747. hres = SafeArrayGetElement( pSafeArray, &lItem, &vValue );
  1748. if( FAILED( hres ) )
  1749. {
  1750. break;
  1751. }
  1752. if ( V_VT(&vValue) == VT_UI1 )
  1753. {
  1754. bValue = V_UI1(&vValue);
  1755. }
  1756. else if ( V_VT(&vValue) == VT_I2 )
  1757. {
  1758. bValue = (BYTE)V_I2(&vValue);
  1759. }
  1760. else if ( V_VT(&vValue) == VT_I4 )
  1761. {
  1762. bValue = (BYTE)V_I4(&vValue);
  1763. }
  1764. else
  1765. {
  1766. bValue = 0;
  1767. }
  1768. pbV[lItem-lBound] = bValue;
  1769. }
  1770. *psz = (LPSTR)pbV;
  1771. *pdwLen = cV;
  1772. }
  1773. else
  1774. {
  1775. hres = E_FAIL;
  1776. }
  1777. Exit:
  1778. VariantClear( &vOut );
  1779. return hres;
  1780. }
  1781. HRESULT
  1782. GetStringAFromBSTR(
  1783. BSTR bstr,
  1784. LPSTR* psz,
  1785. LPDWORD pdwLen,
  1786. BOOL fAddDelimInCount
  1787. )
  1788. /*++
  1789. Routine Description:
  1790. Allocate string buffer from BSTR - for IIS6 only
  1791. Arguments:
  1792. bstr - bstr to convert from
  1793. psz - updated with ptr to buffer, to be freed with FreeString()
  1794. pdwLen - updated with strlen(string), incremented by 1 if fAddDelimInCount is TRUE
  1795. fAddDelimInCount - TRUE to increment *pdwLen
  1796. Returns:
  1797. COM status
  1798. --*/
  1799. {
  1800. UINT cch = SysStringLen(bstr);
  1801. UINT cchT;
  1802. // include NULL terminator
  1803. *pdwLen = cch + (fAddDelimInCount ? 1 : 0);
  1804. CHAR *szNew = (CHAR*)LocalAlloc( LMEM_FIXED, (2 * cch) + 1); // * 2 for worst case DBCS string
  1805. if (szNew == NULL)
  1806. {
  1807. return E_OUTOFMEMORY;
  1808. }
  1809. cchT = WideCharToMultiByte(CP_ACP, 0, bstr, cch + 1, szNew, (2 * cch) + 1, NULL, NULL);
  1810. *psz = szNew;
  1811. return NOERROR;
  1812. }
  1813. HRESULT
  1814. GetBlobFromVariant(
  1815. VARIANT* pVar,
  1816. PBYTE* ppbOut,
  1817. LPDWORD pcbOut
  1818. )
  1819. /*++
  1820. Routine Description:
  1821. Allocate string buffer from BSTR - for IIS6 only
  1822. Arguments:
  1823. pVar - variant to convert from. Recognizes BSTR, VT_ARRAY|VT_UI1, ByRef or ByVal
  1824. ppbOut - updated with ptr to buffer, to be freed with LocalFree()
  1825. pcbOut - updated with size of input
  1826. Returns:
  1827. COM status
  1828. --*/
  1829. {
  1830. LPBYTE pbV;
  1831. UINT cV;
  1832. HRESULT hres;
  1833. WORD vt = V_VT(pVar);
  1834. BOOL fByRef = FALSE;
  1835. VARIANT vOut;
  1836. VariantInit( &vOut );
  1837. if ( vt & VT_BYREF )
  1838. {
  1839. vt &= ~VT_BYREF;
  1840. fByRef = TRUE;
  1841. }
  1842. if ( vt == VT_DISPATCH )
  1843. {
  1844. if ( FAILED(hres = VariantResolveDispatch( &vOut, pVar )) )
  1845. {
  1846. return hres;
  1847. }
  1848. pVar = &vOut;
  1849. vt = V_VT(pVar);
  1850. if ( fByRef = vt & VT_BYREF )
  1851. {
  1852. vt &= ~VT_BYREF;
  1853. }
  1854. }
  1855. // if pVar is BSTR, convert to multibytes
  1856. if ( vt == VT_VARIANT )
  1857. {
  1858. pVar = (VARIANT*)V_BSTR(pVar);
  1859. vt = V_VT(pVar);
  1860. if ( fByRef = vt & VT_BYREF )
  1861. {
  1862. vt &= ~VT_BYREF;
  1863. }
  1864. }
  1865. if ( vt == VT_BSTR )
  1866. {
  1867. hres = GetStringAFromBSTR( fByRef ?
  1868. *(BSTR*)V_BSTR(pVar) :
  1869. V_BSTR(pVar),
  1870. (LPSTR *)ppbOut,
  1871. pcbOut,
  1872. FALSE );
  1873. }
  1874. else if( vt == (VT_ARRAY | VT_UI1) )
  1875. {
  1876. long lBound, uBound, lItem;
  1877. BYTE bValue;
  1878. SAFEARRAY* pSafeArray;
  1879. // array of VT_UI1 (probably OctetString)
  1880. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  1881. hres = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  1882. hres = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  1883. cV = uBound - lBound + 1;
  1884. if ( !(pbV = (LPBYTE)LocalAlloc( LMEM_FIXED, cV )) )
  1885. {
  1886. hres = E_OUTOFMEMORY;
  1887. goto Exit;
  1888. }
  1889. hres = S_OK;
  1890. for( lItem = lBound; lItem <= uBound ; lItem++ )
  1891. {
  1892. hres = SafeArrayGetElement( pSafeArray, &lItem, &bValue );
  1893. if( FAILED( hres ) )
  1894. {
  1895. break;
  1896. }
  1897. pbV[lItem-lBound] = bValue;
  1898. }
  1899. *ppbOut = pbV;
  1900. *pcbOut = cV;
  1901. }
  1902. else if( vt == (VT_ARRAY | VT_VARIANT) )
  1903. {
  1904. long lBound, uBound, lItem;
  1905. VARIANT vValue;
  1906. BYTE bValue;
  1907. SAFEARRAY* pSafeArray;
  1908. // array of VT_VARIANT (probably VT_I4 )
  1909. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  1910. hres = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  1911. hres = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  1912. cV = uBound - lBound + 1;
  1913. if ( !(pbV = (LPBYTE)LocalAlloc( LMEM_FIXED, cV )) )
  1914. {
  1915. hres = E_OUTOFMEMORY;
  1916. goto Exit;
  1917. }
  1918. hres = S_OK;
  1919. for( lItem = lBound; lItem <= uBound ; lItem++ )
  1920. {
  1921. hres = SafeArrayGetElement( pSafeArray, &lItem, &vValue );
  1922. if( FAILED( hres ) )
  1923. {
  1924. break;
  1925. }
  1926. if ( V_VT(&vValue) == VT_UI1 )
  1927. {
  1928. bValue = V_UI1(&vValue);
  1929. }
  1930. else if ( V_VT(&vValue) == VT_I2 )
  1931. {
  1932. bValue = (BYTE)V_I2(&vValue);
  1933. }
  1934. else if ( V_VT(&vValue) == VT_I4 )
  1935. {
  1936. bValue = (BYTE)V_I4(&vValue);
  1937. }
  1938. else
  1939. {
  1940. bValue = 0;
  1941. }
  1942. pbV[lItem-lBound] = bValue;
  1943. }
  1944. *ppbOut = pbV;
  1945. *pcbOut = cV;
  1946. }
  1947. else
  1948. {
  1949. hres = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  1950. }
  1951. Exit:
  1952. VariantClear( &vOut );
  1953. return hres;
  1954. }
  1955. VOID
  1956. FreeString(
  1957. LPSTR psz
  1958. )
  1959. /*++
  1960. Routine Description:
  1961. Free a string returned by GetStringFromVariant() or GetStringFromBTR()
  1962. can be NULL
  1963. Arguments:
  1964. psz - string to free, can be NULL
  1965. Returns:
  1966. Nothing
  1967. --*/
  1968. {
  1969. if ( psz )
  1970. {
  1971. LocalFree( psz );
  1972. }
  1973. }
  1974. HRESULT
  1975. SetBSTR(
  1976. BSTR* pbstrRet,
  1977. DWORD cch,
  1978. LPBYTE sz
  1979. )
  1980. /*++
  1981. Routine Description:
  1982. Build a BSTR from byte array - for IIS5, IIS5.1 assumes ansi string on input
  1983. Arguments:
  1984. pbstrRet - updated with BSTR
  1985. cch - byte count in sz
  1986. sz - byte array
  1987. Returns:
  1988. COM status
  1989. --*/
  1990. {
  1991. BSTR bstrRet;
  1992. if (sz == NULL)
  1993. {
  1994. *pbstrRet = NULL;
  1995. return(NOERROR);
  1996. }
  1997. // Allocate a string of the desired length
  1998. // SysAllocStringLen allocates enough room for unicode characters plus a null
  1999. // Given a NULL string it will just allocate the space
  2000. bstrRet = SysAllocStringLen(NULL, cch);
  2001. if (bstrRet == NULL)
  2002. {
  2003. return(E_OUTOFMEMORY);
  2004. }
  2005. // If we were given "", we will have cch=0. return the empty bstr
  2006. // otherwise, really copy/convert the string
  2007. // NOTE we pass -1 as 4th parameter of MultiByteToWideChar for DBCS support
  2008. if (cch != 0)
  2009. {
  2010. UINT cchTemp = 0;
  2011. if (MultiByteToWideChar(CP_ACP, 0, (LPSTR)sz, -1, bstrRet, cch+1) == 0)
  2012. {
  2013. SysFreeString(bstrRet);
  2014. return(HRESULT_FROM_WIN32(GetLastError()));
  2015. }
  2016. // If there are some DBCS characters in the sz(Input), then, the character count of BSTR(DWORD) is
  2017. // already set to cch(strlen(sz)) in SysAllocStringLen(NULL, cch), we cannot change the count,
  2018. // and later call of SysStringLen(bstr) always returns the number of characters specified in the
  2019. // cch parameter at allocation time. Bad, because one DBCS character(2 bytes) will convert
  2020. // to one UNICODE character(2 bytes), not 2 UNICODE characters(4 bytes).
  2021. // Example: For input sz contains only one DBCS character, we want to see SysStringLen(bstr)
  2022. // = 1, not 2.
  2023. bstrRet[cch] = 0;
  2024. cchTemp = wcslen(bstrRet);
  2025. if (cchTemp < cch)
  2026. {
  2027. BSTR bstrTemp = SysAllocString(bstrRet);
  2028. SysFreeString(bstrRet);
  2029. bstrRet = bstrTemp;
  2030. cch = cchTemp;
  2031. }
  2032. }
  2033. if (bstrRet != NULL)
  2034. bstrRet[cch] = 0;
  2035. *pbstrRet = bstrRet;
  2036. return(NOERROR);
  2037. }
  2038. HRESULT
  2039. SetBSTRFromStringW(
  2040. BSTR* pbstrRet,
  2041. DWORD cb,
  2042. LPBYTE sz
  2043. )
  2044. /*++
  2045. Routine Description:
  2046. Build a BSTR from byte array (that is actually WCHAR string)
  2047. Arguments:
  2048. pbstrRet - updated with BSTR
  2049. cb - byte count
  2050. sz - byte array (we assume WCHAR string)
  2051. Returns:
  2052. COM status
  2053. --*/
  2054. {
  2055. BSTR bstrRet;
  2056. if (sz == NULL)
  2057. {
  2058. *pbstrRet = NULL;
  2059. return(NOERROR);
  2060. }
  2061. // Allocate a string of the desired length
  2062. // SysAllocStringLen allocates enough room for unicode characters plus a null
  2063. // Given a NULL string it will just allocate the space
  2064. bstrRet = SysAllocStringLen(NULL, cb/sizeof(WCHAR));
  2065. if (bstrRet == NULL)
  2066. {
  2067. return(E_OUTOFMEMORY);
  2068. }
  2069. wcsncpy( bstrRet, (WCHAR *) sz, cb/sizeof(WCHAR) );
  2070. *pbstrRet = bstrRet;
  2071. return(NOERROR);
  2072. }
  2073. HRESULT
  2074. CIISDsCrMap::Create(
  2075. IUnknown *pUnkOuter,
  2076. REFIID riid,
  2077. void **ppvObj
  2078. )
  2079. /*++
  2080. Routine Description:
  2081. Create a CIISDsCrMap
  2082. Arguments:
  2083. pUnkOuter - ptr to iunknown
  2084. riid - requested IID
  2085. ppvObj - updated with ptr to requested IID
  2086. Returns:
  2087. COM status
  2088. --*/
  2089. {
  2090. CCredentials Credentials;
  2091. CIISDsCrMap FAR * pMap = NULL;
  2092. HRESULT hr = S_OK;
  2093. BSTR bstrAdsPath = NULL;
  2094. OBJECTINFO ObjectInfo;
  2095. POBJECTINFO pObjectInfo = &ObjectInfo;
  2096. CLexer * pLexer = NULL;
  2097. LPWSTR pszIISPathName = NULL;
  2098. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  2099. hr = AllocateObject(pUnkOuter, Credentials, &pMap);
  2100. BAIL_ON_FAILURE(hr);
  2101. //
  2102. // get ServerName and pszPath
  2103. //
  2104. hr = pMap->_pADs->get_ADsPath(&bstrAdsPath);
  2105. BAIL_ON_FAILURE(hr);
  2106. pLexer = new CLexer();
  2107. hr = pLexer->Initialize(bstrAdsPath);
  2108. BAIL_ON_FAILURE(hr);
  2109. //
  2110. // Parse the pathname
  2111. //
  2112. hr = ADsObject(pLexer, pObjectInfo);
  2113. BAIL_ON_FAILURE(hr);
  2114. pszIISPathName = AllocADsStr(bstrAdsPath);
  2115. if (!pszIISPathName) {
  2116. hr = E_OUTOFMEMORY;
  2117. BAIL_ON_FAILURE(hr);
  2118. }
  2119. *pszIISPathName = L'\0';
  2120. hr = BuildIISPathFromADsPath(
  2121. pObjectInfo,
  2122. pszIISPathName
  2123. );
  2124. BAIL_ON_FAILURE(hr);
  2125. hr = pMap->Init( pObjectInfo->TreeName,
  2126. pszIISPathName );
  2127. BAIL_ON_FAILURE(hr);
  2128. //
  2129. // pass non-delegating IUnknown back to the aggregator
  2130. //
  2131. *ppvObj = (INonDelegatingUnknown FAR *) pMap;
  2132. if (bstrAdsPath) {
  2133. ADsFreeString(bstrAdsPath);
  2134. }
  2135. if (pLexer) {
  2136. delete pLexer;
  2137. }
  2138. if (pszIISPathName ) {
  2139. FreeADsStr( pszIISPathName );
  2140. }
  2141. FreeObjectInfo( &ObjectInfo );
  2142. RRETURN(hr);
  2143. error:
  2144. if (bstrAdsPath) {
  2145. ADsFreeString(bstrAdsPath);
  2146. }
  2147. if (pLexer) {
  2148. delete pLexer;
  2149. }
  2150. if (pszIISPathName ) {
  2151. FreeADsStr( pszIISPathName );
  2152. }
  2153. FreeObjectInfo( &ObjectInfo );
  2154. *ppvObj = NULL;
  2155. delete pMap;
  2156. RRETURN(hr);
  2157. }
  2158. STDMETHODIMP
  2159. CIISDsCrMap::QueryInterface(
  2160. REFIID iid,
  2161. LPVOID FAR* ppv
  2162. )
  2163. /*++
  2164. Routine Description:
  2165. Query interface to CIISDsCrMap
  2166. Arguments:
  2167. iid - requested IID
  2168. ppv - updated with ptr to requested IID
  2169. Returns:
  2170. COM status
  2171. --*/
  2172. {
  2173. HRESULT hr = S_OK;
  2174. hr = _pUnkOuter->QueryInterface(iid,ppv);
  2175. RRETURN(hr);
  2176. }
  2177. CIISDsCrMap::CIISDsCrMap(
  2178. )
  2179. /*++
  2180. Routine Description:
  2181. CIISDsCrMap constructor
  2182. Arguments:
  2183. pADs - ptr to contained ADs
  2184. Credentials - credential
  2185. pDispMgr - ptr to dispatch manager
  2186. Returns:
  2187. Nothing
  2188. --*/
  2189. {
  2190. m_pcAdmCom = NULL;
  2191. m_hmd = NULL;
  2192. m_pszServerName = NULL;
  2193. m_pszMetabasePath = NULL;
  2194. m_ADsPath = NULL;
  2195. _pADs = NULL;
  2196. _pDispMgr = NULL;
  2197. m_fIsIIS6 = TRUE;
  2198. ENLIST_TRACKING(CIISDsCrMap);
  2199. }
  2200. CIISDsCrMap::~CIISDsCrMap(
  2201. )
  2202. /*++
  2203. Routine Description:
  2204. CIISDsCrMap destructor
  2205. Arguments:
  2206. None
  2207. Returns:
  2208. Nothing
  2209. --*/
  2210. {
  2211. if ( m_ADsPath )
  2212. {
  2213. ADsFreeString( m_ADsPath );
  2214. }
  2215. if ( m_pszServerName )
  2216. {
  2217. LocalFree( m_pszServerName );
  2218. }
  2219. if ( m_pszMetabasePath )
  2220. {
  2221. LocalFree( m_pszMetabasePath );
  2222. }
  2223. if ( _pDispMgr )
  2224. {
  2225. delete _pDispMgr;
  2226. }
  2227. }
  2228. HRESULT
  2229. CIISDsCrMap::AllocateObject(
  2230. IUnknown *pUnkOuter,
  2231. CCredentials& Credentials,
  2232. CIISDsCrMap ** ppMap
  2233. )
  2234. /*++
  2235. Routine Description:
  2236. Allocate CIISDsCrMap
  2237. Arguments:
  2238. pUnkOuter - ptr to iunknown
  2239. Credentials - credential
  2240. ppMap - updated with ptr to IUnknown to Allocated object
  2241. Returns:
  2242. COM status
  2243. --*/
  2244. {
  2245. CIISDsCrMap FAR * pMap = NULL;
  2246. IADs FAR * pADs = NULL;
  2247. CAggregateeDispMgr FAR * pDispMgr = NULL;
  2248. HRESULT hr = S_OK;
  2249. pDispMgr = new CAggregateeDispMgr;
  2250. if (pDispMgr == NULL) {
  2251. hr = E_OUTOFMEMORY;
  2252. }
  2253. BAIL_ON_FAILURE(hr);
  2254. pMap = new CIISDsCrMap();
  2255. if (pMap == NULL) {
  2256. hr = E_OUTOFMEMORY;
  2257. }
  2258. BAIL_ON_FAILURE(hr);
  2259. hr = pDispMgr->LoadTypeInfoEntry(
  2260. LIBID_IISExt, //LIBID_ADs,
  2261. IID_IISDsCrMap,
  2262. (IISDsCrMap *)pMap,
  2263. DISPID_REGULAR
  2264. );
  2265. BAIL_ON_FAILURE(hr);
  2266. //
  2267. // Store the IADs Pointer, but again do NOT ref-count
  2268. // this pointer - we keep the pointer around, but do
  2269. // a release immediately.
  2270. //
  2271. hr = pUnkOuter->QueryInterface(IID_IADs, (void **)&pADs);
  2272. pADs->Release();
  2273. pMap->_pADs = pADs;
  2274. //
  2275. // Store the pointer to the pUnkOuter object
  2276. // AND DO NOT add ref this pointer
  2277. //
  2278. pMap->_pUnkOuter = pUnkOuter;
  2279. pMap->m_Credentials = Credentials;
  2280. pMap->_pDispMgr = pDispMgr;
  2281. *ppMap = pMap;
  2282. RRETURN(hr);
  2283. error:
  2284. delete pDispMgr;
  2285. delete pMap;
  2286. RRETURN(hr);
  2287. }
  2288. HRESULT
  2289. CIISDsCrMap::Init(
  2290. LPWSTR pszServerName,
  2291. LPWSTR pszMetabasePath
  2292. )
  2293. /*++
  2294. Routine Description:
  2295. Initialize CIISDsCrMap
  2296. Arguments:
  2297. pszServerName - target computer name for metabase access
  2298. pszParent - metabase path to IisMapper object
  2299. Returns:
  2300. COM status
  2301. --*/
  2302. {
  2303. UINT cL;
  2304. HRESULT hr = S_OK;
  2305. DWORD dwMajVer = 0;
  2306. DWORD dwLen = 0;
  2307. METADATA_RECORD mr = {
  2308. MD_SERVER_VERSION_MAJOR,
  2309. METADATA_NO_ATTRIBUTES,
  2310. IIS_MD_UT_SERVER,
  2311. DWORD_METADATA,
  2312. sizeof(DWORD),
  2313. (unsigned char*)&dwMajVer,
  2314. 0
  2315. };
  2316. hr = InitServerInfo(pszServerName, &m_pcAdmCom);
  2317. BAIL_ON_FAILURE(hr);
  2318. // need to set m_fIsIIS6
  2319. METADATA_HANDLE MDataHandle;
  2320. hr = OpenAdminBaseKey(pszServerName,
  2321. L"/LM/W3SVC/Info",
  2322. METADATA_PERMISSION_READ,
  2323. &m_pcAdmCom,
  2324. &MDataHandle);
  2325. if (HRESULTTOWIN32(hr) == ERROR_PATH_NOT_FOUND)
  2326. {
  2327. m_fIsIIS6 = FALSE;
  2328. }
  2329. else
  2330. {
  2331. BAIL_ON_FAILURE(hr);
  2332. }
  2333. if (hr == S_OK)
  2334. {
  2335. hr = m_pcAdmCom->GetData(
  2336. MDataHandle,
  2337. L"",
  2338. &mr,
  2339. &dwLen);
  2340. if(hr == MD_ERROR_DATA_NOT_FOUND)
  2341. {
  2342. m_fIsIIS6 = FALSE;
  2343. }
  2344. else
  2345. {
  2346. BAIL_ON_FAILURE(hr);
  2347. }
  2348. if (hr == S_OK)
  2349. {
  2350. if (dwMajVer >= 6)
  2351. {
  2352. m_fIsIIS6 = TRUE;
  2353. }
  2354. else
  2355. {
  2356. m_fIsIIS6 = FALSE;
  2357. }
  2358. }
  2359. }
  2360. hr = S_OK;
  2361. cL = wcslen( pszServerName );
  2362. if ( m_pszServerName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cL + 1 )*sizeof(WCHAR) ) )
  2363. {
  2364. memcpy( m_pszServerName, pszServerName, ( cL + 1 )*sizeof(WCHAR) );
  2365. }
  2366. else
  2367. {
  2368. BAIL_ON_FAILURE(hr=E_OUTOFMEMORY);
  2369. }
  2370. cL = wcslen( pszMetabasePath );
  2371. while ( cL && pszMetabasePath[cL-1] != L'/' && pszMetabasePath[cL-1] != L'\\' )
  2372. {
  2373. --cL;
  2374. }
  2375. if ( m_fIsIIS6 && ( m_pszMetabasePath = (LPWSTR)LocalAlloc( LMEM_FIXED, (( cL + 1 )*sizeof(WCHAR) ) )))
  2376. {
  2377. memcpy( m_pszMetabasePath, pszMetabasePath, cL * sizeof(WCHAR) );
  2378. m_pszMetabasePath[ cL ] = L'\0';
  2379. }
  2380. else if ( !m_fIsIIS6 && ( m_pszMetabasePath = (LPWSTR)LocalAlloc( LMEM_FIXED, ( cL*sizeof(WCHAR) + sizeof(L"<nsepm>") )) ) )
  2381. {
  2382. memcpy( m_pszMetabasePath, pszMetabasePath, cL * sizeof(WCHAR) );
  2383. memcpy( m_pszMetabasePath + cL, L"<nsepm>", sizeof(L"<nsepm>") );
  2384. }
  2385. else
  2386. {
  2387. BAIL_ON_FAILURE(hr=E_OUTOFMEMORY);
  2388. }
  2389. error:
  2390. if (m_pcAdmCom)
  2391. {
  2392. CloseAdminBaseKey(m_pcAdmCom, MDataHandle);
  2393. }
  2394. return hr;
  2395. }
  2396. HRESULT
  2397. SetVariantAsByteArray(
  2398. VARIANT* pvarReturn,
  2399. DWORD cbLen,
  2400. LPBYTE pbIn
  2401. )
  2402. /*++
  2403. Routine Description:
  2404. Create variant as byte array
  2405. Arguments:
  2406. pVarReturn - ptr to created variant
  2407. cbLen - byte count
  2408. pbIn - byte array
  2409. Returns:
  2410. COM status
  2411. --*/
  2412. {
  2413. HRESULT hr;
  2414. SAFEARRAYBOUND rgsabound[1];
  2415. BYTE * pbData = NULL;
  2416. // Set the variant type of the output parameter
  2417. V_VT(pvarReturn) = VT_ARRAY|VT_UI1;
  2418. V_ARRAY(pvarReturn) = NULL;
  2419. // Allocate a SafeArray for the data
  2420. rgsabound[0].lLbound = 0;
  2421. rgsabound[0].cElements = cbLen;
  2422. V_ARRAY(pvarReturn) = SafeArrayCreate(VT_UI1, 1, rgsabound);
  2423. if (V_ARRAY(pvarReturn) == NULL)
  2424. {
  2425. return E_OUTOFMEMORY;
  2426. }
  2427. if (FAILED(SafeArrayAccessData(V_ARRAY(pvarReturn), (void **) &pbData)))
  2428. {
  2429. return E_UNEXPECTED;
  2430. }
  2431. memcpy(pbData, pbIn, cbLen );
  2432. SafeArrayUnaccessData(V_ARRAY(pvarReturn));
  2433. return NOERROR;
  2434. }
  2435. HRESULT
  2436. SetVariantAsBSTR(
  2437. VARIANT* pvarReturn,
  2438. DWORD cbLen,
  2439. LPBYTE pbIn
  2440. )
  2441. /*++
  2442. Routine Description:
  2443. Create variant BSTR
  2444. Arguments:
  2445. pVarReturn - ptr to created variant
  2446. cbLen - byte count
  2447. pbIn - byte array
  2448. Returns:
  2449. COM status
  2450. --*/
  2451. {
  2452. HRESULT hr;
  2453. V_VT(pvarReturn) = VT_BSTR;
  2454. return SetBSTR( &V_BSTR(pvarReturn), cbLen, pbIn );
  2455. }
  2456. HRESULT
  2457. SetVariantAsBSTRFromStringW(
  2458. VARIANT* pvarReturn,
  2459. DWORD cbLen,
  2460. LPBYTE pbIn
  2461. )
  2462. /*++
  2463. Routine Description:
  2464. Create variant BSTR
  2465. Arguments:
  2466. pVarReturn - ptr to created variant
  2467. cbLen - byte count
  2468. pbIn - byte array
  2469. Returns:
  2470. COM status
  2471. --*/
  2472. {
  2473. HRESULT hr;
  2474. V_VT(pvarReturn) = VT_BSTR;
  2475. return SetBSTRFromStringW( &V_BSTR(pvarReturn), cbLen, pbIn );
  2476. }
  2477. HRESULT
  2478. SetVariantAsLong(
  2479. VARIANT* pvarReturn,
  2480. DWORD dwV
  2481. )
  2482. /*++
  2483. Routine Description:
  2484. Create variant as long
  2485. Arguments:
  2486. pVarReturn - ptr to created variant
  2487. dwV - value
  2488. Returns:
  2489. COM status
  2490. --*/
  2491. {
  2492. HRESULT hr;
  2493. V_VT(pvarReturn) = VT_I4;
  2494. V_I4(pvarReturn) = dwV;
  2495. return S_OK;
  2496. }
  2497. HRESULT
  2498. VariantResolveDispatch(
  2499. VARIANT * pVarOut,
  2500. VARIANT * pVarIn
  2501. )
  2502. /*++
  2503. Routine Description:
  2504. Extract value from IDispatch default property
  2505. Arguments:
  2506. pVarOut - ptr to created variant
  2507. pVarIn - ptr to IDispatch variant to resolve
  2508. Returns:
  2509. COM status
  2510. --*/
  2511. {
  2512. VARIANT varResolved; // value of IDispatch::Invoke
  2513. DISPPARAMS dispParamsNoArgs = {NULL, NULL, 0, 0};
  2514. EXCEPINFO ExcepInfo;
  2515. HRESULT hrCopy;
  2516. VariantInit(pVarOut);
  2517. hrCopy = VariantCopy(pVarOut, pVarIn);
  2518. if (FAILED(hrCopy))
  2519. {
  2520. return hrCopy;
  2521. }
  2522. // follow the IDispatch chain.
  2523. //
  2524. while (V_VT(pVarOut) == VT_DISPATCH)
  2525. {
  2526. HRESULT hrInvoke = S_OK;
  2527. // If the variant is equal to Nothing, then it can be argued
  2528. // with certainty that it does not have a default property!
  2529. // hence we return DISP_E_MEMBERNOTFOUND for this case.
  2530. //
  2531. if (V_DISPATCH(pVarOut) == NULL)
  2532. {
  2533. hrInvoke = DISP_E_MEMBERNOTFOUND;
  2534. }
  2535. else
  2536. {
  2537. VariantInit(&varResolved);
  2538. hrInvoke = V_DISPATCH(pVarOut)->Invoke(
  2539. DISPID_VALUE,
  2540. IID_NULL,
  2541. LOCALE_SYSTEM_DEFAULT,
  2542. DISPATCH_PROPERTYGET | DISPATCH_METHOD,
  2543. &dispParamsNoArgs,
  2544. &varResolved,
  2545. &ExcepInfo,
  2546. NULL);
  2547. }
  2548. if (FAILED(hrInvoke))
  2549. {
  2550. if (hrInvoke == DISP_E_EXCEPTION)
  2551. {
  2552. //
  2553. // forward the ExcepInfo from Invoke to caller's ExcepInfo
  2554. //
  2555. SysFreeString(ExcepInfo.bstrHelpFile);
  2556. }
  2557. VariantClear(pVarOut);
  2558. return hrInvoke;
  2559. }
  2560. // The correct code to restart the loop is:
  2561. //
  2562. // VariantClear(pVar)
  2563. // VariantCopy(pVar, &varResolved);
  2564. // VariantClear(&varResolved);
  2565. //
  2566. // however, the same affect can be achieved by:
  2567. //
  2568. // VariantClear(pVar)
  2569. // *pVar = varResolved;
  2570. // VariantInit(&varResolved)
  2571. //
  2572. // this avoids a copy. The equivalence rests in the fact that
  2573. // *pVar will contain the pointers of varResolved, after we
  2574. // trash varResolved (WITHOUT releasing strings or dispatch
  2575. // pointers), so the net ref count is unchanged. For strings,
  2576. // there is still only one pointer to the string.
  2577. //
  2578. // NOTE: the next interation of the loop will do the VariantInit.
  2579. //
  2580. VariantClear(pVarOut);
  2581. *pVarOut = varResolved;
  2582. }
  2583. return S_OK;
  2584. }
  2585. STDMETHODIMP
  2586. CIISDsCrMap::NonDelegatingQueryInterface(
  2587. REFIID iid,
  2588. LPVOID FAR* ppv
  2589. )
  2590. {
  2591. ASSERT(ppv);
  2592. if (IsEqualIID(iid, IID_IISDsCrMap)) {
  2593. *ppv = (IADsUser FAR *) this;
  2594. } else if (IsEqualIID(iid, IID_IADsExtension)) {
  2595. *ppv = (IADsExtension FAR *) this;
  2596. } else if (IsEqualIID(iid, IID_IUnknown)) {
  2597. //
  2598. // probably not needed since our 3rd party extension does not stand
  2599. // alone and provider does not ask for this, but to be safe
  2600. //
  2601. *ppv = (INonDelegatingUnknown FAR *) this;
  2602. } else {
  2603. *ppv = NULL;
  2604. return E_NOINTERFACE;
  2605. }
  2606. //
  2607. // Delegating AddRef to aggregator for IADsExtesnion and IISDsCrMap.
  2608. // AddRef on itself for IPrivateUnknown. (both tested.)
  2609. //
  2610. ((IUnknown *) (*ppv)) -> AddRef();
  2611. return S_OK;
  2612. }
  2613. //
  2614. // IADsExtension::Operate()
  2615. //
  2616. STDMETHODIMP
  2617. CIISDsCrMap::Operate(
  2618. THIS_ DWORD dwCode,
  2619. VARIANT varUserName,
  2620. VARIANT varPassword,
  2621. VARIANT varFlags
  2622. )
  2623. {
  2624. RRETURN(E_NOTIMPL);
  2625. }
  2626. STDMETHODIMP
  2627. CIISDsCrMap::ADSIInitializeDispatchManager(
  2628. long dwExtensionId
  2629. )
  2630. {
  2631. HRESULT hr = S_OK;
  2632. if (_fDispInitialized) {
  2633. RRETURN(E_FAIL);
  2634. }
  2635. hr = _pDispMgr->InitializeDispMgr(dwExtensionId);
  2636. if (SUCCEEDED(hr)) {
  2637. _fDispInitialized = TRUE;
  2638. }
  2639. RRETURN(hr);
  2640. }
  2641. STDMETHODIMP
  2642. CIISDsCrMap::ADSIInitializeObject(
  2643. THIS_ BSTR lpszUserName,
  2644. BSTR lpszPassword,
  2645. long lnReserved
  2646. )
  2647. {
  2648. CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved);
  2649. m_Credentials = NewCredentials;
  2650. RRETURN(S_OK);
  2651. }
  2652. STDMETHODIMP
  2653. CIISDsCrMap::ADSIReleaseObject()
  2654. {
  2655. delete this;
  2656. RRETURN(S_OK);
  2657. }