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