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.

435 lines
15 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1996.
  5. //
  6. // File: acclist.hxx
  7. //
  8. // Contents: Class to manage a list of access control structures for a
  9. // given object
  10. //
  11. // History: 28-Jul-96 MacM Created
  12. //
  13. //--------------------------------------------------------------------
  14. #ifndef __ACCLIST_HXX__
  15. #define __ACCLIST_HXX__
  16. //
  17. // Use until uplevel ACLs appear
  18. //
  19. #define _NO_UPLEVEL
  20. typedef struct _ACCLIST_NODE
  21. {
  22. PWSTR pwszProperty;
  23. PWSTR pwszPropInBuff;
  24. SECURITY_INFORMATION SeInfo;
  25. PACTRL_ACCESS_ENTRY_LIST pAccessList;
  26. PACTRL_ACCESS_ENTRY_LIST pAuditList;
  27. ULONG fState;
  28. } ACCLIST_NODE, *PACCLIST_NODE;
  29. typedef struct _ACCLIST_CNODE
  30. {
  31. PACTRL_ACCESS_ENTRY pList;
  32. PACCLIST_NODE pONode;
  33. ULONG cExp;
  34. ULONG cL1Inherit;
  35. ULONG cL2Inherit;
  36. BOOL Empty;
  37. } ACCLIST_CNODE, *PACCLIST_CNODE;
  38. typedef struct _TRUSTEE_NODE
  39. {
  40. TRUSTEE Trustee;
  41. PWSTR pwszTrusteeName;
  42. PWSTR pwszTrusteeInBuff;
  43. PSID pSid;
  44. ULONG fFlags;
  45. SID_NAME_USE SidType;
  46. PWSTR pwszDomainName;
  47. ULONG cUseCount;
  48. struct _TRUSTEE_NODE *pImpersonate;
  49. } TRUSTEE_NODE, *PTRUSTEE_NODE;
  50. typedef struct _IPROP_IN_BUFF
  51. {
  52. PWSTR pwszIProp;
  53. PWSTR pwszIPropInBuff;
  54. } IPROP_IN_BUFF, *PIPROP_IN_BUFF;
  55. //
  56. // Node for turning an acl into an access list
  57. //
  58. typedef struct _ACCLIST_ATOACCESS
  59. {
  60. GUID *pGuid;
  61. CSList AceList;
  62. } ACCLIST_ATOACCESS, *PACCLIST_ATOACCESS;
  63. typedef struct _ACCLIST_ATOANODE
  64. {
  65. PACE_HEADER pAce;
  66. ULONG fInherit;
  67. } ACCLIST_ATOANODE, *PACCLIST_ATOANODE;
  68. //
  69. // Used when building an acl to get them in the proper order
  70. //
  71. typedef struct _ACC_ACLBLD_NODE
  72. {
  73. PACCLIST_NODE pNode;
  74. ULONG iLastIndex;
  75. } ACC_ACLBLD_NODE, *PACC_ACLBLD_NODE;
  76. typedef enum _ACC_ACLBLD_TYPE
  77. {
  78. AAT_DENIED = 0,
  79. AAT_OBJ_DENIED,
  80. AAT_ALLOWED,
  81. AAT_OBJ_ALLOWED,
  82. AAT_PSET_ALLOWED,
  83. AAT_PROP_ALLOWED,
  84. AAT_IDENIED,
  85. AAT_IOBJ_DENIED,
  86. AAT_IALLOWED,
  87. AAT_IOBJ_ALLOWED,
  88. AAT_IPSET_ALLOWED,
  89. AAT_IPROP_ALLOWED,
  90. AAT_AUDIT,
  91. AAT_INVALID,
  92. } ACC_ACLBLD_TYPE, *PACC_ACLBLD_TYPE;
  93. //
  94. // State flags for the ACCLIST_NODE structure
  95. //
  96. #define ACCLIST_DACL_PROTECTED 0x00000001
  97. #define ACCLIST_SACL_PROTECTED 0x00000002
  98. //
  99. // Flags for the above structure
  100. //
  101. #define TRUSTEE_DELETE_SID 0x00000001
  102. #define TRUSTEE_DELETE_NAME 0x00000002
  103. #define TRUSTEE_DELETE_DOMAIN 0x00000004
  104. #define TRUSTEE_OPT_NOTHING 0x00000000
  105. #define TRUSTEE_OPT_SID 0x00000001
  106. #define TRUSTEE_OPT_NAME 0x00000002
  107. #define TRUSTEE_OPT_INSERT_ONLY 0x00000004
  108. #define ACCLIST_SD_ABSOK 0x00000001
  109. #define ACCLIST_SD_NOFREE 0x00000002
  110. #define ACCLIST_SD_DS_STYLE 0x00000004 // The first 4 bytes of the
  111. // returned security descriptor
  112. // is the SECURITY_INFORMATION
  113. #define ACCLIST_COMPRESS 0x008000000 // This node is to be
  114. // compressed out of existance
  115. #define ACCLIST_DENIED 0x80000000 // Access denied entry -or-
  116. #define ACCLIST_AUDIT ACCLIST_DENIED // an audit entry
  117. #define ACCLIST_OBJ_DENIED 0x40000000 // Access denied object entry
  118. #define ACCLIST_ALLOWED 0x20000000 // Access allowed entry
  119. #define ACCLIST_OBJ_ALLOWED 0x10000000 // Access allowed object entry
  120. #define ACCLIST_PSET_ALLOWED 0x08000000 // Access allowed property
  121. // set entry
  122. #define ACCLIST_PROP_ALLOWED 0x04000000 // Access allowed property
  123. // entry
  124. #define ACCLIST_UNKOWN_ENTRY 0x02000000 // Some weird kind of entry
  125. // was given
  126. #define ACCLIST_VALID_TYPE_FLAGS 0xFE000000 // Mask of the above flags
  127. #define ACCLIST_VALID_IN_LEVEL_FLAGS \
  128. (INHERITED_PARENT | INHERITED_GRANDPARENT) // Mask of the inheritance
  129. // level flags
  130. //
  131. // Function prototypes - Forward definitions for inline functions
  132. //
  133. BOOL CompProps(IN PVOID pvNode1,
  134. IN PVOID pvNode2);
  135. void DelTrusteeNode(PVOID pvNode);
  136. BOOL CompTrusteeToTrusteeNode(IN PVOID pvTrustee,
  137. IN PVOID pvNode2);
  138. BOOL CompTrustees(IN PVOID pvTrustee,
  139. IN PVOID pvTrustee2);
  140. //
  141. // These functions are used to determine when to process a access_entry
  142. // when building a acl
  143. //
  144. ACC_ACLBLD_TYPE GetATypeForEntry(IN PWSTR pwszProperty,
  145. IN PACTRL_ACCESS_ENTRY pAE,
  146. IN SECURITY_INFORMATION SeInfo);
  147. //+-------------------------------------------------------------------
  148. //
  149. // Class: CAccessList
  150. //
  151. // Synopsis: This class wraps the implementation of a CAccessList
  152. // (ACTRL_ALIST).
  153. //
  154. // Methods: Init
  155. //
  156. //--------------------------------------------------------------------
  157. class CAccessList
  158. {
  159. public:
  160. CAccessList();
  161. ~CAccessList();
  162. inline DWORD SetObjectType(IN SE_OBJECT_TYPE ObjType);
  163. inline VOID SetDsPathInfo(IN PLDAP pLDAP = NULL,
  164. IN PWSTR pwszDsPath = NULL);
  165. inline DWORD SetLookupServer(IN PWSTR pwszLookupServer);
  166. inline VOID SetKernelObjectType(IN MARTA_KERNEL_TYPE KernelType );
  167. DWORD AddSD(IN PSECURITY_DESCRIPTOR pSD,
  168. IN SECURITY_INFORMATION SeInfo,
  169. IN PWSTR pwszProperty,
  170. IN BOOL fAddAll = TRUE);
  171. DWORD AddAcl(IN PACL pDAcl,
  172. IN PACL pSAcl,
  173. IN PSID pOwner,
  174. IN PSID pGroup,
  175. IN SECURITY_INFORMATION SeInfo,
  176. IN PWSTR pwszProperty,
  177. IN BOOL fAddAll = TRUE,
  178. IN ULONG fControl = 0);
  179. DWORD RemoveTrusteeFromAccess(IN SECURITY_INFORMATION SeInfo,
  180. IN PTRUSTEE pTrustee,
  181. IN PWSTR pwszProperty OPTIONAL);
  182. DWORD RevokeTrusteeAccess(IN SECURITY_INFORMATION SeInfo,
  183. IN PACTRL_ACCESSW pSrcList,
  184. IN PWSTR pwszProperty OPTIONAL);
  185. DWORD MarshalAccessLists(IN SECURITY_INFORMATION SeInfo,
  186. OUT PACTRL_ACCESS *ppAccess,
  187. OUT PACTRL_AUDIT *ppAudit);
  188. DWORD AddAccessLists(IN SECURITY_INFORMATION SeInfo,
  189. IN PACTRL_ACCESSW pAdd,
  190. IN BOOL fMerge = FALSE,
  191. IN BOOL fOldStyleMerge =
  192. FALSE);
  193. DWORD AddOwnerGroup(IN SECURITY_INFORMATION SeInfo,
  194. IN PTRUSTEE pOwner,
  195. IN PTRUSTEE pGroup);
  196. DWORD GetExplicitAccess(IN PTRUSTEE pTrustee,
  197. IN PWSTR pwszProperty,
  198. OUT PULONG pDeniedMask,
  199. OUT PULONG pAllowedMask);
  200. DWORD GetExplicitAudits(IN PTRUSTEE pTrustee,
  201. IN PWSTR pwszProperty,
  202. OUT PULONG pSuccessMask,
  203. OUT PULONG pFailureMask);
  204. DWORD GetExplicitEntries(IN PTRUSTEE pTrustee,
  205. IN PWSTR pwszProperty,
  206. IN SECURITY_INFORMATION SeInfo,
  207. OUT PULONG pcEntries,
  208. OUT PACTRL_ACCESS_ENTRYW *ppAEList);
  209. DWORD BuildSDForAccessList(
  210. OUT PSECURITY_DESCRIPTOR *ppSD,
  211. OUT PSECURITY_INFORMATION pSeInfo,
  212. IN ULONG fFlags =
  213. ACCLIST_SD_ABSOK);
  214. DWORD GetSDSidAsTrustee(IN SECURITY_INFORMATION SeInfo,
  215. OUT PTRUSTEE *ppTrustee);
  216. DWORD QuerySDSize() {return(_cSDSize);};
  217. private:
  218. CSList _AccList;
  219. CSList _TrusteeList;
  220. PSID _pGroup;
  221. PSID _pOwner;
  222. ULONG _fDAclFlags;
  223. ULONG _fSAclFlags;
  224. PSECURITY_DESCRIPTOR _pSD;
  225. SECURITY_INFORMATION _SeInfo;
  226. BOOL _fSDValid;
  227. ULONG _cSDSize;
  228. BOOL _fFreeSD;
  229. SE_OBJECT_TYPE _ObjType;
  230. PLDAP _pLDAP;
  231. PWSTR _pwszDsPathReference;
  232. PWSTR _pwszLookupServer;
  233. MARTA_KERNEL_TYPE _KernelObjectType;
  234. DWORD ConvertAclToAccess(IN SECURITY_INFORMATION SeInfo,
  235. IN PACL pAcl,
  236. IN PWSTR pwszProperty,
  237. IN BOOL fAddAll,
  238. IN BOOL fProtected);
  239. DWORD MarshalAccessList(IN SECURITY_INFORMATION SeInfo,
  240. OUT PACTRL_ACCESSW *ppAList);
  241. DWORD GetTrusteeNode(IN PTRUSTEE pTrustee,
  242. IN ULONG fNodeOptions,
  243. OUT PTRUSTEE_NODE *ppTrusteeNode);
  244. inline DWORD FreeAEList(PACTRL_ACCESS_ENTRY_LIST pFree);
  245. inline DWORD RemoveTrustee(PTRUSTEE_W pTrustee);
  246. DWORD CopyAccessEntry(IN PACTRL_ACCESS_ENTRY pNewEntry,
  247. IN PACTRL_ACCESS_ENTRY pOldEntry);
  248. DWORD CollapseInheritedAces();
  249. DWORD GrowInheritedAces();
  250. DWORD ShrinkList(IN PACTRL_ACCESS_ENTRY_LIST pOldList,
  251. IN ULONG cRemoved,
  252. IN PACTRL_ACCESS_ENTRY_LIST *ppNewList);
  253. DWORD CompressList(IN SECURITY_INFORMATION SeInfo,
  254. OUT PACCLIST_CNODE *ppList,
  255. OUT PULONG pcItems);
  256. VOID FreeCompressedList(IN PACCLIST_CNODE pList,
  257. IN ULONG cItems);
  258. DWORD AddSubList(IN PACCLIST_CNODE pCList,
  259. IN CSList& TempList,
  260. IN ULONG iStart);
  261. DWORD SizeCompressedListAsAcl(IN PACCLIST_CNODE pList,
  262. IN ULONG cItems,
  263. OUT PULONG pcSize,
  264. IN BOOL fForceNullToEmpty);
  265. DWORD BuildAcl(IN PACCLIST_CNODE pList,
  266. IN ULONG cItems,
  267. IN PACL pAcl,
  268. IN SECURITY_INFORMATION SeInfo,
  269. OUT BOOL *pfProtected);
  270. DWORD InsertEntryInAcl(IN PACTRL_ACCESS_ENTRY pAE,
  271. IN GUID *pObject,
  272. IN PACL pAcl);
  273. };
  274. DWORD CAccessList::SetObjectType(IN SE_OBJECT_TYPE ObjType)
  275. {
  276. _ObjType = ObjType;
  277. return(ERROR_SUCCESS);
  278. }
  279. DWORD CAccessList::FreeAEList(PACTRL_ACCESS_ENTRY_LIST pFree)
  280. {
  281. DWORD dwErr = ERROR_SUCCESS;
  282. if(pFree != NULL)
  283. {
  284. for(ULONG iIndex = 0; iIndex < pFree->cEntries; iIndex++)
  285. {
  286. dwErr = RemoveTrustee(&(pFree->pAccessList[iIndex].Trustee));
  287. if(dwErr != ERROR_SUCCESS)
  288. {
  289. break;
  290. }
  291. }
  292. }
  293. AccFree(pFree);
  294. return(dwErr);
  295. }
  296. DWORD CAccessList::RemoveTrustee(PTRUSTEE_W pTrustee)
  297. {
  298. DWORD dwErr = ERROR_SUCCESS;
  299. PTRUSTEE_NODE pTrusteeNode =(PTRUSTEE_NODE)
  300. _TrusteeList.Find((PVOID)pTrustee,
  301. CompTrusteeToTrusteeNode);
  302. ASSERT(pTrusteeNode != NULL);
  303. if(pTrusteeNode == NULL)
  304. {
  305. dwErr = ERROR_INVALID_PARAMETER;
  306. }
  307. else
  308. {
  309. pTrusteeNode->cUseCount--;
  310. if(pTrusteeNode->cUseCount == 0)
  311. {
  312. _TrusteeList.Remove((PVOID)pTrusteeNode);
  313. DelTrusteeNode((PVOID)pTrusteeNode);
  314. }
  315. }
  316. return(dwErr);
  317. }
  318. VOID CAccessList::SetDsPathInfo(IN PLDAP pLDAP,
  319. IN PWSTR pwszDsPath )
  320. {
  321. _pLDAP = pLDAP;
  322. _pwszDsPathReference = pwszDsPath;
  323. }
  324. DWORD CAccessList::SetLookupServer(IN PWSTR pwszLookupServer)
  325. {
  326. DWORD dwErr = ERROR_SUCCESS;
  327. //
  328. // jinhuang: please do not leak memory
  329. //
  330. if ( _pwszLookupServer ) {
  331. AccFree(_pwszLookupServer);
  332. _pwszLookupServer = NULL;
  333. }
  334. ACC_ALLOC_AND_COPY_STRINGW( pwszLookupServer, _pwszLookupServer, dwErr );
  335. return(dwErr);
  336. }
  337. VOID CAccessList::SetKernelObjectType(IN MARTA_KERNEL_TYPE KernelType )
  338. {
  339. _KernelObjectType = KernelType;
  340. }
  341. #endif // __ACCLIST_HXX__