1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/lsalib/lsa.c 5 * PURPOSE: Client-side LSA functions 6 * UPDATE HISTORY: 7 * Created 05/08/00 8 */ 9 10 /* INCLUDES ******************************************************************/ 11 12 #include <ndk/exfuncs.h> 13 #include <ndk/lpctypes.h> 14 #include <ndk/lpcfuncs.h> 15 #include <ndk/mmfuncs.h> 16 #include <ndk/rtlfuncs.h> 17 #include <ndk/obfuncs.h> 18 #include <lsass/lsass.h> 19 20 #define NDEBUG 21 #include <debug.h> 22 23 /* FUNCTIONS *****************************************************************/ 24 25 /* 26 * @implemented 27 */ 28 NTSTATUS 29 NTAPI 30 LsaCallAuthenticationPackage(IN HANDLE LsaHandle, 31 IN ULONG AuthenticationPackage, 32 IN PVOID ProtocolSubmitBuffer, 33 IN ULONG SubmitBufferLength, 34 OUT PVOID *ProtocolReturnBuffer, 35 OUT PULONG ReturnBufferLength, 36 OUT PNTSTATUS ProtocolStatus) 37 { 38 LSA_API_MSG ApiMessage; 39 NTSTATUS Status; 40 41 DPRINT1("LsaCallAuthenticationPackage()\n"); 42 43 ApiMessage.ApiNumber = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE; 44 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.CallAuthenticationPackage); 45 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; 46 ApiMessage.h.u2.ZeroInit = 0; 47 48 ApiMessage.CallAuthenticationPackage.Request.AuthenticationPackage = AuthenticationPackage; 49 ApiMessage.CallAuthenticationPackage.Request.ProtocolSubmitBuffer = ProtocolSubmitBuffer; 50 ApiMessage.CallAuthenticationPackage.Request.SubmitBufferLength = SubmitBufferLength; 51 52 Status = ZwRequestWaitReplyPort(LsaHandle, 53 (PPORT_MESSAGE)&ApiMessage, 54 (PPORT_MESSAGE)&ApiMessage); 55 if (!NT_SUCCESS(Status)) 56 { 57 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); 58 return Status; 59 } 60 61 if (!NT_SUCCESS(ApiMessage.Status)) 62 { 63 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); 64 return ApiMessage.Status; 65 } 66 67 *ProtocolReturnBuffer = ApiMessage.CallAuthenticationPackage.Reply.ProtocolReturnBuffer; 68 *ReturnBufferLength = ApiMessage.CallAuthenticationPackage.Reply.ReturnBufferLength; 69 *ProtocolStatus = ApiMessage.CallAuthenticationPackage.Reply.ProtocolStatus; 70 71 return Status; 72 } 73 74 75 /* 76 * @implemented 77 */ 78 NTSTATUS 79 NTAPI 80 LsaDeregisterLogonProcess(IN HANDLE LsaHandle) 81 { 82 LSA_API_MSG ApiMessage; 83 NTSTATUS Status; 84 85 DPRINT("LsaDeregisterLogonProcess()\n"); 86 87 ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS; 88 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess); 89 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; 90 ApiMessage.h.u2.ZeroInit = 0; 91 92 Status = ZwRequestWaitReplyPort(LsaHandle, 93 (PPORT_MESSAGE)&ApiMessage, 94 (PPORT_MESSAGE)&ApiMessage); 95 if (!NT_SUCCESS(Status)) 96 { 97 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status); 98 return Status; 99 } 100 101 if (!NT_SUCCESS(ApiMessage.Status)) 102 { 103 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status); 104 return ApiMessage.Status; 105 } 106 107 ZwClose(LsaHandle); 108 109 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status); 110 111 return Status; 112 } 113 114 115 /* 116 * @implemented 117 */ 118 NTSTATUS 119 NTAPI 120 LsaFreeReturnBuffer(IN PVOID Buffer) 121 { 122 SIZE_T Size = 0; 123 124 return ZwFreeVirtualMemory(NtCurrentProcess(), 125 &Buffer, 126 &Size, 127 MEM_RELEASE); 128 } 129 130 131 /* 132 * @implemented 133 */ 134 NTSTATUS 135 NTAPI 136 LsaLookupAuthenticationPackage(IN HANDLE LsaHandle, 137 IN PLSA_STRING PackageName, 138 OUT PULONG AuthenticationPackage) 139 { 140 LSA_API_MSG ApiMessage; 141 NTSTATUS Status; 142 143 /* Check the package name length */ 144 if (PackageName->Length > LSASS_MAX_PACKAGE_NAME_LENGTH) 145 { 146 return STATUS_NAME_TOO_LONG; 147 } 148 149 ApiMessage.ApiNumber = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE; 150 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LookupAuthenticationPackage); 151 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; 152 ApiMessage.h.u2.ZeroInit = 0; 153 154 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength = PackageName->Length; 155 strncpy(ApiMessage.LookupAuthenticationPackage.Request.PackageName, 156 PackageName->Buffer, 157 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength); 158 ApiMessage.LookupAuthenticationPackage.Request.PackageName[ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength] = ANSI_NULL; 159 160 Status = ZwRequestWaitReplyPort(LsaHandle, 161 (PPORT_MESSAGE)&ApiMessage, 162 (PPORT_MESSAGE)&ApiMessage); 163 if (!NT_SUCCESS(Status)) 164 { 165 return Status; 166 } 167 168 if (!NT_SUCCESS(ApiMessage.Status)) 169 { 170 return ApiMessage.Status; 171 } 172 173 *AuthenticationPackage = ApiMessage.LookupAuthenticationPackage.Reply.Package; 174 175 return Status; 176 } 177 178 179 /* 180 * @implemented 181 */ 182 NTSTATUS 183 NTAPI 184 LsaLogonUser(IN HANDLE LsaHandle, 185 IN PLSA_STRING OriginName, 186 IN SECURITY_LOGON_TYPE LogonType, 187 IN ULONG AuthenticationPackage, 188 IN PVOID AuthenticationInformation, 189 IN ULONG AuthenticationInformationLength, 190 IN PTOKEN_GROUPS LocalGroups OPTIONAL, 191 IN PTOKEN_SOURCE SourceContext, 192 OUT PVOID *ProfileBuffer, 193 OUT PULONG ProfileBufferLength, 194 OUT PLUID LogonId, 195 OUT PHANDLE Token, 196 OUT PQUOTA_LIMITS Quotas, 197 OUT PNTSTATUS SubStatus) 198 { 199 LSA_API_MSG ApiMessage; 200 NTSTATUS Status; 201 202 ApiMessage.ApiNumber = LSASS_REQUEST_LOGON_USER; 203 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LogonUser); 204 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; 205 ApiMessage.h.u2.ZeroInit = 0; 206 207 ApiMessage.LogonUser.Request.OriginName = *OriginName; 208 ApiMessage.LogonUser.Request.LogonType = LogonType; 209 ApiMessage.LogonUser.Request.AuthenticationPackage = AuthenticationPackage; 210 ApiMessage.LogonUser.Request.AuthenticationInformation = AuthenticationInformation; 211 ApiMessage.LogonUser.Request.AuthenticationInformationLength = AuthenticationInformationLength; 212 ApiMessage.LogonUser.Request.LocalGroups = LocalGroups; 213 if (LocalGroups != NULL) 214 ApiMessage.LogonUser.Request.LocalGroupsCount = LocalGroups->GroupCount; 215 else 216 ApiMessage.LogonUser.Request.LocalGroupsCount = 0; 217 ApiMessage.LogonUser.Request.SourceContext = *SourceContext; 218 219 Status = ZwRequestWaitReplyPort(LsaHandle, 220 (PPORT_MESSAGE)&ApiMessage, 221 (PPORT_MESSAGE)&ApiMessage); 222 if (!NT_SUCCESS(Status)) 223 { 224 return Status; 225 } 226 227 *SubStatus = ApiMessage.LogonUser.Reply.SubStatus; 228 229 if (!NT_SUCCESS(ApiMessage.Status)) 230 { 231 return ApiMessage.Status; 232 } 233 234 *ProfileBuffer = ApiMessage.LogonUser.Reply.ProfileBuffer; 235 *ProfileBufferLength = ApiMessage.LogonUser.Reply.ProfileBufferLength; 236 *LogonId = ApiMessage.LogonUser.Reply.LogonId; 237 *Token = ApiMessage.LogonUser.Reply.Token; 238 *Quotas = ApiMessage.LogonUser.Reply.Quotas; 239 240 return Status; 241 } 242 243 244 /* 245 * @implemented 246 */ 247 NTSTATUS 248 NTAPI 249 LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName, 250 OUT PHANDLE LsaHandle, 251 OUT PLSA_OPERATIONAL_MODE OperationalMode) 252 { 253 SECURITY_QUALITY_OF_SERVICE SecurityQos; 254 LSA_CONNECTION_INFO ConnectInfo; 255 ULONG ConnectInfoLength = sizeof(ConnectInfo); 256 UNICODE_STRING PortName; 257 OBJECT_ATTRIBUTES ObjectAttributes; 258 UNICODE_STRING EventName; 259 HANDLE EventHandle; 260 NTSTATUS Status; 261 262 DPRINT("LsaRegisterLogonProcess()\n"); 263 264 /* Check the logon process name length */ 265 if (LogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH) 266 return STATUS_NAME_TOO_LONG; 267 268 /* Wait for the LSA authentication thread */ 269 RtlInitUnicodeString(&EventName, 270 L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED"); 271 InitializeObjectAttributes(&ObjectAttributes, 272 &EventName, 273 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 274 NULL, 275 NULL); 276 Status = ZwOpenEvent(&EventHandle, 277 SYNCHRONIZE, 278 &ObjectAttributes); 279 if (!NT_SUCCESS(Status)) 280 { 281 DPRINT("ZwOpenEvent failed (Status 0x%08lx)\n", Status); 282 283 Status = ZwCreateEvent(&EventHandle, 284 SYNCHRONIZE, 285 &ObjectAttributes, 286 NotificationEvent, 287 FALSE); 288 if (!NT_SUCCESS(Status)) 289 { 290 DPRINT1("ZwCreateEvent failed (Status 0x%08lx)\n", Status); 291 return Status; 292 } 293 } 294 295 Status = ZwWaitForSingleObject(EventHandle, 296 TRUE, 297 NULL); 298 ZwClose(EventHandle); 299 if (!NT_SUCCESS(Status)) 300 { 301 DPRINT1("ZwWaitForSingleObject failed (Status 0x%08lx)\n", Status); 302 return Status; 303 } 304 305 /* Establish the connection */ 306 RtlInitUnicodeString(&PortName, 307 L"\\LsaAuthenticationPort"); 308 309 SecurityQos.Length = sizeof(SecurityQos); 310 SecurityQos.ImpersonationLevel = SecurityIdentification; 311 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 312 SecurityQos.EffectiveOnly = TRUE; 313 314 strncpy(ConnectInfo.LogonProcessNameBuffer, 315 LogonProcessName->Buffer, 316 LogonProcessName->Length); 317 ConnectInfo.Length = LogonProcessName->Length; 318 ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL; 319 ConnectInfo.CreateContext = TRUE; 320 321 Status = ZwConnectPort(LsaHandle, 322 &PortName, 323 &SecurityQos, 324 NULL, 325 NULL, 326 NULL, 327 &ConnectInfo, 328 &ConnectInfoLength); 329 if (!NT_SUCCESS(Status)) 330 { 331 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status); 332 return Status; 333 } 334 335 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode); 336 *OperationalMode = ConnectInfo.OperationalMode; 337 338 if (!NT_SUCCESS(ConnectInfo.Status)) 339 { 340 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status); 341 } 342 343 return ConnectInfo.Status; 344 } 345