Source code of Windows XP (NT5)
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.

427 lines
12 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. c2NtfAcl.c
  5. Abstract:
  6. NTFS File and Directory Security processing and display functions
  7. Author:
  8. Bob Watson (a-robw)
  9. Revision History:
  10. 23 Dec 94
  11. --*/
  12. #include <windows.h>
  13. #include <tchar.h>
  14. #include <stdio.h>
  15. #include <c2dll.h>
  16. #include <c2inc.h>
  17. #include <c2utils.h>
  18. #include <strings.h>
  19. #include "c2acls.h"
  20. #include "c2aclres.h"
  21. // define action codes here. They are only meaningful in the
  22. // context of this module.
  23. #define AC_NTFS_ACLS_MAKE_C2 1
  24. #define AC_NTFS_ACLS_MAKE_NOTC2 2
  25. #define SECURE C2DLL_C2
  26. #define FS_UNKNOWN 0x00000000
  27. #define FS_FAT 0x00000001
  28. #define FS_NTFS 0x00000002
  29. #define FS_HPFS 0x00000004
  30. static
  31. DWORD
  32. GetSystemDriveFileSystem (
  33. )
  34. {
  35. TCHAR szSystemDir[MAX_PATH];
  36. TCHAR szVolumeName[MAX_PATH];
  37. TCHAR szFileSystemName[MAX_PATH];
  38. DWORD dwVolumeSerialNumber;
  39. DWORD dwMaxComponentLength;
  40. DWORD dwFileSystemFlags;
  41. DWORD dwReturn = FS_UNKNOWN;
  42. if (GetSystemDirectory (szSystemDir, (sizeof(szSystemDir)/sizeof(TCHAR))) > 0) {
  43. // truncate path and just keep drive letter, colon & backslash
  44. szSystemDir[3] = 0;
  45. if (GetDriveType(szSystemDir) == DRIVE_FIXED) {
  46. // only check fixed disk volumes
  47. if (GetVolumeInformation(szSystemDir,
  48. szVolumeName,
  49. sizeof(szVolumeName) / sizeof(TCHAR),
  50. &dwVolumeSerialNumber,
  51. &dwMaxComponentLength,
  52. &dwFileSystemFlags,
  53. szFileSystemName,
  54. sizeof(szFileSystemName) / sizeof(TCHAR))) {
  55. // volume information returned so see if it's NOT NTFS..
  56. if (lstrcmpi(szFileSystemName,
  57. GetStringResource (GetDllInstance(), IDS_NTFS)) == 0) {
  58. dwReturn = FS_NTFS;
  59. } else if (lstrcmpi(szFileSystemName,
  60. GetStringResource (GetDllInstance(), IDS_FAT)) == 0) {
  61. dwReturn = FS_FAT;
  62. } else if (lstrcmpi(szFileSystemName,
  63. GetStringResource (GetDllInstance(), IDS_HPFS)) == 0) {
  64. dwReturn = FS_HPFS;
  65. } else {
  66. //return Unknown
  67. }
  68. } else {
  69. // unable to read volume information
  70. }
  71. } else {
  72. // unable to get drive type
  73. }
  74. } else {
  75. // unable to look up system dir
  76. }
  77. return dwReturn;
  78. }
  79. //static
  80. LONG
  81. ProcessNtfsInf (
  82. IN LPCTSTR szInfFileName
  83. )
  84. /*++
  85. Routine Description:
  86. Read the NTFS security INF file and update the registry key security
  87. Return Value:
  88. WIN32 status of function
  89. --*/
  90. {
  91. LONG lReturn;
  92. LONG lStatus;
  93. DWORD dwReturnSize;
  94. DWORD dwPathListSize;
  95. LPTSTR mszPathList;
  96. LPTSTR szThisPath;
  97. LPCTSTR szFilePath;
  98. TCHAR mszThisSection[SMALL_BUFFER_SIZE];
  99. DWORD dwDirFlags;
  100. PACL paclFile;
  101. PACL paclDir;
  102. SECURITY_DESCRIPTOR sdFile;
  103. SECURITY_DESCRIPTOR sdDir;
  104. if (FileExists(szInfFileName)) {
  105. // file found, so continue
  106. dwReturnSize = 0;
  107. dwPathListSize = 0;
  108. mszPathList = NULL;
  109. do {
  110. // allocate buffer to hold key list
  111. dwPathListSize += MAX_PATH * 1024; // add room for 1K keys
  112. // free any previous allocations
  113. GLOBAL_FREE_IF_ALLOC (mszPathList);
  114. mszPathList = (LPTSTR)GLOBAL_ALLOC(dwPathListSize * sizeof(TCHAR));
  115. // read the keys to process (i.e. get a list of the section
  116. // headers in the .ini file.
  117. dwReturnSize = GetPrivateProfileString (
  118. NULL, // list all sections
  119. NULL, // not used
  120. cmszEmptyString, // empty string for default,
  121. mszPathList,
  122. dwPathListSize, // buffer size in characters
  123. szInfFileName); // file name
  124. } while (dwReturnSize == (dwPathListSize -2)); // this value indicates truncation
  125. if (dwReturnSize != 0) {
  126. // process all file paths in list
  127. for (szThisPath = mszPathList;
  128. *szThisPath != 0;
  129. szThisPath += lstrlen(szThisPath)+1) {
  130. // read in all the ACEs for this key
  131. dwReturnSize = GetPrivateProfileSection (
  132. szThisPath,
  133. mszThisSection,
  134. SMALL_BUFFER_SIZE,
  135. szInfFileName);
  136. if (dwReturnSize != 0) {
  137. // make 2 security Descriptors, one to be assigned
  138. // to files (containing access for just the file)
  139. // and one for directories that have access for
  140. // directories themselves as well as the sub-items
  141. // (files and dirs)
  142. paclFile = (PACL)GLOBAL_ALLOC(SMALL_BUFFER_SIZE);
  143. paclDir = (PACL)GLOBAL_ALLOC(SMALL_BUFFER_SIZE);
  144. if ((paclFile != NULL) && (paclDir != NULL)){
  145. InitializeSecurityDescriptor (&sdFile,
  146. SECURITY_DESCRIPTOR_REVISION);
  147. InitializeSecurityDescriptor (&sdDir,
  148. SECURITY_DESCRIPTOR_REVISION);
  149. if (InitializeAcl(paclFile, SMALL_BUFFER_SIZE, ACL_REVISION) &&
  150. InitializeAcl(paclDir, SMALL_BUFFER_SIZE, ACL_REVISION)) {
  151. // make ACL from section
  152. szFilePath = GetFilePathFromHeader (
  153. szThisPath, &dwDirFlags);
  154. lStatus = MakeAclFromNtfsSection (
  155. mszThisSection,
  156. TRUE,
  157. paclDir);
  158. // add ACL to Security Descriptor
  159. SetSecurityDescriptorDacl (
  160. &sdDir,
  161. TRUE,
  162. paclDir,
  163. FALSE);
  164. lStatus = MakeAclFromNtfsSection (
  165. mszThisSection,
  166. FALSE,
  167. paclFile);
  168. // add ACL to Security Descriptor
  169. SetSecurityDescriptorDacl (
  170. &sdFile,
  171. TRUE,
  172. paclFile,
  173. FALSE);
  174. // DACL built now update key
  175. lStatus = SetNtfsFileSecurity (
  176. szFilePath,
  177. dwDirFlags,
  178. &sdDir,
  179. &sdFile);
  180. } else {
  181. // unable to initialize ACL
  182. }
  183. GLOBAL_FREE_IF_ALLOC (paclFile);
  184. GLOBAL_FREE_IF_ALLOC (paclDir);
  185. } else {
  186. // unable to allocate ACL buffer
  187. }
  188. } else {
  189. // no entries found in this section
  190. }
  191. } // end while scanning list of sections
  192. } else {
  193. // no section list returned
  194. }
  195. GLOBAL_FREE_IF_ALLOC (mszPathList);
  196. } else {
  197. lReturn = ERROR_FILE_NOT_FOUND;
  198. }
  199. return lReturn;
  200. }
  201. LONG
  202. C2QueryNtfsFiles (
  203. IN LPARAM lParam
  204. )
  205. /*++
  206. Routine Description:
  207. Function called to find out the current state of this configuration
  208. item. This function reads the current state of the item and
  209. sets the C2 Compliance flag and the Status string to reflect
  210. the current value of the configuration item.
  211. For the moment, the registry is not read and compared so no status
  212. is returned.
  213. Arguments:
  214. Pointer to the Dll data block passed as an LPARAM.
  215. ReturnValue:
  216. ERROR_SUCCESS if the function succeeds otherwise a
  217. WIN32 error is returned if an error occurs
  218. --*/
  219. {
  220. PC2DLL_DATA pC2Data;
  221. if (lParam != 0) {
  222. pC2Data = (PC2DLL_DATA)lParam;
  223. // return message based on flag for now
  224. pC2Data->lC2Compliance = C2DLL_UNKNOWN;
  225. lstrcpy (pC2Data->szStatusName,
  226. GetStringResource (GetDllInstance(), IDS_UNABLE_READ));
  227. return ERROR_SUCCESS;
  228. } else {
  229. return ERROR_BAD_ARGUMENTS;
  230. }
  231. }
  232. LONG
  233. C2SetNtfsFiles (
  234. IN LPARAM lParam
  235. )
  236. /*++
  237. Routine Description:
  238. Function called to change the current state of this configuration
  239. item based on an action code passed in the DLL data block. If
  240. this function successfully sets the state of the configuration
  241. item, then the C2 Compliance flag and the Status string to reflect
  242. the new value of the configuration item.
  243. Arguments:
  244. Pointer to the Dll data block passed as an LPARAM.
  245. ReturnValue:
  246. ERROR_SUCCESS if the function succeeds otherwise a
  247. WIN32 error is returned if an error occurs
  248. --*/
  249. {
  250. PC2DLL_DATA pC2Data;
  251. TCHAR szInfFileName[MAX_PATH];
  252. if (lParam != 0) {
  253. pC2Data = (PC2DLL_DATA)lParam;
  254. switch (pC2Data->lActionCode ) {
  255. case AC_NTFS_ACLS_MAKE_C2:
  256. if (DisplayDllMessageBox(
  257. pC2Data->hWnd,
  258. IDS_NTFS_ACLS_CONFIRM,
  259. IDS_NTFS_ACLS_CAPTION,
  260. MBOKCANCEL_QUESTION) == IDOK) {
  261. SET_WAIT_CURSOR;
  262. if (GetFilePath(
  263. GetStringResource(GetDllInstance(), IDS_NTFS_ACL_INF),
  264. szInfFileName)) {
  265. if (ProcessNtfsInf(szInfFileName) == ERROR_SUCCESS) {
  266. pC2Data->lC2Compliance = SECURE;
  267. lstrcpy (pC2Data->szStatusName,
  268. GetStringResource(GetDllInstance(), IDS_NTFS_ACLS_COMPLY));
  269. } else {
  270. // unable to set acl security
  271. }
  272. } else {
  273. // unable to get acl file path
  274. }
  275. SET_ARROW_CURSOR;
  276. } else {
  277. // user opted not to set acls
  278. }
  279. break;
  280. default:
  281. // no change;
  282. break;
  283. }
  284. } else {
  285. return ERROR_BAD_ARGUMENTS;
  286. }
  287. return ERROR_SUCCESS;
  288. }
  289. LONG
  290. C2DisplayNtfsFiles (
  291. IN LPARAM lParam
  292. )
  293. /*++
  294. Routine Description:
  295. Function called to display more information on the configuration
  296. item and provide the user with the option to change the current
  297. setting (if appropriate). If the User "OK's" out of the UI,
  298. then the action code field in the DLL data block is set to the
  299. appropriate (and configuration item-specific) action code so the
  300. "Set" function can be called to perform the desired action. If
  301. the user Cancels out of the UI, then the Action code field is
  302. set to 0 (no action) and no action is performed.
  303. Arguments:
  304. Pointer to the Dll data block passed as an LPARAM.
  305. ReturnValue:
  306. ERROR_SUCCESS if the function succeeds otherwise a
  307. WIN32 error is returned if an error occurs
  308. --*/
  309. {
  310. PC2DLL_DATA pC2Data;
  311. if (lParam != 0) {
  312. pC2Data = (PC2DLL_DATA)lParam;
  313. } else {
  314. return ERROR_BAD_ARGUMENTS;
  315. }
  316. if (GetSystemDriveFileSystem() == FS_NTFS) {
  317. if (pC2Data->lC2Compliance == SECURE) {
  318. DisplayDllMessageBox (
  319. pC2Data->hWnd,
  320. IDS_NTFS_ACLS_COMPLY,
  321. IDS_NTFS_ACLS_CAPTION,
  322. MBOK_INFO);
  323. } else {
  324. if (DisplayDllMessageBox (
  325. pC2Data->hWnd,
  326. IDS_NTFS_ACLS_QUERY_SET,
  327. IDS_NTFS_ACLS_CAPTION,
  328. MBOKCANCEL_QUESTION) == IDOK) {
  329. pC2Data->lActionCode = AC_NTFS_ACLS_MAKE_C2;
  330. pC2Data->lActionValue = 0; // not used
  331. } else {
  332. pC2Data->lActionCode = 0; // no action
  333. pC2Data->lActionValue = 0; // not used
  334. }
  335. }
  336. } else {
  337. DisplayDllMessageBox (
  338. pC2Data->hWnd,
  339. IDS_NTFS_ACLS_NOT_NTFS,
  340. IDS_NTFS_ACLS_CAPTION,
  341. MBOK_EXCLAIM);
  342. pC2Data->lActionCode = 0; // no action
  343. pC2Data->lActionValue = 0; // not used
  344. }
  345. return ERROR_SUCCESS;
  346. }