935f32b99200c4ef37712ba612c0c51d03e468c5
[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 NTSTATUS Status;
213 #if 0
214 HANDLE EventHandle;
215 #endif
216 UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
217 #if 0
218 OBJECT_ATTRIBUTES ObjectAttributes;
219 #endif
220 SECURITY_QUALITY_OF_SERVICE SecurityQos;
221 LSA_CONNECTION_INFO ConnectInfo;
222 ULONG ConnectInfoLength = sizeof(ConnectInfo);
223
224 DPRINT("LsaRegisterLogonProcess()\n");
225
226 /* Check the logon process name length */
227 if (LogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
228 return STATUS_NAME_TOO_LONG;
229
230 #if 0
231 /*
232 * First check whether the LSA server is ready:
233 * open the LSA event and wait on it.
234 */
235 // Note that we just reuse the 'PortName' variable here.
236 RtlInitUnicodeString(&PortName, L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
237 InitializeObjectAttributes(&ObjectAttributes,
238 &PortName,
239 OBJ_CASE_INSENSITIVE,
240 NULL,
241 NULL);
242 Status = NtOpenEvent(&EventHandle, SYNCHRONIZE, &ObjectAttributes);
243 if (!NT_SUCCESS(Status))
244 {
245 DPRINT1("NtOpenEvent failed (Status 0x%08lx)\n", Status);
246 return Status;
247 }
248
249 Status = NtWaitForSingleObject(EventHandle, TRUE, NULL);
250 NtClose(EventHandle);
251 if (!NT_SUCCESS(Status))
252 {
253 DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status);
254 return Status;
255 }
256 #endif
257
258 /* Now attempt the connection */
259 RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort");
260
261 SecurityQos.Length = sizeof(SecurityQos);
262 SecurityQos.ImpersonationLevel = SecurityIdentification;
263 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
264 SecurityQos.EffectiveOnly = TRUE;
265
266 strncpy(ConnectInfo.LogonProcessNameBuffer,
267 LogonProcessName->Buffer,
268 LogonProcessName->Length);
269 ConnectInfo.Length = LogonProcessName->Length;
270 ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL;
271 ConnectInfo.CreateContext = TRUE;
272
273 Status = ZwConnectPort(LsaHandle,
274 &PortName,
275 &SecurityQos,
276 NULL,
277 NULL,
278 NULL,
279 &ConnectInfo,
280 &ConnectInfoLength);
281 if (!NT_SUCCESS(Status))
282 {
283 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
284 return Status;
285 }
286
287 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode);
288 *OperationalMode = ConnectInfo.OperationalMode;
289
290 if (!NT_SUCCESS(ConnectInfo.Status))
291 {
292 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
293 }
294
295 return ConnectInfo.Status;
296 }
297
298
299 /*
300 * @implemented
301 */
302 NTSTATUS
303 NTAPI
304 LsaDeregisterLogonProcess(IN HANDLE LsaHandle)
305 {
306 NTSTATUS Status;
307 LSA_API_MSG ApiMessage;
308
309 DPRINT("LsaDeregisterLogonProcess()\n");
310
311 ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
312 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess);
313 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
314 ApiMessage.h.u2.ZeroInit = 0;
315
316 Status = ZwRequestWaitReplyPort(LsaHandle,
317 (PPORT_MESSAGE)&ApiMessage,
318 (PPORT_MESSAGE)&ApiMessage);
319 if (!NT_SUCCESS(Status))
320 {
321 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
322 return Status;
323 }
324
325 if (!NT_SUCCESS(ApiMessage.Status))
326 {
327 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
328 return ApiMessage.Status;
329 }
330
331 NtClose(LsaHandle);
332
333 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
334
335 return Status;
336 }