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.

223 lines
4.9 KiB

  1. //
  2. // Copyright (C) 2000-2002, Microsoft Corporation
  3. //
  4. // File: filesecurity.c
  5. //
  6. // Contents: miscellaneous dfs functions.
  7. //
  8. // History: April 16 2002, Author: Rohanp
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <malloc.h>
  18. #include <dsgetdc.h>
  19. #include <lm.h>
  20. #include <dfsheader.h>
  21. #include <dfsmisc.h>
  22. #include <shellapi.h>
  23. #include <Aclapi.h>
  24. #include <authz.h>
  25. #include <lm.h>
  26. extern
  27. DWORD
  28. DfsIsAccessGrantedBySid(DWORD dwDesiredAccess,
  29. PSECURITY_DESCRIPTOR pSD,
  30. PSID TheSID,
  31. GENERIC_MAPPING * DfsGenericMapping);
  32. GENERIC_MAPPING DfsFileGenericMapping = {
  33. FILE_GENERIC_READ, // Generic read
  34. FILE_GENERIC_WRITE, // Generic write
  35. FILE_GENERIC_EXECUTE,
  36. FILE_ALL_ACCESS
  37. };
  38. DWORD
  39. DfsGetFileSecurityByHandle(IN HANDLE hFile,
  40. OUT PSECURITY_DESCRIPTOR *ppSD)
  41. {
  42. DWORD dwErr = ERROR_SUCCESS;
  43. NTSTATUS Status = 0;
  44. ULONG cNeeded = 0;
  45. SECURITY_INFORMATION SeInfo;
  46. SeInfo = DACL_SECURITY_INFORMATION |GROUP_SECURITY_INFORMATION |OWNER_SECURITY_INFORMATION;
  47. Status = NtQuerySecurityObject(hFile,
  48. SeInfo,
  49. *ppSD,
  50. 0,
  51. &cNeeded);
  52. if(!NT_SUCCESS(Status))
  53. {
  54. if(Status == STATUS_BUFFER_TOO_SMALL)
  55. {
  56. Status = STATUS_SUCCESS;
  57. }
  58. }
  59. dwErr = RtlNtStatusToDosError(Status);
  60. //
  61. // Now, the actual read
  62. //
  63. if(dwErr == ERROR_SUCCESS)
  64. {
  65. *ppSD = (PISECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, cNeeded);
  66. if(*ppSD == NULL)
  67. {
  68. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  69. }
  70. else
  71. {
  72. Status = NtQuerySecurityObject(hFile,
  73. SeInfo,
  74. *ppSD,
  75. cNeeded,
  76. &cNeeded);
  77. }
  78. }
  79. return(dwErr);
  80. }
  81. DWORD
  82. DfsGetFileSecurityByName(PUNICODE_STRING DirectoryName,
  83. PSECURITY_DESCRIPTOR *pSD2)
  84. {
  85. DWORD Status = 0;
  86. ULONG cpsd = 0;
  87. PSECURITY_DESCRIPTOR pSD = NULL;
  88. LPCTSTR pDir = NULL;
  89. pDir = &DirectoryName->Buffer[4];
  90. if (!GetFileSecurity((LPCTSTR)pDir,
  91. DACL_SECURITY_INFORMATION |
  92. GROUP_SECURITY_INFORMATION |
  93. OWNER_SECURITY_INFORMATION,
  94. NULL,
  95. 0,
  96. &cpsd) )
  97. {
  98. Status = GetLastError();
  99. if (ERROR_INSUFFICIENT_BUFFER == Status)
  100. {
  101. if ( NULL == ( pSD = (PSECURITY_DESCRIPTOR )LocalAlloc(LMEM_FIXED, cpsd)))
  102. {
  103. return(ERROR_NOT_ENOUGH_MEMORY);
  104. }
  105. Status = 0;
  106. if (!GetFileSecurity((LPCTSTR)pDir,
  107. DACL_SECURITY_INFORMATION |
  108. GROUP_SECURITY_INFORMATION |
  109. OWNER_SECURITY_INFORMATION,
  110. pSD,
  111. cpsd,
  112. &cpsd) )
  113. {
  114. Status = GetLastError();
  115. }
  116. }
  117. }
  118. *pSD2 = pSD;
  119. return Status;
  120. }
  121. DWORD
  122. DoesLocalSystemHaveWriteAccess(PSECURITY_DESCRIPTOR pSD)
  123. {
  124. DWORD SidSize = 0;
  125. DWORD Status = 0;
  126. DWORD dwError = 0;
  127. DWORD dwDesiredAccess = 0;
  128. BOOL RetVal = FALSE;
  129. PSID TheSID = NULL;
  130. SidSize = SECURITY_MAX_SID_SIZE;
  131. // Allocate enough memory for the largest possible SID
  132. TheSID = LocalAlloc(LMEM_FIXED, SidSize);
  133. if(!TheSID)
  134. {
  135. Status = GetLastError();
  136. goto Exit;
  137. }
  138. if(!CreateWellKnownSid(WinLocalSystemSid, NULL, TheSID, &SidSize))
  139. {
  140. Status = GetLastError();
  141. goto Exit;
  142. }
  143. Status = DfsIsAccessGrantedBySid(GENERIC_WRITE,
  144. pSD,
  145. TheSID,
  146. &DfsFileGenericMapping);
  147. Exit:
  148. if(TheSID)
  149. {
  150. LocalFree (TheSID);
  151. }
  152. return Status;
  153. }
  154. DWORD
  155. CheckDirectoryForLocalSystemAccess(PUNICODE_STRING DirectoryName)
  156. {
  157. DWORD Status = 0;
  158. PSECURITY_DESCRIPTOR pSD = NULL;
  159. Status = DfsGetFileSecurityByName(DirectoryName,
  160. &pSD);
  161. if(Status == ERROR_SUCCESS)
  162. {
  163. Status = DoesLocalSystemHaveWriteAccess(pSD);
  164. }
  165. if(pSD)
  166. {
  167. LocalFree(pSD);
  168. }
  169. return Status;
  170. }