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.
 
 
 
 
 
 

274 lines
9.2 KiB

//+---------------------------------------------------------------------------
//
// Scheduling Agent Service
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: atsec.cxx
//
// Contents: Net Schedule API access checking routines.
//
// Functions: AtCheckSecurity
// AtCreateSecurityObject
// AtDeleteSecurityObject
//
// History: 06-Nov-92 vladimv created.
// 30-May-96 EricB adapted for the scheduling agent.
//
//----------------------------------------------------------------------------
//
// Some NT header definitions conflict with some of the standard windows
// definitions. Thus, the project precompiled header can't be used.
//
extern "C" {
#include <nt.h> // NT definitions
#include <ntrtl.h> // NT runtime library definitions
#include <nturtl.h>
#include <netevent.h>
}
#include <windef.h> // Win32 type definitions
#include <winbase.h> // Win32 base API prototypes
#include <winsvc.h> // Win32 service control APIs
#include <winreg.h> // HKEY
#include <lmcons.h> // LAN Manager common definitions
#include <lmerr.h> // LAN Manager network error definitions
#include <netlib.h> // LAN Man utility routines
#include <netlibnt.h> // NetpNtStatusToApiStatus
#include <rpc.h> // DataTypes and runtime APIs
#include <rpcutil.h> // Prototypes for MIDL user functions
#include <secobj.h> // ACE_DATA
#include <..\..\..\smdebug\smdebug.h>
#include <debug.hxx>
#include "atsec.hxx"
//
// Security descriptor to control user access to the AT schedule service
// configuration information.
//
PSECURITY_DESCRIPTOR AtGlobalSecurityDescriptor = NULL;
#define AT_JOB_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \
AT_JOB_ADD | \
AT_JOB_DEL | \
AT_JOB_ENUM | \
AT_JOB_GET_INFO)
//
// Structure that describes the mapping of Generic access rights to
// object specific access rights for the AT schedule service security object.
//
GENERIC_MAPPING AtGlobalInformationMapping = {
STANDARD_RIGHTS_READ | // Generic read
AT_JOB_ENUM |
AT_JOB_GET_INFO,
STANDARD_RIGHTS_WRITE | // Generic write
AT_JOB_ADD |
AT_JOB_DEL,
STANDARD_RIGHTS_EXECUTE, // Generic execute
AT_JOB_ALL_ACCESS // Generic all
};
//+---------------------------------------------------------------------------
//
// Function: AtCheckSecurity
//
// Synopsis: Verify that the caller has the proper privilege.
//
// Arguments: [DesiredAccess] - the type of access.
//
// Returns: NERR_Success or reason for failure.
//
// Notes: This routine checks if an rpc caller is allowed to perform a
// given AT service operation. Members of the groups LocalAdmin
// and LocalBackupOperators are allowed to do all operations and
// everybody else is not allowed to do anything.
//
//----------------------------------------------------------------------------
NET_API_STATUS
AtCheckSecurity(ACCESS_MASK DesiredAccess)
{
NTSTATUS NtStatus;
NET_API_STATUS Status;
HANDLE ClientToken;
LPWSTR StringArray[2];
WCHAR ErrorCodeString[25];
if ((Status = RpcImpersonateClient(NULL)) != NERR_Success)
{
ERR_OUT("RpcImpersonateClient", Status);
return Status;
}
NtStatus = NtOpenThreadToken(NtCurrentThread(),
TOKEN_QUERY,
(BOOLEAN)TRUE,
&ClientToken);
if (NtStatus != STATUS_SUCCESS)
{
ERR_OUT("NtOpenThreadToken", NtStatus);
}
else
{
PRIVILEGE_SET PrivilegeSet;
DWORD PrivilegeSetLength;
ACCESS_MASK GrantedAccess;
NTSTATUS AccessStatus;
PrivilegeSetLength = sizeof( PrivilegeSet);
// NtAccessCheck() returns STATUS_SUCCESS if parameters
// are correct. Whether or not access is allowed is
// governed by the returned value of AccessStatus.
NtStatus = NtAccessCheck(
AtGlobalSecurityDescriptor, // SecurityDescriptor
ClientToken, // ClientToken
DesiredAccess, // DesiredAccess
&AtGlobalInformationMapping, // GenericMapping
&PrivilegeSet,
&PrivilegeSetLength,
&GrantedAccess, // GrantedAccess
&AccessStatus); // AccessStatus
if (NtStatus != STATUS_SUCCESS)
{
ERR_OUT("NtAccessCheck", NtStatus);
}
else
{
NtStatus = AccessStatus;
}
NtClose(ClientToken);
}
if ((Status = RpcRevertToSelf()) != NERR_Success)
{
ERR_OUT("RpcRevertToSelf", Status);
return Status;
}
return(NetpNtStatusToApiStatus(NtStatus));
}
//+----------------------------------------------------------------------------
//
// Function: AtCreateSecurityObject
//
// Synopsis: Creates the scheduler user-mode configuration information
// object which is represented by a security descriptor.
//
// Returns: NERR_Success or reason for failure.
//
//-----------------------------------------------------------------------------
NET_API_STATUS
AtCreateSecurityObject(VOID)
{
DWORD SubmitControl;
NTSTATUS status;
DWORD type;
DWORD Length;
HKEY LsaKey;
//
// Server operators are permitted to manage the AT schedule service only if
// the key exists and the proper flag is set. In all other case we do not
// permit server operators to manage the AT schedule service.
//
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
SCH_LSA_REGISTRY_PATH,
0L,
KEY_READ,
&LsaKey);
if (status != ERROR_SUCCESS)
{
ERR_OUT("RegOpenKeyEx(LsaKey)", status);
return status;
}
Length = sizeof(SubmitControl);
status = RegQueryValueEx(LsaKey,
SCH_LSA_SUBMIT_CONTROL,
NULL,
&type,
(LPBYTE)&SubmitControl,
&Length);
RegCloseKey(LsaKey);
if (status != ERROR_SUCCESS ||
type != REG_DWORD ||
Length != sizeof(SubmitControl))
{
DBG_OUT3("SubmitControl reg value not found, "
"ServerOps not enabled for AT cmd.");
SubmitControl = 0;
}
status = NetpCreateWellKnownSids(NULL);
if (!NT_SUCCESS(status))
{
ERR_OUT("Failure to create security object", 0);
return NetpNtStatusToApiStatus(status);
}
//
// Order matters! These ACEs are inserted into the DACL in the
// following order. Security access is granted or denied based on
// the order of the ACEs in the DACL.
//
// In win3.1 both LocalGroupAdmins and LocalGroupSystemOps were
// allowed to perform all Schedule Service operations. In win3.5
// LocalGroupSystemOps may be disallowed (this is the default case).
//
ACE_DATA aceData[] = {
{ACCESS_ALLOWED_ACE_TYPE, 0, 0, GENERIC_ALL, &AliasAdminsSid},
{ACCESS_ALLOWED_ACE_TYPE, 0, 0, GENERIC_ALL, &AliasSystemOpsSid}
};
status = NetpCreateSecurityObject(
aceData, // pAceData
(SubmitControl & SCH_SERVER_OPS) ? 2 : 1, // countAceData
NULL, // OwnerSid
NULL, // PrimaryGroupSid
&AtGlobalInformationMapping,
&AtGlobalSecurityDescriptor); // ppNewDescriptor
if (!NT_SUCCESS(status))
{
ERR_OUT("Failure to create security object", 0);
return NetpNtStatusToApiStatus(status);
}
return NERR_Success;
}
//+---------------------------------------------------------------------------
//
// Function: AtDeleteSecurityObject
//
// Synopsis: Destroys the schedule service user-mode configuration
// information object.
//
// Returns: NERR_Success or reason for failure.
//
//----------------------------------------------------------------------------
void
AtDeleteSecurityObject(VOID)
{
if (AtGlobalSecurityDescriptor != NULL)
{
NetpDeleteSecurityObject(&AtGlobalSecurityDescriptor);
NetpFreeWellKnownSids();
}
}