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.

1121 lines
30 KiB

  1. /*************************************************************************
  2. *
  3. * security.c
  4. *
  5. * NT Security routines
  6. *
  7. * copyright notice: Copyright 1997, Microsoft
  8. *
  9. *************************************************************************/
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <ntexapi.h>
  14. #include <ntseapi.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. #include <windows.h>
  19. #include <string.h>
  20. #include <wcstr.h>
  21. #include "seopaque.h"
  22. #include "sertlp.h"
  23. #include <process.h>
  24. #include <winsta.h>
  25. #include <syslib.h>
  26. #include <lmcons.h> // for DNLEN KLB 09-18-96
  27. #include "security.h"
  28. #if DBG
  29. ULONG
  30. DbgPrint(
  31. PCH Format,
  32. ...
  33. );
  34. #define DBGPRINT(x) DbgPrint x
  35. #if DBGTRACE
  36. #define TRACE0(x) DbgPrint x
  37. #define TRACE1(x) DbgPrint x
  38. #else
  39. #define TRACE0(x)
  40. #define TRACE1(x)
  41. #endif
  42. #else
  43. #define DBGPRINT(x)
  44. #define TRACE0(x)
  45. #define TRACE1(x)
  46. #endif
  47. typedef struct _SIDLIST {
  48. struct _SIDLIST *Next;
  49. USHORT SidCrc;
  50. PWCHAR pAccountName;
  51. PWCHAR pDomainName;
  52. } SIDLIST, *PSIDLIST;
  53. static PSIDLIST SidCache = NULL;
  54. // Computer Name
  55. WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1];
  56. // Admins only ACL
  57. PACL pAdminsOnlyAcl = NULL;
  58. DWORD AdminsOnlyAclSize = 0;
  59. //
  60. // Universal well known SIDs
  61. //
  62. PSID SeNullSid;
  63. PSID SeWorldSid;
  64. PSID SeLocalSid;
  65. PSID SeCreatorOwnerSid;
  66. PSID SeCreatorGroupSid;
  67. //
  68. // Sids defined by NT
  69. //
  70. PSID SeNtAuthoritySid;
  71. PSID SeDialupSid;
  72. PSID SeNetworkSid;
  73. PSID SeBatchSid;
  74. PSID SeInteractiveSid;
  75. PSID SeServiceSid;
  76. PSID SeLocalGuestSid;
  77. PSID SeLocalSystemSid;
  78. PSID SeLocalAdminSid;
  79. PSID SeLocalManagerSid;
  80. PSID SeAliasAdminsSid;
  81. PSID SeAliasUsersSid;
  82. PSID SeAliasGuestsSid;
  83. PSID SeAliasPowerUsersSid;
  84. PSID SeAliasAccountOpsSid;
  85. PSID SeAliasSystemOpsSid;
  86. PSID SeAliasPrintOpsSid;
  87. PSID SeAliasBackupOpsSid;
  88. PSID SeAliasReplicatorSid;
  89. static SID_IDENTIFIER_AUTHORITY SepNullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
  90. static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  91. static SID_IDENTIFIER_AUTHORITY SepLocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
  92. static SID_IDENTIFIER_AUTHORITY SepCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
  93. static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY;
  94. //
  95. // Sid of primary domain, and admin account in that domain
  96. //
  97. PSID SepPrimaryDomainSid;
  98. PSID SepPrimaryDomainAdminSid;
  99. // External data
  100. extern ADMIN_ACCOUNTS AllowAccounts[];
  101. extern DWORD AllowAccountEntries;
  102. extern ACCESS_MASK AllowAccess;
  103. extern ADMIN_ACCOUNTS DenyAccounts[];
  104. extern DWORD DenyAccountEntries;
  105. extern ACCESS_MASK DeniedAccess;
  106. // Forward and external references
  107. BOOLEAN
  108. InitializeBuiltinSids();
  109. BOOL
  110. LoadAccountSids();
  111. BOOL
  112. BuildSecureAcl();
  113. BOOL
  114. xxxLookupBuiltinAccount(
  115. PWCHAR pSystemName,
  116. PWCHAR pAccountName,
  117. PSID *ppSid
  118. );
  119. BOOL
  120. GetCurrentUserSid( PSID *ppSid );
  121. /*****************************************************************************
  122. *
  123. * InitSecurity
  124. *
  125. * Initialize the security package
  126. *
  127. * ENTRY:
  128. * Param1 (input/output)
  129. * Comments
  130. *
  131. * EXIT:
  132. * TRUE - no error
  133. * FALSE - error
  134. *
  135. ****************************************************************************/
  136. BOOL
  137. InitSecurity(
  138. )
  139. {
  140. BOOL rc;
  141. DWORD Size = sizeof(ComputerName)/sizeof(WCHAR);
  142. rc = GetComputerNameW( ComputerName, &Size );
  143. if( !rc ) {
  144. DBGPRINT(("***ERROR*** %d Could not get computer name\n",GetLastError() ));
  145. return( FALSE );
  146. }
  147. rc = InitializeBuiltinSids();
  148. if( !rc ) {
  149. DBGPRINT(("***ERROR*** Some built-in accounts not loaded\n"));
  150. return( FALSE );
  151. }
  152. rc = LoadAccountSids();
  153. if( !rc ) {
  154. DBGPRINT(("***ERROR*** Some accounts not loaded\n"));
  155. return( FALSE );
  156. }
  157. rc = BuildSecureAcl();
  158. if( !rc ) {
  159. DBGPRINT(("***ERROR*** Could not build ACL\n"));
  160. return( FALSE );
  161. }
  162. return( TRUE );
  163. }
  164. /*****************************************************************************
  165. *
  166. * LoadAccountSids
  167. *
  168. * Load the list of account access SIDS.
  169. *
  170. *
  171. * ENTRY:
  172. * Param1 (input/output)
  173. * Comments
  174. *
  175. * EXIT:
  176. * STATUS_SUCCESS - no error
  177. *
  178. ****************************************************************************/
  179. BOOL
  180. LoadAccountSids()
  181. {
  182. BOOL rc, Final;
  183. NTSTATUS Status;
  184. SID_IDENTIFIER_AUTHORITY gSystemSidAuthority = SECURITY_NT_AUTHORITY;
  185. Final = TRUE;
  186. //
  187. // Get the SID's for all of the allow accounts
  188. //
  189. //
  190. // Get the SID of the built-in Administrators group
  191. //
  192. Status = RtlAllocateAndInitializeSid(
  193. &gSystemSidAuthority,
  194. 2,
  195. SECURITY_BUILTIN_DOMAIN_RID,
  196. DOMAIN_ALIAS_RID_ADMINS,
  197. 0,0,0,0,0,0,
  198. &(AllowAccounts[ADMIN_ACCOUNT].pSid));
  199. if (!NT_SUCCESS(Status)) {
  200. DBGPRINT(("SYSLIB: Couldn't allocate Administrators SID (0x%x)\n", Status ));
  201. Final = FALSE;
  202. }
  203. //
  204. // SYSTEM
  205. //
  206. Status = RtlAllocateAndInitializeSid(
  207. &gSystemSidAuthority,
  208. 1,
  209. SECURITY_LOCAL_SYSTEM_RID,
  210. 0,0,0,0,0,0,0,
  211. &(AllowAccounts[SYSTEM_ACCOUNT].pSid));
  212. if (!NT_SUCCESS(Status)) {
  213. DBGPRINT(("SYSLIB: Couldn't allocate SYSTEM SID (0x%x)\n", Status ));
  214. Final = FALSE;
  215. }
  216. //
  217. // Get the current user's Sid
  218. //
  219. rc = xxxLookupAccountName(
  220. ComputerName,
  221. CURRENT_USER,
  222. &(AllowAccounts[USER_ACCOUNT].pSid)
  223. );
  224. if ( !rc ) {
  225. // It might be a special builtin account
  226. rc = xxxLookupBuiltinAccount(
  227. ComputerName,
  228. CURRENT_USER,
  229. &(AllowAccounts[USER_ACCOUNT].pSid)
  230. );
  231. if( !rc ) {
  232. DBGPRINT(("***WARNING*** Could not find SID for current user account, Error %d\n", GetLastError() ));
  233. Final = FALSE;
  234. }
  235. }
  236. #ifdef notdef
  237. //
  238. // Lookup the SID's for all of the deny accounts
  239. //
  240. for( Index = 0; Index < DenyAccountEntries; Index++ ) {
  241. p = &DenyAccounts[Index];
  242. rc = xxxLookupAccountName(
  243. ComputerName,
  244. p->Name,
  245. &p->pSid
  246. );
  247. if( !rc ) {
  248. // It might be a special builtin account
  249. rc = xxxLookupBuiltinAccount(
  250. ComputerName,
  251. p->Name,
  252. &p->pSid
  253. );
  254. if( !rc ) {
  255. DBGPRINT(("***WARNING*** Could not find SID for account %ws Error %d\n",p->Name,GetLastError() ));
  256. Final = FALSE;
  257. }
  258. }
  259. }
  260. #endif
  261. // Lower level function outputs if any accounts are invalid
  262. return( Final );
  263. }
  264. /*****************************************************************************
  265. *
  266. * IsAllowSid
  267. *
  268. * Returns whether the supplied SID is in the allow group
  269. *
  270. *
  271. * ENTRY:
  272. * Param1 (input/output)
  273. * Comments
  274. *
  275. * EXIT:
  276. * STATUS_SUCCESS - no error
  277. *
  278. ****************************************************************************/
  279. BOOL
  280. IsAllowSid(
  281. PSID pSid
  282. )
  283. {
  284. DWORD Index;
  285. PADMIN_ACCOUNTS p;
  286. BOOL AllowSid = FALSE;
  287. for( Index = 0; Index < AllowAccountEntries; Index++ ) {
  288. p = &AllowAccounts[Index];
  289. if( p->pSid && EqualSid( pSid, p->pSid ) ) {
  290. // The Sid is for an allowed account
  291. AllowSid = TRUE;
  292. break;
  293. }
  294. }
  295. return( AllowSid );
  296. }
  297. /*****************************************************************************
  298. *
  299. * xxxLookupAccountName
  300. *
  301. * Wrapper to lookup the SID for a given account name
  302. *
  303. * Returns a pointer to the SID in newly allocated memory
  304. *
  305. * ENTRY:
  306. * Param1 (input/output)
  307. * Comments
  308. *
  309. * EXIT:
  310. * STATUS_SUCCESS - no error
  311. *
  312. ****************************************************************************/
  313. BOOL
  314. xxxLookupAccountName(
  315. PWCHAR pSystemName,
  316. PWCHAR pAccountName,
  317. PSID *ppSid
  318. )
  319. {
  320. BOOL rc;
  321. DWORD Size, DomainSize, Error;
  322. SID_NAME_USE Type;
  323. PWCHAR pDomain = NULL;
  324. PSID pSid = NULL;
  325. WCHAR Buf;
  326. WCHAR pCurrentUser[MAX_ACCOUNT_NAME]; // KLB 09-16-96
  327. DWORD dwCurrentUser = MAX_ACCOUNT_NAME; // KLB 09-16-96
  328. WCHAR pAccountToLookup[MAX_ACCOUNT_NAME+DNLEN+1]; // KLB 09-18-96
  329. LPWSTR pLogon32DomainName = NULL; // KLB 09-19-96
  330. WINSTATIONINFORMATION WinInfo; // KLB 09-30-96
  331. ULONG ReturnLength; // KLB 09-30-96
  332. Size = 0;
  333. DomainSize = 0;
  334. /*
  335. * Open the WinStation and Query its information.
  336. */
  337. memset( &WinInfo, 0, sizeof(WINSTATIONINFORMATION) );
  338. rc = WinStationQueryInformation( SERVERNAME_CURRENT,
  339. LOGONID_CURRENT,
  340. WinStationInformation,
  341. (PVOID)&WinInfo,
  342. sizeof(WINSTATIONINFORMATION),
  343. &ReturnLength );
  344. if ( !rc ) {
  345. DBGPRINT(("error querying winstation information %d.\n", GetLastError() ));
  346. return( FALSE );
  347. }
  348. if( ReturnLength != sizeof(WINSTATIONINFORMATION) ) {
  349. DBGPRINT(("winstation info version mismatch!\n"));
  350. return( FALSE );
  351. }
  352. if (lstrcmpi(pAccountName,CURRENT_USER) == 0) {
  353. lstrcpy( pAccountToLookup, WinInfo.Domain );
  354. lstrcat( pAccountToLookup, L"\\" );
  355. lstrcat( pAccountToLookup, WinInfo.UserName );
  356. } else {
  357. lstrcpy( pAccountToLookup, pAccountName );
  358. }
  359. DBGPRINT(( "looking up account %ws\n", pAccountToLookup ));
  360. rc = LookupAccountNameW(
  361. pSystemName,
  362. pAccountToLookup, // KLB 09-16-96
  363. &Buf, // pSid
  364. &Size,
  365. &Buf, // pDomain
  366. &DomainSize,
  367. &Type
  368. );
  369. if( rc ) {
  370. DBGPRINT(("Internal error on account name %ws\n",pAccountToLookup));
  371. return( FALSE );
  372. }
  373. else {
  374. Error = GetLastError();
  375. if( Error != ERROR_INSUFFICIENT_BUFFER ) {
  376. DBGPRINT(("***ERROR*** %d looking up SID for account name %ws skipped without processing!\n",Error,pAccountToLookup));
  377. return( FALSE );
  378. }
  379. pSid = LocalAlloc( LMEM_FIXED, Size );
  380. if( pSid == NULL ) {
  381. DBGPRINT(("***ERROR*** Out of memory, skipped account %ws without processing!\n",pAccountToLookup));
  382. return( FALSE );
  383. }
  384. pDomain = LocalAlloc( LMEM_FIXED, DomainSize*sizeof(WCHAR) );
  385. if( pDomain == NULL ) {
  386. DBGPRINT(("***ERROR*** Out of memory, skipped account %ws without processing!\n",pAccountToLookup));
  387. LocalFree( pSid );
  388. return( FALSE );
  389. }
  390. rc = LookupAccountNameW(
  391. pSystemName,
  392. pAccountToLookup,
  393. pSid,
  394. &Size,
  395. pDomain,
  396. &DomainSize,
  397. &Type
  398. );
  399. if( !rc ) {
  400. DBGPRINT(("***ERROR*** %d looking up SID for account name %ws skipped without processing!\n",Error,pAccountToLookup));
  401. LocalFree( pSid );
  402. LocalFree( pDomain );
  403. return( FALSE );
  404. }
  405. *ppSid = pSid;
  406. LocalFree( pDomain );
  407. DBGPRINT(( "leaving xxxLookupAccountName(); pSid is okay, returning TRUE.\n" ));
  408. return( TRUE );
  409. }
  410. }
  411. /*****************************************************************************
  412. *
  413. * InitializeBuiltinSids
  414. *
  415. * Initialize the built in SIDS
  416. *
  417. * ENTRY:
  418. * Param1 (input/output)
  419. * Comments
  420. *
  421. * EXIT:
  422. * STATUS_SUCCESS - no error
  423. *
  424. ****************************************************************************/
  425. BOOLEAN
  426. InitializeBuiltinSids()
  427. {
  428. ULONG SidWithZeroSubAuthorities;
  429. ULONG SidWithOneSubAuthority;
  430. ULONG SidWithTwoSubAuthorities;
  431. ULONG SidWithThreeSubAuthorities;
  432. SID_IDENTIFIER_AUTHORITY NullSidAuthority;
  433. SID_IDENTIFIER_AUTHORITY WorldSidAuthority;
  434. SID_IDENTIFIER_AUTHORITY LocalSidAuthority;
  435. SID_IDENTIFIER_AUTHORITY CreatorSidAuthority;
  436. SID_IDENTIFIER_AUTHORITY SeNtAuthority;
  437. NullSidAuthority = SepNullSidAuthority;
  438. WorldSidAuthority = SepWorldSidAuthority;
  439. LocalSidAuthority = SepLocalSidAuthority;
  440. CreatorSidAuthority = SepCreatorSidAuthority;
  441. SeNtAuthority = SepNtAuthority;
  442. //
  443. // The following SID sizes need to be allocated
  444. //
  445. SidWithZeroSubAuthorities = RtlLengthRequiredSid( 0 );
  446. SidWithOneSubAuthority = RtlLengthRequiredSid( 1 );
  447. SidWithTwoSubAuthorities = RtlLengthRequiredSid( 2 );
  448. SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 );
  449. //
  450. // Allocate and initialize the universal SIDs
  451. //
  452. SeNullSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  453. SeWorldSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  454. SeLocalSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  455. SeCreatorOwnerSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  456. SeCreatorGroupSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  457. //
  458. // Fail initialization if we didn't get enough memory for the universal
  459. // SIDs.
  460. //
  461. if ( (SeNullSid == NULL) ||
  462. (SeWorldSid == NULL) ||
  463. (SeLocalSid == NULL) ||
  464. (SeCreatorOwnerSid == NULL) ||
  465. (SeCreatorGroupSid == NULL)
  466. ) {
  467. return( FALSE );
  468. }
  469. RtlInitializeSid( SeNullSid, &NullSidAuthority, 1 );
  470. RtlInitializeSid( SeWorldSid, &WorldSidAuthority, 1 );
  471. RtlInitializeSid( SeLocalSid, &LocalSidAuthority, 1 );
  472. RtlInitializeSid( SeCreatorOwnerSid, &CreatorSidAuthority, 1 );
  473. RtlInitializeSid( SeCreatorGroupSid, &CreatorSidAuthority, 1 );
  474. *(RtlSubAuthoritySid( SeNullSid, 0 )) = SECURITY_NULL_RID;
  475. *(RtlSubAuthoritySid( SeWorldSid, 0 )) = SECURITY_WORLD_RID;
  476. *(RtlSubAuthoritySid( SeLocalSid, 0 )) = SECURITY_LOCAL_RID;
  477. *(RtlSubAuthoritySid( SeCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
  478. *(RtlSubAuthoritySid( SeCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
  479. //
  480. // Allocate and initialize the NT defined SIDs
  481. //
  482. SeNtAuthoritySid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithZeroSubAuthorities);
  483. SeDialupSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  484. SeNetworkSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  485. SeBatchSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  486. SeInteractiveSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  487. SeServiceSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  488. SeLocalGuestSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  489. SeLocalSystemSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  490. SeLocalAdminSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  491. SeLocalManagerSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
  492. SeAliasAdminsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  493. SeAliasUsersSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  494. SeAliasGuestsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  495. SeAliasPowerUsersSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  496. SeAliasAccountOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  497. SeAliasSystemOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  498. SeAliasPrintOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  499. SeAliasBackupOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  500. SeAliasReplicatorSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
  501. //
  502. // Fail initialization if we didn't get enough memory for the NT SIDs.
  503. //
  504. if ( (SeNtAuthoritySid == NULL) ||
  505. (SeDialupSid == NULL) ||
  506. (SeNetworkSid == NULL) ||
  507. (SeBatchSid == NULL) ||
  508. (SeInteractiveSid == NULL) ||
  509. (SeServiceSid == NULL) ||
  510. (SeLocalGuestSid == NULL) ||
  511. (SeLocalSystemSid == NULL) ||
  512. (SeLocalAdminSid == NULL) ||
  513. (SeLocalManagerSid == NULL) ||
  514. (SeAliasAdminsSid == NULL) ||
  515. (SeAliasUsersSid == NULL) ||
  516. (SeAliasGuestsSid == NULL) ||
  517. (SeAliasPowerUsersSid == NULL) ||
  518. (SeAliasAccountOpsSid == NULL) ||
  519. (SeAliasSystemOpsSid == NULL) ||
  520. (SeAliasReplicatorSid == NULL) ||
  521. (SeAliasPrintOpsSid == NULL) ||
  522. (SeAliasBackupOpsSid == NULL)
  523. ) {
  524. return( FALSE );
  525. }
  526. RtlInitializeSid( SeNtAuthoritySid, &SeNtAuthority, 0 );
  527. RtlInitializeSid( SeDialupSid, &SeNtAuthority, 1 );
  528. RtlInitializeSid( SeNetworkSid, &SeNtAuthority, 1 );
  529. RtlInitializeSid( SeBatchSid, &SeNtAuthority, 1 );
  530. RtlInitializeSid( SeInteractiveSid, &SeNtAuthority, 1 );
  531. RtlInitializeSid( SeServiceSid, &SeNtAuthority, 1 );
  532. RtlInitializeSid( SeLocalGuestSid, &SeNtAuthority, 1 );
  533. RtlInitializeSid( SeLocalSystemSid, &SeNtAuthority, 1 );
  534. RtlInitializeSid( SeLocalAdminSid, &SeNtAuthority, 1 );
  535. RtlInitializeSid( SeLocalManagerSid, &SeNtAuthority, 1 );
  536. RtlInitializeSid( SeAliasAdminsSid, &SeNtAuthority, 2);
  537. RtlInitializeSid( SeAliasUsersSid, &SeNtAuthority, 2);
  538. RtlInitializeSid( SeAliasGuestsSid, &SeNtAuthority, 2);
  539. RtlInitializeSid( SeAliasPowerUsersSid, &SeNtAuthority, 2);
  540. RtlInitializeSid( SeAliasAccountOpsSid, &SeNtAuthority, 2);
  541. RtlInitializeSid( SeAliasSystemOpsSid, &SeNtAuthority, 2);
  542. RtlInitializeSid( SeAliasPrintOpsSid, &SeNtAuthority, 2);
  543. RtlInitializeSid( SeAliasBackupOpsSid, &SeNtAuthority, 2);
  544. RtlInitializeSid( SeAliasReplicatorSid, &SeNtAuthority, 2);
  545. *(RtlSubAuthoritySid( SeDialupSid, 0 )) = SECURITY_DIALUP_RID;
  546. *(RtlSubAuthoritySid( SeNetworkSid, 0 )) = SECURITY_NETWORK_RID;
  547. *(RtlSubAuthoritySid( SeBatchSid, 0 )) = SECURITY_BATCH_RID;
  548. *(RtlSubAuthoritySid( SeInteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID;
  549. *(RtlSubAuthoritySid( SeServiceSid, 0 )) = SECURITY_SERVICE_RID;
  550. // *(RtlSubAuthoritySid( SeLocalGuestSid, 0 )) = SECURITY_LOCAL_GUESTS_RID;
  551. *(RtlSubAuthoritySid( SeLocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
  552. // *(RtlSubAuthoritySid( SeLocalAdminSid, 0 )) = SECURITY_LOCAL_ADMIN_RID;
  553. // *(RtlSubAuthoritySid( SeLocalManagerSid, 0 )) = SECURITY_LOCAL_MANAGER_RID;
  554. *(RtlSubAuthoritySid( SeAliasAdminsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  555. *(RtlSubAuthoritySid( SeAliasUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  556. *(RtlSubAuthoritySid( SeAliasGuestsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  557. *(RtlSubAuthoritySid( SeAliasPowerUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  558. *(RtlSubAuthoritySid( SeAliasAccountOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  559. *(RtlSubAuthoritySid( SeAliasSystemOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  560. *(RtlSubAuthoritySid( SeAliasPrintOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  561. *(RtlSubAuthoritySid( SeAliasBackupOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  562. *(RtlSubAuthoritySid( SeAliasReplicatorSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  563. *(RtlSubAuthoritySid( SeAliasAdminsSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;
  564. *(RtlSubAuthoritySid( SeAliasUsersSid, 1 )) = DOMAIN_ALIAS_RID_USERS;
  565. *(RtlSubAuthoritySid( SeAliasGuestsSid, 1 )) = DOMAIN_ALIAS_RID_GUESTS;
  566. *(RtlSubAuthoritySid( SeAliasPowerUsersSid, 1 )) = DOMAIN_ALIAS_RID_POWER_USERS;
  567. *(RtlSubAuthoritySid( SeAliasAccountOpsSid, 1 )) = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
  568. *(RtlSubAuthoritySid( SeAliasSystemOpsSid, 1 )) = DOMAIN_ALIAS_RID_SYSTEM_OPS;
  569. *(RtlSubAuthoritySid( SeAliasPrintOpsSid, 1 )) = DOMAIN_ALIAS_RID_PRINT_OPS;
  570. *(RtlSubAuthoritySid( SeAliasBackupOpsSid, 1 )) = DOMAIN_ALIAS_RID_BACKUP_OPS;
  571. *(RtlSubAuthoritySid( SeAliasReplicatorSid, 1 )) = DOMAIN_ALIAS_RID_REPLICATOR;
  572. return( TRUE );
  573. }
  574. /*****************************************************************************
  575. *
  576. * xxxLookupBuiltinAccount
  577. *
  578. * Wrapper to lookup the SID for a given built in account name
  579. *
  580. * Returns a pointer to the SID in newly allocated memory
  581. *
  582. * ENTRY:
  583. * Param1 (input/output)
  584. * Comments
  585. *
  586. * EXIT:
  587. * STATUS_SUCCESS - no error
  588. *
  589. ****************************************************************************/
  590. BOOL
  591. xxxLookupBuiltinAccount(
  592. PWCHAR pSystemName,
  593. PWCHAR pAccountName,
  594. PSID *ppSid
  595. )
  596. {
  597. USHORT SidLen;
  598. SID_NAME_USE Type;
  599. PSID pSid = NULL;
  600. if( _wcsicmp( L"NULL_SID", pAccountName ) == 0 ) {
  601. pSid = SeNullSid;
  602. Type = SidTypeInvalid;
  603. }
  604. if( pSid == NULL ) {
  605. SetLastError( ERROR_NONE_MAPPED );
  606. return( FALSE );
  607. }
  608. SidLen = (USHORT)GetLengthSid( pSid );
  609. *ppSid = LocalAlloc(LMEM_FIXED, SidLen );
  610. if( *ppSid == NULL ) {
  611. SetLastError( ERROR_INSUFFICIENT_BUFFER );
  612. return( FALSE );
  613. }
  614. RtlMoveMemory( *ppSid, pSid, SidLen );
  615. return( TRUE );
  616. #ifdef notdef
  617. if( EqualSid( SeNullSid, pSid ) ) {
  618. pName = L"NULL_SID";
  619. Type = SidTypeInvalid;
  620. }
  621. if( EqualSid( SeWorldSid, pSid ) ) {
  622. pName = L"WORLD";
  623. Type = SidTypeWellKnownGroup;
  624. }
  625. if( EqualSid( SeLocalSid, pSid ) ) {
  626. pName = L"LOCAL_ACCOUNT";
  627. Type = SidTypeWellKnownGroup;
  628. }
  629. if( EqualSid( SeCreatorOwnerSid, pSid ) ) {
  630. pName = L"CREATOR_OWNER";
  631. Type = SidTypeWellKnownGroup;
  632. }
  633. if( EqualSid( SeCreatorGroupSid, pSid ) ) {
  634. pName = L"CREATOR_GROUP";
  635. Type = SidTypeWellKnownGroup;
  636. }
  637. //
  638. // Look at the NT SIDS
  639. //
  640. if( EqualSid( SeNtAuthoritySid, pSid ) ) {
  641. pName = L"NTAUTHORITY";
  642. Type = SidTypeWellKnownGroup;
  643. }
  644. if( EqualSid( SeDialupSid, pSid ) ) {
  645. pName = L"DIALUP";
  646. Type = SidTypeWellKnownGroup;
  647. }
  648. if( EqualSid( SeNetworkSid, pSid ) ) {
  649. pName = L"NETWORK";
  650. Type = SidTypeWellKnownGroup;
  651. }
  652. if( EqualSid( SeBatchSid, pSid ) ) {
  653. pName = L"BATCH";
  654. Type = SidTypeWellKnownGroup;
  655. }
  656. if( EqualSid( SeInteractiveSid, pSid ) ) {
  657. pName = L"INTERACTIVE";
  658. Type = SidTypeWellKnownGroup;
  659. }
  660. if( EqualSid( SeServiceSid, pSid ) ) {
  661. pName = L"SERVICE";
  662. Type = SidTypeWellKnownGroup;
  663. }
  664. if( EqualSid( SeLocalGuestSid, pSid ) ) {
  665. pName = L"LOCALGUEST";
  666. Type = SidTypeWellKnownGroup;
  667. }
  668. if( EqualSid( SeLocalSystemSid, pSid ) ) {
  669. pName = L"LOCALSYSTEM";
  670. Type = SidTypeWellKnownGroup;
  671. }
  672. if( EqualSid( SeLocalAdminSid, pSid ) ) {
  673. pName = L"LOCALADMIN";
  674. Type = SidTypeWellKnownGroup;
  675. }
  676. if( EqualSid( SeLocalManagerSid, pSid ) ) {
  677. pName = L"LOCALMANAGER";
  678. Type = SidTypeWellKnownGroup;
  679. }
  680. if( EqualSid( SeAliasAdminsSid, pSid ) ) {
  681. pName = L"ALIAS_ADMINS";
  682. Type = SidTypeAlias;
  683. }
  684. if( EqualSid( SeAliasUsersSid, pSid ) ) {
  685. pName = L"ALIAS_USERS";
  686. Type = SidTypeAlias;
  687. }
  688. if( EqualSid( SeAliasGuestsSid, pSid ) ) {
  689. pName = L"ALIAS_GUESTS";
  690. Type = SidTypeAlias;
  691. }
  692. if( EqualSid( SeAliasPowerUsersSid, pSid ) ) {
  693. pName = L"ALIAS_POWERUSERS";
  694. Type = SidTypeAlias;
  695. }
  696. if( EqualSid( SeAliasAccountOpsSid, pSid ) ) {
  697. pName = L"ALIAS_ACCOUNT_OPS";
  698. Type = SidTypeAlias;
  699. }
  700. if( EqualSid( SeAliasSystemOpsSid, pSid ) ) {
  701. pName = L"ALIAS_SYSTEM_OPS";
  702. Type = SidTypeAlias;
  703. }
  704. if( EqualSid( SeAliasPrintOpsSid, pSid ) ) {
  705. pName = L"ALIAS_PRINT_OPS";
  706. Type = SidTypeAlias;
  707. }
  708. if( EqualSid( SeAliasBackupOpsSid, pSid ) ) {
  709. pName = L"ALIAS_BACKUP_OPS";
  710. Type = SidTypeAlias;
  711. }
  712. if( EqualSid( SeAliasReplicatorSid, pSid ) ) {
  713. pName = L"ALIAS_REPLICATOR";
  714. Type = SidTypeAlias;
  715. }
  716. #endif
  717. }
  718. /*****************************************************************************
  719. *
  720. * GetSecureAcl
  721. *
  722. * Comment
  723. *
  724. * ENTRY:
  725. * Param1 (input/output)
  726. * Comments
  727. *
  728. * EXIT:
  729. * STATUS_SUCCESS - no error
  730. *
  731. ****************************************************************************/
  732. PACL
  733. GetSecureAcl()
  734. {
  735. return( pAdminsOnlyAcl );
  736. }
  737. /*****************************************************************************
  738. *
  739. * BuildSecureAcl
  740. *
  741. * Comment
  742. *
  743. * ENTRY:
  744. * Param1 (input/output)
  745. * Comments
  746. *
  747. * EXIT:
  748. * STATUS_SUCCESS - no error
  749. *
  750. ****************************************************************************/
  751. BOOL
  752. BuildSecureAcl()
  753. {
  754. BOOL rc;
  755. DWORD Index, Error;
  756. PADMIN_ACCOUNTS p;
  757. DWORD AclSize;
  758. PACL pAcl = NULL;
  759. PACCESS_ALLOWED_ACE pAce = NULL;
  760. /*
  761. * Calculate the ACL size
  762. */
  763. AclSize = sizeof(ACL);
  764. //
  765. // Reserve memory for the deny ACE's
  766. //
  767. for( Index = 0; Index < DenyAccountEntries; Index++ ) {
  768. p = &DenyAccounts[Index];
  769. if( p->pSid ) {
  770. AclSize += sizeof(ACCESS_DENIED_ACE);
  771. AclSize += (GetLengthSid( p->pSid ) - sizeof(DWORD));
  772. }
  773. }
  774. //
  775. // Reserve memory for the allowed ACE's
  776. //
  777. for( Index = 0; Index < AllowAccountEntries; Index++ ) {
  778. p = &AllowAccounts[Index];
  779. if( p->pSid ) {
  780. AclSize += sizeof(ACCESS_ALLOWED_ACE);
  781. AclSize += (GetLengthSid( p->pSid ) - sizeof(DWORD));
  782. }
  783. }
  784. pAcl = LocalAlloc( LMEM_FIXED, AclSize );
  785. if( pAcl == NULL ) {
  786. DBGPRINT(("Could not allocate memory\n"));
  787. return( FALSE );
  788. }
  789. rc = InitializeAcl(
  790. pAcl,
  791. AclSize,
  792. ACL_REVISION
  793. );
  794. if( !rc ) {
  795. DBGPRINT(("Error %d InitializeAcl\n",GetLastError()));
  796. LocalFree( pAcl );
  797. return( FALSE );
  798. }
  799. /*
  800. * Add a deny all ACE for each account in the deny list
  801. */
  802. for( Index = 0; Index < DenyAccountEntries; Index++ ) {
  803. p = &DenyAccounts[Index];
  804. rc = AddAccessDeniedAce(
  805. pAcl,
  806. ACL_REVISION,
  807. FILE_ALL_ACCESS,
  808. p->pSid
  809. );
  810. if( !rc ) {
  811. Error = GetLastError();
  812. DBGPRINT(("***ERROR*** adding deny ACE %d for account %ws\n",Error,p->Name));
  813. }
  814. }
  815. /*
  816. * Add an allow all ACE for each account in the allow list
  817. */
  818. for( Index = 0; Index < AllowAccountEntries; Index++ ) {
  819. p = &AllowAccounts[Index];
  820. rc = AddAccessAllowedAce(
  821. pAcl,
  822. ACL_REVISION,
  823. FILE_ALL_ACCESS,
  824. p->pSid
  825. );
  826. if( !rc ) {
  827. Error = GetLastError();
  828. DBGPRINT(("***ERROR*** adding allow ACE %d for account %ws\n",Error,p->Name));
  829. }
  830. }
  831. pAdminsOnlyAcl = pAcl;
  832. AdminsOnlyAclSize = AclSize;
  833. //
  834. // Put the inherit flags on the ACE's
  835. //
  836. for( Index=0; Index < pAcl->AceCount; Index++ ) {
  837. rc = GetAce( pAcl, Index, (PVOID)&pAce );
  838. if( !rc ) {
  839. continue;
  840. }
  841. pAce->Header.AceFlags |= (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
  842. }
  843. return( TRUE );
  844. }
  845. /*****************************************************************************
  846. *
  847. * GetLocalAdminSid
  848. *
  849. * Comment
  850. *
  851. * ENTRY:
  852. * Param1 (input/output)
  853. * Comments
  854. *
  855. * EXIT:
  856. * STATUS_SUCCESS - no error
  857. *
  858. ****************************************************************************/
  859. PSID
  860. GetLocalAdminSid()
  861. {
  862. return( SeLocalAdminSid );
  863. }
  864. /*****************************************************************************
  865. *
  866. * GetAdminSid
  867. *
  868. * Comment
  869. *
  870. * ENTRY:
  871. * Param1 (input/output)
  872. * Comments
  873. *
  874. * EXIT:
  875. *
  876. ****************************************************************************/
  877. PSID
  878. GetAdminSid()
  879. {
  880. return( AllowAccounts[ADMIN_ACCOUNT].pSid );
  881. }
  882. /*****************************************************************************
  883. *
  884. * GetLocalAdminGroupSid
  885. *
  886. * Comment
  887. *
  888. * ENTRY:
  889. * Param1 (input/output)
  890. * Comments
  891. *
  892. * EXIT:
  893. * STATUS_SUCCESS - no error
  894. *
  895. ****************************************************************************/
  896. PSID
  897. GetLocalAdminGroupSid()
  898. {
  899. return( SeAliasAdminsSid );
  900. }
  901. /*****************************************************************************
  902. *
  903. * GetLocalAdminGroupSid
  904. *
  905. * Comment
  906. *
  907. * ENTRY:
  908. * Param1 (input/output)
  909. * Comments
  910. *
  911. * EXIT:
  912. * STATUS_SUCCESS - no error
  913. *
  914. ****************************************************************************/
  915. BOOL CheckUserSid()
  916. {
  917. BOOL rc;
  918. PSID pSid;
  919. PSID pPrevSid;
  920. rc = xxxLookupAccountName(
  921. ComputerName,
  922. AllowAccounts[USER_ACCOUNT].Name,
  923. &pSid
  924. );
  925. if( !rc ) {
  926. // It might be a special builtin account
  927. rc = xxxLookupBuiltinAccount(
  928. ComputerName,
  929. AllowAccounts[USER_ACCOUNT].Name,
  930. &pSid
  931. );
  932. }
  933. pPrevSid = AllowAccounts[USER_ACCOUNT].pSid;
  934. if (rc && (!pPrevSid || !EqualSid( pSid, pPrevSid ))) {
  935. AllowAccounts[USER_ACCOUNT].pSid = pSid;
  936. if (pAdminsOnlyAcl) {
  937. LocalFree( pAdminsOnlyAcl );
  938. pAdminsOnlyAcl = NULL;
  939. AdminsOnlyAclSize = 0;
  940. }
  941. rc = BuildSecureAcl();
  942. }
  943. return(rc);
  944. }