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.

197 lines
5.9 KiB

  1. extern "C"
  2. {
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. }
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <windows.h>
  10. //+----------------------------------------------------------------------------
  11. ULONG GetAcl(WCHAR *filename, WCHAR *outfile);
  12. //+----------------------------------------------------------------------------
  13. #define RESULTS(a) if (fdebug & 1) {printf a;}
  14. #define VERBOSE(a) if (fdebug & 2) {printf a;}
  15. //+----------------------------------------------------------------------------
  16. VOID Usage()
  17. {
  18. printf("USAGE veracl <filename> [/d] [name permission[...]]\n");
  19. }
  20. //+----------------------------------------------------------------------------
  21. ULONG fdebug;
  22. VOID _cdecl main(INT argc, char *argv[])
  23. {
  24. if ( (argc < 2) ||
  25. ( (argc > 2) && ( (argv[2][0] != '/') && ((argc % 2) != 0) ) ) )
  26. {
  27. Usage();
  28. exit(1);
  29. } else if ((argc > 2) && (argv[2][0] == '/') )
  30. {
  31. if (0 == _stricmp(&argv[2][1],"r") )
  32. {
  33. fdebug = 1;
  34. } else if (0 == _stricmp(&argv[2][1],"d") )
  35. {
  36. fdebug = 2;
  37. } else
  38. {
  39. Usage();
  40. exit(1);
  41. }
  42. } else
  43. {
  44. fdebug = 0;
  45. }
  46. ULONG ret;
  47. CHAR db[1024];
  48. FILE *pf;
  49. WCHAR wch[256];
  50. WCHAR *pwch;
  51. CHAR *pch;
  52. for ( pwch = wch, pch = argv[1]; *pwch = (WCHAR)(*pch);pwch++,pch++);
  53. if ( ERROR_SUCCESS == (ret = GetAcl(wch, L"DinkWink.cmp")))
  54. {
  55. if (NULL != (pf = fopen("DinkWink.cmp","r")))
  56. {
  57. CHAR *ptok = NULL;
  58. for (int k = fdebug ? 3 : 2; k < argc; k+=2)
  59. {
  60. if (NULL != fgets(db,1024, pf))
  61. {
  62. VERBOSE(("GetAcl returned: %s[%d]\n",db,k))
  63. if (k <= 3)
  64. {
  65. if ( NULL == ( ptok = strtok(db, " ")))
  66. {
  67. VERBOSE(("no file name found\n"))
  68. ret = ERROR_INVALID_DATA;
  69. break;
  70. }
  71. VERBOSE(("ptok (1st) [%s]\n",ptok))
  72. }
  73. if (NULL != ( ptok = strtok(k <= 3 ? NULL : db, ":\n")))
  74. {
  75. // this ugly little mess should strip off the leading spaces
  76. for (; *ptok == ' ';ptok++);
  77. VERBOSE(("ptok (2nd) [%s]\n",ptok))
  78. if (0 == _stricmp(ptok, argv[k]))
  79. {
  80. if (NULL != (ptok = strtok(NULL, " ")))
  81. {
  82. VERBOSE(("ptok (3rd) [%s]\n",ptok))
  83. if ((argc <= k) || (0 != _stricmp(ptok, argv[k+1])))
  84. {
  85. VERBOSE(("mismatch type %s != %s\n",ptok))
  86. ret = ERROR_INVALID_DATA;
  87. break;
  88. }
  89. } else
  90. {
  91. VERBOSE(("access type not found in\n"))
  92. ret = ERROR_INVALID_DATA;
  93. break;
  94. }
  95. } else
  96. {
  97. VERBOSE(("mismatch %s != %s\n",ptok, argv[k]))
  98. ret = ERROR_INVALID_DATA;
  99. break;
  100. }
  101. } else
  102. {
  103. VERBOSE((": not found in CACLs output\n"))
  104. ret = ERROR_INVALID_DATA;
  105. break;
  106. }
  107. } else
  108. {
  109. VERBOSE(("End of CACLs output\n"))
  110. ret = ERROR_INVALID_DATA;
  111. break;
  112. }
  113. }
  114. if (k != argc)
  115. {
  116. VERBOSE(("not all name:permissions found on file\n"))
  117. for (int j = k; j < argc ;j+=2 )
  118. VERBOSE((" %s:%s\n",argv[j], argv[j+1]))
  119. ret = ERROR_INVALID_DATA;
  120. }
  121. fclose(pf);
  122. } else
  123. {
  124. ret = GetLastError();
  125. VERBOSE(("fopen failed, %ld\n", ret))
  126. }
  127. DeleteFile(L"DinkWink.cmp");
  128. } else
  129. {
  130. VERBOSE(("GetAcl failed, %ld\n", ret))
  131. }
  132. if (ret == ERROR_SUCCESS)
  133. {
  134. RESULTS(("PASSED\n"))
  135. }
  136. else
  137. {
  138. RESULTS(("FAILED\n"))
  139. }
  140. exit(ret);
  141. }
  142. //+----------------------------------------------------------------------------
  143. ULONG GetAcl(WCHAR *filename, WCHAR *outfile)
  144. {
  145. ULONG ret = ERROR_SUCCESS;
  146. WCHAR cmdline[1024];
  147. wsprintf(cmdline, L"cmd /c CACLS.EXE %ws > %ws",
  148. filename,
  149. outfile);
  150. VERBOSE(("CMD: %ws\n",cmdline))
  151. STARTUPINFO sui;
  152. memset(&sui,0,sizeof(STARTUPINFO));
  153. sui.cb = sizeof(STARTUPINFO);
  154. PROCESS_INFORMATION pi;
  155. if (CreateProcess(NULL,
  156. cmdline,
  157. NULL,
  158. NULL,
  159. TRUE,
  160. NORMAL_PRIORITY_CLASS,
  161. NULL,
  162. NULL,
  163. &sui,
  164. &pi))
  165. {
  166. ULONG ec;
  167. CloseHandle(pi.hThread);
  168. DWORD dw = WaitForSingleObject(pi.hProcess, INFINITE);
  169. if (!GetExitCodeProcess(pi.hProcess, &ec))
  170. ret = GetLastError();
  171. CloseHandle(pi.hProcess);
  172. if (ret == ERROR_SUCCESS)
  173. ret = ec;
  174. } else
  175. ret = GetLastError();
  176. return(ret);
  177. }