470f2deeb87eeece99160ce9e16d163d37a8c092
[reactos.git] / lib / secur32 / lsa.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/secur32/lsa.c
6  * PURPOSE:         Client-side LSA functions
7  * UPDATE HISTORY:
8  *                  Created 05/08/00
9  */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <windows.h>
14 #include <ddk/ntddk.h>
15 #include <napi/lpc.h>
16 #include <lsass/lsass.h>
17 #include <string.h>
18
19 /* GLOBALS *******************************************************************/
20
21 extern HANDLE Secur32Heap;
22
23 /* FUNCTIONS *****************************************************************/
24
25 NTSTATUS STDCALL
26 LsaDeregisterLogonProcess(HANDLE LsaHandle)
27 {
28    LSASS_REQUEST Request;
29    LSASS_REPLY Reply;
30    NTSTATUS Status;
31       
32    Request.Header.DataSize = 0;
33    Request.Header.MessageSize = sizeof(LSASS_REQUEST);
34    Request.Type = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
35    Status = NtRequestWaitReplyPort(LsaHandle,
36                                    &Request.Header,
37                                    &Reply.Header);
38    if (!NT_SUCCESS(Status))
39      {
40         return(Status);
41      }
42    
43    if (!NT_SUCCESS(Reply.Status))
44      {
45         return(Reply.Status);
46      }
47    
48    return(Status);
49 }
50
51 NTSTATUS STDCALL
52 LsaConnectUntrusted(PHANDLE LsaHandle)
53 {
54   return(STATUS_UNSUCCESSFUL);
55 }
56
57 NTSTATUS STDCALL
58 LsaCallAuthenticationPackage(HANDLE LsaHandle,
59                              ULONG AuthenticationPackage,
60                              PVOID ProtocolSubmitBuffer,
61                              ULONG SubmitBufferLength,
62                              PVOID* ProtocolReturnBuffer,
63                              PULONG ReturnBufferLength,
64                              PNTSTATUS ProtocolStatus)
65 {
66    PLSASS_REQUEST Request;
67    PLSASS_REPLY Reply;
68    UCHAR RawRequest[MAX_MESSAGE_DATA];
69    UCHAR RawReply[MAX_MESSAGE_DATA];
70    NTSTATUS Status;
71    ULONG OutBufferSize;
72
73    Request = (PLSASS_REQUEST)RawRequest;
74    Reply = (PLSASS_REPLY)RawReply;
75    
76    Request->Header.DataSize = sizeof(LSASS_REQUEST) + SubmitBufferLength -
77      sizeof(LPC_MESSAGE_HEADER);
78    Request->Header.MessageSize = 
79      Request->Header.DataSize + sizeof(LPC_MESSAGE_HEADER);
80    Request->Type = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE;
81    Request->d.CallAuthenticationPackageRequest.AuthenticationPackage =
82      AuthenticationPackage;
83    Request->d.CallAuthenticationPackageRequest.InBufferLength =
84      SubmitBufferLength;
85    memcpy(Request->d.CallAuthenticationPackageRequest.InBuffer,
86           ProtocolSubmitBuffer,
87           SubmitBufferLength);
88    
89    Status = NtRequestWaitReplyPort(LsaHandle,
90                                    &Request->Header,
91                                    &Reply->Header);
92    if (!NT_SUCCESS(Status))
93      {
94         return(Status);
95      }
96    
97    if (!NT_SUCCESS(Reply->Status))
98      {
99         return(Reply->Status);
100      }
101    
102    OutBufferSize = Reply->d.CallAuthenticationPackageReply.OutBufferLength;
103    *ProtocolReturnBuffer = RtlAllocateHeap(Secur32Heap,
104                                            0,
105                                            OutBufferSize);
106    *ReturnBufferLength = OutBufferSize;
107    memcpy(*ProtocolReturnBuffer,
108           Reply->d.CallAuthenticationPackageReply.OutBuffer,
109           *ReturnBufferLength);
110    
111    return(Status);
112 }
113
114 NTSTATUS STDCALL
115 LsaFreeReturnBuffer(PVOID Buffer)
116 {
117    return(RtlFreeHeap(Secur32Heap, 0, Buffer));
118 }
119
120 NTSTATUS STDCALL
121 LsaLookupAuthenticationPackage(HANDLE LsaHandle,
122                                PLSA_STRING PackageName,
123                                PULONG AuthenticationPackage)
124 {
125    NTSTATUS Status;
126    PLSASS_REQUEST Request;
127    UCHAR RawRequest[MAX_MESSAGE_DATA];
128    LSASS_REPLY Reply;
129    
130    Request = (PLSASS_REQUEST)RawRequest;
131    Request->Header.DataSize = sizeof(LSASS_REQUEST) + PackageName->Length -
132      sizeof(LPC_MESSAGE_HEADER);
133    Request->Header.MessageSize = Request->Header.DataSize +
134      sizeof(LPC_MESSAGE_HEADER);
135    Request->Type = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
136    
137    Status = NtRequestWaitReplyPort(LsaHandle,
138                           &Request->Header,
139                           &Reply.Header);
140    if (!NT_SUCCESS(Status))
141      {
142         return(Status);
143      }
144    if (!NT_SUCCESS(Reply.Status))
145      {
146         return(Reply.Status);
147      }
148    
149    *AuthenticationPackage = Reply.d.LookupAuthenticationPackageReply.Package;
150    
151    return(Reply.Status);
152 }
153
154 NTSTATUS STDCALL
155 LsaLogonUser(HANDLE LsaHandle,
156              PLSA_STRING OriginName,
157              SECURITY_LOGON_TYPE LogonType,
158              ULONG AuthenticationPackage,
159              PVOID AuthenticationInformation,
160              ULONG AuthenticationInformationLength,
161              PTOKEN_GROUPS LocalGroups,
162              PTOKEN_SOURCE SourceContext,
163              PVOID* ProfileBuffer,
164              PULONG ProfileBufferLength,
165              PLUID LogonId,
166              PHANDLE Token,
167              PQUOTA_LIMITS Quotas,
168              PNTSTATUS SubStatus)
169 {
170    ULONG RequestLength;
171    ULONG CurrentLength;
172    PLSASS_REQUEST Request;
173    UCHAR RawMessage[MAX_MESSAGE_DATA];
174    PLSASS_REPLY Reply;
175    UCHAR RawReply[MAX_MESSAGE_DATA];
176    NTSTATUS Status;
177    
178    RequestLength = sizeof(LSASS_REQUEST) - sizeof(LPC_MESSAGE_HEADER);
179    RequestLength = RequestLength + (OriginName->Length * sizeof(WCHAR));
180    RequestLength = RequestLength + AuthenticationInformationLength;
181    RequestLength = RequestLength + 
182      (LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
183    
184    CurrentLength = 0;
185    Request = (PLSASS_REQUEST)RawMessage;
186    
187    Request->d.LogonUserRequest.OriginNameLength = OriginName->Length;
188    Request->d.LogonUserRequest.OriginName = (PWSTR)&RawMessage[CurrentLength];
189    memcpy((PWSTR)&RawMessage[CurrentLength],
190           OriginName->Buffer,
191           OriginName->Length * sizeof(WCHAR));
192    CurrentLength = CurrentLength + (OriginName->Length * sizeof(WCHAR));
193    
194    Request->d.LogonUserRequest.LogonType = LogonType;
195    
196    Request->d.LogonUserRequest.AuthenticationPackage =
197      AuthenticationPackage;
198    
199    Request->d.LogonUserRequest.AuthenticationInformation = 
200      (PVOID)&RawMessage[CurrentLength];
201    Request->d.LogonUserRequest.AuthenticationInformationLength =
202      AuthenticationInformationLength;
203    memcpy((PVOID)&RawMessage[CurrentLength],
204           AuthenticationInformation,
205           AuthenticationInformationLength);
206    CurrentLength = CurrentLength + AuthenticationInformationLength;
207    
208    Request->d.LogonUserRequest.LocalGroupsCount = LocalGroups->GroupCount;
209    Request->d.LogonUserRequest.LocalGroups = 
210      (PSID_AND_ATTRIBUTES)&RawMessage[CurrentLength];
211    memcpy((PSID_AND_ATTRIBUTES)&RawMessage[CurrentLength],
212           LocalGroups->Groups,
213           LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
214    
215    Request->d.LogonUserRequest.SourceContext = *SourceContext;
216    
217    Request->Type = LSASS_REQUEST_LOGON_USER;
218    Request->Header.DataSize = RequestLength - sizeof(LPC_MESSAGE_HEADER);
219    Request->Header.MessageSize = RequestLength + sizeof(LPC_MESSAGE_HEADER);
220    
221    Reply = (PLSASS_REPLY)RawReply;
222    
223    Status = NtRequestWaitReplyPort(LsaHandle,
224                                    &Request->Header,
225                                    &Reply->Header);
226    if (!NT_SUCCESS(Status))
227      {
228         return(Status);
229      }
230
231    *SubStatus = Reply->d.LogonUserReply.SubStatus;
232    
233    if (!NT_SUCCESS(Reply->Status))
234      {
235         return(Status);
236      }
237    
238    *ProfileBuffer = RtlAllocateHeap(Secur32Heap,
239                                     0,
240                                   Reply->d.LogonUserReply.ProfileBufferLength);
241    memcpy(*ProfileBuffer,
242           (PVOID)((ULONG)Reply->d.LogonUserReply.Data +
243                   (ULONG)Reply->d.LogonUserReply.ProfileBuffer),
244           Reply->d.LogonUserReply.ProfileBufferLength);
245    *LogonId = Reply->d.LogonUserReply.LogonId;
246    *Token = Reply->d.LogonUserReply.Token;
247    memcpy(Quotas, 
248           &Reply->d.LogonUserReply.Quotas,
249           sizeof(Reply->d.LogonUserReply.Quotas));
250    
251    return(Status);
252 }
253
254 NTSTATUS STDCALL
255 LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
256                         PHANDLE Handle,
257                         PLSA_OPERATIONAL_MODE OperationalMode)
258 {
259    UNICODE_STRING Portname = UNICODE_STRING_INITIALIZER(L"\\SeLsaCommandPort");
260    ULONG ConnectInfoLength;
261    NTSTATUS Status;
262    LSASS_REQUEST Request;
263    LSASS_REPLY Reply;
264
265    ConnectInfoLength = 0;
266    Status = NtConnectPort(Handle,
267                           &Portname,
268                           NULL,
269                           NULL,
270                           NULL,
271                           NULL,
272                           NULL,
273                           &ConnectInfoLength);
274    if (!NT_SUCCESS(Status))
275      {
276         return(Status);
277      }
278    
279    Request.Type = LSASS_REQUEST_REGISTER_LOGON_PROCESS;
280    Request.Header.DataSize = sizeof(LSASS_REQUEST) - 
281      sizeof(LPC_MESSAGE_HEADER);
282    Request.Header.MessageSize = sizeof(LSASS_REQUEST);
283    
284    Request.d.RegisterLogonProcessRequest.Length = LsaLogonProcessName->Length;
285    wcscpy(Request.d.RegisterLogonProcessRequest.LogonProcessNameBuffer,
286           LsaLogonProcessName->Buffer);
287    
288    Status = NtRequestWaitReplyPort(*Handle,
289                                    &Request.Header,
290                                    &Reply.Header);
291    if (!NT_SUCCESS(Status))
292      {
293         NtClose(*Handle);
294         *Handle = INVALID_HANDLE_VALUE;
295         return(Status);
296      }
297    
298    if (!NT_SUCCESS(Reply.Status))
299      {
300         NtClose(*Handle);
301         *Handle = INVALID_HANDLE_VALUE;
302         return(Status);
303      }
304    
305    *OperationalMode = Reply.d.RegisterLogonProcessReply.OperationalMode;
306    
307    return(Reply.Status);
308 }
309