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