/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/secur32/lsalpc.c * PURPOSE: LSA LPC port functions */ /* INCLUDES ******************************************************************/ #include "precomp.h" #include #include #include #include #include #include #include #include WINE_DEFAULT_DEBUG_CHANNEL(secur32); /* GLOBALS *******************************************************************/ HANDLE LsaPortHandle; extern HANDLE Secur32Heap; /* FUNCTIONS *****************************************************************/ VOID LsapInitLsaPort(VOID) { LsaPortHandle = NULL; } VOID LsapCloseLsaPort(VOID) { if (LsaPortHandle != NULL) { NtClose(LsaPortHandle); LsaPortHandle = NULL; } } NTSTATUS LsapOpenLsaPort(VOID) { UNICODE_STRING PortName; SECURITY_QUALITY_OF_SERVICE SecurityQos; LSA_CONNECTION_INFO ConnectInfo; ULONG ConnectInfoLength; NTSTATUS Status; TRACE("LsapOpenLsaPort()\n"); if (LsaPortHandle != NULL) return STATUS_SUCCESS; RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort"); SecurityQos.Length = sizeof(SecurityQos); SecurityQos.ImpersonationLevel = SecurityIdentification; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.EffectiveOnly = TRUE; RtlZeroMemory(&ConnectInfo, sizeof(ConnectInfo)); ConnectInfo.CreateContext = FALSE; ConnectInfo.TrustedCaller = TRUE; ConnectInfoLength = sizeof(LSA_CONNECTION_INFO); Status = NtConnectPort(&LsaPortHandle, &PortName, &SecurityQos, NULL, NULL, NULL, &ConnectInfo, &ConnectInfoLength); if (!NT_SUCCESS(Status)) { TRACE("NtConnectPort failed (Status 0x%08lx)\n", Status); } return Status; /* if (!NT_SUCCESS(ConnectInfo.Status)) { DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status); } return ConnectInfo.Status; */ } /* PUBLIC FUNCTIONS **********************************************************/ /* * @implemented */ NTSTATUS NTAPI LsaConnectUntrusted( OUT PHANDLE LsaHandle) { UNICODE_STRING PortName; SECURITY_QUALITY_OF_SERVICE SecurityQos; LSA_CONNECTION_INFO ConnectInfo; ULONG ConnectInfoLength = sizeof(ConnectInfo); OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING EventName; HANDLE EventHandle; NTSTATUS Status; TRACE("LsaConnectUntrusted(%p)\n", LsaHandle); // TODO: we may need to impersonate ourselves before, because we are untrusted! /* Wait for the LSA authentication thread */ RtlInitUnicodeString(&EventName, L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED"); InitializeObjectAttributes(&ObjectAttributes, &EventName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = NtOpenEvent(&EventHandle, SYNCHRONIZE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { WARN("NtOpenEvent failed (Status 0x%08lx)\n", Status); Status = NtCreateEvent(&EventHandle, SYNCHRONIZE, &ObjectAttributes, NotificationEvent, FALSE); if (!NT_SUCCESS(Status)) { WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status); return Status; } } Status = NtWaitForSingleObject(EventHandle, TRUE, NULL); NtClose(EventHandle); if (!NT_SUCCESS(Status)) { ERR("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status); return Status; } /* Connect to the authentication port */ RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort"); SecurityQos.Length = sizeof(SecurityQos); SecurityQos.ImpersonationLevel = SecurityIdentification; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.EffectiveOnly = TRUE; RtlZeroMemory(&ConnectInfo, ConnectInfoLength); ConnectInfo.CreateContext = TRUE; ConnectInfo.TrustedCaller = FALSE; Status = NtConnectPort(LsaHandle, &PortName, &SecurityQos, NULL, NULL, NULL, &ConnectInfo, &ConnectInfoLength); if (!NT_SUCCESS(Status)) { ERR("NtConnectPort failed (Status 0x%08lx)\n", Status); return Status; } if (!NT_SUCCESS(ConnectInfo.Status)) { ERR("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status); } return ConnectInfo.Status; } /* * @implemented */ NTSTATUS NTAPI LsaEnumerateLogonSessions( PULONG LogonSessionCount, PLUID *LogonSessionList) { LSA_API_MSG ApiMessage; NTSTATUS Status; TRACE("LsaEnumerateLogonSessions(%p %p)\n", LogonSessionCount, LogonSessionList); Status = LsapOpenLsaPort(); if (!NT_SUCCESS(Status)) return Status; ApiMessage.ApiNumber = LSASS_REQUEST_ENUM_LOGON_SESSIONS; ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.EnumLogonSessions); ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; ApiMessage.h.u2.ZeroInit = 0; Status = NtRequestWaitReplyPort(LsaPortHandle, (PPORT_MESSAGE)&ApiMessage, (PPORT_MESSAGE)&ApiMessage); if (!NT_SUCCESS(Status)) { ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); return Status; } if (!NT_SUCCESS(ApiMessage.Status)) { ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); return ApiMessage.Status; } *LogonSessionCount = ApiMessage.EnumLogonSessions.Reply.LogonSessionCount; *LogonSessionList = ApiMessage.EnumLogonSessions.Reply.LogonSessionBuffer; return Status; } /* * @unimplemented */ NTSTATUS NTAPI LsaGetLogonSessionData( PLUID LogonId, PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData) { LSA_API_MSG ApiMessage; PSECURITY_LOGON_SESSION_DATA SessionData; NTSTATUS Status; TRACE("LsaGetLogonSessionData(%p %p)\n", LogonId, ppLogonSessionData); Status = LsapOpenLsaPort(); if (!NT_SUCCESS(Status)) return Status; ApiMessage.ApiNumber = LSASS_REQUEST_GET_LOGON_SESSION_DATA; ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.GetLogonSessionData); ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; ApiMessage.h.u2.ZeroInit = 0; RtlCopyLuid(&ApiMessage.GetLogonSessionData.Request.LogonId, LogonId); Status = NtRequestWaitReplyPort(LsaPortHandle, (PPORT_MESSAGE)&ApiMessage, (PPORT_MESSAGE)&ApiMessage); if (!NT_SUCCESS(Status)) { ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); return Status; } if (!NT_SUCCESS(ApiMessage.Status)) { ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); return ApiMessage.Status; } SessionData = ApiMessage.GetLogonSessionData.Reply.SessionDataBuffer; TRACE("UserName: %p\n", SessionData->UserName.Buffer); if (SessionData->UserName.Buffer != NULL) SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->UserName.Buffer); TRACE("LogonDomain: %p\n", SessionData->LogonDomain.Buffer); if (SessionData->LogonDomain.Buffer != NULL) SessionData->LogonDomain.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonDomain.Buffer); TRACE("AuthenticationPackage: %p\n", SessionData->AuthenticationPackage.Buffer); if (SessionData->AuthenticationPackage.Buffer != NULL) SessionData->AuthenticationPackage.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->AuthenticationPackage.Buffer); TRACE("Sid: %p\n", SessionData->Sid); if (SessionData->Sid != NULL) SessionData->Sid = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Sid); TRACE("LogonServer: %p\n", SessionData->LogonServer.Buffer); if (SessionData->LogonServer.Buffer != NULL) SessionData->LogonServer.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonServer.Buffer); TRACE("DnsDomainName: %p\n", SessionData->DnsDomainName.Buffer); if (SessionData->DnsDomainName.Buffer != NULL) SessionData->DnsDomainName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->DnsDomainName.Buffer); TRACE("Upn: %p\n", SessionData->Upn.Buffer); if (SessionData->Upn.Buffer != NULL) SessionData->Upn.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Upn.Buffer); *ppLogonSessionData = SessionData; return Status; } /* * @implemented */ NTSTATUS NTAPI LsaRegisterPolicyChangeNotification( POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, HANDLE NotificationEventHandle) { LSA_API_MSG ApiMessage; NTSTATUS Status; TRACE("LsaRegisterPolicyChangeNotification(%lu %p)\n", InformationClass, NotificationEventHandle); Status = LsapOpenLsaPort(); if (!NT_SUCCESS(Status)) return Status; ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY; ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify); ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; ApiMessage.h.u2.ZeroInit = 0; ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass; ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle; ApiMessage.PolicyChangeNotify.Request.Register = TRUE; Status = NtRequestWaitReplyPort(LsaPortHandle, (PPORT_MESSAGE)&ApiMessage, (PPORT_MESSAGE)&ApiMessage); if (!NT_SUCCESS(Status)) { ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); return Status; } if (!NT_SUCCESS(ApiMessage.Status)) { ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); return ApiMessage.Status; } return Status; } /* * @implemented */ NTSTATUS NTAPI LsaUnregisterPolicyChangeNotification( POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, HANDLE NotificationEventHandle) { LSA_API_MSG ApiMessage; NTSTATUS Status; TRACE("LsaUnregisterPolicyChangeNotification(%lu %p)\n", InformationClass, NotificationEventHandle); Status = LsapOpenLsaPort(); if (!NT_SUCCESS(Status)) return Status; ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY; ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify); ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; ApiMessage.h.u2.ZeroInit = 0; ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass; ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle; ApiMessage.PolicyChangeNotify.Request.Register = FALSE; Status = NtRequestWaitReplyPort(LsaPortHandle, (PPORT_MESSAGE)&ApiMessage, (PPORT_MESSAGE)&ApiMessage); if (!NT_SUCCESS(Status)) { ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); return Status; } if (!NT_SUCCESS(ApiMessage.Status)) { ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); return ApiMessage.Status; } return Status; } /* EOF */