[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 #include "samsrv.h"
21
22 #include <samsrv/samsrv.h>
23
24 /* GLOBALS *******************************************************************/
25
26 ENCRYPTED_NT_OWF_PASSWORD EmptyNtHash;
27 ENCRYPTED_LM_OWF_PASSWORD EmptyLmHash;
28 RTL_RESOURCE SampResource;
29
30
31 /* FUNCTIONS *****************************************************************/
32
33 static
34 NTSTATUS
35 SampInitHashes(VOID)
36 {
37 UNICODE_STRING EmptyNtPassword = {0, 0, NULL};
38 CHAR EmptyLmPassword[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
39 NTSTATUS Status;
40
41 /* Calculate the NT hash value of the empty password */
42 Status = SystemFunction007(&EmptyNtPassword,
43 (LPBYTE)&EmptyNtHash);
44 if (!NT_SUCCESS(Status))
45 {
46 ERR("Calculation of the empty NT hash failed (Status 0x%08lx)\n", Status);
47 return Status;
48 }
49
50 /* Calculate the LM hash value of the empty password */
51 Status = SystemFunction006(EmptyLmPassword,
52 (LPSTR)&EmptyLmHash);
53 if (!NT_SUCCESS(Status))
54 {
55 ERR("Calculation of the empty LM hash failed (Status 0x%08lx)\n", Status);
56 }
57
58 return Status;
59 }
60
61
62 NTSTATUS
63 NTAPI
64 SamIConnect(IN PSAMPR_SERVER_NAME ServerName,
65 OUT SAMPR_HANDLE *ServerHandle,
66 IN ACCESS_MASK DesiredAccess,
67 IN BOOLEAN Trusted)
68 {
69 PSAM_DB_OBJECT ServerObject;
70 NTSTATUS Status;
71
72 TRACE("SamIConnect(%p %p %lx %ld)\n",
73 ServerName, ServerHandle, DesiredAccess, Trusted);
74
75 /* Map generic access rights */
76 RtlMapGenericMask(&DesiredAccess,
77 pServerMapping);
78
79 /* Open the Server Object */
80 Status = SampOpenDbObject(NULL,
81 NULL,
82 L"SAM",
83 0,
84 SamDbServerObject,
85 DesiredAccess,
86 &ServerObject);
87 if (NT_SUCCESS(Status))
88 {
89 ServerObject->Trusted = Trusted;
90 *ServerHandle = (SAMPR_HANDLE)ServerObject;
91 }
92
93 TRACE("SamIConnect done (Status 0x%08lx)\n", Status);
94
95 return Status;
96 }
97
98
99 NTSTATUS
100 NTAPI
101 SamIInitialize(VOID)
102 {
103 NTSTATUS Status = STATUS_SUCCESS;
104
105 TRACE("SamIInitialize() called\n");
106
107 Status = SampInitHashes();
108 if (!NT_SUCCESS(Status))
109 return Status;
110
111 if (SampIsSetupRunning())
112 {
113 Status = SampInitializeRegistry();
114 if (!NT_SUCCESS(Status))
115 return Status;
116 }
117
118 RtlInitializeResource(&SampResource);
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 SamIFreeVoid(PVOID Ptr)
147 {
148 MIDL_user_free(Ptr);
149 }
150
151
152 VOID
153 NTAPI
154 SamIFree_SAMPR_ALIAS_INFO_BUFFER(
155 PSAMPR_ALIAS_INFO_BUFFER Ptr,
156 ALIAS_INFORMATION_CLASS InformationClass)
157 {
158 if (Ptr == NULL)
159 return;
160
161 switch (InformationClass)
162 {
163 case AliasGeneralInformation:
164 if (Ptr->General.Name.Buffer != NULL)
165 MIDL_user_free(Ptr->General.Name.Buffer);
166
167 if (Ptr->General.AdminComment.Buffer != NULL)
168 MIDL_user_free(Ptr->General.AdminComment.Buffer);
169 break;
170
171 case AliasNameInformation:
172 if (Ptr->Name.Name.Buffer != NULL)
173 MIDL_user_free(Ptr->Name.Name.Buffer);
174 break;
175
176 case AliasAdminCommentInformation:
177 if (Ptr->AdminComment.AdminComment.Buffer != NULL)
178 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer);
179 break;
180
181 default:
182 FIXME("Unsupported information class: %lu\n", InformationClass);
183 break;
184 }
185
186 MIDL_user_free(Ptr);
187 }
188
189
190 VOID
191 NTAPI
192 SamIFree_SAMPR_DOMAIN_INFO_BUFFER(
193 PSAMPR_DOMAIN_INFO_BUFFER Ptr,
194 DOMAIN_INFORMATION_CLASS InformationClass)
195 {
196 if (Ptr == NULL)
197 return;
198
199 switch (InformationClass)
200 {
201 case DomainPasswordInformation:
202 break;
203
204 case DomainGeneralInformation:
205 if (Ptr->General.OemInformation.Buffer != NULL)
206 MIDL_user_free(Ptr->General.OemInformation.Buffer);
207
208 if (Ptr->General.DomainName.Buffer != NULL)
209 MIDL_user_free(Ptr->General.DomainName.Buffer);
210
211 if (Ptr->General.ReplicaSourceNodeName.Buffer != NULL)
212 MIDL_user_free(Ptr->General.ReplicaSourceNodeName.Buffer);
213 break;
214
215 case DomainLogoffInformation:
216 break;
217
218 case DomainOemInformation:
219 if (Ptr->Oem.OemInformation.Buffer != NULL)
220 MIDL_user_free(Ptr->Oem.OemInformation.Buffer);
221 break;
222
223 case DomainNameInformation:
224 if (Ptr->Name.DomainName.Buffer != NULL)
225 MIDL_user_free(Ptr->Name.DomainName.Buffer);
226 break;
227
228 case DomainReplicationInformation:
229 if (Ptr->Replication.ReplicaSourceNodeName.Buffer != NULL)
230 MIDL_user_free(Ptr->Replication.ReplicaSourceNodeName.Buffer);
231 break;
232
233 case DomainServerRoleInformation:
234 break;
235
236 case DomainModifiedInformation:
237 break;
238
239 case DomainStateInformation:
240 break;
241
242 case DomainGeneralInformation2:
243 if (Ptr->General2.I1.OemInformation.Buffer != NULL)
244 MIDL_user_free(Ptr->General2.I1.OemInformation.Buffer);
245
246 if (Ptr->General2.I1.DomainName.Buffer != NULL)
247 MIDL_user_free(Ptr->General2.I1.DomainName.Buffer);
248
249 if (Ptr->General2.I1.ReplicaSourceNodeName.Buffer != NULL)
250 MIDL_user_free(Ptr->General2.I1.ReplicaSourceNodeName.Buffer);
251 break;
252
253 case DomainLockoutInformation:
254 break;
255
256 case DomainModifiedInformation2:
257 break;
258
259 default:
260 FIXME("Unsupported information class: %lu\n", InformationClass);
261 break;
262 }
263
264 MIDL_user_free(Ptr);
265 }
266
267
268 VOID
269 NTAPI
270 SamIFree_SAMPR_ENUMERATION_BUFFER(PSAMPR_ENUMERATION_BUFFER Ptr)
271 {
272 ULONG i;
273
274 if (Ptr != NULL)
275 {
276 if (Ptr->Buffer != NULL)
277 {
278 for (i = 0; i < Ptr->EntriesRead; i++)
279 {
280 if (Ptr->Buffer[i].Name.Buffer != NULL)
281 MIDL_user_free(Ptr->Buffer[i].Name.Buffer);
282 }
283
284 MIDL_user_free(Ptr->Buffer);
285 }
286
287 MIDL_user_free(Ptr);
288 }
289 }
290
291
292 VOID
293 NTAPI
294 SamIFree_SAMPR_GET_GROUPS_BUFFER(PSAMPR_GET_GROUPS_BUFFER Ptr)
295 {
296 if (Ptr != NULL)
297 {
298 if (Ptr->Groups != NULL)
299 MIDL_user_free(Ptr->Groups);
300
301 MIDL_user_free(Ptr);
302 }
303 }
304
305
306 VOID
307 NTAPI
308 SamIFree_SAMPR_GET_MEMBERS_BUFFER(PSAMPR_GET_MEMBERS_BUFFER Ptr)
309 {
310 if (Ptr != NULL)
311 {
312 if (Ptr->Members != NULL)
313 MIDL_user_free(Ptr->Members);
314
315 if (Ptr->Attributes != NULL)
316 MIDL_user_free(Ptr->Attributes);
317
318 MIDL_user_free(Ptr);
319 }
320 }
321
322
323 VOID
324 NTAPI
325 SamIFree_SAMPR_GROUP_INFO_BUFFER(
326 PSAMPR_GROUP_INFO_BUFFER Ptr,
327 GROUP_INFORMATION_CLASS InformationClass)
328 {
329 if (Ptr == NULL)
330 return;
331
332 switch (InformationClass)
333 {
334 case GroupGeneralInformation:
335 if (Ptr->General.Name.Buffer != NULL)
336 MIDL_user_free(Ptr->General.Name.Buffer);
337
338 if (Ptr->General.AdminComment.Buffer != NULL)
339 MIDL_user_free(Ptr->General.AdminComment.Buffer);
340 break;
341
342 case GroupNameInformation:
343 if (Ptr->Name.Name.Buffer != NULL)
344 MIDL_user_free(Ptr->Name.Name.Buffer);
345 break;
346
347 case GroupAttributeInformation:
348 break;
349
350 case GroupAdminCommentInformation:
351 if (Ptr->AdminComment.AdminComment.Buffer != NULL)
352 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer);
353 break;
354
355 default:
356 FIXME("Unsupported information class: %lu\n", InformationClass);
357 break;
358 }
359
360 MIDL_user_free(Ptr);
361 }
362
363
364 VOID
365 NTAPI
366 SamIFree_SAMPR_PSID_ARRAY(PSAMPR_PSID_ARRAY Ptr)
367 {
368 if (Ptr != NULL)
369 {
370 if (Ptr->Sids != NULL)
371 {
372 MIDL_user_free(Ptr->Sids);
373 }
374 }
375 }
376
377
378 VOID
379 NTAPI
380 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr)
381 {
382 ULONG i;
383
384 if (Ptr != NULL)
385 {
386 if (Ptr->Element != NULL)
387 {
388 for (i = 0; i < Ptr->Count; i++)
389 {
390 if (Ptr->Element[i].Buffer != NULL)
391 MIDL_user_free(Ptr->Element[i].Buffer);
392 }
393
394 MIDL_user_free(Ptr->Element);
395 Ptr->Element = NULL;
396 Ptr->Count = 0;
397 }
398 }
399 }
400
401
402 VOID
403 NTAPI
404 SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR(PSAMPR_SR_SECURITY_DESCRIPTOR Ptr)
405 {
406 if (Ptr != NULL)
407 {
408 if (Ptr->SecurityDescriptor != NULL)
409 MIDL_user_free(Ptr->SecurityDescriptor);
410
411 MIDL_user_free(Ptr);
412 }
413 }
414
415
416 VOID
417 NTAPI
418 SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr)
419 {
420 if (Ptr != NULL)
421 {
422 if (Ptr->Element != NULL)
423 {
424 MIDL_user_free(Ptr->Element);
425 Ptr->Element = NULL;
426 Ptr->Count = 0;
427 }
428 }
429 }
430
431
432 VOID
433 NTAPI
434 SamIFree_SAMPR_USER_INFO_BUFFER(PSAMPR_USER_INFO_BUFFER Ptr,
435 USER_INFORMATION_CLASS InformationClass)
436 {
437 if (Ptr == NULL)
438 return;
439
440 switch (InformationClass)
441 {
442 case UserGeneralInformation:
443 if (Ptr->General.UserName.Buffer != NULL)
444 MIDL_user_free(Ptr->General.UserName.Buffer);
445
446 if (Ptr->General.FullName.Buffer != NULL)
447 MIDL_user_free(Ptr->General.FullName.Buffer);
448
449 if (Ptr->General.AdminComment.Buffer != NULL)
450 MIDL_user_free(Ptr->General.AdminComment.Buffer);
451
452 if (Ptr->General.UserComment.Buffer != NULL)
453 MIDL_user_free(Ptr->General.UserComment.Buffer);
454 break;
455
456 case UserPreferencesInformation:
457 if (Ptr->Preferences.UserComment.Buffer != NULL)
458 MIDL_user_free(Ptr->Preferences.UserComment.Buffer);
459
460 if (Ptr->Preferences.Reserved1.Buffer != NULL)
461 MIDL_user_free(Ptr->Preferences.Reserved1.Buffer);
462 break;
463
464 case UserLogonInformation:
465 if (Ptr->Logon.UserName.Buffer != NULL)
466 MIDL_user_free(Ptr->Logon.UserName.Buffer);
467
468 if (Ptr->Logon.FullName.Buffer != NULL)
469 MIDL_user_free(Ptr->Logon.FullName.Buffer);
470
471 if (Ptr->Logon.HomeDirectory.Buffer != NULL)
472 MIDL_user_free(Ptr->Logon.HomeDirectory.Buffer);
473
474 if (Ptr->Logon.HomeDirectoryDrive.Buffer != NULL)
475 MIDL_user_free(Ptr->Logon.HomeDirectoryDrive.Buffer);
476
477 if (Ptr->Logon.ScriptPath.Buffer != NULL)
478 MIDL_user_free(Ptr->Logon.ScriptPath.Buffer);
479
480 if (Ptr->Logon.ProfilePath.Buffer != NULL)
481 MIDL_user_free(Ptr->Logon.ProfilePath.Buffer);
482
483 if (Ptr->Logon.WorkStations.Buffer != NULL)
484 MIDL_user_free(Ptr->Logon.WorkStations.Buffer);
485
486 if (Ptr->Logon.LogonHours.LogonHours != NULL)
487 MIDL_user_free(Ptr->Logon.LogonHours.LogonHours);
488 break;
489
490 case UserLogonHoursInformation:
491 if (Ptr->LogonHours.LogonHours.LogonHours != NULL)
492 MIDL_user_free(Ptr->LogonHours.LogonHours.LogonHours);
493 break;
494
495 case UserAccountInformation:
496 if (Ptr->Account.UserName.Buffer != NULL)
497 MIDL_user_free(Ptr->Account.UserName.Buffer);
498
499 if (Ptr->Account.FullName.Buffer != NULL)
500 MIDL_user_free(Ptr->Account.FullName.Buffer);
501
502 if (Ptr->Account.HomeDirectory.Buffer != NULL)
503 MIDL_user_free(Ptr->Account.HomeDirectory.Buffer);
504
505 if (Ptr->Account.HomeDirectoryDrive.Buffer != NULL)
506 MIDL_user_free(Ptr->Account.HomeDirectoryDrive.Buffer);
507
508 if (Ptr->Account.ScriptPath.Buffer != NULL)
509 MIDL_user_free(Ptr->Account.ScriptPath.Buffer);
510
511 if (Ptr->Account.ProfilePath.Buffer != NULL)
512 MIDL_user_free(Ptr->Account.ProfilePath.Buffer);
513
514 if (Ptr->Account.AdminComment.Buffer != NULL)
515 MIDL_user_free(Ptr->Account.AdminComment.Buffer);
516
517 if (Ptr->Account.WorkStations.Buffer != NULL)
518 MIDL_user_free(Ptr->Account.WorkStations.Buffer);
519
520 if (Ptr->Account.LogonHours.LogonHours != NULL)
521 MIDL_user_free(Ptr->Account.LogonHours.LogonHours);
522 break;
523
524 case UserNameInformation:
525 if (Ptr->Name.UserName.Buffer != NULL)
526 MIDL_user_free(Ptr->Name.UserName.Buffer);
527
528 if (Ptr->Name.FullName.Buffer != NULL)
529 MIDL_user_free(Ptr->Name.FullName.Buffer);
530 break;
531
532 case UserAccountNameInformation:
533 if (Ptr->AccountName.UserName.Buffer != NULL)
534 MIDL_user_free(Ptr->AccountName.UserName.Buffer);
535 break;
536
537 case UserFullNameInformation:
538 if (Ptr->FullName.FullName.Buffer != NULL)
539 MIDL_user_free(Ptr->FullName.FullName.Buffer);
540 break;
541
542 case UserPrimaryGroupInformation:
543 break;
544
545 case UserHomeInformation:
546 if (Ptr->Home.HomeDirectory.Buffer != NULL)
547 MIDL_user_free(Ptr->Home.HomeDirectory.Buffer);
548
549 if (Ptr->Home.HomeDirectoryDrive.Buffer != NULL)
550 MIDL_user_free(Ptr->Home.HomeDirectoryDrive.Buffer);
551 break;
552
553 case UserScriptInformation:
554 if (Ptr->Script.ScriptPath.Buffer != NULL)
555 MIDL_user_free(Ptr->Script.ScriptPath.Buffer);
556
557 case UserProfileInformation:
558 if (Ptr->Profile.ProfilePath.Buffer != NULL)
559 MIDL_user_free(Ptr->Profile.ProfilePath.Buffer);
560
561 case UserAdminCommentInformation:
562 if (Ptr->AdminComment.AdminComment.Buffer != NULL)
563 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer);
564 break;
565
566 case UserWorkStationsInformation:
567 if (Ptr->WorkStations.WorkStations.Buffer != NULL)
568 MIDL_user_free(Ptr->WorkStations.WorkStations.Buffer);
569 break;
570
571 case UserSetPasswordInformation:
572 ERR("Information class UserSetPasswordInformation cannot be queried!\n");
573 break;
574
575 case UserControlInformation:
576 break;
577
578 case UserExpiresInformation:
579 break;
580
581 case UserInternal1Information:
582 break;
583
584 case UserInternal2Information:
585 break;
586
587 case UserParametersInformation:
588 if (Ptr->Parameters.Parameters.Buffer != NULL)
589 MIDL_user_free(Ptr->Parameters.Parameters.Buffer);
590 break;
591
592 case UserAllInformation:
593 if (Ptr->All.UserName.Buffer != NULL)
594 MIDL_user_free(Ptr->All.UserName.Buffer);
595
596 if (Ptr->All.FullName.Buffer != NULL)
597 MIDL_user_free(Ptr->All.FullName.Buffer);
598
599 if (Ptr->All.HomeDirectory.Buffer != NULL)
600 MIDL_user_free(Ptr->All.HomeDirectory.Buffer);
601
602 if (Ptr->All.HomeDirectoryDrive.Buffer != NULL)
603 MIDL_user_free(Ptr->All.HomeDirectoryDrive.Buffer);
604
605 if (Ptr->All.ScriptPath.Buffer != NULL)
606 MIDL_user_free(Ptr->All.ScriptPath.Buffer);
607
608 if (Ptr->All.ProfilePath.Buffer != NULL)
609 MIDL_user_free(Ptr->All.ProfilePath.Buffer);
610
611 if (Ptr->All.AdminComment.Buffer != NULL)
612 MIDL_user_free(Ptr->All.AdminComment.Buffer);
613
614 if (Ptr->All.WorkStations.Buffer != NULL)
615 MIDL_user_free(Ptr->All.WorkStations.Buffer);
616
617 if (Ptr->All.UserComment.Buffer != NULL)
618 MIDL_user_free(Ptr->All.UserComment.Buffer);
619
620 if (Ptr->All.Parameters.Buffer != NULL)
621 MIDL_user_free(Ptr->All.Parameters.Buffer);
622
623 if (Ptr->All.LmOwfPassword.Buffer != NULL)
624 MIDL_user_free(Ptr->All.LmOwfPassword.Buffer);
625
626 if (Ptr->All.NtOwfPassword.Buffer != NULL)
627 MIDL_user_free(Ptr->All.NtOwfPassword.Buffer);
628
629 if (Ptr->All.PrivateData.Buffer != NULL)
630 MIDL_user_free(Ptr->All.PrivateData.Buffer);
631
632 if (Ptr->All.SecurityDescriptor.SecurityDescriptor != NULL)
633 MIDL_user_free(Ptr->All.SecurityDescriptor.SecurityDescriptor);
634
635 if (Ptr->All.LogonHours.LogonHours != NULL)
636 MIDL_user_free(Ptr->All.LogonHours.LogonHours);
637 break;
638
639 default:
640 FIXME("Unsupported information class: %lu\n", InformationClass);
641 break;
642 }
643
644 MIDL_user_free(Ptr);
645 }
646
647 /* EOF */