//+------------------------------------------------------------------- // // 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__