[CONUTILS] Make the headers C++ compatible.
[reactos.git] / sdk / lib / lsalib / lsa.c
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 }