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.

264 lines
6.6 KiB

  1. /****************************************************************************
  2. PROGRAM: LSA.C
  3. PURPOSE: Utility routines that access the LSA.
  4. ****************************************************************************/
  5. #include "pviewp.h"
  6. #include <ntlsa.h>
  7. #include <string.h>
  8. // Module global that holds handle to LSA once it has been opened.
  9. static LSA_HANDLE LsaHandle = NULL;
  10. LSA_HANDLE OpenLsa(VOID);
  11. VOID CloseLsa(LSA_HANDLE);
  12. /****************************************************************************
  13. FUNCTION: LsaInit
  14. PURPOSE: Does any initialization required for this module
  15. RETURNS: TRUE on success, FALSE on failure
  16. ****************************************************************************/
  17. BOOL LsaInit(VOID)
  18. {
  19. LsaHandle = OpenLsa();
  20. return (LsaHandle != NULL);
  21. return (TRUE);
  22. }
  23. /****************************************************************************
  24. FUNCTION: LsaTerminate
  25. PURPOSE: Does any cleanup required for this module
  26. RETURNS: TRUE on success, FALSE on failure
  27. ****************************************************************************/
  28. BOOL LsaTerminate(VOID)
  29. {
  30. if (LsaHandle != NULL) {
  31. CloseLsa(LsaHandle);
  32. }
  33. LsaHandle = NULL;
  34. return(TRUE);
  35. }
  36. /****************************************************************************
  37. FUNCTION: OpenLsa
  38. PURPOSE: Opens the Lsa
  39. Returns handle to Lsa or NULL on failure
  40. ****************************************************************************/
  41. LSA_HANDLE OpenLsa(VOID)
  42. {
  43. NTSTATUS Status;
  44. OBJECT_ATTRIBUTES ObjectAttributes;
  45. LSA_HANDLE ConnectHandle = NULL;
  46. SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  47. //
  48. // Set up the Security Quality Of Service
  49. //
  50. SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  51. SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
  52. SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  53. SecurityQualityOfService.EffectiveOnly = FALSE;
  54. //
  55. // Set up the object attributes prior to opening the LSA.
  56. //
  57. InitializeObjectAttributes(&ObjectAttributes,
  58. NULL,
  59. 0L,
  60. (HANDLE)NULL,
  61. NULL);
  62. //
  63. // The InitializeObjectAttributes macro presently stores NULL for
  64. // the SecurityQualityOfService field, so we must manually copy that
  65. // structure for now.
  66. //
  67. ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
  68. //
  69. // Open a handle to the LSA. Specifying NULL for the Server means that the
  70. // server is the same as the client.
  71. //
  72. Status = LsaOpenPolicy(NULL,
  73. &ObjectAttributes,
  74. POLICY_LOOKUP_NAMES,
  75. &ConnectHandle
  76. );
  77. if (!NT_SUCCESS(Status)) {
  78. DbgPrint("LSM - Lsa Open failed 0x%lx\n", Status);
  79. return NULL;
  80. }
  81. return(ConnectHandle);
  82. }
  83. /****************************************************************************
  84. FUNCTION: CloseLsa
  85. PURPOSE: Closes the Lsa
  86. ****************************************************************************/
  87. VOID CloseLsa(
  88. LSA_HANDLE LsaHandle)
  89. {
  90. NTSTATUS Status;
  91. Status = LsaClose(LsaHandle);
  92. if (!NT_SUCCESS(Status)) {
  93. DbgPrint("LSM - Lsa Close failed 0x%lx\n", Status);
  94. }
  95. return;
  96. }
  97. /****************************************************************************
  98. FUNCTION: SID2Name
  99. PURPOSE: Converts a SID into a readable string.
  100. RETURNS : TRUE on success otherwise FALSE.
  101. ****************************************************************************/
  102. BOOL SID2Name(
  103. PSID Sid,
  104. LPSTR String,
  105. USHORT MaxStringBytes)
  106. {
  107. NTSTATUS Status;
  108. ANSI_STRING AnsiName;
  109. PLSA_REFERENCED_DOMAIN_LIST DomainList;
  110. PLSA_TRANSLATED_NAME NameList;
  111. if (LsaHandle == NULL) {
  112. DbgPrint("SECEDIT : Lsa not open yet\n");
  113. return(FALSE);
  114. }
  115. Status = LsaLookupSids(LsaHandle, 1, &Sid, &DomainList, &NameList);
  116. if (NT_SUCCESS(Status)) {
  117. // Convert to ansi string
  118. RtlUnicodeStringToAnsiString(&AnsiName, &NameList->Name, TRUE);
  119. // Free up the returned data
  120. LsaFreeMemory((PVOID)DomainList);
  121. LsaFreeMemory((PVOID)NameList);
  122. // Copy the ansi string into our local variable
  123. strncpy(String, AnsiName.Buffer, MaxStringBytes);
  124. // Free up the ansi string
  125. RtlFreeAnsiString(&AnsiName);
  126. } else {
  127. UNICODE_STRING UnicodeName;
  128. if (NT_SUCCESS(RtlConvertSidToUnicodeString(&UnicodeName, Sid, TRUE))) {
  129. DbgPrint("LsaLookupSids failed for sid <%wZ>, error = 0x%lx\n", &UnicodeName, Status);
  130. AnsiName.Buffer = String;
  131. AnsiName.MaximumLength = MaxStringBytes;
  132. RtlUnicodeStringToAnsiString(&AnsiName, &UnicodeName, FALSE);
  133. RtlFreeUnicodeString(&UnicodeName);
  134. } else {
  135. DbgPrint("LsaLookupSids failed, error = 0x%lx\n", Status);
  136. return(FALSE);
  137. }
  138. }
  139. return(TRUE);
  140. }
  141. /****************************************************************************
  142. FUNCTION: PRIV2Name
  143. PURPOSE: Converts a PRIVILEGE into a readable string.
  144. RETURNS : TRUE on success otherwise FALSE.
  145. ****************************************************************************/
  146. BOOL PRIV2Name(
  147. LUID Privilege,
  148. LPSTR lpstr,
  149. UINT MaxStringBytes)
  150. {
  151. NTSTATUS Status;
  152. STRING String;
  153. PUNICODE_STRING UString;
  154. if (LsaHandle == NULL) {
  155. DbgPrint("SECEDIT : Lsa not open yet\n");
  156. return(FALSE);
  157. }
  158. Status = LsaLookupPrivilegeName(LsaHandle, &Privilege, &UString);
  159. if (!NT_SUCCESS(Status)) {
  160. DbgPrint("SECEDIT: LsaLookupPrivilegeName failed, status = 0x%lx\n", Status);
  161. strcpy(lpstr, "<Unknown>");
  162. } else {
  163. //
  164. // Convert it to ANSI - because that's what the rest of the app is.
  165. //
  166. if (UString->Length > (USHORT)MaxStringBytes) {
  167. DbgPrint("SECEDIT: Truncating returned privilege name: *%S*\n", UString);
  168. UString->Length = (USHORT)MaxStringBytes;
  169. DbgPrint(" To: *%S*\n", UString);
  170. }
  171. String.Length = 0;
  172. String.MaximumLength = (USHORT)MaxStringBytes;
  173. String.Buffer = lpstr;
  174. Status = RtlUnicodeStringToAnsiString( &String, UString, FALSE );
  175. ASSERT(NT_SUCCESS(Status));
  176. LsaFreeMemory( UString );
  177. }
  178. return(TRUE);
  179. }