1 /* 2 * PROJECT: Local Security Authority Server DLL 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/win32/lsasrv/authport.c 5 * PURPOSE: LsaAuthenticationPort server routines 6 * COPYRIGHT: Copyright 2009 Eric Kohl 7 */ 8 9 #include "lsasrv.h" 10 11 #include <ndk/lpcfuncs.h> 12 13 static LIST_ENTRY LsapLogonContextList; 14 15 static HANDLE PortThreadHandle = NULL; 16 static HANDLE AuthPortHandle = NULL; 17 18 19 /* FUNCTIONS ***************************************************************/ 20 21 static NTSTATUS 22 LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg, 23 PLSAP_LOGON_CONTEXT LogonContext) 24 { 25 TRACE("LsapDeregisterLogonProcess(%p %p)\n", RequestMsg, LogonContext); 26 27 RemoveHeadList(&LogonContext->Entry); 28 29 NtClose(LogonContext->ClientProcessHandle); 30 NtClose(LogonContext->ConnectionHandle); 31 32 RtlFreeHeap(RtlGetProcessHeap(), 0, LogonContext); 33 34 return STATUS_SUCCESS; 35 } 36 37 38 static NTSTATUS 39 LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, 40 PLSAP_LOGON_CONTEXT *LogonContext) 41 { 42 OBJECT_ATTRIBUTES ObjectAttributes; 43 HANDLE ProcessHandle = NULL; 44 PLSAP_LOGON_CONTEXT Context = NULL; 45 NTSTATUS Status; 46 47 TRACE("LsapCheckLogonProcess(%p)\n", RequestMsg); 48 49 TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread); 50 51 InitializeObjectAttributes(&ObjectAttributes, 52 NULL, 53 0, 54 NULL, 55 NULL); 56 57 Status = NtOpenProcess(&ProcessHandle, 58 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE, 59 &ObjectAttributes, 60 &RequestMsg->h.ClientId); 61 if (!NT_SUCCESS(Status)) 62 { 63 TRACE("NtOpenProcess() failed (Status %lx)\n", Status); 64 return Status; 65 } 66 67 /* Allocate the logon context */ 68 Context = RtlAllocateHeap(RtlGetProcessHeap(), 69 HEAP_ZERO_MEMORY, 70 sizeof(LSAP_LOGON_CONTEXT)); 71 if (Context == NULL) 72 { 73 NtClose(ProcessHandle); 74 return STATUS_INSUFFICIENT_RESOURCES; 75 } 76 77 TRACE("New LogonContext: %p\n", Context); 78 79 Context->ClientProcessHandle = ProcessHandle; 80 81 *LogonContext = Context; 82 83 return STATUS_SUCCESS; 84 } 85 86 87 static NTSTATUS 88 LsapHandlePortConnection(PLSA_API_MSG RequestMsg) 89 { 90 PLSAP_LOGON_CONTEXT LogonContext = NULL; 91 HANDLE ConnectionHandle = NULL; 92 BOOLEAN Accept; 93 REMOTE_PORT_VIEW RemotePortView; 94 NTSTATUS Status = STATUS_SUCCESS; 95 96 TRACE("LsapHandlePortConnection(%p)\n", RequestMsg); 97 98 TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer); 99 100 if (RequestMsg->ConnectInfo.CreateContext != FALSE) 101 { 102 Status = LsapCheckLogonProcess(RequestMsg, 103 &LogonContext); 104 105 RequestMsg->ConnectInfo.OperationalMode = 0x43218765; 106 107 RequestMsg->ConnectInfo.Status = Status; 108 } 109 110 if (NT_SUCCESS(Status)) 111 { 112 Accept = TRUE; 113 } 114 else 115 { 116 Accept = FALSE; 117 } 118 119 RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); 120 Status = NtAcceptConnectPort(&ConnectionHandle, 121 (PVOID*)LogonContext, 122 &RequestMsg->h, 123 Accept, 124 NULL, 125 &RemotePortView); 126 if (!NT_SUCCESS(Status)) 127 { 128 ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status); 129 return Status; 130 } 131 132 if (Accept != FALSE) 133 { 134 if (LogonContext != NULL) 135 { 136 LogonContext->ConnectionHandle = ConnectionHandle; 137 138 InsertHeadList(&LsapLogonContextList, 139 &LogonContext->Entry); 140 } 141 142 Status = NtCompleteConnectPort(ConnectionHandle); 143 if (!NT_SUCCESS(Status)) 144 { 145 ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status); 146 return Status; 147 } 148 } 149 150 return Status; 151 } 152 153 154 NTSTATUS WINAPI 155 AuthPortThreadRoutine(PVOID Param) 156 { 157 PLSAP_LOGON_CONTEXT LogonContext; 158 PLSA_API_MSG ReplyMsg = NULL; 159 LSA_API_MSG RequestMsg; 160 NTSTATUS Status; 161 162 TRACE("AuthPortThreadRoutine() called\n"); 163 164 Status = STATUS_SUCCESS; 165 166 for (;;) 167 { 168 TRACE("Reply: %p\n", ReplyMsg); 169 Status = NtReplyWaitReceivePort(AuthPortHandle, 170 (PVOID*)&LogonContext, 171 (PPORT_MESSAGE)ReplyMsg, 172 (PPORT_MESSAGE)&RequestMsg); 173 if (!NT_SUCCESS(Status)) 174 { 175 TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status); 176 break; 177 } 178 179 TRACE("Received message\n"); 180 181 switch (RequestMsg.h.u2.s2.Type) 182 { 183 case LPC_CONNECTION_REQUEST: 184 TRACE("Port connection request\n"); 185 Status = LsapHandlePortConnection(&RequestMsg); 186 ReplyMsg = NULL; 187 break; 188 189 case LPC_PORT_CLOSED: 190 TRACE("Port closed\n"); 191 ReplyMsg = NULL; 192 break; 193 194 case LPC_CLIENT_DIED: 195 TRACE("Client died\n"); 196 ReplyMsg = NULL; 197 break; 198 199 default: 200 TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber); 201 202 switch (RequestMsg.ApiNumber) 203 { 204 case LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE: 205 RequestMsg.Status = LsapCallAuthenticationPackage(&RequestMsg, 206 LogonContext); 207 ReplyMsg = &RequestMsg; 208 break; 209 210 case LSASS_REQUEST_DEREGISTER_LOGON_PROCESS: 211 212 ReplyMsg = &RequestMsg; 213 RequestMsg.Status = STATUS_SUCCESS; 214 NtReplyPort(AuthPortHandle, 215 &ReplyMsg->h); 216 217 LsapDeregisterLogonProcess(&RequestMsg, 218 LogonContext); 219 220 ReplyMsg = NULL; 221 break; 222 223 case LSASS_REQUEST_LOGON_USER: 224 RequestMsg.Status = LsapLogonUser(&RequestMsg, 225 LogonContext); 226 ReplyMsg = &RequestMsg; 227 break; 228 229 case LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE: 230 RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg, 231 LogonContext); 232 ReplyMsg = &RequestMsg; 233 break; 234 235 case LSASS_REQUEST_ENUM_LOGON_SESSIONS: 236 RequestMsg.Status = LsapEnumLogonSessions(&RequestMsg); 237 ReplyMsg = &RequestMsg; 238 break; 239 240 case LSASS_REQUEST_GET_LOGON_SESSION_DATA: 241 RequestMsg.Status = LsapGetLogonSessionData(&RequestMsg); 242 ReplyMsg = &RequestMsg; 243 break; 244 245 case LSASS_REQUEST_POLICY_CHANGE_NOTIFY: 246 RequestMsg.Status = LsapRegisterNotification(&RequestMsg); 247 ReplyMsg = &RequestMsg; 248 break; 249 250 default: 251 RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE; 252 ReplyMsg = &RequestMsg; 253 break; 254 } 255 256 break; 257 } 258 } 259 260 return STATUS_SUCCESS; 261 } 262 263 264 NTSTATUS 265 StartAuthenticationPort(VOID) 266 { 267 OBJECT_ATTRIBUTES ObjectAttributes; 268 UNICODE_STRING PortName; 269 DWORD ThreadId; 270 UNICODE_STRING EventName; 271 HANDLE EventHandle; 272 NTSTATUS Status; 273 274 TRACE("StartAuthenticationPort()\n"); 275 276 /* Initialize the logon context list */ 277 InitializeListHead(&LsapLogonContextList); 278 279 RtlInitUnicodeString(&PortName, 280 L"\\LsaAuthenticationPort"); 281 282 InitializeObjectAttributes(&ObjectAttributes, 283 &PortName, 284 0, 285 NULL, 286 NULL); 287 288 Status = NtCreatePort(&AuthPortHandle, 289 &ObjectAttributes, 290 sizeof(LSA_CONNECTION_INFO), 291 sizeof(LSA_API_MSG), 292 sizeof(LSA_API_MSG) * 32); 293 if (!NT_SUCCESS(Status)) 294 { 295 WARN("NtCreatePort() failed (Status %lx)\n", Status); 296 return Status; 297 } 298 299 RtlInitUnicodeString(&EventName, 300 L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED"); 301 InitializeObjectAttributes(&ObjectAttributes, 302 &EventName, 303 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 304 NULL, 305 NULL); 306 Status = NtOpenEvent(&EventHandle, 307 EVENT_MODIFY_STATE, 308 &ObjectAttributes); 309 if (!NT_SUCCESS(Status)) 310 { 311 TRACE("NtOpenEvent failed (Status 0x%08lx)\n", Status); 312 313 Status = NtCreateEvent(&EventHandle, 314 EVENT_MODIFY_STATE, 315 &ObjectAttributes, 316 NotificationEvent, 317 FALSE); 318 if (!NT_SUCCESS(Status)) 319 { 320 WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status); 321 return Status; 322 } 323 } 324 325 Status = NtSetEvent(EventHandle, NULL); 326 NtClose(EventHandle); 327 if (!NT_SUCCESS(Status)) 328 { 329 WARN("NtSetEvent failed (Status 0x%08lx)\n", Status); 330 return Status; 331 } 332 333 PortThreadHandle = CreateThread(NULL, 334 0x1000, 335 (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine, 336 NULL, 337 0, 338 &ThreadId); 339 340 341 return STATUS_SUCCESS; 342 } 343 344 /* EOF */ 345