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.

254 lines
7.9 KiB

  1. //-----------------------------------------------------------------------------
  2. // fileperms.h
  3. //-----------------------------------------------------------------------------
  4. #include <aclapi.h>
  5. ////////////////////////////////////////////////////////////////
  6. //
  7. // AddPermissionToPath( PATH, ACCOUNT(RID or SAM), PERMISSION, INHERIT, OVERWRITE )
  8. //
  9. // pszPath - Should be the path to the File Object that you
  10. // want to set permissions on. Note: This is not
  11. // setting SHARE permissions, but NTFS file perms.
  12. // (Directories will work as well.)
  13. //
  14. // dwRID - Well-known RID specifying the account you want
  15. // to give access to the file.
  16. // (DOMAIN_ALIAS_RID_ADMINS, for example.)
  17. //
  18. // pszSAM - SAM-Account name specifying the account you want
  19. // to give access to the file.
  20. // (Users.h includes all SBS groups and users.)
  21. //
  22. // nAccess - Specify the File access flags that you want the
  23. // user to have.
  24. // (FILE_ALL_ACCESS is the default.)
  25. //
  26. // bInheritFromParent - Specify whether you want the new ACL
  27. // to inherit the parent settings.
  28. // (TRUE is the default.)
  29. //
  30. // bOverwriteExisting - Specify whether you want the existing
  31. // ACL on the object to remain.
  32. // (FALSE is the default.)
  33. //
  34. // nInheritance = Specify the type of inheritance you
  35. // want.
  36. // ((OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE)
  37. // is the default.)
  38. //
  39. // (NOTE: If you want it to apply to
  40. // directory objects only, use only the
  41. // CONTAINER_INHERIT_ACE.)
  42. //
  43. ////////////////////////////////////////////////////////////////
  44. #ifndef _FILEPERMS_H
  45. #define _FILEPERMS_H
  46. inline HRESULT _AddPermissionToPath( LPCTSTR pszPath,
  47. SID* pSID,
  48. UINT nAccess = FILE_ALL_ACCESS,
  49. BOOL bInheritFromParent = TRUE,
  50. BOOL bOverwriteExisting = FALSE,
  51. UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
  52. {
  53. if( !pszPath ) return E_POINTER;
  54. if( !pSID ) return E_POINTER;
  55. PSECURITY_DESCRIPTOR pSD = NULL;
  56. PACL pOldAcl = NULL;
  57. PACL pNewAcl = NULL;
  58. DWORD dwError = 0;
  59. DWORD dwOldSize = 0;
  60. DWORD dwNewSize = 0;
  61. ACL_SIZE_INFORMATION pACLSize;
  62. ZeroMemory(&pACLSize, sizeof(ACL_SIZE_INFORMATION));
  63. // Get the current information for the path
  64. dwError = GetNamedSecurityInfo( (LPTSTR)pszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, &pSD );
  65. if( dwError != ERROR_SUCCESS )
  66. {
  67. goto cleanup;
  68. }
  69. // If there was any current information, let's make sure we allocate enough
  70. // size for it when we go to add our new ACE.
  71. if( !bOverwriteExisting && pOldAcl )
  72. {
  73. if (!::GetAclInformation( pOldAcl, &pACLSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ))
  74. {
  75. dwError = GetLastError();
  76. goto cleanup;
  77. }
  78. dwOldSize = pACLSize.AclBytesInUse;
  79. }
  80. dwNewSize = dwOldSize + sizeof(ACL) + sizeof (ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid( pSID );
  81. pNewAcl = (ACL*)malloc(dwNewSize);
  82. if (pNewAcl == NULL)
  83. {
  84. dwError = ERROR_NOT_ENOUGH_MEMORY;
  85. goto cleanup;
  86. }
  87. ZeroMemory( pNewAcl, dwNewSize );
  88. if ( !::InitializeAcl(pNewAcl, dwNewSize, ACL_REVISION) )
  89. {
  90. dwError = GetLastError();
  91. goto cleanup;
  92. }
  93. // Copy existing entries into new DACL.
  94. if( !bOverwriteExisting )
  95. {
  96. for ( DWORD dwCount = 0; dwCount < pACLSize.AceCount; dwCount++ )
  97. {
  98. PACCESS_ALLOWED_ACE pACE = NULL;
  99. // Get the Old ACE
  100. if ( !::GetAce(pOldAcl, dwCount, (void**)&pACE) )
  101. {
  102. ASSERT(FALSE);
  103. continue;
  104. }
  105. if( bInheritFromParent || !(pACE->Header.AceFlags & INHERITED_ACE) )
  106. {
  107. // Add it to the new ACL
  108. if ( !::AddAce(pNewAcl, ACL_REVISION, (DWORD)-1, pACE, pACE->Header.AceSize) )
  109. {
  110. ASSERT(FALSE);
  111. continue;
  112. }
  113. }
  114. }
  115. }
  116. if( !::AddAccessAllowedAceEx(pNewAcl, ACL_REVISION, nInheritance, nAccess, pSID) )
  117. {
  118. dwError = GetLastError();
  119. goto cleanup;
  120. }
  121. SECURITY_INFORMATION siType = DACL_SECURITY_INFORMATION;
  122. siType |= bInheritFromParent ? 0 : PROTECTED_DACL_SECURITY_INFORMATION;
  123. dwError = SetNamedSecurityInfo( (LPTSTR)pszPath, SE_FILE_OBJECT, siType, NULL, NULL, pNewAcl, NULL );
  124. if( dwError != ERROR_SUCCESS )
  125. {
  126. goto cleanup;
  127. }
  128. cleanup:
  129. if ( pNewAcl != NULL )
  130. {
  131. free( pNewAcl );
  132. pNewAcl = NULL;
  133. }
  134. if ( pSD != NULL )
  135. {
  136. LocalFree( pSD );
  137. pSD = NULL;
  138. pOldAcl = NULL;
  139. }
  140. return HRESULT_FROM_WIN32( dwError );
  141. }
  142. //
  143. // Well-Known RID Version
  144. //
  145. inline HRESULT AddPermissionToPath( LPCTSTR pszPath,
  146. DWORD dwRID,
  147. UINT nAccess = FILE_ALL_ACCESS,
  148. BOOL bInheritFromParent = TRUE,
  149. BOOL bOverwriteExisting = FALSE,
  150. UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
  151. {
  152. if( !pszPath ) return E_POINTER;
  153. if( _tcslen(pszPath) == 0 ) return E_INVALIDARG;
  154. PSID psid = NULL;
  155. SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
  156. BOOL bRet = AllocateAndInitializeSid( &sia,
  157. 2,
  158. SECURITY_BUILTIN_DOMAIN_RID,
  159. dwRID,
  160. 0, 0, 0, 0, 0, 0,
  161. &psid);
  162. if( !bRet )
  163. {
  164. return HRESULT_FROM_WIN32( GetLastError() );
  165. }
  166. else if( !psid )
  167. {
  168. return E_FAIL;
  169. }
  170. HRESULT hr = _AddPermissionToPath( pszPath, (SID*)psid, nAccess, bInheritFromParent, bOverwriteExisting, nInheritance );
  171. FreeSid( psid );
  172. return hr;
  173. }
  174. //
  175. // SAM Account version
  176. //
  177. inline HRESULT AddPermissionToPath( LPCTSTR pszPath,
  178. LPCTSTR pszSAM,
  179. UINT nAccess = FILE_ALL_ACCESS,
  180. BOOL bInheritFromParent = TRUE,
  181. BOOL bOverwriteExisting = FALSE,
  182. UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
  183. {
  184. if( !pszPath || !pszSAM ) return E_POINTER;
  185. if( (_tcslen(pszPath) == 0) || (_tcslen(pszSAM) == 0 ) ) return E_INVALIDARG;
  186. HRESULT hr = S_OK;
  187. DWORD dwSize = 0;
  188. DWORD dwDomainSize = 0;
  189. SID_NAME_USE snu;
  190. if( !LookupAccountName(NULL, pszSAM, NULL, &dwSize, NULL, &dwDomainSize, &snu) &&
  191. GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  192. {
  193. SID* psid = (SID*)new BYTE[dwSize];
  194. if( !psid )
  195. {
  196. return E_OUTOFMEMORY;
  197. }
  198. TCHAR* pszDomain = new TCHAR[dwDomainSize];
  199. if( !pszDomain )
  200. {
  201. delete[] psid;
  202. return E_OUTOFMEMORY;
  203. }
  204. if( LookupAccountName(NULL, pszSAM, psid, &dwSize, pszDomain, &dwDomainSize, &snu) )
  205. {
  206. hr = _AddPermissionToPath( pszPath, psid, nAccess, bInheritFromParent, bOverwriteExisting, nInheritance );
  207. }
  208. else
  209. {
  210. hr = HRESULT_FROM_WIN32( GetLastError() );
  211. }
  212. delete[] psid;
  213. delete[] pszDomain;
  214. }
  215. else
  216. {
  217. return E_FAIL;
  218. }
  219. return hr;
  220. }
  221. #endif // _FILEPERMS_H