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.
431 lines
11 KiB
431 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
acehelp.hxx
|
|
|
|
Abstract:
|
|
|
|
This module contains definitions for helper routines for
|
|
manipulating ACE's.
|
|
|
|
|
|
Author:
|
|
|
|
Bill McJohn (billmc) 09-Feb-1992
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
extern "C" {
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntseapi.h>
|
|
#include <windows.h>
|
|
}
|
|
|
|
|
|
#include "lmconst.hxx"
|
|
#include "acehelp.hxx"
|
|
|
|
VOID
|
|
ConvertAccessMasks(
|
|
IN USHORT LanmanAccess,
|
|
OUT PACCESS_MASK DirMask,
|
|
OUT PACCESS_MASK FileMask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method constructs NT Access Masks that correspond to a
|
|
Lanman 2.x access mask.
|
|
|
|
Arguments:
|
|
|
|
LanmanAccess -- Supplies the Lanman 2.x access mask.
|
|
DirMask -- Receives the corresponding access mask for
|
|
a directory object.
|
|
FileMask -- Receives the corresponding access mask for
|
|
a file object.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
register ACCESS_MASK DirResult, FileResult;
|
|
|
|
if( (LanmanAccess & ~LM_ACCESS_GROUP) == LM_ACCESS_ALL ) {
|
|
|
|
// This access mask grants all possible permissions.
|
|
|
|
DirResult = GENERIC_ALL;
|
|
FileResult = GENERIC_ALL;
|
|
|
|
} else {
|
|
|
|
// Check each of the possible bits.
|
|
|
|
DirResult = 0;
|
|
FileResult = 0;
|
|
|
|
|
|
if( LanmanAccess & LM_ACCESS_READ ) {
|
|
|
|
DirResult |= GENERIC_READ;
|
|
FileResult |= GENERIC_READ;
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_WRITE ) {
|
|
|
|
DirResult |= GENERIC_WRITE;
|
|
FileResult |= GENERIC_WRITE;
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_CREATE ) {
|
|
|
|
DirResult |= (GENERIC_WRITE | GENERIC_EXECUTE);
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_EXEC ) {
|
|
|
|
DirResult |= GENERIC_EXECUTE;
|
|
FileResult |= GENERIC_EXECUTE;
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_DELETE ) {
|
|
|
|
DirResult |= DELETE;
|
|
FileResult |= DELETE;
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_ATRIB ) {
|
|
|
|
DirResult |= FILE_WRITE_ATTRIBUTES;
|
|
FileResult |= FILE_WRITE_ATTRIBUTES;
|
|
}
|
|
|
|
if( LanmanAccess & LM_ACCESS_PERM ) {
|
|
|
|
DirResult |= (WRITE_DAC | WRITE_OWNER);
|
|
FileResult |= (WRITE_DAC | WRITE_OWNER);
|
|
}
|
|
}
|
|
|
|
*DirMask = DirResult;
|
|
*FileMask = FileResult;
|
|
}
|
|
|
|
VOID
|
|
ConvertAuditBits(
|
|
IN USHORT LmAuditBits,
|
|
OUT PACCESS_MASK DirSuccessfulMask,
|
|
OUT PACCESS_MASK DirFailedMask,
|
|
OUT PACCESS_MASK FileSuccessfulMask,
|
|
OUT PACCESS_MASK FileFailedMask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function constructs NT access masks that correspond to
|
|
Lanman 2.x Audit bitmasks.
|
|
|
|
Arguments:
|
|
|
|
LmAuditBits -- Supplies the Lanman 2.x audit bitmask
|
|
DirSuccessfulMask -- Receives the corresponding NT access mask
|
|
for auditing successful directory accesses.
|
|
DirFailedMask -- Receives the corresponding NT access mask
|
|
for auditing failed directory accesses.
|
|
FileSuccessfulMask -- Receives the corresponding NT access mask
|
|
for auditing successful file accesses.
|
|
FileFailedMask -- Receives the corresponding NT access mask
|
|
for auditing failed file accesses.
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ACCESS_MASK DirFailedResult, DirSuccessfulResult,
|
|
FileFailedResult, FileSuccessfulResult;
|
|
|
|
// If the 'all' bit is set, this conversion is easy:
|
|
|
|
if( LmAuditBits & LM_AUDIT_ALL ) {
|
|
|
|
*DirSuccessfulMask = GENERIC_ALL;
|
|
*DirFailedMask = GENERIC_ALL;
|
|
*FileSuccessfulMask = GENERIC_ALL;
|
|
*FileFailedMask = GENERIC_ALL;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
// Compute the audit mask for successful directory access:
|
|
//
|
|
DirSuccessfulResult = 0;
|
|
if( LmAuditBits & LM_AUDIT_S_CREATE ) DirSuccessfulResult |= (FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE);
|
|
if( LmAuditBits & LM_AUDIT_S_DELETE ) DirSuccessfulResult |= DELETE;
|
|
if( LmAuditBits & LM_AUDIT_S_ACL ) DirSuccessfulResult |= (WRITE_DAC | WRITE_OWNER);
|
|
|
|
// Compute the audit mask for failed directory access:
|
|
//
|
|
DirFailedResult = 0;
|
|
if( LmAuditBits & LM_AUDIT_F_CREATE ) DirFailedResult |= (FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE);
|
|
if( LmAuditBits & LM_AUDIT_F_DELETE ) DirFailedResult |= DELETE;
|
|
if( LmAuditBits & LM_AUDIT_F_ACL ) DirFailedResult |= (WRITE_DAC | WRITE_OWNER);
|
|
|
|
// Compute the audit mask for successful file access:
|
|
//
|
|
FileSuccessfulResult = 0;
|
|
if( LmAuditBits & LM_AUDIT_S_OPEN ) FileSuccessfulResult |= GENERIC_READ;
|
|
if( LmAuditBits & LM_AUDIT_S_WRITE ) FileSuccessfulResult |= GENERIC_WRITE;
|
|
if( LmAuditBits & LM_AUDIT_S_DELETE ) FileSuccessfulResult |= DELETE;
|
|
if( LmAuditBits & LM_AUDIT_S_ACL ) FileSuccessfulResult |= (WRITE_DAC | WRITE_OWNER);
|
|
|
|
// Compute the audit mask for failed file access:
|
|
//
|
|
FileFailedResult = 0;
|
|
if( LmAuditBits & LM_AUDIT_F_OPEN ) FileFailedResult |= GENERIC_READ;
|
|
if( LmAuditBits & LM_AUDIT_F_WRITE ) FileFailedResult |= GENERIC_WRITE;
|
|
if( LmAuditBits & LM_AUDIT_F_DELETE ) FileFailedResult |= DELETE;
|
|
if( LmAuditBits & LM_AUDIT_F_ACL ) FileFailedResult |= (WRITE_DAC | WRITE_OWNER);
|
|
|
|
|
|
// Fill in the return values:
|
|
|
|
*DirSuccessfulMask = DirSuccessfulResult;
|
|
*DirFailedMask = DirFailedResult;
|
|
*FileSuccessfulMask = FileSuccessfulResult;
|
|
*FileFailedMask = FileFailedResult;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
CreateAccessAllowedAce(
|
|
IN OUT PVOID Buffer,
|
|
IN ULONG BufferLength,
|
|
IN ACCESS_MASK Access,
|
|
IN UCHAR InheritFlags,
|
|
IN PSID Sid,
|
|
OUT PULONG AceLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method creates an access-allowed ACE in the supplied buffer.
|
|
|
|
Arguments:
|
|
|
|
Buffer -- Supplies the buffer in which the ACE should be
|
|
created.
|
|
BufferLength -- Supplies the length of the buffer.
|
|
Access -- Supplies the desired Access Mask.
|
|
InheritFlags -- Supplies the ACE's inherit flags.
|
|
Sid -- Supplies the ACE's SID.
|
|
AceLength -- Receives the length of the created ACE.
|
|
|
|
Return Value:
|
|
|
|
TRUE upon successful completion.
|
|
|
|
--*/
|
|
{
|
|
PACCESS_ALLOWED_ACE NewAce;
|
|
ULONG SidLength;
|
|
|
|
SidLength = GetLengthSid( Sid );
|
|
|
|
*AceLength = sizeof( ACE_HEADER ) +
|
|
sizeof( ACCESS_MASK ) +
|
|
SidLength;
|
|
|
|
if( *AceLength > BufferLength ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
NewAce = (PACCESS_ALLOWED_ACE)Buffer;
|
|
|
|
NewAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
|
|
NewAce->Header.AceSize = (USHORT)*AceLength;
|
|
NewAce->Header.AceFlags = InheritFlags;
|
|
|
|
NewAce->Mask = Access;
|
|
|
|
return( CopySid( SidLength,
|
|
(PSID)((PBYTE)Buffer + sizeof( ACE_HEADER ) +
|
|
sizeof( ACCESS_MASK )),
|
|
Sid ) );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
CreateAccessDeniedAce(
|
|
IN OUT PVOID Buffer,
|
|
IN ULONG BufferLength,
|
|
IN ACCESS_MASK Access,
|
|
IN UCHAR InheritFlags,
|
|
IN PSID Sid,
|
|
OUT PULONG AceLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method creates an access-denied ACE in the supplied buffer.
|
|
Note that the only sort of access-denied ACE that ACLCONV creates
|
|
is one which denies all access.
|
|
|
|
Arguments:
|
|
|
|
Buffer -- Supplies the buffer in which the ACE should be
|
|
created.
|
|
BufferLength -- Supplies the length of the buffer.
|
|
Access -- Supplies the desired Access Mask.
|
|
InheritFlags -- Supplies the ACE's inherit flags.
|
|
Sid -- Supplies the ACE's SID.
|
|
AceLength -- Receives the length of the created ACE.
|
|
|
|
Return Value:
|
|
|
|
TRUE upon successful completion.
|
|
|
|
--*/
|
|
{
|
|
PACCESS_DENIED_ACE NewAce;
|
|
ULONG SidLength;
|
|
|
|
UNREFERENCED_PARAMETER( Access );
|
|
|
|
SidLength = GetLengthSid( Sid );
|
|
|
|
*AceLength = sizeof( ACE_HEADER ) +
|
|
sizeof( ACCESS_MASK ) +
|
|
SidLength;
|
|
|
|
if( *AceLength > BufferLength ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
NewAce = (PACCESS_DENIED_ACE)Buffer;
|
|
|
|
NewAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
|
|
NewAce->Header.AceSize = (USHORT)*AceLength;
|
|
NewAce->Header.AceFlags = InheritFlags;
|
|
|
|
NewAce->Mask = GENERIC_ALL;
|
|
|
|
return( CopySid( SidLength,
|
|
(PSID)((PBYTE)Buffer + sizeof( ACE_HEADER ) +
|
|
sizeof( ACCESS_MASK )),
|
|
Sid ) );
|
|
}
|
|
|
|
|
|
SID_IDENTIFIER_AUTHORITY World = SECURITY_WORLD_SID_AUTHORITY;
|
|
|
|
BOOLEAN
|
|
CreateSystemAuditAce(
|
|
IN OUT PVOID Buffer,
|
|
IN ULONG BufferLength,
|
|
IN ACCESS_MASK Access,
|
|
IN UCHAR InheritFlags,
|
|
IN BOOLEAN AuditFailures,
|
|
OUT PULONG AceLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method creates a System Audit ACE in the supplied buffer.
|
|
|
|
Arguments:
|
|
|
|
Buffer -- Supplies the buffer in which the ACE should
|
|
be created.
|
|
BufferLength -- Supplies the length of the buffer.
|
|
Access -- Supplies the access mask that should be audited.
|
|
InheritFlags -- Supplies the inheritance flags for the ACE.
|
|
AuditFailures -- Supplies a flag which, if TRUE, indicates that
|
|
the ACE should be set to audit failed access,
|
|
rather than successful access.
|
|
AceLength -- Receives the length of the ACE.
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE upon successful completion.
|
|
|
|
Notes:
|
|
|
|
ACLCONV always creates System Audit Aces with the well-known SID WORLD.
|
|
It has the SID Identifier Authority SECURITY_WORLD_SID_AUTHORITY and
|
|
no subauthorities.
|
|
|
|
--*/
|
|
{
|
|
PSYSTEM_AUDIT_ACE NewAce;
|
|
ULONG NewAceLength, SidOffset, SidLength;
|
|
PSID WorldSid;
|
|
|
|
|
|
// See if the supplied buffer is big enough to hold a System
|
|
// Audit Ace that has an SID with one subauthority. This kind
|
|
// of ACE consists of an ACE_HEADER followed by an ACCESS_MASK
|
|
// followed by the SID.
|
|
|
|
SidLength = GetSidLengthRequired( 1 );
|
|
|
|
SidOffset = sizeof( ACE_HEADER ) + sizeof( ACCESS_MASK );
|
|
|
|
NewAceLength = SidOffset + SidLength;
|
|
|
|
if( NewAceLength > BufferLength ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the ACE.
|
|
|
|
NewAce = (PSYSTEM_AUDIT_ACE)Buffer;
|
|
|
|
NewAce->Header.AceType = SYSTEM_AUDIT_ACE_TYPE;
|
|
NewAce->Header.AceSize = (USHORT)NewAceLength;
|
|
NewAce->Header.AceFlags = InheritFlags;
|
|
NewAce->Header.AceFlags |= AuditFailures ? SUCCESSFUL_ACCESS_ACE_FLAG :
|
|
FAILED_ACCESS_ACE_FLAG;
|
|
|
|
NewAce->Mask = Access;
|
|
|
|
// WORLD is a well-known SID with one subauthority.
|
|
//
|
|
WorldSid = (PSID)((PBYTE)Buffer + SidOffset);
|
|
InitializeSid( WorldSid, &World, 1 );
|
|
*GetSidSubAuthority( WorldSid, 0 ) = SECURITY_WORLD_RID;
|
|
|
|
*AceLength = NewAceLength;
|
|
return TRUE;
|
|
}
|