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.

920 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: certmap.c
  7. //
  8. // Contents: Routines to call appropriate mapper, be it the system
  9. // default one (in the LSA process) or an application one (in
  10. // the application process).
  11. //
  12. // Classes:
  13. //
  14. // Functions:
  15. //
  16. // History: 12-23-96 jbanes Created.
  17. //
  18. //----------------------------------------------------------------------------
  19. #include <spbase.h>
  20. DWORD
  21. WINAPI
  22. SslReferenceMapper(HMAPPER *phMapper)
  23. {
  24. DWORD dwResult;
  25. SecBuffer Input;
  26. SecBuffer Output;
  27. SECURITY_STATUS scRet;
  28. if(phMapper == NULL)
  29. {
  30. return SP_LOG_RESULT(-1);
  31. }
  32. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  33. {
  34. // System mapper.
  35. return phMapper->m_vtable->ReferenceMapper(phMapper);
  36. }
  37. else
  38. {
  39. // Application mapper.
  40. Input.BufferType = SECBUFFER_DATA;
  41. Input.cbBuffer = 0;
  42. Input.pvBuffer = NULL;
  43. scRet = PerformApplicationCallback( SCH_REFERENCE_MAPPER_CALLBACK,
  44. (ULONG_PTR)phMapper->m_Reserved1,
  45. TRUE,
  46. &Input,
  47. &Output,
  48. TRUE);
  49. if(!NT_SUCCESS(scRet))
  50. {
  51. DebugLog((DEB_ERROR, "Error 0x%x referencing mapper\n", scRet));
  52. return SP_LOG_RESULT(scRet);
  53. }
  54. SP_ASSERT(Output.cbBuffer == sizeof(DWORD));
  55. dwResult = *(PDWORD)(Output.pvBuffer);
  56. SPExternalFree(Output.pvBuffer);
  57. return dwResult;
  58. }
  59. }
  60. DWORD
  61. WINAPI
  62. SslDereferenceMapper(HMAPPER *phMapper)
  63. {
  64. DWORD dwResult;
  65. SecBuffer Input;
  66. SecBuffer Output;
  67. SECURITY_STATUS scRet;
  68. if(phMapper == NULL)
  69. {
  70. return SP_LOG_RESULT(0);
  71. }
  72. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  73. {
  74. // System mapper.
  75. return phMapper->m_vtable->DeReferenceMapper(phMapper);
  76. }
  77. else
  78. {
  79. // Application mapper.
  80. Input.BufferType = SECBUFFER_DATA;
  81. Input.cbBuffer = 0;
  82. Input.pvBuffer = NULL;
  83. scRet = PerformApplicationCallback( SCH_REFERENCE_MAPPER_CALLBACK,
  84. (ULONG_PTR)phMapper->m_Reserved1,
  85. FALSE,
  86. &Input,
  87. &Output,
  88. TRUE);
  89. if(!NT_SUCCESS(scRet))
  90. {
  91. DebugLog((DEB_ERROR, "Error 0x%x dereferencing mapper\n", scRet));
  92. return SP_LOG_RESULT(scRet);
  93. }
  94. SP_ASSERT(Output.cbBuffer == sizeof(DWORD));
  95. dwResult = *(PDWORD)(Output.pvBuffer);
  96. SPExternalFree(Output.pvBuffer);
  97. return dwResult;
  98. }
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Function: ReferenceMapperCallback
  103. //
  104. // Synopsis: Reference (or dereference) the application mapper.
  105. //
  106. // Arguments: [fReference] -- Whether to reference or dereference.
  107. // [dwArg2] -- Not used.
  108. // [pInput] -- HMAPPER structure.
  109. // [pOutput] -- DWORD reference count.
  110. //
  111. // History: 10-17-97 jbanes Created
  112. //
  113. // Notes:
  114. //
  115. //----------------------------------------------------------------------------
  116. SECURITY_STATUS
  117. ReferenceMapperCallback(
  118. ULONG_PTR Mapper,
  119. ULONG_PTR fReference,
  120. SecBuffer *pInput,
  121. SecBuffer *pOutput)
  122. {
  123. DWORD dwResult;
  124. HMAPPER *phMapper;
  125. if(!SchannelInit(TRUE))
  126. {
  127. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  128. }
  129. DebugLog((DEB_TRACE, "ReferenceMapperCallback\n"));
  130. phMapper = (HMAPPER *)Mapper;
  131. // Perform reference counting.
  132. try
  133. {
  134. if(fReference)
  135. {
  136. dwResult = phMapper->m_vtable->ReferenceMapper(phMapper);
  137. }
  138. else
  139. {
  140. dwResult = phMapper->m_vtable->DeReferenceMapper(phMapper);
  141. }
  142. }
  143. except(EXCEPTION_EXECUTE_HANDLER)
  144. {
  145. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  146. }
  147. // Build output buffer
  148. pOutput->BufferType = SECBUFFER_DATA;
  149. pOutput->cbBuffer = sizeof(DWORD);
  150. pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
  151. if(pOutput->pvBuffer == NULL)
  152. {
  153. return SEC_E_INSUFFICIENT_MEMORY;
  154. }
  155. *(DWORD *)(pOutput->pvBuffer) = dwResult;
  156. return SEC_E_OK;
  157. }
  158. SECURITY_STATUS
  159. WINAPI
  160. SslGetMapperIssuerList(
  161. HMAPPER * phMapper, // in
  162. BYTE ** ppIssuerList, // out
  163. DWORD * pcbIssuerList) // out
  164. {
  165. SecBuffer Input;
  166. SecBuffer Output;
  167. SECURITY_STATUS Status;
  168. if(phMapper == NULL)
  169. {
  170. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  171. }
  172. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  173. {
  174. // System mapper.
  175. Status = phMapper->m_vtable->GetIssuerList(phMapper,
  176. 0,
  177. NULL,
  178. pcbIssuerList);
  179. if(!NT_SUCCESS(Status))
  180. {
  181. return SP_LOG_RESULT(Status);
  182. }
  183. *ppIssuerList = SPExternalAlloc(*pcbIssuerList);
  184. if(*ppIssuerList == NULL)
  185. {
  186. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  187. }
  188. Status = phMapper->m_vtable->GetIssuerList(phMapper,
  189. 0,
  190. *ppIssuerList,
  191. pcbIssuerList);
  192. if(!NT_SUCCESS(Status))
  193. {
  194. SPExternalFree(*ppIssuerList);
  195. return SP_LOG_RESULT(Status);
  196. }
  197. return Status;
  198. }
  199. else
  200. {
  201. // Application mapper.
  202. Input.BufferType = SECBUFFER_DATA;
  203. Input.cbBuffer = 0;
  204. Input.pvBuffer = NULL;
  205. Status = PerformApplicationCallback( SCH_GET_MAPPER_ISSUER_LIST_CALLBACK,
  206. (ULONG_PTR)phMapper->m_Reserved1,
  207. 0,
  208. &Input,
  209. &Output,
  210. TRUE);
  211. if(!NT_SUCCESS(Status))
  212. {
  213. DebugLog((DEB_ERROR, "Error 0x%x getting mapper issuer list\n", Status));
  214. *ppIssuerList = NULL;
  215. *pcbIssuerList = 0;
  216. return Status;
  217. }
  218. *ppIssuerList = Output.pvBuffer;
  219. *pcbIssuerList = Output.cbBuffer;
  220. return Status;
  221. }
  222. }
  223. //+---------------------------------------------------------------------------
  224. //
  225. // Function: GetMapperIssuerListCallback
  226. //
  227. // Synopsis: Query the application mapper for the list of trusted CAs.
  228. //
  229. // Arguments: [pIssuerList] -- Pointer to LSA buffer.
  230. // [cbIssuerList] -- Size of LSA buffer.
  231. // [pInput] -- HMAPPER structure.
  232. // [pOutput] -- Issuer list.
  233. //
  234. // History: 10-17-97 jbanes Created
  235. //
  236. // Notes: The format of the output buffer is as follows:
  237. //
  238. // BYTE rgbIssuerList;
  239. //
  240. //----------------------------------------------------------------------------
  241. SECURITY_STATUS
  242. GetMapperIssuerListCallback(
  243. ULONG_PTR Mapper,
  244. ULONG_PTR dwArg2,
  245. SecBuffer *pInput,
  246. SecBuffer *pOutput)
  247. {
  248. HMAPPER * phMapper;
  249. DWORD cbIssuerList;
  250. DWORD Status;
  251. if(!SchannelInit(TRUE))
  252. {
  253. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  254. }
  255. DebugLog((DEB_TRACE, "GetMapperIssuerListCallback\n"));
  256. phMapper = (HMAPPER *)Mapper;
  257. pOutput->BufferType = SECBUFFER_DATA;
  258. pOutput->cbBuffer = 0;
  259. pOutput->pvBuffer = NULL;
  260. try
  261. {
  262. Status = phMapper->m_vtable->GetIssuerList(phMapper,
  263. NULL,
  264. NULL,
  265. &cbIssuerList);
  266. if(!NT_SUCCESS(Status))
  267. {
  268. SP_LOG_RESULT(Status);
  269. goto error;
  270. }
  271. pOutput->cbBuffer = cbIssuerList;
  272. pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
  273. if(pOutput->pvBuffer == NULL)
  274. {
  275. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  276. goto error;
  277. }
  278. Status = phMapper->m_vtable->GetIssuerList(phMapper,
  279. NULL,
  280. pOutput->pvBuffer,
  281. &cbIssuerList);
  282. if(!NT_SUCCESS(Status))
  283. {
  284. SP_LOG_RESULT(Status);
  285. goto error;
  286. }
  287. }
  288. except(EXCEPTION_EXECUTE_HANDLER)
  289. {
  290. Status = SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  291. goto error;
  292. }
  293. return SEC_E_OK;
  294. error:
  295. if(pOutput->pvBuffer)
  296. {
  297. FreeExtVirtualAlloc(pOutput->pvBuffer, pOutput->cbBuffer);
  298. pOutput->pvBuffer = NULL;
  299. }
  300. return Status;
  301. }
  302. SECURITY_STATUS
  303. WINAPI
  304. SslGetMapperChallenge(
  305. HMAPPER * phMapper, // in
  306. BYTE * pAuthenticatorId, // in
  307. DWORD cbAuthenticatorId, // in
  308. BYTE * pChallenge, // out
  309. DWORD * pcbChallenge) // out
  310. {
  311. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  312. }
  313. SECURITY_STATUS
  314. WINAPI
  315. SslMapCredential(
  316. HMAPPER * phMapper, // in
  317. DWORD dwCredentialType, // in
  318. PCCERT_CONTEXT pCredential, // in
  319. PCCERT_CONTEXT pAuthority, // in
  320. HLOCATOR * phLocator) // out
  321. {
  322. SecBuffer Input;
  323. SecBuffer Output;
  324. PBYTE pbBuffer;
  325. DWORD cbCredential;
  326. DWORD cbAuthority;
  327. SECURITY_STATUS scRet;
  328. if(phMapper == NULL)
  329. {
  330. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  331. }
  332. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  333. {
  334. // System mapper.
  335. scRet = phMapper->m_vtable->MapCredential(phMapper,
  336. dwCredentialType,
  337. pCredential,
  338. pAuthority,
  339. phLocator);
  340. return MapWinTrustError(scRet, SEC_E_NO_IMPERSONATION, 0);
  341. }
  342. else
  343. {
  344. // Application mapper.
  345. // Determine the size of the serialized cert contexts.
  346. scRet = SerializeCertContext(pCredential,
  347. NULL,
  348. &cbCredential);
  349. if(FAILED(scRet))
  350. {
  351. return SP_LOG_RESULT(scRet);
  352. }
  353. if(pAuthority)
  354. {
  355. if(!CertSerializeCertificateStoreElement(
  356. pAuthority,
  357. 0, NULL,
  358. &cbAuthority))
  359. {
  360. return SP_LOG_RESULT(GetLastError());
  361. }
  362. }
  363. else
  364. {
  365. cbAuthority = 0;
  366. }
  367. // Allocate memory for the input buffer.
  368. Input.BufferType = SECBUFFER_DATA;
  369. Input.cbBuffer = sizeof(DWORD) + cbCredential +
  370. sizeof(DWORD) + cbAuthority;
  371. Input.pvBuffer = LocalAlloc(LMEM_FIXED, Input.cbBuffer);
  372. if(Input.pvBuffer == NULL)
  373. {
  374. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  375. }
  376. // Build the input buffer.
  377. pbBuffer = Input.pvBuffer;
  378. *(PDWORD)pbBuffer = cbCredential;
  379. pbBuffer += sizeof(DWORD);
  380. *(PDWORD)pbBuffer = cbAuthority;
  381. pbBuffer += sizeof(DWORD);
  382. scRet = SerializeCertContext(pCredential,
  383. pbBuffer,
  384. &cbCredential);
  385. if(FAILED(scRet))
  386. {
  387. LocalFree(Input.pvBuffer);
  388. return SP_LOG_RESULT(scRet);
  389. }
  390. pbBuffer += cbCredential;
  391. if(pAuthority)
  392. {
  393. if(!CertSerializeCertificateStoreElement(
  394. pAuthority,
  395. 0,
  396. pbBuffer,
  397. &cbAuthority))
  398. {
  399. scRet = SP_LOG_RESULT(GetLastError());
  400. LocalFree(Input.pvBuffer);
  401. return scRet;
  402. }
  403. pbBuffer += cbAuthority;
  404. }
  405. SP_ASSERT(pbBuffer - (PBYTE)Input.pvBuffer == (INT)Input.cbBuffer);
  406. scRet = PerformApplicationCallback( SCH_MAP_CREDENTIAL_CALLBACK,
  407. (ULONG_PTR)phMapper->m_Reserved1,
  408. dwCredentialType,
  409. &Input,
  410. &Output,
  411. TRUE);
  412. LocalFree(Input.pvBuffer);
  413. if(!NT_SUCCESS(scRet))
  414. {
  415. DebugLog((DEB_ERROR, "Error 0x%x mapping credential\n", scRet));
  416. return scRet;
  417. }
  418. SP_ASSERT(Output.cbBuffer == sizeof(HLOCATOR));
  419. CopyMemory(phLocator, Output.pvBuffer, sizeof(HLOCATOR));
  420. SPExternalFree(Output.pvBuffer);
  421. return SEC_E_OK;
  422. }
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Function: MapCredentialCallback
  427. //
  428. // Synopsis: Maps the specified certificate to an NT user account, via
  429. // an application-installed certificate mapper.
  430. //
  431. // Arguments: [dwCredentialType] -- Credential type.
  432. // [dwArg2] -- Not used.
  433. // [pInput] -- See notes.
  434. // [pOutput] -- Returned locator.
  435. //
  436. // History: 12-29-97 jbanes Created
  437. //
  438. // Notes: The format of the input buffer is:
  439. //
  440. // DWORD cbCredential;
  441. // DWORD cbAuthority;
  442. // BYTE rgbCredential[cbCredential];
  443. // BYTE rgbAuthority[cbAuthority];
  444. //
  445. // The credential and authority fields consist of serialized
  446. // CERT_CONTEXT structures.
  447. //
  448. //----------------------------------------------------------------------------
  449. SECURITY_STATUS
  450. MapCredentialCallback(
  451. ULONG_PTR Mapper,
  452. ULONG_PTR dwCredentialType,
  453. SecBuffer *pInput,
  454. SecBuffer *pOutput)
  455. {
  456. HMAPPER * phMapper;
  457. PCCERT_CONTEXT pCredential = NULL;
  458. PCCERT_CONTEXT pAuthority = NULL;
  459. SECURITY_STATUS scRet;
  460. DWORD cbCredential;
  461. DWORD cbAuthority;
  462. PBYTE pbBuffer;
  463. HLOCATOR hLocator;
  464. if(!SchannelInit(TRUE))
  465. {
  466. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  467. }
  468. DebugLog((DEB_TRACE, "MapCredentialCallback\n"));
  469. phMapper = (HMAPPER *)Mapper;
  470. // Initialize output buffer.
  471. pOutput->BufferType = SECBUFFER_DATA;
  472. pOutput->cbBuffer = 0;
  473. pOutput->pvBuffer = NULL;
  474. //
  475. // Parse input buffer
  476. //
  477. pbBuffer = pInput->pvBuffer;
  478. if(pInput->cbBuffer < sizeof(DWORD) * 2)
  479. {
  480. scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  481. goto done;
  482. }
  483. cbCredential = *(PDWORD)pbBuffer;
  484. pbBuffer += sizeof(DWORD);
  485. cbAuthority = *(PDWORD)pbBuffer;
  486. pbBuffer += sizeof(DWORD);
  487. if(pInput->cbBuffer < sizeof(DWORD) * 2 + cbCredential + cbAuthority)
  488. {
  489. scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  490. goto done;
  491. }
  492. // Deserialize "credential" certificate context.
  493. scRet = DeserializeCertContext(&pCredential,
  494. pbBuffer,
  495. cbCredential);
  496. if(FAILED(scRet))
  497. {
  498. scRet = SP_LOG_RESULT(scRet);
  499. goto done;
  500. }
  501. pbBuffer += cbCredential;
  502. // Deserialize "authority" certificate context.
  503. if(cbAuthority && pCredential->hCertStore)
  504. {
  505. if(!CertAddSerializedElementToStore(pCredential->hCertStore,
  506. pbBuffer + sizeof(DWORD),
  507. *(DWORD *)pbBuffer,
  508. CERT_STORE_ADD_USE_EXISTING,
  509. 0,
  510. CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
  511. NULL,
  512. &pAuthority))
  513. {
  514. scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  515. goto done;
  516. }
  517. }
  518. //
  519. // Call application mapper.
  520. //
  521. try
  522. {
  523. scRet = phMapper->m_vtable->MapCredential(phMapper,
  524. (DWORD)dwCredentialType,
  525. pCredential,
  526. pAuthority,
  527. &hLocator);
  528. if(!NT_SUCCESS(scRet))
  529. {
  530. // Mapping was unsuccessful.
  531. scRet = MapWinTrustError(scRet, SEC_E_NO_IMPERSONATION, 0);
  532. goto done;
  533. }
  534. }
  535. except(EXCEPTION_EXECUTE_HANDLER)
  536. {
  537. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  538. }
  539. //
  540. // Build output buffer
  541. //
  542. pOutput->BufferType = SECBUFFER_DATA;
  543. pOutput->cbBuffer = sizeof(HLOCATOR);
  544. pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
  545. if(pOutput->pvBuffer == NULL)
  546. {
  547. scRet = SEC_E_INSUFFICIENT_MEMORY;
  548. goto done;
  549. }
  550. *(HLOCATOR *)(pOutput->pvBuffer) = hLocator;
  551. scRet = SEC_E_OK;
  552. done:
  553. if(pCredential)
  554. {
  555. CertFreeCertificateContext(pCredential);
  556. }
  557. if(pAuthority)
  558. {
  559. CertFreeCertificateContext(pAuthority);
  560. }
  561. return scRet;
  562. }
  563. SECURITY_STATUS
  564. WINAPI
  565. SslCloseLocator(
  566. HMAPPER * phMapper, // in
  567. HLOCATOR hLocator) // in
  568. {
  569. SecBuffer Input;
  570. SecBuffer Output;
  571. SECURITY_STATUS scRet;
  572. if(phMapper == NULL)
  573. {
  574. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  575. }
  576. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  577. {
  578. // System mapper.
  579. return phMapper->m_vtable->CloseLocator(phMapper,
  580. hLocator);
  581. }
  582. else
  583. {
  584. // Application mapper.
  585. Input.BufferType = SECBUFFER_DATA;
  586. Input.cbBuffer = 0;
  587. Input.pvBuffer = NULL;
  588. scRet = PerformApplicationCallback( SCH_CLOSE_LOCATOR_CALLBACK,
  589. (ULONG_PTR)phMapper->m_Reserved1,
  590. (ULONG_PTR)hLocator,
  591. &Input,
  592. &Output,
  593. FALSE);
  594. if(!NT_SUCCESS(scRet))
  595. {
  596. DebugLog((DEB_ERROR, "Error 0x%x closing locator\n", scRet));
  597. return scRet;
  598. }
  599. SP_ASSERT(Output.cbBuffer == 0);
  600. return scRet;
  601. }
  602. }
  603. //+---------------------------------------------------------------------------
  604. //
  605. // Function: CloseLocatorCallback
  606. //
  607. // Synopsis: Reference (or dereference) the application mapper.
  608. //
  609. // Arguments: [hLocator] -- Handle to locator.
  610. // [dwArg2] -- Not used.
  611. // [pInput] -- HMAPPER structure.
  612. // [pOutput] -- Not used.
  613. //
  614. // History: 12-28-97 jbanes Created
  615. //
  616. // Notes:
  617. //
  618. //----------------------------------------------------------------------------
  619. SECURITY_STATUS
  620. CloseLocatorCallback(
  621. ULONG_PTR Mapper,
  622. ULONG_PTR hLocator,
  623. SecBuffer *pInput,
  624. SecBuffer *pOutput)
  625. {
  626. HMAPPER *phMapper;
  627. SECURITY_STATUS Status;
  628. if(!SchannelInit(TRUE))
  629. {
  630. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  631. }
  632. DebugLog((DEB_TRACE, "CloseLocatorCallback\n"));
  633. phMapper = (HMAPPER *)Mapper;
  634. // Close the locator.
  635. try
  636. {
  637. Status = phMapper->m_vtable->CloseLocator(phMapper, hLocator);
  638. }
  639. except(EXCEPTION_EXECUTE_HANDLER)
  640. {
  641. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  642. }
  643. // Build output buffer
  644. pOutput->BufferType = SECBUFFER_DATA;
  645. pOutput->cbBuffer = 0;
  646. pOutput->pvBuffer = NULL;
  647. return Status;
  648. }
  649. SECURITY_STATUS
  650. WINAPI
  651. SslQueryMappedCredentialAttributes(
  652. HMAPPER * phMapper, // in
  653. HLOCATOR hLocator, // in
  654. DWORD dwAttribute, // in
  655. PVOID * ppBuffer) // out
  656. {
  657. SecBuffer Input;
  658. SecBuffer Output;
  659. SECURITY_STATUS scRet;
  660. if(phMapper == NULL)
  661. {
  662. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  663. }
  664. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  665. {
  666. // System mapper.
  667. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  668. }
  669. else
  670. {
  671. // Application mapper.
  672. Input.BufferType = SECBUFFER_DATA;
  673. Input.cbBuffer = sizeof(DWORD);
  674. Input.pvBuffer = &dwAttribute;
  675. scRet = PerformApplicationCallback( SCH_GET_MAPPER_ATTRIBUTES_CALLBACK,
  676. (ULONG_PTR)phMapper->m_Reserved1,
  677. hLocator,
  678. &Input,
  679. &Output,
  680. TRUE);
  681. if(!NT_SUCCESS(scRet))
  682. {
  683. DebugLog((DEB_ERROR, "Error 0x%x querying mapped attribute.\n", scRet));
  684. return scRet;
  685. }
  686. if(Output.cbBuffer != sizeof(PVOID))
  687. {
  688. SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  689. }
  690. *ppBuffer = *(PVOID *)Output.pvBuffer;
  691. SPExternalFree(Output.pvBuffer); //this is allocated by SPExternalAlloc()
  692. return SEC_E_OK;
  693. }
  694. }
  695. //+---------------------------------------------------------------------------
  696. //
  697. // Function: QueryMappedCredAttributesCallback
  698. //
  699. // Synopsis: Queries the application mapper for the specified property.
  700. //
  701. // Arguments: [hLocator] -- Handle to locator.
  702. // [dwAttribute] -- Attribute to query.
  703. // [pInput] -- HMAPPER structure.
  704. // [pOutput] -- Pointer to attribute data (in the
  705. // application's address space).
  706. //
  707. // History: 03-16-98 jbanes Created
  708. //
  709. // Notes:
  710. //
  711. //----------------------------------------------------------------------------
  712. SECURITY_STATUS
  713. QueryMappedCredAttributesCallback(
  714. ULONG_PTR Mapper,
  715. ULONG_PTR hLocator,
  716. SecBuffer *pInput,
  717. SecBuffer *pOutput)
  718. {
  719. HMAPPER * phMapper;
  720. DWORD dwAttribute;
  721. PVOID pvBuffer;
  722. DWORD cbBuffer;
  723. DWORD Status;
  724. if(!SchannelInit(TRUE))
  725. {
  726. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  727. }
  728. DebugLog((DEB_TRACE, "QueryMappedCredAttributesCallback\n"));
  729. phMapper = (HMAPPER *)Mapper;
  730. // Parse input buffer
  731. SP_ASSERT(pInput->cbBuffer == sizeof(DWORD));
  732. dwAttribute = *(DWORD *)pInput->pvBuffer;
  733. // Query propery.
  734. try
  735. {
  736. // Determine buffer size.
  737. Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
  738. phMapper,
  739. hLocator,
  740. dwAttribute,
  741. NULL,
  742. &cbBuffer);
  743. if(FAILED(Status))
  744. {
  745. return SP_LOG_RESULT(Status);
  746. }
  747. // Allocate memory. This gets freed by the APPLICATION with FreeSecurityBuffer() call
  748. // SPExternalAlloc() for the above reason!!!!
  749. pvBuffer = SPExternalAlloc(cbBuffer);
  750. if(pvBuffer == NULL)
  751. {
  752. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  753. }
  754. // Read propery.
  755. Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
  756. phMapper,
  757. hLocator,
  758. dwAttribute,
  759. pvBuffer,
  760. &cbBuffer);
  761. if(FAILED(Status))
  762. {
  763. SPExternalFree(pvBuffer);
  764. return SP_LOG_RESULT(Status);
  765. }
  766. }
  767. except(EXCEPTION_EXECUTE_HANDLER)
  768. {
  769. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  770. }
  771. // Build output buffer
  772. pOutput->BufferType = SECBUFFER_DATA;
  773. pOutput->cbBuffer = sizeof(PVOID);
  774. pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
  775. if(pOutput->pvBuffer == NULL)
  776. {
  777. SPExternalFree(pvBuffer);
  778. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  779. }
  780. *(PVOID *)(pOutput->pvBuffer) = pvBuffer;
  781. return SEC_E_OK;
  782. }