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.

446 lines
11 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. test.cpp
  5. Abstract:
  6. Utility which allows to dump a file DACL in ADL or set a file DACL from ADL
  7. Author:
  8. t-eugenz - August 2000
  9. Environment:
  10. User mode only.
  11. Revision History:
  12. Created - August 2000
  13. --*/
  14. #include "adl.h"
  15. //
  16. // Various file rights
  17. // More general rights have priority
  18. //
  19. ADL_MASK_STRING MaskStringMap[] =
  20. {
  21. { (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | WRITE_DAC
  22. | WRITE_OWNER | READ_CONTROL | DELETE) & ~SYNCHRONIZE , L"full control" },
  23. { FILE_GENERIC_READ & ~SYNCHRONIZE, L"read" },
  24. { FILE_GENERIC_WRITE & ~SYNCHRONIZE, L"write" },
  25. { FILE_GENERIC_EXECUTE & ~SYNCHRONIZE, L"execute" },
  26. { DELETE & ~SYNCHRONIZE, L"delete" },
  27. { READ_CONTROL, L"read control"},
  28. { WRITE_DAC, L"write dac"},
  29. { WRITE_OWNER, L"write owner" },
  30. { SYNCHRONIZE, L"synchronize" },
  31. { FILE_READ_DATA, L"read data" },
  32. { FILE_WRITE_DATA, L"write data" },
  33. { FILE_APPEND_DATA, L"append data" },
  34. { FILE_READ_EA, L"read extended attributes" },
  35. { FILE_WRITE_EA, L"write extended attributes" },
  36. { FILE_EXECUTE, L"file execute" },
  37. { FILE_READ_ATTRIBUTES, L"read attributes" },
  38. { FILE_WRITE_ATTRIBUTES, L"write attributes" },
  39. { 0, NULL }
  40. };
  41. //
  42. // Representation of the English version of ADL
  43. //
  44. ADL_LANGUAGE_SPEC lEnglish =
  45. {
  46. TK_LANG_ENGLISH,
  47. 0,
  48. L' ',
  49. L'\t',
  50. L'\n',
  51. L'\r',
  52. L'"',
  53. L',',
  54. L';',
  55. L'(',
  56. L')',
  57. L'@',
  58. L'\\',
  59. L'.',
  60. 0,
  61. L"and",
  62. L"except",
  63. L"on",
  64. L"allowed",
  65. L"as",
  66. L"this file",
  67. L"subfolders",
  68. L"files",
  69. L"subfolders and files",
  70. L"noprop"
  71. };
  72. ADL_PARSER_CONTROL EnglishFileParser =
  73. {
  74. &lEnglish,
  75. MaskStringMap,
  76. ACCESS_SYSTEM_SECURITY | MAXIMUM_ALLOWED,
  77. SYNCHRONIZE
  78. };
  79. //
  80. // Error handler
  81. //
  82. void HandleError(AdlStatement::ADL_ERROR_TYPE adlErr, const AdlToken *pTok)
  83. {
  84. switch(adlErr)
  85. {
  86. //
  87. // Errors that should not happen unless there is a problem with the
  88. // system or the user makes a mistake
  89. //
  90. case AdlStatement::ERROR_FATAL_LEXER_ERROR:
  91. case AdlStatement::ERROR_FATAL_PARSER_ERROR:
  92. case AdlStatement::ERROR_FATAL_ACL_CONVERT_ERROR:
  93. case AdlStatement::ERROR_OUT_OF_MEMORY:
  94. case AdlStatement::ERROR_ACL_API_FAILED:
  95. case AdlStatement::ERROR_NOT_INITIALIZED:
  96. wprintf(L"\n\nFatal internal error, Errorcode %u, THIS IS BAD\n\n", adlErr);
  97. break;
  98. case AdlStatement::ERROR_LSA_FAILED:
  99. wprintf(L"\n\nError: LSA failed. Unable to resolve user information\n\n");
  100. break;
  101. //
  102. // Input-related grammar errors: no token supplied
  103. //
  104. case AdlStatement::ERROR_UNTERMINATED_STRING:
  105. wprintf(L"\n\nError: unmatched quote in the input\n\n");
  106. break;
  107. case AdlStatement::ERROR_UNKNOWN_ACE_TYPE:
  108. wprintf(L"\n\nError: Unknown ACE type encountered\n\n");
  109. break;
  110. case AdlStatement::ERROR_IMPERSONATION_UNSUPPORTED:
  111. wprintf(L"\n\nError: Impersonation is currently not supported in ADL\n\n");
  112. break;
  113. case AdlStatement::ERROR_INVALID_PARSER_CONTROL:
  114. wprintf(L"\n\nError: The specified laanguage type is not supported\n\n");
  115. break;
  116. //
  117. // For this error, the last read token is supplied
  118. //
  119. case AdlStatement::ERROR_NOT_IN_LANGUAGE:
  120. wprintf(L"\n\nError, invalid ADL statement, did not expect '%s',\n\
  121. which was found between characters %u and %u\n\n", pTok->GetValue(),
  122. pTok->GetStart(), pTok->GetEnd());
  123. break;
  124. //
  125. // Input-related semantic errors
  126. //
  127. //
  128. // For these errors, the offending token is supplied
  129. //
  130. case AdlStatement::ERROR_UNKNOWN_USER:
  131. wprintf(L"\n\nError, unknown user: ");
  132. if( pTok->GetOptValue() != NULL )
  133. {
  134. wprintf(L"'%s%c%s' ", pTok->GetValue(), lEnglish.CH_AT, pTok->GetOptValue());
  135. }
  136. else
  137. {
  138. wprintf(L"'%s' ", pTok->GetValue());
  139. }
  140. wprintf(L"found between characters %u and %u\n\n", pTok->GetStart(), pTok->GetEnd());
  141. break;
  142. case AdlStatement::ERROR_UNKNOWN_PERMISSION:
  143. wprintf(L"\n\nError, unknown permission: '%s' \
  144. found between characters %u and %u\n\n",
  145. pTok->GetValue(), pTok->GetStart(), pTok->GetEnd());
  146. break;
  147. case AdlStatement::ERROR_INVALID_USERNAME:
  148. wprintf(L"\n\nError, invalid username string: '%s' \
  149. found between characters %u and %u\n\n",
  150. pTok->GetValue(), pTok->GetStart(), pTok->GetEnd());
  151. break;
  152. case AdlStatement::ERROR_INVALID_DOMAIN:
  153. wprintf(L"\n\nError, invalid domain name string: '%s' \
  154. found between characters %u and %u\n\n",
  155. pTok->GetValue(), pTok->GetStart(), pTok->GetEnd());
  156. break;
  157. case AdlStatement::ERROR_INVALID_OBJECT:
  158. wprintf(L"\n\nError, invalid object specifier: '%s' \
  159. found between characters %u and %u\n\n",
  160. pTok->GetValue(), pTok->GetStart(), pTok->GetEnd());
  161. break;
  162. //
  163. // Other errors with no token supplied
  164. //
  165. case AdlStatement::ERROR_UNKNOWN_SID:
  166. wprintf(L"\n\nError: SID encountered which could not be resolved to a name\n\n");
  167. break;
  168. case AdlStatement::ERROR_UNKNOWN_ACCESS_MASK:
  169. wprintf(L"\n\nError: Access mask contains unknown bit\n\n");
  170. break;
  171. case AdlStatement::ERROR_INEXPRESSIBLE_ACL:
  172. wprintf(L"\n\nError: This DACL cannot be expressed in ADL\n\n");
  173. break;
  174. default:
  175. wprintf(L"\n\nUNKNOWN Error code: %u, THIS IS VERY BAD\n\n", adlErr);
  176. break;
  177. }
  178. }
  179. //
  180. // -dump Filename
  181. //
  182. void DumpDaclToAdl(int argc, WCHAR *argv[]) {
  183. DWORD dwErr;
  184. if(argc != 3)
  185. {
  186. wprintf(L"\nUsage:\n\n%s -dump <target>\n\n", argv[0]);
  187. exit(1);
  188. }
  189. PSECURITY_DESCRIPTOR pSD;
  190. SECURITY_INFORMATION SecInfo = DACL_SECURITY_INFORMATION;
  191. DWORD dwLengthNeeded;
  192. GetFileSecurity(
  193. argv[2],
  194. SecInfo,
  195. NULL,
  196. 0,
  197. &dwLengthNeeded);
  198. pSD = (PSECURITY_DESCRIPTOR) new BYTE[dwLengthNeeded];
  199. dwErr = GetFileSecurity(
  200. argv[2],
  201. SecInfo,
  202. pSD,
  203. dwLengthNeeded,
  204. &dwLengthNeeded);
  205. if( dwErr == 0)
  206. {
  207. dwErr = GetLastError();
  208. wprintf(L"GetFileSecurity failed on file '%s' with error %u, 0x%x\n",
  209. argv[2], dwErr, dwErr);
  210. exit(5);
  211. }
  212. PACL pDacl;
  213. BOOL fDaclPresent;
  214. BOOL fDaclDefaulted;
  215. GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pDacl, &fDaclDefaulted);
  216. if( !fDaclPresent || pDacl == NULL )
  217. {
  218. wprintf(L"Security descriptor of '%s' does not contain a DACL",argv[2]);
  219. exit(6);
  220. }
  221. AdlStatement *stat;
  222. try
  223. {
  224. stat = new AdlStatement(&EnglishFileParser);
  225. wstring ws;
  226. stat->ReadFromDacl(pDacl);
  227. stat->WriteToString(&ws);
  228. wprintf(L"%s", ws.c_str());
  229. }
  230. catch(AdlStatement::ADL_ERROR_TYPE adlErr)
  231. {
  232. HandleError(adlErr, stat->GetErrorToken());
  233. }
  234. if( stat != NULL )
  235. {
  236. delete stat;
  237. }
  238. delete[] (PBYTE)pSD;
  239. }
  240. //
  241. // -set adlfile target
  242. //
  243. void WriteDaclFromAdl(int argc, WCHAR *argv[]) {
  244. WCHAR buf[16384];
  245. char buf3[16384];
  246. DWORD i;
  247. DWORD dwErr;
  248. if(argc != 4)
  249. {
  250. wprintf(L"\nUsage:\n\n%s -set <adl rules file> <target>\n\n", argv[0]);
  251. exit(1);
  252. }
  253. FILE *in = _wfopen(argv[2], L"rb");
  254. if(in == NULL)
  255. {
  256. wprintf(L"Error: cannot open input ADL file '%s', exiting\n", argv[2]);
  257. exit(2);
  258. }
  259. // skip top byte
  260. if( fgetwc(in) != 0xFEFF)
  261. {
  262. fseek(in, 0, SEEK_SET);
  263. for(i = 0; (buf3[i] = (char)fgetc(in)) != EOF && i < 16384; i++);
  264. buf3[i] = 0;
  265. MultiByteToWideChar(CP_ACP, 0, buf3, i+1, buf, 16384);
  266. }
  267. else
  268. {
  269. for(i = 0; (buf[i] = fgetwc(in)) != WEOF && i < 16384; i++);
  270. buf[i] = 0;
  271. }
  272. AdlStatement * stat;
  273. try
  274. {
  275. stat = new AdlStatement( &EnglishFileParser);
  276. wstring ws;
  277. stat->ReadFromString(buf);
  278. stat->WriteToString(&ws);
  279. wprintf(L"Setting permissions to:\n-------------\n%s\n-------------\n",
  280. ws.c_str());
  281. }
  282. catch(AdlStatement::ADL_ERROR_TYPE adlErr)
  283. {
  284. HandleError(adlErr, stat->GetErrorToken());
  285. if( stat != NULL )
  286. {
  287. delete stat;
  288. }
  289. exit(6);
  290. }
  291. //
  292. // Initialize the security descriptor
  293. //
  294. SECURITY_DESCRIPTOR SD;
  295. InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION);
  296. SetSecurityDescriptorGroup(&SD, NULL, FALSE);
  297. SetSecurityDescriptorOwner(&SD, NULL, FALSE);
  298. SetSecurityDescriptorSacl(&SD, FALSE, NULL, FALSE);
  299. PACL pDacl = NULL;
  300. try
  301. {
  302. stat->WriteToDacl(&pDacl);
  303. }
  304. catch(AdlStatement::ADL_ERROR_TYPE adlErr)
  305. {
  306. HandleError(adlErr, stat->GetErrorToken());
  307. delete stat;
  308. exit(7);
  309. }
  310. SetSecurityDescriptorDacl(&SD, TRUE, pDacl, FALSE);
  311. //
  312. // Set the file security
  313. //
  314. SECURITY_INFORMATION SecInfo = DACL_SECURITY_INFORMATION;
  315. dwErr = SetFileSecurity(argv[3], SecInfo, &SD);
  316. if(dwErr == 0)
  317. {
  318. dwErr = GetLastError();
  319. wprintf(L"SetFileSecurity on %s failed with %d, 0x%x\n",
  320. argv[3],
  321. dwErr,
  322. dwErr);
  323. }
  324. else
  325. {
  326. wprintf(L"Success, permissions set.\n");
  327. }
  328. AdlStatement::FreeMemory(pDacl);
  329. delete stat;
  330. }
  331. void __cdecl wmain(int argc, WCHAR *argv[])
  332. {
  333. if(argc < 2)
  334. {
  335. wprintf(L"\nUsage:\n\n%s -set <adl rules file> <target>\n"
  336. L"%s -dump <target>\n\n", argv[0], argv[0]);
  337. }
  338. else
  339. {
  340. if(!_wcsicmp(argv[1], L"-dump"))
  341. {
  342. DumpDaclToAdl(argc, argv);
  343. }
  344. else if(!_wcsicmp(argv[1], L"-set"))
  345. {
  346. WriteDaclFromAdl(argc, argv);
  347. }
  348. else
  349. {
  350. wprintf(L"\nUsage:\n\n%s -set <adl rules file> <target>\n"
  351. L"%s -dump <target>\n\n", argv[0], argv[0]);
  352. }
  353. }
  354. }