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.

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