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
)
280 UNICODE_STRING PortName
; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
282 OBJECT_ATTRIBUTES ObjectAttributes
;
284 SECURITY_QUALITY_OF_SERVICE SecurityQos
;
285 LSA_CONNECTION_INFO ConnectInfo
;
286 ULONG ConnectInfoLength
= sizeof(ConnectInfo
);
288 DPRINT("LsaRegisterLogonProcess()\n");
290 /* Check the logon process name length */
291 if (LogonProcessName
->Length
> LSASS_MAX_LOGON_PROCESS_NAME_LENGTH
)
292 return STATUS_NAME_TOO_LONG
;
296 * First check whether the LSA server is ready:
297 * open the LSA event and wait on it.
299 // Note that we just reuse the 'PortName' variable here.
300 RtlInitUnicodeString(&PortName
, L
"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
301 InitializeObjectAttributes(&ObjectAttributes
,
303 OBJ_CASE_INSENSITIVE
,
306 Status
= NtOpenEvent(&EventHandle
, SYNCHRONIZE
, &ObjectAttributes
);
307 if (!NT_SUCCESS(Status
))
309 DPRINT1("NtOpenEvent failed (Status 0x%08lx)\n", Status
);
313 Status
= NtWaitForSingleObject(EventHandle
, TRUE
, NULL
);
314 NtClose(EventHandle
);
315 if (!NT_SUCCESS(Status
))
317 DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status
);
322 /* Now attempt the connection */
323 RtlInitUnicodeString(&PortName
, L
"\\LsaAuthenticationPort");
325 SecurityQos
.Length
= sizeof(SecurityQos
);
326 SecurityQos
.ImpersonationLevel
= SecurityIdentification
;
327 SecurityQos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
328 SecurityQos
.EffectiveOnly
= TRUE
;
330 strncpy(ConnectInfo
.LogonProcessNameBuffer
,
331 LogonProcessName
->Buffer
,
332 LogonProcessName
->Length
);
333 ConnectInfo
.Length
= LogonProcessName
->Length
;
334 ConnectInfo
.LogonProcessNameBuffer
[ConnectInfo
.Length
] = ANSI_NULL
;
335 ConnectInfo
.CreateContext
= TRUE
;
337 Status
= ZwConnectPort(LsaHandle
,
345 if (!NT_SUCCESS(Status
))
347 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status
);
351 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo
.OperationalMode
);
352 *OperationalMode
= ConnectInfo
.OperationalMode
;
354 if (!NT_SUCCESS(ConnectInfo
.Status
))
356 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo
.Status
);
359 return ConnectInfo
.Status
;
368 LsaDeregisterLogonProcess(IN HANDLE LsaHandle
)
371 LSA_API_MSG ApiMessage
;
373 DPRINT("LsaDeregisterLogonProcess()\n");
375 ApiMessage
.ApiNumber
= LSASS_REQUEST_DEREGISTER_LOGON_PROCESS
;
376 ApiMessage
.h
.u1
.s1
.DataLength
= LSA_PORT_DATA_SIZE(ApiMessage
.DeregisterLogonProcess
);
377 ApiMessage
.h
.u1
.s1
.TotalLength
= LSA_PORT_MESSAGE_SIZE
;
378 ApiMessage
.h
.u2
.ZeroInit
= 0;
380 Status
= ZwRequestWaitReplyPort(LsaHandle
,
381 (PPORT_MESSAGE
)&ApiMessage
,
382 (PPORT_MESSAGE
)&ApiMessage
);
383 if (!NT_SUCCESS(Status
))
385 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status
);
389 if (!NT_SUCCESS(ApiMessage
.Status
))
391 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage
.Status
);
392 return ApiMessage
.Status
;
397 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status
);