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.

398 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. rights.cxx
  5. Abstract:
  6. rights
  7. Author:
  8. Larry Zhu (LZhu) December 1, 2001 Created
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "precomp.hxx"
  14. #pragma hdrstop
  15. #include "rights.hxx"
  16. NTSTATUS
  17. OpenPolicy(
  18. IN OPTIONAL PWSTR pszServer,
  19. IN DWORD DesiredAccess,
  20. IN PLSA_HANDLE phPolicy
  21. )
  22. {
  23. LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
  24. LSA_UNICODE_STRING ServerString = {0};
  25. PLSA_UNICODE_STRING pServer = NULL;
  26. if (pszServer != NULL)
  27. {
  28. RtlInitUnicodeString(&ServerString, pszServer);
  29. pServer = &ServerString;
  30. }
  31. return LsaOpenPolicy(
  32. pServer,
  33. &ObjectAttributes,
  34. DesiredAccess,
  35. phPolicy
  36. );
  37. }
  38. BOOL
  39. GetAccountSid(
  40. PCWSTR pszServer,
  41. PCWSTR pszAccount,
  42. PSID *ppSid
  43. )
  44. {
  45. WCHAR szReferencedDomain[MAX_PATH + 1] = {0};
  46. DWORD cbSid = 0; // initial allocation attempt
  47. DWORD cchReferencedDomain = 0; // initial allocation size
  48. SID_NAME_USE eUse;
  49. *ppSid = NULL;
  50. if (!LookupAccountName(
  51. pszServer, // machine to lookup account on
  52. pszAccount, // account to lookup
  53. NULL, // SID of interest
  54. &cbSid, // size of SID
  55. NULL, // domain account was found on
  56. &cchReferencedDomain,
  57. &eUse
  58. ) && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
  59. {
  60. cchReferencedDomain = COUNTOF(szReferencedDomain) - 1;
  61. *ppSid = new CHAR[cbSid];
  62. }
  63. return *ppSid && LookupAccountName(
  64. pszServer, // machine to lookup account on
  65. pszAccount, // account to lookup
  66. *ppSid, // SID of interest
  67. &cbSid, // size of SID
  68. szReferencedDomain, // domain account was found on
  69. &cchReferencedDomain,
  70. &eUse
  71. );
  72. }
  73. NTSTATUS
  74. SetAccountSystemAccess(
  75. LSA_HANDLE hPolicy,
  76. PSID pAccountSid,
  77. ULONG NewAccess
  78. )
  79. {
  80. TNtStatus Status;
  81. LSA_HANDLE hAccount = NULL;
  82. ULONG PreviousAccess = 0;
  83. DBGCFG1(Status, STATUS_OBJECT_NAME_NOT_FOUND);
  84. Status DBGCHK = LsaOpenAccount(
  85. hPolicy,
  86. pAccountSid,
  87. ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW,
  88. &hAccount
  89. );
  90. if (STATUS_OBJECT_NAME_NOT_FOUND == Status)
  91. {
  92. Status DBGCHK = LsaCreateAccount(
  93. hPolicy,
  94. pAccountSid,
  95. ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW,
  96. &hAccount
  97. );
  98. }
  99. if (NT_SUCCESS(Status))
  100. {
  101. Status DBGCHK = LsaGetSystemAccessAccount(
  102. hAccount,
  103. &PreviousAccess
  104. );
  105. }
  106. if (NT_SUCCESS(Status))
  107. {
  108. DebugPrintf(SSPI_LOG, "SetSystemAccessToAccount setting SystemAccess from %#x to %#x\n", PreviousAccess, NewAccess);
  109. Status DBGCHK = LsaSetSystemAccessAccount(
  110. hAccount,
  111. NewAccess
  112. );
  113. }
  114. if (hAccount)
  115. {
  116. LsaClose(hAccount);
  117. }
  118. return Status;
  119. }
  120. VOID
  121. Usage(
  122. IN PCWSTR pszProgramName
  123. )
  124. {
  125. DebugPrintf(SSPI_LOG, "Usage: %ws -a <account name> -p <privilege to add> -P <privilege to remove> -r <system access to set> -s <server name>\n", pszProgramName);
  126. DebugPrintf(SSPI_LOG, "example system access are SECURITY_ACCESS_INTERACTIVE_LOGON and SECURITY_ACCESS_DENY_SERVICE_LOGON\n");
  127. exit(1);
  128. }
  129. NTSTATUS
  130. EnumRights(
  131. IN LSA_HANDLE hPolicy,
  132. IN PSID pAccountSid
  133. )
  134. {
  135. TNtStatus Status;
  136. PPRIVILEGE_SET pPrivSet = {0};
  137. PUNICODE_STRING pPrivName = NULL;
  138. PUNICODE_STRING pPrivDisplayName = NULL;
  139. LSA_HANDLE hAccount = NULL;
  140. SHORT Language = 0;
  141. ULONG SystemAccess = 0;
  142. CHAR szLine[MAX_PATH] = {0};
  143. DebugPrintf(SSPI_LOG, "Enumerate logon rights and privileges for account:\n");
  144. Status DBGCHK = LsaOpenAccount(
  145. hPolicy,
  146. pAccountSid,
  147. ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW,
  148. &hAccount
  149. );
  150. if (NT_SUCCESS(Status))
  151. {
  152. Status DBGCHK = LsaEnumeratePrivilegesOfAccount(
  153. hAccount,
  154. &pPrivSet
  155. );
  156. }
  157. for (ULONG i = 0; NT_SUCCESS(Status) && (i < pPrivSet->PrivilegeCount); i++)
  158. {
  159. pPrivName = NULL;
  160. pPrivDisplayName = NULL;
  161. INT cchUsed = 0;
  162. cchUsed = _snprintf(szLine, COUNTOF(szLine) - 1, "\nLUID %#x:%#x Attributes %#x ",
  163. pPrivSet->Privilege[i].Luid.HighPart,
  164. pPrivSet->Privilege[i].Luid.LowPart,
  165. pPrivSet->Privilege[i].Attributes);
  166. Status DBGCHK = LsaLookupPrivilegeName(
  167. hPolicy,
  168. &pPrivSet->Privilege[i].Luid,
  169. &pPrivName
  170. );
  171. if (NT_SUCCESS(Status))
  172. {
  173. Status DBGCHK = LsaLookupPrivilegeDisplayName(
  174. hPolicy,
  175. pPrivName,
  176. &pPrivDisplayName,
  177. &Language
  178. );
  179. }
  180. if (NT_SUCCESS(Status))
  181. {
  182. if (cchUsed >= 0)
  183. {
  184. _snprintf(szLine + cchUsed, COUNTOF(szLine) - 1 - cchUsed, "\tName = %wZ, Display name = %wZ, Language = %d\n",
  185. pPrivName, pPrivDisplayName, Language);
  186. }
  187. DebugPrintf(SSPI_LOG, "Privilege %d\n%s\n", i, szLine);
  188. }
  189. if (pPrivDisplayName)
  190. {
  191. LsaFreeMemory(pPrivDisplayName->Buffer);
  192. LsaFreeMemory(pPrivDisplayName);
  193. pPrivDisplayName = NULL;
  194. }
  195. if (pPrivName)
  196. {
  197. LsaFreeMemory(pPrivName->Buffer);
  198. LsaFreeMemory(pPrivName);
  199. pPrivName = NULL;
  200. }
  201. }
  202. if (NT_SUCCESS(Status))
  203. {
  204. Status DBGCHK = LsaGetSystemAccessAccount(
  205. hAccount,
  206. &SystemAccess
  207. );
  208. }
  209. if (NT_SUCCESS(Status))
  210. {
  211. DebugPrintf(SSPI_LOG, "System access for account = 0x%x\n", SystemAccess);
  212. }
  213. if (pPrivSet)
  214. {
  215. LsaFreeMemory(pPrivSet);
  216. }
  217. if (hAccount)
  218. {
  219. LsaClose(hAccount);
  220. }
  221. return Status;
  222. }
  223. VOID __cdecl
  224. _tmain(
  225. IN INT argc,
  226. IN PTSTR argv[]
  227. )
  228. {
  229. TNtStatus Status = STATUS_SUCCESS;
  230. PSID pSid = NULL;
  231. HANDLE hPolicy = NULL;
  232. PWSTR pszComputer = NULL;
  233. PWSTR pszAccount = NULL;
  234. UNICODE_STRING Privilege = {0};
  235. ULONG Access = 0;
  236. BOOLEAN bIsRemove = FALSE;
  237. BOOLEAN bSetLogonRights = FALSE;
  238. for (INT i = 1; i < argc; i++)
  239. {
  240. if ((*argv[i] == '-') || (*argv[i] == '/'))
  241. {
  242. switch (*(argv[i] + 1))
  243. {
  244. case 'a':
  245. pszAccount = argv[++i];
  246. break;
  247. case 'p':
  248. RtlInitUnicodeString(&Privilege, argv[++i]);
  249. break;
  250. case 'P':
  251. RtlInitUnicodeString(&Privilege, argv[++i]);
  252. bIsRemove = TRUE;
  253. break;
  254. case 'r':
  255. bSetLogonRights = TRUE;
  256. Access = wcstol(argv[++i], NULL, 0);
  257. break;
  258. case 's':
  259. pszComputer = argv[++i];
  260. break;
  261. case 'h':
  262. case '?':
  263. default:
  264. Usage(argv[0]);
  265. }
  266. }
  267. else
  268. {
  269. Usage(argv[0]);
  270. }
  271. }
  272. Status DBGCHK = OpenPolicy(
  273. pszComputer, // target machine
  274. POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
  275. &hPolicy // resultant policy handle
  276. );
  277. if (NT_SUCCESS(Status))
  278. {
  279. Status DBGCHK = GetAccountSid(
  280. NULL, // default lookup logic
  281. pszAccount, // account to obtain SID
  282. &pSid // buffer to allocate to contain resultant SID
  283. ) ? S_OK : GetLastErrorAsHResult();
  284. }
  285. if (NT_SUCCESS(Status) && Privilege.Length && Privilege.Buffer)
  286. {
  287. if (!bIsRemove)
  288. {
  289. DebugPrintf(SSPI_LOG, "Adding Privilege %wZ\n", &Privilege);
  290. Status DBGCHK = LsaAddAccountRights(
  291. hPolicy, // open policy handle
  292. pSid, // target SID
  293. &Privilege, // privileges
  294. 1 // privilege count
  295. );
  296. }
  297. else
  298. {
  299. DebugPrintf(SSPI_LOG, "Removing Privilege %wZ\n", &Privilege);
  300. Status DBGCHK = LsaRemoveAccountRights(
  301. hPolicy, // open policy handle
  302. pSid, // target SID
  303. FALSE, // do not disable all rights
  304. &Privilege, // privileges
  305. 1 // privilege count
  306. );
  307. }
  308. }
  309. if (NT_SUCCESS(Status) && bSetLogonRights)
  310. {
  311. Status DBGCHK = SetAccountSystemAccess(
  312. hPolicy,
  313. pSid,
  314. Access
  315. );
  316. }
  317. if (NT_SUCCESS(Status))
  318. {
  319. DebugPrintf(SSPI_LOG, "SystemAccess/Privilege is applied to account %ws on server %ws\n", pszAccount, pszComputer ? pszComputer : L"localhost");
  320. Status DBGCHK = EnumRights(hPolicy, pSid);
  321. }
  322. else
  323. {
  324. DebugPrintf(SSPI_ERROR, "Failed to apply SystemAccess/Privilege to account %ws on server %ws\n", pszAccount, pszComputer ? pszComputer : L"localhost");
  325. }
  326. if (hPolicy)
  327. {
  328. LsaClose(hPolicy);
  329. }
  330. if (pSid)
  331. {
  332. delete [] pSid;
  333. }
  334. }