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
10 /* INCLUDES ******************************************************************/
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 <psdk/ntsecapi.h>
19 #include <lsass/lsass.h>
24 /* GLOBALS *******************************************************************/
26 // FIXME: Do we really need this?!
27 #if !defined(__NTOSKRNL__) && !defined(_NTOSKRNL_) && !defined(_NTSYSTEM_)
28 extern HANDLE Secur32Heap
;
31 /* FUNCTIONS *****************************************************************/
33 /* This API is not defined and exported by NTOSKRNL */
34 #if !defined(__NTOSKRNL__) && !defined(_NTOSKRNL_) && !defined(_NTSYSTEM_)
40 LsaConnectUntrusted(OUT PHANDLE LsaHandle
)
43 UNICODE_STRING PortName
; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
44 SECURITY_QUALITY_OF_SERVICE SecurityQos
;
45 LSA_CONNECTION_INFO ConnectInfo
;
46 ULONG ConnectInfoLength
= sizeof(ConnectInfo
);
48 DPRINT("LsaConnectUntrusted(%p)\n", LsaHandle
);
50 // TODO: Wait on L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED" event
51 // for the LSA server to be ready, and because we are untrusted,
52 // we may need to impersonate ourselves before!
54 RtlInitUnicodeString(&PortName
, L
"\\LsaAuthenticationPort");
56 SecurityQos
.Length
= sizeof(SecurityQos
);
57 SecurityQos
.ImpersonationLevel
= SecurityIdentification
;
58 SecurityQos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
59 SecurityQos
.EffectiveOnly
= TRUE
;
61 RtlZeroMemory(&ConnectInfo
,
64 ConnectInfo
.CreateContext
= TRUE
;
66 Status
= ZwConnectPort(LsaHandle
,
74 if (!NT_SUCCESS(Status
))
76 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status
);
80 if (!NT_SUCCESS(ConnectInfo
.Status
))
82 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo
.Status
);
85 return ConnectInfo
.Status
;
94 LsaCallAuthenticationPackage(IN HANDLE LsaHandle
,
95 IN ULONG AuthenticationPackage
,
96 IN PVOID ProtocolSubmitBuffer
,
97 IN ULONG SubmitBufferLength
,
98 OUT PVOID
*ProtocolReturnBuffer
,
99 OUT PULONG ReturnBufferLength
,
100 OUT PNTSTATUS ProtocolStatus
)
103 LSA_API_MSG ApiMessage
;
105 DPRINT1("LsaCallAuthenticationPackage()\n");
107 ApiMessage
.ApiNumber
= LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE
;
108 ApiMessage
.h
.u1
.s1
.DataLength
= LSA_PORT_DATA_SIZE(ApiMessage
.CallAuthenticationPackage
);
109 ApiMessage
.h
.u1
.s1
.TotalLength
= LSA_PORT_MESSAGE_SIZE
;
110 ApiMessage
.h
.u2
.ZeroInit
= 0;
112 ApiMessage
.CallAuthenticationPackage
.Request
.AuthenticationPackage
= AuthenticationPackage
;
113 ApiMessage
.CallAuthenticationPackage
.Request
.ProtocolSubmitBuffer
= ProtocolSubmitBuffer
;
114 ApiMessage
.CallAuthenticationPackage
.Request
.SubmitBufferLength
= SubmitBufferLength
;
116 Status
= ZwRequestWaitReplyPort(LsaHandle
,
117 (PPORT_MESSAGE
)&ApiMessage
,
118 (PPORT_MESSAGE
)&ApiMessage
);
119 if (!NT_SUCCESS(Status
))
121 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status
);
125 if (!NT_SUCCESS(ApiMessage
.Status
))
127 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage
.Status
);
128 return ApiMessage
.Status
;
131 *ProtocolReturnBuffer
= ApiMessage
.CallAuthenticationPackage
.Reply
.ProtocolReturnBuffer
;
132 *ReturnBufferLength
= ApiMessage
.CallAuthenticationPackage
.Reply
.ReturnBufferLength
;
133 *ProtocolStatus
= ApiMessage
.CallAuthenticationPackage
.Reply
.ProtocolStatus
;
144 LsaFreeReturnBuffer(IN PVOID Buffer
)
147 return ZwFreeVirtualMemory(NtCurrentProcess(),
159 LsaLookupAuthenticationPackage(IN HANDLE LsaHandle
,
160 IN PLSA_STRING PackageName
,
161 OUT PULONG AuthenticationPackage
)
164 LSA_API_MSG ApiMessage
;
166 /* Check the package name length */
167 if (PackageName
->Length
> LSASS_MAX_PACKAGE_NAME_LENGTH
)
169 return STATUS_NAME_TOO_LONG
;
172 ApiMessage
.ApiNumber
= LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE
;
173 ApiMessage
.h
.u1
.s1
.DataLength
= LSA_PORT_DATA_SIZE(ApiMessage
.LookupAuthenticationPackage
);
174 ApiMessage
.h
.u1
.s1
.TotalLength
= LSA_PORT_MESSAGE_SIZE
;
175 ApiMessage
.h
.u2
.ZeroInit
= 0;
177 ApiMessage
.LookupAuthenticationPackage
.Request
.PackageNameLength
= PackageName
->Length
;
178 strncpy(ApiMessage
.LookupAuthenticationPackage
.Request
.PackageName
,
180 ApiMessage
.LookupAuthenticationPackage
.Request
.PackageNameLength
);
181 ApiMessage
.LookupAuthenticationPackage
.Request
.PackageName
[ApiMessage
.LookupAuthenticationPackage
.Request
.PackageNameLength
] = ANSI_NULL
;
183 Status
= ZwRequestWaitReplyPort(LsaHandle
,
184 (PPORT_MESSAGE
)&ApiMessage
,
185 (PPORT_MESSAGE
)&ApiMessage
);
186 if (!NT_SUCCESS(Status
))
191 if (!NT_SUCCESS(ApiMessage
.Status
))
193 return ApiMessage
.Status
;
196 *AuthenticationPackage
= ApiMessage
.LookupAuthenticationPackage
.Reply
.Package
;
207 LsaLogonUser(IN HANDLE LsaHandle
,
208 IN PLSA_STRING OriginName
,
209 IN SECURITY_LOGON_TYPE LogonType
,
210 IN ULONG AuthenticationPackage
,
211 IN PVOID AuthenticationInformation
,
212 IN ULONG AuthenticationInformationLength
,
213 IN PTOKEN_GROUPS LocalGroups OPTIONAL
,
214 IN PTOKEN_SOURCE SourceContext
,
215 OUT PVOID
*ProfileBuffer
,
216 OUT PULONG ProfileBufferLength
,
219 OUT PQUOTA_LIMITS Quotas
,
220 OUT PNTSTATUS SubStatus
)
223 LSA_API_MSG ApiMessage
;
225 ApiMessage
.ApiNumber
= LSASS_REQUEST_LOGON_USER
;
226 ApiMessage
.h
.u1
.s1
.DataLength
= LSA_PORT_DATA_SIZE(ApiMessage
.LogonUser
);
227 ApiMessage
.h
.u1
.s1
.TotalLength
= LSA_PORT_MESSAGE_SIZE
;
228 ApiMessage
.h
.u2
.ZeroInit
= 0;
230 ApiMessage
.LogonUser
.Request
.OriginName
= *OriginName
;
231 ApiMessage
.LogonUser
.Request
.LogonType
= LogonType
;
232 ApiMessage
.LogonUser
.Request
.AuthenticationPackage
= AuthenticationPackage
;
233 ApiMessage
.LogonUser
.Request
.AuthenticationInformation
= AuthenticationInformation
;
234 ApiMessage
.LogonUser
.Request
.AuthenticationInformationLength
= AuthenticationInformationLength
;
235 ApiMessage
.LogonUser
.Request
.LocalGroups
= LocalGroups
;
236 if (LocalGroups
!= NULL
)
237 ApiMessage
.LogonUser
.Request
.LocalGroupsCount
= LocalGroups
->GroupCount
;
239 ApiMessage
.LogonUser
.Request
.LocalGroupsCount
= 0;
240 ApiMessage
.LogonUser
.Request
.SourceContext
= *SourceContext
;
242 Status
= ZwRequestWaitReplyPort(LsaHandle
,
243 (PPORT_MESSAGE
)&ApiMessage
,
244 (PPORT_MESSAGE
)&ApiMessage
);
245 if (!NT_SUCCESS(Status
))
250 *SubStatus
= ApiMessage
.LogonUser
.Reply
.SubStatus
;
252 if (!NT_SUCCESS(ApiMessage
.Status
))
254 return ApiMessage
.Status
;
257 *ProfileBuffer
= ApiMessage
.LogonUser
.Reply
.ProfileBuffer
;
258 *ProfileBufferLength
= ApiMessage
.LogonUser
.Reply
.ProfileBufferLength
;
259 *LogonId
= ApiMessage
.LogonUser
.Reply
.LogonId
;
260 *Token
= ApiMessage
.LogonUser
.Reply
.Token
;
261 *Quotas
= ApiMessage
.LogonUser
.Reply
.Quotas
;
272 LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName
,
273 OUT PHANDLE LsaHandle
,
274 OUT PLSA_OPERATIONAL_MODE OperationalMode
)
278 UNICODE_STRING PortName
; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
279 OBJECT_ATTRIBUTES ObjectAttributes
;
280 SECURITY_QUALITY_OF_SERVICE SecurityQos
;
281 LSA_CONNECTION_INFO ConnectInfo
;
282 ULONG ConnectInfoLength
= sizeof(ConnectInfo
);
284 DPRINT("LsaRegisterLogonProcess()\n");
286 /* Check the logon process name length */
287 if (LogonProcessName
->Length
> LSASS_MAX_LOGON_PROCESS_NAME_LENGTH
)
288 return STATUS_NAME_TOO_LONG
;
291 * First check whether the LSA server is ready:
292 * open the LSA event and wait on it.
294 // Note that we just reuse the 'PortName' variable here.
295 RtlInitUnicodeString(&PortName
, L
"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
296 InitializeObjectAttributes(&ObjectAttributes
,
298 OBJ_CASE_INSENSITIVE
,
301 Status
= NtOpenEvent(&EventHandle
, SYNCHRONIZE
, &ObjectAttributes
);
302 if (!NT_SUCCESS(Status
))
304 DPRINT1("NtOpenEvent failed (Status 0x%08lx)\n", Status
);
308 Status
= NtWaitForSingleObject(EventHandle
, TRUE
, NULL
);
309 NtClose(EventHandle
);
310 if (!NT_SUCCESS(Status
))
312 DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status
);
316 /* Now attempt the connection */
317 RtlInitUnicodeString(&PortName
, L
"\\LsaAuthenticationPort");
319 SecurityQos
.Length
= sizeof(SecurityQos
);
320 SecurityQos
.ImpersonationLevel
= SecurityIdentification
;
321 SecurityQos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
322 SecurityQos
.EffectiveOnly
= TRUE
;
324 strncpy(ConnectInfo
.LogonProcessNameBuffer
,
325 LogonProcessName
->Buffer
,
326 LogonProcessName
->Length
);
327 ConnectInfo
.Length
= LogonProcessName
->Length
;
328 ConnectInfo
.LogonProcessNameBuffer
[ConnectInfo
.Length
] = ANSI_NULL
;
329 ConnectInfo
.CreateContext
= TRUE
;
331 Status
= ZwConnectPort(LsaHandle
,
339 if (!NT_SUCCESS(Status
))
341 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status
);
345 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo
.OperationalMode
);
346 *OperationalMode
= ConnectInfo
.OperationalMode
;
348 if (!NT_SUCCESS(ConnectInfo
.Status
))
350 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo
.Status
);
353 return ConnectInfo
.Status
;
362 LsaDeregisterLogonProcess(IN HANDLE LsaHandle
)
365 LSA_API_MSG ApiMessage
;
367 DPRINT("LsaDeregisterLogonProcess()\n");
369 ApiMessage
.ApiNumber
= LSASS_REQUEST_DEREGISTER_LOGON_PROCESS
;
370 ApiMessage
.h
.u1
.s1
.DataLength
= LSA_PORT_DATA_SIZE(ApiMessage
.DeregisterLogonProcess
);
371 ApiMessage
.h
.u1
.s1
.TotalLength
= LSA_PORT_MESSAGE_SIZE
;
372 ApiMessage
.h
.u2
.ZeroInit
= 0;
374 Status
= ZwRequestWaitReplyPort(LsaHandle
,
375 (PPORT_MESSAGE
)&ApiMessage
,
376 (PPORT_MESSAGE
)&ApiMessage
);
377 if (!NT_SUCCESS(Status
))
379 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status
);
383 if (!NT_SUCCESS(ApiMessage
.Status
))
385 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage
.Status
);
386 return ApiMessage
.Status
;
391 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status
);