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.

428 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. main.cpp
  5. Abstract:
  6. The test for the Mail resource manager
  7. Author:
  8. t-eugenz - August 2000
  9. Environment:
  10. User mode only.
  11. Revision History:
  12. Created - August 2000
  13. --*/
  14. #include "mailrm.h"
  15. #include "main.h"
  16. //
  17. // The set of mailboxes to create
  18. //
  19. mailStruct pMailboxes[] =
  20. {
  21. { BobSid, TRUE, L"Bob" },
  22. { MarthaSid, FALSE, L"Martha" },
  23. { JoeSid, FALSE, L"Joe" },
  24. { JaneSid, FALSE, L"Jane" },
  25. { MailAdminsSid, FALSE, L"Admin" },
  26. { NULL, FALSE, NULL }
  27. };
  28. //
  29. // The set of single access attempts to run
  30. //
  31. testStruct pTests[] =
  32. {
  33. { MailAdminsSid, BobSid, ACCESS_MAIL_READ, 0xC0000001 },
  34. { BobSid, BobSid, ACCESS_MAIL_READ, 0xD0000001 },
  35. { BobSid, BobSid, ACCESS_MAIL_WRITE, 0xD0000001 },
  36. { MarthaSid, BobSid, ACCESS_MAIL_READ, 0xC0000001 },
  37. { JaneSid, JaneSid, ACCESS_MAIL_READ, 0xC0000001 },
  38. { NULL, NULL, 0, 0 }
  39. };
  40. //
  41. // The set of mailboxes to attempt to access for the multiple mailbox access
  42. // check, and the access type to request
  43. //
  44. MAILRM_MULTI_REQUEST_ELEM pRequestElems[] =
  45. {
  46. { BobSid, ACCESS_MAIL_WRITE},
  47. { MarthaSid, ACCESS_MAIL_WRITE},
  48. { MarthaSid, ACCESS_MAIL_READ},
  49. { JaneSid, ACCESS_MAIL_WRITE}
  50. };
  51. //
  52. // The rest of the information for the multiple access check
  53. //
  54. MAILRM_MULTI_REQUEST mRequest =
  55. {
  56. MailAdminsSid, // Administrator performing the access
  57. 0xC1000001, // Administrators coming from insecure 193.0.0.1
  58. 4, // 4 mailboxes to access, as above
  59. pRequestElems // The list of mailboxes
  60. };
  61. void __cdecl wmain(int argc, char *argv[])
  62. /*++
  63. Routine Description
  64. This runs a set of sample tests on the MailRM object.
  65. It first tries to enable the Audit privilege in the current process's
  66. token. If you would like to test auditing, make sure to run this with
  67. an account which has this privilege. Otherwise, the audits will be
  68. ignored (however, the rest of the example will still work).
  69. It then constructs the MailRM instance, and adds the set of managed
  70. mailboxes declared in main.h to the resource manager.
  71. Then it performs the set of access attempts listed in main.h on the
  72. resource manager.
  73. Finally, it attempts a multiple access check by administrators. The
  74. mailboxes accessed are listed above. Successfuly accessed mailboxes
  75. receive administrative notifications.
  76. Arguments
  77. None.
  78. Return Value
  79. None.
  80. --*/
  81. {
  82. DWORD dwIdx;
  83. MailRM * pMRM;
  84. Mailbox * pMbx;
  85. //
  86. // Enable the Audit privilege in the process token
  87. // To disable audit generation, comment this out
  88. //
  89. try {
  90. GetAuditPrivilege();
  91. }
  92. catch(...)
  93. {
  94. wprintf(L"Error enabling Audit privilege, audits will not be logged\n");
  95. }
  96. //
  97. // Initialize the resource manager object
  98. //
  99. try {
  100. pMRM = new MailRM();
  101. }
  102. catch(...)
  103. {
  104. wprintf(L"Fatal exception while instantiating MailRM, exiting\n");
  105. exit(1);
  106. }
  107. //
  108. // Create mailboxes and register them with the resource manager
  109. //
  110. for( dwIdx = 0; pMailboxes[dwIdx].psUser != NULL; dwIdx++ )
  111. {
  112. pMRM->AddMailbox( new Mailbox(pMailboxes[dwIdx].psUser,
  113. pMailboxes[dwIdx].bIsSensitive,
  114. pMailboxes[dwIdx].szName) );
  115. }
  116. //
  117. // Run the access checks
  118. //
  119. wprintf(L"\n\nIndividual access checks\n");
  120. try {
  121. for( dwIdx =0; pTests[dwIdx].psUser != NULL; dwIdx++ )
  122. {
  123. pMbx = pMRM->GetMailboxAccess(pTests[dwIdx].psMailbox,
  124. pTests[dwIdx].psUser,
  125. pTests[dwIdx].dwIP,
  126. pTests[dwIdx].amAccess);
  127. if( pMbx != NULL )
  128. {
  129. wprintf(L"Granted: ");
  130. }
  131. else
  132. {
  133. wprintf(L"Denied: ");
  134. }
  135. PrintTest(pTests[dwIdx]);
  136. }
  137. }
  138. catch(...)
  139. {
  140. wprintf(L"Failed on individual access checks\n");
  141. }
  142. //
  143. // Now perform the access check using the GetMultipleAccess, which
  144. // uses a cached access check internally.
  145. // For every mailbox successfuly opened for write,
  146. // we send an administrative note.
  147. //
  148. wprintf(L"\n\nMultiple cached access checks\n");
  149. PMAILRM_MULTI_REPLY pReply = new MAILRM_MULTI_REPLY[mRequest.dwNumElems];
  150. if( pReply == NULL )
  151. {
  152. wprintf(L"Out of memory, exiting\n");
  153. exit(1);
  154. }
  155. try {
  156. if( FALSE == pMRM->GetMultipleMailboxAccess(&mRequest, pReply) )
  157. {
  158. wprintf(L"Failed on multiple access check\n");
  159. }
  160. else
  161. {
  162. for( dwIdx = 0; dwIdx < mRequest.dwNumElems; dwIdx++ )
  163. {
  164. if( pReply[dwIdx].pMailbox != NULL
  165. && ( mRequest.pRequestElem[dwIdx].amAccessRequested
  166. & ACCESS_MAIL_WRITE ) )
  167. {
  168. pReply[dwIdx].pMailbox->SendMail(
  169. L"Note: Mail server will be down for 1 hour\n\n",
  170. FALSE
  171. );
  172. wprintf(L"Granted: ");
  173. }
  174. else
  175. {
  176. wprintf(L"Denied: ");
  177. }
  178. PrintMultiTest(&mRequest, pReply, dwIdx);
  179. }
  180. }
  181. }
  182. catch(...)
  183. {
  184. wprintf(L"Multiple access check failed, exiting\n");
  185. exit(1);
  186. }
  187. //
  188. // Clean up
  189. //
  190. //
  191. // This also deletes all managed mailboxes
  192. //
  193. delete pMRM;
  194. delete[] pReply;
  195. }
  196. void GetAuditPrivilege()
  197. /*++
  198. Routine Description
  199. This attempts to enable the AUDIT privilege in the current process's
  200. token, which will allow the process to generate audits.
  201. Failure to enable the privilege is ignored. Audits will simply not
  202. be generated, but the rest of the example will not be effected.
  203. The privilege is enabled for the duration of this process, since
  204. the process's token is modified, not the user's token. Therefore,
  205. there is no need to set the privileges back to their initial state.
  206. If this were a part of a larger system, it would be a good idea
  207. to only enable the Audit privilege when needed, and restore the
  208. original privileges afterwards. This can be done by passing
  209. a previous state parameter to AdjustTokenPrivileges, which
  210. would save the original state (to be restored later).
  211. Arguments
  212. None.
  213. Return Value
  214. None.
  215. --*/
  216. {
  217. HANDLE hProcess;
  218. HANDLE hToken;
  219. //
  220. // First, we get a handle to the process we are running in, requesting
  221. // the right to read process information
  222. //
  223. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
  224. FALSE,
  225. GetCurrentProcessId()
  226. );
  227. if( hProcess == NULL )
  228. {
  229. throw (DWORD)ERROR_INTERNAL_ERROR ;
  230. }
  231. //
  232. // We need to be able to read the current privileges and set new privileges,
  233. // as required by AdjustTokenPrivileges
  234. //
  235. OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
  236. if( hProcess == NULL )
  237. {
  238. CloseHandle(hProcess);
  239. throw (DWORD)ERROR_INTERNAL_ERROR;
  240. }
  241. //
  242. // We have the token handle, no need for the process anymore
  243. //
  244. CloseHandle(hProcess);
  245. LUID lPrivAudit;
  246. LookupPrivilegeValue(NULL, SE_AUDIT_NAME, &lPrivAudit);
  247. //
  248. // Only 1 privilege to enable
  249. //
  250. TOKEN_PRIVILEGES NewPrivileges;
  251. NewPrivileges.PrivilegeCount = 1;
  252. NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  253. NewPrivileges.Privileges[0].Luid = lPrivAudit;
  254. //
  255. // Now adjust the privileges in the process token
  256. //
  257. AdjustTokenPrivileges(hToken, FALSE, &NewPrivileges, 0, NULL, NULL);
  258. //
  259. // And we're done with the token handle
  260. //
  261. CloseHandle(hToken);
  262. }
  263. //
  264. // Functions to print the test output
  265. //
  266. void PrintUser(const PSID psUser)
  267. {
  268. DWORD i;
  269. for(i=0; pMailboxes[i].psUser != NULL; i++)
  270. {
  271. if(EqualSid(psUser, pMailboxes[i].psUser))
  272. {
  273. wprintf(pMailboxes[i].szName);
  274. return;
  275. }
  276. }
  277. wprintf(L"UnknownUser");
  278. }
  279. void PrintPerm(ACCESS_MASK am)
  280. {
  281. wprintf(L" (");
  282. if( am & ACCESS_MAIL_READ ) wprintf(L" Read");
  283. if( am & ACCESS_MAIL_WRITE ) wprintf(L" Write");
  284. if( am & ACCESS_MAIL_ADMIN ) wprintf(L" Admin");
  285. wprintf(L" ) ");
  286. }
  287. void PrintTest(testStruct tst)
  288. {
  289. wprintf(L"[ User: ");
  290. PrintUser(tst.psUser);
  291. wprintf(L", Mailbox: ");
  292. PrintUser(tst.psMailbox);
  293. PrintPerm(tst.amAccess);
  294. wprintf(L"IP: %d.%d.%d.%d ]\n", (tst.dwIP >> 24) & 0x000000FF,
  295. (tst.dwIP >> 16) & 0x000000FF,
  296. (tst.dwIP >> 8) & 0x000000FF,
  297. tst.dwIP & 0x000000FF );
  298. }
  299. void PrintMultiTest(PMAILRM_MULTI_REQUEST pRequest,
  300. PMAILRM_MULTI_REPLY pReply,
  301. DWORD dwIdx)
  302. {
  303. wprintf(L"[ User: ");
  304. PrintUser(pRequest->psUser);
  305. wprintf(L", Mailbox: ");
  306. PrintUser(pRequest->pRequestElem[dwIdx].psMailbox);
  307. PrintPerm(pRequest->pRequestElem[dwIdx].amAccessRequested);
  308. wprintf(L"IP: %d.%d.%d.%d ]\n", (pRequest->dwIp >> 24) & 0x000000FF,
  309. (pRequest->dwIp >> 16) & 0x000000FF,
  310. (pRequest->dwIp >> 8) & 0x000000FF,
  311. pRequest->dwIp & 0x000000FF );
  312. }