xref: /reactos/dll/win32/syssetup/security.c (revision 02e84521)
1 /*
2  * COPYRIGHT:         See COPYING in the top level directory
3  * PROJECT:           ReactOS system libraries
4  * PURPOSE:           System setup
5  * FILE:              dll/win32/syssetup/security.c
6  * PROGRAMER:         Eric Kohl
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "precomp.h"
12 
13 #include <ntlsa.h>
14 #include <ntsecapi.h>
15 #include <ntsam.h>
16 #include <sddl.h>
17 
18 #define NDEBUG
19 #include <debug.h>
20 
21 /* FUNCTIONS ****************************************************************/
22 
23 NTSTATUS
24 WINAPI
25 SetAccountsDomainSid(
26     PSID DomainSid,
27     LPCWSTR DomainName)
28 {
29     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
30     POLICY_ACCOUNT_DOMAIN_INFO Info;
31     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
32     LSA_HANDLE PolicyHandle;
33 
34     SAM_HANDLE ServerHandle = NULL;
35     SAM_HANDLE DomainHandle = NULL;
36     DOMAIN_NAME_INFORMATION DomainNameInfo;
37 
38     NTSTATUS Status;
39 
40     DPRINT("SYSSETUP: SetAccountsDomainSid\n");
41 
42     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
43     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
44 
45     Status = LsaOpenPolicy(NULL,
46                            &ObjectAttributes,
47                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
48                            &PolicyHandle);
49     if (Status != STATUS_SUCCESS)
50     {
51         DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
52         return Status;
53     }
54 
55     Status = LsaQueryInformationPolicy(PolicyHandle,
56                                        PolicyAccountDomainInformation,
57                                        (PVOID *)&OrigInfo);
58     if (Status == STATUS_SUCCESS && OrigInfo != NULL)
59     {
60         if (DomainName == NULL)
61         {
62             Info.DomainName.Buffer = OrigInfo->DomainName.Buffer;
63             Info.DomainName.Length = OrigInfo->DomainName.Length;
64             Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength;
65         }
66         else
67         {
68             Info.DomainName.Buffer = (LPWSTR)DomainName;
69             Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
70             Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
71         }
72 
73         if (DomainSid == NULL)
74             Info.DomainSid = OrigInfo->DomainSid;
75         else
76             Info.DomainSid = DomainSid;
77     }
78     else
79     {
80         Info.DomainName.Buffer = (LPWSTR)DomainName;
81         Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
82         Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
83         Info.DomainSid = DomainSid;
84     }
85 
86     Status = LsaSetInformationPolicy(PolicyHandle,
87                                      PolicyAccountDomainInformation,
88                                      (PVOID)&Info);
89     if (Status != STATUS_SUCCESS)
90     {
91         DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
92     }
93 
94     if (OrigInfo != NULL)
95         LsaFreeMemory(OrigInfo);
96 
97     LsaClose(PolicyHandle);
98 
99     DomainNameInfo.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
100     DomainNameInfo.DomainName.MaximumLength = (wcslen(DomainName) + 1) * sizeof(WCHAR);
101     DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName;
102 
103     Status = SamConnect(NULL,
104                         &ServerHandle,
105                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
106                         NULL);
107     if (NT_SUCCESS(Status))
108     {
109         Status = SamOpenDomain(ServerHandle,
110                                DOMAIN_WRITE_OTHER_PARAMETERS,
111                                Info.DomainSid,
112                                &DomainHandle);
113         if (NT_SUCCESS(Status))
114         {
115             Status = SamSetInformationDomain(DomainHandle,
116                                              DomainNameInformation,
117                                              (PVOID)&DomainNameInfo);
118             if (!NT_SUCCESS(Status))
119             {
120                 DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status);
121             }
122 
123             SamCloseHandle(DomainHandle);
124         }
125         else
126         {
127             DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status);
128         }
129 
130         SamCloseHandle(ServerHandle);
131     }
132 
133     return Status;
134 }
135 
136 
137 /* Hack */
138 static
139 NTSTATUS
140 SetPrimaryDomain(LPCWSTR DomainName,
141                  PSID DomainSid)
142 {
143     PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL;
144     POLICY_PRIMARY_DOMAIN_INFO Info;
145     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
146     LSA_HANDLE PolicyHandle;
147     NTSTATUS Status;
148 
149     DPRINT1("SYSSETUP: SetPrimaryDomain()\n");
150 
151     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
152     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
153 
154     Status = LsaOpenPolicy(NULL,
155                            &ObjectAttributes,
156                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
157                            &PolicyHandle);
158     if (Status != STATUS_SUCCESS)
159     {
160         DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
161         return Status;
162     }
163 
164     Status = LsaQueryInformationPolicy(PolicyHandle,
165                                        PolicyPrimaryDomainInformation,
166                                        (PVOID *)&OrigInfo);
167     if (Status == STATUS_SUCCESS && OrigInfo != NULL)
168     {
169         if (DomainName == NULL)
170         {
171             Info.Name.Buffer = OrigInfo->Name.Buffer;
172             Info.Name.Length = OrigInfo->Name.Length;
173             Info.Name.MaximumLength = OrigInfo->Name.MaximumLength;
174         }
175         else
176         {
177             Info.Name.Buffer = (LPWSTR)DomainName;
178             Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR);
179             Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
180         }
181 
182         if (DomainSid == NULL)
183             Info.Sid = OrigInfo->Sid;
184         else
185             Info.Sid = DomainSid;
186     }
187     else
188     {
189         Info.Name.Buffer = (LPWSTR)DomainName;
190         Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR);
191         Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
192         Info.Sid = DomainSid;
193     }
194 
195     Status = LsaSetInformationPolicy(PolicyHandle,
196                                      PolicyPrimaryDomainInformation,
197                                      (PVOID)&Info);
198     if (Status != STATUS_SUCCESS)
199     {
200         DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
201     }
202 
203     if (OrigInfo != NULL)
204         LsaFreeMemory(OrigInfo);
205 
206     LsaClose(PolicyHandle);
207 
208     return Status;
209 }
210 
211 
212 static
213 VOID
214 InstallBuiltinAccounts(VOID)
215 {
216     LPWSTR BuiltinAccounts[] = {
217         L"S-1-1-0",         /* Everyone */
218         L"S-1-5-4",         /* Interactive */
219         L"S-1-5-6",         /* Service */
220         L"S-1-5-19",        /* Local Service */
221         L"S-1-5-20",        /* Network Service */
222         L"S-1-5-32-544",    /* Administrators */
223         L"S-1-5-32-545",    /* Users */
224         L"S-1-5-32-547",    /* Power Users */
225         L"S-1-5-32-551",    /* Backup Operators */
226         L"S-1-5-32-555"};   /* Remote Desktop Users */
227     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
228     NTSTATUS Status;
229     LSA_HANDLE PolicyHandle = NULL;
230     LSA_HANDLE AccountHandle = NULL;
231     PSID AccountSid;
232     ULONG i;
233 
234     DPRINT("InstallBuiltinAccounts()\n");
235 
236     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
237 
238     Status = LsaOpenPolicy(NULL,
239                            &ObjectAttributes,
240                            POLICY_CREATE_ACCOUNT,
241                            &PolicyHandle);
242     if (!NT_SUCCESS(Status))
243     {
244         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
245         return;
246     }
247 
248     for (i = 0; i < ARRAYSIZE(BuiltinAccounts); i++)
249     {
250         if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid))
251         {
252             DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError());
253             continue;
254         }
255 
256         Status = LsaCreateAccount(PolicyHandle,
257                                   AccountSid,
258                                   0,
259                                   &AccountHandle);
260         if (NT_SUCCESS(Status))
261         {
262             LsaClose(AccountHandle);
263         }
264 
265         LocalFree(AccountSid);
266     }
267 
268     LsaClose(PolicyHandle);
269 }
270 
271 
272 static
273 VOID
274 InstallPrivileges(
275     HINF hSecurityInf)
276 {
277     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
278     WCHAR szPrivilegeString[256];
279     WCHAR szSidString[256];
280     INFCONTEXT InfContext;
281     DWORD i;
282     PSID AccountSid = NULL;
283     NTSTATUS Status;
284     LSA_HANDLE PolicyHandle = NULL;
285     LSA_UNICODE_STRING RightString;
286     PLSA_TRANSLATED_SID2 Sids = NULL;
287 
288     DPRINT("InstallPrivileges()\n");
289 
290     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
291 
292     Status = LsaOpenPolicy(NULL,
293                            &ObjectAttributes,
294                            POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
295                            &PolicyHandle);
296     if (!NT_SUCCESS(Status))
297     {
298         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
299         goto done;
300     }
301 
302     if (!SetupFindFirstLineW(hSecurityInf,
303                              L"Privilege Rights",
304                              NULL,
305                              &InfContext))
306     {
307         DPRINT1("SetupFindFirstLineW failed\n");
308         goto done;
309     }
310 
311     do
312     {
313         /* Retrieve the privilege name */
314         if (!SetupGetStringFieldW(&InfContext,
315                                   0,
316                                   szPrivilegeString,
317                                   ARRAYSIZE(szPrivilegeString),
318                                   NULL))
319         {
320             DPRINT1("SetupGetStringFieldW() failed\n");
321             goto done;
322         }
323         DPRINT("Privilege: %S\n", szPrivilegeString);
324 
325         for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
326         {
327             if (!SetupGetStringFieldW(&InfContext,
328                                       i + 1,
329                                       szSidString,
330                                       ARRAYSIZE(szSidString),
331                                       NULL))
332             {
333                 DPRINT1("SetupGetStringFieldW() failed\n");
334                 goto done;
335             }
336             DPRINT("SID: %S\n", szSidString);
337 
338             if (szSidString[0] == UNICODE_NULL)
339                 continue;
340 
341             if (szSidString[0] == L'*')
342             {
343                 DPRINT("Account Sid: %S\n", &szSidString[1]);
344 
345                 if (!ConvertStringSidToSid(&szSidString[1], &AccountSid))
346                 {
347                     DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError());
348                     continue;
349                 }
350             }
351             else
352             {
353                 DPRINT("Account name: %S\n", szSidString);
354                 continue;
355 
356             }
357 
358             RtlInitUnicodeString(&RightString, szPrivilegeString);
359             Status = LsaAddAccountRights(PolicyHandle,
360                                          (AccountSid != NULL) ? AccountSid : Sids[0].Sid,
361                                          &RightString,
362                                          1);
363             if (!NT_SUCCESS(Status))
364             {
365                 DPRINT1("LsaAddAccountRights() failed (Status %08lx)\n", Status);
366             }
367 
368             if (Sids != NULL)
369             {
370                 LsaFreeMemory(Sids);
371                 Sids = NULL;
372             }
373 
374             if (AccountSid != NULL)
375             {
376                 LocalFree(AccountSid);
377                 AccountSid = NULL;
378             }
379         }
380 
381     }
382     while (SetupFindNextLine(&InfContext, &InfContext));
383 
384 done:
385     if (PolicyHandle != NULL)
386         LsaClose(PolicyHandle);
387 }
388 
389 
390 static
391 VOID
392 ApplyRegistryValues(
393     HINF hSecurityInf)
394 {
395     WCHAR szRegistryPath[MAX_PATH];
396     WCHAR szRootName[MAX_PATH];
397     WCHAR szKeyName[MAX_PATH];
398     WCHAR szValueName[MAX_PATH];
399     INFCONTEXT InfContext;
400     DWORD dwLength, dwType;
401     HKEY hRootKey, hKey;
402     PWSTR Ptr1, Ptr2;
403     DWORD dwError;
404     PVOID pBuffer;
405 
406     DPRINT("ApplyRegistryValues()\n");
407 
408     if (!SetupFindFirstLineW(hSecurityInf,
409                              L"Registry Values",
410                              NULL,
411                              &InfContext))
412     {
413         DPRINT1("SetupFindFirstLineW failed\n");
414         return;
415     }
416 
417     do
418     {
419         /* Retrieve the privilege name */
420         if (!SetupGetStringFieldW(&InfContext,
421                                   0,
422                                   szRegistryPath,
423                                   ARRAYSIZE(szRegistryPath),
424                                   NULL))
425         {
426             DPRINT1("SetupGetStringFieldW() failed\n");
427             return;
428         }
429 
430         DPRINT("RegistryPath: %S\n", szRegistryPath);
431 
432         Ptr1 = wcschr(szRegistryPath, L'\\');
433         Ptr2 = wcsrchr(szRegistryPath, L'\\');
434         if (Ptr1 != NULL && Ptr2 != NULL && Ptr1 != Ptr2)
435         {
436             dwLength = (DWORD)(((ULONG_PTR)Ptr1 - (ULONG_PTR)szRegistryPath) / sizeof(WCHAR));
437             wcsncpy(szRootName, szRegistryPath, dwLength);
438             szRootName[dwLength] = UNICODE_NULL;
439 
440             Ptr1++;
441             dwLength = (DWORD)(((ULONG_PTR)Ptr2 - (ULONG_PTR)Ptr1) / sizeof(WCHAR));
442             wcsncpy(szKeyName, Ptr1, dwLength);
443             szKeyName[dwLength] = UNICODE_NULL;
444 
445             Ptr2++;
446             wcscpy(szValueName, Ptr2);
447 
448             DPRINT("RootName: %S\n", szRootName);
449             DPRINT("KeyName: %S\n", szKeyName);
450             DPRINT("ValueName: %S\n", szValueName);
451 
452             if (_wcsicmp(szRootName, L"Machine") == 0)
453             {
454                 hRootKey = HKEY_LOCAL_MACHINE;
455             }
456             else
457             {
458                 DPRINT1("Unsupported root key %S\n", szRootName);
459                 break;
460             }
461 
462             if (!SetupGetIntField(&InfContext,
463                                   1,
464                                   (PINT)&dwType))
465             {
466                 DPRINT1("Failed to get key type (Error %lu)\n", GetLastError());
467                 break;
468             }
469 
470             if (dwType != REG_SZ && dwType != REG_EXPAND_SZ && dwType != REG_BINARY &&
471                 dwType != REG_DWORD && dwType != REG_MULTI_SZ)
472             {
473                 DPRINT1("Invalid value type %lu\n", dwType);
474                 break;
475             }
476 
477             dwLength = 0;
478             switch (dwType)
479             {
480                 case REG_SZ:
481                 case REG_EXPAND_SZ:
482                     SetupGetStringField(&InfContext,
483                                         2,
484                                         NULL,
485                                         0,
486                                         &dwLength);
487                     dwLength *= sizeof(WCHAR);
488                     break;
489 
490                 case REG_BINARY:
491                     SetupGetBinaryField(&InfContext,
492                                         2,
493                                         NULL,
494                                         0,
495                                         &dwLength);
496                     break;
497 
498                 case REG_DWORD:
499                     dwLength = sizeof(INT);
500                     break;
501 
502                 case REG_MULTI_SZ:
503                     SetupGetMultiSzField(&InfContext,
504                                          2,
505                                          NULL,
506                                          0,
507                                          &dwLength);
508                     dwLength *= sizeof(WCHAR);
509                     break;
510             }
511 
512             if (dwLength == 0)
513             {
514                 DPRINT1("Failed to determine the required buffer size!\n");
515                 break;
516             }
517 
518             dwError = RegCreateKeyExW(hRootKey,
519                                       szKeyName,
520                                       0,
521                                       NULL,
522                                       REG_OPTION_NON_VOLATILE,
523                                       KEY_WRITE,
524                                       NULL,
525                                       &hKey,
526                                       NULL);
527             if (dwError != ERROR_SUCCESS)
528             {
529                 DPRINT1("Failed to create the key %S (Error %lu)\n", szKeyName, dwError);
530                 break;
531             }
532 
533             pBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
534             if (pBuffer)
535             {
536                 switch (dwType)
537                 {
538                     case REG_SZ:
539                     case REG_EXPAND_SZ:
540                         SetupGetStringField(&InfContext,
541                                             2,
542                                             pBuffer,
543                                             dwLength / sizeof(WCHAR),
544                                             &dwLength);
545                         dwLength *= sizeof(WCHAR);
546                         break;
547 
548                     case REG_BINARY:
549                         SetupGetBinaryField(&InfContext,
550                                             2,
551                                             pBuffer,
552                                             dwLength,
553                                             &dwLength);
554                         break;
555 
556                     case REG_DWORD:
557                         SetupGetIntField(&InfContext,
558                                          2,
559                                          pBuffer);
560                         break;
561 
562                     case REG_MULTI_SZ:
563                         SetupGetMultiSzField(&InfContext,
564                                              2,
565                                              pBuffer,
566                                              dwLength / sizeof(WCHAR),
567                                              &dwLength);
568                         dwLength *= sizeof(WCHAR);
569                         break;
570                 }
571 
572                 RegSetValueEx(hKey,
573                               szValueName,
574                               0,
575                               dwType,
576                               pBuffer,
577                               dwLength);
578 
579                 HeapFree(GetProcessHeap(), 0, pBuffer);
580             }
581 
582             RegCloseKey(hKey);
583         }
584     }
585     while (SetupFindNextLine(&InfContext, &InfContext));
586 }
587 
588 
589 VOID
590 InstallSecurity(VOID)
591 {
592     HINF hSecurityInf;
593     PWSTR pszSecurityInf;
594 
595 //    if (IsServer())
596 //        pszSecurityInf = L"defltsv.inf";
597 //    else
598         pszSecurityInf = L"defltws.inf";
599 
600     InstallBuiltinAccounts();
601 
602     hSecurityInf = SetupOpenInfFileW(pszSecurityInf,
603                                      NULL,
604                                      INF_STYLE_WIN4,
605                                      NULL);
606     if (hSecurityInf != INVALID_HANDLE_VALUE)
607     {
608         InstallPrivileges(hSecurityInf);
609         ApplyRegistryValues(hSecurityInf);
610 
611         SetupCloseInfFile(hSecurityInf);
612     }
613 
614     /* Hack */
615     SetPrimaryDomain(L"WORKGROUP", NULL);
616 }
617 
618 
619 NTSTATUS
620 SetAdministratorPassword(LPCWSTR Password)
621 {
622     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
623     PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
624     USER_SET_PASSWORD_INFORMATION PasswordInfo;
625     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
626     LSA_HANDLE PolicyHandle = NULL;
627     SAM_HANDLE ServerHandle = NULL;
628     SAM_HANDLE DomainHandle = NULL;
629     SAM_HANDLE UserHandle = NULL;
630     NTSTATUS Status;
631 
632     DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
633 
634     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
635     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
636 
637     Status = LsaOpenPolicy(NULL,
638                            &ObjectAttributes,
639                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
640                            &PolicyHandle);
641     if (Status != STATUS_SUCCESS)
642     {
643         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
644         return Status;
645     }
646 
647     Status = LsaQueryInformationPolicy(PolicyHandle,
648                                        PolicyAccountDomainInformation,
649                                        (PVOID *)&OrigInfo);
650     if (!NT_SUCCESS(Status))
651     {
652         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
653         goto done;
654     }
655 
656     Status = SamConnect(NULL,
657                         &ServerHandle,
658                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
659                         NULL);
660     if (!NT_SUCCESS(Status))
661     {
662         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
663         goto done;
664     }
665 
666     Status = SamOpenDomain(ServerHandle,
667                            DOMAIN_LOOKUP,
668                            OrigInfo->DomainSid,
669                            &DomainHandle);
670     if (!NT_SUCCESS(Status))
671     {
672         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
673         goto done;
674     }
675 
676     Status = SamOpenUser(DomainHandle,
677                          USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
678                          DOMAIN_USER_RID_ADMIN,
679                          &UserHandle);
680     if (!NT_SUCCESS(Status))
681     {
682         DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
683         goto done;
684     }
685 
686     RtlInitUnicodeString(&PasswordInfo.Password, Password);
687     PasswordInfo.PasswordExpired = FALSE;
688 
689     Status = SamSetInformationUser(UserHandle,
690                                    UserSetPasswordInformation,
691                                    (PVOID)&PasswordInfo);
692     if (!NT_SUCCESS(Status))
693     {
694         DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
695         goto done;
696     }
697 
698     Status = SamQueryInformationUser(UserHandle,
699                                      UserAccountNameInformation,
700                                      (PVOID*)&AccountNameInfo);
701     if (!NT_SUCCESS(Status))
702     {
703         DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
704         goto done;
705     }
706 
707     AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
708                                      HEAP_ZERO_MEMORY,
709                                      AccountNameInfo->UserName.Length + sizeof(WCHAR));
710     if (AdminInfo.Name != NULL)
711         RtlCopyMemory(AdminInfo.Name,
712                       AccountNameInfo->UserName.Buffer,
713                       AccountNameInfo->UserName.Length);
714 
715     AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
716                                        HEAP_ZERO_MEMORY,
717                                        OrigInfo->DomainName.Length + sizeof(WCHAR));
718     if (AdminInfo.Domain != NULL)
719         RtlCopyMemory(AdminInfo.Domain,
720                       OrigInfo->DomainName.Buffer,
721                       OrigInfo->DomainName.Length);
722 
723     AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
724                                          0,
725                                          (wcslen(Password) + 1) * sizeof(WCHAR));
726     if (AdminInfo.Password != NULL)
727         wcscpy(AdminInfo.Password, Password);
728 
729     DPRINT("Administrator Name: %S\n", AdminInfo.Name);
730     DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
731     DPRINT("Administrator Password: %S\n", AdminInfo.Password);
732 
733 done:
734     if (AccountNameInfo != NULL)
735         SamFreeMemory(AccountNameInfo);
736 
737     if (OrigInfo != NULL)
738         LsaFreeMemory(OrigInfo);
739 
740     if (PolicyHandle != NULL)
741         LsaClose(PolicyHandle);
742 
743     if (UserHandle != NULL)
744         SamCloseHandle(UserHandle);
745 
746     if (DomainHandle != NULL)
747         SamCloseHandle(DomainHandle);
748 
749     if (ServerHandle != NULL)
750         SamCloseHandle(ServerHandle);
751 
752     DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
753 
754     return Status;
755 }
756 
757 
758 VOID
759 SetAutoAdminLogon(VOID)
760 {
761     WCHAR szAutoAdminLogon[2];
762     HKEY hKey = NULL;
763     DWORD dwType;
764     DWORD dwSize;
765     LONG lError;
766 
767     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
768                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
769                            0,
770                            KEY_READ | KEY_WRITE,
771                            &hKey);
772     if (lError != ERROR_SUCCESS)
773         return;
774 
775     dwSize = 2 * sizeof(WCHAR);
776     lError = RegQueryValueExW(hKey,
777                               L"AutoAdminLogon",
778                               NULL,
779                               &dwType,
780                               (LPBYTE)szAutoAdminLogon,
781                               &dwSize);
782     if (lError != ERROR_SUCCESS)
783         goto done;
784 
785     if (wcscmp(szAutoAdminLogon, L"1") == 0)
786     {
787         RegSetValueExW(hKey,
788                        L"DefaultDomainName",
789                        0,
790                        REG_SZ,
791                        (LPBYTE)AdminInfo.Domain,
792                        (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
793 
794         RegSetValueExW(hKey,
795                        L"DefaultUserName",
796                        0,
797                        REG_SZ,
798                        (LPBYTE)AdminInfo.Name,
799                        (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
800 
801         RegSetValueExW(hKey,
802                        L"DefaultPassword",
803                        0,
804                        REG_SZ,
805                        (LPBYTE)AdminInfo.Password,
806                        (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
807     }
808 
809 done:
810     if (hKey != NULL)
811         RegCloseKey(hKey);
812 }
813 
814 
815 /* EOF */
816 
817