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.

329 lines
7.9 KiB

  1. #include "pch.h"
  2. #include "fundsrmp.h"
  3. //
  4. // The various SIDs, the easy way
  5. //
  6. DWORD BobGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00020001};
  7. DWORD MarthaGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00020002};
  8. DWORD JoeGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00020003};
  9. DWORD VPGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010001};
  10. DWORD ManagerGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010002};
  11. DWORD EmployeeGuid[] = {0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010003};
  12. DWORD EveryoneGuid[] = {0x101, 0x01000000, 0};
  13. PSID BobSid = (PSID)BobGuid;
  14. PSID MarthaSid= (PSID)MarthaGuid;
  15. PSID JoeSid = (PSID)JoeGuid;
  16. PSID VPSid = (PSID)VPGuid;
  17. PSID ManagerSid = (PSID)ManagerGuid;
  18. PSID EmployeeSid = (PSID)EmployeeGuid;
  19. PSID EveryoneSid = (PSID)EveryoneGuid;
  20. //
  21. // Maximum spending approvals, in cents
  22. //
  23. DWORD MaxSpendingVP = 100000000;
  24. DWORD MaxSpendingManager = 1000000;
  25. DWORD MaxSpendingEmployee = 50000;
  26. //
  27. // The callback routines used with AuthZ
  28. //
  29. BOOL
  30. FundsAccessCheck(
  31. IN AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
  32. IN PACE_HEADER pAce,
  33. IN PVOID pArgs OPTIONAL,
  34. IN OUT PBOOL pbAceApplicable
  35. )
  36. /*++
  37. Routine Description
  38. This is the callback access check. It is registered with a
  39. resource manager. AuthzAccessCheck calls this function when it
  40. encounters a callback type ACE, one of:
  41. ACCESS_ALLOWED_CALLBACK_ACE_TYPE
  42. ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
  43. ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
  44. This function determines if the given callback ACE applies to the
  45. client context (which has already had dynamic groups computed) and
  46. the optional arguments, in this case the request amount.
  47. The list of groups which apply to the user is traversed. If a group
  48. is found which allows the user the requested access, pbAceApplicable
  49. is set to true and the function returns. If the end of the group list
  50. is reached, pbAceApplicable is set to false and the function returns.
  51. Arguments
  52. hAuthzClientContext - handle to the AuthzClientContext.
  53. pAce - pointer to the Ace header.
  54. pArgs - optional arguments, in this case DWORD*, DWORD is the spending
  55. request amount in cents
  56. pbAceApplicable - returns true iff the ACE allows the client's request
  57. Return value
  58. Bool, true on success, false on error
  59. Error checking
  60. Sample code, no error checking
  61. --*/
  62. {
  63. //
  64. // First, look up the user's SID from the context
  65. //
  66. DWORD dwTokenGroupsSize = 0;
  67. PVOID pvTokenGroupsBuf = NULL;
  68. DWORD i;
  69. PDWORD pAccessMask = NULL;
  70. //
  71. // The requested spending amount, in cents
  72. //
  73. DWORD dwRequestedSpending = ((PDWORD)pArgs)[0];
  74. //
  75. // By default, the ACE does not apply to the request
  76. //
  77. *pbAceApplicable = FALSE;
  78. //
  79. // The object's access mask (right after the ACE_HEADER)
  80. // The access mask determines types of expenditures allowed
  81. // from this fund
  82. //
  83. pAccessMask = (PDWORD) (pAce + sizeof(ACE_HEADER));
  84. //
  85. // Get needed buffer size
  86. //
  87. AuthzGetContextInformation(hAuthzClientContext,
  88. AuthzContextInfoGroupsSids,
  89. NULL,
  90. 0,
  91. &dwTokenGroupsSize
  92. );
  93. pvTokenGroupsBuf = malloc(dwTokenGroupsSize);
  94. //
  95. // Get the actual TOKEN_GROUPS array
  96. //
  97. AuthzGetContextInformation(hAuthzClientContext,
  98. AuthzContextInfoGroupsSids,
  99. pvTokenGroupsBuf,
  100. dwTokenGroupsSize,
  101. &dwTokenGroupsSize
  102. );
  103. //
  104. // Go through the groups until end is reached or a group applying to the
  105. // request is found
  106. //
  107. for( i = 0;
  108. i < ((PTOKEN_GROUPS)pvTokenGroupsBuf)->GroupCount
  109. && *pbAceApplicable != TRUE;
  110. i++ )
  111. {
  112. //
  113. // Again, this is the business logic.
  114. // Each level of employee can approve different amounts.
  115. //
  116. //
  117. // VP
  118. //
  119. if( dwRequestedSpending <= MaxSpendingVP &&
  120. EqualSid(VPSid, ((PTOKEN_GROUPS)pvTokenGroupsBuf)->Groups[i].Sid) )
  121. {
  122. *pbAceApplicable = TRUE;
  123. }
  124. //
  125. // Manager
  126. //
  127. if( dwRequestedSpending <= MaxSpendingManager &&
  128. EqualSid(ManagerSid, ((PTOKEN_GROUPS)pvTokenGroupsBuf)->Groups[i].Sid) )
  129. {
  130. *pbAceApplicable = TRUE;
  131. }
  132. //
  133. // Employee
  134. //
  135. if( dwRequestedSpending <= MaxSpendingEmployee &&
  136. EqualSid(EmployeeSid, ((PTOKEN_GROUPS)pvTokenGroupsBuf)->Groups[i].Sid) )
  137. {
  138. *pbAceApplicable = TRUE;
  139. }
  140. }
  141. return TRUE;
  142. }
  143. BOOL
  144. FundsComputeDynamicGroups(
  145. IN AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
  146. IN PVOID Args,
  147. OUT PSID_AND_ATTRIBUTES *pSidAttrArray,
  148. OUT PDWORD pSidCount,
  149. OUT PSID_AND_ATTRIBUTES *pRestrictedSidAttrArray,
  150. OUT PDWORD pRestrictedSidCount
  151. )
  152. /*++
  153. Routine Description
  154. Resource manager callback to compute dynamic groups. This is used by the RM
  155. to decide if the specified client context should be included in any RM defined groups.
  156. In this example, the employees are hardcoded into their roles. However, this is the
  157. place you would normally retrieve data from an external source to determine the
  158. users' additional roles.
  159. Arguments
  160. hAuthzClientContext - handle to client context.
  161. Args - optional parameter to pass information for evaluating group membership.
  162. pSidAttrArray - computed group membership SIDs
  163. pSidCount - count of SIDs
  164. pRestrictedSidAttrArray - computed group membership restricted SIDs
  165. pRestrictedSidCount - count of restricted SIDs
  166. Return Value
  167. Bool, true for success, false on failure.
  168. Error checking
  169. Sample code, no error checking
  170. --*/
  171. {
  172. //
  173. // First, look up the user's SID from the context
  174. //
  175. DWORD dwSidSize = 0;
  176. PVOID pvSidBuf = NULL;
  177. PSID psSidPtr = NULL;
  178. //
  179. // Get needed buffer size
  180. //
  181. AuthzGetContextInformation(hAuthzClientContext,
  182. AuthzContextInfoUserSid,
  183. NULL,
  184. 0,
  185. &dwSidSize
  186. );
  187. pvSidBuf = malloc(dwSidSize);
  188. //
  189. // Get the actual SID (inside a TOKEN_USER structure)
  190. //
  191. AuthzGetContextInformation(hAuthzClientContext,
  192. AuthzContextInfoUserSid,
  193. pvSidBuf,
  194. dwSidSize,
  195. &dwSidSize
  196. );
  197. psSidPtr = ((PTOKEN_USER)pvSidBuf)->User.Sid;
  198. //
  199. // Allocate the memory for the returns, which will be deallocated by FreeDynamicGroups
  200. // Only a single group will be returned, determining the employee type
  201. //
  202. *pSidCount = 1;
  203. *pSidAttrArray = (PSID_AND_ATTRIBUTES)malloc( sizeof(SID_AND_ATTRIBUTES) );
  204. //
  205. // No restricted group sids
  206. //
  207. pRestrictedSidCount = 0;
  208. *pRestrictedSidAttrArray = NULL;
  209. (*pSidAttrArray)[0].Attributes = SE_GROUP_ENABLED;
  210. //
  211. // The hardcoded logic:
  212. // Bob is a VP
  213. // Martha is a Manager
  214. // Joe is an Employee
  215. //
  216. if( EqualSid(psSidPtr, BobSid) )
  217. {
  218. (*pSidAttrArray)[0].Sid = VPSid;
  219. }
  220. else if( EqualSid(psSidPtr, MarthaSid) )
  221. {
  222. (*pSidAttrArray)[0].Sid = ManagerSid;
  223. }
  224. else if( EqualSid(psSidPtr, JoeSid) )
  225. {
  226. (*pSidAttrArray)[0].Sid = EmployeeSid;
  227. }
  228. free(pvSidBuf);
  229. return TRUE;
  230. }
  231. VOID
  232. FundsFreeDynamicGroups (
  233. IN PSID_AND_ATTRIBUTES pSidAttrArray
  234. )
  235. /*++
  236. Routine Description
  237. Frees memory allocated for the dynamic group array.
  238. Arguments
  239. pSidAttrArray - array to free.
  240. Return Value
  241. None.
  242. --*/
  243. {
  244. if (pSidAttrArray != NULL)
  245. {
  246. free(pSidAttrArray);
  247. }
  248. }