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

6831 lines
128 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. iismap.cxx
  5. Abstract:
  6. Classes to handle mapping
  7. Author:
  8. Philippe Choquier (phillich) 17-may-1996
  9. --*/
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <wincrypt.h>
  14. //#include <crypt32l.h>
  15. #include "xbf.hxx"
  16. extern "C" {
  17. #include "immd5.h"
  18. }
  19. #include <iis64.h>
  20. #include <iismap.hxx>
  21. #include "iismaprc.h"
  22. #include "mapmsg.h"
  23. #include "iiscmr.hxx"
  24. #include <refb.hxx>
  25. #include <icrypt.hxx>
  26. #include "dbgutil.h"
  27. //
  28. // global vars
  29. //
  30. CRITICAL_SECTION g_csIisMap;
  31. DWORD g_dwGuid = 0;
  32. HKEY g_hKey = NULL;
  33. LPSTR g_pszInstallPath = NULL;
  34. DECLARE_DEBUG_PRINTS_OBJECT();
  35. //
  36. //
  37. //
  38. #if defined(DECODE_ASN1)
  39. PRDN_VALUE_BLOB
  40. CertGetNameField(
  41. UINT iEncoding,
  42. IN LPCTSTR pszObjId,
  43. IN PNAME_INFO pInfo
  44. );
  45. UINT DecodeNames(
  46. IN PNAME_BLOB pNameBlob,
  47. IN LPSTR* pFields,
  48. IN LPSTR pStore
  49. );
  50. UINT DecodeCert(
  51. IN PBYTE pbEncodedCert,
  52. IN DWORD cbEncodedCert,
  53. LPSTR* pFields,
  54. LPSTR pStore
  55. );
  56. #endif
  57. //
  58. // global functions
  59. //
  60. extern "C" int __cdecl
  61. QsortIisMappingCmp(
  62. const void *pA,
  63. const void *pB )
  64. /*++
  65. Routine Description:
  66. Compare function for 2 CIisMapping entries
  67. compare using mask, then all fields as defined in
  68. the linked CIisAcctMapper hierarchy
  69. Arguments:
  70. pA -- ptr to 1st element
  71. pB -- ptr tp 2nd elemet
  72. Returns:
  73. -1 if *pA < *pB, 0 if *pA == *pB, 1 if *pA > *pB
  74. --*/
  75. {
  76. return (*(CIisMapping**)pA)->Cmp( *(CIisMapping**)pB, FALSE );
  77. }
  78. extern "C" int __cdecl
  79. MatchIisMappingCmp(
  80. const void *pA,
  81. const void *pB )
  82. /*++
  83. Routine Description:
  84. Compare function for 2 CIisMapping entries
  85. do not uses mask, uses all fields as defined in
  86. the linked CIisAcctMapper hierarchy
  87. Arguments:
  88. pA -- ptr to 1st element
  89. pB -- ptr tp 2nd elemet
  90. Returns:
  91. -1 if *pA < *pB, 0 if *pA == *pB, 1 if *pA > *pB
  92. --*/
  93. {
  94. return ( *(CIisMapping**)pA)->Cmp( *(CIisMapping**)pB, TRUE );
  95. }
  96. HRESULT
  97. GetSecurityDescriptorForMetabaseExtensionFile(
  98. PSECURITY_DESCRIPTOR * ppsdStorage
  99. )
  100. /*++
  101. Routine Description:
  102. Build security descriptor that will be set for the extension file
  103. *.mp (includes Administrators and System )
  104. Arguments:
  105. ppsdStorage - Security Descriptor to be set for extension file
  106. Returns:
  107. HRESULT
  108. --*/
  109. {
  110. HRESULT hr = ERROR_SUCCESS;
  111. BOOL fRet = FALSE;
  112. DWORD dwDaclSize = 0;
  113. SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
  114. PSID psidSystem = NULL;
  115. PSID psidAdmin = NULL;
  116. PACL paclDiscretionary = NULL;
  117. DBG_ASSERT( ppsdStorage != NULL );
  118. *ppsdStorage = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  119. if ( *ppsdStorage == NULL )
  120. {
  121. hr = HRESULT_FROM_WIN32(GetLastError());
  122. goto exit;
  123. }
  124. //
  125. // Initialize the security descriptor.
  126. //
  127. fRet = InitializeSecurityDescriptor(
  128. *ppsdStorage,
  129. SECURITY_DESCRIPTOR_REVISION
  130. );
  131. if( !fRet )
  132. {
  133. hr = HRESULT_FROM_WIN32(GetLastError());
  134. goto exit;
  135. }
  136. //
  137. // Create the SIDs for the local system and admin group.
  138. //
  139. fRet = AllocateAndInitializeSid(
  140. &ntAuthority,
  141. 1,
  142. SECURITY_LOCAL_SYSTEM_RID,
  143. 0,
  144. 0,
  145. 0,
  146. 0,
  147. 0,
  148. 0,
  149. 0,
  150. &psidSystem
  151. );
  152. if( !fRet )
  153. {
  154. hr = HRESULT_FROM_WIN32(GetLastError());
  155. goto exit;
  156. }
  157. fRet= AllocateAndInitializeSid(
  158. &ntAuthority,
  159. 2,
  160. SECURITY_BUILTIN_DOMAIN_RID,
  161. DOMAIN_ALIAS_RID_ADMINS,
  162. 0,
  163. 0,
  164. 0,
  165. 0,
  166. 0,
  167. 0,
  168. &psidAdmin
  169. );
  170. if( !fRet )
  171. {
  172. hr = HRESULT_FROM_WIN32(GetLastError());
  173. goto exit;
  174. }
  175. //
  176. // Create the DACL containing an access-allowed ACE
  177. // for the local system and admin SIDs.
  178. //
  179. dwDaclSize = sizeof(ACL)
  180. + sizeof(ACCESS_ALLOWED_ACE)
  181. + GetLengthSid(psidAdmin)
  182. + sizeof(ACCESS_ALLOWED_ACE)
  183. + GetLengthSid(psidSystem)
  184. - sizeof(DWORD);
  185. paclDiscretionary = (PACL)LocalAlloc(LPTR, dwDaclSize );
  186. if ( paclDiscretionary == NULL )
  187. {
  188. hr = HRESULT_FROM_WIN32(GetLastError());
  189. goto exit;
  190. }
  191. fRet = InitializeAcl(
  192. paclDiscretionary,
  193. dwDaclSize,
  194. ACL_REVISION
  195. );
  196. if( !fRet )
  197. {
  198. hr = HRESULT_FROM_WIN32(GetLastError());
  199. goto exit;
  200. }
  201. fRet = AddAccessAllowedAce(
  202. paclDiscretionary,
  203. ACL_REVISION,
  204. FILE_ALL_ACCESS,
  205. psidSystem
  206. );
  207. if ( !fRet )
  208. {
  209. hr = HRESULT_FROM_WIN32(GetLastError());
  210. goto exit;
  211. }
  212. fRet = AddAccessAllowedAce(
  213. paclDiscretionary,
  214. ACL_REVISION,
  215. FILE_ALL_ACCESS,
  216. psidAdmin
  217. );
  218. if ( !fRet )
  219. {
  220. hr = HRESULT_FROM_WIN32(GetLastError());
  221. goto exit;
  222. }
  223. //
  224. // Set the DACL into the security descriptor.
  225. //
  226. fRet = SetSecurityDescriptorDacl(
  227. *ppsdStorage,
  228. TRUE,
  229. paclDiscretionary,
  230. FALSE
  231. );
  232. if ( !fRet ) {
  233. hr = HRESULT_FROM_WIN32(GetLastError());
  234. goto exit;
  235. }
  236. hr = S_OK;
  237. exit:
  238. if ( psidAdmin != NULL )
  239. {
  240. FreeSid( psidAdmin );
  241. psidAdmin = NULL;
  242. }
  243. if ( psidSystem != NULL )
  244. {
  245. FreeSid( psidSystem );
  246. psidSystem = NULL;
  247. }
  248. if ( FAILED( hr ) ) {
  249. if ( paclDiscretionary != NULL )
  250. {
  251. LocalFree( paclDiscretionary );
  252. paclDiscretionary = NULL;
  253. }
  254. if ( *ppsdStorage != NULL )
  255. {
  256. LocalFree( *ppsdStorage );
  257. *ppsdStorage = NULL;
  258. }
  259. }
  260. return hr;
  261. }
  262. HRESULT
  263. FreeSecurityDescriptorForMetabaseExtensionFile(
  264. PSECURITY_DESCRIPTOR psdStorage
  265. )
  266. /*++
  267. Routine Description:
  268. Free security descriptor generated by
  269. GetSecurityDescriptorForMetabaseExtentionFile()
  270. Arguments:
  271. psdStorage - Security Descriptor to be freed
  272. Returns:
  273. HRESULT
  274. --*/
  275. {
  276. HRESULT hr = ERROR_SUCCESS;
  277. BOOL fRet = FALSE;
  278. BOOL fDaclPresent;
  279. PACL paclDiscretionary = NULL;
  280. BOOL fDaclDefaulted;
  281. //
  282. // Get the DACL from the security descriptor.
  283. //
  284. if ( psdStorage == NULL )
  285. {
  286. hr = S_OK;
  287. goto exit;
  288. }
  289. fRet = GetSecurityDescriptorDacl(
  290. psdStorage,
  291. &fDaclPresent,
  292. &paclDiscretionary,
  293. &fDaclDefaulted
  294. );
  295. if ( !fRet )
  296. {
  297. hr = HRESULT_FROM_WIN32(GetLastError());
  298. goto exit;
  299. }
  300. if ( fDaclPresent && paclDiscretionary != NULL )
  301. {
  302. LocalFree( paclDiscretionary );
  303. paclDiscretionary = NULL;
  304. }
  305. LocalFree( psdStorage );
  306. hr = S_OK;
  307. exit:
  308. return hr;
  309. }
  310. INT
  311. Iisfputs(
  312. const char* pBuf,
  313. FILE* fOut
  314. )
  315. {
  316. return (fputs( pBuf, fOut ) == EOF || fputc( '\n', fOut ) == EOF)
  317. ? EOF
  318. : 0;
  319. }
  320. LPSTR
  321. Iisfgets(
  322. LPSTR pBuf,
  323. INT cMax,
  324. FILE* fIn
  325. )
  326. {
  327. LPSTR pszWas = pBuf;
  328. INT ch = 0;
  329. while ( cMax > 1 && (ch=fgetc(fIn))!= EOF && ch != '\n' )
  330. {
  331. *pBuf++ = (CHAR)ch;
  332. --cMax;
  333. }
  334. if ( ch != EOF )
  335. {
  336. *pBuf = '\0';
  337. return pszWas;
  338. }
  339. return NULL;
  340. }
  341. //
  342. // Fields for the Certificate mapper
  343. //
  344. IISMDB_Fields IisCertMappingFields[] = {
  345. {IISMDB_TYPE_ISSUER_O, NULL, IDS_IISMAP_FLD0, 40 },
  346. {IISMDB_TYPE_ISSUER_OU, NULL, IDS_IISMAP_FLD1, 40 },
  347. {IISMDB_TYPE_ISSUER_C, NULL, IDS_IISMAP_FLD2, 40 },
  348. {IISMDB_TYPE_SUBJECT_O, NULL, IDS_IISMAP_FLD3, 40 },
  349. {IISMDB_TYPE_SUBJECT_OU, NULL, IDS_IISMAP_FLD4, 40 },
  350. {IISMDB_TYPE_SUBJECT_C, NULL, IDS_IISMAP_FLD5, 40 },
  351. {IISMDB_TYPE_SUBJECT_CN, NULL, IDS_IISMAP_FLD6, 40 },
  352. {IISMDB_TYPE_NTACCT, NULL, IDS_IISMAP_FLD7, 40 },
  353. } ;
  354. //
  355. // default hierarchy for the Certificate mapper
  356. //
  357. IISMDB_HEntry IisCertMappingHierarchy[] = {
  358. {IISMDB_INDEX_ISSUER_O, TRUE},
  359. {IISMDB_INDEX_ISSUER_OU, FALSE},
  360. {IISMDB_INDEX_ISSUER_C, FALSE},
  361. {IISMDB_INDEX_SUBJECT_O, TRUE},
  362. {IISMDB_INDEX_SUBJECT_OU, FALSE},
  363. {IISMDB_INDEX_SUBJECT_C, FALSE},
  364. {IISMDB_INDEX_SUBJECT_CN, TRUE},
  365. } ;
  366. //
  367. // Fields for the Certificate 1:1 mapper
  368. //
  369. IISMDB_Fields IisCert11MappingFields[] = {
  370. #if defined(CERT11_FULL_CERT)
  371. {IISMDB_INDEX_CERT11_CERT, NULL, IDS_IISMAP11_FLDC, 40 },
  372. #else
  373. {IISMDB_INDEX_CERT11_SUBJECT, NULL, IDS_IISMAP11_FLDS, 40 },
  374. {IISMDB_INDEX_CERT11_ISSUER, NULL, IDS_IISMAP11_FLDI, 40 },
  375. #endif
  376. {IISMDB_INDEX_CERT11_NT_ACCT, NULL, IDS_IISMAP11_FLDA, 40 },
  377. #if defined(CERT11_FULL_CERT)
  378. {IISMDB_INDEX_CERT11_NAME, NULL, IDS_IISMAP11_FLDN, 40 },
  379. {IISMDB_INDEX_CERT11_ENABLED, NULL, IDS_IISMAP11_FLDE, 40 },
  380. {IISMDB_INDEX_CERT11_NT_PWD, NULL, IDS_IISMAP11_FLDP, 40 },
  381. #endif
  382. } ;
  383. //
  384. // default hierarchy for the Certificate 1:1 mapper
  385. //
  386. IISMDB_HEntry IisCert11MappingHierarchy[] = {
  387. #if defined(CERT11_FULL_CERT)
  388. {IISMDB_INDEX_CERT11_CERT, TRUE},
  389. #else
  390. {IISMDB_INDEX_CERT11_ISSUER, TRUE},
  391. {IISMDB_INDEX_CERT11_SUBJECT, FALSE},
  392. #endif
  393. } ;
  394. //
  395. // Fields for the Ita mapper
  396. //
  397. IISMDB_Fields IisItaMappingFields[] = {
  398. {IISMDB_TYPE_ITACCT, NULL, IDS_ITAIISMAP_FLD0, 40 },
  399. {IISMDB_TYPE_ITPWD, NULL, IDS_ITAIISMAP_FLD1, 40 },
  400. {IISMDB_TYPE_NTACCT, NULL, IDS_ITAIISMAP_FLD2, 40 },
  401. } ;
  402. //
  403. // default hierarchy for the Ita mapper
  404. //
  405. IISMDB_HEntry IisItaMappingHierarchy[] = {
  406. {IISIMDB_INDEX_IT_ACCT, TRUE},
  407. {IISIMDB_INDEX_IT_PWD, TRUE},
  408. } ;
  409. //
  410. // Fields for the Md5 mapper
  411. //
  412. IISMDB_Fields IisMd5MappingFields[] = {
  413. {IISMDB_TYPE_ITREALM, NULL, IDS_MD5IISMAP_FLD0, 40 },
  414. {IISMDB_TYPE_ITACCT, NULL, IDS_MD5IISMAP_FLD1, 40 },
  415. {IISMDB_TYPE_ITMD5PWD, NULL, IDS_MD5IISMAP_FLD2, 40 },
  416. {IISMDB_TYPE_NTACCT, NULL, IDS_MD5IISMAP_FLD3, 40 },
  417. {IISMMDB_INDEX_IT_CLRPWD, NULL, IDS_MD5IISMAP_FLD4, 40 },
  418. {IISMMDB_INDEX_NT_PWD, NULL, IDS_MD5IISMAP_FLD5, 40 },
  419. } ;
  420. //
  421. // default hierarchy for the Md5 mapper
  422. //
  423. IISMDB_HEntry IisMd5MappingHierarchy[] = {
  424. {IISMMDB_INDEX_IT_REALM, TRUE},
  425. {IISMMDB_INDEX_IT_ACCT, TRUE},
  426. } ;
  427. HINSTANCE g_hModule = (HINSTANCE)INVALID_HANDLE_VALUE;
  428. // CIisAcctMapper
  429. CIisAcctMapper::CIisAcctMapper(
  430. )
  431. /*++
  432. Routine Description:
  433. Constructor for CIisAcctMapper
  434. Arguments:
  435. None
  436. Returns:
  437. Nothing
  438. --*/
  439. {
  440. m_cInit = -1;
  441. m_pMapping = NULL;
  442. m_cMapping = 0;
  443. m_pAltMapping = NULL;
  444. m_cAltMapping = 0;
  445. m_pHierarchy = NULL;
  446. m_cHierarchy = 0;
  447. m_achFileName[0] = '\0';
  448. m_pClasses = NULL;
  449. m_pSesKey = NULL;
  450. m_dwSesKey = 0;
  451. m_hNotifyEvent = NULL;
  452. m_fRequestTerminate = FALSE;
  453. INITIALIZE_CRITICAL_SECTION( &csLock );
  454. }
  455. CIisAcctMapper::~CIisAcctMapper(
  456. )
  457. /*++
  458. Routine Description:
  459. Destructor for CIisAcctMapper
  460. Arguments:
  461. None
  462. Returns:
  463. Nothing
  464. --*/
  465. {
  466. Reset();
  467. if ( m_pHierarchy != NULL )
  468. {
  469. LocalFree( m_pHierarchy );
  470. }
  471. if ( m_pSesKey != NULL )
  472. {
  473. LocalFree( m_pSesKey );
  474. }
  475. DeleteCriticalSection( &csLock );
  476. }
  477. VOID
  478. FreeCIisAcctMapper(
  479. LPVOID pMapper
  480. )
  481. /*++
  482. Routine Description:
  483. Delete a CIisAcctMapper
  484. Arguments:
  485. pMapper - ptr to mapper
  486. Returns:
  487. Nothing
  488. --*/
  489. {
  490. delete (CIisAcctMapper*)pMapper;
  491. }
  492. BOOL
  493. CIisAcctMapper::Create(
  494. VOID
  495. )
  496. /*++
  497. Routine Description:
  498. Create file for CIisAcctMapper with proper SD
  499. Arguments:
  500. None
  501. Returns:
  502. TRUE if success, FALSE if error
  503. --*/
  504. {
  505. // create file name, store in m_achFileName
  506. // from g_dwGuid
  507. // and g_pszInstallPath
  508. UINT cLen;
  509. UINT cIter;
  510. HANDLE hF;
  511. HRESULT hr = E_FAIL;
  512. BOOL fRet = FALSE;
  513. PSECURITY_DESCRIPTOR psdForMetabaseExtensionFile = NULL;
  514. SECURITY_ATTRIBUTES saStorage;
  515. PSECURITY_ATTRIBUTES psaStorage = NULL;
  516. Reset();
  517. if ( g_pszInstallPath )
  518. {
  519. cLen = strlen(g_pszInstallPath);
  520. memcpy( m_achFileName, g_pszInstallPath, cLen );
  521. if ( cLen && m_achFileName[cLen-1] != '\\' )
  522. {
  523. m_achFileName[cLen++] = '\\';
  524. }
  525. }
  526. else
  527. {
  528. cLen = 0;
  529. }
  530. wsprintf( m_achFileName+cLen, "%08x.mp", g_dwGuid );
  531. //
  532. // build security descriptor (Administrators and SYSTEM)
  533. // to be set on metabase extension file
  534. //
  535. hr = GetSecurityDescriptorForMetabaseExtensionFile(
  536. &psdForMetabaseExtensionFile );
  537. if ( SUCCEEDED(hr) && psdForMetabaseExtensionFile != NULL )
  538. {
  539. saStorage.nLength = sizeof(SECURITY_ATTRIBUTES);
  540. saStorage.lpSecurityDescriptor = psdForMetabaseExtensionFile;
  541. saStorage.bInheritHandle = FALSE;
  542. }
  543. else
  544. {
  545. return FALSE;
  546. }
  547. //
  548. // Open file and close it right away
  549. // If file didn't exist, then empty file with good SD (Security Descriptor)
  550. // will be created. That will later be opened using C runtime (fopen)
  551. // in Save() method and good SD will persist.
  552. // Ideally Save() should be using Win32 CreateFile()
  553. // instead fopen and it could set SD itself. But since this is legacy
  554. // source file and rather unsafe for making too many changes, pragmatic
  555. // approach was chosen to set SD here in Create() method
  556. //
  557. if ( (hF = CreateFile( m_achFileName,
  558. GENERIC_READ,
  559. FILE_SHARE_READ|FILE_SHARE_WRITE,
  560. &saStorage,
  561. OPEN_ALWAYS,
  562. FILE_ATTRIBUTE_NORMAL,
  563. NULL ) ) != INVALID_HANDLE_VALUE )
  564. {
  565. CloseHandle( hF );
  566. fRet = TRUE;
  567. }
  568. else
  569. {
  570. fRet = FALSE;
  571. }
  572. if ( psdForMetabaseExtensionFile != NULL )
  573. {
  574. FreeSecurityDescriptorForMetabaseExtensionFile(
  575. psdForMetabaseExtensionFile );
  576. psdForMetabaseExtensionFile = NULL;
  577. }
  578. return fRet;
  579. }
  580. BOOL
  581. CIisAcctMapper::Delete(
  582. VOID
  583. )
  584. /*++
  585. Routine Description:
  586. Delete external storage used by this mapper ( i.e. file )
  587. Arguments:
  588. None
  589. Returns:
  590. TRUE if success, FALSE if error
  591. --*/
  592. {
  593. BOOL fSt = TRUE;
  594. Lock();
  595. if ( m_achFileName[0] )
  596. {
  597. fSt = DeleteFile( m_achFileName );
  598. m_achFileName[0] = '\0';
  599. }
  600. Unlock();
  601. return fSt;
  602. }
  603. BOOL
  604. CIisAcctMapper::Serialize(
  605. CStoreXBF* pXbf
  606. )
  607. /*++
  608. Routine Description:
  609. Serialize mapper reference ( NOT mapping info ) to buffer
  610. Save() must be called to save mapping info before calling Serialize()
  611. Arguments:
  612. pXbf - ptr to extensible buffer to serialize to
  613. Returns:
  614. TRUE if success, FALSE if error
  615. --*/
  616. {
  617. return pXbf->Append( (DWORD)strlen(m_achFileName) ) &&
  618. pXbf->Append( (LPBYTE)m_achFileName, (DWORD)strlen(m_achFileName) ) &&
  619. pXbf->Append( (LPBYTE)m_md5.digest, (DWORD)sizeof(m_md5.digest) ) &&
  620. pXbf->Append( (DWORD)m_dwSesKey ) &&
  621. pXbf->Append( (LPBYTE)m_pSesKey, (DWORD)m_dwSesKey ) ;
  622. }
  623. BOOL
  624. CIisAcctMapper::Unserialize(
  625. CStoreXBF* pXBF
  626. )
  627. /*++
  628. Routine Description:
  629. Unserialize mapper reference ( NOT mapping info ) from extensible buffer
  630. Load() must be called to load mapping info
  631. Arguments:
  632. pXBF - ptr to extensible buffer
  633. Returns:
  634. TRUE if success, FALSE if error
  635. --*/
  636. {
  637. LPBYTE pb = pXBF->GetBuff();
  638. DWORD c = pXBF->GetUsed();
  639. return Unserialize( &pb, &c );
  640. }
  641. BOOL
  642. CIisAcctMapper::Unserialize(
  643. LPBYTE* ppb,
  644. LPDWORD pc
  645. )
  646. /*++
  647. Routine Description:
  648. Unserialize mapper reference ( NOT mapping info ) from buffer
  649. Load() must be called to load mapping info
  650. Arguments:
  651. ppb - ptr to buffer
  652. pc - ptr to buffer length
  653. Returns:
  654. TRUE if success, FALSE if error
  655. --*/
  656. {
  657. DWORD cName;
  658. if ( ::Unserialize( ppb, pc, &cName ) &&
  659. cName <= *pc )
  660. {
  661. memcpy( m_achFileName, *ppb, cName );
  662. m_achFileName[ cName ] = '\0';
  663. *ppb += cName;
  664. *pc -= cName;
  665. if ( sizeof(m_md5.digest) <= *pc )
  666. {
  667. memcpy( m_md5.digest, *ppb, sizeof(m_md5.digest) );
  668. *ppb += sizeof(m_md5.digest);
  669. *pc -= sizeof(m_md5.digest);
  670. if ( ::Unserialize( ppb, pc, &m_dwSesKey ) &&
  671. cName <= *pc )
  672. {
  673. if ( m_pSesKey != NULL )
  674. {
  675. LocalFree( m_pSesKey );
  676. }
  677. if ( !(m_pSesKey = (LPBYTE)LocalAlloc( LMEM_FIXED, m_dwSesKey )) )
  678. {
  679. m_dwSesKey = 0;
  680. return FALSE;
  681. }
  682. memcpy( m_pSesKey, *ppb, m_dwSesKey );
  683. *ppb += m_dwSesKey;
  684. *pc -= m_dwSesKey;
  685. return TRUE;
  686. }
  687. }
  688. }
  689. return FALSE;
  690. }
  691. BOOL
  692. CIisAcctMapper::Serialize(
  693. VOID
  694. )
  695. /*++
  696. Routine Description:
  697. Serialize mapper reference ( NOT mapping info ) to registry
  698. Save() must be called to save mapping info before calling Serialize()
  699. Warning : this allow only 1 instance
  700. Arguments:
  701. None
  702. Returns:
  703. TRUE if success, FALSE if error
  704. --*/
  705. {
  706. BOOL fSt = TRUE;
  707. HKEY hKey;
  708. LONG st;
  709. if ( (st = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  710. GetRegKeyName(),
  711. 0,
  712. KEY_WRITE,
  713. &hKey )) != ERROR_SUCCESS )
  714. {
  715. SetLastError( st );
  716. return FALSE;
  717. }
  718. if ( RegSetValueEx( hKey,
  719. FILE_VALIDATOR,
  720. NULL,
  721. REG_BINARY,
  722. (LPBYTE)m_md5.digest,
  723. sizeof(m_md5.digest) ) != ERROR_SUCCESS ||
  724. RegSetValueEx( hKey,
  725. FILE_LOCATION,
  726. NULL,
  727. REG_SZ,
  728. (LPBYTE)m_achFileName,
  729. strlen(m_achFileName) ) != ERROR_SUCCESS )
  730. {
  731. fSt = FALSE;
  732. }
  733. RegCloseKey( hKey );
  734. return fSt;
  735. }
  736. BOOL
  737. CIisAcctMapper::Unserialize(
  738. VOID
  739. )
  740. /*++
  741. Routine Description:
  742. Unserialize mapper reference ( NOT mapping info ) From registry
  743. Load() must be called to load mapping info
  744. Warning : this allow only 1 instance
  745. Arguments:
  746. None
  747. Returns:
  748. TRUE if success, FALSE if error
  749. --*/
  750. {
  751. BOOL fSt = FALSE;
  752. HKEY hKey;
  753. DWORD dwLen;
  754. DWORD dwType;
  755. LONG st;
  756. // Check registry
  757. if ( (st = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  758. GetRegKeyName(),
  759. 0,
  760. KEY_READ,
  761. &hKey )) != ERROR_SUCCESS )
  762. {
  763. SetLastError( st );
  764. return FALSE;
  765. }
  766. dwLen = sizeof(m_md5.digest);
  767. if ( RegQueryValueEx( hKey,
  768. FILE_VALIDATOR,
  769. NULL,
  770. &dwType,
  771. (LPBYTE)m_md5.digest,
  772. &dwLen ) == ERROR_SUCCESS &&
  773. dwType == REG_BINARY &&
  774. (( dwLen = sizeof(m_achFileName) ), TRUE ) &&
  775. RegQueryValueEx( hKey,
  776. FILE_LOCATION,
  777. NULL,
  778. &dwType,
  779. (LPBYTE)m_achFileName,
  780. &dwLen ) == ERROR_SUCCESS &&
  781. dwType == REG_SZ )
  782. {
  783. fSt = TRUE;
  784. }
  785. RegCloseKey( hKey );
  786. return fSt;
  787. }
  788. BOOL
  789. CIisAcctMapper::UpdateClasses(
  790. BOOL fComputeMask
  791. )
  792. /*++
  793. Routine Description:
  794. Constructor for CIisAcctMapper
  795. Arguments:
  796. fComputeMask -- TRUE if mask to be recomputed
  797. Returns:
  798. TRUE if success, FALSE if error
  799. --*/
  800. {
  801. UINT x;
  802. UINT mx = 1 << m_cHierarchy;
  803. if ( fComputeMask )
  804. {
  805. for ( x = 0 ; x < m_cMapping ; ++x )
  806. {
  807. m_pMapping[x]->UpdateMask( m_pHierarchy, m_cHierarchy );
  808. }
  809. }
  810. SortMappings();
  811. if ( m_pClasses == NULL )
  812. {
  813. m_pClasses = (MappingClass*)LocalAlloc(
  814. LMEM_FIXED,
  815. sizeof(MappingClass)*(mx+1) );
  816. if ( m_pClasses == NULL )
  817. {
  818. return FALSE;
  819. }
  820. }
  821. DWORD dwN = 0; // current class index in m_pClasses
  822. DWORD dwLastClass = 0;
  823. DWORD dwFirst = 0; // first entry for current dwLastClass
  824. for ( x = 0 ; x <= m_cMapping ; ++x )
  825. {
  826. DWORD dwCur;
  827. dwCur = (x==m_cMapping) ? dwLastClass+1: m_pMapping[x]->GetMask();
  828. if ( dwCur > dwLastClass )
  829. {
  830. if ( x > dwFirst )
  831. {
  832. m_pClasses[dwN].dwClass = dwLastClass;
  833. m_pClasses[dwN].dwFirst = dwFirst;
  834. m_pClasses[dwN].dwLast = x - 1;
  835. ++dwN;
  836. }
  837. dwLastClass = dwCur;
  838. dwFirst = x;
  839. }
  840. }
  841. m_pClasses[dwN].dwClass = 0xffffffff;
  842. return TRUE;
  843. }
  844. BOOL
  845. CIisAcctMapper::SortMappings(
  846. )
  847. /*++
  848. Routine Description:
  849. Sort the mappings. Masks for mapping objects are assumed
  850. to be already computed.
  851. Arguments:
  852. None
  853. Returns:
  854. TRUE if success, FALSE if error
  855. --*/
  856. {
  857. qsort( (LPVOID)m_pMapping,
  858. m_cMapping,
  859. sizeof(CIisMapping*),
  860. QsortIisMappingCmp
  861. );
  862. return TRUE;
  863. }
  864. BOOL
  865. CIisAcctMapper::FindMatch(
  866. CIisMapping* pQuery,
  867. CIisMapping** pResult,
  868. LPDWORD piResult
  869. )
  870. /*++
  871. Routine Description:
  872. Find a match base on field contents in CIisMapping
  873. Arguments:
  874. pQuery -- describe fields to consider for mapping
  875. pResult -- updated with result if found mapping
  876. Returns:
  877. TRUE if mapping found, else FALSE
  878. Lock:
  879. mapper must be locked for ptr to remain valid
  880. --*/
  881. {
  882. // iterate through classes, do bsearch on each
  883. MappingClass *pH = m_pClasses;
  884. if ( pH == NULL )
  885. {
  886. return FALSE;
  887. }
  888. while ( pH->dwClass != 0xffffffff )
  889. {
  890. CIisMapping **pRes = (CIisMapping **)bsearch( (LPVOID)&pQuery,
  891. (LPVOID)(m_pMapping+pH->dwFirst),
  892. pH->dwLast - pH->dwFirst + 1,
  893. sizeof(CIisMapping*),
  894. MatchIisMappingCmp );
  895. if ( piResult != NULL )
  896. {
  897. *piResult = DIFF(pRes - m_pMapping);
  898. }
  899. if ( pRes != NULL )
  900. {
  901. *pResult = *pRes;
  902. return TRUE;
  903. }
  904. ++pH;
  905. }
  906. return FALSE;
  907. }
  908. #if 0
  909. DWORD
  910. WINAPI IisMappingUpdateIndication(
  911. LPVOID pV )
  912. /*++
  913. Routine Description:
  914. Shell for registry update notification
  915. Arguments:
  916. pV -- ptr to CIisAcctMapper to be notified
  917. Returns:
  918. NT error code ( 0 if no error )
  919. --*/
  920. {
  921. return ((CIisAcctMapper*)pV)->UpdateIndication();
  922. }
  923. DWORD
  924. CIisAcctMapper::UpdateIndication(
  925. VOID )
  926. /*++
  927. Routine Description:
  928. Thread monitoring authentication methods update in registry
  929. Arguments:
  930. None
  931. Returns:
  932. NT error
  933. --*/
  934. {
  935. for ( ;; )
  936. {
  937. if ( RegNotifyChangeKeyValue( m_hKey,
  938. FALSE,
  939. REG_NOTIFY_CHANGE_LAST_SET,
  940. m_hNotifyEvent,
  941. TRUE ) != ERROR_SUCCESS )
  942. {
  943. break;
  944. }
  945. if ( WaitForSingleObject( m_hNotifyEvent, INFINITE)
  946. != WAIT_OBJECT_0 )
  947. {
  948. break;
  949. }
  950. if ( m_fRequestTerminate )
  951. {
  952. break;
  953. }
  954. // re-load mapper
  955. Lock();
  956. if ( !Load() && GetLastError() == ERROR_INVALID_ACCESS )
  957. {
  958. Reset();
  959. }
  960. Unlock();
  961. }
  962. return 0;
  963. }
  964. #endif
  965. #if 0
  966. BOOL
  967. CIisAcctMapper::Init(
  968. BOOL *pfFirst,
  969. BOOL fMonitorChange
  970. )
  971. /*++
  972. Routine Description:
  973. Initialize mappings, optionally load map file
  974. Arguments:
  975. fLoad -- TRUE to load mappings from file
  976. Returns:
  977. TRUE if success, FALSE if error
  978. --*/
  979. {
  980. *pfFirst = FALSE;
  981. BOOL fSt = TRUE;
  982. if ( !InterlockedIncrement( &m_cInit ) )
  983. {
  984. *pfFirst = TRUE;
  985. if ( fMonitorChange )
  986. {
  987. m_hNotifyEvent = IIS_CREATE_EVENT(
  988. "CIisAcctMapper::m_hNotifyEvent",
  989. this,
  990. FALSE,
  991. FALSE
  992. );
  993. }
  994. m_fRequestTerminate = FALSE;
  995. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  996. GetRegKeyName(),
  997. 0,
  998. KEY_READ,
  999. &m_hKey ) == ERROR_SUCCESS )
  1000. {
  1001. DWORD dwLen = sizeof( m_achFileName );
  1002. DWORD dwType;
  1003. if ( RegQueryValueEx( m_hKey,
  1004. FILE_LOCATION,
  1005. NULL,
  1006. &dwType,
  1007. (LPBYTE)m_achFileName,
  1008. &dwLen ) != ERROR_SUCCESS
  1009. || dwType != REG_SZ )
  1010. {
  1011. strcpy( m_achFileName, IIS_CERT_FILENAME );
  1012. }
  1013. if ( fMonitorChange )
  1014. {
  1015. // create registry monitoring thread
  1016. DWORD dwID;
  1017. if ( (m_hThread = CreateThread( NULL,
  1018. 0,
  1019. (LPTHREAD_START_ROUTINE)::IisMappingUpdateIndication,
  1020. (LPVOID)this,
  1021. 0,
  1022. &dwID )) == NULL )
  1023. {
  1024. fSt = FALSE;
  1025. goto ex;
  1026. }
  1027. }
  1028. fSt = Reset();
  1029. }
  1030. else
  1031. {
  1032. SetLastError( ERROR_CANTOPEN );
  1033. fSt = FALSE;
  1034. }
  1035. }
  1036. //
  1037. // log event if error
  1038. //
  1039. if ( !fSt )
  1040. {
  1041. char achErr[32];
  1042. LPCTSTR pA[1];
  1043. pA[0] = achErr;
  1044. _itoa( GetLastError(), achErr, 10 );
  1045. ReportIisMapEvent( EVENTLOG_ERROR_TYPE,
  1046. IISMAP_EVENT_INIT_ERROR,
  1047. 1,
  1048. pA );
  1049. }
  1050. return fSt;
  1051. }
  1052. BOOL
  1053. CIisAcctMapper::Terminate(
  1054. BOOL fForce
  1055. )
  1056. /*++
  1057. Routine Description:
  1058. Terminate mapping
  1059. Arguments:
  1060. None
  1061. Returns:
  1062. TRUE if success, FALSE if error
  1063. --*/
  1064. {
  1065. BOOL fSt = TRUE;
  1066. if ( InterlockedDecrement( &m_cInit ) < 0 || fForce )
  1067. {
  1068. #if 0
  1069. if ( m_hNotifyEvent && m_hThread )
  1070. {
  1071. m_fRequestTerminate = TRUE;
  1072. SetEvent( m_hNotifyEvent );
  1073. if ( m_hThread != NULL )
  1074. {
  1075. fSt = WaitForSingleObject( m_hThread, 1000 * 3 )
  1076. == WAIT_OBJECT_0;
  1077. if ( !fSt )
  1078. {
  1079. TerminateThread( m_hThread, 0 );
  1080. }
  1081. CloseHandle( m_hThread );
  1082. m_hThread = NULL;
  1083. if ( m_hKey != NULL )
  1084. {
  1085. RegCloseKey( m_hKey );
  1086. m_hKey = NULL;
  1087. }
  1088. if ( m_hNotifyEvent != NULL )
  1089. {
  1090. CloseHandle( m_hNotifyEvent );
  1091. m_hNotifyEvent = NULL;
  1092. }
  1093. return fSt;
  1094. }
  1095. }
  1096. if ( m_hKey != NULL )
  1097. {
  1098. RegCloseKey( m_hKey );
  1099. m_hKey = NULL;
  1100. }
  1101. #endif
  1102. }
  1103. return TRUE;
  1104. }
  1105. #endif
  1106. void
  1107. CIisAcctMapper::Lock(
  1108. )
  1109. /*++
  1110. Routine Description:
  1111. Prevent access to mapper from other threads
  1112. Arguments:
  1113. None
  1114. Returns:
  1115. Nothing
  1116. --*/
  1117. {
  1118. EnterCriticalSection( &csLock );
  1119. }
  1120. void
  1121. CIisAcctMapper::Unlock(
  1122. )
  1123. /*++
  1124. Routine Description:
  1125. Re-enabled access to mapper from other threads
  1126. Arguments:
  1127. None
  1128. Returns:
  1129. Nothing
  1130. --*/
  1131. {
  1132. LeaveCriticalSection( &csLock );
  1133. }
  1134. BOOL
  1135. CIisAcctMapper::FlushAlternate(
  1136. BOOL fApply
  1137. )
  1138. /*++
  1139. Routine Description:
  1140. Flush alternate list, optionaly commiting it to the main list
  1141. Arguments:
  1142. fApply -- TRUE to commit changes made in alternate list
  1143. Returns:
  1144. TRUE if success, otherwise FALSE
  1145. --*/
  1146. {
  1147. UINT i;
  1148. UINT iM;
  1149. BOOL fSt = TRUE;
  1150. if ( m_pAltMapping )
  1151. {
  1152. if ( fApply )
  1153. {
  1154. //
  1155. // Transfer non existing objects from regular to alternate list
  1156. //
  1157. iM = min( m_cMapping, m_cAltMapping );
  1158. for ( i = 0 ; i < iM ; ++ i )
  1159. {
  1160. if ( m_pAltMapping[i] == NULL )
  1161. {
  1162. m_pAltMapping[i] = m_pMapping[i];
  1163. }
  1164. else
  1165. {
  1166. delete m_pMapping[i];
  1167. }
  1168. }
  1169. //
  1170. // delete extra objects
  1171. //
  1172. if ( m_cMapping > m_cAltMapping )
  1173. {
  1174. for ( i = m_cAltMapping ; i < m_cMapping ; ++i )
  1175. {
  1176. delete m_pMapping[i];
  1177. }
  1178. }
  1179. if ( m_pMapping )
  1180. {
  1181. LocalFree( m_pMapping );
  1182. }
  1183. m_pMapping = m_pAltMapping;
  1184. m_cMapping = m_cAltMapping;
  1185. fSt = UpdateClasses( TRUE );
  1186. }
  1187. else
  1188. {
  1189. for ( i = 0 ; i < m_cAltMapping ; ++i )
  1190. {
  1191. if ( m_pAltMapping[i] )
  1192. {
  1193. delete m_pAltMapping;
  1194. }
  1195. }
  1196. LocalFree( m_pAltMapping );
  1197. }
  1198. }
  1199. m_pAltMapping = NULL;
  1200. m_cAltMapping = 0;
  1201. return fSt;
  1202. }
  1203. BOOL
  1204. CIisAcctMapper::GetMapping(
  1205. DWORD iIndex,
  1206. CIisMapping** pM,
  1207. BOOL fGetFromAlternate,
  1208. BOOL fPutOnAlternate
  1209. )
  1210. /*++
  1211. Routine Description:
  1212. Get mapping entry based on index
  1213. Arguments:
  1214. iIndex -- index in mapping array
  1215. pM -- updated with pointer to mapping. mapping object
  1216. still owned by the mapper object.
  1217. fGetFromAlternate -- TRUE if retrieve from alternate list
  1218. fPutOnAlternate -- TRUE if put returned mapping on alternate list
  1219. Returns:
  1220. TRUE if success, FALSE if error
  1221. --*/
  1222. {
  1223. if ( fPutOnAlternate )
  1224. {
  1225. // create alternate list if not exist
  1226. if ( !m_pAltMapping && m_cMapping )
  1227. {
  1228. m_pAltMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*(m_cMapping) );
  1229. if ( m_pAltMapping == NULL )
  1230. {
  1231. return FALSE;
  1232. }
  1233. memset( m_pAltMapping, '\0', sizeof(CIisMapping*) * m_cMapping );
  1234. m_cAltMapping = m_cMapping;
  1235. }
  1236. if ( iIndex < m_cAltMapping )
  1237. {
  1238. if ( m_pAltMapping[iIndex] == NULL &&
  1239. m_pMapping != NULL ) // work-around for compiler bug
  1240. {
  1241. // duplicate mapping to alternate list if not exist
  1242. if ( m_pMapping[iIndex]->Clone( pM ) )
  1243. {
  1244. m_pAltMapping[iIndex] = *pM;
  1245. }
  1246. else
  1247. {
  1248. return FALSE;
  1249. }
  1250. }
  1251. else
  1252. {
  1253. *pM = m_pAltMapping[iIndex];
  1254. }
  1255. return TRUE;
  1256. }
  1257. return FALSE;
  1258. }
  1259. if ( fGetFromAlternate &&
  1260. m_pAltMapping &&
  1261. iIndex < m_cAltMapping )
  1262. {
  1263. if ( m_pAltMapping[iIndex] )
  1264. {
  1265. *pM = m_pAltMapping[iIndex];
  1266. }
  1267. else
  1268. {
  1269. *pM = m_pMapping[iIndex];
  1270. }
  1271. return TRUE;
  1272. }
  1273. if ( iIndex < m_cMapping )
  1274. {
  1275. *pM = m_pMapping[iIndex];
  1276. return TRUE;
  1277. }
  1278. return FALSE;
  1279. }
  1280. BOOL
  1281. CIisAcctMapper::GetMappingForUpdate(
  1282. DWORD iIndex,
  1283. CIisMapping** pM
  1284. )
  1285. /*++
  1286. Routine Description:
  1287. Get mapping entry based on index
  1288. returns a copy of the mapping so update is cancelable
  1289. Arguments:
  1290. iIndex -- index in mapping array
  1291. pM -- updated with pointer to mapping. mapping object
  1292. still owned by the mapper object.
  1293. Returns:
  1294. TRUE if success, FALSE if error
  1295. --*/
  1296. {
  1297. if ( iIndex < m_cMapping )
  1298. {
  1299. if ( (*pM = CreateNewMapping()) == NULL )
  1300. {
  1301. return FALSE;
  1302. }
  1303. return (*pM)->Copy( m_pMapping[iIndex] );
  1304. }
  1305. return FALSE;
  1306. }
  1307. BOOL
  1308. CIisAcctMapper::Update(
  1309. DWORD iIndex,
  1310. CIisMapping* pM
  1311. )
  1312. /*++
  1313. Routine Description:
  1314. Update a mapping
  1315. Arguments:
  1316. iIndex -- index in mapping array
  1317. pM -- pointer to mapping.
  1318. Returns:
  1319. TRUE if success, FALSE if error
  1320. --*/
  1321. {
  1322. if ( iIndex < m_cMapping )
  1323. {
  1324. pM->UpdateMask( m_pHierarchy, m_cHierarchy);
  1325. return m_pMapping[iIndex]->Copy( pM ) && UpdateClasses( FALSE );
  1326. }
  1327. return FALSE;
  1328. }
  1329. BOOL
  1330. CIisAcctMapper::Update(
  1331. DWORD iIndex
  1332. )
  1333. /*++
  1334. Routine Description:
  1335. Update a mapping
  1336. Arguments:
  1337. iIndex -- index in mapping array
  1338. Returns:
  1339. TRUE if success, FALSE if error
  1340. --*/
  1341. {
  1342. if ( iIndex < m_cMapping )
  1343. {
  1344. return m_pMapping[iIndex]->UpdateMask( m_pHierarchy, m_cHierarchy);
  1345. }
  1346. return FALSE;
  1347. }
  1348. BOOL
  1349. CIisAcctMapper::Add(
  1350. CIisMapping* pM,
  1351. BOOL fAlternate
  1352. )
  1353. /*++
  1354. Routine Description:
  1355. Add a mapping entry to mapping array
  1356. Transfer ownership of mapping object to mapper
  1357. Arguments:
  1358. pM -- pointer to mapping to be added to mapper
  1359. fAlternate - TRUE if add to alternate list
  1360. Returns:
  1361. TRUE if success, FALSE if error
  1362. --*/
  1363. {
  1364. CIisMapping **pMapping;
  1365. if ( fAlternate )
  1366. {
  1367. DWORD dwC = m_pAltMapping ? m_cAltMapping : m_cMapping;
  1368. CIisMapping** pMap = m_pAltMapping ? m_pAltMapping : m_pMapping;
  1369. pMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*(dwC+1) );
  1370. if ( pMapping == NULL )
  1371. {
  1372. return FALSE;
  1373. }
  1374. if ( m_pAltMapping )
  1375. {
  1376. memcpy( pMapping, pMap, sizeof(CIisMapping*) * dwC );
  1377. LocalFree( m_pAltMapping );
  1378. }
  1379. else
  1380. {
  1381. memset( pMapping, '\0', dwC * sizeof(LPVOID) );
  1382. }
  1383. m_pAltMapping = pMapping;
  1384. m_pAltMapping[dwC] = pM;
  1385. m_cAltMapping = dwC + 1;
  1386. return TRUE;
  1387. }
  1388. else
  1389. {
  1390. pMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*(m_cMapping+1) );
  1391. if ( pMapping == NULL )
  1392. {
  1393. return FALSE;
  1394. }
  1395. if ( m_pMapping )
  1396. {
  1397. memcpy( pMapping, m_pMapping, sizeof(CIisMapping*) * m_cMapping );
  1398. LocalFree( m_pMapping );
  1399. }
  1400. m_pMapping = pMapping;
  1401. pM->UpdateMask( m_pHierarchy, m_cHierarchy );
  1402. m_pMapping[m_cMapping] = pM;
  1403. ++m_cMapping;
  1404. SortMappings();
  1405. return UpdateClasses( FALSE );
  1406. }
  1407. }
  1408. DWORD
  1409. CIisAcctMapper::AddEx(
  1410. CIisMapping* pM
  1411. )
  1412. /*++
  1413. Routine Description:
  1414. Add a mapping entry to mapping array
  1415. Transfer ownership of mapping object to mapper
  1416. Arguments:
  1417. pM -- pointer to mapping to be added to mapper
  1418. Returns:
  1419. Index of entry if success, otherwise 0xffffffff
  1420. --*/
  1421. {
  1422. CIisMapping **pMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*(m_cMapping+1) );
  1423. if ( pMapping == NULL )
  1424. {
  1425. return 0xffffffff;
  1426. }
  1427. if ( m_pMapping )
  1428. {
  1429. memcpy( pMapping, m_pMapping, sizeof(CIisMapping*) * m_cMapping );
  1430. LocalFree( m_pMapping );
  1431. }
  1432. m_pMapping = pMapping;
  1433. pM->UpdateMask( m_pHierarchy, m_cHierarchy );
  1434. m_pMapping[m_cMapping] = pM;
  1435. ++m_cMapping;
  1436. SortMappings();
  1437. if ( UpdateClasses( FALSE ) )
  1438. {
  1439. return m_cMapping-1;
  1440. }
  1441. return 0xffffffff;
  1442. }
  1443. VOID
  1444. CIisAcctMapper::DeleteMappingObject(
  1445. CIisMapping *pM
  1446. )
  1447. /*++
  1448. Routine Description:
  1449. Delete a mapping object
  1450. Arguments:
  1451. pM - ptr to mapping object
  1452. Returns:
  1453. Nothing
  1454. --*/
  1455. {
  1456. delete pM;
  1457. }
  1458. BOOL
  1459. CIisAcctMapper::Delete(
  1460. DWORD dwIndex,
  1461. BOOL fUseAlternate
  1462. )
  1463. /*++
  1464. Routine Description:
  1465. Delete a mapping entry based on index
  1466. Arguments:
  1467. iIndex -- index in mapping array
  1468. fUseAlternate -- TRUE if update alternate list
  1469. Returns:
  1470. TRUE if success, FALSE if error
  1471. --*/
  1472. {
  1473. UINT i;
  1474. UINT iM;
  1475. if ( fUseAlternate )
  1476. {
  1477. //
  1478. // clone all entries from main to alternate list
  1479. //
  1480. if ( !m_pAltMapping )
  1481. {
  1482. m_pAltMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*(m_cMapping) );
  1483. if ( m_pAltMapping == NULL )
  1484. {
  1485. return FALSE;
  1486. }
  1487. memset( m_pAltMapping, '\0', sizeof(CIisMapping*) * m_cMapping );
  1488. m_cAltMapping = m_cMapping;
  1489. }
  1490. iM = min( m_cMapping, m_cAltMapping );
  1491. for ( i = 0 ; i < iM ; ++i )
  1492. {
  1493. if ( m_pAltMapping[i] == NULL )
  1494. {
  1495. if ( !m_pMapping[i]->Clone( &m_pAltMapping[i] ) )
  1496. {
  1497. return FALSE;
  1498. }
  1499. }
  1500. }
  1501. if ( dwIndex < m_cAltMapping )
  1502. {
  1503. delete m_pAltMapping[dwIndex];
  1504. memmove( m_pAltMapping+dwIndex,
  1505. m_pAltMapping+dwIndex+1,
  1506. (m_cAltMapping - dwIndex - 1) * sizeof(CIisMapping*) );
  1507. --m_cAltMapping;
  1508. return TRUE;
  1509. }
  1510. return FALSE;
  1511. }
  1512. if ( dwIndex < m_cMapping )
  1513. {
  1514. delete m_pMapping[dwIndex];
  1515. memmove( m_pMapping+dwIndex,
  1516. m_pMapping+dwIndex+1,
  1517. (m_cMapping - dwIndex - 1) * sizeof(CIisMapping*) );
  1518. --m_cMapping;
  1519. return UpdateClasses( FALSE );
  1520. }
  1521. return FALSE;
  1522. }
  1523. BOOL
  1524. CIisAcctMapper::Save(
  1525. )
  1526. /*++
  1527. Routine Description:
  1528. Save mapper ( mappings, hierarchy, derived class private data )
  1529. to a file, updating registry entry with MD5 signature
  1530. Arguments:
  1531. None
  1532. Returns:
  1533. TRUE if success, FALSE if error
  1534. --*/
  1535. {
  1536. UINT x;
  1537. FILE * fOut = NULL;
  1538. BOOL fSt = TRUE;
  1539. DWORD dwVal;
  1540. DWORD st;
  1541. IIS_CRYPTO_STORAGE storage;
  1542. PIIS_CRYPTO_BLOB blob;
  1543. Lock();
  1544. MD5Init( &m_md5 );
  1545. if ( FAILED(storage.Initialize()) )
  1546. {
  1547. fSt = FALSE;
  1548. goto cleanup;
  1549. }
  1550. if ( m_pSesKey != NULL )
  1551. {
  1552. LocalFree( m_pSesKey );
  1553. m_pSesKey = NULL;
  1554. m_dwSesKey = 0;
  1555. }
  1556. if ( FAILED( storage.GetSessionKeyBlob( &blob ) ) )
  1557. {
  1558. fSt = FALSE;
  1559. goto cleanup;
  1560. }
  1561. m_dwSesKey = IISCryptoGetBlobLength( blob );
  1562. if ( (m_pSesKey = (LPBYTE)LocalAlloc( LMEM_FIXED, m_dwSesKey)) == NULL )
  1563. {
  1564. m_dwSesKey = 0;
  1565. fSt = FALSE;
  1566. goto cleanup;
  1567. }
  1568. memcpy( m_pSesKey, (LPBYTE)blob, m_dwSesKey );
  1569. if ( (fOut = fopen( m_achFileName, "wb" )) == NULL )
  1570. {
  1571. fSt = FALSE;
  1572. goto cleanup;
  1573. }
  1574. // magic value & version
  1575. dwVal = IISMDB_FILE_MAGIC_VALUE;
  1576. if( fwrite( (LPVOID)&dwVal, sizeof(dwVal), 1, fOut ) != 1 )
  1577. {
  1578. fSt = FALSE;
  1579. goto cleanup;
  1580. }
  1581. MD5Update( &m_md5, (LPBYTE)&dwVal, sizeof(dwVal) );
  1582. dwVal = IISMDB_CURRENT_VERSION;
  1583. if( fwrite( (LPVOID)&dwVal, sizeof(dwVal), 1, fOut ) != 1 )
  1584. {
  1585. fSt = FALSE;
  1586. goto cleanup;
  1587. }
  1588. MD5Update( &m_md5, (LPBYTE)&dwVal, sizeof(dwVal) );
  1589. // mappings
  1590. if( fwrite( (LPVOID)&m_cMapping, sizeof(m_cMapping), 1, fOut ) != 1 )
  1591. {
  1592. fSt = FALSE;
  1593. goto cleanup;
  1594. }
  1595. MD5Update( &m_md5, (LPBYTE)&m_cMapping, sizeof(m_cMapping) );
  1596. for ( x = 0 ; x < m_cMapping ; ++x )
  1597. {
  1598. if ( !m_pMapping[x]->Serialize( fOut ,(VALID_CTX)&m_md5, (LPVOID)&storage) )
  1599. {
  1600. fSt = FALSE;
  1601. goto cleanup;
  1602. }
  1603. }
  1604. // save hierarchy
  1605. if( fwrite( (LPVOID)&m_cHierarchy, sizeof(m_cHierarchy), 1, fOut ) != 1 )
  1606. {
  1607. fSt = FALSE;
  1608. goto cleanup;
  1609. }
  1610. MD5Update( &m_md5, (LPBYTE)&m_cHierarchy, sizeof(m_cHierarchy) );
  1611. if( fwrite( (LPVOID)m_pHierarchy, sizeof(IISMDB_HEntry), m_cHierarchy, fOut ) != m_cHierarchy )
  1612. {
  1613. fSt = FALSE;
  1614. goto cleanup;
  1615. }
  1616. MD5Update( &m_md5, (LPBYTE)m_pHierarchy, sizeof(IISMDB_HEntry)*m_cHierarchy );
  1617. // save private data
  1618. fSt = SavePrivate( fOut, (VALID_CTX)&m_md5 );
  1619. MD5Final( &m_md5 );
  1620. cleanup:
  1621. if ( fOut != NULL )
  1622. {
  1623. fclose( fOut );
  1624. }
  1625. // update registry
  1626. if ( !fSt )
  1627. {
  1628. memset( m_md5.digest, '\0', sizeof(m_md5.digest) );
  1629. }
  1630. Unlock();
  1631. return fSt;
  1632. }
  1633. BOOL
  1634. CIisAcctMapper::Reset(
  1635. )
  1636. /*++
  1637. Routine Description:
  1638. Reset mapper to empty state
  1639. Arguments:
  1640. None
  1641. Returns:
  1642. TRUE if success, FALSE if error
  1643. --*/
  1644. {
  1645. UINT x;
  1646. // free all mapping
  1647. if ( m_pMapping != NULL )
  1648. {
  1649. for ( x = 0 ; x < m_cMapping ; ++x )
  1650. {
  1651. delete m_pMapping[x];
  1652. }
  1653. LocalFree( m_pMapping );
  1654. m_pMapping = NULL;
  1655. }
  1656. m_cMapping = 0;
  1657. if ( m_pClasses != NULL )
  1658. {
  1659. LocalFree( m_pClasses );
  1660. m_pClasses = NULL;
  1661. }
  1662. // default hierarchy
  1663. if ( m_pHierarchy == NULL )
  1664. {
  1665. IISMDB_HEntry *pH = GetDefaultHierarchy( &m_cHierarchy );
  1666. m_pHierarchy = (IISMDB_HEntry*)LocalAlloc( LMEM_FIXED, sizeof(IISMDB_HEntry)*m_cHierarchy );
  1667. if ( m_pHierarchy == NULL )
  1668. {
  1669. return FALSE;
  1670. }
  1671. memcpy( m_pHierarchy, pH, m_cHierarchy * sizeof(IISMDB_HEntry) );
  1672. }
  1673. return ResetPrivate();
  1674. }
  1675. BOOL
  1676. CIisAcctMapper::Load(
  1677. )
  1678. /*++
  1679. Routine Description:
  1680. Load mapper ( mappings, hierarchy, derived class private data )
  1681. from a file, checking registry entry for MD5 signature
  1682. Arguments:
  1683. None
  1684. Returns:
  1685. TRUE if success, FALSE if error
  1686. --*/
  1687. {
  1688. UINT x;
  1689. MD5_CTX md5Check;
  1690. FILE * fIn;
  1691. BOOL fSt = TRUE;
  1692. DWORD dwType;
  1693. DWORD dwLen;
  1694. DWORD dwVal;
  1695. IIS_CRYPTO_STORAGE storage;
  1696. Reset();
  1697. MD5Init( &md5Check );
  1698. if ( FAILED( storage.Initialize( (PIIS_CRYPTO_BLOB)m_pSesKey) ) )
  1699. {
  1700. return FALSE;
  1701. }
  1702. if ( (fIn = fopen( m_achFileName, "rb" )) == NULL )
  1703. {
  1704. return FALSE;
  1705. }
  1706. // magic value & version
  1707. if( fread( (LPVOID)&dwVal, sizeof(dwVal), 1, fIn ) != 1 )
  1708. {
  1709. fSt = FALSE;
  1710. goto cleanup;
  1711. }
  1712. if ( dwVal != IISMDB_FILE_MAGIC_VALUE )
  1713. {
  1714. SetLastError( ERROR_BAD_FORMAT );
  1715. fSt = FALSE;
  1716. goto cleanup;
  1717. }
  1718. MD5Update( &md5Check, (LPBYTE)&dwVal, sizeof(dwVal) );
  1719. if( fread( (LPVOID)&dwVal, sizeof(dwVal), 1, fIn ) != 1 )
  1720. {
  1721. fSt = FALSE;
  1722. goto cleanup;
  1723. }
  1724. MD5Update( &md5Check, (LPBYTE)&dwVal, sizeof(dwVal) );
  1725. // mappings
  1726. if( fread( (LPVOID)&m_cMapping, sizeof(m_cMapping), 1, fIn ) != 1 )
  1727. {
  1728. fSt = FALSE;
  1729. goto cleanup;
  1730. }
  1731. MD5Update( &md5Check, (LPBYTE)&m_cMapping, sizeof(m_cMapping) );
  1732. m_pMapping = (CIisMapping**)LocalAlloc( LMEM_FIXED, sizeof(CIisMapping*)*m_cMapping );
  1733. if ( m_pMapping == NULL )
  1734. {
  1735. fSt = FALSE;
  1736. goto cleanup;
  1737. }
  1738. for ( x = 0 ; x < m_cMapping ; ++x )
  1739. {
  1740. if ( !(m_pMapping[x] = CreateNewMapping()) )
  1741. {
  1742. m_cMapping = x;
  1743. fSt = FALSE;
  1744. goto cleanup;
  1745. }
  1746. if ( !m_pMapping[x]->Deserialize( fIn ,(VALID_CTX)&md5Check, (LPVOID)&storage ) )
  1747. {
  1748. m_cMapping = x;
  1749. fSt = FALSE;
  1750. goto cleanup;
  1751. }
  1752. }
  1753. // load hierarchy
  1754. if( fread( (LPVOID)&m_cHierarchy, sizeof(m_cHierarchy), 1, fIn ) != 1 )
  1755. {
  1756. fSt = FALSE;
  1757. goto cleanup;
  1758. }
  1759. MD5Update( &md5Check, (LPBYTE)&m_cHierarchy, sizeof(m_cHierarchy) );
  1760. m_pHierarchy = (IISMDB_HEntry*)LocalAlloc( LMEM_FIXED, sizeof(IISMDB_HEntry)*m_cHierarchy );
  1761. if ( m_pHierarchy == NULL )
  1762. {
  1763. fSt = FALSE;
  1764. goto cleanup;
  1765. }
  1766. if( fread( (LPVOID)m_pHierarchy, sizeof(IISMDB_HEntry), m_cHierarchy, fIn ) != m_cHierarchy )
  1767. {
  1768. fSt = FALSE;
  1769. goto cleanup;
  1770. }
  1771. //
  1772. // insure hierarchy correct
  1773. //
  1774. for ( x = 0 ; x < m_cHierarchy; ++x )
  1775. {
  1776. if ( m_pHierarchy[x].m_dwIndex >= m_cFields )
  1777. {
  1778. fSt = FALSE;
  1779. goto cleanup;
  1780. }
  1781. }
  1782. MD5Update( &md5Check, (LPBYTE)m_pHierarchy, sizeof(IISMDB_HEntry)*m_cHierarchy );
  1783. // load private data
  1784. fSt = LoadPrivate( fIn, (VALID_CTX)&md5Check );
  1785. MD5Final( &md5Check );
  1786. #if 0
  1787. //
  1788. // Don't use signature for now - a metabase Restore operation
  1789. // may have restored another signature, so metabase and
  1790. // file won't match
  1791. //
  1792. if ( !(fSt = !memcmp( m_md5.digest,
  1793. md5Check.digest,
  1794. sizeof(md5Check.digest) )) )
  1795. {
  1796. SetLastError( ERROR_INVALID_ACCESS );
  1797. }
  1798. #endif
  1799. cleanup:
  1800. fclose( fIn );
  1801. if ( !fSt && GetLastError() != ERROR_INVALID_ACCESS )
  1802. {
  1803. Reset();
  1804. }
  1805. else
  1806. {
  1807. UpdateClasses();
  1808. }
  1809. if ( !fSt )
  1810. {
  1811. char achErr[32];
  1812. LPCTSTR pA[2];
  1813. pA[0] = m_achFileName;
  1814. pA[1] = achErr;
  1815. _itoa( GetLastError(), achErr, 10 );
  1816. ReportIisMapEvent( EVENTLOG_ERROR_TYPE,
  1817. IISMAP_EVENT_LOAD_ERROR,
  1818. 2,
  1819. pA );
  1820. }
  1821. return fSt;
  1822. }
  1823. // CIisCertMapper
  1824. CIisCertMapper::CIisCertMapper(
  1825. )
  1826. /*++
  1827. Routine Description:
  1828. Constructor for CIisCertMapper
  1829. Arguments:
  1830. None
  1831. Returns:
  1832. Nothing
  1833. --*/
  1834. {
  1835. m_pIssuers = NULL;
  1836. m_cIssuers = 0;
  1837. m_pFields = IisCertMappingFields;
  1838. m_cFields = sizeof(IisCertMappingFields)/sizeof(IISMDB_Fields);
  1839. m_dwOptions = IISMDB_CERT_OPTIONS;
  1840. }
  1841. CIisCertMapper::~CIisCertMapper(
  1842. )
  1843. /*++
  1844. Routine Description:
  1845. Destructor for CIisCertMapper
  1846. Arguments:
  1847. None
  1848. Returns:
  1849. Nothing
  1850. --*/
  1851. {
  1852. }
  1853. IISMDB_HEntry*
  1854. CIisCertMapper::GetDefaultHierarchy(
  1855. LPDWORD pdwN
  1856. )
  1857. /*++
  1858. Routine Description:
  1859. return ptr to default hierarchy for certificates mapping
  1860. Arguments:
  1861. pdwN -- updated with hierarchy entries count
  1862. Returns:
  1863. ptr to hierarchy entries or NULL if error
  1864. --*/
  1865. {
  1866. *pdwN = sizeof(IisCertMappingHierarchy) / sizeof(IISMDB_HEntry);
  1867. return IisCertMappingHierarchy;
  1868. }
  1869. #if defined(DECODE_ASN1)
  1870. CIisMapping*
  1871. CIisCertMapper::CreateNewMapping(
  1872. Cert_Map *pC
  1873. )
  1874. /*++
  1875. Routine Description:
  1876. Create a new mapping from a certificate
  1877. Arguments:
  1878. pC -- ptr to certificate issuer & subject
  1879. Returns:
  1880. ptr to mapping. ownership of this object is transfered to caller.
  1881. NULL if error
  1882. --*/
  1883. {
  1884. CCertMapping *pCM = new CCertMapping( this );
  1885. if ( pCM == NULL )
  1886. {
  1887. return NULL;
  1888. }
  1889. if ( pCM->Init( pC, m_pHierarchy, m_cHierarchy ) )
  1890. {
  1891. return (CIisMapping*)pCM;
  1892. }
  1893. delete pCM;
  1894. return NULL;
  1895. }
  1896. CIisMapping*
  1897. CIisCertMapper::CreateNewMapping(
  1898. const LPBYTE pC,
  1899. DWORD cC
  1900. )
  1901. /*++
  1902. Routine Description:
  1903. Create a new mapping from a certificate
  1904. Arguments:
  1905. pC -- ptr to certificate issuer & subject
  1906. cC -- size of buffer pointed to by pC
  1907. Returns:
  1908. ptr to mapping. ownership of this object is transfered to caller.
  1909. NULL if error
  1910. --*/
  1911. {
  1912. CCertMapping *pCM = new CCertMapping( this );
  1913. if ( pCM == NULL )
  1914. {
  1915. return NULL;
  1916. }
  1917. if ( pCM->Init( pC, cC, m_pHierarchy, m_cHierarchy ) )
  1918. {
  1919. return (CIisMapping*)pCM;
  1920. }
  1921. delete pCM;
  1922. return NULL;
  1923. }
  1924. #endif
  1925. BOOL
  1926. CIisCertMapper::ResetPrivate(
  1927. )
  1928. /*++
  1929. Routine Description:
  1930. Reset CIisCertMapper issuer list
  1931. Arguments:
  1932. None
  1933. Returns:
  1934. TRUE if success, FALSE if error
  1935. --*/
  1936. {
  1937. // free issuer list
  1938. if ( m_pIssuers != NULL )
  1939. {
  1940. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  1941. {
  1942. LocalFree( m_pIssuers[x].pbIssuer );
  1943. }
  1944. LocalFree( m_pIssuers );
  1945. m_pIssuers = NULL;
  1946. }
  1947. m_cIssuers = 0;
  1948. return TRUE;
  1949. }
  1950. BOOL
  1951. CIisCertMapper::LoadPrivate(
  1952. FILE* fIn,
  1953. VALID_CTX pMD5
  1954. )
  1955. /*++
  1956. Routine Description:
  1957. Load issuer list
  1958. Arguments:
  1959. fIn -- file to read from
  1960. pMD5 -- MD5 to update with signature from input byte stream
  1961. Returns:
  1962. TRUE if success, FALSE if error
  1963. --*/
  1964. {
  1965. BOOL fSt = TRUE;
  1966. UINT x;
  1967. if( fread( (LPVOID)&m_cIssuers, sizeof(m_cIssuers), 1, fIn ) != 1 )
  1968. {
  1969. fSt = FALSE;
  1970. goto cleanup;
  1971. }
  1972. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_cIssuers, sizeof(m_cIssuers) );
  1973. m_pIssuers = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, sizeof(IssuerAccepted)*m_cIssuers );
  1974. if ( m_pIssuers == NULL )
  1975. {
  1976. fSt = FALSE;
  1977. goto cleanup;
  1978. }
  1979. for ( x = 0 ; x < m_cIssuers ; ++x )
  1980. {
  1981. if ( fread( (LPVOID)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen), 1, fIn ) != 1 )
  1982. {
  1983. m_cIssuers = x;
  1984. fSt = FALSE;
  1985. goto cleanup;
  1986. }
  1987. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen) );
  1988. if ( (m_pIssuers[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED, m_pIssuers[x].cbIssuerLen )) == NULL )
  1989. {
  1990. m_cIssuers = x;
  1991. fSt = FALSE;
  1992. goto cleanup;
  1993. }
  1994. if ( fread( m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen, 1, fIn ) != 1 )
  1995. {
  1996. m_cIssuers = x;
  1997. fSt = FALSE;
  1998. goto cleanup;
  1999. }
  2000. MD5Update( (MD5_CTX*)pMD5, m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen );
  2001. }
  2002. cleanup:
  2003. return fSt;
  2004. }
  2005. BOOL
  2006. CIisCertMapper::SavePrivate(
  2007. FILE* fOut,
  2008. VALID_CTX pMD5
  2009. )
  2010. /*++
  2011. Routine Description:
  2012. Save issuer list
  2013. Arguments:
  2014. fOut -- file to write to
  2015. pMD5 -- MD5 to update with signature of output byte stream
  2016. Returns:
  2017. TRUE if success, FALSE if error
  2018. --*/
  2019. {
  2020. BOOL fSt = TRUE;
  2021. UINT x;
  2022. if( fwrite( (LPVOID)&m_cIssuers, sizeof(m_cIssuers), 1, fOut ) != 1 )
  2023. {
  2024. fSt = FALSE;
  2025. goto cleanup;
  2026. }
  2027. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_cIssuers, sizeof(m_cIssuers) );
  2028. for ( x = 0 ; x < m_cIssuers ; ++x )
  2029. {
  2030. if ( fwrite( (LPVOID)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen), 1, fOut ) != 1 )
  2031. {
  2032. fSt = FALSE;
  2033. goto cleanup;
  2034. }
  2035. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen) );
  2036. if ( fwrite( m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen, 1, fOut ) != 1 )
  2037. {
  2038. fSt = FALSE;
  2039. goto cleanup;
  2040. }
  2041. MD5Update( (MD5_CTX*)pMD5, m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen );
  2042. }
  2043. cleanup:
  2044. return fSt;
  2045. }
  2046. BOOL
  2047. CIisCertMapper::SetIssuerList(
  2048. IssuerAccepted*pI,
  2049. DWORD dwC
  2050. )
  2051. /*++
  2052. Routine Description:
  2053. Set the issuer list by copying supplied list
  2054. Arguments:
  2055. pI -- list of issuers
  2056. dwC -- count of issuers
  2057. Returns:
  2058. TRUE if success, FALSE if error
  2059. --*/
  2060. {
  2061. UINT x;
  2062. if ( (m_pIssuers = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, sizeof(IssuerAccepted)*dwC )) == NULL )
  2063. {
  2064. return FALSE;
  2065. }
  2066. for ( x = 0 ; x < dwC ; ++x )
  2067. {
  2068. m_pIssuers[x].cbIssuerLen = pI[x].cbIssuerLen;
  2069. if ( (m_pIssuers[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED, pI[x].cbIssuerLen )) == NULL )
  2070. {
  2071. m_cIssuers = x;
  2072. return FALSE;
  2073. }
  2074. memcpy( m_pIssuers[x].pbIssuer, pI[x].pbIssuer, pI[x].cbIssuerLen );
  2075. }
  2076. m_cIssuers = dwC;
  2077. return TRUE;
  2078. }
  2079. BOOL
  2080. CIisCertMapper::GetIssuerList(
  2081. IssuerAccepted**pIssuers,
  2082. DWORD*pdwI
  2083. )
  2084. /*++
  2085. Routine Description:
  2086. Retrieve the issuer list. Ownership of list transferred to caller
  2087. Arguments:
  2088. pI -- updated with ptr to array of issuers
  2089. pdwI -- updated with count of issuers
  2090. Returns:
  2091. TRUE if success, FALSE if error
  2092. --*/
  2093. {
  2094. IssuerAccepted *pI;
  2095. Lock();
  2096. pI = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, m_cIssuers * sizeof(IssuerAccepted*) );
  2097. if ( pI == NULL )
  2098. {
  2099. Unlock();
  2100. return FALSE;
  2101. }
  2102. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  2103. {
  2104. if ( (pI[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED,
  2105. m_pIssuers[x].cbIssuerLen ))
  2106. == NULL )
  2107. {
  2108. Unlock();
  2109. DeleteIssuerList( pI, x );
  2110. return FALSE;
  2111. }
  2112. memcpy( pI[x].pbIssuer,
  2113. m_pIssuers[x].pbIssuer,
  2114. m_pIssuers[x].cbIssuerLen );
  2115. }
  2116. *pIssuers = pI;
  2117. *pdwI = m_cIssuers;
  2118. Unlock();
  2119. return TRUE;
  2120. }
  2121. BOOL
  2122. CIisCertMapper::DeleteIssuerList(
  2123. IssuerAccepted* pI,
  2124. DWORD dwI
  2125. )
  2126. /*++
  2127. Routine Description:
  2128. Delete an issuer list.
  2129. Arguments:
  2130. pI -- ptr to array of issuers
  2131. dwI -- count of issuers
  2132. Returns:
  2133. TRUE if success, FALSE if error
  2134. --*/
  2135. {
  2136. for ( DWORD x = 0 ; x < dwI ; ++x )
  2137. {
  2138. LocalFree( pI[x].pbIssuer );
  2139. }
  2140. LocalFree( pI );
  2141. return TRUE;
  2142. }
  2143. BOOL
  2144. CIisCertMapper::GetIssuerBuffer(
  2145. LPBYTE pB,
  2146. DWORD* pdwI
  2147. )
  2148. /*++
  2149. Routine Description:
  2150. Retrieve the issuer list. Ownership of list transferred to caller
  2151. Arguments:
  2152. pB -- updated with ptr to issuers buffer
  2153. pdwI -- updated with size of buffer of issuers
  2154. Returns:
  2155. TRUE if success, FALSE if error
  2156. --*/
  2157. {
  2158. LPBYTE pS;
  2159. DWORD dwC = 0;
  2160. Lock();
  2161. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  2162. {
  2163. dwC += m_pIssuers[x].cbIssuerLen + sizeof(USHORT);
  2164. }
  2165. *pdwI = dwC;
  2166. if ( pB != NULL )
  2167. {
  2168. for ( pS = pB, x = 0 ; x < m_cIssuers ; ++x )
  2169. {
  2170. pS[0] = (BYTE)(m_pIssuers[x].cbIssuerLen >> 8);
  2171. pS[1] = (BYTE)(m_pIssuers[x].cbIssuerLen);
  2172. memcpy( pS + sizeof(USHORT),
  2173. m_pIssuers[x].pbIssuer,
  2174. m_pIssuers[x].cbIssuerLen );
  2175. pS += m_pIssuers[x].cbIssuerLen + sizeof(USHORT);
  2176. }
  2177. }
  2178. Unlock();
  2179. return TRUE;
  2180. }
  2181. BOOL
  2182. CIisCertMapper::FreeIssuerBuffer(
  2183. LPBYTE pI
  2184. )
  2185. /*++
  2186. Routine Description:
  2187. Delete an issuer list.
  2188. Arguments:
  2189. pI -- ptr to issuers
  2190. Returns:
  2191. TRUE if success, FALSE if error
  2192. --*/
  2193. {
  2194. LocalFree( pI );
  2195. return TRUE;
  2196. }
  2197. // CIisCert11Mapper
  2198. CIisCert11Mapper::CIisCert11Mapper(
  2199. )
  2200. /*++
  2201. Routine Description:
  2202. Constructor for CIisCert11Mapper
  2203. Arguments:
  2204. None
  2205. Returns:
  2206. Nothing
  2207. --*/
  2208. {
  2209. m_pIssuers = NULL;
  2210. m_cIssuers = 0;
  2211. m_pFields = IisCert11MappingFields;
  2212. m_cFields = sizeof(IisCert11MappingFields)/sizeof(IISMDB_Fields);
  2213. m_dwOptions = IISMDB_CERT11_OPTIONS;
  2214. m_pSubjectSource = NULL;
  2215. m_pDefaultDomain = NULL;
  2216. }
  2217. CIisCert11Mapper::~CIisCert11Mapper(
  2218. )
  2219. /*++
  2220. Routine Description:
  2221. Destructor for CIisCert11Mapper
  2222. Arguments:
  2223. None
  2224. Returns:
  2225. Nothing
  2226. --*/
  2227. {
  2228. }
  2229. BOOL
  2230. CIisCert11Mapper::Add(
  2231. CIisMapping* pM
  2232. )
  2233. /*++
  2234. Routine Description:
  2235. Add a mapping entry to mapping array
  2236. Transfer ownership of mapping object to mapper
  2237. Check is mapping to same NT account does not already exist.
  2238. Arguments:
  2239. pM -- pointer to mapping to be added to mapper
  2240. Returns:
  2241. TRUE if success, FALSE if error
  2242. --*/
  2243. {
  2244. UINT x;
  2245. LPSTR pA;
  2246. LPSTR pF;
  2247. DWORD dwA;
  2248. DWORD dwF;
  2249. // check if NT acct not already present.
  2250. // if so, return FALSE, SetLastError( ERROR_INVALID_PARAMETER );
  2251. if ( pM == NULL )
  2252. {
  2253. return FALSE;
  2254. }
  2255. #if 0
  2256. if ( !pM->MappingGetField( IISMDB_INDEX_CERT11_NT_ACCT, &pA, &dwA, FALSE )
  2257. || pA == NULL )
  2258. {
  2259. pA = "";
  2260. }
  2261. for ( x = 0 ; x < m_cMapping ; ++x )
  2262. {
  2263. if ( !m_pMapping[x]->MappingGetField( IISMDB_INDEX_CERT11_NT_ACCT, &pF, &dwF, FALSE )
  2264. || pF == NULL )
  2265. {
  2266. pF = "";
  2267. }
  2268. if ( dwA == dwF && !memcmp( pF, pA, dwF ) )
  2269. {
  2270. SetLastError( ERROR_INVALID_PARAMETER );
  2271. return FALSE;
  2272. }
  2273. }
  2274. #endif
  2275. #if 1
  2276. #if defined(CERT11_FULL_CERT)
  2277. LPSTR pCe;
  2278. DWORD dwCe;
  2279. LPSTR pCeIter;
  2280. DWORD dwCeIter;
  2281. if ( !pM->MappingGetField( IISMDB_INDEX_CERT11_CERT, &pCe, &dwCe, FALSE )
  2282. || pCe == NULL )
  2283. {
  2284. dwCe = 0;
  2285. }
  2286. for ( x = 0 ; x < m_cMapping ; ++x )
  2287. {
  2288. if ( !m_pMapping[x]->MappingGetField( IISMDB_INDEX_CERT11_CERT, &pCeIter, &dwCeIter, FALSE )
  2289. || pCeIter == NULL )
  2290. {
  2291. dwCeIter = 0;
  2292. }
  2293. if ( dwCe == dwCeIter && !memcmp( pCe, pCeIter, dwCe ) )
  2294. {
  2295. SetLastError( ERROR_INVALID_PARAMETER );
  2296. return FALSE;
  2297. }
  2298. }
  2299. #else
  2300. LPSTR pSu;
  2301. LPSTR pIs;
  2302. DWORD dwSu;
  2303. DWORD dwIs;
  2304. LPSTR pSuIter;
  2305. LPSTR pIsIter;
  2306. DWORD dwSuIter;
  2307. DWORD dwIsIter;
  2308. if ( !pM->MappingGetField( IISMDB_INDEX_CERT11_SUBJECT, &pSu, &dwSu, FALSE )
  2309. || pSu == NULL )
  2310. {
  2311. dwSu = 0;
  2312. }
  2313. if ( !pM->MappingGetField( IISMDB_INDEX_CERT11_ISSUER, &pIs, &dwIs, FALSE )
  2314. || pIs == NULL )
  2315. {
  2316. dwIs = 0;
  2317. }
  2318. for ( x = 0 ; x < m_cMapping ; ++x )
  2319. {
  2320. if ( !m_pMapping[x]->MappingGetField( IISMDB_INDEX_CERT11_SUBJECT, &pSuIter, &dwSuIter, FALSE )
  2321. || pSuIter == NULL )
  2322. {
  2323. dwSuIter = 0;
  2324. }
  2325. if ( !m_pMapping[x]->MappingGetField( IISMDB_INDEX_CERT11_ISSUER, &pIsIter, &dwIsIter, FALSE )
  2326. || pIsIter == NULL )
  2327. {
  2328. dwIsIter = 0;
  2329. }
  2330. if ( dwSu == dwSuIter && !memcmp( pSu, pSuIter, dwSu ) &&
  2331. dwIs == dwIsIter && !memcmp( pIs, pIsIter, dwIs ) )
  2332. {
  2333. SetLastError( ERROR_INVALID_PARAMETER );
  2334. return FALSE;
  2335. }
  2336. }
  2337. #endif
  2338. #endif
  2339. return CIisAcctMapper::Add( pM );
  2340. }
  2341. IISMDB_HEntry*
  2342. CIisCert11Mapper::GetDefaultHierarchy(
  2343. LPDWORD pdwN
  2344. )
  2345. /*++
  2346. Routine Description:
  2347. return ptr to default hierarchy for certificates mapping
  2348. Arguments:
  2349. pdwN -- updated with hierarchy entries count
  2350. Returns:
  2351. ptr to hierarchy entries or NULL if error
  2352. --*/
  2353. {
  2354. *pdwN = sizeof(IisCert11MappingHierarchy) / sizeof(IISMDB_HEntry);
  2355. return IisCert11MappingHierarchy;
  2356. }
  2357. #if defined(CERT11_FULL_CERT)
  2358. CIisMapping*
  2359. CIisCert11Mapper::CreateNewMapping(
  2360. LPBYTE pC,
  2361. DWORD dwC
  2362. )
  2363. /*++
  2364. Routine Description:
  2365. Create a new mapping from a certificate
  2366. Arguments:
  2367. pC -- cert ( ASN.1 format )
  2368. dwC -- length of cert
  2369. Returns:
  2370. ptr to mapping. ownership of this object is transfered to caller.
  2371. NULL if error
  2372. --*/
  2373. {
  2374. CCert11Mapping *pCM = new CCert11Mapping( this );
  2375. if ( pCM == NULL )
  2376. {
  2377. return NULL;
  2378. }
  2379. if ( pCM->Init( pC, dwC, m_pHierarchy, m_cHierarchy ) )
  2380. {
  2381. return (CIisMapping*)pCM;
  2382. }
  2383. delete pCM;
  2384. return NULL;
  2385. }
  2386. #else
  2387. CIisMapping*
  2388. CIisCert11Mapper::CreateNewMapping(
  2389. LPBYTE pI,
  2390. DWORD dwI,
  2391. LPBYTE pS,
  2392. DWORD dwS
  2393. )
  2394. /*++
  2395. Routine Description:
  2396. Create a new mapping from a certificate
  2397. Arguments:
  2398. pI -- cert issuer ( ASN.1 format )
  2399. dwI -- length of issuer
  2400. pS -- cert subject ( ASN.1 format )
  2401. dwS -- length of subject
  2402. Returns:
  2403. ptr to mapping. ownership of this object is transfered to caller.
  2404. NULL if error
  2405. --*/
  2406. {
  2407. CCert11Mapping *pCM = new CCert11Mapping( this );
  2408. if ( pCM == NULL )
  2409. {
  2410. return NULL;
  2411. }
  2412. if ( pCM->Init( pI, dwI, pS, dwS, m_pHierarchy, m_cHierarchy ) )
  2413. {
  2414. return (CIisMapping*)pCM;
  2415. }
  2416. delete pCM;
  2417. return NULL;
  2418. }
  2419. #endif
  2420. BOOL
  2421. CIisCert11Mapper::ResetPrivate(
  2422. )
  2423. /*++
  2424. Routine Description:
  2425. Reset CIisCert11Mapper issuer list
  2426. Arguments:
  2427. None
  2428. Returns:
  2429. TRUE if success, FALSE if error
  2430. --*/
  2431. {
  2432. // free issuer list
  2433. if ( m_pIssuers != NULL )
  2434. {
  2435. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  2436. {
  2437. LocalFree( m_pIssuers[x].pbIssuer );
  2438. }
  2439. LocalFree( m_pIssuers );
  2440. m_pIssuers = NULL;
  2441. }
  2442. m_cIssuers = 0;
  2443. if ( m_pSubjectSource != NULL )
  2444. {
  2445. LocalFree( m_pSubjectSource );
  2446. }
  2447. if ( m_pDefaultDomain != NULL )
  2448. {
  2449. LocalFree( m_pDefaultDomain );
  2450. }
  2451. return TRUE;
  2452. }
  2453. BOOL
  2454. CIisCert11Mapper::LoadPrivate(
  2455. FILE* fIn,
  2456. VALID_CTX pMD5
  2457. )
  2458. /*++
  2459. Routine Description:
  2460. Load issuer list
  2461. Arguments:
  2462. fIn -- file to read from
  2463. pMD5 -- MD5 to update with signature from input byte stream
  2464. Returns:
  2465. TRUE if success, FALSE if error
  2466. --*/
  2467. {
  2468. BOOL fSt = TRUE;
  2469. UINT x;
  2470. UINT cLen;
  2471. CHAR achBuf[64];
  2472. if( fread( (LPVOID)&m_cIssuers, sizeof(m_cIssuers), 1, fIn ) != 1 )
  2473. {
  2474. fSt = FALSE;
  2475. goto cleanup;
  2476. }
  2477. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_cIssuers, sizeof(m_cIssuers) );
  2478. m_pIssuers = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, sizeof(IssuerAccepted)*m_cIssuers );
  2479. if ( m_pIssuers == NULL )
  2480. {
  2481. fSt = FALSE;
  2482. goto cleanup;
  2483. }
  2484. for ( x = 0 ; x < m_cIssuers ; ++x )
  2485. {
  2486. if ( fread( (LPVOID)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen), 1, fIn ) != 1 )
  2487. {
  2488. m_cIssuers = x;
  2489. fSt = FALSE;
  2490. goto cleanup;
  2491. }
  2492. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen) );
  2493. if ( (m_pIssuers[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED, m_pIssuers[x].cbIssuerLen )) == NULL )
  2494. {
  2495. m_cIssuers = x;
  2496. fSt = FALSE;
  2497. goto cleanup;
  2498. }
  2499. if ( fread( m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen, 1, fIn ) != 1 )
  2500. {
  2501. m_cIssuers = x;
  2502. fSt = FALSE;
  2503. goto cleanup;
  2504. }
  2505. MD5Update( (MD5_CTX*)pMD5, m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen );
  2506. }
  2507. //
  2508. // Read subject source
  2509. //
  2510. if( Iisfgets( achBuf, sizeof(achBuf), fIn ) == NULL )
  2511. {
  2512. fSt = FALSE;
  2513. goto cleanup;
  2514. }
  2515. cLen = strlen(achBuf);
  2516. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)achBuf, cLen );
  2517. if ( !(m_pSubjectSource = (LPSTR)LocalAlloc( LMEM_FIXED, cLen+1 )) )
  2518. {
  2519. fSt = FALSE;
  2520. goto cleanup;
  2521. }
  2522. memcpy( m_pSubjectSource, achBuf, cLen+1 );
  2523. //
  2524. // Read default domain
  2525. //
  2526. if( Iisfgets( achBuf, sizeof(achBuf), fIn ) == NULL )
  2527. {
  2528. fSt = FALSE;
  2529. goto cleanup;
  2530. }
  2531. cLen = strlen(achBuf);
  2532. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)achBuf, cLen );
  2533. if ( !(m_pDefaultDomain = (LPSTR)LocalAlloc( LMEM_FIXED, cLen+1 )) )
  2534. {
  2535. fSt = FALSE;
  2536. goto cleanup;
  2537. }
  2538. memcpy( m_pDefaultDomain, achBuf, cLen+1 );
  2539. cleanup:
  2540. return fSt;
  2541. }
  2542. BOOL
  2543. CIisCert11Mapper::SavePrivate(
  2544. FILE* fOut,
  2545. VALID_CTX pMD5
  2546. )
  2547. /*++
  2548. Routine Description:
  2549. Save issuer list
  2550. Arguments:
  2551. fOut -- file to write to
  2552. pMD5 -- MD5 to update with signature of output byte stream
  2553. Returns:
  2554. TRUE if success, FALSE if error
  2555. --*/
  2556. {
  2557. BOOL fSt = TRUE;
  2558. UINT x;
  2559. if( fwrite( (LPVOID)&m_cIssuers, sizeof(m_cIssuers), 1, fOut ) != 1 )
  2560. {
  2561. fSt = FALSE;
  2562. goto cleanup;
  2563. }
  2564. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_cIssuers, sizeof(m_cIssuers) );
  2565. for ( x = 0 ; x < m_cIssuers ; ++x )
  2566. {
  2567. if ( fwrite( (LPVOID)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen), 1, fOut ) != 1 )
  2568. {
  2569. fSt = FALSE;
  2570. goto cleanup;
  2571. }
  2572. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)&m_pIssuers[x].cbIssuerLen, sizeof(m_pIssuers[x].cbIssuerLen) );
  2573. if ( fwrite( m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen, 1, fOut ) != 1 )
  2574. {
  2575. fSt = FALSE;
  2576. goto cleanup;
  2577. }
  2578. MD5Update( (MD5_CTX*)pMD5, m_pIssuers[x].pbIssuer, m_pIssuers[x].cbIssuerLen );
  2579. }
  2580. //
  2581. // Write subject source
  2582. //
  2583. if ( m_pSubjectSource )
  2584. {
  2585. if( Iisfputs( m_pSubjectSource, fOut ) == EOF )
  2586. {
  2587. fSt = FALSE;
  2588. goto cleanup;
  2589. }
  2590. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)m_pSubjectSource, strlen( m_pSubjectSource ) );
  2591. }
  2592. else
  2593. {
  2594. Iisfputs( "", fOut );
  2595. }
  2596. //
  2597. // Write default domain
  2598. //
  2599. if ( m_pDefaultDomain )
  2600. {
  2601. if( Iisfputs( m_pDefaultDomain, fOut ) == EOF )
  2602. {
  2603. fSt = FALSE;
  2604. goto cleanup;
  2605. }
  2606. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)m_pDefaultDomain, strlen( m_pDefaultDomain ) );
  2607. }
  2608. else
  2609. {
  2610. Iisfputs( "", fOut );
  2611. }
  2612. cleanup:
  2613. return fSt;
  2614. }
  2615. BOOL
  2616. CIisCert11Mapper::SetSubjectSource(
  2617. LPSTR psz
  2618. )
  2619. /*++
  2620. Routine Description:
  2621. Set the subject field to use as source for NT acct
  2622. Arguments:
  2623. psz - ASN.1 name of field to use
  2624. Returns:
  2625. TRUE if success, FALSE if error
  2626. --*/
  2627. {
  2628. if ( m_pSubjectSource != NULL )
  2629. {
  2630. LocalFree( m_pSubjectSource );
  2631. }
  2632. if ( m_pSubjectSource = (LPSTR)LocalAlloc( LMEM_FIXED, strlen(psz)+1) )
  2633. {
  2634. strcpy( m_pSubjectSource, psz );
  2635. return TRUE;
  2636. }
  2637. return FALSE;
  2638. }
  2639. BOOL
  2640. CIisCert11Mapper::SetDefaultDomain(
  2641. LPSTR psz
  2642. )
  2643. /*++
  2644. Routine Description:
  2645. Set the domain to use for NT acct
  2646. Arguments:
  2647. psz - domain name
  2648. Returns:
  2649. TRUE if success, FALSE if error
  2650. --*/
  2651. {
  2652. if ( m_pDefaultDomain != NULL )
  2653. {
  2654. LocalFree( m_pDefaultDomain );
  2655. }
  2656. if ( m_pDefaultDomain = (LPSTR)LocalAlloc( LMEM_FIXED, strlen(psz)+1) )
  2657. {
  2658. strcpy( m_pDefaultDomain, psz );
  2659. return TRUE;
  2660. }
  2661. return FALSE;
  2662. }
  2663. BOOL
  2664. CIisCert11Mapper::SetIssuerList(
  2665. IssuerAccepted*pI,
  2666. DWORD dwC
  2667. )
  2668. /*++
  2669. Routine Description:
  2670. Set the issuer list by copying supplied list
  2671. Arguments:
  2672. pI -- list of issuers
  2673. dwC -- count of issuers
  2674. Returns:
  2675. TRUE if success, FALSE if error
  2676. --*/
  2677. {
  2678. UINT x;
  2679. if ( (m_pIssuers = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, sizeof(IssuerAccepted)*dwC )) == NULL )
  2680. {
  2681. return FALSE;
  2682. }
  2683. for ( x = 0 ; x < dwC ; ++x )
  2684. {
  2685. m_pIssuers[x].cbIssuerLen = pI[x].cbIssuerLen;
  2686. if ( (m_pIssuers[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED, pI[x].cbIssuerLen )) == NULL )
  2687. {
  2688. m_cIssuers = x;
  2689. return FALSE;
  2690. }
  2691. memcpy( m_pIssuers[x].pbIssuer, pI[x].pbIssuer, pI[x].cbIssuerLen );
  2692. }
  2693. m_cIssuers = dwC;
  2694. return TRUE;
  2695. }
  2696. BOOL
  2697. CIisCert11Mapper::GetIssuerList(
  2698. IssuerAccepted**pIssuers,
  2699. DWORD*pdwI
  2700. )
  2701. /*++
  2702. Routine Description:
  2703. Retrieve the issuer list. Ownership of list transferred to caller
  2704. Arguments:
  2705. pI -- updated with ptr to array of issuers
  2706. pdwI -- updated with count of issuers
  2707. Returns:
  2708. TRUE if success, FALSE if error
  2709. --*/
  2710. {
  2711. IssuerAccepted *pI;
  2712. Lock();
  2713. pI = (IssuerAccepted*)LocalAlloc( LMEM_FIXED, m_cIssuers * sizeof(IssuerAccepted*) );
  2714. if ( pI == NULL )
  2715. {
  2716. Unlock();
  2717. return FALSE;
  2718. }
  2719. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  2720. {
  2721. if ( (pI[x].pbIssuer = (LPBYTE)LocalAlloc( LMEM_FIXED,
  2722. m_pIssuers[x].cbIssuerLen ))
  2723. == NULL )
  2724. {
  2725. Unlock();
  2726. DeleteIssuerList( pI, x );
  2727. return FALSE;
  2728. }
  2729. memcpy( pI[x].pbIssuer,
  2730. m_pIssuers[x].pbIssuer,
  2731. m_pIssuers[x].cbIssuerLen );
  2732. }
  2733. *pIssuers = pI;
  2734. *pdwI = m_cIssuers;
  2735. Unlock();
  2736. return TRUE;
  2737. }
  2738. BOOL
  2739. CIisCert11Mapper::DeleteIssuerList(
  2740. IssuerAccepted* pI,
  2741. DWORD dwI
  2742. )
  2743. /*++
  2744. Routine Description:
  2745. Delete an issuer list.
  2746. Arguments:
  2747. pI -- ptr to array of issuers
  2748. dwI -- count of issuers
  2749. Returns:
  2750. TRUE if success, FALSE if error
  2751. --*/
  2752. {
  2753. for ( DWORD x = 0 ; x < dwI ; ++x )
  2754. {
  2755. LocalFree( pI[x].pbIssuer );
  2756. }
  2757. LocalFree( pI );
  2758. return TRUE;
  2759. }
  2760. BOOL
  2761. CIisCert11Mapper::GetIssuerBuffer(
  2762. LPBYTE pB,
  2763. DWORD* pdwI
  2764. )
  2765. /*++
  2766. Routine Description:
  2767. Retrieve the issuer list. Ownership of list transferred to caller
  2768. Arguments:
  2769. pB -- updated with ptr to issuers buffer
  2770. pdwI -- updated with size of buffer of issuers
  2771. Returns:
  2772. TRUE if success, FALSE if error
  2773. --*/
  2774. {
  2775. LPBYTE pS;
  2776. DWORD dwC = 0;
  2777. Lock();
  2778. for ( UINT x = 0 ; x < m_cIssuers ; ++x )
  2779. {
  2780. dwC += m_pIssuers[x].cbIssuerLen + sizeof(USHORT);
  2781. }
  2782. *pdwI = dwC;
  2783. if ( pB != NULL )
  2784. {
  2785. for ( pS = pB, x = 0 ; x < m_cIssuers ; ++x )
  2786. {
  2787. pS[0] = (BYTE)(m_pIssuers[x].cbIssuerLen >> 8);
  2788. pS[1] = (BYTE)(m_pIssuers[x].cbIssuerLen);
  2789. memcpy( pS + sizeof(USHORT),
  2790. m_pIssuers[x].pbIssuer,
  2791. m_pIssuers[x].cbIssuerLen );
  2792. pS += m_pIssuers[x].cbIssuerLen + sizeof(USHORT);
  2793. }
  2794. }
  2795. Unlock();
  2796. return TRUE;
  2797. }
  2798. BOOL
  2799. CIisCert11Mapper::FreeIssuerBuffer(
  2800. LPBYTE pI
  2801. )
  2802. /*++
  2803. Routine Description:
  2804. Delete an issuer list.
  2805. Arguments:
  2806. pI -- ptr to issuers
  2807. Returns:
  2808. TRUE if success, FALSE if error
  2809. --*/
  2810. {
  2811. LocalFree( pI );
  2812. return TRUE;
  2813. }
  2814. // CCertMapping
  2815. CCertMapping::CCertMapping(
  2816. CIisAcctMapper* pMap
  2817. )
  2818. /*++
  2819. Routine Description:
  2820. Constructor for CCertMapping
  2821. Arguments:
  2822. pMap -- ptr to mapper object linked to this mapping
  2823. Returns:
  2824. Nothing
  2825. --*/
  2826. {
  2827. m_pMapper = (CIisAcctMapper*)pMap;
  2828. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  2829. {
  2830. m_pFields[x] = NULL;
  2831. }
  2832. }
  2833. CCertMapping::~CCertMapping(
  2834. )
  2835. /*++
  2836. Routine Description:
  2837. Destructor for CCertMapping
  2838. Arguments:
  2839. None
  2840. Returns:
  2841. Nothing
  2842. --*/
  2843. {
  2844. }
  2845. #if defined(DECODE_ASN1)
  2846. BOOL
  2847. DecodeNextField(
  2848. LPBYTE* ppAscii,
  2849. DWORD* pcAscii,
  2850. int* piF,
  2851. LPBYTE* ppN
  2852. )
  2853. /*++
  2854. Routine Description:
  2855. Decode next field certificate ASCII representation
  2856. field format as
  2857. name=content
  2858. where name is zero or more non comma chars
  2859. Arguments:
  2860. ppAscii - ptr to buffer where to scan for next field
  2861. updated with ptr to field content
  2862. pcAscii - ptr to count of char in ppAscii
  2863. updated with count of remaining char after ppAscii update
  2864. piF - updated with field type ( -1: unrecognized, 0:O, 1:OU, 2:C, 3:CN )
  2865. ppN - updated with ptr to field name
  2866. Returns:
  2867. TRUE if next field exists, otherwise FALSE
  2868. --*/
  2869. {
  2870. LPBYTE pAscii = *ppAscii;
  2871. LPBYTE pN;
  2872. int iF;
  2873. LPBYTE p = (LPBYTE)memchr( pAscii, '=', *pcAscii );
  2874. if ( p == NULL )
  2875. {
  2876. return FALSE;
  2877. }
  2878. for ( pN = p ; pN > pAscii && pN[-1] != ' ' ; --pN )
  2879. {
  2880. }
  2881. if ( pN[0] == 'O' && pN[1] == '=' )
  2882. {
  2883. iF = 0;
  2884. }
  2885. else if ( pN[0] == 'O' && pN[1] == 'U' && pN[2] == '=' )
  2886. {
  2887. iF = 1;
  2888. }
  2889. else if ( pN[0] == 'C' && pN[1] == '=' )
  2890. {
  2891. iF = 2;
  2892. }
  2893. else if ( pN[0] == 'C' && pN[1] == 'U' && pN[2] == '=' )
  2894. {
  2895. iF = 3;
  2896. }
  2897. else
  2898. {
  2899. iF = -1;
  2900. }
  2901. *piF = iF;
  2902. *pcAscii -= (p + 1 - pAscii);
  2903. *ppAscii = p + 1;
  2904. *ppN = pN;
  2905. return TRUE;
  2906. }
  2907. int
  2908. IisDecodeAsciiDN(
  2909. LPSTR *pF,
  2910. LPSTR pStore,
  2911. LPBYTE pAscii,
  2912. DWORD cAscii
  2913. )
  2914. /*++
  2915. Routine Description:
  2916. Decode certificate ASCII representation to an array of well-known fields
  2917. ( 0:O, 1:OU, 2:C, 3:CN )
  2918. Arguments:
  2919. pF - ptr to array of fields to be updated with ptr to field content
  2920. pStore - buffer to be used to store fields content, assumed to be big enough
  2921. pAscii - ptr to buffer where to scan for fields
  2922. cAscii - ptr to count of char in pAscii
  2923. Returns:
  2924. # of chars stored in pStore
  2925. --*/
  2926. {
  2927. int iF;
  2928. int iNF;
  2929. LPBYTE pN;
  2930. BOOL f;
  2931. int l = 0;
  2932. //O, OU, C, CN
  2933. f = DecodeNextField( &pAscii, &cAscii, &iF, &pN );
  2934. for ( ; f ; )
  2935. {
  2936. LPBYTE pC = pAscii;
  2937. if ( !(f=DecodeNextField( &pAscii, &cAscii, &iNF, &pN )) )
  2938. {
  2939. pN = pAscii + cAscii;
  2940. }
  2941. else
  2942. {
  2943. while ( pN > pC && *pN != ',' )
  2944. {
  2945. --pN;
  2946. }
  2947. }
  2948. // field content is from pC to pN-1 inclusive
  2949. if ( iF >= 0 )
  2950. {
  2951. pF[iF] = pStore;
  2952. int cL = pN - pC;
  2953. memcpy( pStore, pC, cL );
  2954. pStore[cL++] = '\0';
  2955. l += cL;
  2956. pStore += cL;
  2957. }
  2958. iF = iNF;
  2959. }
  2960. return l;
  2961. }
  2962. BOOL
  2963. CCertMapping::Init(
  2964. Cert_Map *pCert,
  2965. IISMDB_HEntry *pH,
  2966. DWORD dwH
  2967. )
  2968. /*++
  2969. Routine Description:
  2970. Constructor for CCertMapping
  2971. Arguments:
  2972. pCert -- ptr to certificate info to initialize from
  2973. pH -- ptr to hierarchy info
  2974. dwH -- number of hierarchy entries
  2975. Returns:
  2976. TRUE if success, otherwise FALSE
  2977. --*/
  2978. {
  2979. int l;
  2980. int l2;
  2981. if ( m_pBuff )
  2982. {
  2983. LocalFree( m_pBuff );
  2984. }
  2985. m_cUsedBuff = 0;
  2986. if ( !(m_pBuff = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cAllocBuff = 2048 )) )
  2987. {
  2988. return FALSE;
  2989. }
  2990. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  2991. {
  2992. m_pFields[x] = NULL;
  2993. }
  2994. //
  2995. // Check if content ASCII ( if so, 1st byte is a field name, so >= 'A' )
  2996. //
  2997. if ( pCert->cbIssuerLen && pCert->pIssuer[0] >= 'A' )
  2998. {
  2999. if ( (l = IisDecodeAsciiDN( m_pFields,
  3000. (LPSTR)m_pBuff,
  3001. pCert->pIssuer,
  3002. pCert->cbIssuerLen
  3003. )) == -1
  3004. || (l2 = IisDecodeAsciiDN(
  3005. m_pFields+3,
  3006. (LPSTR)m_pBuff+l,
  3007. pCert->pSubject,
  3008. pCert->cbSubjectLen
  3009. )) == -1
  3010. )
  3011. {
  3012. SetLastError( ERROR_INVALID_PARAMETER );
  3013. return FALSE;
  3014. }
  3015. }
  3016. //
  3017. // otherwise decode ASN.1 format
  3018. //
  3019. else if ( (l = IisDecodeDN( m_pFields,
  3020. (LPSTR)m_pBuff,
  3021. pCert->pIssuer,
  3022. pCert->cbIssuerLen
  3023. )) == -1
  3024. || (l2 = IisDecodeDN(
  3025. m_pFields+3,
  3026. (LPSTR)m_pBuff+l,
  3027. pCert->pSubject,
  3028. pCert->cbSubjectLen
  3029. )) == -1
  3030. )
  3031. {
  3032. SetLastError( ERROR_INVALID_PARAMETER );
  3033. return FALSE;
  3034. }
  3035. m_cUsedBuff = (UINT)(l + l2);
  3036. UpdateMask( pH, dwH );
  3037. return TRUE;
  3038. }
  3039. BOOL
  3040. CCertMapping::Init(
  3041. const LPBYTE pCert,
  3042. DWORD cCert,
  3043. IISMDB_HEntry *pH,
  3044. DWORD dwH
  3045. )
  3046. /*++
  3047. Routine Description:
  3048. Constructor for CCertMapping
  3049. Arguments:
  3050. pCert -- ptr to certificate info to initialize from
  3051. cCert -- size of buffer pointed to by pCert
  3052. pH -- ptr to hierarchy info
  3053. dwH -- number of hierarchy entries
  3054. Returns:
  3055. TRUE if success, otherwise FALSE
  3056. --*/
  3057. {
  3058. UINT l;
  3059. if ( m_pBuff )
  3060. {
  3061. LocalFree( m_pBuff );
  3062. }
  3063. m_cUsedBuff = 0;
  3064. if ( !(m_pBuff = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cAllocBuff = 2048 )) )
  3065. {
  3066. return FALSE;
  3067. }
  3068. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  3069. {
  3070. m_pFields[x] = NULL;
  3071. }
  3072. //
  3073. // decode ASN.1 format
  3074. //
  3075. // extract issuer, subject from pCert, cCert
  3076. // O, OU, C, CN ( issuer then subject )
  3077. //
  3078. if ( (l = DecodeCert(
  3079. pCert,
  3080. cCert,
  3081. m_pFields,
  3082. (LPSTR)m_pBuff
  3083. )) == 0
  3084. )
  3085. {
  3086. SetLastError( ERROR_INVALID_PARAMETER );
  3087. return FALSE;
  3088. }
  3089. m_cUsedBuff = l;
  3090. UpdateMask( pH, dwH );
  3091. return TRUE;
  3092. }
  3093. #endif
  3094. // CCert11Mapping
  3095. CCert11Mapping::CCert11Mapping(
  3096. CIisAcctMapper* pMap
  3097. )
  3098. /*++
  3099. Routine Description:
  3100. Constructor for CCert11Mapping
  3101. Arguments:
  3102. pMap -- ptr to mapper object linked to this mapping
  3103. Returns:
  3104. Nothing
  3105. --*/
  3106. {
  3107. m_pMapper = (CIisAcctMapper*)pMap;
  3108. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  3109. {
  3110. m_pFields[x] = NULL;
  3111. }
  3112. for ( x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  3113. {
  3114. m_cFields[x] = 0;
  3115. }
  3116. }
  3117. CCert11Mapping::~CCert11Mapping(
  3118. )
  3119. /*++
  3120. Routine Description:
  3121. Destructor for CCert11Mapping
  3122. Arguments:
  3123. None
  3124. Returns:
  3125. Nothing
  3126. --*/
  3127. {
  3128. }
  3129. #if defined(CERT11_FULL_CERT)
  3130. BOOL
  3131. CCert11Mapping::Init(
  3132. LPBYTE pC,
  3133. DWORD dwC,
  3134. IISMDB_HEntry *pH,
  3135. DWORD dwH
  3136. )
  3137. /*++
  3138. Routine Description:
  3139. Constructor for CCert11Mapping
  3140. Arguments:
  3141. pC -- cert ( ASN.1 format )
  3142. dwC -- length of cert
  3143. pH -- ptr to hierarchy info
  3144. dwH -- number of hierarchy entries
  3145. Returns:
  3146. TRUE if success, FALSE if error
  3147. --*/
  3148. {
  3149. StoreFieldRef( IISMDB_INDEX_CERT11_CERT, (LPSTR)pC, dwC );
  3150. UpdateMask( pH, dwH );
  3151. return TRUE;
  3152. }
  3153. #else
  3154. BOOL
  3155. CCert11Mapping::Init(
  3156. LPBYTE pI,
  3157. DWORD dwI,
  3158. LPBYTE pS,
  3159. DWORD dwS,
  3160. IISMDB_HEntry *pH,
  3161. DWORD dwH
  3162. )
  3163. /*++
  3164. Routine Description:
  3165. Constructor for CCert11Mapping
  3166. Arguments:
  3167. pI -- cert issuer ( ASN.1 format )
  3168. dwI -- length of issuer
  3169. pS -- cert subject ( ASN.1 format )
  3170. dwS -- length of subject
  3171. pH -- ptr to hierarchy info
  3172. dwH -- number of hierarchy entries
  3173. Returns:
  3174. TRUE if success, FALSE if error
  3175. --*/
  3176. {
  3177. StoreFieldRef( IISMDB_INDEX_CERT11_SUBJECT, (LPSTR)pS, dwS );
  3178. StoreFieldRef( IISMDB_INDEX_CERT11_ISSUER, (LPSTR)pI, dwI);
  3179. UpdateMask( pH, dwH );
  3180. return TRUE;
  3181. }
  3182. #endif
  3183. // CIisMapping
  3184. CIisMapping::CIisMapping(
  3185. )
  3186. /*++
  3187. Routine Description:
  3188. Constructor for CIisMapping
  3189. Arguments:
  3190. None
  3191. Returns:
  3192. Nothing
  3193. --*/
  3194. {
  3195. m_pBuff = NULL;
  3196. m_cUsedBuff = m_cAllocBuff = 0;
  3197. m_dwMask = 0;
  3198. }
  3199. BOOL
  3200. CIisMapping::CloneEx(
  3201. CIisMapping** ppM,
  3202. LPSTR* ppTargetS,
  3203. LPSTR* ppS,
  3204. LPDWORD pTargetC,
  3205. LPDWORD pC,
  3206. UINT cF
  3207. )
  3208. /*++
  3209. Routine Description:
  3210. Clone a mapping entry
  3211. Arguments:
  3212. Returns:
  3213. TRUE if success, otherwise FALSE
  3214. --*/
  3215. {
  3216. CIisMapping* pM = *ppM;
  3217. UINT i;
  3218. if ( ppTargetS && ppS )
  3219. {
  3220. memcpy( ppTargetS, ppS, sizeof(LPSTR*) * cF );
  3221. }
  3222. if ( pTargetC && pC )
  3223. {
  3224. memcpy( pTargetC, pC, sizeof(DWORD) * cF );
  3225. }
  3226. if ( !(pM->m_pBuff = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cAllocBuff )) )
  3227. {
  3228. delete pM;
  3229. *ppM = NULL;
  3230. return FALSE;
  3231. }
  3232. memcpy( pM->m_pBuff, m_pBuff, m_cUsedBuff );
  3233. pM->m_cUsedBuff = m_cUsedBuff;
  3234. pM->m_cAllocBuff = m_cAllocBuff;
  3235. pM->m_pMapper = m_pMapper;
  3236. pM->m_dwMask = m_dwMask;
  3237. //
  3238. // Adjust ptr to point to new buffer
  3239. //
  3240. for ( i = 0 ; i < cF ; ++i )
  3241. {
  3242. if ( ppTargetS[i] )
  3243. {
  3244. ppTargetS[i] += pM->m_pBuff - m_pBuff;
  3245. }
  3246. }
  3247. return TRUE;
  3248. }
  3249. BOOL
  3250. CIisMapping::UpdateMask(
  3251. IISMDB_HEntry* pH,
  3252. DWORD dwI
  3253. )
  3254. /*++
  3255. Routine Description:
  3256. Update mask of significant fields for a mapping object
  3257. Field is significant if not containing "*"
  3258. mask if bitmask of n bits where n is # of hierarchy entries
  3259. bit of rank m == 0 means field pointed by hierarchy entry n - 1 - m
  3260. is significant. ( i.e. MSB is hierarchy entry 0, the most significant )
  3261. Arguments:
  3262. pH -- ptr to hierarchy info
  3263. dwI -- number of hierarchy entries
  3264. Returns:
  3265. TRUE if success, FALSE if error
  3266. --*/
  3267. {
  3268. LPSTR *pFields;
  3269. LPDWORD pcFields;
  3270. LPSTR pF;
  3271. DWORD dwC;
  3272. int iMax;
  3273. m_dwMask = (1u << dwI)-1;
  3274. iMax = GetNbField( &pFields, &pcFields );
  3275. if ( pcFields )
  3276. {
  3277. for ( UINT x = 0 ; x < dwI ; ++x )
  3278. {
  3279. MappingGetField( pH[x].m_dwIndex, &pF, &dwC, FALSE );
  3280. if ( !pF || dwC != 1 || *pF != '*' )
  3281. {
  3282. m_dwMask &= ~(1u << (dwI - 1 - x) );
  3283. }
  3284. }
  3285. }
  3286. else
  3287. {
  3288. for ( UINT x = 0 ; x < dwI ; ++x )
  3289. {
  3290. MappingGetField( pH[x].m_dwIndex, &pF );
  3291. if ( !pF || strcmp( pF, "*" ) )
  3292. {
  3293. m_dwMask &= ~(1u << (dwI - 1 - x) );
  3294. }
  3295. }
  3296. }
  3297. return TRUE;
  3298. }
  3299. BOOL
  3300. CIisMapping::Copy(
  3301. CIisMapping* pM
  3302. )
  3303. /*++
  3304. Routine Description:
  3305. Copy the specified mapping in this
  3306. Arguments:
  3307. pM - ptr to mapping to duplicate
  3308. Returns:
  3309. TRUE if success, FALSE if error
  3310. --*/
  3311. {
  3312. LPSTR *pFields;
  3313. LPSTR pF;
  3314. UINT iMax = GetNbField( &pFields );
  3315. for ( UINT x = 0 ; x < iMax ; ++x )
  3316. {
  3317. if ( pM->MappingGetField( x, &pF ) && *pF )
  3318. {
  3319. if ( !MappingSetField( x, pF ) )
  3320. {
  3321. return FALSE;
  3322. }
  3323. }
  3324. }
  3325. return TRUE;
  3326. }
  3327. int
  3328. CIisMapping::Cmp(
  3329. CIisMapping* pM,
  3330. BOOL fCmpForMatch
  3331. )
  3332. /*++
  3333. Routine Description:
  3334. Compare 2 mappings, return -1, 0 or 1 as suitable for qsort or bsearch
  3335. Can compare either for full sort order ( using mask & significant fields )
  3336. or for a match ( not using mask )
  3337. Arguments:
  3338. pM -- ptr to mapping to compare to. This is to be used as the 2nd
  3339. entry for purpose of lexicographical order.
  3340. fCmpForMatch -- TRUE if comparing for a match inside a given mask class
  3341. Returns:
  3342. -1 if *this < *pM, 0 if *this == *pM, 1 if *this > *pM
  3343. --*/
  3344. {
  3345. DWORD dwCmpMask = 0xffffffff;
  3346. // if not compare for match, consider mask
  3347. if ( !fCmpForMatch )
  3348. {
  3349. if ( m_dwMask < pM->GetMask() )
  3350. {
  3351. return -1;
  3352. }
  3353. else if ( m_dwMask > pM->GetMask() )
  3354. {
  3355. return 1;
  3356. }
  3357. // mask are identical, have to consider fields
  3358. }
  3359. // compute common significant fields : bit is 1 if significant
  3360. dwCmpMask = (~m_dwMask) & (~pM->GetMask());
  3361. DWORD dwH;
  3362. IISMDB_HEntry* pH = m_pMapper->GetHierarchy( &dwH );
  3363. UINT x;
  3364. LPSTR *pFL;
  3365. LPDWORD pcFL;
  3366. GetNbField( &pFL, &pcFL );
  3367. for ( x = 0 ; x < dwH ; ++x )
  3368. {
  3369. if( ! (dwCmpMask & (1u << (dwH - 1 - x) )) )
  3370. {
  3371. continue;
  3372. }
  3373. LPSTR pA;
  3374. LPSTR pB;
  3375. DWORD dwA;
  3376. DWORD dwB;
  3377. int fC;
  3378. if ( pcFL ) // check if length available
  3379. {
  3380. MappingGetField( pH[x].m_dwIndex, &pA, &dwA, FALSE );
  3381. pM->MappingGetField( pH[x].m_dwIndex, &pB, &dwB, FALSE );
  3382. if ( pA == NULL )
  3383. {
  3384. dwA = 0;
  3385. }
  3386. if ( pB == NULL )
  3387. {
  3388. dwB = 0;
  3389. }
  3390. if ( dwA != dwB )
  3391. {
  3392. return dwA < dwB ? -1 : 1;
  3393. }
  3394. fC = memcmp( pA, pB, dwA );
  3395. }
  3396. else
  3397. {
  3398. MappingGetField( pH[x].m_dwIndex, &pA );
  3399. pM->MappingGetField( pH[x].m_dwIndex, &pB );
  3400. if ( pA == NULL )
  3401. {
  3402. pA = "";
  3403. }
  3404. if ( pB == NULL )
  3405. {
  3406. pB = "";
  3407. }
  3408. fC = strcmp( pA, pB );
  3409. }
  3410. if ( fC )
  3411. {
  3412. return fC;
  3413. }
  3414. }
  3415. return 0;
  3416. }
  3417. BOOL
  3418. CIisMapping::MappingGetField(
  3419. DWORD dwIndex,
  3420. LPSTR *pF
  3421. )
  3422. /*++
  3423. Routine Description:
  3424. Get ptr to field in mapping entry
  3425. ownership of field remains with mapping entry
  3426. Arguments:
  3427. dwIndex -- index of field
  3428. pF -- updated with ptr to field entry. can be NULL if
  3429. field empty.
  3430. Returns:
  3431. TRUE if success, FALSE if error
  3432. Lock:
  3433. mapper must be locked for ptr to remain valid
  3434. --*/
  3435. {
  3436. LPSTR *pFields;
  3437. DWORD iMax = GetNbField( &pFields );
  3438. if ( dwIndex >= iMax )
  3439. {
  3440. return FALSE;
  3441. }
  3442. *pF = pFields[dwIndex];
  3443. return TRUE;
  3444. }
  3445. BOOL
  3446. CIisMapping::MappingGetField(
  3447. DWORD dwIndex,
  3448. LPSTR *pF,
  3449. LPDWORD pcF,
  3450. BOOL fUuEncode
  3451. )
  3452. /*++
  3453. Routine Description:
  3454. Get ptr to field in mapping entry
  3455. ownership of field remains with mapping entry
  3456. Arguments:
  3457. dwIndex -- index of field
  3458. pF -- updated with ptr to field entry. can be NULL if
  3459. field empty.
  3460. pcF -- updated with length of fields, 0 if empty
  3461. fUuEncode -- TRUE if result is to be uuencoded.
  3462. if TRUE, caller must LocalFree( *pF )
  3463. Returns:
  3464. TRUE if success, FALSE if error
  3465. Lock:
  3466. mapper must be locked for ptr to remain valid
  3467. --*/
  3468. {
  3469. LPSTR *pFields;
  3470. LPDWORD pcFields;
  3471. DWORD iMax = GetNbField( &pFields, &pcFields );
  3472. if ( dwIndex >= iMax )
  3473. {
  3474. return FALSE;
  3475. }
  3476. if ( fUuEncode )
  3477. {
  3478. LPSTR pU = (LPSTR)LocalAlloc( LMEM_FIXED, ((pcFields[dwIndex]+3)*4)/3+1 );
  3479. if ( pU == NULL )
  3480. {
  3481. return FALSE;
  3482. }
  3483. DWORD cO;
  3484. IISuuencode( (LPBYTE)pFields[dwIndex], pcFields[dwIndex], (LPBYTE)pU, FALSE );
  3485. *pF = pU;
  3486. *pcF = strlen(pU);
  3487. }
  3488. else
  3489. {
  3490. *pF = pFields[dwIndex];
  3491. *pcF = pcFields[dwIndex];
  3492. }
  3493. return TRUE;
  3494. }
  3495. BOOL
  3496. CIisMapping::MappingSetField(
  3497. DWORD dwIndex,
  3498. LPSTR pszNew
  3499. )
  3500. /*++
  3501. Routine Description:
  3502. Set field in mapping entry to specified content
  3503. data pointed by pszNew is copied inside mapping entry
  3504. Arguments:
  3505. dwIndex -- index of field
  3506. pszNew -- data to copy inside field
  3507. Returns:
  3508. TRUE if success, FALSE if error
  3509. Lock:
  3510. mapper must be locked for ptr to remain valid
  3511. --*/
  3512. {
  3513. LPSTR *pFields;
  3514. DWORD iMax = GetNbField( &pFields );
  3515. if ( dwIndex >= iMax )
  3516. {
  3517. return FALSE;
  3518. }
  3519. return StoreField( pFields, dwIndex, iMax, pszNew );
  3520. }
  3521. BOOL
  3522. CIisMapping::MappingSetField(
  3523. DWORD dwIndex,
  3524. LPSTR pszNew,
  3525. DWORD cNew,
  3526. BOOL fIsUuEncoded
  3527. )
  3528. /*++
  3529. Routine Description:
  3530. Set field in mapping entry to specified content
  3531. data pointed by pszNew is copied inside mapping entry
  3532. Arguments:
  3533. dwIndex -- index of field
  3534. pszNew -- data to copy inside field
  3535. cNew -- length of data
  3536. fIsUuEncoded -- TRUE if pszNew is UUEncoded
  3537. Returns:
  3538. TRUE if success, FALSE if error
  3539. Lock:
  3540. mapper must be locked for ptr to remain valid
  3541. --*/
  3542. {
  3543. LPSTR *pFields;
  3544. LPDWORD pcFields;
  3545. DWORD iMax = GetNbField( &pFields, &pcFields );
  3546. if ( dwIndex >= iMax )
  3547. {
  3548. return FALSE;
  3549. }
  3550. return StoreField( pFields, pcFields, dwIndex, iMax, pszNew, cNew, fIsUuEncoded );
  3551. }
  3552. BOOL
  3553. CIisMapping::StoreField(
  3554. LPSTR* ppszFields,
  3555. DWORD dwIndex,
  3556. DWORD dwNbIndex,
  3557. LPSTR pszNew
  3558. )
  3559. /*++
  3560. Routine Description:
  3561. Update field array in mapping entry with new field
  3562. data pointed by pszNew is copied inside mapping entry
  3563. Arguments:
  3564. ppszFields -- array of field pointers to be updated
  3565. dwIndex -- index of field
  3566. dwNbIndex -- number of fields in array
  3567. pszNew -- data to copy inside field
  3568. Returns:
  3569. TRUE if success, FALSE if error
  3570. --*/
  3571. {
  3572. UINT x;
  3573. // pszOld is assumed to point inside m_pBuff if non NULL
  3574. // is has to be removed
  3575. LPSTR pszOld = ppszFields[dwIndex];
  3576. if ( pszOld && m_pBuff && (LPBYTE)pszOld > m_pBuff && (LPBYTE)pszOld < m_pBuff+m_cUsedBuff )
  3577. {
  3578. int lO = strlen( pszOld ) + 1;
  3579. int lM = DIFF((m_pBuff + m_cUsedBuff) - (LPBYTE)pszOld) - lO;
  3580. if ( lM )
  3581. {
  3582. memmove( pszOld, pszOld + lO, lM );
  3583. for ( x = 0 ; x < dwNbIndex ; ++x )
  3584. {
  3585. if ( x != dwIndex && ppszFields[x] > pszOld )
  3586. {
  3587. ppszFields[x] -= lO;
  3588. }
  3589. }
  3590. }
  3591. ppszFields[ dwIndex ] = NULL;
  3592. m_cUsedBuff -= lO;
  3593. }
  3594. // pszNew is to appended to m_pBuff
  3595. int lN = strlen( pszNew ) + 1;
  3596. if ( m_cUsedBuff + lN > m_cAllocBuff )
  3597. {
  3598. UINT cNewBuff = (( m_cUsedBuff + lN + IIS_MAP_BUFF_GRAN ) / IIS_MAP_BUFF_GRAN) * IIS_MAP_BUFF_GRAN;
  3599. LPSTR pNewBuff = (LPSTR)LocalAlloc( LMEM_FIXED, cNewBuff );
  3600. if ( pNewBuff == NULL )
  3601. {
  3602. return FALSE;
  3603. }
  3604. if ( m_pBuff )
  3605. {
  3606. memcpy( pNewBuff, m_pBuff, m_cUsedBuff );
  3607. LocalFree( m_pBuff );
  3608. }
  3609. m_cAllocBuff = cNewBuff;
  3610. // adjust pointers
  3611. for ( UINT x = 0 ; x < dwNbIndex ; ++x )
  3612. {
  3613. if ( x != dwIndex )
  3614. {
  3615. if ( ppszFields[x] != NULL )
  3616. {
  3617. ppszFields[x] += ((LPBYTE)pNewBuff - m_pBuff);
  3618. }
  3619. }
  3620. }
  3621. m_pBuff = (LPBYTE)pNewBuff;
  3622. }
  3623. memcpy( m_pBuff + m_cUsedBuff, pszNew, lN );
  3624. ppszFields[dwIndex] = (LPSTR)(m_pBuff + m_cUsedBuff);
  3625. m_cUsedBuff += lN;
  3626. return TRUE;
  3627. }
  3628. BOOL
  3629. CIisMapping::StoreField(
  3630. LPSTR* ppszFields,
  3631. LPDWORD ppdwFields,
  3632. DWORD dwIndex,
  3633. DWORD dwNbIndex,
  3634. LPSTR pbNew,
  3635. DWORD cNew,
  3636. BOOL fIsUuEncoded
  3637. )
  3638. /*++
  3639. Routine Description:
  3640. Update field array in mapping entry with new field
  3641. data pointed by pszNew is copied inside mapping entry
  3642. Arguments:
  3643. ppszFields -- array of field pointers to be updated
  3644. ppdwFields -- array of field length to be updated
  3645. dwIndex -- index of field
  3646. dwNbIndex -- number of fields in array
  3647. pbNew -- data to copy inside field
  3648. cNew -- length of data
  3649. fIsUuEncoded -- TRUE if pbNew is UUEncoded
  3650. Returns:
  3651. TRUE if success, FALSE if error
  3652. --*/
  3653. {
  3654. UINT x;
  3655. // pszOld is assumed to point inside m_pBuff if non NULL
  3656. // it has to be removed
  3657. LPSTR pszOld = ppszFields[dwIndex];
  3658. if ( pszOld && m_pBuff && (LPBYTE)pszOld > m_pBuff && (LPBYTE)pszOld < m_pBuff+m_cUsedBuff )
  3659. {
  3660. int lO = ppdwFields[dwIndex];
  3661. int lM = DIFF((m_pBuff + m_cUsedBuff) - (LPBYTE)pszOld) - lO;
  3662. if ( lM )
  3663. {
  3664. memmove( pszOld, pszOld + lO, lM );
  3665. for ( x = 0 ; x < dwNbIndex ; ++x )
  3666. {
  3667. if ( x != dwIndex && ppszFields[x] > pszOld )
  3668. {
  3669. ppszFields[x] -= lO;
  3670. }
  3671. }
  3672. }
  3673. ppszFields[ dwIndex ] = NULL;
  3674. m_cUsedBuff -= lO;
  3675. }
  3676. // pszNew is to appended to m_pBuff
  3677. int lN = cNew;
  3678. if ( fIsUuEncoded )
  3679. {
  3680. LPSTR pU = (LPSTR)LocalAlloc( LMEM_FIXED, lN + 3);
  3681. if ( pU == NULL )
  3682. {
  3683. return FALSE;
  3684. }
  3685. DWORD cO;
  3686. IISuudecode( pbNew, (LPBYTE)pU, &cO, FALSE );
  3687. pbNew = pU;
  3688. cNew = lN = cO;
  3689. }
  3690. if ( m_cUsedBuff + lN > m_cAllocBuff )
  3691. {
  3692. UINT cNewBuff = (( m_cUsedBuff + lN + IIS_MAP_BUFF_GRAN ) / IIS_MAP_BUFF_GRAN) * IIS_MAP_BUFF_GRAN;
  3693. LPSTR pNewBuff = (LPSTR)LocalAlloc( LMEM_FIXED, cNewBuff );
  3694. if ( pNewBuff == NULL )
  3695. {
  3696. if ( fIsUuEncoded )
  3697. {
  3698. LocalFree( pbNew );
  3699. }
  3700. return FALSE;
  3701. }
  3702. if ( m_pBuff )
  3703. {
  3704. memcpy( pNewBuff, m_pBuff, m_cUsedBuff );
  3705. LocalFree( m_pBuff );
  3706. }
  3707. m_cAllocBuff = cNewBuff;
  3708. // adjust pointers
  3709. for ( UINT x = 0 ; x < dwNbIndex ; ++x )
  3710. {
  3711. if ( x != dwIndex )
  3712. {
  3713. if ( ppszFields[x] != NULL )
  3714. {
  3715. ppszFields[x] += ((LPBYTE)pNewBuff - m_pBuff);
  3716. }
  3717. }
  3718. }
  3719. m_pBuff = (LPBYTE)pNewBuff;
  3720. }
  3721. memcpy( m_pBuff + m_cUsedBuff, pbNew, lN );
  3722. ppszFields[dwIndex] = (LPSTR)(m_pBuff + m_cUsedBuff);
  3723. if ( ppdwFields )
  3724. {
  3725. ppdwFields[dwIndex] = cNew;
  3726. }
  3727. m_cUsedBuff += lN;
  3728. if ( fIsUuEncoded )
  3729. {
  3730. LocalFree( pbNew );
  3731. }
  3732. return TRUE;
  3733. }
  3734. BOOL
  3735. CIisMapping::Serialize(
  3736. FILE* pFile,
  3737. VALID_CTX pMD5,
  3738. LPVOID pStorage
  3739. )
  3740. /*++
  3741. Routine Description:
  3742. Serialize a mapping entry
  3743. Arguments:
  3744. pFile -- file to write to
  3745. pMD5 -- MD5 to update with signature of written bytes
  3746. Returns:
  3747. TRUE if success, FALSE if error
  3748. Lock:
  3749. mapper must be locked while serializing
  3750. --*/
  3751. {
  3752. LPSTR *pFields;
  3753. LPDWORD pcFields;
  3754. LPSTR pO = NULL;
  3755. DWORD dwO = 0;
  3756. UINT iMax = GetNbField( &pFields, &pcFields );
  3757. UINT x;
  3758. LPBYTE pB;
  3759. BOOL fMustFree;
  3760. for ( x = 0 ; x < iMax ; ++x )
  3761. {
  3762. LPSTR pF;
  3763. DWORD dwF;
  3764. fMustFree = FALSE;
  3765. if ( pcFields )
  3766. {
  3767. MappingGetField( x, &pF, &dwF, FALSE );
  3768. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)pF, dwF );
  3769. store_as_binary:
  3770. if ( IsCrypt( x ) && dwF )
  3771. {
  3772. if ( FAILED(((IIS_CRYPTO_STORAGE*)pStorage)->EncryptData(
  3773. (PIIS_CRYPTO_BLOB*)&pB,
  3774. pF,
  3775. dwF,
  3776. REG_BINARY )) )
  3777. {
  3778. return FALSE;
  3779. }
  3780. pF = (LPSTR)pB;
  3781. dwF = IISCryptoGetBlobLength( (PIIS_CRYPTO_BLOB)pB );
  3782. fMustFree = TRUE;
  3783. }
  3784. if ( dwF )
  3785. {
  3786. DWORD dwNeed = ((dwF+2)*4)/3 + 1;
  3787. if ( dwNeed > dwO )
  3788. {
  3789. if ( pO != NULL )
  3790. {
  3791. LocalFree( pO );
  3792. }
  3793. dwNeed += 100; // alloc more than needed
  3794. // to minimize # of allocation
  3795. if ( !(pO = (LPSTR)LocalAlloc( LMEM_FIXED, dwNeed )) )
  3796. {
  3797. return FALSE;
  3798. }
  3799. dwO = dwNeed;
  3800. }
  3801. /* INTRINSA suppress = null */
  3802. IISuuencode( (LPBYTE)pF, dwF, (LPBYTE)pO, FALSE );
  3803. fputs( pO, pFile );
  3804. }
  3805. if ( fMustFree )
  3806. {
  3807. IISCryptoFreeBlob( (PIIS_CRYPTO_BLOB)pB );
  3808. }
  3809. }
  3810. else
  3811. {
  3812. MappingGetField( x, &pF );
  3813. if ( pF != NULL )
  3814. {
  3815. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)pF, strlen(pF) );
  3816. if ( IsCrypt( x ) )
  3817. {
  3818. dwF = strlen( pF ) + 1;
  3819. goto store_as_binary;
  3820. }
  3821. fputs( pF, pFile );
  3822. }
  3823. }
  3824. fputs( "|", pFile );
  3825. }
  3826. fputs( "\r\n", pFile );
  3827. if ( pO != NULL )
  3828. {
  3829. LocalFree( pO );
  3830. }
  3831. return TRUE;
  3832. }
  3833. BOOL
  3834. CIisMapping::Deserialize(
  3835. FILE* pFile,
  3836. VALID_CTX pMD5,
  3837. LPVOID pStorage
  3838. )
  3839. /*++
  3840. Routine Description:
  3841. Deserialize a mapping entry
  3842. Arguments:
  3843. pFile -- file to read from
  3844. pMD5 -- MD5 to update with signature of read bytes
  3845. Returns:
  3846. TRUE if success, FALSE if error
  3847. Lock:
  3848. mapper must be locked while serializing
  3849. --*/
  3850. {
  3851. LPSTR *pFields;
  3852. LPDWORD pcFields;
  3853. UINT iMax;
  3854. UINT x;
  3855. int c;
  3856. CHAR achBuf[4096];
  3857. DWORD dwType;
  3858. LPBYTE pB;
  3859. iMax = GetNbField( &pFields, &pcFields );
  3860. for ( x = 0 ; x < iMax ; ++x )
  3861. {
  3862. StoreFieldRef( x, NULL );
  3863. }
  3864. for ( x = 0 ; x < sizeof(achBuf) && (c=fgetc(pFile))!= EOF ; )
  3865. {
  3866. achBuf[x++] = (CHAR)c;
  3867. if ( c == '\n' )
  3868. {
  3869. break;
  3870. }
  3871. }
  3872. if ( x == sizeof(achBuf ) )
  3873. {
  3874. return FALSE;
  3875. }
  3876. if ( x > 1 )
  3877. {
  3878. achBuf[x-2] = '\0';
  3879. m_cUsedBuff = m_cAllocBuff = x - 1;
  3880. if ( (m_pBuff = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cAllocBuff )) == NULL )
  3881. {
  3882. m_cAllocBuff = m_cUsedBuff = 0;
  3883. return FALSE;
  3884. }
  3885. memcpy( m_pBuff, achBuf, m_cUsedBuff );
  3886. LPSTR pCur = (LPSTR)m_pBuff;
  3887. LPSTR pNext;
  3888. LPSTR pStore = (LPSTR)m_pBuff;
  3889. DWORD dwDec;
  3890. if ( pcFields )
  3891. {
  3892. for ( x = 0 ; x < iMax ; ++x )
  3893. {
  3894. pNext = strchr( pCur, '|' );
  3895. if ( pNext != NULL )
  3896. {
  3897. *pNext = '\0';
  3898. ++pNext;
  3899. }
  3900. else
  3901. {
  3902. pNext = NULL;
  3903. }
  3904. IISuudecode( pCur, (PBYTE)pStore, &dwDec, FALSE );
  3905. if ( IsCrypt( x ) && dwDec )
  3906. {
  3907. if ( FAILED(((IIS_CRYPTO_STORAGE*)pStorage)->DecryptData(
  3908. (PVOID*)&pB,
  3909. &dwDec,
  3910. &dwType,
  3911. (PIIS_CRYPTO_BLOB)pStore )) )
  3912. {
  3913. return FALSE;
  3914. }
  3915. memmove( pStore, pB, dwDec );
  3916. }
  3917. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)pStore, dwDec );
  3918. StoreFieldRef( x, pStore, dwDec );
  3919. pCur = pNext;
  3920. pStore += dwDec;
  3921. }
  3922. }
  3923. else
  3924. {
  3925. for ( x = 0 ; x < iMax ; ++x )
  3926. {
  3927. pNext = strchr( pCur, '|' );
  3928. if ( pNext != NULL )
  3929. {
  3930. *pNext = '\0';
  3931. ++pNext;
  3932. }
  3933. if ( *pCur && IsCrypt( x ) )
  3934. {
  3935. IISuudecode( pCur, (PBYTE)pCur, &dwDec, FALSE );
  3936. if ( FAILED(((IIS_CRYPTO_STORAGE*)pStorage)->DecryptData(
  3937. (PVOID*)&pB,
  3938. &dwDec,
  3939. &dwType,
  3940. (PIIS_CRYPTO_BLOB)pCur )) )
  3941. {
  3942. return FALSE;
  3943. }
  3944. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)pB, dwDec );
  3945. StoreFieldRef( x, (LPSTR)pB );
  3946. pCur = pNext;
  3947. }
  3948. else
  3949. {
  3950. MD5Update( (MD5_CTX*)pMD5, (LPBYTE)pCur, strlen(pCur) );
  3951. StoreFieldRef( x, pCur );
  3952. pCur = pNext;
  3953. }
  3954. }
  3955. }
  3956. return TRUE;
  3957. }
  3958. return FALSE;
  3959. }
  3960. //
  3961. extern "C" BOOL WINAPI
  3962. DllMain(
  3963. HANDLE hModule,
  3964. DWORD dwReason,
  3965. LPVOID pV
  3966. )
  3967. /*++
  3968. Routine Description:
  3969. DLL init/terminate notification function
  3970. Arguments:
  3971. hModule - DLL handle
  3972. dwReason - notification type
  3973. LPVOID - not used
  3974. Returns:
  3975. TRUE if success, FALSE if failure
  3976. --*/
  3977. {
  3978. //BOOL f = Crypt32DllMain( (HINSTANCE)hModule, dwReason, pV );
  3979. switch ( dwReason )
  3980. {
  3981. case DLL_PROCESS_ATTACH:
  3982. #ifdef _NO_TRACING_
  3983. CREATE_DEBUG_PRINT_OBJECT( "IISMAP" );
  3984. #endif
  3985. // record the module handle to access module info later
  3986. g_hModule = (HINSTANCE)hModule;
  3987. INITIALIZE_CRITICAL_SECTION( &g_csIisMap );
  3988. InitializeWildcardMapping( hModule );
  3989. InitializeMapping( hModule );
  3990. if ( IISCryptoInitialize() != NO_ERROR )
  3991. {
  3992. return FALSE;
  3993. }
  3994. return TRUE;
  3995. case DLL_PROCESS_DETACH:
  3996. IISCryptoTerminate();
  3997. TerminateWildcardMapping();
  3998. TerminateMapping();
  3999. DeleteCriticalSection( &g_csIisMap );
  4000. #ifdef _NO_TRACING_
  4001. DELETE_DEBUG_PRINT_OBJECT( );
  4002. #endif
  4003. break;
  4004. }
  4005. return TRUE;
  4006. }
  4007. BOOL
  4008. InitializeMapping(
  4009. HANDLE hModule
  4010. )
  4011. /*++
  4012. Routine Description:
  4013. Initialize mapping
  4014. Arguments:
  4015. hModule - module handle of this DLL
  4016. Return Value:
  4017. Nothing
  4018. --*/
  4019. {
  4020. // get install path
  4021. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  4022. W3_PARAMS,
  4023. 0,
  4024. KEY_READ|KEY_SET_VALUE,
  4025. &g_hKey ) == ERROR_SUCCESS )
  4026. {
  4027. DWORD dwLen = 0;
  4028. DWORD dwType;
  4029. if ( RegQueryValueEx( g_hKey,
  4030. INSTALL_PATH,
  4031. NULL,
  4032. &dwType,
  4033. NULL,
  4034. &dwLen ) != ERROR_SUCCESS ||
  4035. dwType != REG_SZ ||
  4036. !( g_pszInstallPath = (LPSTR)LocalAlloc( LMEM_FIXED, dwLen ) ) ||
  4037. RegQueryValueEx( g_hKey,
  4038. INSTALL_PATH,
  4039. NULL,
  4040. &dwType,
  4041. (LPBYTE)g_pszInstallPath,
  4042. &dwLen ) != ERROR_SUCCESS )
  4043. {
  4044. if ( g_pszInstallPath )
  4045. {
  4046. LocalFree( g_pszInstallPath );
  4047. g_pszInstallPath = NULL;
  4048. }
  4049. }
  4050. dwLen = sizeof( g_dwGuid );
  4051. if ( RegQueryValueEx( g_hKey,
  4052. MAPPER_GUID,
  4053. NULL,
  4054. &dwType,
  4055. (LPBYTE)&g_dwGuid,
  4056. &dwLen ) != ERROR_SUCCESS ||
  4057. dwType != REG_DWORD )
  4058. {
  4059. g_dwGuid = 0;
  4060. }
  4061. return LoadFieldNames( IisItaMappingFields,
  4062. sizeof(IisItaMappingFields)/sizeof(IISMDB_Fields) ) &&
  4063. LoadFieldNames( IisCert11MappingFields,
  4064. sizeof(IisCert11MappingFields)/sizeof(IISMDB_Fields) ) &&
  4065. LoadFieldNames( IisMd5MappingFields,
  4066. sizeof(IisMd5MappingFields)/sizeof(IISMDB_Fields) );
  4067. }
  4068. else
  4069. {
  4070. g_hKey = NULL;
  4071. }
  4072. return FALSE;
  4073. }
  4074. BOOL
  4075. LoadFieldNames(
  4076. IISMDB_Fields* pFields,
  4077. UINT cFields
  4078. )
  4079. /*++
  4080. Routine Description:
  4081. Load fields names from resource
  4082. Arguments:
  4083. pFields - ptr to array where to store reference to names
  4084. cFields - count of element in array
  4085. Return Value:
  4086. TRUE if success, otherwise FALSE
  4087. --*/
  4088. {
  4089. UINT x;
  4090. BOOL fSt = TRUE;
  4091. for ( x = 0 ;
  4092. x < cFields ;
  4093. ++x )
  4094. {
  4095. char achTmp[128];
  4096. if ( LoadString( g_hModule,
  4097. pFields[x].m_dwResID,
  4098. achTmp,
  4099. sizeof( achTmp ) ) != 0 )
  4100. {
  4101. int lN = strlen( achTmp ) + sizeof(CHAR);
  4102. if ( (pFields[x].m_pszDisplayName = (LPSTR)LocalAlloc( LMEM_FIXED, lN )) == NULL )
  4103. {
  4104. fSt = FALSE;
  4105. break;
  4106. }
  4107. memcpy( pFields[x].m_pszDisplayName, achTmp, lN );
  4108. }
  4109. else
  4110. {
  4111. fSt = FALSE;
  4112. break;
  4113. }
  4114. }
  4115. return fSt;
  4116. }
  4117. VOID
  4118. FreeFieldNames(
  4119. IISMDB_Fields* pFields,
  4120. UINT cFields
  4121. )
  4122. /*++
  4123. Routine Description:
  4124. Free fields names loaded from resource
  4125. Arguments:
  4126. pFields - ptr to array where reference to names are stored
  4127. cFields - count of element in array
  4128. Return Value:
  4129. Nothing
  4130. --*/
  4131. {
  4132. UINT x;
  4133. BOOL fSt = TRUE;
  4134. for ( x = 0 ;
  4135. x < cFields ;
  4136. ++x )
  4137. {
  4138. if ( pFields[x].m_pszDisplayName )
  4139. {
  4140. LocalFree( pFields[x].m_pszDisplayName );
  4141. }
  4142. }
  4143. }
  4144. VOID
  4145. TerminateMapping(
  4146. )
  4147. /*++
  4148. Routine Description:
  4149. Terminate mapping
  4150. Arguments:
  4151. None
  4152. Return Value:
  4153. Nothing
  4154. --*/
  4155. {
  4156. if ( g_hKey != NULL )
  4157. {
  4158. RegCloseKey( g_hKey );
  4159. }
  4160. if ( g_pszInstallPath )
  4161. {
  4162. LocalFree( g_pszInstallPath );
  4163. }
  4164. FreeFieldNames( IisItaMappingFields,
  4165. sizeof(IisItaMappingFields)/sizeof(IISMDB_Fields) );
  4166. FreeFieldNames( IisCert11MappingFields,
  4167. sizeof(IisCert11MappingFields)/sizeof(IISMDB_Fields) );
  4168. FreeFieldNames( IisMd5MappingFields,
  4169. sizeof(IisMd5MappingFields)/sizeof(IISMDB_Fields) );
  4170. }
  4171. //
  4172. dllexp
  4173. BOOL
  4174. ReportIisMapEvent(
  4175. WORD wType,
  4176. DWORD dwEventId,
  4177. WORD cNbStr,
  4178. LPCTSTR* pStr
  4179. )
  4180. /*++
  4181. Routine Description:
  4182. Log an event based on type, ID and insertion strings
  4183. Arguments:
  4184. wType -- event type ( error, warning, information )
  4185. dwEventId -- event ID ( as defined by the .mc file )
  4186. cNbStr -- nbr of LPSTR in the pStr array
  4187. pStr -- insertion strings
  4188. Returns:
  4189. TRUE if success, FALSE if failure
  4190. --*/
  4191. {
  4192. BOOL fSt = TRUE;
  4193. HANDLE hEventLog = NULL;
  4194. hEventLog = RegisterEventSource(NULL,"IISMAP");
  4195. if ( hEventLog != NULL )
  4196. {
  4197. if (!ReportEvent(hEventLog, // event log handle
  4198. wType, // event type
  4199. 0, // category zero
  4200. (DWORD) dwEventId, // event identifier
  4201. NULL, // no user security identifier
  4202. cNbStr, // count of substitution strings (may be no strings)
  4203. // less ProgName (argv[0]) and Event ID (argv[1])
  4204. 0, // no data
  4205. (LPCTSTR *) pStr, // address of string array
  4206. NULL)) // address of data
  4207. {
  4208. fSt = FALSE;
  4209. }
  4210. DeregisterEventSource( hEventLog );
  4211. }
  4212. else
  4213. {
  4214. fSt = FALSE;
  4215. }
  4216. return fSt;
  4217. }
  4218. /////////////////////////////////////////
  4219. // CIisItaMapper
  4220. CIisItaMapper::CIisItaMapper(
  4221. )
  4222. /*++
  4223. Routine Description:
  4224. Constructor for CIisItaMapper
  4225. Arguments:
  4226. None
  4227. Returns:
  4228. Nothing
  4229. --*/
  4230. {
  4231. m_pFields = IisItaMappingFields;
  4232. m_cFields = sizeof(IisItaMappingFields)/sizeof(IISMDB_Fields);
  4233. m_dwOptions = IISMDB_ITA_OPTIONS;
  4234. }
  4235. CIisItaMapper::~CIisItaMapper(
  4236. )
  4237. /*++
  4238. Routine Description:
  4239. Destructor for CIisItaMapper
  4240. Arguments:
  4241. None
  4242. Returns:
  4243. Nothing
  4244. --*/
  4245. {
  4246. }
  4247. IISMDB_HEntry*
  4248. CIisItaMapper::GetDefaultHierarchy(
  4249. LPDWORD pdwN
  4250. )
  4251. /*++
  4252. Routine Description:
  4253. return ptr to default hierarchy for ita mapping
  4254. Arguments:
  4255. pdwN -- updated with hierarchy entries count
  4256. Returns:
  4257. ptr to hierarchy entries or NULL if error
  4258. --*/
  4259. {
  4260. *pdwN = sizeof(IisItaMappingHierarchy) / sizeof(IISMDB_HEntry);
  4261. return IisItaMappingHierarchy;
  4262. }
  4263. CIisMapping*
  4264. CIisItaMapper::CreateNewMapping(
  4265. LPSTR pszType,
  4266. LPSTR pszUser,
  4267. LPSTR pszPwd
  4268. )
  4269. /*++
  4270. Routine Description:
  4271. Create a new mapping from internet credentials
  4272. Arguments:
  4273. pszType -- login type : basic, user, MD5, SSL/PCT, ...
  4274. pszUser -- user name
  4275. pszPwd -- clear text password
  4276. Returns:
  4277. ptr to mapping. ownership of this object is transfered to caller.
  4278. NULL if error
  4279. --*/
  4280. {
  4281. CItaMapping *pCM = new CItaMapping( this );
  4282. if ( pCM == NULL )
  4283. {
  4284. return NULL;
  4285. }
  4286. if ( pCM->Init( pszType, pszUser, pszPwd, m_pHierarchy, m_cHierarchy ) )
  4287. {
  4288. return (CIisMapping*)pCM;
  4289. }
  4290. delete pCM;
  4291. return NULL;
  4292. }
  4293. // CItaMapping
  4294. CItaMapping::CItaMapping(
  4295. CIisAcctMapper* pMap
  4296. )
  4297. /*++
  4298. Routine Description:
  4299. Constructor for CItaMapping
  4300. Arguments:
  4301. pMap -- ptr to mapper object linked to this mapping
  4302. Returns:
  4303. Nothing
  4304. --*/
  4305. {
  4306. m_pMapper = (CIisAcctMapper*)pMap;
  4307. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  4308. {
  4309. m_pFields[x] = NULL;
  4310. }
  4311. }
  4312. CItaMapping::~CItaMapping(
  4313. )
  4314. /*++
  4315. Routine Description:
  4316. Destructor for CItaMapping
  4317. Arguments:
  4318. None
  4319. Returns:
  4320. Nothing
  4321. --*/
  4322. {
  4323. }
  4324. BOOL
  4325. CItaMapping::Init(
  4326. LPSTR pszType,
  4327. LPSTR pszUser,
  4328. LPSTR pszPwd,
  4329. IISMDB_HEntry *pH,
  4330. DWORD dwH
  4331. )
  4332. /*++
  4333. Routine Description:
  4334. Constructor for CItaMapping
  4335. Arguments:
  4336. pszType -- login type : basic, user, MD5, SSL/PCT, ...
  4337. pszUser -- user name
  4338. pszPwd -- clear text password
  4339. pH -- ptr to hierarchy info
  4340. dwH -- number of hierarchy entries
  4341. Returns:
  4342. TRUE if success, FALSE if error
  4343. --*/
  4344. {
  4345. if ( !MappingSetField( IISIMDB_INDEX_IT_ACCT, pszUser ) )
  4346. {
  4347. return FALSE;
  4348. }
  4349. if ( !MappingSetField( IISIMDB_INDEX_IT_PWD, pszPwd ) )
  4350. {
  4351. return FALSE;
  4352. }
  4353. return UpdateMask( pH, dwH );
  4354. }
  4355. BOOL
  4356. CCert11Mapping::MappingSetField(
  4357. DWORD dwIndex,
  4358. LPSTR pszNew
  4359. )
  4360. /*++
  4361. Routine Description:
  4362. Set field in mapping entry to specified content
  4363. data pointed by pszNew is copied inside mapping entry
  4364. Arguments:
  4365. dwIndex -- index of field
  4366. pszNew -- data to copy inside field
  4367. Returns:
  4368. TRUE if success, FALSE if error
  4369. Lock:
  4370. mapper must be locked for ptr to remain valid
  4371. --*/
  4372. {
  4373. LPSTR *pFields;
  4374. LPDWORD pcFields;
  4375. DWORD iMax = GetNbField( &pFields, &pcFields );
  4376. if ( dwIndex >= iMax )
  4377. {
  4378. return FALSE;
  4379. }
  4380. return StoreField( pFields, pcFields, dwIndex, iMax, pszNew, strlen(pszNew)+1, FALSE );
  4381. }
  4382. BOOL
  4383. CItaMapping::MappingSetField(
  4384. DWORD dwIndex,
  4385. LPSTR pszNew
  4386. )
  4387. /*++
  4388. Routine Description:
  4389. Set field in mapping entry to specified content
  4390. data pointed by pszNew is copied inside mapping entry
  4391. Arguments:
  4392. dwIndex -- index of field
  4393. pszNew -- data to copy inside field
  4394. Returns:
  4395. TRUE if success, FALSE if error
  4396. Lock:
  4397. mapper must be locked for ptr to remain valid
  4398. --*/
  4399. {
  4400. MD5_CTX md5;
  4401. CHAR achDigest[ sizeof(md5.digest)*2 + 1];
  4402. #define TOHEX(a) ((a)>=10 ? 'a'+(a)-10 : '0'+(a))
  4403. // convert clear text pwd to MD5 digest ( as ASCII string )
  4404. if ( dwIndex == IISIMDB_INDEX_IT_PWD )
  4405. {
  4406. MD5Init( &md5 );
  4407. MD5Update( &md5, (LPBYTE)pszNew, strlen(pszNew) );
  4408. MD5Final( &md5 );
  4409. for ( UINT x = 0, y = 0 ; x < sizeof(md5.digest) ; ++x )
  4410. {
  4411. UINT v;
  4412. v = md5.digest[x]>>4;
  4413. achDigest[y++] = TOHEX( v );
  4414. v = md5.digest[x]&0x0f;
  4415. achDigest[y++] = TOHEX( v );
  4416. }
  4417. achDigest[y] = '\0';
  4418. pszNew = achDigest;
  4419. }
  4420. return CIisMapping::MappingSetField( dwIndex, pszNew );
  4421. }
  4422. // CIisMd5Mapper
  4423. CIisMd5Mapper::CIisMd5Mapper(
  4424. )
  4425. /*++
  4426. Routine Description:
  4427. Constructor for CIisMd5Mapper
  4428. Arguments:
  4429. None
  4430. Returns:
  4431. Nothing
  4432. --*/
  4433. {
  4434. m_pFields = IisMd5MappingFields;
  4435. m_cFields = sizeof(IisMd5MappingFields)/sizeof(IISMDB_Fields);
  4436. m_dwOptions = IISMDB_MD5_OPTIONS;
  4437. }
  4438. CIisMd5Mapper::~CIisMd5Mapper(
  4439. )
  4440. /*++
  4441. Routine Description:
  4442. Destructor for CIisMd5Mapper
  4443. Arguments:
  4444. None
  4445. Returns:
  4446. Nothing
  4447. --*/
  4448. {
  4449. }
  4450. IISMDB_HEntry*
  4451. CIisMd5Mapper::GetDefaultHierarchy(
  4452. LPDWORD pdwN
  4453. )
  4454. /*++
  4455. Routine Description:
  4456. return ptr to default hierarchy for ita mapping
  4457. Arguments:
  4458. pdwN -- updated with hierarchy entries count
  4459. Returns:
  4460. ptr to hierarchy entries or NULL if error
  4461. --*/
  4462. {
  4463. *pdwN = sizeof(IisMd5MappingHierarchy) / sizeof(IISMDB_HEntry);
  4464. return IisMd5MappingHierarchy;
  4465. }
  4466. CIisMapping*
  4467. CIisMd5Mapper::CreateNewMapping(
  4468. LPSTR pszRealm,
  4469. LPSTR pszUser
  4470. )
  4471. /*++
  4472. Routine Description:
  4473. Create a new mapping from internet credentials
  4474. Arguments:
  4475. pszRealm -- Realm
  4476. pszUser -- user name
  4477. Returns:
  4478. ptr to mapping. ownership of this object is transfered to caller.
  4479. NULL if error
  4480. --*/
  4481. {
  4482. CMd5Mapping *pCM = new CMd5Mapping( this );
  4483. if ( pCM == NULL )
  4484. {
  4485. return NULL;
  4486. }
  4487. if ( pCM->Init( pszRealm, pszUser, m_pHierarchy, m_cHierarchy ) )
  4488. {
  4489. return (CIisMapping*)pCM;
  4490. }
  4491. delete pCM;
  4492. return NULL;
  4493. }
  4494. // CMd5Mapping
  4495. CMd5Mapping::CMd5Mapping(
  4496. CIisAcctMapper* pMap
  4497. )
  4498. /*++
  4499. Routine Description:
  4500. Constructor for CMd5Mapping
  4501. Arguments:
  4502. pMap -- ptr to mapper object linked to this mapping
  4503. Returns:
  4504. Nothing
  4505. --*/
  4506. {
  4507. m_pMapper = (CIisAcctMapper*)pMap;
  4508. for ( int x = 0 ; x < sizeof(m_pFields)/sizeof(LPSTR) ; ++x )
  4509. {
  4510. m_pFields[x] = NULL;
  4511. }
  4512. }
  4513. CMd5Mapping::~CMd5Mapping(
  4514. )
  4515. /*++
  4516. Routine Description:
  4517. Destructor for CItaMapping
  4518. Arguments:
  4519. None
  4520. Returns:
  4521. Nothing
  4522. --*/
  4523. {
  4524. }
  4525. BOOL
  4526. CMd5Mapping::Init(
  4527. LPSTR pszRealm,
  4528. LPSTR pszUser,
  4529. IISMDB_HEntry *pH,
  4530. DWORD dwH
  4531. )
  4532. /*++
  4533. Routine Description:
  4534. Constructor for CItaMapping
  4535. Arguments:
  4536. pszRealm -- Realm
  4537. pszUser -- user name
  4538. pH -- ptr to hierarchy info
  4539. dwH -- number of hierarchy entries
  4540. Returns:
  4541. TRUE if success, FALSE if error
  4542. --*/
  4543. {
  4544. if ( !MappingSetField( IISMMDB_INDEX_IT_ACCT, pszUser ) )
  4545. {
  4546. return FALSE;
  4547. }
  4548. if ( !MappingSetField( IISMMDB_INDEX_IT_REALM, pszRealm ) )
  4549. {
  4550. return FALSE;
  4551. }
  4552. return UpdateMask( pH, dwH );
  4553. }
  4554. BOOL
  4555. CMd5Mapping::MappingSetField(
  4556. DWORD dwIndex,
  4557. LPSTR pszNew
  4558. )
  4559. /*++
  4560. Routine Description:
  4561. Set field in mapping entry to specified content
  4562. data pointed by pszNew is copied inside mapping entry
  4563. Arguments:
  4564. dwIndex -- index of field
  4565. pszNew -- data to copy inside field
  4566. Returns:
  4567. TRUE if success, FALSE if error
  4568. Lock:
  4569. mapper must be locked for ptr to remain valid
  4570. --*/
  4571. {
  4572. MD5_CTX md5;
  4573. CHAR achDigest[ sizeof(md5.digest)*2 + 1];
  4574. // convert clear text pwd to MD5 digest ( as ASCII string )
  4575. if ( dwIndex == IISMMDB_INDEX_IT_MD5PWD )
  4576. {
  4577. if ( !CIisMapping::MappingSetField( IISMMDB_INDEX_IT_CLRPWD, pszNew ) )
  4578. {
  4579. return FALSE;
  4580. }
  4581. gen_md5pwd:
  4582. LPSTR pszName = m_pFields[IISMMDB_INDEX_IT_ACCT];
  4583. LPSTR pszRealm = m_pFields[IISMMDB_INDEX_IT_REALM];
  4584. CHAR *pS;
  4585. if ( pszName == NULL )
  4586. {
  4587. pszName = "";
  4588. }
  4589. if ( pszRealm == NULL )
  4590. {
  4591. pszRealm = "";
  4592. }
  4593. pS = new CHAR[strlen(pszName)+1+strlen(pszRealm)+1+strlen(pszNew)+1];
  4594. if ( pS == NULL )
  4595. {
  4596. return FALSE;
  4597. }
  4598. strcpy( pS, pszName );
  4599. strcat( pS, ":" );
  4600. strcat( pS, pszRealm );
  4601. strcat( pS, ":" );
  4602. strcat( pS, pszNew );
  4603. MD5Init( &md5 );
  4604. MD5Update( &md5, (LPBYTE)pS, strlen(pS) );
  4605. MD5Final( &md5 );
  4606. for ( UINT x = 0, y = 0 ; x < sizeof(md5.digest) ; ++x )
  4607. {
  4608. UINT v;
  4609. v = md5.digest[x]>>4;
  4610. achDigest[y++] = TOHEX( v );
  4611. v = md5.digest[x]&0x0f;
  4612. achDigest[y++] = TOHEX( v );
  4613. }
  4614. achDigest[y] = '\0';
  4615. pszNew = achDigest;
  4616. delete [] pS;
  4617. }
  4618. else if ( (dwIndex == IISMMDB_INDEX_IT_REALM ||
  4619. dwIndex == IISMMDB_INDEX_IT_ACCT) &&
  4620. m_pFields[ IISMMDB_INDEX_IT_CLRPWD ] )
  4621. {
  4622. if ( !CIisMapping::MappingSetField( dwIndex, pszNew ) )
  4623. {
  4624. return FALSE;
  4625. }
  4626. dwIndex = IISMMDB_INDEX_IT_MD5PWD;
  4627. pszNew = m_pFields[ IISMMDB_INDEX_IT_CLRPWD ];
  4628. goto gen_md5pwd;
  4629. }
  4630. return CIisMapping::MappingSetField( dwIndex, pszNew );
  4631. }
  4632. #if 0
  4633. PRDN_VALUE_BLOB
  4634. CertGetNameField(
  4635. UINT iEncoding,
  4636. IN LPCTSTR pszObjId,
  4637. IN PNAME_INFO pInfo
  4638. )
  4639. {
  4640. DWORD cRDN, cAttr;
  4641. PRDN pRDN;
  4642. PRDN_ATTR pAttr;
  4643. // Array of RDNs
  4644. for ( cRDN = pInfo->cRDN, pRDN = pInfo->rgRDN ;
  4645. cRDN > 0 ;
  4646. cRDN--, pRDN++ )
  4647. {
  4648. for ( cAttr = pRDN->cRDNAttr, pAttr = pRDN->rgRDNAttr ;
  4649. cAttr > 0 ;
  4650. cAttr--, pAttr++ )
  4651. {
  4652. if ( !strcmp( pAttr->pszObjId, pszObjId ) )
  4653. {
  4654. return &pAttr->Value;
  4655. }
  4656. }
  4657. }
  4658. return NULL;
  4659. }
  4660. BOOL
  4661. StoreField(
  4662. LPSTR* pFields,
  4663. LPSTR* pStore,
  4664. UINT* pLen,
  4665. PRDN_VALUE_BLOB pValue
  4666. )
  4667. {
  4668. memcpy( *pStore, pValue->pbData, pValue->cbData );
  4669. (*pStore)[ pValue->cbData ] = '\0';
  4670. *pFields = *pStore;
  4671. *pStore += pValue->cbData + 1;
  4672. *pLen += pValue->cbData + 1;
  4673. return TRUE;
  4674. }
  4675. UINT DecodeNames(
  4676. IN PNAME_BLOB pNameBlob,
  4677. IN LPSTR* pFields,
  4678. IN LPSTR pStore
  4679. )
  4680. {
  4681. PNAME_INFO pNameInfo = NULL;
  4682. DWORD cbNameInfo;
  4683. PRDN_VALUE_BLOB pValue;
  4684. UINT l = 0;
  4685. if (!DecodeObject(X509_ASN_ENCODING,
  4686. (LPCSTR)X509_NAME,
  4687. pNameBlob->pbData,
  4688. pNameBlob->cbData,
  4689. NULL,
  4690. &cbNameInfo))
  4691. {
  4692. goto Ret;
  4693. }
  4694. if (NULL == (pNameInfo = (PNAME_INFO)malloc(cbNameInfo)))
  4695. {
  4696. goto Ret;
  4697. }
  4698. if (!CertDecodeName(X509_ASN_ENCODING,
  4699. //(LPCSTR)X509_NAME,
  4700. pNameBlob->pbData,
  4701. pNameBlob->cbData,
  4702. pNameInfo,
  4703. &cbNameInfo))
  4704. {
  4705. goto Ret;
  4706. }
  4707. if (NULL == (pValue = CertGetNameField(X509_ASN_ENCODING,
  4708. COUNTRY_NAME_OBJID,
  4709. pNameInfo)))
  4710. {
  4711. goto Ret;
  4712. }
  4713. StoreField( pFields+IISMDB_INDEX_ISSUER_C, &pStore, &l, pValue );
  4714. if (NULL == (pValue = CertGetNameField(X509_ASN_ENCODING,
  4715. ORGANIZATION_NAME_OBJID,
  4716. pNameInfo)))
  4717. {
  4718. goto Ret;
  4719. }
  4720. StoreField( pFields+IISMDB_INDEX_ISSUER_O, &pStore, &l, pValue );
  4721. if (NULL == (pValue = CertGetNameField(X509_ASN_ENCODING,
  4722. ORGANIZATIONAL_UNIT_NAME_OBJID,
  4723. pNameInfo)))
  4724. {
  4725. goto Ret;
  4726. }
  4727. StoreField( pFields+IISMDB_INDEX_ISSUER_OU, &pStore, &l, pValue );
  4728. if (NULL == (pValue = CertGetNameField(X509_ASN_ENCODING,
  4729. COMMON_NAME_OBJID,
  4730. pNameInfo)))
  4731. {
  4732. goto Ret;
  4733. }
  4734. StoreField( pFields+IISMDB_INDEX_ISSUER_C+1, &pStore, &l, pValue );
  4735. Ret:
  4736. free(pNameInfo);
  4737. return l;
  4738. }
  4739. UINT DecodeCert(
  4740. IN PBYTE pbEncodedCert,
  4741. IN DWORD cbEncodedCert,
  4742. LPSTR* pFields,
  4743. LPSTR pStore
  4744. )
  4745. {
  4746. PCCERT_CONTEXT pCert = NULL;
  4747. UINT l;
  4748. if (NULL == (pCert = CertCreateCertificateContext(X509_ASN_ENCODING,
  4749. pbEncodedCert,
  4750. cbEncodedCert)))
  4751. {
  4752. return 0;
  4753. }
  4754. l = DecodeNames(&pCert->pCertInfo->Issuer, pFields, pStore )
  4755. +
  4756. DecodeNames(&pCert->pCertInfo->Subject, pFields+3, pStore );
  4757. CertFreeCertificateContext( pCert );
  4758. return l;
  4759. }
  4760. #endif
  4761. ///////////////////////
  4762. //
  4763. // Taken from NCSA HTTP and wwwlib.
  4764. //
  4765. // NOTE: These conform to RFC1113, which is slightly different then the Unix
  4766. // uuencode and uudecode!
  4767. //
  4768. const int _pr2six[256]={
  4769. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4770. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
  4771. 52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
  4772. 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
  4773. 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
  4774. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4775. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4776. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4777. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4778. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4779. 64,64,64,64,64,64,64,64,64,64,64,64,64
  4780. };
  4781. char _six2pr[64] = {
  4782. 'A','B','C','D','E','F','G','H','I','J','K','L','M',
  4783. 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  4784. 'a','b','c','d','e','f','g','h','i','j','k','l','m',
  4785. 'n','o','p','q','r','s','t','u','v','w','x','y','z',
  4786. '0','1','2','3','4','5','6','7','8','9','+','/'
  4787. };
  4788. const int _pr2six64[256]={
  4789. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4790. 64,64,64,64,64,64,64,64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
  4791. 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
  4792. 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  4793. 0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4794. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4795. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4796. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4797. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4798. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  4799. 64,64,64,64,64,64,64,64,64,64,64,64,64
  4800. };
  4801. char _six2pr64[64] = {
  4802. '`','!','"','#','$','%','&','\'','(',')','*','+',',',
  4803. '-','.','/','0','1','2','3','4','5','6','7','8','9',
  4804. ':',';','<','=','>','?','@','A','B','C','D','E','F',
  4805. 'G','H','I','J','K','L','M','N','O','P','Q','R','S',
  4806. 'T','U','V','W','X','Y','Z','[','\\',']','^','_'
  4807. };
  4808. BOOL IISuudecode(char * bufcoded,
  4809. BYTE * bufout,
  4810. DWORD * pcbDecoded,
  4811. BOOL fBase64
  4812. )
  4813. {
  4814. int nbytesdecoded;
  4815. char *bufin = bufcoded;
  4816. int nprbytes;
  4817. int *pr2six = (int*)(fBase64 ? _pr2six64 : _pr2six);
  4818. int chL;
  4819. /* Strip leading whitespace. */
  4820. while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
  4821. /* Figure out how many characters are in the input buffer.
  4822. * If this would decode into more bytes than would fit into
  4823. * the output buffer, adjust the number of input bytes downwards.
  4824. */
  4825. bufin = bufcoded;
  4826. while(pr2six[*(bufin++)] <= 63);
  4827. nprbytes = DIFF(bufin - bufcoded) - 1;
  4828. nbytesdecoded = ((nprbytes+3)/4) * 3;
  4829. bufin = bufcoded;
  4830. while (nprbytes > 0) {
  4831. chL = bufin[2];
  4832. *(bufout++) =
  4833. (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
  4834. *(bufout++) =
  4835. (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
  4836. *(bufout++) =
  4837. (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
  4838. bufin += 4;
  4839. nprbytes -= 4;
  4840. }
  4841. if(nprbytes & 03) {
  4842. if(pr2six[chL] > 63)
  4843. nbytesdecoded -= 2;
  4844. else
  4845. nbytesdecoded -= 1;
  4846. }
  4847. if ( pcbDecoded )
  4848. *pcbDecoded = nbytesdecoded;
  4849. return TRUE;
  4850. }
  4851. //
  4852. // NOTE NOTE NOTE
  4853. // If the buffer length isn't a multiple of 3, we encode one extra byte beyond the
  4854. // end of the buffer. This garbage byte is stripped off by the uudecode code, but
  4855. // -IT HAS TO BE THERE- for uudecode to work. This applies not only our uudecode, but
  4856. // to every uudecode() function that is based on the lib-www distribution [probably
  4857. // a fairly large percentage of the code that's floating around out there].
  4858. //
  4859. BOOL IISuuencode( BYTE * bufin,
  4860. DWORD nbytes,
  4861. BYTE * outptr,
  4862. BOOL fBase64 )
  4863. {
  4864. unsigned int i;
  4865. unsigned int iRemainder = 0;
  4866. unsigned int iClosestMultOfThree = 0;
  4867. char *six2pr = fBase64 ? _six2pr64 : _six2pr;
  4868. BOOL fOneByteDiff = FALSE;
  4869. BOOL fTwoByteDiff = FALSE;
  4870. iRemainder = nbytes % 3; //also works for nbytes == 1, 2
  4871. fOneByteDiff = (iRemainder == 1 ? TRUE : FALSE);
  4872. fTwoByteDiff = (iRemainder == 2 ? TRUE : FALSE);
  4873. iClosestMultOfThree = ((nbytes - iRemainder)/3) * 3 ;
  4874. //
  4875. // Encode bytes in buffer up to multiple of 3 that is closest to nbytes.
  4876. //
  4877. for (i=0; i< iClosestMultOfThree ; i += 3) {
  4878. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  4879. *(outptr++) = six2pr[((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)]; /*c2*/
  4880. *(outptr++) = six2pr[((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)];/*c3*/
  4881. *(outptr++) = six2pr[bufin[2] & 077]; /* c4 */
  4882. bufin += 3;
  4883. }
  4884. //
  4885. // We deal with trailing bytes by pretending that the input buffer has been padded with
  4886. // zeros. Expressions are thus the same as above, but the second half drops off b'cos
  4887. // ( a | ( b & 0) ) = ( a | 0 ) = a
  4888. //
  4889. if (fOneByteDiff)
  4890. {
  4891. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  4892. *(outptr++) = six2pr[((*bufin << 4) & 060)]; /* c2 */
  4893. //pad with '='
  4894. *(outptr++) = '='; /* c3 */
  4895. *(outptr++) = '='; /* c4 */
  4896. }
  4897. else if (fTwoByteDiff)
  4898. {
  4899. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  4900. *(outptr++) = six2pr[((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)]; /*c2*/
  4901. *(outptr++) = six2pr[((bufin[1] << 2) & 074)];/*c3*/
  4902. //pad with '='
  4903. *(outptr++) = '='; /* c4 */
  4904. }
  4905. //encoded buffer must be zero-terminated
  4906. *outptr = '\0';
  4907. return TRUE;
  4908. }
  4909. #if 0
  4910. //
  4911. // Functions to create 1:1 mapping using issuer, subject to NT acct
  4912. //
  4913. static CIisCert11Mapper g_ExpCert11Mapper;
  4914. LONG g_fCert11Init = FALSE;
  4915. DWORD
  4916. MappingInit(
  4917. VOID
  4918. )
  4919. /*++
  4920. Routine Description:
  4921. Initialize cert 1:1 mapping entry points
  4922. Arguments:
  4923. None
  4924. Returns:
  4925. 0 if success, otherwise NT error code
  4926. --*/
  4927. {
  4928. DWORD st = 0;
  4929. BOOL fFirst;
  4930. EnterCriticalSection( &g_csIisMap );
  4931. if ( !g_fCert11Init )
  4932. {
  4933. st = g_ExpCert11Mapper.Init( &fFirst, FALSE ) ? 0 : ERROR_OPEN_FAILED;
  4934. if ( !st )
  4935. {
  4936. st = g_ExpCert11Mapper.Load() ? 0 : GetLastError();
  4937. }
  4938. g_fCert11Init = TRUE;
  4939. }
  4940. LeaveCriticalSection( &g_csIisMap );
  4941. return st;
  4942. }
  4943. BOOL
  4944. UnicodeToAnsi(
  4945. LPWSTR pwsz,
  4946. LPSTR* ppsz,
  4947. LPDWORD pc )
  4948. /*++
  4949. Routine Description:
  4950. Create ANSI version of Unicode string
  4951. Arguments:
  4952. pwsz - ptr to Unicode string
  4953. ppsz - updated with ptr to ANSI string, or NULL if error
  4954. pc - updated with # of chars in converted string
  4955. Returns:
  4956. TRUE if success, otherwise FALSE
  4957. --*/
  4958. {
  4959. DWORD dwW = wcslen( pwsz );
  4960. #if 1 // DBCS worst case
  4961. DWORD dwS = dwW * 2;
  4962. #else
  4963. DWORD dwS = dwW;
  4964. #endif
  4965. LPSTR psz;
  4966. if ( *ppsz = psz = (LPSTR)LocalAlloc( LMEM_FIXED, dwS + 1 ) )
  4967. {
  4968. dwS = WideCharToMultiByte( CP_ACP, 0,
  4969. pwsz, dwW,
  4970. psz, dwS,
  4971. NULL, NULL );
  4972. psz[dwS] = '\0';
  4973. *pc = dwS;
  4974. }
  4975. if ( dwS == 0 && dwW != 0 )
  4976. {
  4977. if ( psz )
  4978. {
  4979. LocalFree( psz );
  4980. *ppsz = NULL;
  4981. }
  4982. return FALSE;
  4983. }
  4984. return TRUE;
  4985. }
  4986. #define UnicodeToAnsiFree( a ) {if ( (a)!=NULL ) LocalFree(a);}
  4987. DWORD WINAPI
  4988. CreateMapping(
  4989. LPWSTR pwszUuIssuer,
  4990. LPWSTR pwszUuSubject,
  4991. LPWSTR pwszNtAcct
  4992. )
  4993. /*++
  4994. Routine Description:
  4995. Create mapping for cert 1:1 mapper
  4996. Arguments:
  4997. pwszUuIssuer - uuencoded Issuer
  4998. pwszSubject - uuencoded Subject
  4999. pwszNtAcct - NT account to map to
  5000. Returns:
  5001. 0 if success, otherwise NT error code
  5002. --*/
  5003. {
  5004. DWORD st = 0;
  5005. LPSTR pI;
  5006. LPSTR pS;
  5007. LPSTR pN;
  5008. DWORD cI;
  5009. DWORD cS;
  5010. DWORD cN;
  5011. if ( (st=MappingInit()) )
  5012. {
  5013. return st;
  5014. }
  5015. CIisMapping *pM = g_ExpCert11Mapper.CreateNewMapping();
  5016. if ( !pM )
  5017. {
  5018. return ERROR_NOT_ENOUGH_MEMORY;
  5019. }
  5020. UnicodeToAnsi( pwszUuIssuer, &pI, &cI );
  5021. UnicodeToAnsi( pwszUuSubject, &pS, &cS );
  5022. UnicodeToAnsi( pwszNtAcct, &pN, &cN );
  5023. if ( pI != NULL && pS != NULL && pN != NULL )
  5024. {
  5025. pM->MappingSetField( IISMDB_INDEX_CERT11_ISSUER, pI, cI, TRUE );
  5026. pM->MappingSetField( IISMDB_INDEX_CERT11_SUBJECT, pS, cS, TRUE );
  5027. pM->MappingSetField( IISMDB_INDEX_CERT11_NT_ACCT, pN, cN, FALSE );
  5028. if ( !g_ExpCert11Mapper.Add( pM ) )
  5029. {
  5030. st = GetLastError();;
  5031. }
  5032. }
  5033. else
  5034. {
  5035. st = ERROR_NOT_ENOUGH_MEMORY;
  5036. }
  5037. UnicodeToAnsiFree( pI );
  5038. UnicodeToAnsiFree( pS );
  5039. UnicodeToAnsiFree( pN );
  5040. return st;
  5041. }
  5042. DWORD WINAPI
  5043. CheckMapping(
  5044. LPWSTR pwszUuIssuer,
  5045. LPWSTR pwszUuSubject,
  5046. LPWSTR* ppwszNtAcct // Out
  5047. )
  5048. /*++
  5049. Routine Description:
  5050. Check if mapping exists for cert 1:1 mapper
  5051. Arguments:
  5052. pwszUuIssuer - uuencoded Issuer
  5053. pwszSubject - uuencoded Subject
  5054. ppwszNtAcct - receive ptr to mapped NT account if exist
  5055. or NULL if any error
  5056. Must be released by a call to LocalFree()
  5057. Returns:
  5058. 0 if success, otherwise NT error code
  5059. ERROR_INVALID_PARAMETER if no such mapping
  5060. --*/
  5061. {
  5062. DWORD st = 0;
  5063. LPSTR pI;
  5064. LPSTR pS;
  5065. DWORD cI;
  5066. DWORD cS;
  5067. LPWSTR pwszNtAcct = NULL;
  5068. if ( (st=MappingInit()) )
  5069. {
  5070. return st;
  5071. }
  5072. CIisMapping *pM = g_ExpCert11Mapper.CreateNewMapping();
  5073. if ( !pM )
  5074. {
  5075. return ERROR_NOT_ENOUGH_MEMORY;
  5076. }
  5077. UnicodeToAnsi( pwszUuIssuer, &pI, &cI );
  5078. UnicodeToAnsi( pwszUuSubject, &pS, &cS );
  5079. if ( pI != NULL && pS != NULL )
  5080. {
  5081. pM->MappingSetField( IISMDB_INDEX_CERT11_ISSUER, pI, cI, TRUE );
  5082. pM->MappingSetField( IISMDB_INDEX_CERT11_SUBJECT, pS, cS, TRUE );
  5083. DWORD iCurrent = 0xffffffff;
  5084. CIisMapping* pMi;
  5085. LPSTR pAcct;
  5086. DWORD dwAcct;
  5087. if ( !g_ExpCert11Mapper.FindMatch( pM, &pMi ) ||
  5088. !pMi->MappingGetField( IISMDB_INDEX_CERT11_NT_ACCT, &pAcct, &dwAcct, FALSE )
  5089. || pAcct == NULL )
  5090. {
  5091. st = ERROR_INVALID_PARAMETER;
  5092. }
  5093. else
  5094. {
  5095. DWORD dw;
  5096. if ( !(pwszNtAcct = (LPWSTR)LocalAlloc( LMEM_FIXED,
  5097. (dwAcct+1)*sizeof(WCHAR) )) )
  5098. {
  5099. st = ERROR_NOT_ENOUGH_MEMORY;
  5100. }
  5101. else
  5102. {
  5103. dw = MultiByteToWideChar( CP_ACP, 0,
  5104. pAcct, dwAcct,
  5105. pwszNtAcct, dwAcct );
  5106. pwszNtAcct[dw] = L'\0';
  5107. *ppwszNtAcct = pwszNtAcct;
  5108. }
  5109. }
  5110. }
  5111. else
  5112. {
  5113. st = ERROR_NOT_ENOUGH_MEMORY;
  5114. }
  5115. g_ExpCert11Mapper.DeleteMappingObject( pM );
  5116. UnicodeToAnsiFree( pI );
  5117. UnicodeToAnsiFree( pS );
  5118. if ( st )
  5119. {
  5120. *ppwszNtAcct = NULL;
  5121. }
  5122. return st;
  5123. }
  5124. DWORD WINAPI
  5125. SaveMapping(
  5126. VOID
  5127. )
  5128. /*++
  5129. Routine Description:
  5130. Save mappings for cert 1:1 mapper
  5131. Arguments:
  5132. None
  5133. Returns:
  5134. 0 if success, otherwise NT error code
  5135. ERROR_WRITE_FAULT if generic write error
  5136. --*/
  5137. {
  5138. DWORD st = 0;
  5139. if ( (st=MappingInit()) )
  5140. {
  5141. return st;
  5142. }
  5143. SetLastError( 0 );
  5144. if ( !g_ExpCert11Mapper.Save() )
  5145. {
  5146. st = GetLastError();
  5147. st = st ? st : ERROR_WRITE_FAULT;
  5148. }
  5149. return st;
  5150. }
  5151. #endif