Windows-Server-2003/termsrv/syslib/security.c

1168 lines
32 KiB
C
Raw Normal View History

2024-08-04 01:28:15 +02:00
/*************************************************************************
*
* security.c
*
* NT Security routines
*
* copyright notice: Copyright 1997, Microsoft
*
*************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntexapi.h>
#include <ntseapi.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <windows.h>
#include <string.h>
#include <wcstr.h>
#include "seopaque.h"
#include "sertlp.h"
#include <process.h>
#include <winsta.h>
#include <syslib.h>
#include <lmcons.h> // for DNLEN KLB 09-18-96
#include "security.h"
#if DBG
ULONG
DbgPrint(
PCH Format,
...
);
#define DBGPRINT(x) DbgPrint x
#if DBGTRACE
#define TRACE0(x) DbgPrint x
#define TRACE1(x) DbgPrint x
#else
#define TRACE0(x)
#define TRACE1(x)
#endif
#else
#define DBGPRINT(x)
#define TRACE0(x)
#define TRACE1(x)
#endif
typedef struct _SIDLIST {
struct _SIDLIST *Next;
USHORT SidCrc;
PWCHAR pAccountName;
PWCHAR pDomainName;
} SIDLIST, *PSIDLIST;
static PSIDLIST SidCache = NULL;
// Computer Name
WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1];
// Admins only ACL
PACL pAdminsOnlyAcl = NULL;
DWORD AdminsOnlyAclSize = 0;
//
// Universal well known SIDs
//
PSID SeNullSid;
PSID SeWorldSid;
PSID SeLocalSid;
PSID SeCreatorOwnerSid;
PSID SeCreatorGroupSid;
//
// Sids defined by NT
//
PSID SeNtAuthoritySid;
PSID SeDialupSid;
PSID SeNetworkSid;
PSID SeBatchSid;
PSID SeInteractiveSid;
PSID SeServiceSid;
PSID SeLocalGuestSid;
PSID SeLocalSystemSid;
PSID SeLocalAdminSid;
PSID SeLocalManagerSid;
PSID SeAliasAdminsSid;
PSID SeAliasUsersSid;
PSID SeAliasGuestsSid;
PSID SeAliasPowerUsersSid;
PSID SeAliasAccountOpsSid;
PSID SeAliasSystemOpsSid;
PSID SeAliasPrintOpsSid;
PSID SeAliasBackupOpsSid;
PSID SeAliasReplicatorSid;
static SID_IDENTIFIER_AUTHORITY SepNullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
static SID_IDENTIFIER_AUTHORITY SepLocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
static SID_IDENTIFIER_AUTHORITY SepCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY;
//
// Sid of primary domain, and admin account in that domain
//
PSID SepPrimaryDomainSid;
PSID SepPrimaryDomainAdminSid;
// External data
extern ADMIN_ACCOUNTS AllowAccounts[];
extern DWORD AllowAccountEntries;
extern ACCESS_MASK AllowAccess;
extern ADMIN_ACCOUNTS DenyAccounts[];
extern DWORD DenyAccountEntries;
extern ACCESS_MASK DeniedAccess;
// Forward and external references
BOOLEAN
InitializeBuiltinSids();
BOOL
LoadAccountSids();
BOOL
BuildSecureAcl();
BOOL
xxxLookupBuiltinAccount(
PWCHAR pSystemName,
PWCHAR pAccountName,
PSID *ppSid
);
BOOL
GetCurrentUserSid( PSID *ppSid );
/*****************************************************************************
*
* InitSecurity
*
* Initialize the security package
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* TRUE - no error
* FALSE - error
*
****************************************************************************/
BOOL
InitSecurity(
)
{
BOOL rc;
DWORD Size = sizeof(ComputerName)/sizeof(WCHAR);
rc = GetComputerNameW( ComputerName, &Size );
if( !rc ) {
DBGPRINT(("***ERROR*** %d Could not get computer name\n",GetLastError() ));
return( FALSE );
}
rc = InitializeBuiltinSids();
if( !rc ) {
DBGPRINT(("***ERROR*** Some built-in accounts not loaded\n"));
return( FALSE );
}
rc = LoadAccountSids();
if( !rc ) {
DBGPRINT(("***ERROR*** Some accounts not loaded\n"));
return( FALSE );
}
rc = BuildSecureAcl();
if( !rc ) {
DBGPRINT(("***ERROR*** Could not build ACL\n"));
return( FALSE );
}
return( TRUE );
}
/*****************************************************************************
*
* LoadAccountSids
*
* Load the list of account access SIDS.
*
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL
LoadAccountSids()
{
BOOL rc, Final;
NTSTATUS Status;
SID_IDENTIFIER_AUTHORITY gSystemSidAuthority = SECURITY_NT_AUTHORITY;
Final = TRUE;
//
// Get the SID's for all of the allow accounts
//
//
// Get the SID of the built-in Administrators group
//
Status = RtlAllocateAndInitializeSid(
&gSystemSidAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0,0,0,0,0,0,
&(AllowAccounts[ADMIN_ACCOUNT].pSid));
if (!NT_SUCCESS(Status)) {
DBGPRINT(("SYSLIB: Couldn't allocate Administrators SID (0x%x)\n", Status ));
Final = FALSE;
}
//
// SYSTEM
//
Status = RtlAllocateAndInitializeSid(
&gSystemSidAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
0,0,0,0,0,0,0,
&(AllowAccounts[SYSTEM_ACCOUNT].pSid));
if (!NT_SUCCESS(Status)) {
DBGPRINT(("SYSLIB: Couldn't allocate SYSTEM SID (0x%x)\n", Status ));
Final = FALSE;
}
//
// Get the current user's Sid
//
//First, see if we run in SYSTEM context.
//If we do, get current user SID from TERMSRV, otherwise use a user SID from process token.
Final = FALSE;
{
HANDLE hToken;
PTOKEN_USER pTokenUser = NULL;
DWORD dwInfoLength = 0;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))
{
GetTokenInformation(hToken,TokenUser,pTokenUser,dwInfoLength,&dwInfoLength);
if(dwInfoLength)
{
pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR,dwInfoLength);
if(pTokenUser)
{
if(GetTokenInformation(hToken,TokenUser,pTokenUser,dwInfoLength,&dwInfoLength))
{
if(EqualSid(AllowAccounts[SYSTEM_ACCOUNT].pSid,pTokenUser->User.Sid))
{
rc = xxxLookupAccountName(
ComputerName,
CURRENT_USER,
&(AllowAccounts[USER_ACCOUNT].pSid)
);
if ( !rc )
{
// It might be a special builtin account
rc = xxxLookupBuiltinAccount(
ComputerName,
CURRENT_USER,
&(AllowAccounts[USER_ACCOUNT].pSid)
);
if( !rc )
{
DBGPRINT(("***WARNING*** Could not find SID for current user account, Error %d\n", GetLastError() ));
}
}
if( rc )
{
Final = TRUE;
}
}
else
{
DWORD dwSidLength = GetLengthSid(pTokenUser->User.Sid);
AllowAccounts[USER_ACCOUNT].pSid = (PSID)LocalAlloc(LPTR,dwSidLength);
if(AllowAccounts[USER_ACCOUNT].pSid)
{
CopyMemory(AllowAccounts[USER_ACCOUNT].pSid,pTokenUser->User.Sid,dwSidLength);
Final = TRUE;
}
}
}
LocalFree(pTokenUser);
}
}
CloseHandle(hToken);
}
}
#ifdef notdef
//
// Lookup the SID's for all of the deny accounts
//
for( Index = 0; Index < DenyAccountEntries; Index++ ) {
p = &DenyAccounts[Index];
rc = xxxLookupAccountName(
ComputerName,
p->Name,
&p->pSid
);
if( !rc ) {
// It might be a special builtin account
rc = xxxLookupBuiltinAccount(
ComputerName,
p->Name,
&p->pSid
);
if( !rc ) {
DBGPRINT(("***WARNING*** Could not find SID for account %ws Error %d\n",p->Name,GetLastError() ));
Final = FALSE;
}
}
}
#endif
// Lower level function outputs if any accounts are invalid
return( Final );
}
/*****************************************************************************
*
* IsAllowSid
*
* Returns whether the supplied SID is in the allow group
*
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL
IsAllowSid(
PSID pSid
)
{
DWORD Index;
PADMIN_ACCOUNTS p;
BOOL AllowSid = FALSE;
for( Index = 0; Index < AllowAccountEntries; Index++ ) {
p = &AllowAccounts[Index];
if( p->pSid && EqualSid( pSid, p->pSid ) ) {
// The Sid is for an allowed account
AllowSid = TRUE;
break;
}
}
return( AllowSid );
}
/*****************************************************************************
*
* xxxLookupAccountName
*
* Wrapper to lookup the SID for a given account name
*
* Returns a pointer to the SID in newly allocated memory
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL
xxxLookupAccountName(
PWCHAR pSystemName,
PWCHAR pAccountName,
PSID *ppSid
)
{
BOOL rc;
DWORD Size, DomainSize, Error;
SID_NAME_USE Type;
PWCHAR pDomain = NULL;
PSID pSid = NULL;
WCHAR Buf;
WCHAR pCurrentUser[MAX_ACCOUNT_NAME]; // KLB 09-16-96
DWORD dwCurrentUser = MAX_ACCOUNT_NAME; // KLB 09-16-96
WCHAR pAccountToLookup[MAX_ACCOUNT_NAME+DNLEN+1]; // KLB 09-18-96
LPWSTR pLogon32DomainName = NULL; // KLB 09-19-96
WINSTATIONINFORMATION WinInfo; // KLB 09-30-96
ULONG ReturnLength; // KLB 09-30-96
Size = 0;
DomainSize = 0;
/*
* Open the WinStation and Query its information.
*/
memset( &WinInfo, 0, sizeof(WINSTATIONINFORMATION) );
rc = WinStationQueryInformation( SERVERNAME_CURRENT,
LOGONID_CURRENT,
WinStationInformation,
(PVOID)&WinInfo,
sizeof(WINSTATIONINFORMATION),
&ReturnLength );
if ( !rc ) {
DBGPRINT(("error querying winstation information %d.\n", GetLastError() ));
return( FALSE );
}
if( ReturnLength != sizeof(WINSTATIONINFORMATION) ) {
DBGPRINT(("winstation info version mismatch!\n"));
return( FALSE );
}
if (lstrcmpi(pAccountName,CURRENT_USER) == 0) {
lstrcpy( pAccountToLookup, WinInfo.Domain );
lstrcat( pAccountToLookup, L"\\" );
lstrcat( pAccountToLookup, WinInfo.UserName );
} else {
lstrcpy( pAccountToLookup, pAccountName );
}
DBGPRINT(( "looking up account %ws\n", pAccountToLookup ));
rc = LookupAccountNameW(
pSystemName,
pAccountToLookup, // KLB 09-16-96
&Buf, // pSid
&Size,
&Buf, // pDomain
&DomainSize,
&Type
);
if( rc ) {
DBGPRINT(("Internal error on account name %ws\n",pAccountToLookup));
return( FALSE );
}
else {
Error = GetLastError();
if( Error != ERROR_INSUFFICIENT_BUFFER ) {
DBGPRINT(("***ERROR*** %d looking up SID for account name %ws skipped without processing!\n",Error,pAccountToLookup));
return( FALSE );
}
pSid = LocalAlloc( LMEM_FIXED, Size );
if( pSid == NULL ) {
DBGPRINT(("***ERROR*** Out of memory, skipped account %ws without processing!\n",pAccountToLookup));
return( FALSE );
}
pDomain = LocalAlloc( LMEM_FIXED, DomainSize*sizeof(WCHAR) );
if( pDomain == NULL ) {
DBGPRINT(("***ERROR*** Out of memory, skipped account %ws without processing!\n",pAccountToLookup));
LocalFree( pSid );
return( FALSE );
}
rc = LookupAccountNameW(
pSystemName,
pAccountToLookup,
pSid,
&Size,
pDomain,
&DomainSize,
&Type
);
if( !rc ) {
DBGPRINT(("***ERROR*** %d looking up SID for account name %ws skipped without processing!\n",Error,pAccountToLookup));
LocalFree( pSid );
LocalFree( pDomain );
return( FALSE );
}
*ppSid = pSid;
LocalFree( pDomain );
DBGPRINT(( "leaving xxxLookupAccountName(); pSid is okay, returning TRUE.\n" ));
return( TRUE );
}
}
/*****************************************************************************
*
* InitializeBuiltinSids
*
* Initialize the built in SIDS
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOLEAN
InitializeBuiltinSids()
{
ULONG SidWithZeroSubAuthorities;
ULONG SidWithOneSubAuthority;
ULONG SidWithTwoSubAuthorities;
ULONG SidWithThreeSubAuthorities;
SID_IDENTIFIER_AUTHORITY NullSidAuthority;
SID_IDENTIFIER_AUTHORITY WorldSidAuthority;
SID_IDENTIFIER_AUTHORITY LocalSidAuthority;
SID_IDENTIFIER_AUTHORITY CreatorSidAuthority;
SID_IDENTIFIER_AUTHORITY SeNtAuthority;
NullSidAuthority = SepNullSidAuthority;
WorldSidAuthority = SepWorldSidAuthority;
LocalSidAuthority = SepLocalSidAuthority;
CreatorSidAuthority = SepCreatorSidAuthority;
SeNtAuthority = SepNtAuthority;
//
// The following SID sizes need to be allocated
//
SidWithZeroSubAuthorities = RtlLengthRequiredSid( 0 );
SidWithOneSubAuthority = RtlLengthRequiredSid( 1 );
SidWithTwoSubAuthorities = RtlLengthRequiredSid( 2 );
SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 );
//
// Allocate and initialize the universal SIDs
//
SeNullSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeWorldSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeLocalSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeCreatorOwnerSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeCreatorGroupSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
//
// Fail initialization if we didn't get enough memory for the universal
// SIDs.
//
if ( (SeNullSid == NULL) ||
(SeWorldSid == NULL) ||
(SeLocalSid == NULL) ||
(SeCreatorOwnerSid == NULL) ||
(SeCreatorGroupSid == NULL)
) {
return( FALSE );
}
RtlInitializeSid( SeNullSid, &NullSidAuthority, 1 );
RtlInitializeSid( SeWorldSid, &WorldSidAuthority, 1 );
RtlInitializeSid( SeLocalSid, &LocalSidAuthority, 1 );
RtlInitializeSid( SeCreatorOwnerSid, &CreatorSidAuthority, 1 );
RtlInitializeSid( SeCreatorGroupSid, &CreatorSidAuthority, 1 );
*(RtlSubAuthoritySid( SeNullSid, 0 )) = SECURITY_NULL_RID;
*(RtlSubAuthoritySid( SeWorldSid, 0 )) = SECURITY_WORLD_RID;
*(RtlSubAuthoritySid( SeLocalSid, 0 )) = SECURITY_LOCAL_RID;
*(RtlSubAuthoritySid( SeCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
*(RtlSubAuthoritySid( SeCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
//
// Allocate and initialize the NT defined SIDs
//
SeNtAuthoritySid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithZeroSubAuthorities);
SeDialupSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeNetworkSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeBatchSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeInteractiveSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeServiceSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeLocalGuestSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeLocalSystemSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeLocalAdminSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeLocalManagerSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithOneSubAuthority);
SeAliasAdminsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasUsersSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasGuestsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasPowerUsersSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasAccountOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasSystemOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasPrintOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasBackupOpsSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
SeAliasReplicatorSid = (PSID)RtlAllocateHeap(RtlProcessHeap(), 0, SidWithTwoSubAuthorities);
//
// Fail initialization if we didn't get enough memory for the NT SIDs.
//
if ( (SeNtAuthoritySid == NULL) ||
(SeDialupSid == NULL) ||
(SeNetworkSid == NULL) ||
(SeBatchSid == NULL) ||
(SeInteractiveSid == NULL) ||
(SeServiceSid == NULL) ||
(SeLocalGuestSid == NULL) ||
(SeLocalSystemSid == NULL) ||
(SeLocalAdminSid == NULL) ||
(SeLocalManagerSid == NULL) ||
(SeAliasAdminsSid == NULL) ||
(SeAliasUsersSid == NULL) ||
(SeAliasGuestsSid == NULL) ||
(SeAliasPowerUsersSid == NULL) ||
(SeAliasAccountOpsSid == NULL) ||
(SeAliasSystemOpsSid == NULL) ||
(SeAliasReplicatorSid == NULL) ||
(SeAliasPrintOpsSid == NULL) ||
(SeAliasBackupOpsSid == NULL)
) {
return( FALSE );
}
RtlInitializeSid( SeNtAuthoritySid, &SeNtAuthority, 0 );
RtlInitializeSid( SeDialupSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeNetworkSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeBatchSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeInteractiveSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeServiceSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeLocalGuestSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeLocalSystemSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeLocalAdminSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeLocalManagerSid, &SeNtAuthority, 1 );
RtlInitializeSid( SeAliasAdminsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasUsersSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasGuestsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasPowerUsersSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasAccountOpsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasSystemOpsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasPrintOpsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasBackupOpsSid, &SeNtAuthority, 2);
RtlInitializeSid( SeAliasReplicatorSid, &SeNtAuthority, 2);
*(RtlSubAuthoritySid( SeDialupSid, 0 )) = SECURITY_DIALUP_RID;
*(RtlSubAuthoritySid( SeNetworkSid, 0 )) = SECURITY_NETWORK_RID;
*(RtlSubAuthoritySid( SeBatchSid, 0 )) = SECURITY_BATCH_RID;
*(RtlSubAuthoritySid( SeInteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID;
*(RtlSubAuthoritySid( SeServiceSid, 0 )) = SECURITY_SERVICE_RID;
// *(RtlSubAuthoritySid( SeLocalGuestSid, 0 )) = SECURITY_LOCAL_GUESTS_RID;
*(RtlSubAuthoritySid( SeLocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
// *(RtlSubAuthoritySid( SeLocalAdminSid, 0 )) = SECURITY_LOCAL_ADMIN_RID;
// *(RtlSubAuthoritySid( SeLocalManagerSid, 0 )) = SECURITY_LOCAL_MANAGER_RID;
*(RtlSubAuthoritySid( SeAliasAdminsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasGuestsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasPowerUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasAccountOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasSystemOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasPrintOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasBackupOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasReplicatorSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
*(RtlSubAuthoritySid( SeAliasAdminsSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;
*(RtlSubAuthoritySid( SeAliasUsersSid, 1 )) = DOMAIN_ALIAS_RID_USERS;
*(RtlSubAuthoritySid( SeAliasGuestsSid, 1 )) = DOMAIN_ALIAS_RID_GUESTS;
*(RtlSubAuthoritySid( SeAliasPowerUsersSid, 1 )) = DOMAIN_ALIAS_RID_POWER_USERS;
*(RtlSubAuthoritySid( SeAliasAccountOpsSid, 1 )) = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
*(RtlSubAuthoritySid( SeAliasSystemOpsSid, 1 )) = DOMAIN_ALIAS_RID_SYSTEM_OPS;
*(RtlSubAuthoritySid( SeAliasPrintOpsSid, 1 )) = DOMAIN_ALIAS_RID_PRINT_OPS;
*(RtlSubAuthoritySid( SeAliasBackupOpsSid, 1 )) = DOMAIN_ALIAS_RID_BACKUP_OPS;
*(RtlSubAuthoritySid( SeAliasReplicatorSid, 1 )) = DOMAIN_ALIAS_RID_REPLICATOR;
return( TRUE );
}
/*****************************************************************************
*
* xxxLookupBuiltinAccount
*
* Wrapper to lookup the SID for a given built in account name
*
* Returns a pointer to the SID in newly allocated memory
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL
xxxLookupBuiltinAccount(
PWCHAR pSystemName,
PWCHAR pAccountName,
PSID *ppSid
)
{
USHORT SidLen;
SID_NAME_USE Type;
PSID pSid = NULL;
if( _wcsicmp( L"NULL_SID", pAccountName ) == 0 ) {
pSid = SeNullSid;
Type = SidTypeInvalid;
}
if( pSid == NULL ) {
SetLastError( ERROR_NONE_MAPPED );
return( FALSE );
}
SidLen = (USHORT)GetLengthSid( pSid );
*ppSid = LocalAlloc(LMEM_FIXED, SidLen );
if( *ppSid == NULL ) {
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return( FALSE );
}
RtlMoveMemory( *ppSid, pSid, SidLen );
return( TRUE );
#ifdef notdef
if( EqualSid( SeNullSid, pSid ) ) {
pName = L"NULL_SID";
Type = SidTypeInvalid;
}
if( EqualSid( SeWorldSid, pSid ) ) {
pName = L"WORLD";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeLocalSid, pSid ) ) {
pName = L"LOCAL_ACCOUNT";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeCreatorOwnerSid, pSid ) ) {
pName = L"CREATOR_OWNER";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeCreatorGroupSid, pSid ) ) {
pName = L"CREATOR_GROUP";
Type = SidTypeWellKnownGroup;
}
//
// Look at the NT SIDS
//
if( EqualSid( SeNtAuthoritySid, pSid ) ) {
pName = L"NTAUTHORITY";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeDialupSid, pSid ) ) {
pName = L"DIALUP";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeNetworkSid, pSid ) ) {
pName = L"NETWORK";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeBatchSid, pSid ) ) {
pName = L"BATCH";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeInteractiveSid, pSid ) ) {
pName = L"INTERACTIVE";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeServiceSid, pSid ) ) {
pName = L"SERVICE";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeLocalGuestSid, pSid ) ) {
pName = L"LOCALGUEST";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeLocalSystemSid, pSid ) ) {
pName = L"LOCALSYSTEM";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeLocalAdminSid, pSid ) ) {
pName = L"LOCALADMIN";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeLocalManagerSid, pSid ) ) {
pName = L"LOCALMANAGER";
Type = SidTypeWellKnownGroup;
}
if( EqualSid( SeAliasAdminsSid, pSid ) ) {
pName = L"ALIAS_ADMINS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasUsersSid, pSid ) ) {
pName = L"ALIAS_USERS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasGuestsSid, pSid ) ) {
pName = L"ALIAS_GUESTS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasPowerUsersSid, pSid ) ) {
pName = L"ALIAS_POWERUSERS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasAccountOpsSid, pSid ) ) {
pName = L"ALIAS_ACCOUNT_OPS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasSystemOpsSid, pSid ) ) {
pName = L"ALIAS_SYSTEM_OPS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasPrintOpsSid, pSid ) ) {
pName = L"ALIAS_PRINT_OPS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasBackupOpsSid, pSid ) ) {
pName = L"ALIAS_BACKUP_OPS";
Type = SidTypeAlias;
}
if( EqualSid( SeAliasReplicatorSid, pSid ) ) {
pName = L"ALIAS_REPLICATOR";
Type = SidTypeAlias;
}
#endif
}
/*****************************************************************************
*
* GetSecureAcl
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
PACL
GetSecureAcl()
{
return( pAdminsOnlyAcl );
}
/*****************************************************************************
*
* BuildSecureAcl
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL
BuildSecureAcl()
{
BOOL rc;
DWORD Index, Error;
PADMIN_ACCOUNTS p;
DWORD AclSize;
PACL pAcl = NULL;
PACCESS_ALLOWED_ACE pAce = NULL;
/*
* Calculate the ACL size
*/
AclSize = sizeof(ACL);
//
// Reserve memory for the deny ACE's
//
for( Index = 0; Index < DenyAccountEntries; Index++ ) {
p = &DenyAccounts[Index];
if( p->pSid ) {
AclSize += sizeof(ACCESS_DENIED_ACE);
AclSize += (GetLengthSid( p->pSid ) - sizeof(DWORD));
}
}
//
// Reserve memory for the allowed ACE's
//
for( Index = 0; Index < AllowAccountEntries; Index++ ) {
p = &AllowAccounts[Index];
if( p->pSid ) {
AclSize += sizeof(ACCESS_ALLOWED_ACE);
AclSize += (GetLengthSid( p->pSid ) - sizeof(DWORD));
}
}
pAcl = LocalAlloc( LMEM_FIXED, AclSize );
if( pAcl == NULL ) {
DBGPRINT(("Could not allocate memory\n"));
return( FALSE );
}
rc = InitializeAcl(
pAcl,
AclSize,
ACL_REVISION
);
if( !rc ) {
DBGPRINT(("Error %d InitializeAcl\n",GetLastError()));
LocalFree( pAcl );
return( FALSE );
}
/*
* Add a deny all ACE for each account in the deny list
*/
for( Index = 0; Index < DenyAccountEntries; Index++ ) {
p = &DenyAccounts[Index];
rc = AddAccessDeniedAce(
pAcl,
ACL_REVISION,
FILE_ALL_ACCESS,
p->pSid
);
if( !rc ) {
Error = GetLastError();
DBGPRINT(("***ERROR*** adding deny ACE %d for account %ws\n",Error,p->Name));
}
}
/*
* Add an allow all ACE for each account in the allow list
*/
for( Index = 0; Index < AllowAccountEntries; Index++ ) {
p = &AllowAccounts[Index];
rc = AddAccessAllowedAce(
pAcl,
ACL_REVISION,
FILE_ALL_ACCESS,
p->pSid
);
if( !rc ) {
Error = GetLastError();
DBGPRINT(("***ERROR*** adding allow ACE %d for account %ws\n",Error,p->Name));
}
}
pAdminsOnlyAcl = pAcl;
AdminsOnlyAclSize = AclSize;
//
// Put the inherit flags on the ACE's
//
for( Index=0; Index < pAcl->AceCount; Index++ ) {
rc = GetAce( pAcl, Index, (PVOID)&pAce );
if( !rc ) {
continue;
}
pAce->Header.AceFlags |= (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
}
return( TRUE );
}
/*****************************************************************************
*
* GetLocalAdminSid
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
PSID
GetLocalAdminSid()
{
return( SeLocalAdminSid );
}
/*****************************************************************************
*
* GetAdminSid
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
*
****************************************************************************/
PSID
GetAdminSid()
{
return( AllowAccounts[ADMIN_ACCOUNT].pSid );
}
/*****************************************************************************
*
* GetLocalAdminGroupSid
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
PSID
GetLocalAdminGroupSid()
{
return( SeAliasAdminsSid );
}
/*****************************************************************************
*
* GetLocalAdminGroupSid
*
* Comment
*
* ENTRY:
* Param1 (input/output)
* Comments
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
BOOL CheckUserSid()
{
BOOL rc;
PSID pSid;
PSID pPrevSid;
rc = xxxLookupAccountName(
ComputerName,
AllowAccounts[USER_ACCOUNT].Name,
&pSid
);
if( !rc ) {
// It might be a special builtin account
rc = xxxLookupBuiltinAccount(
ComputerName,
AllowAccounts[USER_ACCOUNT].Name,
&pSid
);
}
pPrevSid = AllowAccounts[USER_ACCOUNT].pSid;
if (rc && (!pPrevSid || !EqualSid( pSid, pPrevSid ))) {
AllowAccounts[USER_ACCOUNT].pSid = pSid;
if (pAdminsOnlyAcl) {
LocalFree( pAdminsOnlyAcl );
pAdminsOnlyAcl = NULL;
AdminsOnlyAclSize = 0;
}
rc = BuildSecureAcl();
}
return(rc);
}