[LSALIB]
[reactos.git] / reactos / 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 NTSTATUS Status;
39 LSA_API_MSG ApiMessage;
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 LsaFreeReturnBuffer(IN PVOID Buffer)
81 {
82 SIZE_T Size = 0;
83 return ZwFreeVirtualMemory(NtCurrentProcess(),
84 &Buffer,
85 &Size,
86 MEM_RELEASE);
87 }
88
89
90 /*
91 * @implemented
92 */
93 NTSTATUS
94 NTAPI
95 LsaLookupAuthenticationPackage(IN HANDLE LsaHandle,
96 IN PLSA_STRING PackageName,
97 OUT PULONG AuthenticationPackage)
98 {
99 NTSTATUS Status;
100 LSA_API_MSG ApiMessage;
101
102 /* Check the package name length */
103 if (PackageName->Length > LSASS_MAX_PACKAGE_NAME_LENGTH)
104 {
105 return STATUS_NAME_TOO_LONG;
106 }
107
108 ApiMessage.ApiNumber = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
109 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LookupAuthenticationPackage);
110 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
111 ApiMessage.h.u2.ZeroInit = 0;
112
113 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength = PackageName->Length;
114 strncpy(ApiMessage.LookupAuthenticationPackage.Request.PackageName,
115 PackageName->Buffer,
116 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength);
117 ApiMessage.LookupAuthenticationPackage.Request.PackageName[ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength] = ANSI_NULL;
118
119 Status = ZwRequestWaitReplyPort(LsaHandle,
120 (PPORT_MESSAGE)&ApiMessage,
121 (PPORT_MESSAGE)&ApiMessage);
122 if (!NT_SUCCESS(Status))
123 {
124 return Status;
125 }
126
127 if (!NT_SUCCESS(ApiMessage.Status))
128 {
129 return ApiMessage.Status;
130 }
131
132 *AuthenticationPackage = ApiMessage.LookupAuthenticationPackage.Reply.Package;
133
134 return Status;
135 }
136
137
138 /*
139 * @implemented
140 */
141 NTSTATUS
142 NTAPI
143 LsaLogonUser(IN HANDLE LsaHandle,
144 IN PLSA_STRING OriginName,
145 IN SECURITY_LOGON_TYPE LogonType,
146 IN ULONG AuthenticationPackage,
147 IN PVOID AuthenticationInformation,
148 IN ULONG AuthenticationInformationLength,
149 IN PTOKEN_GROUPS LocalGroups OPTIONAL,
150 IN PTOKEN_SOURCE SourceContext,
151 OUT PVOID *ProfileBuffer,
152 OUT PULONG ProfileBufferLength,
153 OUT PLUID LogonId,
154 OUT PHANDLE Token,
155 OUT PQUOTA_LIMITS Quotas,
156 OUT PNTSTATUS SubStatus)
157 {
158 NTSTATUS Status;
159 LSA_API_MSG ApiMessage;
160
161 ApiMessage.ApiNumber = LSASS_REQUEST_LOGON_USER;
162 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LogonUser);
163 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
164 ApiMessage.h.u2.ZeroInit = 0;
165
166 ApiMessage.LogonUser.Request.OriginName = *OriginName;
167 ApiMessage.LogonUser.Request.LogonType = LogonType;
168 ApiMessage.LogonUser.Request.AuthenticationPackage = AuthenticationPackage;
169 ApiMessage.LogonUser.Request.AuthenticationInformation = AuthenticationInformation;
170 ApiMessage.LogonUser.Request.AuthenticationInformationLength = AuthenticationInformationLength;
171 ApiMessage.LogonUser.Request.LocalGroups = LocalGroups;
172 if (LocalGroups != NULL)
173 ApiMessage.LogonUser.Request.LocalGroupsCount = LocalGroups->GroupCount;
174 else
175 ApiMessage.LogonUser.Request.LocalGroupsCount = 0;
176 ApiMessage.LogonUser.Request.SourceContext = *SourceContext;
177
178 Status = ZwRequestWaitReplyPort(LsaHandle,
179 (PPORT_MESSAGE)&ApiMessage,
180 (PPORT_MESSAGE)&ApiMessage);
181 if (!NT_SUCCESS(Status))
182 {
183 return Status;
184 }
185
186 *SubStatus = ApiMessage.LogonUser.Reply.SubStatus;
187
188 if (!NT_SUCCESS(ApiMessage.Status))
189 {
190 return ApiMessage.Status;
191 }
192
193 *ProfileBuffer = ApiMessage.LogonUser.Reply.ProfileBuffer;
194 *ProfileBufferLength = ApiMessage.LogonUser.Reply.ProfileBufferLength;
195 *LogonId = ApiMessage.LogonUser.Reply.LogonId;
196 *Token = ApiMessage.LogonUser.Reply.Token;
197 *Quotas = ApiMessage.LogonUser.Reply.Quotas;
198
199 return Status;
200 }
201
202
203 /*
204 * @implemented
205 */
206 NTSTATUS
207 NTAPI
208 LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName,
209 OUT PHANDLE LsaHandle,
210 OUT PLSA_OPERATIONAL_MODE OperationalMode)
211 {
212 SECURITY_QUALITY_OF_SERVICE SecurityQos;
213 LSA_CONNECTION_INFO ConnectInfo;
214 ULONG ConnectInfoLength = sizeof(ConnectInfo);
215 UNICODE_STRING PortName;
216 OBJECT_ATTRIBUTES ObjectAttributes;
217 UNICODE_STRING EventName;
218 HANDLE EventHandle;
219 NTSTATUS Status;
220
221 DPRINT("LsaRegisterLogonProcess()\n");
222
223 /* Check the logon process name length */
224 if (LogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
225 return STATUS_NAME_TOO_LONG;
226
227 /* Wait for the LSA authentication thread */
228 RtlInitUnicodeString(&EventName,
229 L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
230 InitializeObjectAttributes(&ObjectAttributes,
231 &EventName,
232 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
233 NULL,
234 NULL);
235 Status = ZwOpenEvent(&EventHandle,
236 SYNCHRONIZE,
237 &ObjectAttributes);
238 if (!NT_SUCCESS(Status))
239 {
240 DPRINT"NtOpenEvent failed (Status 0x%08lx)\n", Status);
241
242 Status = ZwCreateEvent(&EventHandle,
243 SYNCHRONIZE,
244 &ObjectAttributes,
245 NotificationEvent,
246 FALSE);
247 if (!NT_SUCCESS(Status))
248 {
249 DPRINT1("NtCreateEvent failed (Status 0x%08lx)\n", Status);
250 return Status;
251 }
252 }
253
254 Status = ZwWaitForSingleObject(EventHandle,
255 TRUE,
256 NULL);
257 ZwClose(EventHandle);
258 if (!NT_SUCCESS(Status))
259 {
260 DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status);
261 return Status;
262 }
263
264 /* Establish the connection */
265 RtlInitUnicodeString(&PortName,
266 L"\\LsaAuthenticationPort");
267
268 SecurityQos.Length = sizeof(SecurityQos);
269 SecurityQos.ImpersonationLevel = SecurityIdentification;
270 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
271 SecurityQos.EffectiveOnly = TRUE;
272
273 strncpy(ConnectInfo.LogonProcessNameBuffer,
274 LogonProcessName->Buffer,
275 LogonProcessName->Length);
276 ConnectInfo.Length = LogonProcessName->Length;
277 ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL;
278 ConnectInfo.CreateContext = TRUE;
279
280 Status = ZwConnectPort(LsaHandle,
281 &PortName,
282 &SecurityQos,
283 NULL,
284 NULL,
285 NULL,
286 &ConnectInfo,
287 &ConnectInfoLength);
288 if (!NT_SUCCESS(Status))
289 {
290 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
291 return Status;
292 }
293
294 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode);
295 *OperationalMode = ConnectInfo.OperationalMode;
296
297 if (!NT_SUCCESS(ConnectInfo.Status))
298 {
299 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
300 }
301
302 return ConnectInfo.Status;
303 }
304
305
306 /*
307 * @implemented
308 */
309 NTSTATUS
310 NTAPI
311 LsaDeregisterLogonProcess(IN HANDLE LsaHandle)
312 {
313 NTSTATUS Status;
314 LSA_API_MSG ApiMessage;
315
316 DPRINT("LsaDeregisterLogonProcess()\n");
317
318 ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
319 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess);
320 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
321 ApiMessage.h.u2.ZeroInit = 0;
322
323 Status = ZwRequestWaitReplyPort(LsaHandle,
324 (PPORT_MESSAGE)&ApiMessage,
325 (PPORT_MESSAGE)&ApiMessage);
326 if (!NT_SUCCESS(Status))
327 {
328 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
329 return Status;
330 }
331
332 if (!NT_SUCCESS(ApiMessage.Status))
333 {
334 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
335 return ApiMessage.Status;
336 }
337
338 ZwClose(LsaHandle);
339
340 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
341
342 return Status;
343 }