[SAMSRV]
[reactos.git] / reactos / dll / win32 / samsrv / samsrv.c
1 /*
2 * SAM Server DLL
3 * Copyright (C) 2005 Eric Kohl
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /* INCLUDES *****************************************************************/
21
22 #include "samsrv.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
25
26
27 /* GLOBALS *******************************************************************/
28
29 ENCRYPTED_NT_OWF_PASSWORD EmptyNtHash;
30 ENCRYPTED_LM_OWF_PASSWORD EmptyLmHash;
31
32
33 /* FUNCTIONS *****************************************************************/
34
35 static
36 NTSTATUS
37 SampInitHashes(VOID)
38 {
39 UNICODE_STRING EmptyNtPassword = {0, 0, NULL};
40 CHAR EmptyLmPassword[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
41 NTSTATUS Status;
42
43 /* Calculate the NT hash value of the empty password */
44 Status = SystemFunction007(&EmptyNtPassword,
45 (LPBYTE)&EmptyNtHash);
46 if (!NT_SUCCESS(Status))
47 {
48 ERR("Calculation of the empty NT hash failed (Status 0x%08lx)\n", Status);
49 return Status;
50 }
51
52 /* Calculate the LM hash value of the empty password */
53 Status = SystemFunction006(EmptyLmPassword,
54 (LPSTR)&EmptyLmHash);
55 if (!NT_SUCCESS(Status))
56 {
57 ERR("Calculation of the empty LM hash failed (Status 0x%08lx)\n", Status);
58 }
59
60 return Status;
61 }
62
63
64 NTSTATUS
65 NTAPI
66 SamIConnect(IN PSAMPR_SERVER_NAME ServerName,
67 OUT SAMPR_HANDLE *ServerHandle,
68 IN ACCESS_MASK DesiredAccess,
69 IN BOOLEAN Trusted)
70 {
71 PSAM_DB_OBJECT ServerObject;
72 NTSTATUS Status;
73
74 TRACE("SamIConnect(%p %p %lx %ld)\n",
75 ServerName, ServerHandle, DesiredAccess, Trusted);
76
77 /* Map generic access rights */
78 RtlMapGenericMask(&DesiredAccess,
79 pServerMapping);
80
81 /* Open the Server Object */
82 Status = SampOpenDbObject(NULL,
83 NULL,
84 L"SAM",
85 0,
86 SamDbServerObject,
87 DesiredAccess,
88 &ServerObject);
89 if (NT_SUCCESS(Status))
90 {
91 ServerObject->Trusted = Trusted;
92 *ServerHandle = (SAMPR_HANDLE)ServerObject;
93 }
94
95 TRACE("SamIConnect done (Status 0x%08lx)\n", Status);
96
97 return Status;
98 }
99
100
101 NTSTATUS
102 NTAPI
103 SamIInitialize(VOID)
104 {
105 NTSTATUS Status = STATUS_SUCCESS;
106
107 TRACE("SamIInitialize() called\n");
108
109 Status = SampInitHashes();
110 if (!NT_SUCCESS(Status))
111 return Status;
112
113 if (SampIsSetupRunning())
114 {
115 Status = SampInitializeRegistry();
116 if (!NT_SUCCESS(Status))
117 return Status;
118 }
119
120 /* Initialize the SAM database */
121 Status = SampInitDatabase();
122 if (!NT_SUCCESS(Status))
123 return Status;
124
125 /* Start the RPC server */
126 SampStartRpcServer();
127
128 return Status;
129 }
130
131
132 NTSTATUS
133 NTAPI
134 SampInitializeRegistry(VOID)
135 {
136 TRACE("SampInitializeRegistry() called\n");
137
138 SampInitializeSAM();
139
140 return STATUS_SUCCESS;
141 }
142
143
144 VOID
145 NTAPI
146 SamIFree_SAMPR_ENUMERATION_BUFFER(PSAMPR_ENUMERATION_BUFFER Ptr)
147 {
148 ULONG i;
149
150 if (Ptr != NULL)
151 {
152 if (Ptr->Buffer != NULL)
153 {
154 for (i = 0; i < Ptr->EntriesRead; i++)
155 {
156 if (Ptr->Buffer[i].Name.Buffer != NULL)
157 MIDL_user_free(Ptr->Buffer[i].Name.Buffer);
158 }
159
160 MIDL_user_free(Ptr->Buffer);
161 }
162
163 MIDL_user_free(Ptr);
164 }
165 }
166
167
168 VOID
169 NTAPI
170 SamIFree_SAMPR_PSID_ARRAY(PSAMPR_PSID_ARRAY Ptr)
171 {
172 if (Ptr != NULL)
173 {
174 if (Ptr->Sids != NULL)
175 {
176 MIDL_user_free(Ptr->Sids);
177 }
178 }
179 }
180
181
182 VOID
183 NTAPI
184 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr)
185 {
186 ULONG i;
187
188 if (Ptr != NULL)
189 {
190 if (Ptr->Element != NULL)
191 {
192 for (i = 0; i < Ptr->Count; i++)
193 {
194 if (Ptr->Element[i].Buffer != NULL)
195 MIDL_user_free(Ptr->Element[i].Buffer);
196 }
197
198 MIDL_user_free(Ptr->Element);
199 Ptr->Element = NULL;
200 Ptr->Count = 0;
201 }
202 }
203 }
204
205
206 VOID
207 NTAPI
208 SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr)
209 {
210 if (Ptr != NULL)
211 {
212 if (Ptr->Element != NULL)
213 {
214 MIDL_user_free(Ptr->Element);
215 Ptr->Element = NULL;
216 Ptr->Count = 0;
217 }
218 }
219 }
220
221
222 VOID
223 NTAPI
224 SamIFree_SAMPR_USER_INFO_BUFFER(PSAMPR_USER_INFO_BUFFER Ptr,
225 USER_INFORMATION_CLASS InformationClass)
226 {
227 if (Ptr == NULL)
228 return;
229
230 switch (InformationClass)
231 {
232 case UserGeneralInformation:
233 if (Ptr->General.UserName.Buffer != NULL)
234 MIDL_user_free(Ptr->General.UserName.Buffer);
235
236 if (Ptr->General.FullName.Buffer != NULL)
237 MIDL_user_free(Ptr->General.FullName.Buffer);
238
239 if (Ptr->General.AdminComment.Buffer != NULL)
240 MIDL_user_free(Ptr->General.AdminComment.Buffer);
241
242 if (Ptr->General.UserComment.Buffer != NULL)
243 MIDL_user_free(Ptr->General.UserComment.Buffer);
244 break;
245
246 case UserPreferencesInformation:
247 if (Ptr->Preferences.UserComment.Buffer != NULL)
248 MIDL_user_free(Ptr->Preferences.UserComment.Buffer);
249
250 if (Ptr->Preferences.Reserved1.Buffer != NULL)
251 MIDL_user_free(Ptr->Preferences.Reserved1.Buffer);
252 break;
253
254 case UserLogonInformation:
255 if (Ptr->Logon.UserName.Buffer != NULL)
256 MIDL_user_free(Ptr->Logon.UserName.Buffer);
257
258 if (Ptr->Logon.FullName.Buffer != NULL)
259 MIDL_user_free(Ptr->Logon.FullName.Buffer);
260
261 if (Ptr->Logon.HomeDirectory.Buffer != NULL)
262 MIDL_user_free(Ptr->Logon.HomeDirectory.Buffer);
263
264 if (Ptr->Logon.HomeDirectoryDrive.Buffer != NULL)
265 MIDL_user_free(Ptr->Logon.HomeDirectoryDrive.Buffer);
266
267 if (Ptr->Logon.ScriptPath.Buffer != NULL)
268 MIDL_user_free(Ptr->Logon.ScriptPath.Buffer);
269
270 if (Ptr->Logon.ProfilePath.Buffer != NULL)
271 MIDL_user_free(Ptr->Logon.ProfilePath.Buffer);
272
273 if (Ptr->Logon.WorkStations.Buffer != NULL)
274 MIDL_user_free(Ptr->Logon.WorkStations.Buffer);
275
276 if (Ptr->Logon.LogonHours.LogonHours != NULL)
277 MIDL_user_free(Ptr->Logon.LogonHours.LogonHours);
278 break;
279
280 case UserLogonHoursInformation:
281 if (Ptr->LogonHours.LogonHours.LogonHours != NULL)
282 MIDL_user_free(Ptr->LogonHours.LogonHours.LogonHours);
283 break;
284
285 case UserAccountInformation:
286 if (Ptr->Account.UserName.Buffer != NULL)
287 MIDL_user_free(Ptr->Account.UserName.Buffer);
288
289 if (Ptr->Account.FullName.Buffer != NULL)
290 MIDL_user_free(Ptr->Account.FullName.Buffer);
291
292 if (Ptr->Account.HomeDirectory.Buffer != NULL)
293 MIDL_user_free(Ptr->Account.HomeDirectory.Buffer);
294
295 if (Ptr->Account.HomeDirectoryDrive.Buffer != NULL)
296 MIDL_user_free(Ptr->Account.HomeDirectoryDrive.Buffer);
297
298 if (Ptr->Account.ScriptPath.Buffer != NULL)
299 MIDL_user_free(Ptr->Account.ScriptPath.Buffer);
300
301 if (Ptr->Account.ProfilePath.Buffer != NULL)
302 MIDL_user_free(Ptr->Account.ProfilePath.Buffer);
303
304 if (Ptr->Account.AdminComment.Buffer != NULL)
305 MIDL_user_free(Ptr->Account.AdminComment.Buffer);
306
307 if (Ptr->Account.WorkStations.Buffer != NULL)
308 MIDL_user_free(Ptr->Account.WorkStations.Buffer);
309
310 if (Ptr->Account.LogonHours.LogonHours != NULL)
311 MIDL_user_free(Ptr->Account.LogonHours.LogonHours);
312 break;
313
314 case UserNameInformation:
315 if (Ptr->Name.UserName.Buffer != NULL)
316 MIDL_user_free(Ptr->Name.UserName.Buffer);
317
318 if (Ptr->Name.FullName.Buffer != NULL)
319 MIDL_user_free(Ptr->Name.FullName.Buffer);
320 break;
321
322 case UserAccountNameInformation:
323 if (Ptr->AccountName.UserName.Buffer != NULL)
324 MIDL_user_free(Ptr->AccountName.UserName.Buffer);
325 break;
326
327 case UserFullNameInformation:
328 if (Ptr->FullName.FullName.Buffer != NULL)
329 MIDL_user_free(Ptr->FullName.FullName.Buffer);
330 break;
331
332 case UserPrimaryGroupInformation:
333 break;
334
335 case UserHomeInformation:
336 if (Ptr->Home.HomeDirectory.Buffer != NULL)
337 MIDL_user_free(Ptr->Home.HomeDirectory.Buffer);
338
339 if (Ptr->Home.HomeDirectoryDrive.Buffer != NULL)
340 MIDL_user_free(Ptr->Home.HomeDirectoryDrive.Buffer);
341 break;
342
343 case UserScriptInformation:
344 if (Ptr->Script.ScriptPath.Buffer != NULL)
345 MIDL_user_free(Ptr->Script.ScriptPath.Buffer);
346
347 case UserProfileInformation:
348 if (Ptr->Profile.ProfilePath.Buffer != NULL)
349 MIDL_user_free(Ptr->Profile.ProfilePath.Buffer);
350
351 case UserAdminCommentInformation:
352 if (Ptr->AdminComment.AdminComment.Buffer != NULL)
353 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer);
354 break;
355
356 case UserWorkStationsInformation:
357 if (Ptr->WorkStations.WorkStations.Buffer != NULL)
358 MIDL_user_free(Ptr->WorkStations.WorkStations.Buffer);
359 break;
360
361 case UserSetPasswordInformation:
362 ERR("Information class UserSetPasswordInformation cannot be queried!\n");
363 break;
364
365 case UserControlInformation:
366 break;
367
368 case UserExpiresInformation:
369 break;
370
371 case UserInternal1Information:
372 break;
373
374 case UserInternal2Information:
375 break;
376
377 case UserParametersInformation:
378 if (Ptr->Parameters.Parameters.Buffer != NULL)
379 MIDL_user_free(Ptr->Parameters.Parameters.Buffer);
380 break;
381
382 case UserAllInformation:
383 if (Ptr->All.UserName.Buffer != NULL)
384 MIDL_user_free(Ptr->All.UserName.Buffer);
385
386 if (Ptr->All.FullName.Buffer != NULL)
387 MIDL_user_free(Ptr->All.FullName.Buffer);
388
389 if (Ptr->All.HomeDirectory.Buffer != NULL)
390 MIDL_user_free(Ptr->All.HomeDirectory.Buffer);
391
392 if (Ptr->All.HomeDirectoryDrive.Buffer != NULL)
393 MIDL_user_free(Ptr->All.HomeDirectoryDrive.Buffer);
394
395 if (Ptr->All.ScriptPath.Buffer != NULL)
396 MIDL_user_free(Ptr->All.ScriptPath.Buffer);
397
398 if (Ptr->All.ProfilePath.Buffer != NULL)
399 MIDL_user_free(Ptr->All.ProfilePath.Buffer);
400
401 if (Ptr->All.AdminComment.Buffer != NULL)
402 MIDL_user_free(Ptr->All.AdminComment.Buffer);
403
404 if (Ptr->All.WorkStations.Buffer != NULL)
405 MIDL_user_free(Ptr->All.WorkStations.Buffer);
406
407 if (Ptr->All.UserComment.Buffer != NULL)
408 MIDL_user_free(Ptr->All.UserComment.Buffer);
409
410 if (Ptr->All.Parameters.Buffer != NULL)
411 MIDL_user_free(Ptr->All.Parameters.Buffer);
412
413 if (Ptr->All.LmOwfPassword.Buffer != NULL)
414 MIDL_user_free(Ptr->All.LmOwfPassword.Buffer);
415
416 if (Ptr->All.NtOwfPassword.Buffer != NULL)
417 MIDL_user_free(Ptr->All.NtOwfPassword.Buffer);
418
419 if (Ptr->All.PrivateData.Buffer != NULL)
420 MIDL_user_free(Ptr->All.PrivateData.Buffer);
421
422 if (Ptr->All.SecurityDescriptor.SecurityDescriptor != NULL)
423 MIDL_user_free(Ptr->All.SecurityDescriptor.SecurityDescriptor);
424
425 if (Ptr->All.LogonHours.LogonHours != NULL)
426 MIDL_user_free(Ptr->All.LogonHours.LogonHours);
427 break;
428
429 default:
430 FIXME("Unsupported information class: %lu\n", InformationClass);
431 break;
432 }
433
434 MIDL_user_free(Ptr);
435 }
436
437 /* EOF */