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.

347 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998 - 1999.
  5. //
  6. // File: secutil.cxx
  7. //
  8. // Contents: security utility routines
  9. //
  10. // History: 10-April-98 dlee Created from 4 other copies in NT
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include "secutil.hxx"
  16. //+-------------------------------------------------------------------------
  17. //
  18. // Function: InitAllowedAce
  19. //
  20. // Synopsis: Assignes the ACE values into the allowed ACE
  21. //
  22. // Arguments: [pAllowedAce] - Supplies a pointer to the ACE that is
  23. // initialized.
  24. // [AceSize] - Supplies the size of the ACE in bytes.
  25. // [InheritFlags] - Supplies ACE inherit flags.
  26. // [AceFlags] - Supplies ACE type specific control flags.
  27. // [Mask] - Supplies the allowed access masks.
  28. // [pAllowedSid] - Supplies the pointer to the SID of user/
  29. // group which is allowed the specified access.
  30. //
  31. // History: 10-April-98 dlee Stole from 4 other places in NT
  32. //
  33. //--------------------------------------------------------------------------
  34. void InitAllowedAce(
  35. ACCESS_ALLOWED_ACE * pAllowedAce,
  36. USHORT AceSize,
  37. BYTE InheritFlags,
  38. BYTE AceFlags,
  39. ACCESS_MASK Mask,
  40. SID * pAllowedSid )
  41. {
  42. pAllowedAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  43. pAllowedAce->Header.AceSize = AceSize;
  44. pAllowedAce->Header.AceFlags = AceFlags | InheritFlags;
  45. pAllowedAce->Mask = Mask;
  46. if ( !CopySid( GetLengthSid( pAllowedSid ),
  47. &(pAllowedAce->SidStart),
  48. pAllowedSid ) )
  49. THROW( CException() );
  50. } //InitAllowedAce
  51. //+-------------------------------------------------------------------------
  52. //
  53. // Function: InitDeniedAce
  54. //
  55. // Synopsis: Assignes the ACE values into the denied ACE
  56. //
  57. // Arguments: [pDeniedAce] - Supplies a pointer to the ACE that is
  58. // initialized.
  59. // [AceSize] - Supplies the size of the ACE in bytes.
  60. // [InheritFlags] - Supplies ACE inherit flags.
  61. // [AceFlags] - Supplies ACE type specific control flags.
  62. // [Mask] - Supplies the allowed access masks.
  63. // [pDeniedSid] - Supplies the pointer to the SID of user/
  64. // group which is denied the specified access.
  65. //
  66. // History: 10-April-98 dlee Stole from 4 other places in NT
  67. //
  68. //--------------------------------------------------------------------------
  69. void InitDeniedAce(
  70. ACCESS_DENIED_ACE * pDeniedAce,
  71. USHORT AceSize,
  72. BYTE InheritFlags,
  73. BYTE AceFlags,
  74. ACCESS_MASK Mask,
  75. SID * pDeniedSid )
  76. {
  77. pDeniedAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
  78. pDeniedAce->Header.AceSize = AceSize;
  79. pDeniedAce->Header.AceFlags = AceFlags | InheritFlags;
  80. pDeniedAce->Mask = Mask;
  81. if( !CopySid( GetLengthSid( pDeniedSid ),
  82. &(pDeniedAce->SidStart),
  83. pDeniedSid ) )
  84. THROW( CException() );
  85. } //InitDeniedAce
  86. //+-------------------------------------------------------------------------
  87. //
  88. // Function: InitAuditAce
  89. //
  90. // Synopsis: Assignes the ACE values into the audit ACE
  91. //
  92. // Arguments: [pAuditAce] - Supplies a pointer to the ACE that is
  93. // initialized.
  94. // [AceSize] - Supplies the size of the ACE in bytes.
  95. // [InheritFlags] - Supplies ACE inherit flags.
  96. // [AceFlags] - Supplies ACE type specific control flags.
  97. // [Mask] - Supplies the allowed access masks.
  98. // [pAuditSid] - Supplies the pointer to the SID of user/
  99. // group which is audited
  100. //
  101. // History: 10-April-98 dlee Stole from 4 other places in NT
  102. //
  103. //--------------------------------------------------------------------------
  104. void InitAuditAce(
  105. ACCESS_ALLOWED_ACE * pAuditAce,
  106. USHORT AceSize,
  107. BYTE InheritFlags,
  108. BYTE AceFlags,
  109. ACCESS_MASK Mask,
  110. SID * pAuditSid )
  111. {
  112. pAuditAce->Header.AceType = SYSTEM_AUDIT_ACE_TYPE;
  113. pAuditAce->Header.AceSize = AceSize;
  114. pAuditAce->Header.AceFlags = AceFlags | InheritFlags;
  115. pAuditAce->Mask = Mask;
  116. if ( !CopySid( GetLengthSid( pAuditSid ),
  117. &(pAuditAce->SidStart),
  118. pAuditSid ) )
  119. THROW( CException() );
  120. } //InitAuditAce
  121. //+-------------------------------------------------------------------------
  122. //
  123. // Function: CiCreateSecurityDescriptor
  124. //
  125. // Synopsis: Creates a security descriptor from input data
  126. //
  127. // Arguments: [pAceData] - Array of input data
  128. // [cAces] - Count of items in pAceData
  129. // [OwnerSid] - 0 or the owner of the descriptor
  130. // [GroupSid] - 0 or group of the descriptor
  131. // [xAcls] - Resulting absolute SECURITY_DESCRIPTOR,
  132. // allocated to the required size.
  133. //
  134. // History: 10-April-98 dlee Stole from 4 other places in NT
  135. //
  136. //--------------------------------------------------------------------------
  137. void CiCreateSecurityDescriptor( ACE_DATA const * const pAceData,
  138. ULONG cAces,
  139. SID * pOwnerSid,
  140. SID * pGroupSid,
  141. XArray<BYTE> & xAcls )
  142. {
  143. //
  144. // This function returns a pointer to memory dynamically allocated to
  145. // hold the absolute security descriptor, the DACL, the SACL, and all
  146. // the ACEs:
  147. //
  148. // +---------------------------------------------------------------+
  149. // | Security Descriptor |
  150. // +-------------------------------+-------+---------------+-------+
  151. // | DACL | ACE 1 | . . . | ACE n |
  152. // +-------------------------------+-------+---------------+-------+
  153. // | SACL | ACE 1 | . . . | ACE n |
  154. // +-------------------------------+-------+---------------+-------+
  155. //
  156. DWORD cbDacl = sizeof ACL;
  157. DWORD cbSacl = sizeof ACL;
  158. DWORD cbMaxAce = 0;
  159. //
  160. // Compute the total size of the DACL and SACL ACEs and the maximum
  161. // size of any ACE.
  162. //
  163. for ( DWORD i = 0; i < cAces; i++ )
  164. {
  165. DWORD cbAce = GetLengthSid( pAceData[i].pSid );
  166. switch (pAceData[i].AceType)
  167. {
  168. case ACCESS_ALLOWED_ACE_TYPE:
  169. cbAce += sizeof ACCESS_ALLOWED_ACE;
  170. cbDacl += cbAce;
  171. break;
  172. case ACCESS_DENIED_ACE_TYPE:
  173. cbAce += sizeof ACCESS_DENIED_ACE;
  174. cbDacl += cbAce;
  175. break;
  176. case SYSTEM_AUDIT_ACE_TYPE:
  177. cbAce += sizeof SYSTEM_AUDIT_ACE;
  178. cbSacl += cbAce;
  179. break;
  180. default:
  181. Win4Assert( FALSE );
  182. }
  183. cbMaxAce = __max( cbMaxAce, cbAce );
  184. }
  185. //
  186. // Allocate a chunk of memory large enough the security descriptor
  187. // the DACL, the SACL and all ACEs.
  188. // A security descriptor is of opaque data type but
  189. // SECURITY_DESCRIPTOR_MIN_LENGTH is the right size.
  190. //
  191. DWORD cbTotal = SECURITY_DESCRIPTOR_MIN_LENGTH;
  192. if ( cbDacl != sizeof ACL )
  193. cbTotal += cbDacl;
  194. if ( cbSacl != sizeof ACL )
  195. cbTotal += cbSacl;
  196. xAcls.Init( cbTotal );
  197. SECURITY_DESCRIPTOR *pAbsoluteSd = (SECURITY_DESCRIPTOR *) xAcls.Get();
  198. //
  199. // Initialize the Dacl and Sacl
  200. //
  201. BYTE *pbCurrent = (BYTE *) pAbsoluteSd + SECURITY_DESCRIPTOR_MIN_LENGTH;
  202. ACL *pDacl = 0; // Pointer to the DACL portion of above buffer
  203. ACL *pSacl = 0; // Pointer to the SACL portion of above buffer
  204. if ( sizeof ACL != cbDacl )
  205. {
  206. pDacl = (ACL *) pbCurrent;
  207. pbCurrent += cbDacl;
  208. if( !InitializeAcl( pDacl, cbDacl, ACL_REVISION ) )
  209. THROW( CException() );
  210. }
  211. if ( sizeof ACL != cbSacl )
  212. {
  213. pSacl = (ACL *) pbCurrent;
  214. pbCurrent += cbSacl;
  215. if ( !InitializeAcl( pSacl, cbSacl, ACL_REVISION ) )
  216. THROW( CException() );
  217. }
  218. //
  219. // Allocate a temporary buffer big enough for the biggest ACE.
  220. // This is usually pretty small
  221. //
  222. XGrowable<BYTE> xMaxAce( cbMaxAce );
  223. //
  224. // Initialize each ACE, and append it into the end of the DACL or SACL.
  225. //
  226. for ( i = 0; i < cAces; i++ )
  227. {
  228. DWORD cbAce = GetLengthSid( pAceData[i].pSid );
  229. ACL *pCurrentAcl;
  230. switch (pAceData[i].AceType)
  231. {
  232. case ACCESS_ALLOWED_ACE_TYPE:
  233. cbAce += sizeof ACCESS_ALLOWED_ACE;
  234. pCurrentAcl = pDacl;
  235. InitAllowedAce( (ACCESS_ALLOWED_ACE *) xMaxAce.Get(),
  236. (USHORT) cbAce,
  237. pAceData[i].InheritFlags,
  238. pAceData[i].AceFlags,
  239. pAceData[i].Mask,
  240. pAceData[i].pSid );
  241. break;
  242. case ACCESS_DENIED_ACE_TYPE:
  243. cbAce += sizeof ACCESS_DENIED_ACE;
  244. pCurrentAcl = pDacl;
  245. InitDeniedAce( (ACCESS_DENIED_ACE *) xMaxAce.Get(),
  246. (USHORT) cbAce,
  247. pAceData[i].InheritFlags,
  248. pAceData[i].AceFlags,
  249. pAceData[i].Mask,
  250. pAceData[i].pSid );
  251. break;
  252. case SYSTEM_AUDIT_ACE_TYPE:
  253. cbAce += sizeof SYSTEM_AUDIT_ACE;
  254. pCurrentAcl = pSacl;
  255. // Audit uses ACCESS_ALLOWED_ACE
  256. InitAuditAce( (ACCESS_ALLOWED_ACE *) xMaxAce.Get(),
  257. (USHORT) cbAce,
  258. pAceData[i].InheritFlags,
  259. pAceData[i].AceFlags,
  260. pAceData[i].Mask,
  261. pAceData[i].pSid );
  262. break;
  263. }
  264. //
  265. // Append the initialized ACE to the end of DACL or SACL
  266. //
  267. if ( !AddAce( pCurrentAcl,
  268. ACL_REVISION,
  269. MAXULONG,
  270. xMaxAce.Get(),
  271. cbAce ) )
  272. THROW( CException() );
  273. }
  274. //
  275. // Create the security descriptor with absolute pointers to SIDs
  276. // and ACLs.
  277. //
  278. // Owner = pOwnerSid
  279. // Group = pGroupSid
  280. // Dacl = Dacl
  281. // Sacl = Sacl
  282. //
  283. if ( !InitializeSecurityDescriptor( pAbsoluteSd,
  284. SECURITY_DESCRIPTOR_REVISION ) ||
  285. !SetSecurityDescriptorOwner( pAbsoluteSd,
  286. pOwnerSid,
  287. FALSE ) ||
  288. !SetSecurityDescriptorGroup( pAbsoluteSd,
  289. pGroupSid,
  290. FALSE ) ||
  291. !SetSecurityDescriptorDacl( pAbsoluteSd,
  292. TRUE,
  293. pDacl,
  294. FALSE ) ||
  295. !SetSecurityDescriptorSacl( pAbsoluteSd,
  296. FALSE,
  297. pSacl,
  298. FALSE ) )
  299. THROW( CException() );
  300. } //CiCreateSecurityDescriptor