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.
 
 
 
 
 
 

337 lines
8.0 KiB

/****************************** Module Header ******************************\
* Module Name: lsautil.c
*
* Copyright (c) 1994, Microsoft Corporation
*
* Remote shell server main module
*
* History:
* 05-19-94 DaveTh Created.
\***************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <ntlsa.h>
#include <windef.h>
#include <nturtl.h>
#include <winbase.h>
#include "rcmdsrv.h"
#define INITIAL_SIZE_REQUIRED 600
DWORD
CheckUserSystemAccess(
HANDLE TokenHandle,
ULONG DesiredSystemAccess,
PBOOLEAN UserHasAccess
)
/*++
Routine Description:
This function determines whether or not the user whose token is passed
has the interactive accesses desired on this machine.
Arguments:
TokenHandle - Handle of user's token.
DesiredSystemAccess - Specifies desired access type(s).
UserHasAccess - pointer to boolean returned - TRUE means that user
has interactive access.
Return Value:
ERROR_SUCCESS in absence of errors. UserHasAccess is TRUE if all
requested access types are permitted, otherwise FALSE. WIN32 errors
are returned in error cases.
--*/
{
DWORD Result;
LPVOID LpTokenUserInformation = NULL;
LPVOID LpTokenGroupInformation = NULL;
DWORD SizeRequired, SizeProvided;
LSA_HANDLE PolicyHandle = NULL;
LSA_HANDLE AccountHandle = NULL;
NTSTATUS NtStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
POBJECT_ATTRIBUTES LpObjectAttributes;
ULONG GrantedSystemAccess, SidSystemAccess;
DWORD i;
//
// Access LSA policy database
//
LpObjectAttributes = &ObjectAttributes;
InitializeObjectAttributes(
LpObjectAttributes,
NULL,
0,
NULL,
NULL);
if (!NT_SUCCESS(NtStatus = LsaOpenPolicy(
NULL, // Local system
LpObjectAttributes,
GENERIC_READ,
&PolicyHandle))) {
RcDbgPrint("Error opening policy database, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
}
//
// Check groups, user - For each SID, open the account (if it exists).
// If it doesn't exist, no failure, but no access (FALSE). If it
// does exist, accumulate granted accesses in and compare to
// requested mask. If all the bits of the mask have been set at any
// point, UserHasAccess is set TRUE. Otherise, it is left FALSE.
//
*UserHasAccess = FALSE;
GrantedSystemAccess = 0;
//
// Get list of SIDs of groups of which user is a member
//
if ((LpTokenGroupInformation = Alloc(INITIAL_SIZE_REQUIRED)) == NULL) {
Result = GetLastError();
goto Failure;
}
if (!GetTokenInformation (
TokenHandle,
TokenGroups,
LpTokenGroupInformation,
INITIAL_SIZE_REQUIRED,
&SizeRequired)) {
Result = GetLastError();
if ( (Result == ERROR_MORE_DATA) || (Result == ERROR_INSUFFICIENT_BUFFER) ) {
Free(LpTokenGroupInformation);
if ((LpTokenGroupInformation = Alloc(SizeRequired)) == NULL) {
Result = GetLastError();
goto Failure;
}
SizeProvided = SizeRequired;
if (!GetTokenInformation (
TokenHandle,
TokenGroups,
LpTokenGroupInformation,
SizeProvided,
&SizeRequired)) {
Result=GetLastError();
RcDbgPrint("Error accessing group SIDs, error = %d\n", Result);
goto Failure;
}
} else {
RcDbgPrint("Error accessing group SIDs, error = %d\n", Result);
goto Failure;
}
}
//
// Check for each group that user is a member of since groups
// are most likely source of permitted access. Permitted access types
// are cumulative.
//
for (i=0; i< ((PTOKEN_GROUPS)LpTokenGroupInformation)->GroupCount; i++) {
if (NT_SUCCESS(NtStatus = LsaOpenAccount(
PolicyHandle,
((PTOKEN_GROUPS)LpTokenGroupInformation)->Groups[i].Sid,
GENERIC_READ,
&AccountHandle))) {
//
// found account - accumulate and check accesses
//
if (!NT_SUCCESS(NtStatus = LsaGetSystemAccessAccount (
AccountHandle,
&SidSystemAccess))) {
RcDbgPrint("Error getting group account access, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
} else {
//
// Got system access - don't need account handle anymore
//
if (NT_SUCCESS(NtStatus = LsaClose(AccountHandle))) {
AccountHandle = NULL;
} else {
RcDbgPrint("Error closing account handle, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
}
GrantedSystemAccess |= SidSystemAccess;;
if ((GrantedSystemAccess & DesiredSystemAccess) == DesiredSystemAccess) {
*UserHasAccess = TRUE;
goto Success;
}
}
} else if (NtStatus != STATUS_OBJECT_NAME_NOT_FOUND) {
RcDbgPrint("Error opening group account, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
}
}
//
// Get user SID
//
if ((LpTokenUserInformation = Alloc(INITIAL_SIZE_REQUIRED)) == NULL) {
Result = GetLastError();
goto Failure;
}
if (!GetTokenInformation (
TokenHandle,
TokenUser,
LpTokenUserInformation,
INITIAL_SIZE_REQUIRED,
&SizeRequired)) {
Result = GetLastError();
if (Result == ERROR_MORE_DATA) { // Not enough - alloc and redo
Free(LpTokenUserInformation);
if ((LpTokenUserInformation = Alloc(SizeRequired)) == NULL) {
Result = GetLastError();
goto Failure;
}
SizeProvided = SizeRequired;
if (!GetTokenInformation (
TokenHandle,
TokenUser,
LpTokenUserInformation,
SizeProvided,
&SizeRequired)) {
RcDbgPrint("Error accessing user SID, error = %d\n", Result);
Result=GetLastError();
goto Failure;
}
} else {
RcDbgPrint("Error accessing user SID, error = %d\n", Result);
goto Failure;
}
}
//
// Now, check user account. If present, check access and return
// if requested access is allowed. If not allowed, go on to check groups.
// If account doesn't exist, go on to check groups.
//
if (NT_SUCCESS(NtStatus = LsaOpenAccount(
PolicyHandle,
((PTOKEN_USER)LpTokenUserInformation)->User.Sid,
GENERIC_READ,
&AccountHandle))) {
//
// found account - check accesses
//
if (!NT_SUCCESS(NtStatus = LsaGetSystemAccessAccount (
AccountHandle,
&GrantedSystemAccess))) {
RcDbgPrint("Error getting group account access, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
} else {
GrantedSystemAccess |= SidSystemAccess;;
if ((GrantedSystemAccess & DesiredSystemAccess) == DesiredSystemAccess) {
*UserHasAccess = TRUE;
goto Success;
}
}
} else if (NtStatus != STATUS_OBJECT_NAME_NOT_FOUND) {
RcDbgPrint("Error opening user account, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
goto Failure;
}
//
// Success - Jump here if access granted, fall through here on no error
//
Success:
Result = ERROR_SUCCESS;
//
// General failure and success exit - frees memory, closes handles
//
Failure:
if (LpTokenGroupInformation != NULL) {
Free(LpTokenGroupInformation);
}
if (LpTokenUserInformation != NULL) {
Free(LpTokenGroupInformation);
}
if ((PolicyHandle != NULL) &&
(!NT_SUCCESS(NtStatus = LsaClose(PolicyHandle)))) {
RcDbgPrint("Error closing policy handle at exit, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
}
if ((AccountHandle != NULL) &&
(!NT_SUCCESS(NtStatus = LsaClose(AccountHandle)))) {
RcDbgPrint("Error closing account handle at exit, error = %x\n", NtStatus);
Result = RtlNtStatusToDosError(NtStatus);
}
return(Result);
}