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.

849 lines
22 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: ctxtapi.c
  8. //
  9. // Contents: Context APIs to the SPMgr.
  10. // - LsaInitContext
  11. // - LsaAcceptContext
  12. // - LsaFinalizeContext
  13. // - LsaMapContext
  14. //
  15. // And WLsa functions
  16. //
  17. // History: 20 May 92 RichardW Commented existing code
  18. //
  19. //------------------------------------------------------------------------
  20. #include <lsapch.hxx>
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Function: WLsaInitContext
  24. //
  25. // Synopsis: Worker that maps the call to the appropriate package
  26. //
  27. // Effects:
  28. //
  29. // Arguments: [phCredential] --
  30. // [phContext] --
  31. // [pTarget] --
  32. // [fContextReq] --
  33. // [dwReserved1] --
  34. // [TargetDataRep] --
  35. // [pInput] --
  36. // [dwReserved2] --
  37. // [phNewContext] --
  38. // [pOutput] --
  39. // [pfContextAttr] --
  40. // [ptsExpiry] --
  41. // [MappedContext] --
  42. // [ContextData] --
  43. //
  44. // Requires:
  45. //
  46. // Returns:
  47. //
  48. // History: 9-24-96 RichardW Created
  49. //
  50. // Notes:
  51. //
  52. //----------------------------------------------------------------------------
  53. NTSTATUS
  54. WLsaInitContext( PCredHandle phCredential,
  55. PCtxtHandle phContext,
  56. PSECURITY_STRING pTarget,
  57. DWORD fContextReq,
  58. DWORD dwReserved1,
  59. DWORD TargetDataRep,
  60. PSecBufferDesc pInput,
  61. DWORD dwReserved2,
  62. PCtxtHandle phNewContext,
  63. PSecBufferDesc pOutput,
  64. DWORD * pfContextAttr,
  65. PTimeStamp ptsExpiry,
  66. PBOOLEAN MappedContext,
  67. PSecBuffer ContextData )
  68. {
  69. NTSTATUS scRet;
  70. PLSAP_SECURITY_PACKAGE pspPackage;
  71. PSession pSession = GetCurrentSession();
  72. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  73. PVOID ContextKey = NULL ;
  74. PVOID CredKey = NULL ;
  75. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaInitContext(%p : %p, %p : %p, %ws)\n",
  76. pSession->dwProcessID,
  77. phCredential->dwUpper,
  78. phCredential->dwLower,
  79. phContext->dwUpper,
  80. phContext->dwLower,
  81. pTarget->Buffer));
  82. #if DBG
  83. if ( pInput && pInput->cBuffers )
  84. {
  85. DsysAssert( (ULONG_PTR) pInput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
  86. }
  87. if ( pOutput && pOutput->cBuffers )
  88. {
  89. DsysAssert( (ULONG_PTR) pOutput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
  90. }
  91. #endif
  92. //
  93. // Reset the new handle to a known, invalid state
  94. //
  95. phNewContext->dwLower = SPMGR_ID;
  96. phNewContext->dwUpper = 0;
  97. //
  98. // Check handles against the session to make sure they're valid. If the
  99. // context handle is valid, we use that, otherwise the credential.
  100. //
  101. scRet = ValidateContextHandle(
  102. pSession,
  103. phContext,
  104. &ContextKey );
  105. if ( NT_SUCCESS( scRet ) )
  106. {
  107. pspPackage = SpmpValidRequest( phContext->dwLower,
  108. SP_ORDINAL_INITLSAMODECTXT );
  109. //
  110. // Tricky stuff: if the context handle is valid, but does not
  111. // come from the same package as the credential, null out the cred
  112. // handle:
  113. //
  114. if ( phCredential->dwLower != phContext->dwLower )
  115. {
  116. phCredential->dwLower = 0;
  117. phCredential->dwUpper = 0;
  118. }
  119. LsapLogCallInfo( CallInfo, pSession, *phContext );
  120. }
  121. else
  122. {
  123. LsapLogCallInfo( CallInfo, pSession, *phCredential );
  124. scRet = ValidateCredHandle(
  125. pSession,
  126. phCredential,
  127. &CredKey );
  128. if ( NT_SUCCESS( scRet ) )
  129. {
  130. pspPackage = SpmpValidRequest( phCredential->dwLower,
  131. SP_ORDINAL_INITLSAMODECTXT );
  132. }
  133. else
  134. {
  135. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  136. return( SEC_E_INVALID_HANDLE );
  137. }
  138. }
  139. if ( !pspPackage )
  140. {
  141. if ( ContextKey )
  142. {
  143. DerefContextHandle( pSession, NULL, ContextKey );
  144. }
  145. if ( CredKey )
  146. {
  147. DerefCredHandle( pSession, NULL, CredKey );
  148. }
  149. return( SEC_E_INVALID_HANDLE );
  150. }
  151. SetCurrentPackageId( pspPackage->dwPackageID );
  152. StartCallToPackage( pspPackage );
  153. DebugLog((DEB_TRACE_VERB, "\tContext Req = 0x%08x\n", fContextReq));
  154. DebugLog((DEB_TRACE_VERB, "\tPackage = %ws\n", pspPackage->Name.Buffer));
  155. __try
  156. {
  157. scRet = pspPackage->FunctionTable.InitLsaModeContext(
  158. phCredential->dwUpper,
  159. phContext->dwUpper,
  160. pTarget,
  161. fContextReq,
  162. TargetDataRep,
  163. pInput,
  164. &phNewContext->dwUpper,
  165. pOutput,
  166. pfContextAttr,
  167. ptsExpiry,
  168. MappedContext,
  169. ContextData );
  170. }
  171. __except (SP_EXCEPTION)
  172. {
  173. scRet = GetExceptionCode();
  174. scRet = SPException(scRet, pspPackage->dwPackageID);
  175. }
  176. EndCallToPackage( pspPackage );
  177. DebugLog((DEB_TRACE_WAPI, "InitResult = %x\n", scRet));
  178. DebugLog((DEB_TRACE_VERB, "\tFlags = %08x\n", *pfContextAttr));
  179. //
  180. // Only add a new context if the old one didn't exist.
  181. // Otherwise copy the old context over the new context.
  182. //
  183. if ( NT_SUCCESS( scRet ) )
  184. {
  185. if ( (phNewContext->dwUpper != 0) &&
  186. (phNewContext->dwUpper != phContext->dwUpper) )
  187. {
  188. //
  189. // If the package ID is unchanged, set it to the current package
  190. // id. This is so that if package changes the ID through
  191. // LsapChangeHandle, we can catch it.
  192. //
  193. if ( phNewContext->dwLower == SPMGR_ID )
  194. {
  195. phNewContext->dwLower = pspPackage->dwPackageID ;
  196. if(!AddContextHandle( pSession, phNewContext, 0 ))
  197. {
  198. DebugLog(( DEB_ERROR, "Failed adding context handle %p:%p to session %p\n",
  199. phNewContext->dwUpper, phNewContext->dwLower,
  200. pSession ));
  201. pspPackage = SpmpValidRequest(
  202. phNewContext->dwLower,
  203. SP_ORDINAL_DELETECTXT
  204. );
  205. if( pspPackage )
  206. {
  207. //
  208. // remove the handle from the underlying package.
  209. //
  210. StartCallToPackage( pspPackage );
  211. __try
  212. {
  213. pspPackage->FunctionTable.DeleteContext(
  214. phNewContext->dwUpper
  215. );
  216. }
  217. __except (SP_EXCEPTION)
  218. {
  219. NOTHING;
  220. }
  221. EndCallToPackage( pspPackage );
  222. }
  223. phNewContext->dwLower = 0;
  224. phNewContext->dwUpper = 0;
  225. scRet = SEC_E_INSUFFICIENT_MEMORY;
  226. }
  227. }
  228. }
  229. else
  230. {
  231. *phNewContext = *phContext;
  232. }
  233. }
  234. else
  235. {
  236. *phNewContext = *phContext ;
  237. }
  238. DebugLog(( DEB_TRACE_WAPI, "Init New Context = %p : %p to session %p\n",
  239. phNewContext->dwUpper , phNewContext->dwLower, pSession ));
  240. SetCurrentPackageId( SPMGR_ID );
  241. if ( ContextKey )
  242. {
  243. DerefContextHandle( pSession, NULL, ContextKey );
  244. }
  245. if ( CredKey )
  246. {
  247. DerefCredHandle( pSession, NULL, CredKey );
  248. }
  249. return(scRet);
  250. }
  251. //+-------------------------------------------------------------------------
  252. //
  253. // Function: WLsaAcceptContext()
  254. //
  255. // Synopsis: Worker function for AcceptSecurityContext()
  256. //
  257. // Effects: Creates a server-side security context
  258. //
  259. // Arguments: See LsaAcceptContext()
  260. //
  261. // Requires:
  262. //
  263. // Returns:
  264. //
  265. // Notes:
  266. //
  267. //--------------------------------------------------------------------------
  268. NTSTATUS
  269. WLsaAcceptContext( PCredHandle phCredential,
  270. PCtxtHandle phContext,
  271. PSecBufferDesc pInput,
  272. DWORD fContextReq,
  273. DWORD TargetDataRep,
  274. PCtxtHandle phNewContext,
  275. PSecBufferDesc pOutput,
  276. DWORD * pfContextAttr,
  277. PTimeStamp ptsExpiry,
  278. PBOOLEAN MappedContext,
  279. PSecBuffer ContextData)
  280. {
  281. NTSTATUS scRet;
  282. PLSAP_SECURITY_PACKAGE pspPackage;
  283. PSession pSession;
  284. PVOID ContextKey = NULL ;
  285. PVOID CredKey = NULL ;
  286. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  287. //
  288. // Clear out the handle
  289. //
  290. phNewContext->dwLower = SPMGR_ID;
  291. phNewContext->dwUpper = 0;
  292. #if DBG
  293. if ( pInput && pInput->cBuffers )
  294. {
  295. DsysAssert( (ULONG_PTR) pInput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
  296. }
  297. if ( pOutput && pOutput->cBuffers )
  298. {
  299. DsysAssert( (ULONG_PTR) pOutput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
  300. }
  301. #endif
  302. //
  303. // Get our session
  304. //
  305. pSession = GetCurrentSession();
  306. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaAcceptContext(%p : %p)\n",
  307. pSession->dwProcessID,
  308. phCredential->dwUpper, phCredential->dwLower));
  309. //
  310. // Check handles against the session to make sure they're valid. If the
  311. // context handle is valid, we use that, otherwise the credential.
  312. //
  313. scRet = ValidateContextHandle(
  314. pSession,
  315. phContext,
  316. &ContextKey );
  317. if ( NT_SUCCESS( scRet ) )
  318. {
  319. pspPackage = SpmpValidRequest( phContext->dwLower,
  320. SP_ORDINAL_ACCEPTLSAMODECTXT );
  321. //
  322. // Tricky stuff: if the context handle is valid, but does not
  323. // come from the same package as the credential, null out the cred
  324. // handle:
  325. //
  326. if ( phCredential->dwLower != phContext->dwLower )
  327. {
  328. phCredential->dwLower = 0;
  329. phCredential->dwUpper = 0;
  330. }
  331. LsapLogCallInfo( CallInfo, pSession, *phContext );
  332. }
  333. else
  334. {
  335. LsapLogCallInfo( CallInfo, pSession, *phCredential );
  336. scRet = ValidateCredHandle(
  337. pSession,
  338. phCredential,
  339. &CredKey );
  340. if ( NT_SUCCESS( scRet ) )
  341. {
  342. pspPackage = SpmpValidRequest( phCredential->dwLower,
  343. SP_ORDINAL_ACCEPTLSAMODECTXT );
  344. }
  345. else
  346. {
  347. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  348. return( SEC_E_INVALID_HANDLE );
  349. }
  350. }
  351. if ( !pspPackage )
  352. {
  353. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  354. if ( ContextKey )
  355. {
  356. DerefContextHandle( pSession, NULL, ContextKey );
  357. }
  358. if ( CredKey )
  359. {
  360. DerefCredHandle( pSession, NULL, CredKey );
  361. }
  362. return( SEC_E_INVALID_HANDLE );
  363. }
  364. SetCurrentPackageId( pspPackage->dwPackageID );
  365. StartCallToPackage( pspPackage );
  366. __try
  367. {
  368. scRet = pspPackage->FunctionTable.AcceptLsaModeContext(
  369. phCredential->dwUpper,
  370. phContext->dwUpper,
  371. pInput,
  372. fContextReq,
  373. TargetDataRep,
  374. &phNewContext->dwUpper,
  375. pOutput,
  376. pfContextAttr,
  377. ptsExpiry,
  378. MappedContext,
  379. ContextData );
  380. }
  381. __except (SP_EXCEPTION)
  382. {
  383. scRet = GetExceptionCode();
  384. scRet = SPException(scRet, pspPackage->dwPackageID);
  385. }
  386. EndCallToPackage( pspPackage );
  387. DebugLog((DEB_TRACE_WAPI, "[%x] Result = %x\n", pSession->dwProcessID, scRet));
  388. //
  389. // Only add a new context if the old one didn't exist.
  390. // Otherwise copy the old context over the new context.
  391. //
  392. if ( NT_SUCCESS( scRet ) || ( scRet == SEC_E_INCOMPLETE_MESSAGE ) )
  393. {
  394. if ( (phNewContext->dwUpper != 0) &&
  395. (phNewContext->dwUpper != phContext->dwUpper) )
  396. {
  397. //
  398. // If the package ID is unchanged, set it to the current package
  399. // id. This is so that if package changes the ID through
  400. //
  401. if ( phNewContext->dwLower == SPMGR_ID )
  402. {
  403. phNewContext->dwLower = pspPackage->dwPackageID ;
  404. if(!AddContextHandle( pSession, phNewContext, 0 ))
  405. {
  406. DebugLog(( DEB_ERROR, "Failed adding context handle %p:%p to session %p\n",
  407. phNewContext->dwUpper, phNewContext->dwLower,
  408. pSession ));
  409. pspPackage = SpmpValidRequest(
  410. phNewContext->dwLower,
  411. SP_ORDINAL_DELETECTXT
  412. );
  413. if( pspPackage )
  414. {
  415. //
  416. // remove the handle from the underlying package.
  417. //
  418. StartCallToPackage( pspPackage );
  419. __try
  420. {
  421. pspPackage->FunctionTable.DeleteContext(
  422. phNewContext->dwUpper
  423. );
  424. }
  425. __except (SP_EXCEPTION)
  426. {
  427. NOTHING;
  428. }
  429. EndCallToPackage( pspPackage );
  430. }
  431. phNewContext->dwLower = 0;
  432. phNewContext->dwUpper = 0;
  433. scRet = SEC_E_INSUFFICIENT_MEMORY;
  434. }
  435. }
  436. }
  437. else
  438. {
  439. *phNewContext = *phContext;
  440. }
  441. }
  442. else
  443. {
  444. *phNewContext = *phContext ;
  445. }
  446. DebugLog(( DEB_TRACE_WAPI, "Accept new context = %p : %p \n",
  447. phNewContext->dwUpper, phNewContext->dwLower ));
  448. SetCurrentPackageId( SPMGR_ID );
  449. if ( ContextKey )
  450. {
  451. DerefContextHandle( pSession, NULL, ContextKey );
  452. }
  453. if ( CredKey )
  454. {
  455. DerefCredHandle( pSession, NULL, CredKey );
  456. }
  457. return(scRet);
  458. }
  459. //+-------------------------------------------------------------------------
  460. //
  461. // Function: WLsaDeleteContext
  462. //
  463. // Synopsis: Worker function for deleting a context
  464. //
  465. // Effects:
  466. //
  467. // Arguments:
  468. //
  469. // Requires:
  470. //
  471. // Returns:
  472. //
  473. // Notes:
  474. //
  475. //--------------------------------------------------------------------------
  476. NTSTATUS
  477. WLsaDeleteContext( PCtxtHandle phContext)
  478. {
  479. NTSTATUS scRet;
  480. PSession pSession = GetCurrentSession();
  481. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  482. DebugLog((DEB_TRACE_WAPI, "[%x] WDeleteContext(%p : %p)\n",
  483. pSession->dwProcessID,
  484. phContext->dwUpper, phContext->dwLower));
  485. scRet = ValidateAndDerefContextHandle(
  486. pSession,
  487. phContext );
  488. if ( (CallInfo->Flags & CALL_FLAG_NO_HANDLE_CHK) == 0 )
  489. {
  490. if ( !NT_SUCCESS( scRet ) )
  491. {
  492. DebugLog((DEB_ERROR,"[%x] Invalid handle passed to DeleteContext: %p:%p\n",
  493. pSession->dwProcessID,
  494. phContext->dwUpper,phContext->dwLower));
  495. /// DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  496. }
  497. }
  498. LsapLogCallInfo( CallInfo, pSession, *phContext );
  499. if (SUCCEEDED(scRet))
  500. {
  501. phContext->dwUpper = phContext->dwLower = 0xFFFFFFFF;
  502. }
  503. return(scRet);
  504. }
  505. //+-------------------------------------------------------------------------
  506. //
  507. // Function: WLsaApplyControlToken
  508. //
  509. // Synopsis: Worker function for applying a control token
  510. //
  511. // Effects:
  512. //
  513. // Arguments:
  514. //
  515. // Requires:
  516. //
  517. // Returns:
  518. //
  519. // Notes:
  520. //
  521. //--------------------------------------------------------------------------
  522. NTSTATUS
  523. WLsaApplyControlToken( PCtxtHandle phContext,
  524. PSecBufferDesc pInput)
  525. {
  526. NTSTATUS scRet;
  527. PLSAP_SECURITY_PACKAGE pspPackage;
  528. PSession pSession = GetCurrentSession();
  529. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  530. PVOID ContextKey ;
  531. DebugLog((DEB_TRACE_WAPI, "[%x] WApplyControlToken(%p : %p)\n",
  532. pSession->dwProcessID,
  533. phContext->dwUpper, phContext->dwLower));
  534. LsapLogCallInfo( CallInfo, pSession, *phContext );
  535. scRet = ValidateContextHandle(
  536. pSession,
  537. phContext,
  538. &ContextKey );
  539. if ( !NT_SUCCESS( scRet ) )
  540. {
  541. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  542. return( scRet );
  543. }
  544. pspPackage = SpmpValidRequest( phContext->dwLower,
  545. SP_ORDINAL_APPLYCONTROLTOKEN);
  546. if ( !pspPackage )
  547. {
  548. return SEC_E_INVALID_HANDLE ;
  549. }
  550. SetCurrentPackageId(phContext->dwLower);
  551. StartCallToPackage( pspPackage );
  552. __try
  553. {
  554. scRet = pspPackage->FunctionTable.ApplyControlToken(
  555. phContext->dwUpper,
  556. pInput);
  557. }
  558. __except (SP_EXCEPTION)
  559. {
  560. scRet = GetExceptionCode();
  561. scRet = SPException(scRet, pspPackage->dwPackageID);
  562. }
  563. EndCallToPackage( pspPackage );
  564. SetCurrentPackageId( SPMGR_ID );
  565. DerefContextHandle( pSession, NULL, ContextKey );
  566. return(scRet);
  567. }
  568. NTSTATUS
  569. WLsaQueryContextAttributes(
  570. PCtxtHandle phContext,
  571. ULONG ulAttribute,
  572. PVOID pvBuffer
  573. )
  574. {
  575. NTSTATUS scRet;
  576. PLSAP_SECURITY_PACKAGE pspPackage = NULL ;
  577. PSession pSession = GetCurrentSession();
  578. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  579. PVOID ContextKey ;
  580. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaQueryContextAttributes(%p : %p)\n",
  581. pSession->dwProcessID,
  582. phContext->dwUpper, phContext->dwLower));
  583. LsapLogCallInfo( CallInfo, pSession, *phContext );
  584. scRet = ValidateContextHandle(
  585. pSession,
  586. phContext,
  587. &ContextKey );
  588. if ( NT_SUCCESS( scRet ) )
  589. {
  590. pspPackage = SpmpValidRequest( phContext->dwLower,
  591. SP_ORDINAL_QUERYCONTEXTATTRIBUTES);
  592. }
  593. if (( !pspPackage ) ||
  594. !NT_SUCCESS( scRet ) )
  595. {
  596. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  597. return(SEC_E_INVALID_HANDLE);
  598. }
  599. StartCallToPackage( pspPackage );
  600. SetCurrentPackageId(phContext->dwLower);
  601. __try
  602. {
  603. scRet = pspPackage->FunctionTable.QueryContextAttributes(
  604. phContext->dwUpper,
  605. ulAttribute,
  606. pvBuffer );
  607. }
  608. __except (SP_EXCEPTION)
  609. {
  610. scRet = GetExceptionCode();
  611. scRet = SPException(scRet, pspPackage->dwPackageID);
  612. }
  613. EndCallToPackage( pspPackage );
  614. SetCurrentPackageId( SPMGR_ID );
  615. DerefContextHandle( pSession, NULL, ContextKey );
  616. return(scRet);
  617. }
  618. NTSTATUS
  619. WLsaSetContextAttributes(
  620. PCtxtHandle phContext,
  621. ULONG ulAttribute,
  622. PVOID pvBuffer,
  623. ULONG cbBuffer
  624. )
  625. {
  626. NTSTATUS scRet;
  627. PLSAP_SECURITY_PACKAGE pspPackage = NULL ;
  628. PSession pSession = GetCurrentSession();
  629. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  630. PVOID ContextKey ;
  631. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaSetContextAttributes(%p : %p)\n",
  632. pSession->dwProcessID,
  633. phContext->dwUpper, phContext->dwLower));
  634. LsapLogCallInfo( CallInfo, pSession, *phContext );
  635. scRet = ValidateContextHandle(
  636. pSession,
  637. phContext,
  638. &ContextKey );
  639. if ( NT_SUCCESS( scRet ) )
  640. {
  641. pspPackage = SpmpValidRequest( phContext->dwLower,
  642. SP_ORDINAL_SETCONTEXTATTRIBUTES);
  643. }
  644. if (( !pspPackage ) ||
  645. !NT_SUCCESS( scRet ) )
  646. {
  647. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  648. return(SEC_E_INVALID_HANDLE);
  649. }
  650. StartCallToPackage( pspPackage );
  651. SetCurrentPackageId(phContext->dwLower);
  652. __try
  653. {
  654. scRet = pspPackage->FunctionTable.SetContextAttributes(
  655. phContext->dwUpper,
  656. ulAttribute,
  657. pvBuffer,
  658. cbBuffer );
  659. }
  660. __except (SP_EXCEPTION)
  661. {
  662. scRet = GetExceptionCode();
  663. scRet = SPException(scRet, pspPackage->dwPackageID);
  664. }
  665. EndCallToPackage( pspPackage );
  666. SetCurrentPackageId( SPMGR_ID );
  667. DerefContextHandle( pSession, NULL, ContextKey );
  668. return(scRet);
  669. }