|
12 | 12 |
|
13 | 13 | WINE_DEFAULT_DEBUG_CHANNEL(msv1_0); |
14 | 14 |
|
| 15 | +typedef struct _LOGON_LIST_ENTRY |
| 16 | +{ |
| 17 | + LIST_ENTRY ListEntry; |
| 18 | + LUID LogonId; |
| 19 | + ULONG EnumHandle; |
| 20 | +} LOGON_LIST_ENTRY, *PLOGON_LIST_ENTRY; |
| 21 | + |
| 22 | +/* GLOBALS *****************************************************************/ |
| 23 | + |
| 24 | +BOOL PackageInitialized = FALSE; |
| 25 | +LIST_ENTRY LogonListHead; |
| 26 | +ULONG EnumCounter; |
15 | 27 |
|
16 | 28 | /* FUNCTIONS ***************************************************************/ |
17 | 29 |
|
@@ -819,6 +831,125 @@ MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest, |
819 | 831 | } |
820 | 832 |
|
821 | 833 |
|
| 834 | +static |
| 835 | +NTSTATUS |
| 836 | +MsvpEnumerateUsers( |
| 837 | + _In_ PLSA_CLIENT_REQUEST ClientRequest, |
| 838 | + _In_ PVOID ProtocolSubmitBuffer, |
| 839 | + _In_ PVOID ClientBufferBase, |
| 840 | + _In_ ULONG SubmitBufferLength, |
| 841 | + _Out_ PVOID *ProtocolReturnBuffer, |
| 842 | + _Out_ PULONG ReturnBufferLength, |
| 843 | + _Out_ PNTSTATUS ProtocolStatus) |
| 844 | +{ |
| 845 | + PMSV1_0_ENUMUSERS_RESPONSE LocalBuffer = NULL; |
| 846 | + PVOID ClientBaseAddress = NULL; |
| 847 | + ULONG BufferLength; |
| 848 | + PLIST_ENTRY CurrentEntry; |
| 849 | + PLOGON_LIST_ENTRY LogonEntry; |
| 850 | + ULONG LogonCount = 0; |
| 851 | + PLUID LuidPtr; |
| 852 | + PULONG EnumPtr; |
| 853 | + NTSTATUS Status = STATUS_SUCCESS; |
| 854 | + |
| 855 | + TRACE("MsvpEnumerateUsers()\n"); |
| 856 | + |
| 857 | + /* Count the currently logged-on users */ |
| 858 | + CurrentEntry = LogonListHead.Flink; |
| 859 | + while (CurrentEntry != &LogonListHead) |
| 860 | + { |
| 861 | + LogonEntry = CONTAINING_RECORD(CurrentEntry, |
| 862 | + LOGON_LIST_ENTRY, |
| 863 | + ListEntry); |
| 864 | + |
| 865 | + TRACE("Logon %lu: 0x%08lx\n", LogonCount, LogonEntry->LogonId.LowPart); |
| 866 | + LogonCount++; |
| 867 | + |
| 868 | + CurrentEntry = CurrentEntry->Flink; |
| 869 | + } |
| 870 | + |
| 871 | + TRACE("LogonCount %lu\n", LogonCount); |
| 872 | + |
| 873 | + BufferLength = sizeof(MSV1_0_ENUMUSERS_RESPONSE) + |
| 874 | + (LogonCount * sizeof(LUID)) + |
| 875 | + (LogonCount * sizeof(ULONG)); |
| 876 | + |
| 877 | + LocalBuffer = DispatchTable.AllocateLsaHeap(BufferLength); |
| 878 | + if (LocalBuffer == NULL) |
| 879 | + { |
| 880 | + ERR("Failed to allocate the local buffer!\n"); |
| 881 | + Status = STATUS_INSUFFICIENT_RESOURCES; |
| 882 | + goto done; |
| 883 | + } |
| 884 | + |
| 885 | + Status = DispatchTable.AllocateClientBuffer(ClientRequest, |
| 886 | + BufferLength, |
| 887 | + &ClientBaseAddress); |
| 888 | + if (!NT_SUCCESS(Status)) |
| 889 | + { |
| 890 | + ERR("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status); |
| 891 | + goto done; |
| 892 | + } |
| 893 | + |
| 894 | + TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); |
| 895 | + |
| 896 | + /* Fill the local buffer */ |
| 897 | + LocalBuffer->MessageType = MsV1_0EnumerateUsers; |
| 898 | + LocalBuffer->NumberOfLoggedOnUsers = LogonCount; |
| 899 | + |
| 900 | + LuidPtr = (PLUID)((ULONG_PTR)LocalBuffer + sizeof(MSV1_0_ENUMUSERS_RESPONSE)); |
| 901 | + EnumPtr = (PULONG)((ULONG_PTR)LuidPtr + LogonCount * sizeof(LUID)); |
| 902 | + |
| 903 | + LocalBuffer->LogonIds = (PLUID)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)LuidPtr - (ULONG_PTR)LocalBuffer); |
| 904 | + LocalBuffer->EnumHandles = (PULONG)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)EnumPtr - (ULONG_PTR)LocalBuffer); |
| 905 | + |
| 906 | + /* Copy the LogonIds and EnumHandles into the local buffer */ |
| 907 | + CurrentEntry = LogonListHead.Flink; |
| 908 | + while (CurrentEntry != &LogonListHead) |
| 909 | + { |
| 910 | + LogonEntry = CONTAINING_RECORD(CurrentEntry, |
| 911 | + LOGON_LIST_ENTRY, |
| 912 | + ListEntry); |
| 913 | + |
| 914 | + TRACE("Logon: 0x%08lx %lu\n", LogonEntry->LogonId.LowPart, LogonEntry->EnumHandle); |
| 915 | + RtlCopyMemory(LuidPtr, &LogonEntry->LogonId, sizeof(LUID)); |
| 916 | + LuidPtr++; |
| 917 | + |
| 918 | + *EnumPtr = LogonEntry->EnumHandle; |
| 919 | + EnumPtr++; |
| 920 | + |
| 921 | + CurrentEntry = CurrentEntry->Flink; |
| 922 | + } |
| 923 | + |
| 924 | + Status = DispatchTable.CopyToClientBuffer(ClientRequest, |
| 925 | + BufferLength, |
| 926 | + ClientBaseAddress, |
| 927 | + LocalBuffer); |
| 928 | + if (!NT_SUCCESS(Status)) |
| 929 | + { |
| 930 | + ERR("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status); |
| 931 | + goto done; |
| 932 | + } |
| 933 | + |
| 934 | + *ProtocolReturnBuffer = (PMSV1_0_INTERACTIVE_PROFILE)ClientBaseAddress; |
| 935 | + *ReturnBufferLength = BufferLength; |
| 936 | + *ProtocolStatus = STATUS_SUCCESS; |
| 937 | + |
| 938 | +done: |
| 939 | + if (LocalBuffer != NULL) |
| 940 | + DispatchTable.FreeLsaHeap(LocalBuffer); |
| 941 | + |
| 942 | + if (!NT_SUCCESS(Status)) |
| 943 | + { |
| 944 | + if (ClientBaseAddress != NULL) |
| 945 | + DispatchTable.FreeClientBuffer(ClientRequest, |
| 946 | + ClientBaseAddress); |
| 947 | + } |
| 948 | + |
| 949 | + return STATUS_SUCCESS; |
| 950 | +} |
| 951 | + |
| 952 | + |
822 | 953 | /* |
823 | 954 | * @unimplemented |
824 | 955 | */ |
@@ -853,6 +984,15 @@ LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest, |
853 | 984 | break; |
854 | 985 |
|
855 | 986 | case MsV1_0EnumerateUsers: |
| 987 | + Status = MsvpEnumerateUsers(ClientRequest, |
| 988 | + ProtocolSubmitBuffer, |
| 989 | + ClientBufferBase, |
| 990 | + SubmitBufferLength, |
| 991 | + ProtocolReturnBuffer, |
| 992 | + ReturnBufferLength, |
| 993 | + ProtocolStatus); |
| 994 | + break; |
| 995 | + |
856 | 996 | case MsV1_0GetUserInfo: |
857 | 997 | case MsV1_0ReLogonUsers: |
858 | 998 | Status = STATUS_INVALID_PARAMETER; |
@@ -962,6 +1102,13 @@ LsaApInitializePackage(IN ULONG AuthenticationPackageId, |
962 | 1102 | AuthenticationPackageId, LsaDispatchTable, Database, |
963 | 1103 | Confidentiality, AuthenticationPackageName); |
964 | 1104 |
|
| 1105 | + if (!PackageInitialized) |
| 1106 | + { |
| 1107 | + InitializeListHead(&LogonListHead); |
| 1108 | + EnumCounter = 0; |
| 1109 | + PackageInitialized = TRUE; |
| 1110 | + } |
| 1111 | + |
965 | 1112 | /* Get the dispatch table entries */ |
966 | 1113 | DispatchTable.CreateLogonSession = LsaDispatchTable->CreateLogonSession; |
967 | 1114 | DispatchTable.DeleteLogonSession = LsaDispatchTable->DeleteLogonSession; |
@@ -1134,6 +1281,7 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, |
1134 | 1281 | BOOL SpecialAccount = FALSE; |
1135 | 1282 | UCHAR LogonPassHash; |
1136 | 1283 | PUNICODE_STRING ErasePassword = NULL; |
| 1284 | + PLOGON_LIST_ENTRY LogonEntry = NULL; |
1137 | 1285 |
|
1138 | 1286 | TRACE("LsaApLogonUserEx2()\n"); |
1139 | 1287 |
|
@@ -1329,6 +1477,16 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, |
1329 | 1477 |
|
1330 | 1478 | SessionCreated = TRUE; |
1331 | 1479 |
|
| 1480 | + LogonEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGON_LIST_ENTRY)); |
| 1481 | + if (LogonEntry) |
| 1482 | + { |
| 1483 | + RtlCopyMemory(&LogonEntry->LogonId, LogonId, sizeof(LUID)); |
| 1484 | + LogonEntry->EnumHandle = EnumCounter; |
| 1485 | + EnumCounter++; |
| 1486 | + |
| 1487 | + InsertTailList(&LogonListHead, &LogonEntry->ListEntry); |
| 1488 | + } |
| 1489 | + |
1332 | 1490 | if (LogonType == Interactive || LogonType == Batch || LogonType == Service) |
1333 | 1491 | { |
1334 | 1492 | /* Build and fill the interactive profile buffer */ |
|
0 commit comments