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.
435 lines
15 KiB
435 lines
15 KiB
//+-------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1996.
|
|
//
|
|
// File: acclist.hxx
|
|
//
|
|
// Contents: Class to manage a list of access control structures for a
|
|
// given object
|
|
//
|
|
// History: 28-Jul-96 MacM Created
|
|
//
|
|
//--------------------------------------------------------------------
|
|
#ifndef __ACCLIST_HXX__
|
|
#define __ACCLIST_HXX__
|
|
|
|
//
|
|
// Use until uplevel ACLs appear
|
|
//
|
|
#define _NO_UPLEVEL
|
|
|
|
typedef struct _ACCLIST_NODE
|
|
{
|
|
PWSTR pwszProperty;
|
|
PWSTR pwszPropInBuff;
|
|
SECURITY_INFORMATION SeInfo;
|
|
PACTRL_ACCESS_ENTRY_LIST pAccessList;
|
|
PACTRL_ACCESS_ENTRY_LIST pAuditList;
|
|
ULONG fState;
|
|
} ACCLIST_NODE, *PACCLIST_NODE;
|
|
|
|
|
|
typedef struct _ACCLIST_CNODE
|
|
{
|
|
PACTRL_ACCESS_ENTRY pList;
|
|
PACCLIST_NODE pONode;
|
|
ULONG cExp;
|
|
ULONG cL1Inherit;
|
|
ULONG cL2Inherit;
|
|
BOOL Empty;
|
|
|
|
} ACCLIST_CNODE, *PACCLIST_CNODE;
|
|
|
|
|
|
typedef struct _TRUSTEE_NODE
|
|
{
|
|
TRUSTEE Trustee;
|
|
PWSTR pwszTrusteeName;
|
|
PWSTR pwszTrusteeInBuff;
|
|
PSID pSid;
|
|
ULONG fFlags;
|
|
SID_NAME_USE SidType;
|
|
PWSTR pwszDomainName;
|
|
ULONG cUseCount;
|
|
struct _TRUSTEE_NODE *pImpersonate;
|
|
|
|
} TRUSTEE_NODE, *PTRUSTEE_NODE;
|
|
|
|
typedef struct _IPROP_IN_BUFF
|
|
{
|
|
PWSTR pwszIProp;
|
|
PWSTR pwszIPropInBuff;
|
|
} IPROP_IN_BUFF, *PIPROP_IN_BUFF;
|
|
|
|
|
|
//
|
|
// Node for turning an acl into an access list
|
|
//
|
|
typedef struct _ACCLIST_ATOACCESS
|
|
{
|
|
GUID *pGuid;
|
|
CSList AceList;
|
|
} ACCLIST_ATOACCESS, *PACCLIST_ATOACCESS;
|
|
|
|
|
|
typedef struct _ACCLIST_ATOANODE
|
|
{
|
|
PACE_HEADER pAce;
|
|
ULONG fInherit;
|
|
} ACCLIST_ATOANODE, *PACCLIST_ATOANODE;
|
|
|
|
//
|
|
// Used when building an acl to get them in the proper order
|
|
//
|
|
typedef struct _ACC_ACLBLD_NODE
|
|
{
|
|
PACCLIST_NODE pNode;
|
|
ULONG iLastIndex;
|
|
} ACC_ACLBLD_NODE, *PACC_ACLBLD_NODE;
|
|
|
|
typedef enum _ACC_ACLBLD_TYPE
|
|
{
|
|
AAT_DENIED = 0,
|
|
AAT_OBJ_DENIED,
|
|
AAT_ALLOWED,
|
|
AAT_OBJ_ALLOWED,
|
|
AAT_PSET_ALLOWED,
|
|
AAT_PROP_ALLOWED,
|
|
AAT_IDENIED,
|
|
AAT_IOBJ_DENIED,
|
|
AAT_IALLOWED,
|
|
AAT_IOBJ_ALLOWED,
|
|
AAT_IPSET_ALLOWED,
|
|
AAT_IPROP_ALLOWED,
|
|
AAT_AUDIT,
|
|
AAT_INVALID,
|
|
} ACC_ACLBLD_TYPE, *PACC_ACLBLD_TYPE;
|
|
|
|
//
|
|
// State flags for the ACCLIST_NODE structure
|
|
//
|
|
#define ACCLIST_DACL_PROTECTED 0x00000001
|
|
#define ACCLIST_SACL_PROTECTED 0x00000002
|
|
|
|
//
|
|
// Flags for the above structure
|
|
//
|
|
#define TRUSTEE_DELETE_SID 0x00000001
|
|
#define TRUSTEE_DELETE_NAME 0x00000002
|
|
#define TRUSTEE_DELETE_DOMAIN 0x00000004
|
|
|
|
#define TRUSTEE_OPT_NOTHING 0x00000000
|
|
#define TRUSTEE_OPT_SID 0x00000001
|
|
#define TRUSTEE_OPT_NAME 0x00000002
|
|
#define TRUSTEE_OPT_INSERT_ONLY 0x00000004
|
|
|
|
#define ACCLIST_SD_ABSOK 0x00000001
|
|
#define ACCLIST_SD_NOFREE 0x00000002
|
|
#define ACCLIST_SD_DS_STYLE 0x00000004 // The first 4 bytes of the
|
|
// returned security descriptor
|
|
// is the SECURITY_INFORMATION
|
|
|
|
#define ACCLIST_COMPRESS 0x008000000 // This node is to be
|
|
// compressed out of existance
|
|
|
|
#define ACCLIST_DENIED 0x80000000 // Access denied entry -or-
|
|
#define ACCLIST_AUDIT ACCLIST_DENIED // an audit entry
|
|
#define ACCLIST_OBJ_DENIED 0x40000000 // Access denied object entry
|
|
#define ACCLIST_ALLOWED 0x20000000 // Access allowed entry
|
|
#define ACCLIST_OBJ_ALLOWED 0x10000000 // Access allowed object entry
|
|
#define ACCLIST_PSET_ALLOWED 0x08000000 // Access allowed property
|
|
// set entry
|
|
#define ACCLIST_PROP_ALLOWED 0x04000000 // Access allowed property
|
|
// entry
|
|
#define ACCLIST_UNKOWN_ENTRY 0x02000000 // Some weird kind of entry
|
|
// was given
|
|
#define ACCLIST_VALID_TYPE_FLAGS 0xFE000000 // Mask of the above flags
|
|
#define ACCLIST_VALID_IN_LEVEL_FLAGS \
|
|
(INHERITED_PARENT | INHERITED_GRANDPARENT) // Mask of the inheritance
|
|
// level flags
|
|
|
|
//
|
|
// Function prototypes - Forward definitions for inline functions
|
|
//
|
|
BOOL CompProps(IN PVOID pvNode1,
|
|
IN PVOID pvNode2);
|
|
|
|
void DelTrusteeNode(PVOID pvNode);
|
|
|
|
BOOL CompTrusteeToTrusteeNode(IN PVOID pvTrustee,
|
|
IN PVOID pvNode2);
|
|
|
|
BOOL CompTrustees(IN PVOID pvTrustee,
|
|
IN PVOID pvTrustee2);
|
|
|
|
//
|
|
// These functions are used to determine when to process a access_entry
|
|
// when building a acl
|
|
//
|
|
ACC_ACLBLD_TYPE GetATypeForEntry(IN PWSTR pwszProperty,
|
|
IN PACTRL_ACCESS_ENTRY pAE,
|
|
IN SECURITY_INFORMATION SeInfo);
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Class: CAccessList
|
|
//
|
|
// Synopsis: This class wraps the implementation of a CAccessList
|
|
// (ACTRL_ALIST).
|
|
//
|
|
// Methods: Init
|
|
//
|
|
//--------------------------------------------------------------------
|
|
class CAccessList
|
|
{
|
|
|
|
public:
|
|
|
|
CAccessList();
|
|
|
|
~CAccessList();
|
|
|
|
inline DWORD SetObjectType(IN SE_OBJECT_TYPE ObjType);
|
|
|
|
inline VOID SetDsPathInfo(IN PLDAP pLDAP = NULL,
|
|
IN PWSTR pwszDsPath = NULL);
|
|
|
|
inline DWORD SetLookupServer(IN PWSTR pwszLookupServer);
|
|
|
|
inline VOID SetKernelObjectType(IN MARTA_KERNEL_TYPE KernelType );
|
|
|
|
DWORD AddSD(IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN PWSTR pwszProperty,
|
|
IN BOOL fAddAll = TRUE);
|
|
|
|
|
|
DWORD AddAcl(IN PACL pDAcl,
|
|
IN PACL pSAcl,
|
|
IN PSID pOwner,
|
|
IN PSID pGroup,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN PWSTR pwszProperty,
|
|
IN BOOL fAddAll = TRUE,
|
|
IN ULONG fControl = 0);
|
|
|
|
DWORD RemoveTrusteeFromAccess(IN SECURITY_INFORMATION SeInfo,
|
|
IN PTRUSTEE pTrustee,
|
|
IN PWSTR pwszProperty OPTIONAL);
|
|
|
|
DWORD RevokeTrusteeAccess(IN SECURITY_INFORMATION SeInfo,
|
|
IN PACTRL_ACCESSW pSrcList,
|
|
IN PWSTR pwszProperty OPTIONAL);
|
|
|
|
DWORD MarshalAccessLists(IN SECURITY_INFORMATION SeInfo,
|
|
OUT PACTRL_ACCESS *ppAccess,
|
|
OUT PACTRL_AUDIT *ppAudit);
|
|
|
|
DWORD AddAccessLists(IN SECURITY_INFORMATION SeInfo,
|
|
IN PACTRL_ACCESSW pAdd,
|
|
IN BOOL fMerge = FALSE,
|
|
IN BOOL fOldStyleMerge =
|
|
FALSE);
|
|
|
|
DWORD AddOwnerGroup(IN SECURITY_INFORMATION SeInfo,
|
|
IN PTRUSTEE pOwner,
|
|
IN PTRUSTEE pGroup);
|
|
|
|
DWORD GetExplicitAccess(IN PTRUSTEE pTrustee,
|
|
IN PWSTR pwszProperty,
|
|
OUT PULONG pDeniedMask,
|
|
OUT PULONG pAllowedMask);
|
|
|
|
DWORD GetExplicitAudits(IN PTRUSTEE pTrustee,
|
|
IN PWSTR pwszProperty,
|
|
OUT PULONG pSuccessMask,
|
|
OUT PULONG pFailureMask);
|
|
|
|
DWORD GetExplicitEntries(IN PTRUSTEE pTrustee,
|
|
IN PWSTR pwszProperty,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
OUT PULONG pcEntries,
|
|
OUT PACTRL_ACCESS_ENTRYW *ppAEList);
|
|
|
|
DWORD BuildSDForAccessList(
|
|
OUT PSECURITY_DESCRIPTOR *ppSD,
|
|
OUT PSECURITY_INFORMATION pSeInfo,
|
|
IN ULONG fFlags =
|
|
ACCLIST_SD_ABSOK);
|
|
|
|
DWORD GetSDSidAsTrustee(IN SECURITY_INFORMATION SeInfo,
|
|
OUT PTRUSTEE *ppTrustee);
|
|
|
|
DWORD QuerySDSize() {return(_cSDSize);};
|
|
|
|
private:
|
|
|
|
CSList _AccList;
|
|
CSList _TrusteeList;
|
|
PSID _pGroup;
|
|
PSID _pOwner;
|
|
ULONG _fDAclFlags;
|
|
ULONG _fSAclFlags;
|
|
PSECURITY_DESCRIPTOR _pSD;
|
|
SECURITY_INFORMATION _SeInfo;
|
|
BOOL _fSDValid;
|
|
ULONG _cSDSize;
|
|
BOOL _fFreeSD;
|
|
|
|
SE_OBJECT_TYPE _ObjType;
|
|
|
|
|
|
PLDAP _pLDAP;
|
|
PWSTR _pwszDsPathReference;
|
|
PWSTR _pwszLookupServer;
|
|
MARTA_KERNEL_TYPE _KernelObjectType;
|
|
|
|
DWORD ConvertAclToAccess(IN SECURITY_INFORMATION SeInfo,
|
|
IN PACL pAcl,
|
|
IN PWSTR pwszProperty,
|
|
IN BOOL fAddAll,
|
|
IN BOOL fProtected);
|
|
|
|
DWORD MarshalAccessList(IN SECURITY_INFORMATION SeInfo,
|
|
OUT PACTRL_ACCESSW *ppAList);
|
|
|
|
DWORD GetTrusteeNode(IN PTRUSTEE pTrustee,
|
|
IN ULONG fNodeOptions,
|
|
OUT PTRUSTEE_NODE *ppTrusteeNode);
|
|
|
|
|
|
inline DWORD FreeAEList(PACTRL_ACCESS_ENTRY_LIST pFree);
|
|
|
|
inline DWORD RemoveTrustee(PTRUSTEE_W pTrustee);
|
|
|
|
DWORD CopyAccessEntry(IN PACTRL_ACCESS_ENTRY pNewEntry,
|
|
IN PACTRL_ACCESS_ENTRY pOldEntry);
|
|
|
|
DWORD CollapseInheritedAces();
|
|
|
|
DWORD GrowInheritedAces();
|
|
|
|
DWORD ShrinkList(IN PACTRL_ACCESS_ENTRY_LIST pOldList,
|
|
IN ULONG cRemoved,
|
|
IN PACTRL_ACCESS_ENTRY_LIST *ppNewList);
|
|
|
|
|
|
DWORD CompressList(IN SECURITY_INFORMATION SeInfo,
|
|
OUT PACCLIST_CNODE *ppList,
|
|
OUT PULONG pcItems);
|
|
|
|
VOID FreeCompressedList(IN PACCLIST_CNODE pList,
|
|
IN ULONG cItems);
|
|
|
|
DWORD AddSubList(IN PACCLIST_CNODE pCList,
|
|
IN CSList& TempList,
|
|
IN ULONG iStart);
|
|
|
|
DWORD SizeCompressedListAsAcl(IN PACCLIST_CNODE pList,
|
|
IN ULONG cItems,
|
|
OUT PULONG pcSize,
|
|
IN BOOL fForceNullToEmpty);
|
|
|
|
DWORD BuildAcl(IN PACCLIST_CNODE pList,
|
|
IN ULONG cItems,
|
|
IN PACL pAcl,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
OUT BOOL *pfProtected);
|
|
|
|
DWORD InsertEntryInAcl(IN PACTRL_ACCESS_ENTRY pAE,
|
|
IN GUID *pObject,
|
|
IN PACL pAcl);
|
|
|
|
};
|
|
|
|
DWORD CAccessList::SetObjectType(IN SE_OBJECT_TYPE ObjType)
|
|
{
|
|
_ObjType = ObjType;
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
DWORD CAccessList::FreeAEList(PACTRL_ACCESS_ENTRY_LIST pFree)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if(pFree != NULL)
|
|
{
|
|
|
|
for(ULONG iIndex = 0; iIndex < pFree->cEntries; iIndex++)
|
|
{
|
|
dwErr = RemoveTrustee(&(pFree->pAccessList[iIndex].Trustee));
|
|
if(dwErr != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
AccFree(pFree);
|
|
return(dwErr);
|
|
}
|
|
|
|
DWORD CAccessList::RemoveTrustee(PTRUSTEE_W pTrustee)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
PTRUSTEE_NODE pTrusteeNode =(PTRUSTEE_NODE)
|
|
_TrusteeList.Find((PVOID)pTrustee,
|
|
CompTrusteeToTrusteeNode);
|
|
|
|
ASSERT(pTrusteeNode != NULL);
|
|
if(pTrusteeNode == NULL)
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
pTrusteeNode->cUseCount--;
|
|
|
|
if(pTrusteeNode->cUseCount == 0)
|
|
{
|
|
_TrusteeList.Remove((PVOID)pTrusteeNode);
|
|
DelTrusteeNode((PVOID)pTrusteeNode);
|
|
}
|
|
}
|
|
return(dwErr);
|
|
}
|
|
|
|
|
|
VOID CAccessList::SetDsPathInfo(IN PLDAP pLDAP,
|
|
IN PWSTR pwszDsPath )
|
|
{
|
|
_pLDAP = pLDAP;
|
|
_pwszDsPathReference = pwszDsPath;
|
|
|
|
}
|
|
|
|
DWORD CAccessList::SetLookupServer(IN PWSTR pwszLookupServer)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
//
|
|
// jinhuang: please do not leak memory
|
|
//
|
|
if ( _pwszLookupServer ) {
|
|
AccFree(_pwszLookupServer);
|
|
_pwszLookupServer = NULL;
|
|
}
|
|
|
|
ACC_ALLOC_AND_COPY_STRINGW( pwszLookupServer, _pwszLookupServer, dwErr );
|
|
|
|
return(dwErr);
|
|
}
|
|
|
|
VOID CAccessList::SetKernelObjectType(IN MARTA_KERNEL_TYPE KernelType )
|
|
{
|
|
_KernelObjectType = KernelType;
|
|
}
|
|
#endif // __ACCLIST_HXX__
|
|
|
|
|
|
|