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