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.

1669 lines
45 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. security.c
  5. Abstract:
  6. Data and routines for managing API security in the server service.
  7. Author:
  8. David Treadwell (davidtr) 28-Aug-1991
  9. Revision History:
  10. 05/00 (dkruse) - Added code to handle upgrading SD's and RestrictAnonymous changes
  11. --*/
  12. #include "srvsvcp.h"
  13. #include "ssreg.h"
  14. #include <lmsname.h>
  15. #include <netlibnt.h>
  16. #include <debugfmt.h>
  17. #include <seopaque.h>
  18. #include <sertlp.h>
  19. #include <sddl.h>
  20. //
  21. // Global security objects.
  22. //
  23. // ConfigInfo - NetServerGetInfo, NetServerSetInfo
  24. // Connection - NetConnectionEnum
  25. // Disk - NetServerDiskEnum
  26. // File - NetFile APIs
  27. // Session - NetSession APIs
  28. // Share - NetShare APIs (file, print, and admin types)
  29. // Statistics - NetStatisticsGet, NetStatisticsClear
  30. //
  31. SRVSVC_SECURITY_OBJECT SsConfigInfoSecurityObject = {0};
  32. SRVSVC_SECURITY_OBJECT SsConnectionSecurityObject = {0};
  33. SRVSVC_SECURITY_OBJECT SsDiskSecurityObject;
  34. SRVSVC_SECURITY_OBJECT SsFileSecurityObject = {0};
  35. SRVSVC_SECURITY_OBJECT SsSessionSecurityObject = {0};
  36. SRVSVC_SECURITY_OBJECT SsShareFileSecurityObject = {0};
  37. SRVSVC_SECURITY_OBJECT SsSharePrintSecurityObject = {0};
  38. SRVSVC_SECURITY_OBJECT SsShareAdminSecurityObject = {0};
  39. SRVSVC_SECURITY_OBJECT SsShareConnectSecurityObject = {0};
  40. SRVSVC_SECURITY_OBJECT SsShareAdmConnectSecurityObject = {0};
  41. SRVSVC_SECURITY_OBJECT SsStatisticsSecurityObject = {0};
  42. SRVSVC_SECURITY_OBJECT SsDefaultShareSecurityObject = {0};
  43. SRVSVC_SECURITY_OBJECT SsTransportEnumSecurityObject = {0};
  44. BOOLEAN SsRestrictNullSessions = FALSE;
  45. BOOLEAN SsUpgradeSecurityDescriptors = FALSE;
  46. BOOLEAN SsRegenerateSecurityDescriptors = FALSE;
  47. GENERIC_MAPPING SsConfigInfoMapping = {
  48. STANDARD_RIGHTS_READ | // Generic read
  49. SRVSVC_CONFIG_USER_INFO_GET |
  50. SRVSVC_CONFIG_ADMIN_INFO_GET,
  51. STANDARD_RIGHTS_WRITE | // Generic write
  52. SRVSVC_CONFIG_INFO_SET,
  53. STANDARD_RIGHTS_EXECUTE, // Generic execute
  54. SRVSVC_CONFIG_ALL_ACCESS // Generic all
  55. };
  56. GENERIC_MAPPING SsConnectionMapping = {
  57. STANDARD_RIGHTS_READ | // Generic read
  58. SRVSVC_CONNECTION_INFO_GET,
  59. STANDARD_RIGHTS_WRITE | // Generic write
  60. 0,
  61. STANDARD_RIGHTS_EXECUTE, // Generic execute
  62. SRVSVC_CONNECTION_ALL_ACCESS // Generic all
  63. };
  64. GENERIC_MAPPING SsDiskMapping = {
  65. STANDARD_RIGHTS_READ | // Generic read
  66. SRVSVC_DISK_ENUM,
  67. STANDARD_RIGHTS_WRITE | // Generic write
  68. 0,
  69. STANDARD_RIGHTS_EXECUTE, // Generic execute
  70. SRVSVC_DISK_ALL_ACCESS // Generic all
  71. };
  72. GENERIC_MAPPING SsFileMapping = {
  73. STANDARD_RIGHTS_READ | // Generic read
  74. SRVSVC_FILE_INFO_GET,
  75. STANDARD_RIGHTS_WRITE | // Generic write
  76. SRVSVC_FILE_CLOSE,
  77. STANDARD_RIGHTS_EXECUTE, // Generic execute
  78. SRVSVC_FILE_ALL_ACCESS // Generic all
  79. };
  80. GENERIC_MAPPING SsSessionMapping = {
  81. STANDARD_RIGHTS_READ | // Generic read
  82. SRVSVC_SESSION_USER_INFO_GET |
  83. SRVSVC_SESSION_ADMIN_INFO_GET,
  84. STANDARD_RIGHTS_WRITE | // Generic write
  85. SRVSVC_SESSION_DELETE,
  86. STANDARD_RIGHTS_EXECUTE, // Generic execute
  87. SRVSVC_SESSION_ALL_ACCESS // Generic all
  88. };
  89. GENERIC_MAPPING SsShareMapping = {
  90. STANDARD_RIGHTS_READ | // Generic read
  91. SRVSVC_SHARE_USER_INFO_GET |
  92. SRVSVC_SHARE_ADMIN_INFO_GET,
  93. STANDARD_RIGHTS_WRITE | // Generic write
  94. SRVSVC_SHARE_INFO_SET,
  95. STANDARD_RIGHTS_EXECUTE | // Generic execute
  96. SRVSVC_SHARE_CONNECT,
  97. SRVSVC_SHARE_ALL_ACCESS // Generic all
  98. };
  99. GENERIC_MAPPING SsShareConnectMapping = GENERIC_SHARE_CONNECT_MAPPING;
  100. GENERIC_MAPPING SsStatisticsMapping = {
  101. STANDARD_RIGHTS_READ | // Generic read
  102. SRVSVC_STATISTICS_GET,
  103. STANDARD_RIGHTS_WRITE, // Generic write
  104. STANDARD_RIGHTS_EXECUTE, // Generic execute
  105. SRVSVC_STATISTICS_ALL_ACCESS // Generic all
  106. };
  107. //
  108. // Forward declarations.
  109. //
  110. NET_API_STATUS
  111. CreateSecurityObject (
  112. PSRVSVC_SECURITY_OBJECT SecurityObject,
  113. LPTSTR ObjectName,
  114. PGENERIC_MAPPING Mapping,
  115. PACE_DATA AceData,
  116. ULONG AceDataLength,
  117. BOOLEAN bUpgradeSD
  118. );
  119. NET_API_STATUS
  120. CreateConfigInfoSecurityObject (
  121. VOID
  122. );
  123. NET_API_STATUS
  124. CreateConnectionSecurityObject (
  125. VOID
  126. );
  127. NET_API_STATUS
  128. CreateDiskSecurityObject (
  129. VOID
  130. );
  131. NET_API_STATUS
  132. CreateFileSecurityObject (
  133. VOID
  134. );
  135. NET_API_STATUS
  136. CreateSessionSecurityObject (
  137. VOID
  138. );
  139. NET_API_STATUS
  140. CreateShareSecurityObjects (
  141. VOID
  142. );
  143. NET_API_STATUS
  144. CreateStatisticsSecurityObject (
  145. VOID
  146. );
  147. VOID
  148. DeleteSecurityObject (
  149. PSRVSVC_SECURITY_OBJECT SecurityObject
  150. );
  151. NET_API_STATUS
  152. CheckNullSessionAccess(
  153. VOID
  154. );
  155. BOOLEAN
  156. AppendAllowedAceToSelfRelativeSD(
  157. DWORD AceFlags,
  158. DWORD AccessMask,
  159. PSID pNewSid,
  160. PISECURITY_DESCRIPTOR pOldSD,
  161. PSECURITY_DESCRIPTOR* ppNewSD
  162. );
  163. BOOLEAN
  164. DoesAclContainSid(
  165. PACL pAcl,
  166. PSID pSid,
  167. OPTIONAL ACCESS_MASK* pMask
  168. );
  169. NTSTATUS
  170. QueryRegDWord(
  171. PCWSTR Path,
  172. PCWSTR ValueName,
  173. LPDWORD lpResult
  174. );
  175. NTSTATUS
  176. SetRegDWord(
  177. ULONG RelativeTo,
  178. PCWSTR Path,
  179. PCWSTR ValueName,
  180. DWORD Value
  181. );
  182. NET_API_STATUS
  183. SsCreateSecurityObjects (
  184. VOID
  185. )
  186. /*++
  187. Routine Description:
  188. Sets up the objects that will be used for security in the server
  189. service APIs.
  190. Arguments:
  191. None.
  192. Return Value:
  193. NET_API_STATUS - NO_ERROR or reason for failure.
  194. --*/
  195. {
  196. NET_API_STATUS status;
  197. NTSTATUS NtStatus;
  198. DWORD dwUpgrade;
  199. DWORD dwOldRestrictAnonymous;
  200. BOOLEAN bUpdateRestrictAnonymous = FALSE;
  201. // Check whether we need to upgrade security descriptors
  202. // If the key exists, the upgrade has been done
  203. NtStatus = QueryRegDWord( FULL_SECURITY_REGISTRY_PATH, ANONYMOUS_UPGRADE_NAME, &dwUpgrade );
  204. if( !NT_SUCCESS(NtStatus) )
  205. {
  206. SsUpgradeSecurityDescriptors = TRUE;
  207. }
  208. //
  209. // Check whether or not to restrict null session access.
  210. //
  211. status = CheckNullSessionAccess();
  212. if (status != NO_ERROR) {
  213. return(status);
  214. }
  215. //
  216. // Check whether we need to regenerate the SD's because our RestrictAnonymous value changed
  217. //
  218. NtStatus = QueryRegDWord( FULL_SECURITY_REGISTRY_PATH, SAVED_ANONYMOUS_RESTRICTION_NAME, &dwOldRestrictAnonymous );
  219. if( NT_SUCCESS(NtStatus) )
  220. {
  221. if( dwOldRestrictAnonymous != (DWORD)SsRestrictNullSessions )
  222. {
  223. SsRegenerateSecurityDescriptors = TRUE;
  224. bUpdateRestrictAnonymous = TRUE;
  225. }
  226. }
  227. else
  228. {
  229. bUpdateRestrictAnonymous = TRUE;
  230. if( !SsUpgradeSecurityDescriptors )
  231. {
  232. SsRegenerateSecurityDescriptors = TRUE;
  233. }
  234. }
  235. //
  236. // Create ConfigInfo security object.
  237. //
  238. status = CreateConfigInfoSecurityObject( );
  239. if ( status != NO_ERROR ) {
  240. return status;
  241. }
  242. //
  243. // Create Connection security object.
  244. //
  245. status = CreateConnectionSecurityObject( );
  246. if ( status != NO_ERROR ) {
  247. return status;
  248. }
  249. //
  250. // Create Disk security object.
  251. //
  252. status = CreateDiskSecurityObject( );
  253. if ( status != NO_ERROR ) {
  254. return status;
  255. }
  256. //
  257. // Create File security object.
  258. //
  259. status = CreateFileSecurityObject( );
  260. if ( status != NO_ERROR ) {
  261. return status;
  262. }
  263. //
  264. // Create Session security object.
  265. //
  266. status = CreateSessionSecurityObject( );
  267. if ( status != NO_ERROR ) {
  268. return status;
  269. }
  270. //
  271. // Create Share security object.
  272. //
  273. status = CreateShareSecurityObjects( );
  274. if ( status != NO_ERROR ) {
  275. return status;
  276. }
  277. //
  278. // Create Statistics security object.
  279. //
  280. status = CreateStatisticsSecurityObject( );
  281. if ( status != NO_ERROR ) {
  282. return status;
  283. }
  284. // We upgraded them, so we don't need to do it anymore
  285. // Mark that in the registry
  286. if( SsUpgradeSecurityDescriptors )
  287. {
  288. NtStatus = SetRegDWord( RTL_REGISTRY_SERVICES, ABBREVIATED_SECURITY_REGISTRY_PATH, ANONYMOUS_UPGRADE_NAME, (DWORD)1 );
  289. if( !NT_SUCCESS(NtStatus) )
  290. {
  291. return NetpNtStatusToApiStatus(NtStatus);
  292. }
  293. }
  294. // Update the database value to the new one if necessary, or add it the first time
  295. if( bUpdateRestrictAnonymous )
  296. {
  297. NtStatus = SetRegDWord( RTL_REGISTRY_SERVICES, ABBREVIATED_SECURITY_REGISTRY_PATH, SAVED_ANONYMOUS_RESTRICTION_NAME, (DWORD)SsRestrictNullSessions );
  298. if( !NT_SUCCESS(NtStatus) )
  299. {
  300. return NetpNtStatusToApiStatus(NtStatus);
  301. }
  302. }
  303. return NO_ERROR;
  304. } // SsCreateSecurityObjects
  305. VOID
  306. SsDeleteSecurityObjects (
  307. VOID
  308. )
  309. /*++
  310. Routine Description:
  311. Deletes server service security objects.
  312. Arguments:
  313. None.
  314. Return Value:
  315. None.
  316. --*/
  317. {
  318. //
  319. // Delete ConfigInfo security objects.
  320. //
  321. DeleteSecurityObject( &SsConfigInfoSecurityObject );
  322. DeleteSecurityObject( &SsTransportEnumSecurityObject );
  323. //
  324. // Delete Connection security object.
  325. //
  326. DeleteSecurityObject( &SsConnectionSecurityObject );
  327. //
  328. // Delete File security object.
  329. //
  330. DeleteSecurityObject( &SsFileSecurityObject );
  331. //
  332. // Delete Session security object.
  333. //
  334. DeleteSecurityObject( &SsSessionSecurityObject );
  335. //
  336. // Delete Share security objects.
  337. //
  338. DeleteSecurityObject( &SsShareFileSecurityObject );
  339. DeleteSecurityObject( &SsSharePrintSecurityObject );
  340. DeleteSecurityObject( &SsShareAdminSecurityObject );
  341. DeleteSecurityObject( &SsShareConnectSecurityObject );
  342. DeleteSecurityObject( &SsShareAdmConnectSecurityObject );
  343. DeleteSecurityObject( &SsDefaultShareSecurityObject );
  344. //
  345. // Delete Statistics security object.
  346. //
  347. DeleteSecurityObject( &SsStatisticsSecurityObject );
  348. return;
  349. } // SsDeleteSecurityObjects
  350. NET_API_STATUS
  351. SsCheckAccess (
  352. IN PSRVSVC_SECURITY_OBJECT SecurityObject,
  353. IN ACCESS_MASK DesiredAccess
  354. )
  355. /*++
  356. Routine Description:
  357. Calls NetpAccessCheckAndAudit to verify that the caller of an API
  358. has the necessary access to perform the requested operation.
  359. Arguments:
  360. SecurityObject - a pointer to the server service security object
  361. that describes the security on the relevant object.
  362. DesiredAccess - the access needed to perform the requested operation.
  363. Return Value:
  364. NET_API_STATUS - NO_ERROR or reason for failure.
  365. --*/
  366. {
  367. NET_API_STATUS error;
  368. IF_DEBUG(SECURITY) {
  369. SS_PRINT(( "SsCheckAccess: validating object " FORMAT_LPTSTR ", "
  370. "access %lx\n",
  371. SecurityObject->ObjectName, DesiredAccess ));
  372. }
  373. error = NetpAccessCheckAndAudit(
  374. SERVER_DISPLAY_NAME,
  375. SecurityObject->ObjectName,
  376. SecurityObject->SecurityDescriptor,
  377. DesiredAccess,
  378. SecurityObject->Mapping
  379. );
  380. if ( error != NO_ERROR ) {
  381. IF_DEBUG(ACCESS_DENIED) {
  382. SS_PRINT(( "SsCheckAccess: NetpAccessCheckAndAudit failed for "
  383. "object " FORMAT_LPTSTR ", access %lx: %ld\n",
  384. SecurityObject->ObjectName, DesiredAccess, error ));
  385. }
  386. } else {
  387. IF_DEBUG(SECURITY) {
  388. SS_PRINT(( "SsCheckAccess: allowed access for " FORMAT_LPTSTR ", "
  389. "access %lx\n",
  390. SecurityObject->ObjectName, DesiredAccess ));
  391. }
  392. }
  393. return error;
  394. } // SsCheckAccess
  395. NET_API_STATUS
  396. CreateSecurityObject (
  397. PSRVSVC_SECURITY_OBJECT SecurityObject,
  398. LPTSTR ObjectName,
  399. PGENERIC_MAPPING Mapping,
  400. PACE_DATA AceData,
  401. ULONG AceDataLength,
  402. BOOLEAN bUpgradeSD
  403. )
  404. {
  405. NTSTATUS status;
  406. //
  407. // Set up security object.
  408. //
  409. SecurityObject->ObjectName = ObjectName;
  410. SecurityObject->Mapping = Mapping;
  411. //
  412. // Create security descriptor. If we can load it from the registry, then use it.
  413. // Else use the compiled-in value
  414. //
  415. // Get the existing SD from the registry, unless we are supposed to regenerate them due to RestrictAnonymous changing
  416. if( SsRegenerateSecurityDescriptors || !SsGetDefaultSdFromRegistry( ObjectName, &SecurityObject->SecurityDescriptor ) ) {
  417. status = NetpCreateSecurityObject(
  418. AceData,
  419. AceDataLength,
  420. SsData.SsLmsvcsGlobalData->LocalSystemSid,
  421. SsData.SsLmsvcsGlobalData->LocalSystemSid,
  422. Mapping,
  423. &SecurityObject->SecurityDescriptor
  424. );
  425. if( NT_SUCCESS( status ) ) {
  426. //
  427. // Write the value to the registry, since it wasn't there already.
  428. // Ignore any errors.
  429. //
  430. SsWriteDefaultSdToRegistry( ObjectName, SecurityObject->SecurityDescriptor );
  431. } else {
  432. IF_DEBUG(INITIALIZATION_ERRORS) {
  433. SS_PRINT(( "CreateSecurityObject: failed to create " FORMAT_LPTSTR
  434. " object: %lx\n", ObjectName, status ));
  435. }
  436. return NetpNtStatusToApiStatus( status );
  437. }
  438. }
  439. else
  440. {
  441. if( bUpgradeSD )
  442. {
  443. // We need to check if the security descriptor needs to be updated
  444. PACL pAcl;
  445. BOOL bDaclPresent, bDaclDefault;
  446. ACCESS_MASK AccessMask;
  447. if( !GetSecurityDescriptorDacl( SecurityObject->SecurityDescriptor, &bDaclPresent, &pAcl, &bDaclDefault ) )
  448. {
  449. return ERROR_INVALID_ACL;
  450. }
  451. if( bDaclPresent )
  452. {
  453. // If they have authenticated users set, but they're not restricting NULL sessions, add in the World and the Anonymous token.
  454. // If they have the World set but not Anonymous and we're not restricting NULL sessions, add Anonymous
  455. // Note that DoesAclContainSid does NOT alter AccessMask if the Sid is not contained, so we can rest assured that if the condition
  456. // is satisfied, AccessMask will contain a valid value.
  457. if( ( DoesAclContainSid( pAcl, SsData.SsLmsvcsGlobalData->AuthenticatedUserSid, &AccessMask ) ||
  458. DoesAclContainSid( pAcl, SsData.SsLmsvcsGlobalData->WorldSid, &AccessMask ) ) &&
  459. !SsRestrictNullSessions )
  460. {
  461. PSECURITY_DESCRIPTOR pNewSD;
  462. if( !DoesAclContainSid( pAcl, SsData.SsLmsvcsGlobalData->WorldSid, NULL ) )
  463. {
  464. if( !AppendAllowedAceToSelfRelativeSD( 0, AccessMask, SsData.SsLmsvcsGlobalData->WorldSid, SecurityObject->SecurityDescriptor, &pNewSD ) )
  465. {
  466. return NetpNtStatusToApiStatus( STATUS_INVALID_SECURITY_DESCR );
  467. }
  468. MIDL_user_free( SecurityObject->SecurityDescriptor );
  469. SecurityObject->SecurityDescriptor = pNewSD;
  470. if( !GetSecurityDescriptorDacl( SecurityObject->SecurityDescriptor, &bDaclPresent, &pAcl, &bDaclDefault ) )
  471. {
  472. return ERROR_INVALID_ACL;
  473. }
  474. }
  475. if( !DoesAclContainSid( pAcl, SsData.SsLmsvcsGlobalData->AnonymousLogonSid, NULL ) )
  476. {
  477. if( !AppendAllowedAceToSelfRelativeSD( 0, AccessMask, SsData.SsLmsvcsGlobalData->AnonymousLogonSid, SecurityObject->SecurityDescriptor, &pNewSD ) )
  478. {
  479. return NetpNtStatusToApiStatus( STATUS_INVALID_SECURITY_DESCR );
  480. }
  481. MIDL_user_free( SecurityObject->SecurityDescriptor );
  482. SecurityObject->SecurityDescriptor = pNewSD;
  483. }
  484. // Write the updated SID to the registry
  485. SsWriteDefaultSdToRegistry( ObjectName, SecurityObject->SecurityDescriptor );
  486. }
  487. }
  488. }
  489. }
  490. IF_DEBUG(INITIALIZATION) {
  491. SS_PRINT(( "CreateSecurityObject: created " FORMAT_LPTSTR " object.\n",
  492. ObjectName ));
  493. }
  494. return NO_ERROR;
  495. } // CreateSecurityObject
  496. NET_API_STATUS
  497. CreateConfigInfoSecurityObject (
  498. VOID
  499. )
  500. {
  501. PACE_DATA pAceData;
  502. ULONG AceSize;
  503. NET_API_STATUS netStatus;
  504. //
  505. // Required access for getting and setting server information.
  506. //
  507. ACE_DATA ConfigInfoAceData[] = {
  508. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  509. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  510. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  511. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  512. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  513. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->LocalSystemSid},
  514. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  515. SRVSVC_CONFIG_USER_INFO_GET | SRVSVC_CONFIG_POWER_INFO_GET,
  516. &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  517. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  518. SRVSVC_CONFIG_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->WorldSid},
  519. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  520. SRVSVC_CONFIG_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  521. };
  522. ACE_DATA ConfigInfoAceDataRestricted[] = {
  523. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  524. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  525. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  526. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  527. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  528. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->LocalSystemSid},
  529. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  530. SRVSVC_CONFIG_USER_INFO_GET | SRVSVC_CONFIG_POWER_INFO_GET,
  531. &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  532. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  533. SRVSVC_CONFIG_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  534. };
  535. ACE_DATA TransportEnumAceData[] = {
  536. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  537. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  538. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  539. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  540. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  541. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->LocalSystemSid},
  542. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  543. SRVSVC_CONFIG_USER_INFO_GET | SRVSVC_CONFIG_POWER_INFO_GET,
  544. &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  545. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  546. SRVSVC_CONFIG_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  547. };
  548. if( SsRestrictNullSessions )
  549. {
  550. pAceData = ConfigInfoAceDataRestricted;
  551. AceSize = sizeof(ConfigInfoAceDataRestricted)/sizeof(ACE_DATA);
  552. }
  553. else
  554. {
  555. pAceData = ConfigInfoAceData;
  556. AceSize = sizeof(ConfigInfoAceData)/sizeof(ACE_DATA);
  557. }
  558. //
  559. // Create ConfigInfo security object.
  560. //
  561. netStatus = CreateSecurityObject(
  562. &SsConfigInfoSecurityObject,
  563. SRVSVC_CONFIG_INFO_OBJECT,
  564. &SsConfigInfoMapping,
  565. pAceData,
  566. AceSize,
  567. SsUpgradeSecurityDescriptors
  568. );
  569. if( netStatus != NO_ERROR )
  570. {
  571. return netStatus;
  572. }
  573. pAceData = TransportEnumAceData;
  574. AceSize = sizeof(TransportEnumAceData)/sizeof(ACE_DATA);
  575. return CreateSecurityObject(
  576. &SsTransportEnumSecurityObject,
  577. SRVSVC_TRANSPORT_INFO_OBJECT,
  578. &SsConfigInfoMapping,
  579. pAceData,
  580. AceSize,
  581. SsUpgradeSecurityDescriptors
  582. );
  583. } // CreateConfigInfoSecurityObject
  584. NET_API_STATUS
  585. CreateConnectionSecurityObject (
  586. VOID
  587. )
  588. {
  589. //
  590. // Required access for getting and setting Connection information.
  591. //
  592. ACE_DATA ConnectionAceData[] = {
  593. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  594. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  595. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  596. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  597. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  598. SRVSVC_CONNECTION_INFO_GET, &SsData.SsLmsvcsGlobalData->AliasPrintOpsSid},
  599. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  600. SRVSVC_CONNECTION_INFO_GET, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid}
  601. };
  602. //
  603. // Create Connection security object.
  604. //
  605. return CreateSecurityObject(
  606. &SsConnectionSecurityObject,
  607. SRVSVC_CONNECTION_OBJECT,
  608. &SsConnectionMapping,
  609. ConnectionAceData,
  610. sizeof(ConnectionAceData) / sizeof(ACE_DATA),
  611. SsUpgradeSecurityDescriptors
  612. );
  613. return NO_ERROR;
  614. } // CreateConnectionSecurityObject
  615. NET_API_STATUS
  616. CreateDiskSecurityObject (
  617. VOID
  618. )
  619. {
  620. //
  621. // Required access for doing Disk enums
  622. //
  623. ACE_DATA DiskAceData[] = {
  624. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  625. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  626. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  627. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid}
  628. };
  629. //
  630. // Create Disk security object.
  631. //
  632. return CreateSecurityObject(
  633. &SsDiskSecurityObject,
  634. SRVSVC_DISK_OBJECT,
  635. &SsDiskMapping,
  636. DiskAceData,
  637. sizeof(DiskAceData) / sizeof(ACE_DATA),
  638. SsUpgradeSecurityDescriptors
  639. );
  640. } // CreateDiskSecurityObject
  641. NET_API_STATUS
  642. CreateFileSecurityObject (
  643. VOID
  644. )
  645. {
  646. //
  647. // Required access for getting and setting File information.
  648. //
  649. ACE_DATA FileAceData[] = {
  650. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  651. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  652. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  653. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  654. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  655. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid}
  656. };
  657. //
  658. // Create File security object.
  659. //
  660. return CreateSecurityObject(
  661. &SsFileSecurityObject,
  662. SRVSVC_FILE_OBJECT,
  663. &SsFileMapping,
  664. FileAceData,
  665. sizeof(FileAceData) / sizeof(ACE_DATA),
  666. SsUpgradeSecurityDescriptors
  667. );
  668. } // CreateFileSecurityObject
  669. NET_API_STATUS
  670. CreateSessionSecurityObject (
  671. VOID
  672. )
  673. {
  674. PACE_DATA pAceData;
  675. ULONG AceSize;
  676. //
  677. // Required access for getting and setting session information.
  678. //
  679. ACE_DATA SessionAceData[] = {
  680. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  681. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  682. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  683. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  684. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  685. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  686. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  687. SRVSVC_SESSION_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->WorldSid},
  688. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  689. SRVSVC_SESSION_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  690. };
  691. ACE_DATA SessionAceDataRestricted[] = {
  692. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  693. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  694. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  695. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  696. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  697. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  698. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  699. SRVSVC_SESSION_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  700. };
  701. if( SsRestrictNullSessions )
  702. {
  703. pAceData = SessionAceDataRestricted;
  704. AceSize = sizeof(SessionAceDataRestricted)/sizeof(ACE_DATA);
  705. }
  706. else
  707. {
  708. pAceData = SessionAceData;
  709. AceSize = sizeof(SessionAceData)/sizeof(ACE_DATA);
  710. }
  711. //
  712. // Create Session security object.
  713. //
  714. return CreateSecurityObject(
  715. &SsSessionSecurityObject,
  716. SRVSVC_SESSION_OBJECT,
  717. &SsSessionMapping,
  718. SessionAceData,
  719. sizeof(SessionAceData) / sizeof(ACE_DATA),
  720. SsUpgradeSecurityDescriptors
  721. );
  722. } // CreateSessionSecurityObject
  723. NET_API_STATUS
  724. CreateShareSecurityObjects (
  725. VOID
  726. )
  727. {
  728. NET_API_STATUS status;
  729. PACE_DATA pAceData;
  730. ULONG AceSize;
  731. //
  732. // Required access for getting and setting share information.
  733. //
  734. ACE_DATA ShareFileAceData[] = {
  735. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  736. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  737. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  738. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  739. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  740. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  741. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  742. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->WorldSid},
  743. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  744. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  745. };
  746. ACE_DATA ShareFileAceDataRestricted[] = {
  747. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  748. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  749. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  750. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  751. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  752. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  753. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  754. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  755. };
  756. ACE_DATA SharePrintAceData[] = {
  757. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  758. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  759. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  760. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  761. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  762. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPrintOpsSid},
  763. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  764. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  765. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  766. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->WorldSid},
  767. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  768. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  769. };
  770. ACE_DATA SharePrintAceDataRestricted[] = {
  771. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  772. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  773. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  774. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  775. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  776. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPrintOpsSid},
  777. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  778. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  779. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  780. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  781. };
  782. ACE_DATA ShareAdminAceData[] = {
  783. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  784. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  785. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  786. SRVSVC_SHARE_ADMIN_INFO_GET,
  787. &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  788. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  789. SRVSVC_SHARE_ADMIN_INFO_GET,
  790. &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  791. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  792. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->WorldSid},
  793. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  794. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  795. };
  796. ACE_DATA ShareAdminAceDataRestricted[] = {
  797. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  798. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  799. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  800. SRVSVC_SHARE_ADMIN_INFO_GET,
  801. &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  802. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  803. SRVSVC_SHARE_ADMIN_INFO_GET,
  804. &SsData.SsLmsvcsGlobalData->AliasPowerUsersSid},
  805. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  806. SRVSVC_SHARE_USER_INFO_GET, &SsData.SsLmsvcsGlobalData->AuthenticatedUserSid}
  807. };
  808. //
  809. // note for connect we always use WorldSid for backwards compat.
  810. //
  811. ACE_DATA ShareConnectAceData[] = {
  812. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  813. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  814. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  815. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  816. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  817. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasBackupOpsSid},
  818. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  819. SRVSVC_SHARE_CONNECT, &SsData.SsLmsvcsGlobalData->WorldSid},
  820. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  821. SRVSVC_SHARE_CONNECT, &SsData.SsLmsvcsGlobalData->AnonymousLogonSid}
  822. };
  823. ACE_DATA ShareAdmConnectAceData[] = {
  824. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  825. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  826. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  827. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  828. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  829. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasBackupOpsSid}
  830. };
  831. //
  832. // Create Share security objects.
  833. //
  834. if (!SsGetDefaultSdFromRegistry(
  835. SRVSVC_DEFAULT_SHARE_OBJECT,
  836. &SsDefaultShareSecurityObject.SecurityDescriptor)) {
  837. SsDefaultShareSecurityObject.SecurityDescriptor = NULL;
  838. }
  839. if( SsRestrictNullSessions )
  840. {
  841. pAceData = ShareFileAceDataRestricted;
  842. AceSize = sizeof(ShareFileAceDataRestricted)/sizeof(ACE_DATA);
  843. }
  844. else
  845. {
  846. pAceData = ShareFileAceData;
  847. AceSize = sizeof(ShareFileAceData)/sizeof(ACE_DATA);
  848. }
  849. status = CreateSecurityObject(
  850. &SsShareFileSecurityObject,
  851. SRVSVC_SHARE_FILE_OBJECT,
  852. &SsShareMapping,
  853. pAceData,
  854. AceSize,
  855. SsUpgradeSecurityDescriptors
  856. );
  857. if ( status != NO_ERROR ) {
  858. return status;
  859. }
  860. if( SsRestrictNullSessions )
  861. {
  862. pAceData = SharePrintAceDataRestricted;
  863. AceSize = sizeof(SharePrintAceDataRestricted)/sizeof(ACE_DATA);
  864. }
  865. else
  866. {
  867. pAceData = SharePrintAceData;
  868. AceSize = sizeof(SharePrintAceData)/sizeof(ACE_DATA);
  869. }
  870. status = CreateSecurityObject(
  871. &SsSharePrintSecurityObject,
  872. SRVSVC_SHARE_PRINT_OBJECT,
  873. &SsShareMapping,
  874. pAceData,
  875. AceSize,
  876. SsUpgradeSecurityDescriptors
  877. );
  878. if ( status != NO_ERROR ) {
  879. return status;
  880. }
  881. if( SsRestrictNullSessions )
  882. {
  883. pAceData = ShareAdminAceDataRestricted;
  884. AceSize = sizeof(ShareAdminAceDataRestricted)/sizeof(ACE_DATA);
  885. }
  886. else
  887. {
  888. pAceData = ShareAdminAceData;
  889. AceSize = sizeof(ShareAdminAceData)/sizeof(ACE_DATA);
  890. }
  891. status = CreateSecurityObject(
  892. &SsShareAdminSecurityObject,
  893. SRVSVC_SHARE_ADMIN_OBJECT,
  894. &SsShareMapping,
  895. pAceData,
  896. AceSize,
  897. SsUpgradeSecurityDescriptors
  898. );
  899. if ( status != NO_ERROR ) {
  900. return status;
  901. }
  902. pAceData = ShareConnectAceData;
  903. AceSize = sizeof(ShareConnectAceData)/sizeof(ACE_DATA);
  904. // Make sure the upgrade happens for this one. The upgrade
  905. // will not happen if RA != 0. We force RA=0 for this one case.
  906. {
  907. BOOLEAN restrictNullSession = SsRestrictNullSessions;
  908. SsRestrictNullSessions = FALSE;
  909. status = CreateSecurityObject(
  910. &SsShareConnectSecurityObject,
  911. SRVSVC_SHARE_CONNECT_OBJECT,
  912. &SsShareConnectMapping,
  913. pAceData,
  914. AceSize,
  915. SsUpgradeSecurityDescriptors
  916. );
  917. if ( status != NO_ERROR ) {
  918. return status;
  919. }
  920. SsRestrictNullSessions = restrictNullSession;
  921. }
  922. return CreateSecurityObject(
  923. &SsShareAdmConnectSecurityObject,
  924. SRVSVC_SHARE_ADM_CONNECT_OBJECT,
  925. &SsShareConnectMapping,
  926. ShareAdmConnectAceData,
  927. sizeof(ShareAdmConnectAceData) / sizeof(ACE_DATA),
  928. SsUpgradeSecurityDescriptors
  929. );
  930. } // CreateShareSecurityObjects
  931. NET_API_STATUS
  932. CreateStatisticsSecurityObject (
  933. VOID
  934. )
  935. {
  936. //
  937. // Required access for getting and setting Statistics information.
  938. //
  939. ACE_DATA StatisticsAceData[] = {
  940. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  941. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasAdminsSid},
  942. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  943. GENERIC_ALL, &SsData.SsLmsvcsGlobalData->AliasSystemOpsSid},
  944. {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
  945. SRVSVC_STATISTICS_GET, &SsData.SsLmsvcsGlobalData->LocalSid}
  946. };
  947. //
  948. // Create Statistics security object.
  949. //
  950. return CreateSecurityObject(
  951. &SsStatisticsSecurityObject,
  952. SRVSVC_STATISTICS_OBJECT,
  953. &SsStatisticsMapping,
  954. StatisticsAceData,
  955. sizeof(StatisticsAceData) / sizeof(ACE_DATA),
  956. SsUpgradeSecurityDescriptors
  957. );
  958. } // CreateStatisticsSecurityObject
  959. VOID
  960. DeleteSecurityObject (
  961. PSRVSVC_SECURITY_OBJECT SecurityObject
  962. )
  963. {
  964. NTSTATUS status;
  965. if ( SecurityObject->SecurityDescriptor != NULL ) {
  966. status = NetpDeleteSecurityObject(
  967. &SecurityObject->SecurityDescriptor
  968. );
  969. SecurityObject->SecurityDescriptor = NULL;
  970. if ( !NT_SUCCESS(status) ) {
  971. IF_DEBUG(TERMINATION_ERRORS) {
  972. SS_PRINT(( "DeleteSecurityObject: failed to delete "
  973. FORMAT_LPTSTR " object: %X\n",
  974. SecurityObject->ObjectName,
  975. status ));
  976. }
  977. } else {
  978. IF_DEBUG(TERMINATION) {
  979. SS_PRINT(( "DeleteSecurityObject: deleted " FORMAT_LPTSTR
  980. " object.\n",
  981. SecurityObject->ObjectName ));
  982. }
  983. }
  984. }
  985. return;
  986. } // DeleteSecurityObject
  987. NET_API_STATUS
  988. CheckNullSessionAccess(
  989. VOID
  990. )
  991. /*++
  992. Routine Description:
  993. This routine checks to see if we should restict null session access.
  994. in the registry under system\currentcontrolset\Control\Lsa\
  995. RestrictAnonymous indicating whether or not to restrict access.
  996. If access is restricted then you need to be an authenticated user to
  997. get DOMAIN_LIST_ACCOUNTS or GROUP_LIST_MEMBERS or ALIAS_LIST_MEMBERS
  998. access.
  999. Arguments:
  1000. none.
  1001. Return Value:
  1002. NO_ERROR - the routine completed sucesfully.
  1003. --*/
  1004. {
  1005. NTSTATUS NtStatus;
  1006. UNICODE_STRING KeyName;
  1007. OBJECT_ATTRIBUTES ObjectAttributes;
  1008. HANDLE KeyHandle;
  1009. UCHAR Buffer[100];
  1010. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer;
  1011. ULONG KeyValueLength = 100;
  1012. ULONG ResultLength;
  1013. PULONG Flag;
  1014. SsRestrictNullSessions = FALSE;
  1015. //
  1016. // Open the Lsa key in the registry
  1017. //
  1018. RtlInitUnicodeString(
  1019. &KeyName,
  1020. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa"
  1021. );
  1022. InitializeObjectAttributes(
  1023. &ObjectAttributes,
  1024. &KeyName,
  1025. OBJ_CASE_INSENSITIVE,
  1026. 0,
  1027. NULL
  1028. );
  1029. NtStatus = NtOpenKey(
  1030. &KeyHandle,
  1031. KEY_READ,
  1032. &ObjectAttributes
  1033. );
  1034. if (!NT_SUCCESS(NtStatus)) {
  1035. goto Cleanup;
  1036. }
  1037. RtlInitUnicodeString(
  1038. &KeyName,
  1039. L"RestrictAnonymous"
  1040. );
  1041. NtStatus = NtQueryValueKey(
  1042. KeyHandle,
  1043. &KeyName,
  1044. KeyValuePartialInformation,
  1045. KeyValueInformation,
  1046. KeyValueLength,
  1047. &ResultLength
  1048. );
  1049. if (NT_SUCCESS(NtStatus)) {
  1050. //
  1051. // Check that the data is the correct size and type - a ULONG.
  1052. //
  1053. if ((KeyValueInformation->DataLength >= sizeof(ULONG)) &&
  1054. (KeyValueInformation->Type == REG_DWORD)) {
  1055. Flag = (PULONG) KeyValueInformation->Data;
  1056. if (*Flag >= 1) {
  1057. SsRestrictNullSessions = TRUE;
  1058. }
  1059. }
  1060. }
  1061. else
  1062. {
  1063. if( NtStatus == STATUS_OBJECT_NAME_NOT_FOUND )
  1064. {
  1065. // No key means RestrictAnonymous = 0
  1066. NtStatus = STATUS_SUCCESS;
  1067. }
  1068. }
  1069. NtClose(KeyHandle);
  1070. Cleanup:
  1071. if( !NT_SUCCESS(NtStatus) )
  1072. {
  1073. return NetpNtStatusToApiStatus(NtStatus);
  1074. }
  1075. return NO_ERROR;
  1076. }
  1077. BOOLEAN
  1078. DoesAclContainSid(
  1079. PACL pAcl,
  1080. PSID pSid,
  1081. OPTIONAL ACCESS_MASK* pMask
  1082. )
  1083. /*++
  1084. Routine Description:
  1085. This walks the given Acl to see if it contains the desired SID. If it does,
  1086. we optionally also return the AccessMask associated with that SID.
  1087. NOTE: If the value is not found, this routine should NOT touch the pMask variable.
  1088. Arguments:
  1089. pAcl - A pointer to the ACL we're checking
  1090. pSid - The SID we're looking for
  1091. pMask [optional] - Where we fill in the Access Mask if they want to know it.
  1092. Return Value:
  1093. TRUE - the routine completed sucesfully.
  1094. FALSE - the routine encountered an error
  1095. --*/
  1096. {
  1097. ACE_HEADER* pAceHeader;
  1098. ACL_SIZE_INFORMATION AclSize;
  1099. PSID pAceSid;
  1100. WORD wCount;
  1101. if( !GetAclInformation( pAcl, &AclSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ) )
  1102. return FALSE;
  1103. for( wCount=0; wCount < AclSize.AceCount; wCount++ )
  1104. {
  1105. if( !GetAce( pAcl, wCount, &pAceHeader ) )
  1106. return FALSE;
  1107. switch( pAceHeader->AceType )
  1108. {
  1109. case ACCESS_ALLOWED_ACE_TYPE:
  1110. {
  1111. ACCESS_ALLOWED_ACE* pAce = (ACCESS_ALLOWED_ACE*)pAceHeader;
  1112. pAceSid = &(pAce->SidStart);
  1113. if( EqualSid( pAceSid, pSid ) )
  1114. {
  1115. if( pMask )
  1116. {
  1117. *pMask = pAce->Mask;
  1118. }
  1119. return TRUE;
  1120. }
  1121. }
  1122. break;
  1123. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  1124. {
  1125. ACCESS_ALLOWED_OBJECT_ACE* pAce = (ACCESS_ALLOWED_OBJECT_ACE*)pAceHeader;
  1126. pAceSid = &(pAce->SidStart);
  1127. if( EqualSid( pAceSid, pSid ) )
  1128. {
  1129. if( pMask )
  1130. {
  1131. *pMask = pAce->Mask;
  1132. }
  1133. return TRUE;
  1134. }
  1135. }
  1136. break;
  1137. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  1138. case ACCESS_DENIED_ACE_TYPE:
  1139. case SYSTEM_AUDIT_ACE_TYPE:
  1140. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  1141. {
  1142. continue;
  1143. }
  1144. }
  1145. }
  1146. return FALSE;
  1147. }
  1148. BOOLEAN
  1149. AppendAllowedAceToSelfRelativeSD(
  1150. DWORD AceFlags,
  1151. DWORD AccessMask,
  1152. PSID pNewSid,
  1153. PISECURITY_DESCRIPTOR pOldSD,
  1154. PSECURITY_DESCRIPTOR* ppNewSD
  1155. )
  1156. /*++
  1157. Routine Description:
  1158. This routine creates a new Security Descriptor that contains the original SD plus
  1159. appends the new SID (with the given Access). The final SD is in Self-Relative form.
  1160. Arguments:
  1161. AceFlags - The flags associated with this ACE in the SD
  1162. AccessMask - The AccessMask for this ACE
  1163. pNewSid - The SID for this ACE
  1164. pOldSD - The original Security Descriptor
  1165. ppNewSid - OUT pointer to the newly allocated Security Descriptor
  1166. Return Value:
  1167. TRUE - the routine completed sucesfully.
  1168. FALSE - the routine encountered an error
  1169. --*/
  1170. {
  1171. BOOLEAN bSelfRelative;
  1172. SECURITY_DESCRIPTOR NewSDBuffer;
  1173. PISECURITY_DESCRIPTOR pNewSD, pSelfRelativeSD;
  1174. NTSTATUS Status;
  1175. BOOLEAN bResult = FALSE;
  1176. PACL pAcl, pNewAcl;
  1177. DWORD dwNewAclSize;
  1178. DWORD dwRelativeSDLength;
  1179. PSID pSid;
  1180. pNewAcl = NULL;
  1181. pSelfRelativeSD = NULL;
  1182. // Make sure it is self relative
  1183. if( !RtlpAreControlBitsSet( pOldSD, SE_SELF_RELATIVE ) )
  1184. return FALSE;
  1185. // Convert it to absolute
  1186. pNewSD = &NewSDBuffer;
  1187. Status = RtlCreateSecurityDescriptor( pNewSD, SECURITY_DESCRIPTOR_REVISION );
  1188. if( !NT_SUCCESS(Status) )
  1189. goto Cleanup;
  1190. // Copy in the new information
  1191. pNewSD->Control = pOldSD->Control;
  1192. RtlpClearControlBits( pNewSD, SE_SELF_RELATIVE );
  1193. pSid = RtlpOwnerAddrSecurityDescriptor( pOldSD );
  1194. if( pSid )
  1195. {
  1196. pNewSD->Owner = pSid;
  1197. }
  1198. pSid = RtlpGroupAddrSecurityDescriptor( pOldSD );
  1199. if( pSid )
  1200. {
  1201. pNewSD->Group = pSid;
  1202. }
  1203. pAcl = RtlpSaclAddrSecurityDescriptor( pOldSD );
  1204. if( pAcl )
  1205. {
  1206. pNewSD->Sacl = pAcl;
  1207. }
  1208. // Assemble the new ACL
  1209. pAcl = RtlpDaclAddrSecurityDescriptor( pOldSD );
  1210. if( !pAcl )
  1211. {
  1212. goto Cleanup;
  1213. }
  1214. dwNewAclSize = pAcl->AclSize + sizeof(KNOWN_ACE) + GetLengthSid( pNewSid );
  1215. pNewAcl = MIDL_user_allocate( dwNewAclSize );
  1216. if( !pNewAcl )
  1217. {
  1218. goto Cleanup;
  1219. }
  1220. // Copy the old information in
  1221. RtlCopyMemory( pNewAcl, pAcl, pAcl->AclSize );
  1222. pNewAcl->AclSize = (USHORT)dwNewAclSize;
  1223. // Add in the new ACE
  1224. if( !AddAccessAllowedAceEx( pNewAcl, ACL_REVISION, AceFlags, AccessMask, pNewSid ) )
  1225. {
  1226. goto Cleanup;
  1227. }
  1228. // Set the new DACL in the SD
  1229. Status = RtlSetDaclSecurityDescriptor( pNewSD, TRUE, pNewAcl, FALSE );
  1230. if( !NT_SUCCESS(Status) )
  1231. {
  1232. goto Cleanup;
  1233. }
  1234. dwRelativeSDLength = 0;
  1235. // Get the size of the self relative SD
  1236. Status = RtlMakeSelfRelativeSD( pNewSD, NULL, &dwRelativeSDLength );
  1237. if( NT_SUCCESS(Status) )
  1238. {
  1239. // No way we can succeed here
  1240. ASSERT(FALSE);
  1241. goto Cleanup;
  1242. }
  1243. pSelfRelativeSD = MIDL_user_allocate( dwRelativeSDLength );
  1244. if( !pSelfRelativeSD )
  1245. {
  1246. goto Cleanup;
  1247. }
  1248. Status = RtlMakeSelfRelativeSD( pNewSD, pSelfRelativeSD, &dwRelativeSDLength );
  1249. if( !NT_SUCCESS(Status) )
  1250. {
  1251. goto Cleanup;
  1252. }
  1253. // All set. Let it be set and go.
  1254. *ppNewSD = pSelfRelativeSD;
  1255. bResult = TRUE;
  1256. Cleanup:
  1257. if( pNewAcl )
  1258. {
  1259. MIDL_user_free( pNewAcl );
  1260. pNewAcl = NULL;
  1261. }
  1262. if( !bResult )
  1263. {
  1264. if( pSelfRelativeSD )
  1265. {
  1266. MIDL_user_free( pSelfRelativeSD );
  1267. }
  1268. }
  1269. return bResult;
  1270. }
  1271. NTSTATUS
  1272. QueryRegDWord(
  1273. PCWSTR Path,
  1274. PCWSTR ValueName,
  1275. LPDWORD lpResult
  1276. )
  1277. {
  1278. NTSTATUS NtStatus;
  1279. UNICODE_STRING KeyName;
  1280. OBJECT_ATTRIBUTES ObjectAttributes;
  1281. HANDLE KeyHandle;
  1282. UCHAR Buffer[100];
  1283. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer;
  1284. ULONG KeyValueLength = 100;
  1285. ULONG ResultLength;
  1286. PULONG pValue;
  1287. //
  1288. // Open the Lsa key in the registry
  1289. //
  1290. RtlInitUnicodeString(
  1291. &KeyName,
  1292. Path
  1293. );
  1294. InitializeObjectAttributes(
  1295. &ObjectAttributes,
  1296. &KeyName,
  1297. OBJ_CASE_INSENSITIVE,
  1298. 0,
  1299. NULL
  1300. );
  1301. NtStatus = NtOpenKey(
  1302. &KeyHandle,
  1303. KEY_READ,
  1304. &ObjectAttributes
  1305. );
  1306. if (!NT_SUCCESS(NtStatus)) {
  1307. goto Cleanup;
  1308. }
  1309. RtlInitUnicodeString(
  1310. &KeyName,
  1311. ValueName
  1312. );
  1313. NtStatus = NtQueryValueKey(
  1314. KeyHandle,
  1315. &KeyName,
  1316. KeyValuePartialInformation,
  1317. KeyValueInformation,
  1318. KeyValueLength,
  1319. &ResultLength
  1320. );
  1321. if (NT_SUCCESS(NtStatus)) {
  1322. //
  1323. // Check that the data is the correct size and type - a ULONG.
  1324. //
  1325. if ((KeyValueInformation->DataLength >= sizeof(ULONG)) &&
  1326. (KeyValueInformation->Type == REG_DWORD)) {
  1327. pValue = (PULONG) KeyValueInformation->Data;
  1328. *lpResult = (*pValue);
  1329. }
  1330. }
  1331. NtClose(KeyHandle);
  1332. Cleanup:
  1333. return NtStatus;
  1334. }
  1335. NTSTATUS
  1336. SetRegDWord(
  1337. ULONG RelativeTo,
  1338. PCWSTR Path,
  1339. PCWSTR ValueName,
  1340. DWORD Value
  1341. )
  1342. {
  1343. return RtlWriteRegistryValue( RelativeTo, Path, ValueName, REG_DWORD, (PVOID)(&Value), sizeof(DWORD) );
  1344. }