1400 lines
41 KiB
C++
1400 lines
41 KiB
C++
/**********************************************************************/
|
||
/** Microsoft Windows NT **/
|
||
/** Copyright(c) Microsoft Corp., 1992 **/
|
||
/**********************************************************************/
|
||
|
||
/*
|
||
Security.hxx
|
||
|
||
This file contains wrapper classes for the Win32 security structures.
|
||
Specifically: ACL, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL,
|
||
and SID. The wrapper classes follow the same name except the class
|
||
names will begin with an "OS_".
|
||
|
||
FILE HISTORY:
|
||
Johnl 03-Dec-1991 Created
|
||
JohnL 09-Mar-1992 Code review changes
|
||
Thomaspa 09-Apr-1992 Added OS_SID::Compare()
|
||
JonN 30-Oct-1992 Added OS_SID::QueryLastSubAuthority()
|
||
|
||
*/
|
||
|
||
#ifndef _SECURITY_HXX_
|
||
#define _SECURITY_HXX_
|
||
|
||
#include "uibuffer.hxx"
|
||
|
||
/* This error code is returned from the OS_DACL_SUBJECT_ITER and the
|
||
* OS_SACL_SUBJECT_ITER when the iterator encounters an ACL that does
|
||
* not follow the form of (Deny All)* | (Grants)* or when an unrecognized
|
||
* ACE is encountered.
|
||
*/
|
||
#define IERR_UNRECOGNIZED_ACL 14355
|
||
|
||
|
||
// DbgPrint() declaration macro.
|
||
|
||
#if defined(DEBUG)
|
||
#define DBG_PRINT_SEC_IMPLEMENTATION { _DbgPrint(); }
|
||
#else
|
||
#define DBG_PRINT_SEC_IMPLEMENTATION { ; }
|
||
#endif
|
||
|
||
#define DECLARE_DBG_PRINT_SEC \
|
||
void _DbgPrint () const ; \
|
||
void DbgPrint () const DBG_PRINT_SEC_IMPLEMENTATION
|
||
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_OBJECT_WITH_DATA
|
||
|
||
SYNOPSIS: Base class for all OS_* wrapper classes that potentially
|
||
contain their own data (as opposed to pointing at somebody
|
||
elses). This is just a convenient place to declare the
|
||
BUFFER (as opposed to doing it in each class).
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: BASE
|
||
|
||
USES: BUFFER
|
||
|
||
CAVEATS:
|
||
|
||
|
||
NOTES:
|
||
|
||
|
||
HISTORY:
|
||
Johnl 10-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_OBJECT_WITH_DATA : public BASE
|
||
{
|
||
private:
|
||
BUFFER _buffOSData ;
|
||
|
||
protected:
|
||
|
||
OS_OBJECT_WITH_DATA( UINT cbInitSize = 0 ) ;
|
||
~OS_OBJECT_WITH_DATA() ;
|
||
|
||
void * QueryPtr( void ) const
|
||
{ return _buffOSData.QueryPtr() ; }
|
||
|
||
UINT QueryAllocSize( void ) const
|
||
{ return _buffOSData.QuerySize() ; }
|
||
|
||
APIERR Resize( UINT uiNewSize )
|
||
{ return _buffOSData.Resize( uiNewSize ) ; }
|
||
} ;
|
||
|
||
DLL_CLASS OS_SECURITY_DESCRIPTOR ; // Forward reference
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_SID
|
||
|
||
SYNOPSIS: Wrapper class for an NT SID
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: OS_OBJECT_WITH_DATA
|
||
|
||
USES:
|
||
|
||
CAVEATS:
|
||
|
||
|
||
NOTES:
|
||
|
||
|
||
HISTORY:
|
||
Johnl 09-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SID : public OS_OBJECT_WITH_DATA
|
||
{
|
||
private:
|
||
/* This pointer will be aliased either to our internal data buffer
|
||
* or to the SID the user passed in.
|
||
*/
|
||
PSID _psid ;
|
||
|
||
OS_SECURITY_DESCRIPTOR * _pOwner ;
|
||
|
||
protected:
|
||
BOOL IsOwnerAlloc( void ) const
|
||
{ return ((void *)_psid) != QueryPtr() ; }
|
||
|
||
public:
|
||
OS_SID( PSID psid = NULL,
|
||
BOOL fCopy = FALSE,
|
||
OS_SECURITY_DESCRIPTOR * pOwner = NULL ) ;
|
||
|
||
/* Builds a fully qualifed sid from the domain SID and the Relative ID
|
||
* of the account in the domain.
|
||
*/
|
||
OS_SID( PSID psidDomain,
|
||
ULONG ridAccount,
|
||
OS_SECURITY_DESCRIPTOR * pOwner = NULL ) ;
|
||
|
||
~OS_SID() ;
|
||
|
||
/* Returns TRUE if NT thinks this is a valid SID.
|
||
*/
|
||
BOOL IsValid( void ) const ;
|
||
|
||
/* Returns the size of this SID in bytes. If the SID is not valid, then
|
||
* zero is returned.
|
||
*/
|
||
ULONG QueryLength( void ) const ;
|
||
|
||
/* Places the text string of the Identifier Authority into *pnlsRawID.
|
||
* The text string will look something like "1-5-17"
|
||
*/
|
||
APIERR QueryRawID( NLS_STR * pnlsRawID ) const ;
|
||
|
||
/* Retrieves a user/group name suitable for user consumption.
|
||
* If the account is on a remote machine, then pszServer must
|
||
* be filled with the remote machine name.
|
||
*
|
||
* psidFocusedDomain - The doamin SID that the name should be qualified in
|
||
* relation to. Defaults to the current user's logged on domain if
|
||
* NULL.
|
||
*
|
||
* OR
|
||
*
|
||
* pszFocus - indicates how the name should be qualified. If pszFocus
|
||
* is NULL, then the focus is assumed to be pszServer. Note that
|
||
* this form simply opens up an LSAPolicy and gets the domain sid
|
||
* that pszFocus points to (this you should avoid using this form).
|
||
*/
|
||
APIERR QueryName( NLS_STR * pnlsUserName,
|
||
const TCHAR * pszServer = NULL,
|
||
PSID psidFocusedDomain = NULL ) const ;
|
||
|
||
#if 0
|
||
//
|
||
// Nobody should need this form, undef if you do
|
||
//
|
||
APIERR QueryName( NLS_STR * pnlsUserName,
|
||
const TCHAR * pszServer = NULL,
|
||
const TCHAR * pszFocus = NULL ) const ;
|
||
#endif //0
|
||
|
||
/* Returns a pointer to the ith sub-authority in this SID.
|
||
* An error is returned if you request a sub-authority that is
|
||
* out of range.
|
||
*/
|
||
APIERR QuerySubAuthority( UCHAR iSubAuthority,
|
||
PULONG * ppulSubAuthority ) const ;
|
||
|
||
/* Returns a pointer to the count field of of sub-authorities for this
|
||
* SID.
|
||
*/
|
||
APIERR QuerySubAuthorityCount( UCHAR * * ppcSubAuthority ) const ;
|
||
|
||
/* Returns the last SubAuthority, which is the RID for user, group and
|
||
* alias SIDs.
|
||
*/
|
||
APIERR QueryLastSubAuthority( PULONG * ppulSubAuthority ) const;
|
||
|
||
/* Removes the last SubAuthority. This will change user, group and
|
||
* alias SIDs into the SID for their domain.
|
||
*/
|
||
APIERR TrimLastSubAuthority( ULONG * pulLastSubAuthority = NULL );
|
||
|
||
BOOL operator==( const OS_SID & ossid ) const ;
|
||
|
||
int Compare( const OS_SID * possid ) const
|
||
{ return ( *this == *possid ? 0 : 1 ); }
|
||
|
||
APIERR Copy( const OS_SID & ossid ) ;
|
||
|
||
/* This method can be used to initialize a chunk of memory to a valid
|
||
* SID format.
|
||
*/
|
||
static void InitializeMemory( void * pMemToInitAsSID ) ;
|
||
|
||
APIERR SetPtr( PSID psid ) ;
|
||
|
||
DECLARE_DBG_PRINT_SEC
|
||
|
||
/* Conversion operators
|
||
*/
|
||
operator PSID () const
|
||
{ return _psid ; }
|
||
|
||
PSID QueryPSID( void ) const
|
||
{ return _psid ; }
|
||
|
||
/* Don't use this, use QueryPSID (same thing, just clearer name)
|
||
*/
|
||
PSID QuerySid( void ) const
|
||
{ return _psid ; }
|
||
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_SECURITY_DESCRIPTOR_CONTROL
|
||
|
||
SYNOPSIS: Simple wrapper class for Win32 SECURITY_DESCRIPTOR_CONTROL
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT:
|
||
|
||
USES:
|
||
|
||
CAVEATS: The third constructor can be used to operate on a
|
||
SECURITY_DESCRIPTOR_CONTROL thing in place, however the user
|
||
should ensure that the memory being operated on "in place"
|
||
should hang around till this object is destructed.
|
||
|
||
NOTES:
|
||
|
||
|
||
HISTORY:
|
||
Johnl 03-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SECURITY_DESCRIPTOR_CONTROL
|
||
{
|
||
private:
|
||
/* Don't reference this member!! Reference _psecesccont.
|
||
*/
|
||
SECURITY_DESCRIPTOR_CONTROL _secdesccont ;
|
||
|
||
/* This pointer will either be aliased to _secdesccont or else
|
||
* to the PSECURITY_DESCRIPTOR_CONTROL the user constructs this object
|
||
* with.
|
||
*
|
||
* All operations should be performed on *_psecdesccont.
|
||
*/
|
||
PSECURITY_DESCRIPTOR_CONTROL _psecdesccont ;
|
||
|
||
public:
|
||
OS_SECURITY_DESCRIPTOR_CONTROL( SECURITY_DESCRIPTOR_CONTROL secdesccont )
|
||
: _secdesccont( secdesccont ),
|
||
_psecdesccont( &_secdesccont )
|
||
{ ; }
|
||
|
||
OS_SECURITY_DESCRIPTOR_CONTROL( PSECURITY_DESCRIPTOR_CONTROL psecdesccont = NULL )
|
||
: _secdesccont( 0 ),
|
||
_psecdesccont( psecdesccont==NULL ? &_secdesccont : psecdesccont )
|
||
{ ; }
|
||
|
||
/* IsXXX Methods
|
||
*/
|
||
BOOL IsOwnerDefaulted( void ) const
|
||
{ return !!(*_psecdesccont & SE_OWNER_DEFAULTED) ; }
|
||
|
||
BOOL IsGroupDefaulted( void ) const
|
||
{ return !!(*_psecdesccont & SE_GROUP_DEFAULTED) ; }
|
||
|
||
BOOL IsDACLPresent( void ) const
|
||
{ return !!(*_psecdesccont & SE_DACL_PRESENT) ; }
|
||
|
||
BOOL IsDACLDefaulted( void ) const
|
||
{ return !!(*_psecdesccont & SE_DACL_DEFAULTED) ; }
|
||
|
||
BOOL IsSACLPresent( void ) const
|
||
{ return !!(*_psecdesccont & SE_SACL_PRESENT) ; }
|
||
|
||
BOOL IsSACLDefaulted( void ) const
|
||
{ return !!(*_psecdesccont & SE_SACL_DEFAULTED) ; }
|
||
|
||
BOOL IsSelfRelative( void ) const
|
||
{ return !!(*_psecdesccont & SE_SELF_RELATIVE) ; }
|
||
|
||
/* Conversion operators
|
||
*/
|
||
operator PSECURITY_DESCRIPTOR_CONTROL() const
|
||
{ return _psecdesccont ; }
|
||
|
||
operator SECURITY_DESCRIPTOR_CONTROL() const
|
||
{ return *_psecdesccont ; }
|
||
|
||
PSECURITY_DESCRIPTOR_CONTROL QueryControl( void ) const
|
||
{ return _psecdesccont ; }
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_SECURITY_INFORMATION
|
||
|
||
SYNOPSIS: Simple wrapper class for SECURITY_INFORMATION structure
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT:
|
||
|
||
USES:
|
||
|
||
CAVEATS: The third constructor can be used to operate on a
|
||
SECURITY_INFORMATION thing in place, however the user
|
||
should ensure that the memory being operated on "in place"
|
||
should hang around till this object is destructed.
|
||
|
||
NOTES:
|
||
|
||
|
||
HISTORY:
|
||
Johnl 03-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SECURITY_INFORMATION
|
||
{
|
||
private:
|
||
/* Don't reference this member! Dereference _psecinformation!!
|
||
*/
|
||
SECURITY_INFORMATION _secinformation ;
|
||
|
||
/* This pointer will either be aliased to _secinformation or else
|
||
* to the PSECURITY_INFORMATION the user constructs this object with.
|
||
*
|
||
* All operations should be performed on *_psecinformation.
|
||
*/
|
||
PSECURITY_INFORMATION _psecinformation ;
|
||
|
||
public:
|
||
OS_SECURITY_INFORMATION( SECURITY_INFORMATION secinformation = 0 )
|
||
: _secinformation( secinformation ),
|
||
_psecinformation( &_secinformation )
|
||
{ ; }
|
||
|
||
/* This constructor uses the memory pointed at by psecinformation.
|
||
* Beware that what we are pointing at doesn't go out of scope or
|
||
* otherwise deleted before this object is destructed.
|
||
*/
|
||
OS_SECURITY_INFORMATION( PSECURITY_INFORMATION psecinformation )
|
||
: _secinformation( (SECURITY_INFORMATION)0 ),
|
||
_psecinformation( psecinformation )
|
||
{ ; }
|
||
|
||
/* Boolean query methods
|
||
*/
|
||
BOOL IsOwnerReferenced( void ) const
|
||
{ return !!(*_psecinformation & OWNER_SECURITY_INFORMATION) ; }
|
||
|
||
BOOL IsGroupReferenced( void ) const
|
||
{ return !!(*_psecinformation & GROUP_SECURITY_INFORMATION) ; }
|
||
|
||
BOOL IsDACLReferenced( void ) const
|
||
{ return !!(*_psecinformation & DACL_SECURITY_INFORMATION) ; }
|
||
|
||
BOOL IsSACLReferenced( void ) const
|
||
{ return !!(*_psecinformation & SACL_SECURITY_INFORMATION) ; }
|
||
|
||
/* These methods indicate that the object this SECURITY_INFORMATION
|
||
* object is associated with references the type specified in the
|
||
* method name.
|
||
*
|
||
* These use "if" instead of the ternary operator because CFront chokes
|
||
* on the expression.
|
||
*/
|
||
void SetOwnerReference( BOOL fOwner = TRUE )
|
||
{ if (fOwner) *_psecinformation |= OWNER_SECURITY_INFORMATION ;
|
||
else *_psecinformation &= ~OWNER_SECURITY_INFORMATION; }
|
||
|
||
void SetGroupReference( BOOL fGroup = TRUE )
|
||
{ if (fGroup) *_psecinformation |= GROUP_SECURITY_INFORMATION ;
|
||
else *_psecinformation &= ~GROUP_SECURITY_INFORMATION; }
|
||
|
||
|
||
void SetDACLReference( BOOL fDACL = TRUE )
|
||
{ if (fDACL) *_psecinformation |= DACL_SECURITY_INFORMATION ;
|
||
else *_psecinformation &= ~DACL_SECURITY_INFORMATION; }
|
||
|
||
void SetSACLReference( BOOL fSACL = TRUE )
|
||
{ if ( fSACL ) *_psecinformation |= SACL_SECURITY_INFORMATION ;
|
||
else *_psecinformation &= ~SACL_SECURITY_INFORMATION; }
|
||
|
||
/* Conversion operators
|
||
*/
|
||
operator PSECURITY_INFORMATION() const
|
||
{ return _psecinformation ; }
|
||
|
||
operator SECURITY_INFORMATION() const
|
||
{ return *_psecinformation ; }
|
||
|
||
PSECURITY_INFORMATION QuerySecurityInformation( void ) const
|
||
{ return _psecinformation ; }
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_ACE
|
||
|
||
SYNOPSIS: Wrapper class around an NT ACE
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: OS_OBJECT_WITH_DATA
|
||
|
||
USES: OS_SID
|
||
|
||
CAVEATS: Since there is no PACE generic type, you will need to
|
||
cast the PACCESS_ALLOWED_ACE etc. to (void *) and cast
|
||
it again when doing the QueryPtr back to the ACE type.
|
||
|
||
|
||
NOTES: A hierarchy of ACEs are not built up around the OS_ACE since
|
||
this is a simple wrapper class. Because of this, QueryType
|
||
may return unrecognized types in the future (currently there
|
||
are only four defined ACE types).
|
||
|
||
|
||
HISTORY:
|
||
Johnl 11-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_ACE : public OS_OBJECT_WITH_DATA
|
||
{
|
||
private:
|
||
/* Aliased to our data buffer or to an external ACE if the user passed in
|
||
* a non-null ACE pointer.
|
||
*/
|
||
PACE_HEADER _pACEHeader ;
|
||
|
||
/* An ACE contains a SID as part of the ACE, this guy will point
|
||
* to this ACE's SID.
|
||
*/
|
||
OS_SID * _possid ;
|
||
|
||
protected:
|
||
BOOL IsOwnerAlloc( void ) const
|
||
{ return ((void *)_pACEHeader) != QueryPtr() ; }
|
||
|
||
void * QuerySIDMemory( void ) const ;
|
||
|
||
public:
|
||
OS_ACE( void * pACE = NULL ) ;
|
||
~OS_ACE() ;
|
||
|
||
/* Query methods about the ACE Header
|
||
*/
|
||
UCHAR QueryType( void ) const
|
||
{ return _pACEHeader->AceType ; }
|
||
|
||
WORD QuerySize( void ) const
|
||
{ return _pACEHeader->AceSize ; }
|
||
|
||
UCHAR QueryAceFlags( void ) const
|
||
{ return _pACEHeader->AceFlags ; }
|
||
|
||
/* Returns the revision level the class OS_ACE operates at (*not* what
|
||
* level *this* ACE is at).
|
||
*/
|
||
static ULONG QueryRevision() ;
|
||
|
||
/* Query methods on the ACE type specific fields. An assertion error
|
||
* will occur if these methods are called on an ACE that doesn't have
|
||
* the data item queried for or the ACE type is unrecognized.
|
||
*
|
||
* Note that currently, all known ACEs have exactly these two data members.
|
||
*/
|
||
ACCESS_MASK QueryAccessMask( void ) const ;
|
||
APIERR QuerySID( OS_SID * * ppossid ) const ;
|
||
|
||
/* Returns a pointer to the ACE. Note it will need to be cast
|
||
* to the appropriate ACE type.
|
||
*/
|
||
void * QueryACE( void ) const
|
||
{ return (void *) _pACEHeader ; }
|
||
|
||
BOOL IsInherittedByNewObjects( void ) const
|
||
{ return !!( _pACEHeader->AceFlags & OBJECT_INHERIT_ACE) ; }
|
||
|
||
BOOL IsInherittedByNewContainers( void ) const
|
||
{ return !!( _pACEHeader->AceFlags & CONTAINER_INHERIT_ACE) ; }
|
||
|
||
/* The single '!' is correct
|
||
*/
|
||
BOOL IsInheritancePropagated( void ) const
|
||
{ return !( _pACEHeader->AceFlags & NO_PROPAGATE_INHERIT_ACE) ; }
|
||
|
||
BOOL IsInheritOnly( void ) const
|
||
{ return !!( _pACEHeader->AceFlags & INHERIT_ONLY_ACE) ; }
|
||
|
||
BOOL IsKnownACE( void ) const
|
||
{ return ( (QueryType() == ACCESS_ALLOWED_ACE_TYPE) ||
|
||
(QueryType() == ACCESS_DENIED_ACE_TYPE) ||
|
||
(QueryType() == SYSTEM_AUDIT_ACE_TYPE) ||
|
||
(QueryType() == SYSTEM_ALARM_ACE_TYPE) ) ;
|
||
}
|
||
|
||
/* SetXXX Methods
|
||
*/
|
||
void SetAccessMask( ACCESS_MASK accmask ) ;
|
||
|
||
APIERR SetSID( const OS_SID & ossid ) ;
|
||
|
||
void SetType( UCHAR ucType )
|
||
{ _pACEHeader->AceType = ucType ; }
|
||
|
||
void SetInheritFlags( UCHAR ucInheritFlags )
|
||
{ _pACEHeader->AceFlags = (( _pACEHeader->AceFlags & ~VALID_INHERIT_FLAGS)
|
||
| ucInheritFlags) ; }
|
||
|
||
void SetAceFlags( UCHAR ucFlags )
|
||
{ _pACEHeader->AceFlags = ucFlags ; }
|
||
|
||
/* Resizes the ACE, sets the ACE's size field and reallocates memory
|
||
* if necessary.
|
||
*/
|
||
APIERR SetSize( UINT cbSize ) ;
|
||
|
||
void SetInherittedByNewObjects( BOOL fInherittedByObjects = TRUE )
|
||
{ fInherittedByObjects ? (_pACEHeader->AceFlags |= OBJECT_INHERIT_ACE)
|
||
: (_pACEHeader->AceFlags &= ~OBJECT_INHERIT_ACE) ; }
|
||
|
||
void SetInherittedByNewContainers( BOOL fInherittedByContainers = TRUE )
|
||
{ fInherittedByContainers ? (_pACEHeader->AceFlags|=CONTAINER_INHERIT_ACE)
|
||
: (_pACEHeader->AceFlags &= ~CONTAINER_INHERIT_ACE) ; }
|
||
|
||
void SetInheritancePropagated( BOOL fInheritancePropagated = TRUE )
|
||
{ fInheritancePropagated ? (_pACEHeader->AceFlags|=NO_PROPAGATE_INHERIT_ACE)
|
||
: (_pACEHeader->AceFlags &= ~NO_PROPAGATE_INHERIT_ACE) ; }
|
||
|
||
void SetInheritOnly( BOOL fInheritOnly = TRUE )
|
||
{ fInheritOnly ? (_pACEHeader->AceFlags |= INHERIT_ONLY_ACE)
|
||
: (_pACEHeader->AceFlags &= ~INHERIT_ONLY_ACE) ; }
|
||
|
||
DECLARE_DBG_PRINT_SEC
|
||
|
||
/* Sets the ACE this OS_ACE is operating on. The ACE pace points to
|
||
* must be a valid ACE.
|
||
*/
|
||
APIERR SetPtr( void * pace ) ;
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_ACL
|
||
|
||
SYNOPSIS: Wrapper class for an NT ACL
|
||
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: OS_OBJECT_WITH_DATA
|
||
|
||
USES:
|
||
|
||
CAVEATS: The allocation size (in OS_OBJECT_WITH_DATA) should
|
||
correspond to the AclSize field in the ACL Header.
|
||
If one is changed, then the other should be changed.
|
||
|
||
|
||
NOTES:
|
||
|
||
|
||
HISTORY:
|
||
Johnl 05-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_ACL : public OS_OBJECT_WITH_DATA
|
||
{
|
||
private:
|
||
/* Aliased to our internal buffer or to an external ACL if the user
|
||
* passed in a non-null ACL pointer.
|
||
*/
|
||
PACL _pACL ;
|
||
|
||
OS_SECURITY_DESCRIPTOR * _pOwner ;
|
||
|
||
protected:
|
||
BOOL IsOwnerAlloc( void ) const
|
||
{ return ((void *)_pACL) != QueryPtr() ; }
|
||
|
||
/* Sets a new size in the ACE Header and reallocates memory if necessary
|
||
* and possible.
|
||
*/
|
||
APIERR SetSize( UINT cbNewACLSize, BOOL fForceToNonOwnerAlloced = FALSE) ;
|
||
|
||
public:
|
||
OS_ACL( PACL pACL = NULL,
|
||
BOOL fCopy = FALSE,
|
||
OS_SECURITY_DESCRIPTOR * pOwner = NULL ) ;
|
||
~OS_ACL() ;
|
||
|
||
BOOL IsValid( void ) const ;
|
||
|
||
APIERR QuerySizeInformation( ACL_SIZE_INFORMATION * paclsizeinfo ) const ;
|
||
APIERR QueryBytesInUse( PULONG pcbBytesInUse ) const ;
|
||
APIERR QueryACECount( PULONG pcAces ) const ;
|
||
|
||
/* The ACE is *copied* into this ACL. Note that you should avoid
|
||
* doing a QueryACE (which references the real ACL) then an AddACE, as
|
||
* you will have duplicate ACEs in this ACL. This does not *replace*
|
||
* the ace at iAce, it inserts it at that position.
|
||
*
|
||
* Specify MAXULONG for iAce to append the ACE in the ACL.
|
||
*/
|
||
APIERR AddACE( ULONG iAce, const OS_ACE & posace ) ;
|
||
|
||
/* The client will declare an OS_ACE and pass its address here. This
|
||
* is so we don't have to create one or keep an artificial array laying
|
||
* around. The ACE returned will operate on the real ACE in this ACL.
|
||
*/
|
||
APIERR QueryACE( ULONG iAce, OS_ACE * posace ) const ;
|
||
|
||
APIERR DeleteACE( ULONG iAce ) ;
|
||
|
||
/* Copies osaclSrc into *this. *this may change from owner ACL to non-
|
||
* owner alloced if necessary.
|
||
*/
|
||
APIERR Copy( const OS_ACL & osaclSrc, BOOL fForceToNonOwnerAlloced = TRUE);
|
||
|
||
/* Search for the next ACE starting at iStart that contains the SID
|
||
* equal to ossidKey. If found, pfFound will be set to TRUE, posace
|
||
* will point to the found ACE and piAce will contain the index of
|
||
* the ACE in the ACL. If an error occurs or pfFound is FALSE, then
|
||
* posace and piAce should be ignored.
|
||
*/
|
||
APIERR FindACE( const OS_SID & ossidKey,
|
||
BOOL * pfFound,
|
||
OS_ACE * posace,
|
||
PULONG piAce,
|
||
ULONG iStart = 0 ) const ;
|
||
|
||
DECLARE_DBG_PRINT_SEC
|
||
|
||
/* Conversion operators
|
||
*/
|
||
operator PACL() const
|
||
{ return _pACL ; }
|
||
|
||
operator ACL() const
|
||
{ return *_pACL ; }
|
||
|
||
PACL QueryAcl( void ) const
|
||
{ return _pACL ; }
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_SECURITY_DESCRIPTOR
|
||
|
||
SYNOPSIS: Simple Wrapper class for Windows SECURITY_DESCRIPTOR object
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: OS_OBJECT_WITH_DATA
|
||
|
||
USES: OS_ACL, OS_SECURITY_DESCRIPTOR_CONTROL
|
||
|
||
CAVEATS:
|
||
|
||
NOTES: This class is meant to be used in two ways:
|
||
|
||
1) As a method for accessing an existing
|
||
security descriptor. This is indicated by passing a
|
||
non-Null PSECURITY_DESCRIPTOR to the constructor. If
|
||
you do this, then you can only use the Query methods
|
||
and a couple of the set methods (you CANNOT use the
|
||
SetDACL, SetSACL, SetOwner and SetGroup methods).
|
||
|
||
2) As a way to build a security descriptor from scratch.
|
||
When you want to build one from scratch, pass in a
|
||
NULL security descriptor and one will be created for
|
||
you. It will be initialized to contain nothing.
|
||
|
||
The reason for the above restrictions is because a security
|
||
descriptor only contains references to its ACLs, Owner and
|
||
Group, thus this causes a memory ownership problem. When
|
||
we own the memory, then you can do anything you want. When
|
||
somebody else owns the memory, then we can only query its
|
||
contents.
|
||
|
||
HISTORY:
|
||
Johnl 04-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SECURITY_DESCRIPTOR : public OS_OBJECT_WITH_DATA
|
||
{
|
||
/* Give access to method UpdateReferencedSecurityObject
|
||
*/
|
||
friend class OS_ACL ;
|
||
friend class OS_SID ;
|
||
|
||
private:
|
||
|
||
/* Aliased to _buffSecDescData or an external PSECURITY_DESCRIPTOR.
|
||
*/
|
||
PSECURITY_DESCRIPTOR _psecuritydesc ;
|
||
|
||
/* This member should be updated everytime a set method occurs. This is
|
||
* due to not being able to directly access the
|
||
* SECURITY_DESCRIPTOR_CONTROL, we can only copy it (and we can't
|
||
* set it).
|
||
*/
|
||
SECURITY_DESCRIPTOR_CONTROL _secdesccont ;
|
||
|
||
/* This member will be aliased to _secdescont, thus the query methods
|
||
* will always be up to date.
|
||
*/
|
||
OS_SECURITY_DESCRIPTOR_CONTROL _osSecDescControl ;
|
||
|
||
/* These will be "newed" as necessary (i.e., if the corresponding
|
||
* member is contained in this SECURITY_DESCRIPTOR).
|
||
*/
|
||
OS_ACL * _posaclDACL ;
|
||
OS_ACL * _posaclSACL ;
|
||
OS_SID * _possidOwner ;
|
||
OS_SID * _possidGroup ;
|
||
|
||
protected:
|
||
BOOL IsOwnerAlloc( void ) const
|
||
{ return ((void *)_psecuritydesc) != QueryPtr() ; }
|
||
|
||
/* Forces an update of the _secdesccont from the active security
|
||
* descriptor. Note that this should be called after any changes
|
||
* to the security descriptor.
|
||
*/
|
||
APIERR UpdateControl( void ) ;
|
||
|
||
/* This method is called by the private members _posaclDACL, _posaclSACL,
|
||
* _possidOwner or _possidGroup when the member's "base" memory (i.e.,
|
||
* where the actual data is stored) gets changed due to resizing etc.
|
||
* This is necessary to keep the security descriptor pointers valid.
|
||
*
|
||
* An example of why this is needed: We hand out the pointers to the
|
||
* OS_DACL for instance, someone directly manipulates the OS_DACL (adds
|
||
* an ACE which causes a reallocation which causes the ACL to move in
|
||
* memory). The security descriptor in *this is now out of date, thus
|
||
* the OS_DACL (and other security classes) has to call this method
|
||
* to resync the two objects.
|
||
*/
|
||
APIERR UpdateReferencedSecurityObject( OS_OBJECT_WITH_DATA * posobj ) ;
|
||
|
||
public:
|
||
OS_SECURITY_DESCRIPTOR( PSECURITY_DESCRIPTOR psecuritydesc = NULL,
|
||
BOOL fCopy = FALSE ) ;
|
||
~OS_SECURITY_DESCRIPTOR() ;
|
||
|
||
/* Queries the security descriptor control of this security descriptor.
|
||
* The only way to change the security
|
||
* control method is with the SetXXX methods below.
|
||
*/
|
||
const OS_SECURITY_DESCRIPTOR_CONTROL * QueryControl( void ) const
|
||
{ return &_osSecDescControl ; }
|
||
|
||
/* The following query methods determine if the specified component
|
||
* is present and if it is, retrieves it. The first PBOOL parameter
|
||
* will be set to TRUE if the component is present. If it is set to
|
||
* FALSE, then the rest of the parameters should be ignored.
|
||
*
|
||
* For the QueryDACL/SACL methods, *ppOSACL may be set to NULL, which
|
||
* means the ACL is empty.
|
||
*/
|
||
APIERR QueryDACL( PBOOL pfDACLPresent,
|
||
OS_ACL * * ppOSACL,
|
||
PBOOL pfDACLDefaulted = NULL
|
||
) const ;
|
||
|
||
APIERR QuerySACL( PBOOL pfSACLPresent,
|
||
OS_ACL * * pOSACL,
|
||
PBOOL pfSACLDefaulted = NULL
|
||
) const ;
|
||
|
||
APIERR QueryGroup( PBOOL pfContainsGroup,
|
||
OS_SID * * ppOSSID,
|
||
PBOOL pfGroupDefaulted = NULL
|
||
) const ;
|
||
|
||
APIERR QueryOwner( PBOOL pfContainsOwner,
|
||
OS_SID * * ppOSSID,
|
||
PBOOL pfGroupDefaulted = NULL
|
||
) const ;
|
||
|
||
/* Returns the number of bytes this security descriptor uses. Asserts
|
||
* out if the security descriptor is invalid.
|
||
*/
|
||
ULONG QuerySize( void ) const ;
|
||
|
||
/* Returns TRUE if the current security descriptor is valid
|
||
*/
|
||
BOOL IsValid( void ) const ;
|
||
|
||
BOOL IsOwnerPresent( void ) const
|
||
{ return _possidOwner != NULL ; }
|
||
|
||
BOOL IsGroupPresent( void ) const
|
||
{ return _possidGroup != NULL ; }
|
||
|
||
BOOL IsDACLPresent( void ) const
|
||
{ return QueryControl()->IsDACLPresent() ; }
|
||
|
||
BOOL IsSACLPresent( void ) const
|
||
{ return QueryControl()->IsSACLPresent() ; }
|
||
|
||
/* Sets the DACL, SACL, Owner and primary group on this security
|
||
* descriptor. The primary item is copied, thus for items like
|
||
* ACLs, it is recommended you avoid SetXXXs unless necessary because
|
||
* of the hit for the memory copy. The SECURITY_INFORMATION and
|
||
* SECURITY_DESCRIPTOR_CONTROL flags will be set accordingly after
|
||
* each set.
|
||
*
|
||
* fD/SACLPresent - If set to TRUE indicates the ACL is present,
|
||
* if set to FALSE, the D/SACL present flag is set to
|
||
* FALSE and the rest of the parameters are ignored.
|
||
* pOSACL - Pointer to D/SACL to set for this security descriptor.
|
||
* fD/SACLDefaulted - If set to TRUE, indicates the ACL was chosen from
|
||
* some default resource, should normally be FALSE.
|
||
*
|
||
*/
|
||
APIERR SetDACL( BOOL fDACLPresent,
|
||
const OS_ACL * posacl,
|
||
BOOL fDACLDefaulted = FALSE
|
||
) ;
|
||
|
||
APIERR SetSACL( BOOL fSACLPresent,
|
||
const OS_ACL * posacl,
|
||
BOOL fSACLDefaulted = FALSE
|
||
) ;
|
||
|
||
/* Note that setting the owner or group to be not present will make this
|
||
* an "incomplete" security descriptor that AccessCheck will puke all over.
|
||
*/
|
||
APIERR SetOwner( BOOL fOwnerPresent,
|
||
const OS_SID * possid,
|
||
BOOL fOwnerDefaulted = FALSE
|
||
) ;
|
||
|
||
APIERR SetGroup( BOOL fGroupPresent,
|
||
const OS_SID * possid,
|
||
BOOL fGroupDefaulted = FALSE
|
||
) ;
|
||
|
||
APIERR AccessCheck( ACCESS_MASK DesiredAccess,
|
||
PGENERIC_MAPPING pGenericMapping,
|
||
BOOL * pfAccessGranted,
|
||
PACCESS_MASK pGrantedAccess = NULL ) ;
|
||
|
||
/* Copies the passed security descriptor to *this.
|
||
* This is equivalent to calling QueryXXX then SetXXX for each
|
||
* of the components
|
||
*/
|
||
APIERR Copy( const OS_SECURITY_DESCRIPTOR & ossecdescSrc ) ;
|
||
|
||
//
|
||
// Compares this and psecdesc for equality. Note that the security
|
||
// descriptors must conform to the security editor's "canonical" form,
|
||
// thus this isn't a general purpose compare method.
|
||
//
|
||
APIERR Compare( OS_SECURITY_DESCRIPTOR * possecdesc,
|
||
BOOL * pfOwnerEqual,
|
||
BOOL * pfGroupEqual,
|
||
BOOL * pfDACLEqual,
|
||
BOOL * pfSACLEqual,
|
||
PGENERIC_MAPPING pGenericMapping,
|
||
PGENERIC_MAPPING pGenericMappingNewObjects,
|
||
BOOL fMapGenAllOnly,
|
||
BOOL fIsContainer ) ;
|
||
|
||
DECLARE_DBG_PRINT_SEC
|
||
|
||
operator PSECURITY_DESCRIPTOR( void ) const
|
||
{ return _psecuritydesc ; }
|
||
|
||
PSECURITY_DESCRIPTOR QueryDescriptor( void ) const
|
||
{ return _psecuritydesc ; }
|
||
|
||
//
|
||
// The following SetGroup and SetOwner are obsolete and have been
|
||
// supplanted by the above SetOwner.
|
||
//
|
||
APIERR SetGroup( const OS_SID & ossid,
|
||
BOOL fGroupDefaulted = FALSE
|
||
) ;
|
||
|
||
APIERR SetOwner( const OS_SID & ossid,
|
||
BOOL fOwnerDefaulted = FALSE
|
||
) ;
|
||
|
||
|
||
} ; // OS_SECURITY_DESCRIPTOR
|
||
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_ACL_SUBJECT_ITER
|
||
|
||
SYNOPSIS: Iterates through each subject contained in an OS_ACL
|
||
Accumulating the Access masks as appropriate for
|
||
each inheritance option.
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: BASE
|
||
|
||
USES: OS_ACL, OS_ACE
|
||
|
||
CAVEATS: Not all DACLs can be recognized using this iterator.
|
||
Specifically, denies interspersed with grants or partial
|
||
denies cannot be represented with this class (and in fact,
|
||
can only be accurately represented when contained in the
|
||
ACL since order is important).
|
||
|
||
NOTES: IERR_UNRECOGNIZED_ACL will be returned if this ACL doesn't
|
||
support iterating subject by subject
|
||
|
||
HISTORY:
|
||
Johnl 22-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_ACL_SUBJECT_ITER : public BASE
|
||
{
|
||
private:
|
||
const OS_ACL * _posacl ;
|
||
PGENERIC_MAPPING _pGenericMapping ;
|
||
PGENERIC_MAPPING _pGenericMappingNewObjects ;
|
||
BOOL _fMapGenAllOnly ;
|
||
|
||
/* If the associated object isn't a container, then we can ignore most
|
||
* of the inherit bits
|
||
*/
|
||
BOOL _fIsContainer ;
|
||
|
||
OS_SID _ossidCurrentSubject ;
|
||
|
||
/* Index of the first ACE that contains the current subject's SID.
|
||
*/
|
||
ULONG _iCurrentAce ;
|
||
ULONG _cTotalAces ;
|
||
|
||
protected:
|
||
ULONG QueryTotalAceCount( void ) const
|
||
{ return _cTotalAces ; }
|
||
|
||
ULONG QueryCurrentACE( void ) const
|
||
{ return _iCurrentAce ; }
|
||
|
||
const OS_ACL * QueryACL( void ) const
|
||
{ return _posacl ; }
|
||
|
||
void SetCurrentACE( ULONG iNewAce )
|
||
{ _iCurrentAce = iNewAce ; }
|
||
|
||
//
|
||
// Used for special casing the Creator Owner SID
|
||
//
|
||
OS_SID _ossidCreator ;
|
||
OS_SID _ossidCreatorGroup ;
|
||
|
||
public:
|
||
OS_ACL_SUBJECT_ITER( const OS_ACL * posacl,
|
||
PGENERIC_MAPPING pGenericMapping,
|
||
PGENERIC_MAPPING pGenericMappingNewObjects,
|
||
BOOL fMapGenAllOnly,
|
||
BOOL fIsContainer ) ;
|
||
~OS_ACL_SUBJECT_ITER() ;
|
||
|
||
virtual BOOL Next( APIERR * perr ) = 0 ;
|
||
virtual BOOL CompareCurrentSubject( OS_ACL_SUBJECT_ITER * psubjiter ) = 0 ;
|
||
|
||
/* Finds the next new subject in the ACL starting from our
|
||
* current position.
|
||
*
|
||
* pfFoundNewSubject - Set to TRUE if a new subject was found, FALSE
|
||
* otherwise.
|
||
* possidNewSubj - Pointer to OS_SID that will receive the new subject
|
||
* posaceFirstAceWithSubj - pointer to ACE that will receive the first
|
||
* ACE in this ACL that contains the new subject. The current
|
||
* ACE index will be set to this ACE position also.
|
||
*/
|
||
APIERR FindNextSubject( BOOL * pfFoundNewSubject,
|
||
OS_SID * possidNewSubj,
|
||
OS_ACE * posaceFirstAceWithSubj ) ;
|
||
|
||
/* Using the generic mapping passed into the constructor, this method
|
||
* will convert all specific access permissions to the corresponding
|
||
* generic permission(s). If a match is found, then the matching
|
||
* bits are zeroed. If any specific permissions are still on after
|
||
* the mapping, then IERR_UNRECOGNIZED_ACL will be returned.
|
||
*
|
||
* If fMapGenAllOnly is TRUE, then only Generic All is mapped, the other
|
||
* generic bits are not mapped.
|
||
*
|
||
* if fIsInherittedByNewObjects is TRUE, then the new object generic
|
||
* mapping is used instead of the regular generic mapping.
|
||
*/
|
||
APIERR MapSpecificToGeneric( ACCESS_MASK * pAccessMask,
|
||
BOOL fIsInherittedByNewObjects ) ;
|
||
|
||
//
|
||
// Compares the passed subjiter with *this
|
||
//
|
||
APIERR Compare( BOOL * pfACLEqual,
|
||
OS_ACL_SUBJECT_ITER * psubjiter ) ;
|
||
|
||
|
||
void Reset( void )
|
||
{ _iCurrentAce = 0 ; }
|
||
|
||
BOOL MapGenericAllOnly( void ) const
|
||
{ return _fMapGenAllOnly ; }
|
||
|
||
BOOL IsContainer( void ) const
|
||
{ return _fIsContainer ; }
|
||
|
||
|
||
const OS_SID * QuerySID( void ) const
|
||
{ return &_ossidCurrentSubject ; }
|
||
|
||
} ;
|
||
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_DACL_SUBJECT_ITER
|
||
|
||
SYNOPSIS: Iterates through each subject contained in an OS_ACL for
|
||
a DACL, automatically gathering the access masks for each
|
||
subject across multiple ACEs.
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: BASE
|
||
|
||
USES: OS_ACL, OS_ACE
|
||
|
||
CAVEATS: We can gather access masks across multiple ACEs only if
|
||
the ACL conforms to the all Deny Alls followed by all Grants
|
||
form. Note that this iterator will effectively compact
|
||
ACEs as necessary (and throw away ACEs that don't matter,
|
||
like grant ACEs that follow a Deny All Ace).
|
||
|
||
NOTES: IERR_UNRECOGNIZED_ACL will be returned if this ACL doesn't
|
||
support iterating subject by subject
|
||
|
||
The access mask is guaranteed to be zero if the Has*Ace
|
||
flag is FALSE.
|
||
|
||
HISTORY:
|
||
Johnl 22-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_DACL_SUBJECT_ITER : public OS_ACL_SUBJECT_ITER
|
||
{
|
||
private:
|
||
BOOL _fDenyAll ;
|
||
BOOL _fDenyAllNewObj ;
|
||
BOOL _fDenyAllNewCont ;
|
||
BOOL _fDenyAllInheritOnly ;
|
||
|
||
/* Contains the permissions for this SID. The permissions are
|
||
* specific to the ACL we are examining and the types of ACEs it
|
||
* contains.
|
||
*/
|
||
ACCESS_MASK _accessmask ;
|
||
BOOL _fHasAce ;
|
||
|
||
ACCESS_MASK _accessmaskNewObj ;
|
||
BOOL _fHasAceNewObj ;
|
||
|
||
ACCESS_MASK _accessmaskNewCont ;
|
||
BOOL _fHasAceNewCont ;
|
||
|
||
ACCESS_MASK _accessmaskInheritOnly ;
|
||
BOOL _fHasAceInheritOnly ;
|
||
|
||
public:
|
||
OS_DACL_SUBJECT_ITER( OS_ACL * posacl,
|
||
PGENERIC_MAPPING pGenericMapping,
|
||
PGENERIC_MAPPING pGenericMappingNewObjects,
|
||
BOOL fMapGenAllOnly,
|
||
BOOL fIsContainer ) ;
|
||
~OS_DACL_SUBJECT_ITER() ;
|
||
|
||
virtual BOOL Next( APIERR * perr ) ;
|
||
virtual BOOL CompareCurrentSubject( OS_ACL_SUBJECT_ITER * psubjiter ) ;
|
||
|
||
BOOL IsDenyAll( void ) const
|
||
{ return _fDenyAll ; }
|
||
|
||
BOOL IsNewObjectDenyAll( void ) const
|
||
{ return _fDenyAllNewObj ; }
|
||
|
||
BOOL IsNewContainerDenyAll( void ) const
|
||
{ return _fDenyAllNewCont ; }
|
||
|
||
BOOL IsInheritOnlyDenyAll( void ) const
|
||
{ return _fDenyAllInheritOnly ; }
|
||
|
||
/* Returns TRUE if the data in QueryAccessMask and IsDenyAll came from
|
||
* an ACE (thus is not the default value).
|
||
*/
|
||
BOOL HasThisAce( void ) const
|
||
{ return _fHasAce ; }
|
||
|
||
ACCESS_MASK QueryAccessMask( void ) const
|
||
{ return _accessmask ; }
|
||
|
||
BOOL HasNewObjectAce( void ) const
|
||
{ return _fHasAceNewObj ; }
|
||
|
||
ACCESS_MASK QueryNewObjectAccessMask( void ) const
|
||
{ return _accessmaskNewObj ; }
|
||
|
||
BOOL HasNewContainerAce( void ) const
|
||
{ return _fHasAceNewCont ; }
|
||
|
||
ACCESS_MASK QueryNewContainerAccessMask( void ) const
|
||
{ return _accessmaskNewCont ; }
|
||
|
||
BOOL HasInheritOnlyAce( void ) const
|
||
{ return _fHasAceInheritOnly ; }
|
||
|
||
ACCESS_MASK QueryInheritOnlyAccessMask( void ) const
|
||
{ return _accessmaskInheritOnly ; }
|
||
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: SACL_AUDIT_ALARM_DESCRIPTOR
|
||
|
||
SYNOPSIS: Minor storage class for OS_SACL_SUBJECT_ITER
|
||
|
||
NOTES:
|
||
|
||
HISTORY:
|
||
Johnl 31-Dec-1991 Created
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SACL_SUBJECT_DESCRIPTOR
|
||
{
|
||
public:
|
||
ACCESS_MASK _accessmask ;
|
||
BOOL _fHasAce ;
|
||
|
||
void InitToZero( void )
|
||
{
|
||
_accessmask = 0 ;
|
||
_fHasAce = FALSE ;
|
||
}
|
||
} ;
|
||
|
||
/* The following indexes into the array for the appropriate descriptor
|
||
* The _S/_F suffix indicates whether this is a success or failure
|
||
* descriptor.
|
||
*
|
||
* Do not intermix the alarm and audit values.
|
||
*/
|
||
enum OS_SACL_DESCRIPTOR_TYPE
|
||
{
|
||
OS_SACL_DESC_THIS_OBJECT_S_AUDIT = 0,
|
||
OS_SACL_DESC_THIS_OBJECT_F_AUDIT,
|
||
OS_SACL_DESC_NEW_OBJECT_S_AUDIT,
|
||
OS_SACL_DESC_NEW_OBJECT_F_AUDIT,
|
||
OS_SACL_DESC_NEW_CONT_S_AUDIT,
|
||
OS_SACL_DESC_NEW_CONT_F_AUDIT,
|
||
OS_SACL_DESC_INHERIT_ONLY_S_AUDIT,
|
||
OS_SACL_DESC_INHERIT_ONLY_F_AUDIT,
|
||
|
||
/* This must be the first ALARM item in this enumeration
|
||
*/
|
||
OS_SACL_DESC_THIS_OBJECT_S_ALARM,
|
||
OS_SACL_DESC_THIS_OBJECT_F_ALARM,
|
||
OS_SACL_DESC_NEW_OBJECT_S_ALARM,
|
||
OS_SACL_DESC_NEW_OBJECT_F_ALARM,
|
||
OS_SACL_DESC_NEW_CONT_S_ALARM,
|
||
OS_SACL_DESC_NEW_CONT_F_ALARM,
|
||
OS_SACL_DESC_INHERIT_ONLY_S_ALARM,
|
||
OS_SACL_DESC_INHERIT_ONLY_F_ALARM,
|
||
|
||
/* The size of the array that will be needed.
|
||
*/
|
||
OS_SACL_DESC_LAST
|
||
} ;
|
||
|
||
/*************************************************************************
|
||
|
||
NAME: OS_SACL_SUBJECT_ITER
|
||
|
||
SYNOPSIS: Iterates through each subject contained in an OS_ACL,
|
||
automatically gathering the access masks for each
|
||
subject across multiple ACEs.
|
||
|
||
INTERFACE:
|
||
|
||
PARENT: BASE
|
||
|
||
USES: OS_ACL, OS_ACE
|
||
|
||
CAVEATS:
|
||
|
||
NOTES: IERR_UNRECOGNIZED_ACL will be returned if this ACL doesn't
|
||
support iterating subject by subject
|
||
|
||
The access mask is guaranteed to be zero if the Has*Ace
|
||
flag is FALSE.
|
||
|
||
HISTORY:
|
||
Johnl 22-Dec-1991 Created
|
||
|
||
**************************************************************************/
|
||
|
||
DLL_CLASS OS_SACL_SUBJECT_ITER : public OS_ACL_SUBJECT_ITER
|
||
{
|
||
private:
|
||
OS_SACL_SUBJECT_DESCRIPTOR _asaclDesc[OS_SACL_DESC_LAST] ;
|
||
|
||
void InitToZero( void ) ;
|
||
|
||
public:
|
||
OS_SACL_SUBJECT_ITER( OS_ACL * posacl,
|
||
PGENERIC_MAPPING pGenericMapping,
|
||
PGENERIC_MAPPING pGenericMappingNewObjects,
|
||
BOOL fMapGenAllOnly,
|
||
BOOL fIsContainer ) ;
|
||
~OS_SACL_SUBJECT_ITER() ;
|
||
|
||
virtual BOOL Next( APIERR * perr ) ;
|
||
virtual BOOL CompareCurrentSubject( OS_ACL_SUBJECT_ITER * psubjiter ) ;
|
||
|
||
BOOL HasAuditAces( void ) const
|
||
{ return HasThisAuditAce_S() || HasThisAuditAce_F() ||
|
||
HasNewObjectAuditAce_S() || HasNewObjectAuditAce_F() ||
|
||
HasNewContainerAuditAce_S() || HasNewContainerAuditAce_F() ||
|
||
HasInheritOnlyAuditAce_S() || HasInheritOnlyAuditAce_F() ;
|
||
}
|
||
|
||
|
||
/* A name with an _S appended is a Successful Access flag, an _F
|
||
* appended is a Failed access flag.
|
||
*/
|
||
BOOL HasThisAuditAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_S_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryAuditAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_S_AUDIT]._accessmask ; }
|
||
|
||
BOOL HasThisAuditAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_F_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryAuditAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_F_AUDIT]._accessmask ; }
|
||
|
||
/* New Object
|
||
*/
|
||
BOOL HasNewObjectAuditAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_S_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewObjectAuditAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_S_AUDIT]._accessmask ; }
|
||
|
||
BOOL HasNewObjectAuditAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_F_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewObjectAuditAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_F_AUDIT]._accessmask ; }
|
||
|
||
/* New Container
|
||
*/
|
||
BOOL HasNewContainerAuditAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_S_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewContainerAuditAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_S_AUDIT]._accessmask ; }
|
||
|
||
BOOL HasNewContainerAuditAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_F_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewContainerAuditAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_F_AUDIT]._accessmask ; }
|
||
|
||
/* Inherit only
|
||
*/
|
||
BOOL HasInheritOnlyAuditAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_S_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryInheritOnlyAuditAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_S_AUDIT]._accessmask ; }
|
||
|
||
BOOL HasInheritOnlyAuditAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_F_AUDIT]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryInheritOnlyAuditAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_F_AUDIT]._accessmask ; }
|
||
|
||
|
||
BOOL HasThisAlarmAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_S_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryAlarmAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_S_ALARM]._accessmask ; }
|
||
|
||
BOOL HasThisAlarmAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_F_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryAlarmAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_THIS_OBJECT_F_ALARM]._accessmask ; }
|
||
|
||
/* New Object
|
||
*/
|
||
BOOL HasNewObjectAlarmAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_S_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewObjectAlarmAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_S_ALARM]._accessmask ; }
|
||
|
||
BOOL HasNewObjectAlarmAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_F_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewObjectAlarmAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_OBJECT_F_ALARM]._accessmask ; }
|
||
|
||
/* New Container
|
||
*/
|
||
BOOL HasNewContainerAlarmAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_S_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewContainerAlarmAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_S_ALARM]._accessmask ; }
|
||
|
||
BOOL HasNewContainerAlarmAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_F_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryNewContainerAlarmAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_NEW_CONT_F_ALARM]._accessmask ; }
|
||
|
||
/* Inherit only
|
||
*/
|
||
BOOL HasInheritOnlyAlarmAce_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_S_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryInheritOnlyAlarmAccessMask_S( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_S_ALARM]._accessmask ; }
|
||
|
||
BOOL HasInheritOnlyAlarmAce_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_F_ALARM]._fHasAce ; }
|
||
|
||
ACCESS_MASK QueryInheritOnlyAlarmAccessMask_F( void ) const
|
||
{ return _asaclDesc[OS_SACL_DESC_INHERIT_ONLY_F_ALARM]._accessmask ; }
|
||
|
||
|
||
} ;
|
||
|
||
#endif //_SECURITY_HXX_
|
||
|