Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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