mirror of https://github.com/lianthony/NT4.0
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.
527 lines
12 KiB
527 lines
12 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Global.c
|
|
|
|
Abstract:
|
|
|
|
This module contains global variables available throughout
|
|
SecMgr. It also contains a routine to initialize those
|
|
variables.
|
|
|
|
|
|
Author:
|
|
|
|
Jim Kelly (JimK) 22-Sep-1994
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "secmgrp.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Global Variables //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//
|
|
// This variable indicates whether or not the invoking user
|
|
// is an administrator.
|
|
//
|
|
|
|
BOOL
|
|
SecMgrpAdminUser = TRUE;
|
|
|
|
|
|
//
|
|
// Type of product installed and running on this machine
|
|
//
|
|
|
|
NT_PRODUCT_TYPE
|
|
SecMgrpProductType;
|
|
|
|
|
|
//
|
|
// This boolean will be set to TRUE if any changes have been
|
|
// made to the security settings.
|
|
//
|
|
|
|
BOOLEAN
|
|
SecMgrpChangesMade = FALSE;
|
|
|
|
//
|
|
// These variables contain the security level that was
|
|
// in force when the utility was activated, and what the
|
|
// current applied level is (according to the radio buttons).
|
|
// These are used to grey and ungrey the [Apply] and [Check]
|
|
// buttons. In dialoges that check and apply, CurrentLevel
|
|
// is the level being checked or applied.
|
|
//
|
|
|
|
ULONG
|
|
SecMgrpCurrentLevel,
|
|
SecMgrpOriginalLevel;
|
|
|
|
|
|
//
|
|
// Some changes don't take effect until a re-boot has been
|
|
// performed. If any of these changes are made while applying
|
|
// a change, then this variable will be set to TRUE. This will
|
|
// then be used to decide whether to display a message to the
|
|
// user upon utility exit.
|
|
//
|
|
|
|
BOOLEAN
|
|
SecMgrpRebootRequired = FALSE;
|
|
|
|
|
|
//
|
|
// Handle to our own module
|
|
//
|
|
|
|
HINSTANCE
|
|
SecMgrphInstance = NULL;
|
|
|
|
|
|
//
|
|
// Name of our application
|
|
// (localization must live within 100 bytes)
|
|
//
|
|
|
|
TCHAR
|
|
SecMgrpApplicationName[100];
|
|
|
|
|
|
|
|
//
|
|
// Well known sids that we use
|
|
//
|
|
|
|
PSID
|
|
SecMgrpWorldSid,
|
|
SecMgrpAccountOpsSid,
|
|
SecMgrpBackupOpsSid,
|
|
SecMgrpPrintOpsSid,
|
|
SecMgrpServerOpsSid,
|
|
SecMgrpAdminsSid;
|
|
|
|
|
|
//
|
|
// Grouping of well-known sids by type
|
|
//
|
|
|
|
SECMGRP_ACCOUNTS
|
|
SecMgrpAnyoneSids,
|
|
SecMgrpOperatorSids,
|
|
SecMgrpOpersAndAdminsSids,
|
|
SecMgrpAdminsSids;
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Module-Private Prototypes //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
TestTokenForAdmin( HANDLE Token );
|
|
|
|
BOOL
|
|
SecMgrpIsUserAdmin( VOID );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Externally callable routines //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
SecMgrpInitializeGlobals(
|
|
HINSTANCE hInstance
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize global variables.
|
|
|
|
|
|
Arguments
|
|
|
|
hInstance - the HINSTANCE of our app.
|
|
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
ULONG
|
|
Index;
|
|
|
|
BOOLEAN
|
|
IgnoreBoolean;
|
|
|
|
SID_IDENTIFIER_AUTHORITY
|
|
WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY,
|
|
NtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
//
|
|
// Save away our hInstance
|
|
//
|
|
|
|
SecMgrphInstance = hInstance;
|
|
|
|
//
|
|
// Get our application's name
|
|
//
|
|
|
|
LoadString( SecMgrphInstance,
|
|
SECMGRP_STRING_SECURITY_MANAGER,
|
|
&SecMgrpApplicationName[0],
|
|
100
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// Initialize the sids
|
|
//
|
|
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&WorldSidAuthority,
|
|
1,
|
|
SECURITY_WORLD_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&SecMgrpWorldSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize world sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ACCOUNT_OPS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&SecMgrpAccountOpsSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize admin AcountOps sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_SYSTEM_OPS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&SecMgrpServerOpsSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize admin ServerOps sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_PRINT_OPS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&SecMgrpPrintOpsSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize admin PrintOps sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_BACKUP_OPS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&SecMgrpBackupOpsSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize admin BackupOps sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
NtStatus = RtlAllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&SecMgrpAdminsSid
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: Failed to initialize admin alias sid, status = 0x%lx", NtStatus));
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Group the sids by type
|
|
//
|
|
|
|
Index=0;
|
|
SecMgrpAnyoneSids.Sid[Index++] = SecMgrpWorldSid;
|
|
SecMgrpAnyoneSids.Accounts = Index;
|
|
ASSERT(Index < SECMGRP_MAX_WELL_KNOWN_ACCOUNTS);
|
|
|
|
Index=0;
|
|
SecMgrpOperatorSids.Sid[Index++] = SecMgrpAccountOpsSid;
|
|
SecMgrpOperatorSids.Sid[Index++] = SecMgrpBackupOpsSid;
|
|
SecMgrpOperatorSids.Sid[Index++] = SecMgrpPrintOpsSid;
|
|
SecMgrpOperatorSids.Sid[Index++] = SecMgrpServerOpsSid;
|
|
SecMgrpOperatorSids.Accounts = Index;
|
|
ASSERT(Index < SECMGRP_MAX_WELL_KNOWN_ACCOUNTS);
|
|
|
|
Index=0;
|
|
SecMgrpOpersAndAdminsSids.Sid[Index++] = SecMgrpAccountOpsSid;
|
|
SecMgrpOpersAndAdminsSids.Sid[Index++] = SecMgrpBackupOpsSid;
|
|
SecMgrpOpersAndAdminsSids.Sid[Index++] = SecMgrpPrintOpsSid;
|
|
SecMgrpOpersAndAdminsSids.Sid[Index++] = SecMgrpServerOpsSid;
|
|
SecMgrpOpersAndAdminsSids.Sid[Index++] = SecMgrpAdminsSid;
|
|
SecMgrpOpersAndAdminsSids.Accounts = Index;
|
|
ASSERT(Index < SECMGRP_MAX_WELL_KNOWN_ACCOUNTS);
|
|
|
|
Index=0;
|
|
SecMgrpAdminsSids.Sid[Index++] = SecMgrpAdminsSid;
|
|
SecMgrpAdminsSids.Accounts = Index;
|
|
ASSERT(Index < SECMGRP_MAX_WELL_KNOWN_ACCOUNTS);
|
|
|
|
|
|
|
|
|
|
//
|
|
// Make sure we are an admin
|
|
//
|
|
|
|
if (!SecMgrpIsUserAdmin()) {
|
|
|
|
//
|
|
// The invoking user is not an admin.
|
|
// This utility is only for use by administrators.
|
|
//
|
|
|
|
SecMgrpAdminUser = FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the product type
|
|
//
|
|
|
|
IgnoreBoolean = RtlGetNtProductType( &SecMgrpProductType );
|
|
ASSERT(IgnoreBoolean == TRUE);
|
|
|
|
|
|
//
|
|
// We don't yet know our security level, so set it to zero.
|
|
//
|
|
|
|
SecMgrpCurrentLevel = 0;
|
|
SecMgrpOriginalLevel = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Module-Private Functions //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
BOOL
|
|
SecMgrpIsUserAdmin( VOID )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks to see if the current process has administrator
|
|
capabilities.
|
|
|
|
|
|
Arguments
|
|
|
|
None.
|
|
|
|
|
|
Return Values:
|
|
|
|
TRUE - The process has and administrator capabilities.
|
|
|
|
FALSE - The process does NOT have administrator capabilities.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
HANDLE
|
|
Token;
|
|
|
|
BOOL
|
|
IsAdmin;
|
|
|
|
NtStatus = NtOpenProcessToken( NtCurrentProcess(),
|
|
TOKEN_QUERY,
|
|
&Token
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
IsAdmin = TestTokenForAdmin( Token );
|
|
|
|
NtStatus = NtClose( Token );
|
|
|
|
return( IsAdmin );
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
TestTokenForAdmin(
|
|
HANDLE Token
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks to see if the passed token is an administrator's token
|
|
or not. A token is an administrator's token if it contains
|
|
the Administrators local group.
|
|
|
|
|
|
Arguments
|
|
|
|
Token - Handle to token to test for admin.
|
|
|
|
|
|
Return Values:
|
|
|
|
TRUE - The token IS and administrator's.
|
|
|
|
FALSE - The token is NOT an administrator's
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
ULONG
|
|
InfoLength;
|
|
|
|
PTOKEN_GROUPS
|
|
TokenGroupList;
|
|
|
|
ULONG
|
|
GroupIndex;
|
|
|
|
BOOL
|
|
FoundAdmin;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Get a list of groups in the token
|
|
//
|
|
|
|
NtStatus = NtQueryInformationToken(
|
|
Token, // Handle
|
|
TokenGroups, // TokenInformationClass
|
|
NULL, // TokenInformation
|
|
0, // TokenInformationLength
|
|
&InfoLength // ReturnLength
|
|
);
|
|
|
|
if ((NtStatus != STATUS_SUCCESS) && (NtStatus != STATUS_BUFFER_TOO_SMALL)) {
|
|
|
|
KdPrint(("SecMgr: failed to get group info for admin token, status = 0x%lx", NtStatus));
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
TokenGroupList = LocalAlloc( LPTR, InfoLength);
|
|
|
|
if (TokenGroupList == NULL) {
|
|
KdPrint(("SecMgr: unable to allocate memory for token groups"));
|
|
return(FALSE);
|
|
}
|
|
|
|
NtStatus = NtQueryInformationToken(
|
|
Token, // Handle
|
|
TokenGroups, // TokenInformationClass
|
|
TokenGroupList, // TokenInformation
|
|
InfoLength, // TokenInformationLength
|
|
&InfoLength // ReturnLength
|
|
);
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
KdPrint(("SecMgr: failed to query groups for admin token, status = 0x%lx", NtStatus));
|
|
LocalFree(TokenGroupList);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Search group list for admin alias
|
|
//
|
|
|
|
FoundAdmin = FALSE;
|
|
|
|
for (GroupIndex=0; GroupIndex < TokenGroupList->GroupCount; GroupIndex++ ) {
|
|
|
|
if (RtlEqualSid(TokenGroupList->Groups[GroupIndex].Sid, SecMgrpAdminsSid)) {
|
|
FoundAdmin = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Tidy up
|
|
//
|
|
|
|
LocalFree(TokenGroupList);
|
|
|
|
return(FoundAdmin);
|
|
}
|