1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: Local Security Authority Server DLL 4 * FILE: dll/win32/lsasrv/srm.c 5 * PURPOSE: Security Reference Monitor Server 6 * 7 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 8 */ 9 10 /* INCLUDES ****************************************************************/ 11 12 #include "lsasrv.h" 13 #include <ndk/ntndk.h> 14 15 /* GLOBALS *****************************************************************/ 16 17 HANDLE SeLsaCommandPort; 18 HANDLE SeRmCommandPort; 19 20 /* FUNCTIONS ***************************************************************/ 21 22 static 23 VOID 24 LsapComponentTest( 25 PLSAP_RM_API_MESSAGE Message) 26 { 27 ERR("Security: LSA Component Test Command Received\n"); 28 } 29 30 static 31 VOID 32 LsapAdtWriteLog( 33 PLSAP_RM_API_MESSAGE Message) 34 { 35 ERR("LsapAdtWriteLog\n"); 36 } 37 38 static 39 VOID 40 LsapAsync( 41 PLSAP_RM_API_MESSAGE Message) 42 { 43 ERR("LsapAsync\n"); 44 } 45 46 static 47 DWORD 48 WINAPI 49 LsapRmServerThread( 50 PVOID StartContext) 51 { 52 LSAP_RM_API_MESSAGE Message; 53 PPORT_MESSAGE ReplyMessage; 54 REMOTE_PORT_VIEW RemotePortView; 55 HANDLE MessagePort, DummyPortHandle; 56 NTSTATUS Status; 57 58 /* Initialize the port message */ 59 Message.Header.u1.s1.TotalLength = sizeof(Message); 60 Message.Header.u1.s1.DataLength = 0; 61 62 /* Listen on the LSA command port */ 63 Status = NtListenPort(SeLsaCommandPort, &Message.Header); 64 if (!NT_SUCCESS(Status)) 65 { 66 ERR("LsapRmServerThread - Port Listen failed 0x%lx\n", Status); 67 return Status; 68 } 69 70 /* Setup the Port View Structure */ 71 RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); 72 RemotePortView.ViewSize = 0; 73 RemotePortView.ViewBase = NULL; 74 75 /* Accept the connection */ 76 Status = NtAcceptConnectPort(&MessagePort, 77 0, 78 &Message.Header, 79 TRUE, 80 NULL, 81 &RemotePortView); 82 if (!NT_SUCCESS(Status)) 83 { 84 ERR("LsapRmServerThread - Port Accept Connect failed 0x%lx\n", Status); 85 return Status; 86 } 87 88 /* Complete the connection */ 89 Status = NtCompleteConnectPort(MessagePort); 90 if (!NT_SUCCESS(Status)) 91 { 92 ERR("LsapRmServerThread - Port Complete Connect failed 0x%lx\n", Status); 93 return Status; 94 } 95 96 /* No reply yet */ 97 ReplyMessage = NULL; 98 99 /* Start looping */ 100 while (TRUE) 101 { 102 /* Wait for a message */ 103 Status = NtReplyWaitReceivePort(MessagePort, 104 NULL, 105 ReplyMessage, 106 &Message.Header); 107 if (!NT_SUCCESS(Status)) 108 { 109 ERR("LsapRmServerThread - Failed to get message: 0x%lx\n", Status); 110 ReplyMessage = NULL; 111 continue; 112 } 113 114 /* Check if this is a connection request */ 115 if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST) 116 { 117 /* Reject connection request */ 118 NtAcceptConnectPort(&DummyPortHandle, 119 NULL, 120 &Message.Header, 121 FALSE, 122 NULL, 123 NULL); 124 125 /* Start over */ 126 ReplyMessage = NULL; 127 continue; 128 } 129 130 /* Check if this is an actual request */ 131 if (Message.Header.u2.s2.Type == LPC_REQUEST) 132 { 133 ReplyMessage = &Message.Header; 134 135 switch (Message.ApiNumber) 136 { 137 case LsapAdtWriteLogApi: 138 LsapAdtWriteLog(&Message); 139 break; 140 141 case LsapAsyncApi: 142 LsapAsync(&Message); 143 break; 144 145 case LsapComponentTestApi: 146 LsapComponentTest(&Message); 147 break; 148 149 default: 150 ERR("LsapRmServerThread - invalid API number: 0x%lx\n", 151 Message.ApiNumber); 152 ReplyMessage = NULL; 153 } 154 155 continue; 156 } 157 158 ERR("LsapRmServerThread - unexpected message type: 0x%lx\n", 159 Message.Header.u2.s2.Type); 160 161 /* Start over */ 162 ReplyMessage = NULL; 163 } 164 } 165 166 NTSTATUS 167 LsapRmInitializeServer(VOID) 168 { 169 UNICODE_STRING Name; 170 OBJECT_ATTRIBUTES ObjectAttributes; 171 SECURITY_QUALITY_OF_SERVICE SecurityQos; 172 HANDLE InitEvent; 173 HANDLE ThreadHandle; 174 DWORD ThreadId; 175 NTSTATUS Status; 176 177 /* Create the LSA command port */ 178 RtlInitUnicodeString(&Name, L"\\SeLsaCommandPort"); 179 InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL); 180 Status = NtCreatePort(&SeLsaCommandPort, 181 &ObjectAttributes, 182 0, 183 PORT_MAXIMUM_MESSAGE_LENGTH, 184 2 * PAGE_SIZE); 185 if (!NT_SUCCESS(Status)) 186 { 187 ERR("LsapRmInitializeServer - Port Create failed 0x%lx\n", Status); 188 return Status; 189 } 190 191 /* Open the LSA init event */ 192 RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent"); 193 InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL); 194 Status = NtOpenEvent(&InitEvent, 2, &ObjectAttributes); 195 if (!NT_SUCCESS(Status)) 196 { 197 ERR("LsapRmInitializeServer - Lsa Init Event Open failed 0x%lx\n", Status); 198 return Status; 199 } 200 201 /* Signal the kernel, that we are ready */ 202 Status = NtSetEvent(InitEvent, 0); 203 if (!NT_SUCCESS(Status)) 204 { 205 ERR("LsapRmInitializeServer - Set Init Event failed 0x%lx\n", Status); 206 return Status; 207 } 208 209 /* Setup the QoS structure */ 210 SecurityQos.ImpersonationLevel = SecurityIdentification; 211 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 212 SecurityQos.EffectiveOnly = TRUE; 213 214 /* Connect to the kernel server */ 215 RtlInitUnicodeString(&Name, L"\\SeRmCommandPort"); 216 Status = NtConnectPort(&SeRmCommandPort, 217 &Name, 218 &SecurityQos, 219 NULL, 220 NULL, 221 NULL, 222 NULL, 223 NULL); 224 if (!NT_SUCCESS(Status)) 225 { 226 ERR("LsapRmInitializeServer - Connect to Rm Command Port failed 0x%lx\n", Status); 227 return Status; 228 } 229 230 /* Create the server thread */ 231 ThreadHandle = CreateThread(NULL, 0, LsapRmServerThread, NULL, 0, &ThreadId); 232 if (ThreadHandle == NULL) 233 { 234 ERR("LsapRmInitializeServer - Create Thread failed 0x%lx\n", Status); 235 return STATUS_INSUFFICIENT_RESOURCES; 236 } 237 238 /* Close the server thread handle */ 239 CloseHandle(ThreadHandle); 240 241 return STATUS_SUCCESS; 242 } 243 244 NTSTATUS 245 LsapRmCreateLogonSession( 246 PLUID LogonId) 247 { 248 SEP_RM_API_MESSAGE RequestMessage; 249 SEP_RM_API_MESSAGE ReplyMessage; 250 NTSTATUS Status; 251 252 TRACE("LsapRmCreateLogonSession(%p)\n", LogonId); 253 254 RequestMessage.Header.u2.ZeroInit = 0; 255 RequestMessage.Header.u1.s1.TotalLength = 256 (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(LUID)); 257 RequestMessage.Header.u1.s1.DataLength = 258 RequestMessage.Header.u1.s1.TotalLength - 259 (CSHORT)sizeof(PORT_MESSAGE); 260 261 RequestMessage.ApiNumber = (ULONG)RmCreateLogonSession; 262 RtlCopyLuid(&RequestMessage.u.LogonLuid, LogonId); 263 264 ReplyMessage.Header.u2.ZeroInit = 0; 265 ReplyMessage.Header.u1.s1.TotalLength = 266 (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)); 267 ReplyMessage.Header.u1.s1.DataLength = 268 ReplyMessage.Header.u1.s1.TotalLength - 269 (CSHORT)sizeof(PORT_MESSAGE); 270 271 ReplyMessage.u.ResultStatus = STATUS_SUCCESS; 272 273 Status = NtRequestWaitReplyPort(SeRmCommandPort, 274 (PPORT_MESSAGE)&RequestMessage, 275 (PPORT_MESSAGE)&ReplyMessage); 276 if (NT_SUCCESS(Status)) 277 { 278 Status = ReplyMessage.u.ResultStatus; 279 } 280 281 return Status; 282 } 283 284 NTSTATUS 285 LsapRmDeleteLogonSession( 286 PLUID LogonId) 287 { 288 SEP_RM_API_MESSAGE RequestMessage; 289 SEP_RM_API_MESSAGE ReplyMessage; 290 NTSTATUS Status; 291 292 TRACE("LsapRmDeleteLogonSession(%p)\n", LogonId); 293 294 RequestMessage.Header.u2.ZeroInit = 0; 295 RequestMessage.Header.u1.s1.TotalLength = 296 (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(LUID)); 297 RequestMessage.Header.u1.s1.DataLength = 298 RequestMessage.Header.u1.s1.TotalLength - 299 (CSHORT)sizeof(PORT_MESSAGE); 300 301 RequestMessage.ApiNumber = (ULONG)RmDeleteLogonSession; 302 RtlCopyLuid(&RequestMessage.u.LogonLuid, LogonId); 303 304 ReplyMessage.Header.u2.ZeroInit = 0; 305 ReplyMessage.Header.u1.s1.TotalLength = 306 (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)); 307 ReplyMessage.Header.u1.s1.DataLength = 308 ReplyMessage.Header.u1.s1.TotalLength - 309 (CSHORT)sizeof(PORT_MESSAGE); 310 311 ReplyMessage.u.ResultStatus = STATUS_SUCCESS; 312 313 Status = NtRequestWaitReplyPort(SeRmCommandPort, 314 (PPORT_MESSAGE)&RequestMessage, 315 (PPORT_MESSAGE)&ReplyMessage); 316 if (NT_SUCCESS(Status)) 317 { 318 Status = ReplyMessage.u.ResultStatus; 319 } 320 321 return Status; 322 } 323