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.

531 lines
14 KiB

  1. /*************************************************************************
  2. *
  3. * file.c
  4. *
  5. * Process the security on a file
  6. *
  7. * Copyright Microsoft, 1998
  8. *
  9. *
  10. *
  11. *************************************************************************/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <process.h>
  18. #include <winsta.h>
  19. #include <syslib.h>
  20. #include "security.h"
  21. #if DBG
  22. ULONG
  23. DbgPrint(
  24. PCH Format,
  25. ...
  26. );
  27. #define DBGPRINT(x) DbgPrint x
  28. #if DBGTRACE
  29. #define TRACE0(x) DbgPrint x
  30. #define TRACE1(x) DbgPrint x
  31. #else
  32. #define TRACE0(x)
  33. #define TRACE1(x)
  34. #endif
  35. #else
  36. #define DBGPRINT(x)
  37. #define TRACE0(x)
  38. #define TRACE1(x)
  39. #endif
  40. // External data
  41. // data.c
  42. extern ACCESS_MASK DeniedAccess;
  43. // security.c
  44. extern PSID SeCreatorOwnerSid;
  45. extern PSID SeCreatorGroupSid;
  46. FILE_RESULT
  47. xxxSetFileSecurity(
  48. PWCHAR pFile
  49. );
  50. /*****************************************************************************
  51. *
  52. * xxxProcessFile
  53. *
  54. * Process the given file for access security holes
  55. *
  56. * ENTRY:
  57. * Param1 (input/output)
  58. * Comments
  59. *
  60. * EXIT:
  61. * STATUS_SUCCESS - no error
  62. *
  63. ****************************************************************************/
  64. FILE_RESULT
  65. xxxProcessFile(
  66. PWCHAR pFile,
  67. PWIN32_FIND_DATAW p,
  68. DWORD Level,
  69. DWORD Index
  70. )
  71. {
  72. FILE_RESULT rc;
  73. rc = xxxSetFileSecurity( pFile );
  74. return( rc );
  75. }
  76. /*****************************************************************************
  77. *
  78. * xxxSetFileSecurity
  79. *
  80. * Set the security properties for the given file
  81. *
  82. * ENTRY:
  83. * Param1 (input/output)
  84. * Comments
  85. *
  86. * EXIT:
  87. * STATUS_SUCCESS - no error
  88. *
  89. ****************************************************************************/
  90. FILE_RESULT
  91. xxxSetFileSecurity(
  92. PWCHAR pFile
  93. )
  94. {
  95. BOOL rc;
  96. BOOL DaclPresent;
  97. BOOL Default;
  98. BOOL OwnerDefaulted;
  99. BOOL GroupDefaulted;
  100. FILE_RESULT Result, ReturnResult;
  101. DWORD Size, Index;
  102. PACL pACL = NULL;
  103. PVOID pAce = NULL;
  104. SECURITY_INFORMATION Info = 0;
  105. DWORD Error;
  106. PSECURITY_DESCRIPTOR pSelfSd = NULL;
  107. // Absolute SD values
  108. PSECURITY_DESCRIPTOR pAbsSd = NULL;
  109. DWORD AbsSdSize = 0;
  110. PACL pAbsAcl = NULL;
  111. DWORD AbsAclSize = 0;
  112. PACL pAbsSacl = NULL;
  113. DWORD AbsSaclSize = 0;
  114. PSID pAbsOwner = NULL;
  115. DWORD AbsOwnerSize = 0;
  116. PSID pAbsGroup = NULL;
  117. DWORD AbsGroupSize = 0;
  118. DBGPRINT(( "entering xxxSetFileSecurity(pFile=%ws)\n", pFile ));
  119. /*
  120. * Get the files current security descriptor
  121. */
  122. Size = 0;
  123. rc = GetFileSecurityW(
  124. pFile,
  125. DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
  126. NULL, // pSelfSd
  127. 0,
  128. &Size
  129. );
  130. if( rc ) {
  131. Error = GetLastError();
  132. ReportFileResult(
  133. FileAccessErrorUserFormat,
  134. 0, // Access
  135. pFile,
  136. NULL, // pAccountName
  137. NULL, // pDomainName
  138. "%d has no DACL",
  139. Error
  140. );
  141. DBGPRINT(( "leaving xxxSetFileSecurity(1); returning=FileAccessError\n" ));
  142. return( FileAccessError );
  143. }
  144. else {
  145. pSelfSd = LocalAlloc( LMEM_FIXED, Size );
  146. if( pSelfSd == NULL ) {
  147. ReportFileResult(
  148. FileAccessErrorUserFormat,
  149. 0, // Access
  150. pFile,
  151. NULL, // pAccountName
  152. NULL, // pDomainName
  153. "Out of memory skipped entry"
  154. );
  155. DBGPRINT(( "leaving xxxSetFileSecurity(2); returning=0\n" ));
  156. return( FALSE );
  157. }
  158. rc = GetFileSecurityW(
  159. pFile,
  160. DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
  161. pSelfSd,
  162. Size,
  163. &Size
  164. );
  165. if( !rc ) {
  166. Error = GetLastError();
  167. ReportFileResult(
  168. FileAccessErrorUserFormat,
  169. 0, // Access
  170. pFile,
  171. NULL, // pAccountName
  172. NULL, // pDomainName
  173. "%d Could not get DACL",
  174. Error
  175. );
  176. LocalFree( pSelfSd );
  177. DBGPRINT(( "leaving xxxSetFileSecurity(3); returning=FileAccessError\n" ));
  178. return( FileAccessError );
  179. }
  180. }
  181. //
  182. // Now convert the self relative SD to an absolute one.
  183. //
  184. rc = MakeAbsoluteSD (
  185. pSelfSd,
  186. pAbsSd,
  187. &AbsSdSize,
  188. pAbsAcl,
  189. &AbsAclSize,
  190. pAbsSacl,
  191. &AbsSaclSize,
  192. pAbsOwner,
  193. &AbsOwnerSize,
  194. pAbsGroup,
  195. &AbsGroupSize
  196. );
  197. if( !rc ) {
  198. Error = GetLastError();
  199. if( Error != ERROR_INSUFFICIENT_BUFFER ) {
  200. ReportFileResult(
  201. FileAccessErrorUserFormat,
  202. 0, // Access
  203. pFile,
  204. NULL, // pAccountName
  205. NULL, // pDomainName
  206. "%d converting SECURITY_DESCRIPTOR",
  207. Error
  208. );
  209. LocalFree( pSelfSd );
  210. DBGPRINT(( "leaving xxxSetFileSecurity(4); returning=FileAccessError\n" ));
  211. return( FileAccessError );
  212. }
  213. // Allocate buffers and now really get the SD
  214. pAbsSd = LocalAlloc( LMEM_FIXED, AbsSdSize );
  215. pAbsAcl = LocalAlloc( LMEM_FIXED, AbsAclSize );
  216. pAbsSacl = LocalAlloc( LMEM_FIXED, AbsSaclSize );
  217. pAbsOwner = LocalAlloc( LMEM_FIXED, AbsOwnerSize );
  218. pAbsGroup = LocalAlloc( LMEM_FIXED, AbsGroupSize );
  219. if( !( pAbsSd && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup ) ) {
  220. ReportFileResult(
  221. FileAccessErrorUserFormat,
  222. 0, // Access
  223. pFile,
  224. NULL, // pAccountName
  225. NULL, // pDomainName
  226. "Allocating memory"
  227. );
  228. if( pAbsSd ) LocalFree( pAbsSd );
  229. if( pAbsAcl ) LocalFree( pAbsAcl );
  230. if( pAbsSacl ) LocalFree( pAbsSacl );
  231. if( pAbsOwner ) LocalFree( pAbsOwner );
  232. if( pAbsGroup ) LocalFree( pAbsGroup );
  233. LocalFree( pSelfSd );
  234. DBGPRINT(( "leaving xxxSetFileSecurity(5); returning=FileAccessError\n" ));
  235. return( FileAccessError );
  236. }
  237. // Try it again
  238. rc = MakeAbsoluteSD (
  239. pSelfSd,
  240. pAbsSd,
  241. &AbsSdSize,
  242. pAbsAcl,
  243. &AbsAclSize,
  244. pAbsSacl,
  245. &AbsSaclSize,
  246. pAbsOwner,
  247. &AbsOwnerSize,
  248. pAbsGroup,
  249. &AbsGroupSize
  250. );
  251. if( !rc ) {
  252. Error = GetLastError();
  253. ReportFileResult(
  254. FileAccessErrorUserFormat,
  255. 0, // Access
  256. pFile,
  257. NULL, // pAccountName
  258. NULL, // pDomainName
  259. "%d Making ABSOLUTE SD",
  260. Error
  261. );
  262. if( pAbsSd ) LocalFree( pAbsSd );
  263. if( pAbsAcl ) LocalFree( pAbsAcl );
  264. if( pAbsSacl ) LocalFree( pAbsSacl );
  265. if( pAbsOwner ) LocalFree( pAbsOwner );
  266. if( pAbsGroup ) LocalFree( pAbsGroup );
  267. LocalFree( pSelfSd );
  268. DBGPRINT(( "leaving xxxSetFileSecurity(6); returning=FileAccessError\n" ));
  269. return( FileAccessError );
  270. }
  271. }
  272. //
  273. // Get our new trusted ACL
  274. //
  275. pACL = GetSecureAcl();
  276. if( pACL == NULL ) {
  277. ReportFileResult(
  278. FileAccessErrorUserFormat,
  279. 0, // Access
  280. pFile,
  281. NULL, // pAccountName
  282. NULL, // pDomainName
  283. "Could not get New ACL"
  284. );
  285. if( pAbsSd ) LocalFree( pAbsSd );
  286. if( pAbsAcl ) LocalFree( pAbsAcl );
  287. if( pAbsSacl ) LocalFree( pAbsSacl );
  288. if( pAbsOwner ) LocalFree( pAbsOwner );
  289. if( pAbsGroup ) LocalFree( pAbsGroup );
  290. LocalFree( pSelfSd );
  291. DBGPRINT(( "leaving xxxSetFileSecurity(7); returning=FileAccessError\n" ));
  292. return( FileAccessError );
  293. }
  294. //
  295. // Now set the trusted ACL onto the security descriptor
  296. //
  297. rc = SetSecurityDescriptorDacl(
  298. pAbsSd,
  299. TRUE, // DACL present
  300. pACL,
  301. FALSE // Not default
  302. );
  303. if( !rc ) {
  304. Error = GetLastError();
  305. ReportFileResult(
  306. FileAccessErrorUserFormat,
  307. 0, // Access
  308. pFile,
  309. NULL, // pAccountName
  310. NULL, // pDomainName
  311. "Could not set new ACL in Security Descriptor %d",
  312. Error
  313. );
  314. if( pAbsSd ) LocalFree( pAbsSd );
  315. if( pAbsAcl ) LocalFree( pAbsAcl );
  316. if( pAbsSacl ) LocalFree( pAbsSacl );
  317. if( pAbsOwner ) LocalFree( pAbsOwner );
  318. if( pAbsGroup ) LocalFree( pAbsGroup );
  319. LocalFree( pSelfSd );
  320. DBGPRINT(( "leaving xxxSetFileSecurity(8); returning=FileAccessError\n" ));
  321. return( FileAccessError );
  322. }
  323. Info |= DACL_SECURITY_INFORMATION;
  324. //
  325. // If the owner is not one of the admins, we will grab
  326. // it and local admin will now own it
  327. //
  328. if( pAbsOwner && !IsAllowSid( pAbsOwner ) ) {
  329. // Make the local admin own it
  330. rc = SetSecurityDescriptorOwner(
  331. pAbsSd,
  332. GetAdminSid(),
  333. FALSE // Not defaulted
  334. );
  335. if( !rc ) {
  336. Error = GetLastError();
  337. ReportFileResult(
  338. FileAccessErrorUserFormat,
  339. 0, // Access
  340. pFile,
  341. NULL, // pAccountName
  342. NULL, // pDomainName
  343. "Could not set file owner %d",
  344. Error
  345. );
  346. if( pAbsSd ) LocalFree( pAbsSd );
  347. if( pAbsAcl ) LocalFree( pAbsAcl );
  348. if( pAbsSacl ) LocalFree( pAbsSacl );
  349. if( pAbsOwner ) LocalFree( pAbsOwner );
  350. if( pAbsGroup ) LocalFree( pAbsGroup );
  351. LocalFree( pSelfSd );
  352. DBGPRINT(( "leaving xxxSetFileSecurity(9); returning=FileAccessError\n" ));
  353. return( FileAccessError );
  354. }
  355. else {
  356. Info |= OWNER_SECURITY_INFORMATION;
  357. }
  358. }
  359. #ifdef notdef // WWM - don't worry about the group
  360. if( pAbsGroup && !IsAllowSid( pAbsGroup ) ) {
  361. // Make the local admin group own it
  362. rc = SetSecurityDescriptorGroup(
  363. pAbsSd,
  364. GetLocalAdminGroupSid(),
  365. FALSE // Not defaulted
  366. );
  367. if( !rc ) {
  368. Error = GetLastError();
  369. ReportFileResult(
  370. FileAccessErrorUserFormat,
  371. 0, // Access
  372. pFile,
  373. NULL, // pAccountName
  374. NULL, // pDomainName
  375. "Could not set file group %d",
  376. Error
  377. );
  378. if( pAbsSd ) LocalFree( pAbsSd );
  379. if( pAbsAcl ) LocalFree( pAbsAcl );
  380. if( pAbsSacl ) LocalFree( pAbsSacl );
  381. if( pAbsOwner ) LocalFree( pAbsOwner );
  382. if( pAbsGroup ) LocalFree( pAbsGroup );
  383. LocalFree( pSelfSd );
  384. DBGPRINT(( "leaving xxxSetFileSecurity(10); returning=FileAccessError\n" ));
  385. return( FileAccessError );
  386. }
  387. else {
  388. Info |= GROUP_SECURITY_INFORMATION;
  389. }
  390. }
  391. #endif
  392. //
  393. // Now set the new security descriptor onto the file
  394. //
  395. rc = SetFileSecurityW(
  396. pFile,
  397. Info,
  398. pAbsSd
  399. );
  400. if( !rc ) {
  401. Error = GetLastError();
  402. ReportFileResult(
  403. FileAccessErrorUserFormat,
  404. 0, // Access
  405. pFile,
  406. NULL, // pAccountName
  407. NULL, // pDomainName
  408. "Could not set new Security Descriptor %d",
  409. Error
  410. );
  411. if( pAbsSd ) LocalFree( pAbsSd );
  412. if( pAbsAcl ) LocalFree( pAbsAcl );
  413. if( pAbsSacl ) LocalFree( pAbsSacl );
  414. if( pAbsOwner ) LocalFree( pAbsOwner );
  415. if( pAbsGroup ) LocalFree( pAbsGroup );
  416. LocalFree( pSelfSd );
  417. DBGPRINT(( "leaving xxxSetFileSecurity(11); returning=FileAccessError\n" ));
  418. return( FileAccessError );
  419. }
  420. if( pAbsSd ) LocalFree( pAbsSd );
  421. if( pAbsAcl ) LocalFree( pAbsAcl );
  422. if( pAbsSacl ) LocalFree( pAbsSacl );
  423. if( pAbsOwner ) LocalFree( pAbsOwner );
  424. if( pAbsGroup ) LocalFree( pAbsGroup );
  425. LocalFree( pSelfSd );
  426. DBGPRINT(( "leaving xxxSetFileSecurity(12); returning=FileOk\n" ));
  427. return( FileOk );
  428. }
  429. #ifdef notdef
  430. //
  431. // Get the owner SID
  432. //
  433. rc = GetSecurityDescriptorOwner(
  434. pSelfSd,
  435. &Owner,
  436. &OwnerDefaulted
  437. );
  438. if( !rc ) {
  439. // No owner info
  440. Owner = NULL;
  441. }
  442. //
  443. // Get the group SID
  444. //
  445. rc = GetSecurityDescriptorGroup(
  446. pSelfSd,
  447. &Group,
  448. &GroupDefaulted
  449. );
  450. if( !rc ) {
  451. // No group info
  452. Group = NULL;
  453. }
  454. #endif