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.

2659 lines
64 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: sputil.c
  8. //
  9. // Contents: Security package utility functions. Functions for maintaining
  10. // the list of available packages are kept here.
  11. //
  12. //
  13. //
  14. // History: 9 Dec 91, richardw Created
  15. // 11 Mar 92, RichardW Recreated, reworked, etc.
  16. // 21 Mar 94, MikeSw Removed RPC stubs
  17. //
  18. //------------------------------------------------------------------------
  19. #include <lsapch.hxx>
  20. extern "C"
  21. {
  22. #include "sesmgr.h"
  23. #include <stddef.h>
  24. }
  25. //
  26. // Global variables and structures:
  27. //
  28. //
  29. // Debug stuff:
  30. //
  31. #if DBG
  32. ULONG NoUnload = 0;
  33. #endif
  34. extern WCHAR szLsaPath[] ;
  35. RTL_RESOURCE PackageListLock;
  36. PDLL_BINDING * pPackageDllList;
  37. ULONG PackageDllCount;
  38. ULONG PackageDllTotal;
  39. PLSAP_SECURITY_PACKAGE * pPackageControlList;
  40. ULONG PackageControlCount;
  41. ULONG PackageControlTotal;
  42. #define INITIAL_PACKAGE_DLL_SIZE 8
  43. #define INITIAL_PACKAGE_CONTROL_SIZE 8
  44. #define ReadLockPackageList() RtlAcquireResourceShared(&PackageListLock, TRUE)
  45. #define WriteLockPackageList() RtlAcquireResourceExclusive(&PackageListLock, TRUE)
  46. #define UnlockPackageList() RtlReleaseResource(&PackageListLock)
  47. PDLL_BINDING
  48. SpmpFindDll(
  49. PWSTR DllName);
  50. //+---------------------------------------------------------------------------
  51. //
  52. // Function: BindOldPackage
  53. //
  54. // Synopsis: Loads an old style authentication package DLL
  55. //
  56. // Arguments: [hDll] --
  57. // [pTable] --
  58. //
  59. // History: 11-17-95 RichardW Created
  60. //
  61. // Notes:
  62. //
  63. //----------------------------------------------------------------------------
  64. BOOL
  65. BindOldPackage( HANDLE hDll,
  66. PSECPKG_FUNCTION_TABLE pTable)
  67. {
  68. pTable->InitializePackage = (PLSA_AP_INITIALIZE_PACKAGE)
  69. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_INITIALIZE_PACKAGE);
  70. if (pTable->InitializePackage == NULL)
  71. {
  72. return(FALSE);
  73. }
  74. //
  75. // The package needs to support one of LogonUser, LogonUserEx, or LogonUserEx2
  76. pTable->LogonUserEx2 = (PLSA_AP_LOGON_USER_EX2)
  77. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER_EX2);
  78. //
  79. // If this is NULL, then the package should have exported a LsaApLogonUser or Ex
  80. //
  81. if (pTable->LogonUserEx2 == NULL)
  82. {
  83. pTable->LogonUserEx = (PLSA_AP_LOGON_USER_EX)
  84. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER_EX);
  85. if (pTable->LogonUserEx == NULL)
  86. {
  87. pTable->LogonUser = (PLSA_AP_LOGON_USER)
  88. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER);
  89. if (pTable->LogonUser == NULL)
  90. {
  91. return(FALSE);
  92. }
  93. }
  94. }
  95. pTable->CallPackage = (PLSA_AP_CALL_PACKAGE)
  96. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE);
  97. if (pTable->CallPackage == NULL)
  98. {
  99. return(FALSE);
  100. }
  101. //
  102. // CallPackageUntrusted is optional
  103. //
  104. pTable->CallPackageUntrusted = (PLSA_AP_CALL_PACKAGE_UNTRUSTED)
  105. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE_UNTRUSTED);
  106. pTable->CallPackagePassthrough = (PLSA_AP_CALL_PACKAGE_PASSTHROUGH)
  107. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE_PASSTHROUGH);
  108. pTable->LogonTerminated = (PLSA_AP_LOGON_TERMINATED)
  109. GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_TERMINATED);
  110. if (pTable->LogonTerminated == NULL)
  111. {
  112. return(FALSE);
  113. }
  114. //
  115. // If the package supports accept credentials, great. Otherwise
  116. // just leave this blank.
  117. //
  118. pTable->AcceptCredentials = (SpAcceptCredentialsFn *)
  119. GetProcAddress((HMODULE) hDll, SP_ACCEPT_CREDENTIALS_NAME);
  120. return(TRUE);
  121. }
  122. //+-------------------------------------------------------------------------
  123. //
  124. // Function: WLsaEnumeratePackages()
  125. //
  126. // Synopsis: Worker function for LsaEnumeratePackages
  127. //
  128. // Effects: Fills in an array of SecPkgInfo structures
  129. //
  130. // Arguments: pcEntries - receives the number of packages
  131. //
  132. // pPackages - receives all the SecPkgInfo structures
  133. //
  134. // Requires:
  135. //
  136. // Returns: success
  137. //
  138. // Notes:
  139. //
  140. //--------------------------------------------------------------------------
  141. static LPWSTR szInvalidPackage = L"Invalid Package";
  142. NTSTATUS
  143. WLsaEnumeratePackages( PULONG pcEntries,
  144. PSecPkgInfo * pPackages)
  145. {
  146. unsigned int i;
  147. PSession pSession = GetCurrentSession();
  148. ULONG cbSize;
  149. PSecPkgInfo pInfo;
  150. PSecPkgInfo pLocalInfo = NULL, pClientInfo = NULL;
  151. LONG cbMark, cbLength;
  152. NTSTATUS scRet;
  153. PLSAP_SECURITY_PACKAGE pPackage;
  154. PLSA_CALL_INFO CallInfo ;
  155. ULONG Filter ;
  156. Filter = SP_ORDINAL_GETINFO ;
  157. CallInfo = LsapGetCurrentCall();
  158. if ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT )
  159. {
  160. Filter |= SP_ITERATE_FILTER_WOW ;
  161. }
  162. cbSize = sizeof(SecPkgInfo) * lsState.cPackages;
  163. pInfo = (PSecPkgInfo) LsapAllocateLsaHeap(cbSize);
  164. if (!pInfo)
  165. {
  166. return(SEC_E_INSUFFICIENT_MEMORY);
  167. }
  168. pPackage = SpmpIteratePackagesByRequest( NULL, Filter );
  169. i = 0;
  170. while (pPackage)
  171. {
  172. SetCurrentPackageId( pPackage->dwPackageID );
  173. __try
  174. {
  175. (VOID) pPackage->FunctionTable.GetInfo( &pInfo[i] );
  176. cbSize += (wcslen(pInfo[i].Name) + 1) * sizeof(WCHAR);
  177. cbSize += (wcslen(pInfo[i].Comment) + 1) * sizeof(WCHAR);
  178. }
  179. __except (SP_EXCEPTION)
  180. {
  181. SPException( GetExceptionCode(), pPackage->dwPackageID );
  182. //
  183. // Catch it, kill the package, proceed...
  184. //
  185. }
  186. pPackage = SpmpIteratePackagesByRequest( pPackage,
  187. Filter );
  188. i ++;
  189. }
  190. *pcEntries = i;
  191. pLocalInfo = (PSecPkgInfo) LsapAllocateLsaHeap(cbSize);
  192. if (!pLocalInfo)
  193. {
  194. scRet = SEC_E_INSUFFICIENT_MEMORY;
  195. goto Cleanup;
  196. }
  197. pClientInfo = (PSecPkgInfo) LsapClientAllocate(cbSize);
  198. if (!pClientInfo)
  199. {
  200. scRet = SEC_E_INSUFFICIENT_MEMORY;
  201. goto Cleanup;
  202. }
  203. //
  204. // Compute the offset to adjust the pointers by
  205. //
  206. cbMark = *pcEntries * sizeof(SecPkgInfo);
  207. RtlCopyMemory(pLocalInfo,pInfo,cbMark);
  208. for (i = 0; i < *pcEntries ; i++ )
  209. {
  210. cbLength = (wcslen(pInfo[i].Name)+1)*sizeof(WCHAR);
  211. RtlCopyMemory(
  212. (PBYTE) pLocalInfo + cbMark,
  213. pInfo[i].Name,
  214. cbLength);
  215. pLocalInfo[i].Name = (LPWSTR) ((PBYTE) pClientInfo + cbMark);
  216. cbMark += cbLength;
  217. cbLength = (wcslen(pInfo[i].Comment)+1)*sizeof(WCHAR);
  218. RtlCopyMemory(
  219. (PBYTE) pLocalInfo + cbMark,
  220. pInfo[i].Comment,
  221. cbLength);
  222. pLocalInfo[i].Comment = (LPWSTR) ((PBYTE) pClientInfo + cbMark);
  223. cbMark += cbLength;
  224. }
  225. SetCurrentPackageId( SPMGR_ID );
  226. scRet = LsapCopyToClient(pLocalInfo,pClientInfo,cbSize);
  227. if (SUCCEEDED(scRet))
  228. {
  229. *pPackages = pClientInfo;
  230. }
  231. Cleanup:
  232. if (pLocalInfo != NULL)
  233. {
  234. LsapFreeLsaHeap(pLocalInfo);
  235. }
  236. if (FAILED(scRet) && (pClientInfo != NULL))
  237. {
  238. LsapClientFree(pClientInfo);
  239. }
  240. if (pInfo != NULL)
  241. {
  242. LsapFreeLsaHeap(pInfo);
  243. }
  244. return(scRet);
  245. }
  246. //+-------------------------------------------------------------------------
  247. //
  248. // Function: WLsaGetBinding()
  249. //
  250. // Synopsis: Gets the full path/DLL name for a package, based on ID
  251. //
  252. // Effects:
  253. //
  254. // Arguments: dwPackageID - ID of the package the caller needs the path for
  255. // pssPackageName - returns the name of package caller
  256. //
  257. // pszModuleName - Receives the name of the package.
  258. //
  259. // Requires:
  260. //
  261. // Returns:
  262. //
  263. // Notes:
  264. //
  265. //--------------------------------------------------------------------------
  266. NTSTATUS
  267. WLsaGetBinding( ULONG_PTR dwPackageID,
  268. PSEC_PACKAGE_BINDING_INFO BindingInfo,
  269. PULONG TotalSize,
  270. PWSTR * Base)
  271. {
  272. PLSAP_SECURITY_PACKAGE pPackage;
  273. PWSTR Buffer;
  274. PLSA_CALL_INFO CallInfo ;
  275. PSECURITY_STRING DllPath ;
  276. SECURITY_STRING NullString = { 0 };
  277. ZeroMemory( BindingInfo, sizeof( SEC_PACKAGE_BINDING_INFO ) );
  278. pPackage = SpmpValidateHandle(dwPackageID);
  279. CallInfo = LsapGetCurrentCall();
  280. if ( (pPackage != NULL ) &&
  281. ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT ) != 0 )
  282. {
  283. //
  284. // If this is a WOW client, only return bindings for the packages
  285. // that support WOW clients.
  286. //
  287. if ( ( pPackage->fPackage & SP_WOW_SUPPORT ) == 0 )
  288. {
  289. pPackage = NULL ;
  290. }
  291. }
  292. if (pPackage)
  293. {
  294. //
  295. // Easy stuff:
  296. //
  297. BindingInfo->fCapabilities = pPackage->fCapabilities;
  298. BindingInfo->PackageIndex = pPackage->PackageIndex ;
  299. BindingInfo->Version = pPackage->Version ;
  300. BindingInfo->RpcId = pPackage->dwRPCID ;
  301. BindingInfo->TokenSize = pPackage->TokenSize ;
  302. if (pPackage->fPackage & SPM_AUTH_PKG_FLAG)
  303. {
  304. BindingInfo->Flags = PACKAGEINFO_AUTHPKG;
  305. //
  306. // Old style package: no remote binding
  307. //
  308. return( SEC_E_INVALID_HANDLE );
  309. }
  310. DllPath = &pPackage->pBinding->Filename ;
  311. if ( pPackage->pBinding->Flags & DLL_BUILTIN )
  312. {
  313. BindingInfo->Flags = PACKAGEINFO_BUILTIN ;
  314. DllPath = &NullString ;
  315. }
  316. if ( pPackage->pBinding->Flags & DLL_SIGNED )
  317. {
  318. BindingInfo->Flags |= PACKAGEINFO_SIGNED ;
  319. }
  320. if ( ( pPackage->fPackage & SP_WOW_SUPPORT ) &&
  321. ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT ) )
  322. {
  323. DllPath = &pPackage->WowClientDll ;
  324. }
  325. //
  326. // If context thunks are present, copy them in:
  327. //
  328. if ( pPackage->Thunks )
  329. {
  330. BindingInfo->ContextThunksCount =
  331. pPackage->Thunks->Info.ContextThunks.InfoLevelCount ;
  332. if ( pPackage->Thunks->Info.ContextThunks.InfoLevelCount <
  333. PACKAGEINFO_THUNKS )
  334. {
  335. CopyMemory( BindingInfo->ContextThunks,
  336. pPackage->Thunks->Info.ContextThunks.Levels,
  337. BindingInfo->ContextThunksCount * sizeof(DWORD) );
  338. }
  339. else
  340. {
  341. CopyMemory( BindingInfo->ContextThunks,
  342. pPackage->Thunks->Info.ContextThunks.Levels,
  343. PACKAGEINFO_THUNKS * sizeof( DWORD ) );
  344. }
  345. }
  346. else
  347. {
  348. BindingInfo->ContextThunksCount = 0 ;
  349. }
  350. //
  351. // Compute Sizes:
  352. //
  353. *TotalSize = pPackage->Name.Length + 2 +
  354. pPackage->Comment.Length + 2 +
  355. DllPath->Length + 2 ;
  356. Buffer = (PWSTR) LsapAllocateLsaHeap( *TotalSize );
  357. if ( !Buffer )
  358. {
  359. return( SEC_E_INSUFFICIENT_MEMORY );
  360. }
  361. BindingInfo->PackageName.Buffer = Buffer ;
  362. BindingInfo->PackageName.Length = pPackage->Name.Length ;
  363. BindingInfo->PackageName.MaximumLength = pPackage->Name.Length + 2;
  364. CopyMemory( BindingInfo->PackageName.Buffer,
  365. pPackage->Name.Buffer,
  366. BindingInfo->PackageName.MaximumLength );
  367. BindingInfo->Comment.Buffer = BindingInfo->PackageName.Buffer +
  368. BindingInfo->PackageName.MaximumLength / 2 ;
  369. BindingInfo->Comment.Length = pPackage->Comment.Length;
  370. BindingInfo->Comment.MaximumLength = BindingInfo->Comment.Length + 2;
  371. CopyMemory( BindingInfo->Comment.Buffer,
  372. pPackage->Comment.Buffer,
  373. BindingInfo->Comment.MaximumLength );
  374. if ( DllPath->Buffer )
  375. {
  376. BindingInfo->ModuleName.Buffer = BindingInfo->Comment.Buffer +
  377. BindingInfo->Comment.MaximumLength / 2;
  378. BindingInfo->ModuleName.Length = DllPath->Length;
  379. BindingInfo->ModuleName.MaximumLength = BindingInfo->ModuleName.Length + 2;
  380. CopyMemory( BindingInfo->ModuleName.Buffer,
  381. DllPath->Buffer,
  382. BindingInfo->ModuleName.MaximumLength );
  383. }
  384. *Base = Buffer ;
  385. return( SEC_E_OK );
  386. }
  387. return( SEC_E_INVALID_HANDLE );
  388. }
  389. //+---------------------------------------------------------------------------
  390. //
  391. // Function: LsapFindPackage
  392. //
  393. // Synopsis: Internal function for the security DLL to reference packages
  394. // by ID
  395. //
  396. // Arguments: [pPackage] -- name of package
  397. // [pdwPackageId] -- returned id
  398. //
  399. // Returns: STATUS_SUCCESS -- Package found
  400. // SEC_E_SECPKG_NOT_FOUND -- Package not found
  401. //
  402. // History: 5-26-93 RichardW Created
  403. //
  404. //----------------------------------------------------------------------------
  405. NTSTATUS
  406. WLsaFindPackage(PUNICODE_STRING pPackageName,
  407. ULONG_PTR * pdwPackageId)
  408. {
  409. PLSAP_SECURITY_PACKAGE pPackage;
  410. pPackage = SpmpLookupPackage(pPackageName);
  411. if (!pPackage)
  412. {
  413. *pdwPackageId = SPMGR_ID;
  414. return(SEC_E_SECPKG_NOT_FOUND);
  415. }
  416. else
  417. {
  418. *pdwPackageId = pPackage->dwPackageID;
  419. return(S_OK);
  420. }
  421. }
  422. //+---------------------------------------------------------------------------
  423. //
  424. // Function: WLsaAddPackage
  425. //
  426. // Synopsis: Adds a security package to the system
  427. //
  428. // Arguments: [PackageName] -- Package Name
  429. // [Options] -- Options
  430. //
  431. // History: 9-18-96 RichardW Created
  432. //
  433. // Notes:
  434. //
  435. //----------------------------------------------------------------------------
  436. NTSTATUS
  437. WLsaAddPackage(
  438. PSECURITY_STRING PackageName,
  439. PSECURITY_PACKAGE_OPTIONS Options)
  440. {
  441. SECPKG_PARAMETERS Parameters;
  442. PLSAP_SECURITY_PACKAGE Package;
  443. SECPKG_EVENT_PACKAGE_CHANGE Event;
  444. BOOL Success;
  445. SECURITY_STATUS scRet;
  446. PLSAPR_POLICY_DNS_DOMAIN_INFO DnsDomainInfo = NULL;
  447. HKEY hKey ;
  448. DebugLog(( DEB_TRACE, "Adding Package %ws\n", PackageName->Buffer ));
  449. //
  450. // Make sure the caller has the rights to do this by impersonating them,
  451. // then opening the registry key.
  452. //
  453. scRet = LsapImpersonateClient();
  454. if ( NT_SUCCESS( scRet ) )
  455. {
  456. int err ;
  457. err = RegOpenKeyEx(
  458. HKEY_LOCAL_MACHINE,
  459. szLsaPath,
  460. 0,
  461. KEY_READ | KEY_WRITE,
  462. &hKey );
  463. if ( err != 0 )
  464. {
  465. scRet = NtCurrentTeb()->LastStatusValue ;
  466. }
  467. else
  468. {
  469. RegCloseKey( hKey );
  470. }
  471. RevertToSelf();
  472. }
  473. if ( !NT_SUCCESS( scRet ) )
  474. {
  475. return scRet ;
  476. }
  477. //
  478. // Build up the initialization message, to give the packages a better idea
  479. // of what is going on, and reduce their later calls for the same info.
  480. //
  481. Parameters.MachineState = (ULONG) 0;
  482. Parameters.SetupMode = SetupPhase;
  483. //
  484. // Make sure we haven't been through this already:
  485. //
  486. if ( SpmpFindDll( PackageName->Buffer ) )
  487. {
  488. DebugLog(( DEB_TRACE, "AddPackage: DLL %ws already loaded\n", PackageName->Buffer ));
  489. return STATUS_SUCCESS ;
  490. }
  491. scRet = LsaIQueryInformationPolicyTrusted(
  492. PolicyDnsDomainInformation,
  493. (PLSAPR_POLICY_INFORMATION *) &DnsDomainInfo
  494. );
  495. if (!NT_SUCCESS(scRet))
  496. {
  497. DebugLog((DEB_ERROR,"Failed to get primary domain info: 0x%x\n",scRet));
  498. return(scRet);
  499. }
  500. Parameters.DomainName = * (PUNICODE_STRING) &DnsDomainInfo->Name;
  501. Parameters.DnsDomainName = * (PUNICODE_STRING) &DnsDomainInfo->DnsDomainName;
  502. Parameters.DomainSid = (PSID) DnsDomainInfo->Sid;
  503. DebugLog((DEB_TRACE_INIT, "Init Parameters = %d, %s\n",
  504. Parameters.MachineState,
  505. (Parameters.SetupMode ? "Setup" : "Normal") ));
  506. if (SpmpLoadDll( PackageName->Buffer, &Parameters ))
  507. {
  508. //
  509. // Successful Load! Update the registry!
  510. //
  511. if ( Options->Flags & SECPKG_OPTIONS_PERMANENT )
  512. {
  513. Success = AddPackageToRegistry( PackageName );
  514. }
  515. else
  516. {
  517. Success = TRUE ;
  518. }
  519. if ( !Success )
  520. {
  521. //
  522. // Unload it!
  523. //
  524. }
  525. }
  526. else
  527. {
  528. Success = FALSE ;
  529. }
  530. LsaIFree_LSAPR_POLICY_INFORMATION(
  531. PolicyDnsDomainInformation,
  532. (PLSAPR_POLICY_INFORMATION) DnsDomainInfo
  533. );
  534. if ( Success )
  535. {
  536. return( SEC_E_OK );
  537. }
  538. return( SEC_E_SECPKG_NOT_FOUND );
  539. }
  540. //+---------------------------------------------------------------------------
  541. //
  542. // Function: WLsaDeletePackage
  543. //
  544. // Synopsis: Delete a security package
  545. //
  546. // Arguments: [PackageName] --
  547. //
  548. // History: 9-18-96 RichardW Created
  549. //
  550. // Notes:
  551. //
  552. //----------------------------------------------------------------------------
  553. NTSTATUS
  554. WLsaDeletePackage(
  555. PSECURITY_STRING PackageName)
  556. {
  557. return( SEC_E_NOT_SUPPORTED );
  558. }
  559. //+-------------------------------------------------------------------------
  560. //
  561. // Function: SpmCreateEvent
  562. //
  563. // Synopsis: Just like the Win32 function, except that it allows
  564. // for names at the root of the namespace.
  565. //
  566. // Effects:
  567. //
  568. // Arguments:
  569. //
  570. // Requires:
  571. //
  572. // Returns:
  573. //
  574. // Notes:
  575. //
  576. //--------------------------------------------------------------------------
  577. HANDLE
  578. SpmCreateEvent( LPSECURITY_ATTRIBUTES lpsa,
  579. BOOL fManualReset,
  580. BOOL fInitialState,
  581. LPTSTR pszEventName)
  582. {
  583. HANDLE hEvent;
  584. OBJECT_ATTRIBUTES EventAttr;
  585. UNICODE_STRING usName;
  586. NTSTATUS Status;
  587. ULONG ulWin32Error;
  588. RtlInitUnicodeString(&usName, pszEventName);
  589. if (lpsa)
  590. {
  591. InitializeObjectAttributes(&EventAttr, &usName,
  592. (lpsa->bInheritHandle ? OBJ_INHERIT : 0),
  593. NULL,
  594. lpsa->lpSecurityDescriptor);
  595. }
  596. else
  597. {
  598. InitializeObjectAttributes(&EventAttr, &usName, 0, NULL, NULL);
  599. }
  600. Status = NtCreateEvent( &hEvent,
  601. EVENT_ALL_ACCESS,
  602. &EventAttr,
  603. (fManualReset ? NotificationEvent : SynchronizationEvent),
  604. (BOOLEAN) fInitialState);
  605. if (!NT_SUCCESS(Status))
  606. {
  607. ulWin32Error = RtlNtStatusToDosError( Status );
  608. SetLastError(ulWin32Error);
  609. return(NULL);
  610. }
  611. return(hEvent);
  612. }
  613. //+-------------------------------------------------------------------------
  614. //
  615. // Function: SpmOpenEvent
  616. //
  617. // Synopsis: Just like Win32 OpenEvent, except that this supports \ in name
  618. //
  619. // Effects:
  620. //
  621. // Arguments:
  622. //
  623. // Requires:
  624. //
  625. // Returns:
  626. //
  627. // Notes:
  628. //
  629. //--------------------------------------------------------------------------
  630. HANDLE
  631. SpmOpenEvent( ULONG fdwAccess,
  632. BOOL fInherit,
  633. LPTSTR pszEventName)
  634. {
  635. HANDLE hEvent;
  636. OBJECT_ATTRIBUTES EventAttr;
  637. UNICODE_STRING usName;
  638. NTSTATUS Status;
  639. ULONG ulWin32Error;
  640. RtlInitUnicodeString(&usName, pszEventName);
  641. InitializeObjectAttributes(&EventAttr, &usName, OBJ_CASE_INSENSITIVE |
  642. (fInherit ? OBJ_INHERIT : 0), NULL, NULL);
  643. Status = NtOpenEvent( &hEvent,
  644. fdwAccess,
  645. &EventAttr);
  646. if (!NT_SUCCESS(Status))
  647. {
  648. ulWin32Error = RtlNtStatusToDosError( Status );
  649. SetLastError(ulWin32Error);
  650. return(NULL);
  651. }
  652. return(hEvent);
  653. }
  654. ////////////////////////////////////////////////////////////////////////////
  655. //
  656. //
  657. // Package List Manipulation:
  658. //
  659. //
  660. ////////////////////////////////////////////////////////////////////////////
  661. //+---------------------------------------------------------------------------
  662. //
  663. // Function: SpmpAddPackage
  664. //
  665. // Synopsis: Adds a package to the list.
  666. //
  667. // Arguments: [pPackage] -- Package to add
  668. //
  669. // History: 7-26-96 RichardW Created
  670. //
  671. // Notes:
  672. //
  673. //----------------------------------------------------------------------------
  674. ULONG
  675. SpmpAddPackage(
  676. PLSAP_SECURITY_PACKAGE pPackage)
  677. {
  678. PLSAP_SECURITY_PACKAGE * pList;
  679. ULONG PackageId;
  680. //
  681. // Grab excluse access to the list:
  682. //
  683. WriteLockPackageList();
  684. //
  685. // If we don't have any left over space in the array, realloc it
  686. //
  687. if ( PackageControlCount == PackageControlTotal )
  688. {
  689. pList = (PLSAP_SECURITY_PACKAGE *) LsapAllocateLsaHeap( sizeof(PLSAP_SECURITY_PACKAGE) *
  690. (PackageControlTotal + INITIAL_PACKAGE_CONTROL_SIZE));
  691. if (!pList)
  692. {
  693. UnlockPackageList();
  694. return( 0xFFFFFFFF );
  695. }
  696. CopyMemory( pList,
  697. pPackageControlList,
  698. sizeof( PLSAP_SECURITY_PACKAGE ) * PackageControlTotal );
  699. PackageControlTotal += INITIAL_PACKAGE_CONTROL_SIZE;
  700. LsapFreeLsaHeap( pPackageControlList );
  701. pPackageControlList = pList;
  702. }
  703. //
  704. // Obtain a new package id (and slot)
  705. //
  706. PackageId = PackageControlCount++;
  707. pPackageControlList[ PackageId ] = pPackage;
  708. pPackage->pBinding->RefCount++;
  709. pPackage->dwPackageID = PackageId;
  710. UnlockPackageList();
  711. return( PackageId );
  712. }
  713. //+---------------------------------------------------------------------------
  714. //
  715. // Function: SpmpRemovePackage
  716. //
  717. // Synopsis: Removes a package from the list
  718. //
  719. // Arguments: [PackageId] --
  720. //
  721. // History: 7-26-96 RichardW Created
  722. //
  723. // Notes:
  724. //
  725. //----------------------------------------------------------------------------
  726. VOID
  727. SpmpRemovePackage(
  728. ULONG PackageId)
  729. {
  730. WriteLockPackageList();
  731. pPackageControlList[ PackageId ] = NULL;
  732. //
  733. // If the counter hasn't moved on, reclaim the index
  734. //
  735. if (PackageId == PackageControlCount - 1)
  736. {
  737. PackageControlCount--;
  738. }
  739. UnlockPackageList();
  740. }
  741. //+---------------------------------------------------------------------------
  742. //
  743. // Function: SpmpAddDll
  744. //
  745. // Synopsis: Add a DLL binding
  746. //
  747. // Arguments: [pBinding] --
  748. //
  749. // History: 7-26-96 RichardW Created
  750. //
  751. // Notes:
  752. //
  753. //----------------------------------------------------------------------------
  754. BOOL
  755. SpmpAddDll(
  756. PDLL_BINDING pBinding)
  757. {
  758. PDLL_BINDING * pList;
  759. ULONG DllId;
  760. WriteLockPackageList();
  761. if ( PackageDllCount == PackageDllTotal )
  762. {
  763. pList = (PDLL_BINDING *) LsapAllocateLsaHeap( sizeof(PDLL_BINDING) *
  764. (PackageDllTotal + INITIAL_PACKAGE_DLL_SIZE));
  765. if (!pList)
  766. {
  767. UnlockPackageList();
  768. return( FALSE );
  769. }
  770. CopyMemory( pList,
  771. pPackageDllList,
  772. sizeof( PDLL_BINDING ) * PackageDllTotal );
  773. PackageDllTotal += INITIAL_PACKAGE_DLL_SIZE;
  774. LsapFreeLsaHeap( pPackageDllList );
  775. pPackageDllList = pList;
  776. }
  777. pPackageDllList[ PackageDllCount++ ] = pBinding;
  778. UnlockPackageList();
  779. return( TRUE );
  780. }
  781. //+---------------------------------------------------------------------------
  782. //
  783. // Function: SpmpRemoveDll
  784. //
  785. // Synopsis: Removes a DLL binding
  786. //
  787. // Arguments: [pBinding] --
  788. //
  789. // History: 7-26-96 RichardW Created
  790. //
  791. // Notes:
  792. //
  793. //----------------------------------------------------------------------------
  794. VOID
  795. SpmpRemoveDll(
  796. PDLL_BINDING pBinding)
  797. {
  798. ULONG i;
  799. WriteLockPackageList();
  800. if (pPackageDllList[PackageDllCount - 1] == pBinding )
  801. {
  802. PackageDllCount --;
  803. pPackageDllList[ PackageDllCount ] = NULL;
  804. }
  805. else
  806. {
  807. for (i = 0; i < PackageDllCount ; i++ )
  808. {
  809. if (pPackageDllList[ i ] == pBinding)
  810. {
  811. pPackageDllList[ i ] = NULL;
  812. break;
  813. }
  814. }
  815. }
  816. UnlockPackageList();
  817. }
  818. //+---------------------------------------------------------------------------
  819. //
  820. // Function: SpmpFindDll
  821. //
  822. // Synopsis: Searches set of DLLs already loaded for a DLL name
  823. //
  824. // Arguments: [DllName] -- absolute or relative path name
  825. //
  826. // History: 9-20-96 RichardW Created
  827. //
  828. // Notes:
  829. //
  830. //----------------------------------------------------------------------------
  831. PDLL_BINDING
  832. SpmpFindDll(
  833. PWSTR DllName)
  834. {
  835. WCHAR DllPath[ MAX_PATH ];
  836. PWSTR FilePart;
  837. DWORD Length;
  838. UNICODE_STRING Search;
  839. PDLL_BINDING pBinding;
  840. DWORD i;
  841. pBinding = NULL ;
  842. Length = SearchPath(NULL,
  843. DllName,
  844. TEXT(".DLL"),
  845. MAX_PATH,
  846. DllPath,
  847. &FilePart );
  848. if ( Length )
  849. {
  850. //
  851. // Name hit, see if we've loaded it already:
  852. //
  853. Search.Buffer = DllPath;
  854. Search.Length = (USHORT) (Length * sizeof( WCHAR ));
  855. Search.MaximumLength = Search.Length + sizeof( WCHAR ) ;
  856. ReadLockPackageList();
  857. for ( i = 0 ; i < PackageDllCount ; i++ )
  858. {
  859. if ( RtlEqualUnicodeString( &Search,
  860. &(pPackageDllList[i]->Filename),
  861. TRUE) )
  862. {
  863. pBinding = pPackageDllList[ i ];
  864. break;
  865. }
  866. }
  867. UnlockPackageList();
  868. }
  869. return( pBinding );
  870. }
  871. //+---------------------------------------------------------------------------
  872. //
  873. // Function: LsapGetExtendedPackageInfo
  874. //
  875. // Synopsis: Wrapper to get extended information from a package
  876. //
  877. // Arguments: [Package] -- Package to query
  878. // [Class] -- Information class
  879. // [Info] -- returned data
  880. //
  881. // History: 3-04-97 RichardW Created
  882. //
  883. // Notes:
  884. //
  885. //----------------------------------------------------------------------------
  886. NTSTATUS
  887. LsapGetExtendedPackageInfo(
  888. PLSAP_SECURITY_PACKAGE Package,
  889. SECPKG_EXTENDED_INFORMATION_CLASS Class,
  890. PSECPKG_EXTENDED_INFORMATION * Info
  891. )
  892. {
  893. NTSTATUS Status ;
  894. if ( (Package->fPackage & SP_INFO) == 0 )
  895. {
  896. return SEC_E_NOT_SUPPORTED ;
  897. }
  898. DebugLog(( DEB_TRACE, "Getting extended information (%d) from %ws\n",
  899. Class, Package->Name.Buffer ));
  900. __try
  901. {
  902. Status = Package->FunctionTable.GetExtendedInformation( Class, Info );
  903. }
  904. __except (SP_EXCEPTION)
  905. {
  906. Status = SPException(GetExceptionCode(), Package->dwPackageID);
  907. }
  908. return Status ;
  909. }
  910. NTSTATUS
  911. LsapSetExtendedPackageInfo(
  912. PLSAP_SECURITY_PACKAGE Package,
  913. SECPKG_EXTENDED_INFORMATION_CLASS Class,
  914. PSECPKG_EXTENDED_INFORMATION Info
  915. )
  916. {
  917. NTSTATUS Status ;
  918. if ( ((Package->fPackage & SP_INFO) == 0 ) ||
  919. ( Package->FunctionTable.SetExtendedInformation == NULL ) )
  920. {
  921. return SEC_E_NOT_SUPPORTED ;
  922. }
  923. DebugLog(( DEB_TRACE, "Setting extended information (%d) from %ws\n",
  924. Class, Package->Name.Buffer ));
  925. __try
  926. {
  927. Status = Package->FunctionTable.SetExtendedInformation( Class, Info );
  928. }
  929. __except (SP_EXCEPTION)
  930. {
  931. Status = SPException(GetExceptionCode(), Package->dwPackageID);
  932. }
  933. return Status ;
  934. }
  935. //+---------------------------------------------------------------------------
  936. //
  937. // Function: LsapAuditPackageBoot
  938. //
  939. // Synopsis: Audit a package boot (load)
  940. //
  941. // Arguments: [pPackage] --
  942. //
  943. // History: 5-06-97 RichardW Created
  944. //
  945. // Notes:
  946. //
  947. //----------------------------------------------------------------------------
  948. VOID
  949. LsapAuditPackageBoot(
  950. IN PLSAP_SECURITY_PACKAGE pPackage
  951. )
  952. {
  953. WCHAR PackageAndDll[ MAX_PATH ];
  954. UNICODE_STRING AuditName;
  955. wcsncpy( PackageAndDll, pPackage->pBinding->Filename.Buffer, MAX_PATH );
  956. wcsncat( PackageAndDll, L" : ",
  957. MAX_PATH - (pPackage->pBinding->Filename.Length / sizeof(WCHAR)) );
  958. wcsncat( PackageAndDll, pPackage->Name.Buffer,
  959. MAX_PATH - ( pPackage->pBinding->Filename.Length / sizeof(WCHAR) + 4) );
  960. RtlInitUnicodeString( &AuditName, PackageAndDll );
  961. LsapAdtAuditPackageLoad( &AuditName );
  962. }
  963. //+---------------------------------------------------------------------------
  964. //
  965. // Function: SpmpBootPackage
  966. //
  967. // Synopsis: Initializes a package by calling it's entry points
  968. //
  969. // Arguments: [pPackage] -- Package to initialize
  970. // [pParameters] -- Initialization parameters
  971. //
  972. // History: 7-26-96 RichardW Created
  973. //
  974. // Notes:
  975. //
  976. //----------------------------------------------------------------------------
  977. BOOL
  978. SpmpBootPackage(
  979. IN PLSAP_SECURITY_PACKAGE pPackage,
  980. IN PSECPKG_PARAMETERS pParameters
  981. )
  982. {
  983. SECURITY_STATUS scRetCode;
  984. SecPkgInfo spiPackage = { 0 };
  985. UNICODE_STRING TempString;
  986. PSECPKG_EXTENDED_INFORMATION WowClient ;
  987. //
  988. // Break now so debugging people can set breakpoints in the newly loaded
  989. // DLL.
  990. //
  991. BreakOnError(BREAK_ON_LOAD);
  992. // Call the packages initialize function. This gives the package a chance
  993. // to do whatever initialization it needs to do. E.g. the kerberos package
  994. // runs out and finds the KDC.
  995. //
  996. // Set the session ID for tracking and so forth.
  997. //
  998. SetCurrentPackageId(pPackage->dwPackageID);
  999. __try
  1000. {
  1001. scRetCode = pPackage->FunctionTable.Initialize(
  1002. pPackage->dwPackageID,
  1003. pParameters,
  1004. &LsapSecpkgFunctionTable
  1005. );
  1006. }
  1007. __except (SP_EXCEPTION)
  1008. {
  1009. //
  1010. // Well, this is odd. The initialization function blew chunks. That
  1011. // means that the package itself can't be trusted. So, let's change
  1012. // this to an error return, and let the error logic blow away the
  1013. // package.
  1014. //
  1015. scRetCode = SEC_E_CANNOT_INSTALL;
  1016. }
  1017. //
  1018. // Let's see if the package loaded. Hmm.
  1019. //
  1020. if (FAILED(scRetCode))
  1021. {
  1022. goto Cleanup;
  1023. }
  1024. //
  1025. // Hey, a good one. Now, determine the capabilities of the package by
  1026. // calling it's getinfo function.
  1027. //
  1028. __try
  1029. {
  1030. scRetCode = pPackage->FunctionTable.GetInfo( &spiPackage );
  1031. }
  1032. __except (SP_EXCEPTION)
  1033. {
  1034. //
  1035. // If it blows, catch it, and kill the package.
  1036. //
  1037. scRetCode = SPException(GetExceptionCode(), pPackage->dwPackageID);
  1038. }
  1039. //
  1040. // Reset the session ID.
  1041. //
  1042. SetCurrentPackageId( SPMGR_ID );
  1043. //
  1044. // If it failed, note that and return. Note, if there was an exception
  1045. // then SPException() will have tagged the package appropriately.
  1046. //
  1047. if (FAILED(scRetCode))
  1048. {
  1049. goto Cleanup;
  1050. }
  1051. pPackage->fCapabilities = spiPackage.fCapabilities;
  1052. pPackage->dwRPCID = spiPackage.wRPCID;
  1053. pPackage->Version = spiPackage.wVersion ;
  1054. pPackage->TokenSize = spiPackage.cbMaxToken ;
  1055. RtlInitUnicodeString(
  1056. &TempString,
  1057. spiPackage.Name
  1058. );
  1059. scRetCode = LsapDuplicateString(
  1060. &pPackage->Name,
  1061. &TempString
  1062. );
  1063. if (!NT_SUCCESS(scRetCode))
  1064. {
  1065. goto Cleanup;
  1066. }
  1067. RtlInitUnicodeString( &TempString, spiPackage.Comment );
  1068. scRetCode = LsapDuplicateString(
  1069. &pPackage->Comment,
  1070. &TempString );
  1071. if ( !NT_SUCCESS( scRetCode ) )
  1072. {
  1073. goto Cleanup;
  1074. }
  1075. //
  1076. // Find out if the package supports extended information. If so,
  1077. // find out what context attrs it wants thunked to LSA mode.
  1078. //
  1079. if ( pPackage->FunctionTable.GetExtendedInformation )
  1080. {
  1081. pPackage->fPackage |= SP_INFO ;
  1082. scRetCode = LsapGetExtendedPackageInfo(
  1083. pPackage,
  1084. SecpkgContextThunks,
  1085. &pPackage->Thunks );
  1086. if ( scRetCode != STATUS_SUCCESS )
  1087. {
  1088. pPackage->Thunks = NULL ;
  1089. scRetCode = 0 ;
  1090. }
  1091. if ( pPackage->Thunks )
  1092. {
  1093. pPackage->fPackage |= SP_CONTEXT_INFO ;
  1094. }
  1095. scRetCode = LsapGetExtendedPackageInfo(
  1096. pPackage,
  1097. SecpkgWowClientDll,
  1098. &WowClient );
  1099. if ( scRetCode == STATUS_SUCCESS )
  1100. {
  1101. scRetCode = LsapDuplicateString(
  1102. &pPackage->WowClientDll,
  1103. &WowClient->Info.WowClientDll.WowClientDllPath);
  1104. if ( NT_SUCCESS( scRetCode ) )
  1105. {
  1106. pPackage->fPackage |= SP_WOW_SUPPORT ;
  1107. }
  1108. }
  1109. }
  1110. DebugLog((DEB_TRACE_INIT | DEB_TRACE, "Loaded %ws, assigned ID %d, flags %#x\n",
  1111. spiPackage.Name,
  1112. pPackage->dwPackageID,
  1113. pPackage->fPackage ));
  1114. lsState.cPackages++;
  1115. if ((pPackage->fPackage & SPM_AUTH_PKG_FLAG) == 0)
  1116. {
  1117. lsState.cNewPackages ++;
  1118. }
  1119. //
  1120. // And write the audit
  1121. //
  1122. LsapAuditPackageBoot( pPackage );
  1123. return( TRUE );
  1124. Cleanup:
  1125. return( FALSE );
  1126. }
  1127. //+---------------------------------------------------------------------------
  1128. //
  1129. // Function: SpmpBootAuthPackage
  1130. //
  1131. // Synopsis: Initializes an old-style authentication package.
  1132. //
  1133. // Arguments: [pPackage] --
  1134. //
  1135. // History: 5-06-97 RichardW Created
  1136. //
  1137. // Notes:
  1138. //
  1139. //----------------------------------------------------------------------------
  1140. NTSTATUS
  1141. SpmpBootAuthPackage(
  1142. PLSAP_SECURITY_PACKAGE pPackage)
  1143. {
  1144. NTSTATUS scRet;
  1145. PSTRING pNlsName;
  1146. char * pszTemp;
  1147. DebugLog((DEB_TRACE_LSA_AU, "Initializing package %d\n",
  1148. pPackage->dwPackageID));
  1149. __try
  1150. {
  1151. scRet = pPackage->FunctionTable.InitializePackage(
  1152. (ULONG) pPackage->dwPackageID,
  1153. (PLSA_DISPATCH_TABLE) &LsapSecpkgFunctionTable,
  1154. NULL,
  1155. NULL,
  1156. &pNlsName);
  1157. if (NT_SUCCESS(scRet))
  1158. {
  1159. // TODO: why is this alloc+copy here?
  1160. pszTemp = (char *)LsapAllocateLsaHeap(pNlsName->Length + 1);
  1161. if (pszTemp != NULL)
  1162. {
  1163. strncpy(pszTemp, pNlsName->Buffer, pNlsName->Length);
  1164. scRet = RtlAnsiStringToUnicodeString(
  1165. &pPackage->Name,
  1166. pNlsName,
  1167. TRUE // allocate destination
  1168. );
  1169. LsapFreeLsaHeap(pszTemp);
  1170. }
  1171. else
  1172. {
  1173. scRet = STATUS_INSUFFICIENT_RESOURCES;
  1174. }
  1175. //
  1176. // NTBUG 395189
  1177. // Do not free the returned name. There is no correct way to do
  1178. // this, and some vendors do not separately allocate the string
  1179. // and structure, and some might use some other part of memory.
  1180. // So allow this potential leak, but since they are loaded only once
  1181. // and at boot time, that's ok.
  1182. //
  1183. #if 0
  1184. //
  1185. // Free the returned name
  1186. //
  1187. LsapFreeLsaHeap(pNlsName->Buffer);
  1188. LsapFreeLsaHeap(pNlsName);
  1189. #endif
  1190. }
  1191. }
  1192. __except (SP_EXCEPTION)
  1193. {
  1194. scRet = SPException(GetExceptionCode(), pPackage->dwPackageID);
  1195. }
  1196. if (SUCCEEDED(scRet))
  1197. {
  1198. lsState.cPackages ++;
  1199. LsapAuditPackageBoot( pPackage );
  1200. }
  1201. return(scRet);
  1202. }
  1203. //+---------------------------------------------------------------------------
  1204. //
  1205. // Function: SpmpLoadPackage
  1206. //
  1207. // Synopsis: Loads a specific package from a DLL binding
  1208. //
  1209. // Arguments: [pBinding] -- Binding to work from
  1210. // [Package] -- Package index to load
  1211. // [pParameters] -- Parameters to pass for initialization
  1212. //
  1213. // History: 7-26-96 RichardW Created
  1214. //
  1215. // Notes:
  1216. //
  1217. //----------------------------------------------------------------------------
  1218. BOOL
  1219. SpmpLoadPackage(
  1220. PDLL_BINDING pBinding,
  1221. ULONG Package,
  1222. PSECPKG_PARAMETERS pParameters)
  1223. {
  1224. ULONG PackageId;
  1225. PLSAP_SECURITY_PACKAGE pPackage;
  1226. SECPKG_EVENT_PACKAGE_CHANGE Event;
  1227. //
  1228. // Get the package dispatch table:
  1229. //
  1230. pPackage = &pBinding->Packages[Package];
  1231. //
  1232. // Update its binding entry
  1233. //
  1234. pPackage->pBinding = pBinding;
  1235. pPackage->PackageIndex = Package ;
  1236. //
  1237. // Add it as a package to run
  1238. //
  1239. PackageId = SpmpAddPackage( pPackage );
  1240. if ( PackageId != 0xFFFFFFFF )
  1241. {
  1242. //
  1243. // Boot it, so it is initialized
  1244. //
  1245. if ( SpmpBootPackage(pPackage, pParameters) )
  1246. {
  1247. //
  1248. // Notify any listeners:
  1249. //
  1250. Event.ChangeType = SECPKG_PACKAGE_CHANGE_LOAD ;
  1251. Event.PackageName = pPackage->Name ;
  1252. Event.PackageId = PackageId ;
  1253. LsapEventNotify(
  1254. NOTIFY_CLASS_PACKAGE_CHANGE,
  1255. 0,
  1256. sizeof( Event ),
  1257. &Event );
  1258. return( TRUE );
  1259. }
  1260. SpmpRemovePackage( PackageId );
  1261. }
  1262. return( FALSE );
  1263. }
  1264. //+---------------------------------------------------------------------------
  1265. //
  1266. // Function: SpmpLoadDll
  1267. //
  1268. // Synopsis: Loads a new DLL, determines the packages, and loads them
  1269. //
  1270. // Arguments: [pszDll] -- DLL name
  1271. // [pParameters] -- Parameters for initialization
  1272. //
  1273. // History: 7-26-96 RichardW Created
  1274. //
  1275. // Notes:
  1276. //
  1277. //----------------------------------------------------------------------------
  1278. BOOL
  1279. SpmpLoadDll(
  1280. PWSTR pszDll,
  1281. PSECPKG_PARAMETERS pParameters)
  1282. {
  1283. HANDLE hDll;
  1284. DLL_BINDING * pBinding = NULL ;
  1285. PDLL_BINDING * pList;
  1286. SpLsaModeInitializeFn Init;
  1287. ULONG PackageVersion;
  1288. SECURITY_STATUS scRet;
  1289. PSECPKG_FUNCTION_TABLE pTables;
  1290. HINSTANCE hInstance = NULL ;
  1291. ULONG PackageCount;
  1292. PWSTR pszPath;
  1293. ULONG cchPath;
  1294. ULONG i;
  1295. ULONG SuccessCount;
  1296. BOOL IsSigned ;
  1297. hInstance = LoadLibrary( pszDll );
  1298. if (hInstance)
  1299. {
  1300. Init = (SpLsaModeInitializeFn) GetProcAddress(
  1301. hInstance,
  1302. SECPKG_LSAMODEINIT_NAME);
  1303. if (Init)
  1304. {
  1305. scRet = Init( SECPKG_INTERFACE_VERSION,
  1306. &PackageVersion,
  1307. &pTables,
  1308. &PackageCount );
  1309. if (SUCCEEDED(scRet))
  1310. {
  1311. pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) +
  1312. (PackageCount - 1) *
  1313. sizeof( LSAP_SECURITY_PACKAGE ) );
  1314. if (pBinding)
  1315. {
  1316. pBinding->hInstance = hInstance;
  1317. pszPath = (PWSTR) LsapAllocateLsaHeap( MAX_PATH * 2 * 2 );
  1318. if (pszPath)
  1319. {
  1320. UNICODE_STRING TempString;
  1321. cchPath = GetModuleFileName( hInstance,
  1322. pszPath,
  1323. MAX_PATH * 2 );
  1324. RtlInitUnicodeString(
  1325. &TempString,
  1326. pszPath
  1327. );
  1328. scRet = LsapDuplicateString(
  1329. &pBinding->Filename,
  1330. &TempString
  1331. );
  1332. LsapFreeLsaHeap( pszPath );
  1333. if (!NT_SUCCESS(scRet))
  1334. {
  1335. //
  1336. // Bail out:
  1337. //
  1338. goto LoadDll_Error;
  1339. }
  1340. #ifdef LSA_IGNORE_SIGNATURE
  1341. IsSigned = TRUE;
  1342. #else
  1343. IsSigned = FALSE;
  1344. {
  1345. const LPWSTR ExclusionList[] = {
  1346. L"msv1_0",
  1347. L"kerberos",
  1348. L"schannel",
  1349. L"wdigest",
  1350. NULL
  1351. };
  1352. ULONG ExclusionIndex = 0;
  1353. while( ExclusionList[ExclusionIndex] != NULL )
  1354. {
  1355. if( lstrcmpiW( pszDll, ExclusionList[ExclusionIndex] ) == 0 )
  1356. {
  1357. IsSigned = TRUE;
  1358. break;
  1359. }
  1360. ExclusionIndex++;
  1361. }
  1362. }
  1363. if( !IsSigned )
  1364. {
  1365. IsSigned = RtlCheckSignatureInFile( pBinding->Filename.Buffer );
  1366. }
  1367. #endif
  1368. if ( IsSigned )
  1369. {
  1370. pBinding->Flags |= DLL_SIGNED ;
  1371. }
  1372. }
  1373. pBinding->PackageCount = PackageCount;
  1374. SuccessCount = 0;
  1375. for (i = 0 ; i < PackageCount ; i++ )
  1376. {
  1377. //
  1378. // Old auth packages contain all functions up to but not including
  1379. // SetContextAttributes.
  1380. //
  1381. if ( PackageVersion == SECPKG_INTERFACE_VERSION ) {
  1382. //
  1383. // Copy the exported table and zero the rest.
  1384. //
  1385. CopyMemory( &pBinding->Packages[i].FunctionTable,
  1386. &pTables[i],
  1387. offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes ) );
  1388. ZeroMemory( ((LPBYTE)(&pBinding->Packages[i].FunctionTable)) +
  1389. offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes),
  1390. sizeof(SECPKG_FUNCTION_TABLE) -
  1391. offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes) );
  1392. } else {
  1393. CopyMemory( &pBinding->Packages[i].FunctionTable,
  1394. &pTables[i],
  1395. sizeof(SECPKG_FUNCTION_TABLE) );
  1396. }
  1397. if (SpmpLoadPackage( pBinding, i, pParameters ))
  1398. {
  1399. SuccessCount ++;
  1400. }
  1401. }
  1402. if (SuccessCount)
  1403. {
  1404. SpmpAddDll( pBinding );
  1405. return( TRUE );
  1406. }
  1407. }
  1408. }
  1409. }
  1410. }
  1411. LoadDll_Error :
  1412. if ( pBinding != NULL )
  1413. {
  1414. LsapFreeLsaHeap( pBinding );
  1415. }
  1416. if ( hInstance != NULL )
  1417. {
  1418. FreeLibrary( hInstance );
  1419. }
  1420. return( FALSE );
  1421. }
  1422. //+---------------------------------------------------------------------------
  1423. //
  1424. // Function: SpmpLoadAuthPkgDll
  1425. //
  1426. // Synopsis: Loads an old (msv1_0 style) DLL
  1427. //
  1428. // Arguments: [pszDll] --
  1429. //
  1430. // History: 7-26-96 RichardW Created
  1431. //
  1432. // Notes:
  1433. //
  1434. //----------------------------------------------------------------------------
  1435. BOOL
  1436. SpmpLoadAuthPkgDll(
  1437. PWSTR pszDll)
  1438. {
  1439. SECURITY_STATUS scRet;
  1440. HINSTANCE hInstance;
  1441. PDLL_BINDING pBinding = NULL ;
  1442. PLSAP_SECURITY_PACKAGE pPackage;
  1443. ULONG PackageId;
  1444. UNICODE_STRING PackageDll ;
  1445. PWSTR pszPath ;
  1446. DebugLog((DEB_TRACE_INIT, "Loading Old package %ws\n", pszDll));
  1447. hInstance = LoadLibrary( pszDll );
  1448. if ( hInstance )
  1449. {
  1450. pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) );
  1451. if (pBinding)
  1452. {
  1453. pszPath = (PWSTR) LsapAllocateLsaHeap( MAX_PATH * 2 * 2 );
  1454. if (pszPath)
  1455. {
  1456. UNICODE_STRING TempString;
  1457. DWORD cchPath ;
  1458. cchPath = GetModuleFileName( hInstance,
  1459. pszPath,
  1460. MAX_PATH * 2 );
  1461. RtlInitUnicodeString(
  1462. &TempString,
  1463. pszPath
  1464. );
  1465. scRet = LsapDuplicateString(
  1466. &pBinding->Filename,
  1467. &TempString
  1468. );
  1469. LsapFreeLsaHeap( pszPath );
  1470. if (!NT_SUCCESS(scRet))
  1471. {
  1472. goto LoadAuthDll_Error ;
  1473. }
  1474. }
  1475. pBinding->Flags = DLL_AUTHPKG;
  1476. pBinding->hInstance = hInstance;
  1477. pPackage = pBinding->Packages;
  1478. pPackage->pBinding = pBinding;
  1479. pBinding->PackageCount = 1;
  1480. if (BindOldPackage( hInstance, &pPackage->FunctionTable))
  1481. {
  1482. pPackage->fPackage = SPM_AUTH_PKG_FLAG;
  1483. pPackage->fCapabilities = SPM_AUTH_PKG_FLAG;
  1484. pPackage->dwRPCID = SECPKG_ID_NONE;
  1485. PackageId = SpmpAddPackage( pPackage );
  1486. if (PackageId != (ULONG) 0xFFFFFFFF)
  1487. {
  1488. if ( SpmpAddDll( pBinding ) )
  1489. {
  1490. BreakOnError(BREAK_ON_LOAD);
  1491. scRet = SpmpBootAuthPackage( pPackage );
  1492. if (SUCCEEDED(scRet))
  1493. {
  1494. return( TRUE );
  1495. }
  1496. SpmpRemoveDll( pBinding );
  1497. }
  1498. LsapFreeString( &pBinding->Filename );
  1499. pBinding->Filename.Buffer = NULL ;
  1500. SpmpRemovePackage( PackageId );
  1501. }
  1502. }
  1503. }
  1504. }
  1505. LoadAuthDll_Error:
  1506. if ( pBinding )
  1507. {
  1508. if ( pBinding->Filename.Buffer )
  1509. {
  1510. LsapFreeString( &pBinding->Filename );
  1511. }
  1512. LsapFreeLsaHeap( pBinding );
  1513. }
  1514. if ( hInstance )
  1515. {
  1516. FreeLibrary( hInstance );
  1517. }
  1518. return( FALSE );
  1519. }
  1520. //+---------------------------------------------------------------------------
  1521. //
  1522. // Function: SpmpLoadBuiltin
  1523. //
  1524. // Synopsis: Loads a builtin package
  1525. //
  1526. // Arguments: [Flags] -- Flags for the package
  1527. // [pTable] -- Dispatch table
  1528. // [pParameters] -- init parameters
  1529. //
  1530. // History: 7-26-96 RichardW Created
  1531. //
  1532. // Notes:
  1533. //
  1534. //----------------------------------------------------------------------------
  1535. BOOL
  1536. SpmpLoadBuiltin(
  1537. ULONG Flags,
  1538. PSECPKG_FUNCTION_TABLE pTable,
  1539. PSECPKG_PARAMETERS pParameters)
  1540. {
  1541. PDLL_BINDING pBinding;
  1542. PLSAP_SECURITY_PACKAGE pPackage;
  1543. SECURITY_STATUS scRetCode;
  1544. SecPkgInfo spiPackage;
  1545. ULONG PackageId;
  1546. SECPKG_EVENT_PACKAGE_CHANGE Event;
  1547. WCHAR Path[ MAX_PATH ];
  1548. SECURITY_STRING TempString ;
  1549. pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) );
  1550. if (pBinding)
  1551. {
  1552. ZeroMemory( pBinding, sizeof( DLL_BINDING ) );
  1553. pBinding->Flags = DLL_BUILTIN;
  1554. pBinding->PackageCount = 1;
  1555. pBinding->hInstance = GetModuleHandle( L"lsasrv.dll" );
  1556. GetModuleFileName( (HINSTANCE) pBinding->hInstance,
  1557. Path, MAX_PATH );
  1558. RtlInitUnicodeString( &TempString, Path );
  1559. scRetCode = LsapDuplicateString( &pBinding->Filename, &TempString );
  1560. if ( NT_SUCCESS( scRetCode ) )
  1561. {
  1562. pPackage = pBinding->Packages;
  1563. pPackage->pBinding = pBinding;
  1564. pPackage->fPackage = Flags | SP_WOW_SUPPORT ;
  1565. CopyMemory( &pPackage->FunctionTable,
  1566. pTable,
  1567. sizeof(SECPKG_FUNCTION_TABLE) );
  1568. //
  1569. // Fake up the DLL binding:
  1570. //
  1571. if ( SpmpAddDll( pBinding ) )
  1572. {
  1573. //
  1574. // Add the package to the table:
  1575. //
  1576. PackageId = SpmpAddPackage( pPackage );
  1577. if ( PackageId != 0xFFFFFFFF )
  1578. {
  1579. //
  1580. // Initialize the package
  1581. //
  1582. if (SpmpBootPackage(pPackage, pParameters))
  1583. {
  1584. //
  1585. // Notify any listeners:
  1586. //
  1587. Event.PackageName = pPackage->Name ;
  1588. Event.PackageId = PackageId ;
  1589. Event.ChangeType = SECPKG_PACKAGE_CHANGE_LOAD ;
  1590. LsapEventNotify(
  1591. NOTIFY_CLASS_PACKAGE_CHANGE,
  1592. 0,
  1593. sizeof( Event ),
  1594. &Event );
  1595. return( TRUE );
  1596. }
  1597. SpmpRemovePackage( PackageId );
  1598. }
  1599. SpmpRemoveDll( pBinding );
  1600. }
  1601. }
  1602. LsapFreeLsaHeap( pBinding->Filename.Buffer );
  1603. LsapFreeLsaHeap( pBinding );
  1604. }
  1605. return( FALSE );
  1606. }
  1607. BOOL
  1608. SpmpLoadBuiltinAuthPkg(
  1609. PSECPKG_FUNCTION_TABLE pTable)
  1610. {
  1611. PDLL_BINDING pBinding;
  1612. ULONG PackageId;
  1613. PLSAP_SECURITY_PACKAGE pPackage;
  1614. SECURITY_STATUS scRet;
  1615. WCHAR Path[ MAX_PATH ];
  1616. SECURITY_STRING TempString ;
  1617. pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) );
  1618. if (pBinding)
  1619. {
  1620. pBinding->Flags = DLL_AUTHPKG | DLL_BUILTIN;
  1621. pBinding->PackageCount = 1;
  1622. pBinding->hInstance = GetModuleHandle( L"lsasrv.dll" );
  1623. GetModuleFileName( (HINSTANCE) pBinding->hInstance,
  1624. Path, MAX_PATH );
  1625. RtlInitUnicodeString( &TempString, Path );
  1626. scRet = LsapDuplicateString( &pBinding->Filename, &TempString );
  1627. if ( NT_SUCCESS( scRet ) )
  1628. {
  1629. pPackage = pBinding->Packages;
  1630. pPackage->pBinding = pBinding;
  1631. CopyMemory( &pPackage->FunctionTable,
  1632. pTable,
  1633. sizeof( SECPKG_FUNCTION_TABLE ) );
  1634. pPackage->fPackage = SPM_AUTH_PKG_FLAG;
  1635. pPackage->fCapabilities = SPM_AUTH_PKG_FLAG;
  1636. pPackage->dwRPCID = SECPKG_ID_NONE;
  1637. PackageId = SpmpAddPackage( pPackage );
  1638. if (PackageId != (ULONG) 0xFFFFFFFF)
  1639. {
  1640. if ( SpmpAddDll( pBinding ) )
  1641. {
  1642. BreakOnError(BREAK_ON_LOAD);
  1643. scRet = SpmpBootAuthPackage( pPackage );
  1644. if (SUCCEEDED(scRet))
  1645. {
  1646. return( TRUE );
  1647. }
  1648. SpmpRemoveDll( pBinding );
  1649. }
  1650. SpmpRemovePackage( PackageId );
  1651. }
  1652. LsapFreeLsaHeap( pBinding );
  1653. }
  1654. }
  1655. return( FALSE );
  1656. }
  1657. //+---------------------------------------------------------------------------
  1658. //
  1659. // Function: SpmpLocatePackage
  1660. //
  1661. // Synopsis: Locates the package
  1662. //
  1663. // Arguments: [PackageId] --
  1664. //
  1665. // History: 11-15-95 RichardW Created
  1666. //
  1667. // Notes:
  1668. //
  1669. //----------------------------------------------------------------------------
  1670. PLSAP_SECURITY_PACKAGE
  1671. SpmpLocatePackage(
  1672. ULONG_PTR PackageId)
  1673. {
  1674. PLSAP_SECURITY_PACKAGE pControl = NULL;
  1675. ReadLockPackageList();
  1676. if( (ULONG)PackageId < PackageControlCount )
  1677. {
  1678. pControl = pPackageControlList[PackageId];
  1679. }
  1680. UnlockPackageList();
  1681. return( pControl );
  1682. }
  1683. //+---------------------------------------------------------------------------
  1684. //
  1685. // Function: SpmpValidateHandle
  1686. //
  1687. // Synopsis: Validates a package handle
  1688. //
  1689. // Arguments: [PackageHandle] --
  1690. //
  1691. // History: 11-15-95 RichardW Created
  1692. //
  1693. // Notes:
  1694. //
  1695. //----------------------------------------------------------------------------
  1696. PLSAP_SECURITY_PACKAGE
  1697. SpmpValidateHandle(
  1698. ULONG_PTR PackageHandle)
  1699. {
  1700. PLSAP_SECURITY_PACKAGE pControl = NULL;
  1701. ReadLockPackageList();
  1702. if ( PackageHandle < PackageControlCount )
  1703. {
  1704. pControl = pPackageControlList[ PackageHandle ];
  1705. }
  1706. UnlockPackageList();
  1707. return( pControl );
  1708. }
  1709. //+---------------------------------------------------------------------------
  1710. //
  1711. // Function: SpmpValidRequest
  1712. //
  1713. // Synopsis: Validates package handle, requested API code.
  1714. //
  1715. // Arguments: [PackageHandle] --
  1716. // [ApiCode] --
  1717. //
  1718. // History: 11-15-95 RichardW Created
  1719. //
  1720. // Notes:
  1721. //
  1722. //----------------------------------------------------------------------------
  1723. PLSAP_SECURITY_PACKAGE
  1724. SpmpValidRequest(
  1725. ULONG_PTR PackageHandle,
  1726. ULONG ApiCode)
  1727. {
  1728. PLSAP_SECURITY_PACKAGE pControl = NULL;
  1729. PVOID * pTable;
  1730. ReadLockPackageList();
  1731. if ( PackageHandle < PackageControlCount )
  1732. {
  1733. pControl = pPackageControlList[ PackageHandle ];
  1734. }
  1735. UnlockPackageList();
  1736. if (pControl)
  1737. {
  1738. if (pControl->fPackage & (SP_INVALID | SP_SHUTDOWN) )
  1739. {
  1740. pControl = NULL;
  1741. }
  1742. }
  1743. if (pControl)
  1744. {
  1745. pTable = (PVOID *) &pControl->FunctionTable;
  1746. if (pTable[ApiCode])
  1747. {
  1748. return( pControl );
  1749. }
  1750. pControl = NULL;
  1751. }
  1752. return( pControl );
  1753. }
  1754. //+---------------------------------------------------------------------------
  1755. //
  1756. // Function: SpmpLookupPackage
  1757. //
  1758. // Synopsis: Looks up a package based on name
  1759. //
  1760. // Arguments: [pssPackageName] --
  1761. //
  1762. // History: 7-30-96 RichardW Created
  1763. //
  1764. // Notes:
  1765. //
  1766. //----------------------------------------------------------------------------
  1767. PLSAP_SECURITY_PACKAGE
  1768. SpmpLookupPackage(
  1769. PUNICODE_STRING pssPackageName)
  1770. {
  1771. ULONG iPack;
  1772. PLSAP_SECURITY_PACKAGE pPackage;
  1773. PVOID * pTable;
  1774. ReadLockPackageList();
  1775. for (iPack = 0; iPack < PackageControlCount ; iPack++ )
  1776. {
  1777. pPackage = pPackageControlList[ iPack ];
  1778. if ( pPackage )
  1779. {
  1780. if (RtlEqualUnicodeString(
  1781. pssPackageName,
  1782. &pPackageControlList[ iPack ]->Name,
  1783. TRUE)) // case insensitive
  1784. {
  1785. UnlockPackageList();
  1786. return( pPackage );
  1787. }
  1788. }
  1789. }
  1790. UnlockPackageList();
  1791. return(NULL);
  1792. }
  1793. //+---------------------------------------------------------------------------
  1794. //
  1795. // Function: SpmpLookupPackageByRpcId
  1796. //
  1797. // Synopsis: Looks up a package based on RPC ID
  1798. //
  1799. // Arguments: [RpcId] --
  1800. //
  1801. // History: 7-30-96 RichardW Created
  1802. //
  1803. // Notes:
  1804. //
  1805. //----------------------------------------------------------------------------
  1806. PLSAP_SECURITY_PACKAGE
  1807. SpmpLookupPackageByRpcId(
  1808. ULONG RpcId)
  1809. {
  1810. ULONG iPack;
  1811. PLSAP_SECURITY_PACKAGE pPackage;
  1812. PVOID * pTable;
  1813. ReadLockPackageList();
  1814. for (iPack = 0; iPack < PackageControlCount ; iPack++ )
  1815. {
  1816. pPackage = pPackageControlList[ iPack ];
  1817. if ( pPackage )
  1818. {
  1819. if (RpcId == pPackageControlList[iPack]->dwRPCID)
  1820. {
  1821. UnlockPackageList();
  1822. return( pPackage );
  1823. }
  1824. }
  1825. }
  1826. UnlockPackageList();
  1827. return(NULL);
  1828. }
  1829. //+---------------------------------------------------------------------------
  1830. //
  1831. // Function: SpmpLookupPackageAndRequest
  1832. //
  1833. // Synopsis: Returns a package pointer based on a name and the API code
  1834. //
  1835. // Arguments: [pssPackageName] -- Package name
  1836. // [ApiCode] -- Code
  1837. //
  1838. // History: 7-30-96 RichardW Created
  1839. //
  1840. // Notes:
  1841. //
  1842. //----------------------------------------------------------------------------
  1843. PLSAP_SECURITY_PACKAGE
  1844. SpmpLookupPackageAndRequest(
  1845. PUNICODE_STRING pssPackageName,
  1846. ULONG ApiCode)
  1847. {
  1848. ULONG iPack;
  1849. PLSAP_SECURITY_PACKAGE pPackage;
  1850. PVOID * pTable;
  1851. ReadLockPackageList();
  1852. for (iPack = 0; iPack < PackageControlCount ; iPack++ )
  1853. {
  1854. pPackage = pPackageControlList[ iPack ];
  1855. if ( pPackage )
  1856. {
  1857. if (RtlEqualUnicodeString(
  1858. pssPackageName,
  1859. &pPackageControlList[ iPack ]->Name,
  1860. TRUE)) // case insensitive
  1861. {
  1862. UnlockPackageList();
  1863. if ((pPackage->fPackage & ( SP_INVALID | SP_SHUTDOWN )) == 0)
  1864. {
  1865. pTable = (PVOID *) &pPackage->FunctionTable;
  1866. if (pTable[ApiCode])
  1867. {
  1868. return( pPackage );
  1869. }
  1870. }
  1871. return( NULL );
  1872. }
  1873. }
  1874. }
  1875. UnlockPackageList();
  1876. return(NULL);
  1877. }
  1878. //+---------------------------------------------------------------------------
  1879. //
  1880. // Function: SpmpIteratePackagesByRequest
  1881. //
  1882. // Synopsis: Cycle through packages by request code, returning packages
  1883. // that support supplied API
  1884. //
  1885. // Arguments: [pInitialPackage] --
  1886. // [ApiCode] --
  1887. //
  1888. // History: 7-30-96 RichardW Created
  1889. //
  1890. // Notes:
  1891. //
  1892. //----------------------------------------------------------------------------
  1893. PLSAP_SECURITY_PACKAGE
  1894. SpmpIteratePackagesByRequest(
  1895. PLSAP_SECURITY_PACKAGE pInitialPackage,
  1896. ULONG ApiCode)
  1897. {
  1898. ULONG_PTR NextPackage;
  1899. PLSAP_SECURITY_PACKAGE pPackage = NULL;
  1900. PVOID * pTable;
  1901. ULONG Ordinal ;
  1902. ULONG FlagMaskOn = 0 ;
  1903. ULONG FlagMaskOff = SP_INVALID | SP_SHUTDOWN ;
  1904. Ordinal = ApiCode & SP_ORDINAL_MASK ;
  1905. if ( ApiCode & SP_ITERATE_FILTER_WOW )
  1906. {
  1907. FlagMaskOn |= SP_WOW_SUPPORT ;
  1908. }
  1909. ReadLockPackageList();
  1910. if (pInitialPackage)
  1911. {
  1912. NextPackage = pInitialPackage->dwPackageID + 1;
  1913. }
  1914. else
  1915. {
  1916. NextPackage = 0;
  1917. }
  1918. //
  1919. // Walk through the list of packages, filtering on package flags
  1920. // and whether the package supported the requested function
  1921. //
  1922. while (NextPackage < PackageControlCount)
  1923. {
  1924. pPackage = pPackageControlList[ NextPackage ];
  1925. if ( pPackage )
  1926. {
  1927. if ( ( pPackage->fPackage & FlagMaskOff ) == 0 )
  1928. {
  1929. if ( ( pPackage->fPackage & FlagMaskOn ) == FlagMaskOn )
  1930. {
  1931. pTable = (PVOID *) &pPackage->FunctionTable;
  1932. if ( pTable[ Ordinal ] )
  1933. {
  1934. //
  1935. // Found one!
  1936. //
  1937. break;
  1938. }
  1939. }
  1940. }
  1941. pPackage = NULL;
  1942. }
  1943. NextPackage++;
  1944. }
  1945. UnlockPackageList();
  1946. return( pPackage );
  1947. }
  1948. //+---------------------------------------------------------------------------
  1949. //
  1950. // Function: SpmpIteratePackages
  1951. //
  1952. // Synopsis: Safe iteration of the packages
  1953. //
  1954. // Arguments: [pInitialPackage] -- Prior package
  1955. //
  1956. // History: 7-30-96 RichardW Created
  1957. //
  1958. // Notes:
  1959. //
  1960. //----------------------------------------------------------------------------
  1961. PLSAP_SECURITY_PACKAGE
  1962. SpmpIteratePackages(
  1963. PLSAP_SECURITY_PACKAGE pInitialPackage)
  1964. {
  1965. ULONG_PTR NextPackage;
  1966. PLSAP_SECURITY_PACKAGE pPackage = NULL;
  1967. ReadLockPackageList();
  1968. if (pInitialPackage)
  1969. {
  1970. NextPackage = pInitialPackage->dwPackageID + 1;
  1971. }
  1972. else
  1973. {
  1974. NextPackage = 0;
  1975. }
  1976. while (NextPackage < PackageControlCount)
  1977. {
  1978. pPackage = pPackageControlList[ NextPackage ];
  1979. if ( pPackage )
  1980. {
  1981. break;
  1982. }
  1983. NextPackage++;
  1984. }
  1985. UnlockPackageList();
  1986. return( pPackage );
  1987. }
  1988. //+---------------------------------------------------------------------------
  1989. //
  1990. // Function: SpmpCurrentPackageCount
  1991. //
  1992. // Synopsis: Returns the current package count
  1993. //
  1994. // Arguments: (none)
  1995. //
  1996. // History: 7-30-96 RichardW Created
  1997. //
  1998. // Notes:
  1999. //
  2000. //----------------------------------------------------------------------------
  2001. ULONG
  2002. SpmpCurrentPackageCount(
  2003. VOID)
  2004. {
  2005. ULONG Count;
  2006. ReadLockPackageList();
  2007. Count = PackageControlCount;
  2008. UnlockPackageList();
  2009. return( Count );
  2010. }
  2011. //+---------------------------------------------------------------------------
  2012. //
  2013. // Function: LsapAddPackageHandle
  2014. //
  2015. // Synopsis: Increases the package handle count
  2016. //
  2017. // Arguments: [PackageId] --
  2018. //
  2019. // History: 10-08-96 RichardW Created
  2020. //
  2021. // Notes:
  2022. //
  2023. //----------------------------------------------------------------------------
  2024. VOID
  2025. LsapAddPackageHandle(
  2026. ULONG_PTR PackageId,
  2027. BOOL IsContext
  2028. )
  2029. {
  2030. #if DBG
  2031. PLSAP_SECURITY_PACKAGE Package ;
  2032. Package = pPackageControlList[ PackageId ];
  2033. if ( IsContext )
  2034. {
  2035. InterlockedIncrement( (PLONG)&Package->ContextHandles );
  2036. }
  2037. else
  2038. {
  2039. InterlockedIncrement( (PLONG)&Package->CredentialHandles );
  2040. }
  2041. #else
  2042. UNREFERENCED_PARAMETER( PackageId );
  2043. UNREFERENCED_PARAMETER( IsContext );
  2044. #endif
  2045. }
  2046. //+---------------------------------------------------------------------------
  2047. //
  2048. // Function: LsapDelPackageHandle
  2049. //
  2050. // Synopsis: Decrements the package handle count
  2051. //
  2052. // Arguments: [PackageId] --
  2053. //
  2054. // History: 10-08-96 RichardW Created
  2055. //
  2056. // Notes:
  2057. //
  2058. //----------------------------------------------------------------------------
  2059. VOID
  2060. LsapDelPackageHandle(
  2061. PLSAP_SECURITY_PACKAGE Package,
  2062. BOOL IsContext
  2063. )
  2064. {
  2065. #ifdef DBG
  2066. if ( IsContext )
  2067. {
  2068. InterlockedDecrement( (PLONG)&Package->ContextHandles );
  2069. }
  2070. else
  2071. {
  2072. InterlockedDecrement( (PLONG)&Package->CredentialHandles );
  2073. }
  2074. #else
  2075. UNREFERENCED_PARAMETER( Package );
  2076. UNREFERENCED_PARAMETER( IsContext );
  2077. #endif
  2078. }
  2079. //+---------------------------------------------------------------------------
  2080. //
  2081. // Function: SpmpInitializePackageControl
  2082. //
  2083. // Synopsis: Initialize the package controls
  2084. //
  2085. // Arguments: (none)
  2086. //
  2087. // History: 11-15-95 RichardW Created
  2088. //
  2089. // Notes:
  2090. //
  2091. //----------------------------------------------------------------------------
  2092. BOOL
  2093. SpmpInitializePackageControl(
  2094. VOID)
  2095. {
  2096. RtlInitializeResource( &PackageListLock );
  2097. WriteLockPackageList();
  2098. pPackageDllList = (PDLL_BINDING *) LsapAllocateLsaHeap( sizeof(PDLL_BINDING) *
  2099. INITIAL_PACKAGE_DLL_SIZE );
  2100. if (pPackageDllList)
  2101. {
  2102. PackageDllCount = 0;
  2103. PackageDllTotal = INITIAL_PACKAGE_DLL_SIZE;
  2104. pPackageControlList = (PLSAP_SECURITY_PACKAGE *) LsapAllocateLsaHeap( sizeof(PLSAP_SECURITY_PACKAGE) *
  2105. INITIAL_PACKAGE_CONTROL_SIZE );
  2106. if (pPackageControlList)
  2107. {
  2108. PackageControlCount = 0;
  2109. PackageControlTotal = INITIAL_PACKAGE_CONTROL_SIZE;
  2110. UnlockPackageList();
  2111. return( TRUE );
  2112. }
  2113. LsapFreeLsaHeap( pPackageDllList );
  2114. }
  2115. //
  2116. // KEEP the lock, so that nothing else tries to use the package list
  2117. //
  2118. return( FALSE );
  2119. }