xref: /reactos/dll/win32/syssetup/security.c (revision 5d8e8348)
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 #define TICKS_PER_DAY -864000000000LL
22 #define TICKS_PER_MINUTE -600000000LL
23 
24 /* FUNCTIONS ****************************************************************/
25 
26 NTSTATUS
27 WINAPI
SetAccountsDomainSid(PSID DomainSid,LPCWSTR DomainName)28 SetAccountsDomainSid(
29     PSID DomainSid,
30     LPCWSTR DomainName)
31 {
32     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
33     POLICY_ACCOUNT_DOMAIN_INFO Info;
34     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
35     LSA_HANDLE PolicyHandle;
36 
37     SAM_HANDLE ServerHandle = NULL;
38     SAM_HANDLE DomainHandle = NULL;
39     DOMAIN_NAME_INFORMATION DomainNameInfo;
40 
41     SIZE_T DomainNameLength = 0;
42     NTSTATUS Status;
43 
44     DPRINT("SYSSETUP: SetAccountsDomainSid\n");
45 
46     if (DomainName != NULL)
47     {
48         DomainNameLength = wcslen(DomainName);
49         if (DomainNameLength > UNICODE_STRING_MAX_CHARS)
50         {
51             return STATUS_INVALID_PARAMETER;
52         }
53     }
54 
55     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
56     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
57 
58     Status = LsaOpenPolicy(NULL,
59                            &ObjectAttributes,
60                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
61                            &PolicyHandle);
62     if (Status != STATUS_SUCCESS)
63     {
64         DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
65         return Status;
66     }
67 
68     Status = LsaQueryInformationPolicy(PolicyHandle,
69                                        PolicyAccountDomainInformation,
70                                        (PVOID *)&OrigInfo);
71     if (Status == STATUS_SUCCESS && OrigInfo != NULL)
72     {
73         if (DomainName == NULL)
74         {
75             Info.DomainName.Buffer = OrigInfo->DomainName.Buffer;
76             Info.DomainName.Length = OrigInfo->DomainName.Length;
77             Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength;
78         }
79         else
80         {
81             Info.DomainName.Buffer = (LPWSTR)DomainName;
82             Info.DomainName.Length = DomainNameLength * sizeof(WCHAR);
83             Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
84         }
85 
86         if (DomainSid == NULL)
87             Info.DomainSid = OrigInfo->DomainSid;
88         else
89             Info.DomainSid = DomainSid;
90     }
91     else
92     {
93         Info.DomainName.Buffer = (LPWSTR)DomainName;
94         Info.DomainName.Length = DomainNameLength * sizeof(WCHAR);
95         Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
96         Info.DomainSid = DomainSid;
97     }
98 
99     Status = LsaSetInformationPolicy(PolicyHandle,
100                                      PolicyAccountDomainInformation,
101                                      (PVOID)&Info);
102     if (Status != STATUS_SUCCESS)
103     {
104         DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
105     }
106 
107     if (OrigInfo != NULL)
108         LsaFreeMemory(OrigInfo);
109 
110     LsaClose(PolicyHandle);
111 
112     DomainNameInfo.DomainName.Length = DomainNameLength * sizeof(WCHAR);
113     DomainNameInfo.DomainName.MaximumLength = DomainNameInfo.DomainName.Length + sizeof(WCHAR);
114     DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName;
115 
116     Status = SamConnect(NULL,
117                         &ServerHandle,
118                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
119                         NULL);
120     if (NT_SUCCESS(Status))
121     {
122         Status = SamOpenDomain(ServerHandle,
123                                DOMAIN_WRITE_OTHER_PARAMETERS,
124                                Info.DomainSid,
125                                &DomainHandle);
126         if (NT_SUCCESS(Status))
127         {
128             Status = SamSetInformationDomain(DomainHandle,
129                                              DomainNameInformation,
130                                              &DomainNameInfo);
131             if (!NT_SUCCESS(Status))
132             {
133                 DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status);
134             }
135 
136             SamCloseHandle(DomainHandle);
137         }
138         else
139         {
140             DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status);
141         }
142 
143         SamCloseHandle(ServerHandle);
144     }
145 
146     return Status;
147 }
148 
149 
150 /* Hack */
151 static
152 NTSTATUS
SetPrimaryDomain(LPCWSTR DomainName,PSID DomainSid)153 SetPrimaryDomain(LPCWSTR DomainName,
154                  PSID DomainSid)
155 {
156     PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL;
157     POLICY_PRIMARY_DOMAIN_INFO Info;
158     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
159     LSA_HANDLE PolicyHandle;
160     SIZE_T DomainNameLength = 0;
161     NTSTATUS Status;
162 
163     DPRINT1("SYSSETUP: SetPrimaryDomain()\n");
164 
165     if (DomainName != NULL)
166     {
167         DomainNameLength = wcslen(DomainName);
168         if (DomainNameLength > UNICODE_STRING_MAX_CHARS)
169         {
170             return STATUS_INVALID_PARAMETER;
171         }
172     }
173 
174     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
175     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
176 
177     Status = LsaOpenPolicy(NULL,
178                            &ObjectAttributes,
179                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
180                            &PolicyHandle);
181     if (Status != STATUS_SUCCESS)
182     {
183         DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
184         return Status;
185     }
186 
187     Status = LsaQueryInformationPolicy(PolicyHandle,
188                                        PolicyPrimaryDomainInformation,
189                                        (PVOID *)&OrigInfo);
190     if (Status == STATUS_SUCCESS && OrigInfo != NULL)
191     {
192         if (DomainName == NULL)
193         {
194             Info.Name.Buffer = OrigInfo->Name.Buffer;
195             Info.Name.Length = OrigInfo->Name.Length;
196             Info.Name.MaximumLength = OrigInfo->Name.MaximumLength;
197         }
198         else
199         {
200             Info.Name.Buffer = (LPWSTR)DomainName;
201             Info.Name.Length = DomainNameLength * sizeof(WCHAR);
202             Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
203         }
204 
205         if (DomainSid == NULL)
206             Info.Sid = OrigInfo->Sid;
207         else
208             Info.Sid = DomainSid;
209     }
210     else
211     {
212         Info.Name.Buffer = (LPWSTR)DomainName;
213         Info.Name.Length = DomainNameLength * sizeof(WCHAR);
214         Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
215         Info.Sid = DomainSid;
216     }
217 
218     Status = LsaSetInformationPolicy(PolicyHandle,
219                                      PolicyPrimaryDomainInformation,
220                                      (PVOID)&Info);
221     if (Status != STATUS_SUCCESS)
222     {
223         DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
224     }
225 
226     if (OrigInfo != NULL)
227         LsaFreeMemory(OrigInfo);
228 
229     LsaClose(PolicyHandle);
230 
231     return Status;
232 }
233 
234 
235 static
236 VOID
InstallBuiltinAccounts(VOID)237 InstallBuiltinAccounts(VOID)
238 {
239     LPWSTR BuiltinAccounts[] = {
240         L"S-1-1-0",         /* Everyone */
241         L"S-1-5-4",         /* Interactive */
242         L"S-1-5-6",         /* Service */
243         L"S-1-5-19",        /* Local Service */
244         L"S-1-5-20",        /* Network Service */
245         L"S-1-5-32-544",    /* Administrators */
246         L"S-1-5-32-545",    /* Users */
247         L"S-1-5-32-547",    /* Power Users */
248         L"S-1-5-32-551",    /* Backup Operators */
249         L"S-1-5-32-555"};   /* Remote Desktop Users */
250     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
251     NTSTATUS Status;
252     LSA_HANDLE PolicyHandle = NULL;
253     LSA_HANDLE AccountHandle = NULL;
254     PSID AccountSid;
255     ULONG i;
256 
257     DPRINT("InstallBuiltinAccounts()\n");
258 
259     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
260 
261     Status = LsaOpenPolicy(NULL,
262                            &ObjectAttributes,
263                            POLICY_CREATE_ACCOUNT,
264                            &PolicyHandle);
265     if (!NT_SUCCESS(Status))
266     {
267         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
268         return;
269     }
270 
271     for (i = 0; i < ARRAYSIZE(BuiltinAccounts); i++)
272     {
273         if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid))
274         {
275             DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError());
276             continue;
277         }
278 
279         Status = LsaCreateAccount(PolicyHandle,
280                                   AccountSid,
281                                   0,
282                                   &AccountHandle);
283         if (NT_SUCCESS(Status))
284         {
285             LsaClose(AccountHandle);
286         }
287 
288         LocalFree(AccountSid);
289     }
290 
291     LsaClose(PolicyHandle);
292 }
293 
294 
295 static
296 VOID
InstallPrivileges(HINF hSecurityInf)297 InstallPrivileges(
298     HINF hSecurityInf)
299 {
300     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
301     WCHAR szPrivilegeString[256];
302     WCHAR szSidString[256];
303     INFCONTEXT InfContext;
304     DWORD i;
305     PSID AccountSid = NULL;
306     NTSTATUS Status;
307     LSA_HANDLE PolicyHandle = NULL;
308     LSA_UNICODE_STRING RightString, AccountName;
309     PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL;
310     PLSA_TRANSLATED_SID2 Sids = NULL;
311 
312     DPRINT("InstallPrivileges()\n");
313 
314     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
315 
316     Status = LsaOpenPolicy(NULL,
317                            &ObjectAttributes,
318                            POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
319                            &PolicyHandle);
320     if (!NT_SUCCESS(Status))
321     {
322         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
323         goto done;
324     }
325 
326     if (!SetupFindFirstLineW(hSecurityInf,
327                              L"Privilege Rights",
328                              NULL,
329                              &InfContext))
330     {
331         DPRINT1("SetupFindFirstLineW failed\n");
332         goto done;
333     }
334 
335     do
336     {
337         /* Retrieve the privilege name */
338         if (!SetupGetStringFieldW(&InfContext,
339                                   0,
340                                   szPrivilegeString,
341                                   ARRAYSIZE(szPrivilegeString),
342                                   NULL))
343         {
344             DPRINT1("SetupGetStringFieldW() failed\n");
345             goto done;
346         }
347         DPRINT("Privilege: %S\n", szPrivilegeString);
348 
349         for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
350         {
351             if (!SetupGetStringFieldW(&InfContext,
352                                       i + 1,
353                                       szSidString,
354                                       ARRAYSIZE(szSidString),
355                                       NULL))
356             {
357                 DPRINT1("SetupGetStringFieldW() failed\n");
358                 goto done;
359             }
360             DPRINT("SID: %S\n", szSidString);
361 
362             if (szSidString[0] == UNICODE_NULL)
363                 continue;
364 
365             if (szSidString[0] == L'*')
366             {
367                 DPRINT("Account Sid: %S\n", &szSidString[1]);
368 
369                 if (!ConvertStringSidToSid(&szSidString[1], &AccountSid))
370                 {
371                     DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError());
372                     continue;
373                 }
374             }
375             else
376             {
377                 DPRINT("Account name: %S\n", szSidString);
378 
379                 ReferencedDomains = NULL;
380                 Sids = NULL;
381                 RtlInitUnicodeString(&AccountName, szSidString);
382                 Status = LsaLookupNames2(PolicyHandle,
383                                          0,
384                                          1,
385                                          &AccountName,
386                                          &ReferencedDomains,
387                                          &Sids);
388                 if (ReferencedDomains != NULL)
389                 {
390                     LsaFreeMemory(ReferencedDomains);
391                 }
392 
393                 if (!NT_SUCCESS(Status))
394                 {
395                     DPRINT1("LsaLookupNames2() failed (Status 0x%08lx)\n", Status);
396 
397                     if (Sids != NULL)
398                     {
399                         LsaFreeMemory(Sids);
400                         Sids = NULL;
401                     }
402 
403                     continue;
404                 }
405             }
406 
407             RtlInitUnicodeString(&RightString, szPrivilegeString);
408             Status = LsaAddAccountRights(PolicyHandle,
409                                          (AccountSid != NULL) ? AccountSid : Sids[0].Sid,
410                                          &RightString,
411                                          1);
412             if (!NT_SUCCESS(Status))
413             {
414                 DPRINT1("LsaAddAccountRights() failed (Status %08lx)\n", Status);
415             }
416 
417             if (Sids != NULL)
418             {
419                 LsaFreeMemory(Sids);
420                 Sids = NULL;
421             }
422 
423             if (AccountSid != NULL)
424             {
425                 LocalFree(AccountSid);
426                 AccountSid = NULL;
427             }
428         }
429 
430     }
431     while (SetupFindNextLine(&InfContext, &InfContext));
432 
433 done:
434     if (PolicyHandle != NULL)
435         LsaClose(PolicyHandle);
436 }
437 
438 
439 static
440 VOID
ApplyRegistryValues(HINF hSecurityInf)441 ApplyRegistryValues(
442     HINF hSecurityInf)
443 {
444     WCHAR szRegistryPath[MAX_PATH];
445     WCHAR szRootName[MAX_PATH];
446     WCHAR szKeyName[MAX_PATH];
447     WCHAR szValueName[MAX_PATH];
448     INFCONTEXT InfContext;
449     DWORD dwLength, dwType;
450     HKEY hRootKey, hKey;
451     PWSTR Ptr1, Ptr2;
452     DWORD dwError;
453     PVOID pBuffer;
454 
455     DPRINT("ApplyRegistryValues()\n");
456 
457     if (!SetupFindFirstLineW(hSecurityInf,
458                              L"Registry Values",
459                              NULL,
460                              &InfContext))
461     {
462         DPRINT1("SetupFindFirstLineW failed\n");
463         return;
464     }
465 
466     do
467     {
468         /* Retrieve the privilege name */
469         if (!SetupGetStringFieldW(&InfContext,
470                                   0,
471                                   szRegistryPath,
472                                   ARRAYSIZE(szRegistryPath),
473                                   NULL))
474         {
475             DPRINT1("SetupGetStringFieldW() failed\n");
476             return;
477         }
478 
479         DPRINT("RegistryPath: %S\n", szRegistryPath);
480 
481         Ptr1 = wcschr(szRegistryPath, L'\\');
482         Ptr2 = wcsrchr(szRegistryPath, L'\\');
483         if (Ptr1 != NULL && Ptr2 != NULL && Ptr1 != Ptr2)
484         {
485             dwLength = (DWORD)(((ULONG_PTR)Ptr1 - (ULONG_PTR)szRegistryPath) / sizeof(WCHAR));
486             wcsncpy(szRootName, szRegistryPath, dwLength);
487             szRootName[dwLength] = UNICODE_NULL;
488 
489             Ptr1++;
490             dwLength = (DWORD)(((ULONG_PTR)Ptr2 - (ULONG_PTR)Ptr1) / sizeof(WCHAR));
491             wcsncpy(szKeyName, Ptr1, dwLength);
492             szKeyName[dwLength] = UNICODE_NULL;
493 
494             Ptr2++;
495             wcscpy(szValueName, Ptr2);
496 
497             DPRINT("RootName: %S\n", szRootName);
498             DPRINT("KeyName: %S\n", szKeyName);
499             DPRINT("ValueName: %S\n", szValueName);
500 
501             if (_wcsicmp(szRootName, L"Machine") == 0)
502             {
503                 hRootKey = HKEY_LOCAL_MACHINE;
504             }
505             else
506             {
507                 DPRINT1("Unsupported root key %S\n", szRootName);
508                 break;
509             }
510 
511             if (!SetupGetIntField(&InfContext,
512                                   1,
513                                   (PINT)&dwType))
514             {
515                 DPRINT1("Failed to get key type (Error %lu)\n", GetLastError());
516                 break;
517             }
518 
519             if (dwType != REG_SZ && dwType != REG_EXPAND_SZ && dwType != REG_BINARY &&
520                 dwType != REG_DWORD && dwType != REG_MULTI_SZ)
521             {
522                 DPRINT1("Invalid value type %lu\n", dwType);
523                 break;
524             }
525 
526             dwLength = 0;
527             switch (dwType)
528             {
529                 case REG_SZ:
530                 case REG_EXPAND_SZ:
531                     SetupGetStringField(&InfContext,
532                                         2,
533                                         NULL,
534                                         0,
535                                         &dwLength);
536                     dwLength *= sizeof(WCHAR);
537                     break;
538 
539                 case REG_BINARY:
540                     SetupGetBinaryField(&InfContext,
541                                         2,
542                                         NULL,
543                                         0,
544                                         &dwLength);
545                     break;
546 
547                 case REG_DWORD:
548                     dwLength = sizeof(INT);
549                     break;
550 
551                 case REG_MULTI_SZ:
552                     SetupGetMultiSzField(&InfContext,
553                                          2,
554                                          NULL,
555                                          0,
556                                          &dwLength);
557                     dwLength *= sizeof(WCHAR);
558                     break;
559             }
560 
561             if (dwLength == 0)
562             {
563                 DPRINT1("Failed to determine the required buffer size!\n");
564                 break;
565             }
566 
567             dwError = RegCreateKeyExW(hRootKey,
568                                       szKeyName,
569                                       0,
570                                       NULL,
571                                       REG_OPTION_NON_VOLATILE,
572                                       KEY_WRITE,
573                                       NULL,
574                                       &hKey,
575                                       NULL);
576             if (dwError != ERROR_SUCCESS)
577             {
578                 DPRINT1("Failed to create the key %S (Error %lu)\n", szKeyName, dwError);
579                 break;
580             }
581 
582             pBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
583             if (pBuffer)
584             {
585                 switch (dwType)
586                 {
587                     case REG_SZ:
588                     case REG_EXPAND_SZ:
589                         SetupGetStringField(&InfContext,
590                                             2,
591                                             pBuffer,
592                                             dwLength / sizeof(WCHAR),
593                                             &dwLength);
594                         dwLength *= sizeof(WCHAR);
595                         break;
596 
597                     case REG_BINARY:
598                         SetupGetBinaryField(&InfContext,
599                                             2,
600                                             pBuffer,
601                                             dwLength,
602                                             &dwLength);
603                         break;
604 
605                     case REG_DWORD:
606                         SetupGetIntField(&InfContext,
607                                          2,
608                                          pBuffer);
609                         break;
610 
611                     case REG_MULTI_SZ:
612                         SetupGetMultiSzField(&InfContext,
613                                              2,
614                                              pBuffer,
615                                              dwLength / sizeof(WCHAR),
616                                              &dwLength);
617                         dwLength *= sizeof(WCHAR);
618                         break;
619                 }
620 
621                 RegSetValueEx(hKey,
622                               szValueName,
623                               0,
624                               dwType,
625                               pBuffer,
626                               dwLength);
627 
628                 HeapFree(GetProcessHeap(), 0, pBuffer);
629             }
630 
631             RegCloseKey(hKey);
632         }
633     }
634     while (SetupFindNextLine(&InfContext, &InfContext));
635 }
636 
637 
638 static
639 VOID
ApplyEventlogSettings(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName,_In_ PWSTR pszLogName)640 ApplyEventlogSettings(
641     _In_ HINF hSecurityInf,
642     _In_ PWSTR pszSectionName,
643     _In_ PWSTR pszLogName)
644 {
645     INFCONTEXT InfContext;
646     HKEY hServiceKey = NULL, hLogKey = NULL;
647     DWORD dwValue, dwError;
648     BOOL bValueSet;
649 
650     DPRINT("ApplyEventlogSettings(%p %S %S)\n",
651            hSecurityInf, pszSectionName, pszLogName);
652 
653     dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
654                               L"System\\CurrentControlSet\\Services\\Eventlog",
655                               0,
656                               NULL,
657                               REG_OPTION_NON_VOLATILE,
658                               KEY_WRITE,
659                               NULL,
660                               &hServiceKey,
661                               NULL);
662     if (dwError != ERROR_SUCCESS)
663     {
664         DPRINT1("Failed to create the Eventlog Service key (Error %lu)\n", dwError);
665         return;
666     }
667 
668     dwError = RegCreateKeyExW(hServiceKey,
669                               pszLogName,
670                               0,
671                               NULL,
672                               REG_OPTION_NON_VOLATILE,
673                               KEY_WRITE,
674                               NULL,
675                               &hLogKey,
676                               NULL);
677     if (dwError != ERROR_SUCCESS)
678     {
679         DPRINT1("Failed to create the key %S (Error %lu)\n", pszLogName, dwError);
680         RegCloseKey(hServiceKey);
681         return;
682     }
683 
684     if (SetupFindFirstLineW(hSecurityInf,
685                             pszSectionName,
686                             L"MaximumLogSize",
687                             &InfContext))
688     {
689         DPRINT("MaximumLogSize\n");
690         dwValue = 0;
691         SetupGetIntField(&InfContext,
692                          1,
693                          (PINT)&dwValue);
694 
695         DPRINT("MaximumLogSize: %lu (kByte)\n", dwValue);
696         if (dwValue >= 64 && dwValue <= 4194240)
697         {
698             dwValue *= 1024;
699 
700             DPRINT("MaxSize: %lu\n", dwValue);
701             RegSetValueEx(hLogKey,
702                           L"MaxSize",
703                           0,
704                           REG_DWORD,
705                           (LPBYTE)&dwValue,
706                           sizeof(dwValue));
707         }
708     }
709 
710     if (SetupFindFirstLineW(hSecurityInf,
711                             pszSectionName,
712                             L"AuditLogRetentionPeriod",
713                             &InfContext))
714     {
715         bValueSet = FALSE;
716         dwValue = 0;
717         SetupGetIntField(&InfContext,
718                          1,
719                          (PINT)&dwValue);
720         if (dwValue == 0)
721         {
722             bValueSet = TRUE;
723         }
724         else if (dwValue == 1)
725         {
726             if (SetupFindFirstLineW(hSecurityInf,
727                                     pszSectionName,
728                                     L"RetentionDays",
729                                     &InfContext))
730             {
731                 SetupGetIntField(&InfContext,
732                                  1,
733                                  (PINT)&dwValue);
734                 dwValue *= 86400;
735                 bValueSet = TRUE;
736             }
737         }
738         else if (dwValue == 2)
739         {
740             dwValue = (DWORD)-1;
741             bValueSet = TRUE;
742         }
743 
744         if (bValueSet)
745         {
746             DPRINT("Retention: %lu\n", dwValue);
747             RegSetValueEx(hLogKey,
748                           L"Retention",
749                           0,
750                           REG_DWORD,
751                           (LPBYTE)&dwValue,
752                           sizeof(dwValue));
753         }
754     }
755 
756     if (SetupFindFirstLineW(hSecurityInf,
757                             pszSectionName,
758                             L"RestrictGuestAccess",
759                             &InfContext))
760     {
761         dwValue = 0;
762         SetupGetIntField(&InfContext,
763                          1,
764                          (PINT)&dwValue);
765         if (dwValue == 0 || dwValue == 1)
766         {
767             DPRINT("RestrictGuestAccess: %lu\n", dwValue);
768             RegSetValueEx(hLogKey,
769                           L"RestrictGuestAccess",
770                           0,
771                           REG_DWORD,
772                           (LPBYTE)&dwValue,
773                           sizeof(dwValue));
774         }
775     }
776 
777     RegCloseKey(hLogKey);
778     RegCloseKey(hServiceKey);
779 }
780 
781 
782 static
783 VOID
ApplyPasswordSettings(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName)784 ApplyPasswordSettings(
785     _In_ HINF hSecurityInf,
786     _In_ PWSTR pszSectionName)
787 {
788     INFCONTEXT InfContext;
789     PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
790     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
791     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
792     LSA_HANDLE PolicyHandle = NULL;
793     SAM_HANDLE ServerHandle = NULL;
794     SAM_HANDLE DomainHandle = NULL;
795     INT nValue;
796     NTSTATUS Status;
797 
798     DPRINT("ApplyPasswordSettings()\n");
799 
800     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
801     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
802 
803     Status = LsaOpenPolicy(NULL,
804                            &ObjectAttributes,
805                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
806                            &PolicyHandle);
807     if (Status != STATUS_SUCCESS)
808     {
809         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
810         return;
811     }
812 
813     Status = LsaQueryInformationPolicy(PolicyHandle,
814                                        PolicyAccountDomainInformation,
815                                        (PVOID *)&OrigInfo);
816     if (!NT_SUCCESS(Status))
817     {
818         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
819         goto done;
820     }
821 
822     Status = SamConnect(NULL,
823                         &ServerHandle,
824                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
825                         NULL);
826     if (!NT_SUCCESS(Status))
827     {
828         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
829         goto done;
830     }
831 
832     Status = SamOpenDomain(ServerHandle,
833                            DOMAIN_READ_PASSWORD_PARAMETERS | DOMAIN_WRITE_PASSWORD_PARAMS,
834                            OrigInfo->DomainSid,
835                            &DomainHandle);
836     if (!NT_SUCCESS(Status))
837     {
838         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
839         goto done;
840     }
841 
842     Status = SamQueryInformationDomain(DomainHandle,
843                                        DomainPasswordInformation,
844                                        (PVOID*)&PasswordInfo);
845     if (!NT_SUCCESS(Status))
846     {
847         DPRINT1("SamQueryInformationDomain() failed (Status %08lx)\n", Status);
848         goto done;
849     }
850 
851     DPRINT("MaximumPasswordAge (OldValue) : 0x%I64x\n", PasswordInfo->MaxPasswordAge.QuadPart);
852     if (SetupFindFirstLineW(hSecurityInf,
853                             pszSectionName,
854                             L"MaximumPasswordAge",
855                             &InfContext))
856     {
857         if (SetupGetIntField(&InfContext, 1, &nValue))
858         {
859             DPRINT("Value: %ld\n", nValue);
860             if (nValue == -1)
861             {
862                 PasswordInfo->MaxPasswordAge.QuadPart = 0x8000000000000000;
863             }
864             else if ((nValue >= 1) && (nValue < 1000))
865             {
866                 PasswordInfo->MaxPasswordAge.QuadPart = (LONGLONG)nValue * TICKS_PER_DAY;
867             }
868             DPRINT("MaximumPasswordAge (NewValue) : 0x%I64x\n", PasswordInfo->MaxPasswordAge.QuadPart);
869         }
870     }
871 
872     DPRINT("MinimumPasswordAge (OldValue) : 0x%I64x\n", PasswordInfo->MinPasswordAge.QuadPart);
873     if (SetupFindFirstLineW(hSecurityInf,
874                             pszSectionName,
875                             L"MinimumPasswordAge",
876                             &InfContext))
877     {
878         if (SetupGetIntField(&InfContext, 1, &nValue))
879         {
880             DPRINT("Wert: %ld\n", nValue);
881             if ((nValue >= 0) && (nValue < 1000))
882             {
883                 if (PasswordInfo->MaxPasswordAge.QuadPart < (LONGLONG)nValue * TICKS_PER_DAY)
884                     PasswordInfo->MinPasswordAge.QuadPart = (LONGLONG)nValue * TICKS_PER_DAY;
885             }
886             DPRINT("MinimumPasswordAge (NewValue) : 0x%I64x\n", PasswordInfo->MinPasswordAge.QuadPart);
887         }
888     }
889 
890     DPRINT("MinimumPasswordLength (OldValue) : %lu\n", PasswordInfo->MinPasswordLength);
891     if (SetupFindFirstLineW(hSecurityInf,
892                             pszSectionName,
893                             L"MinimumPasswordLength",
894                             &InfContext))
895     {
896         if (SetupGetIntField(&InfContext, 1, &nValue))
897         {
898             DPRINT("Value: %ld\n", nValue);
899             if ((nValue >= 0) && (nValue <= 65535))
900             {
901                 PasswordInfo->MinPasswordLength = nValue;
902             }
903             DPRINT("MinimumPasswordLength (NewValue) : %lu\n", PasswordInfo->MinPasswordLength);
904         }
905     }
906 
907     DPRINT("PasswordHistoryLength (OldValue) : %lu\n", PasswordInfo->PasswordHistoryLength);
908     if (SetupFindFirstLineW(hSecurityInf,
909                             pszSectionName,
910                             L"PasswordHistorySize",
911                             &InfContext))
912     {
913         if (SetupGetIntField(&InfContext, 1, &nValue))
914         {
915             DPRINT("Value: %ld\n", nValue);
916             if ((nValue >= 0) && (nValue <= 65535))
917             {
918                 PasswordInfo->PasswordHistoryLength = nValue;
919             }
920             DPRINT("PasswordHistoryLength (NewValue) : %lu\n", PasswordInfo->PasswordHistoryLength);
921         }
922     }
923 
924     if (SetupFindFirstLineW(hSecurityInf,
925                             pszSectionName,
926                             L"PasswordComplexity",
927                             &InfContext))
928     {
929         if (SetupGetIntField(&InfContext, 1, &nValue))
930         {
931             if (nValue == 0)
932             {
933                 PasswordInfo->PasswordProperties &= ~DOMAIN_PASSWORD_COMPLEX;
934             }
935             else
936             {
937                 PasswordInfo->PasswordProperties |= DOMAIN_PASSWORD_COMPLEX;
938             }
939         }
940     }
941 
942     if (SetupFindFirstLineW(hSecurityInf,
943                             pszSectionName,
944                             L"ClearTextPassword",
945                             &InfContext))
946     {
947         if (SetupGetIntField(&InfContext, 1, &nValue))
948         {
949             if (nValue == 0)
950             {
951                 PasswordInfo->PasswordProperties &= ~DOMAIN_PASSWORD_STORE_CLEARTEXT;
952             }
953             else
954             {
955                 PasswordInfo->PasswordProperties |= DOMAIN_PASSWORD_STORE_CLEARTEXT;
956             }
957         }
958     }
959 
960     /* Windows ignores the RequireLogonToChangePassword option */
961 
962     Status = SamSetInformationDomain(DomainHandle,
963                                      DomainPasswordInformation,
964                                      PasswordInfo);
965     if (!NT_SUCCESS(Status))
966     {
967         DPRINT1("SamSetInformationDomain() failed (Status %08lx)\n", Status);
968         goto done;
969     }
970 
971 done:
972     if (PasswordInfo != NULL)
973         SamFreeMemory(PasswordInfo);
974 
975     if (DomainHandle != NULL)
976         SamCloseHandle(DomainHandle);
977 
978     if (ServerHandle != NULL)
979         SamCloseHandle(ServerHandle);
980 
981     if (OrigInfo != NULL)
982         LsaFreeMemory(OrigInfo);
983 
984     if (PolicyHandle != NULL)
985         LsaClose(PolicyHandle);
986 }
987 
988 
989 static
990 VOID
ApplyLockoutSettings(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName)991 ApplyLockoutSettings(
992     _In_ HINF hSecurityInf,
993     _In_ PWSTR pszSectionName)
994 {
995     INFCONTEXT InfContext;
996     PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
997     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
998     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
999     LSA_HANDLE PolicyHandle = NULL;
1000     SAM_HANDLE ServerHandle = NULL;
1001     SAM_HANDLE DomainHandle = NULL;
1002     INT nValue;
1003     NTSTATUS Status;
1004 
1005     DPRINT("ApplyLockoutSettings()\n");
1006 
1007     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
1008     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
1009 
1010     Status = LsaOpenPolicy(NULL,
1011                            &ObjectAttributes,
1012                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
1013                            &PolicyHandle);
1014     if (Status != STATUS_SUCCESS)
1015     {
1016         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
1017         return;
1018     }
1019 
1020     Status = LsaQueryInformationPolicy(PolicyHandle,
1021                                        PolicyAccountDomainInformation,
1022                                        (PVOID *)&OrigInfo);
1023     if (!NT_SUCCESS(Status))
1024     {
1025         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
1026         goto done;
1027     }
1028 
1029     Status = SamConnect(NULL,
1030                         &ServerHandle,
1031                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1032                         NULL);
1033     if (!NT_SUCCESS(Status))
1034     {
1035         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
1036         goto done;
1037     }
1038 
1039     Status = SamOpenDomain(ServerHandle,
1040                            DOMAIN_READ_PASSWORD_PARAMETERS | DOMAIN_WRITE_PASSWORD_PARAMS,
1041                            OrigInfo->DomainSid,
1042                            &DomainHandle);
1043     if (!NT_SUCCESS(Status))
1044     {
1045         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
1046         goto done;
1047     }
1048 
1049     Status = SamQueryInformationDomain(DomainHandle,
1050                                        DomainLockoutInformation,
1051                                        (PVOID*)&LockoutInfo);
1052     if (!NT_SUCCESS(Status))
1053     {
1054         DPRINT1("SamQueryInformationDomain() failed (Status %08lx)\n", Status);
1055         goto done;
1056     }
1057 
1058     if (SetupFindFirstLineW(hSecurityInf,
1059                             pszSectionName,
1060                             L"LockoutBadCount",
1061                             &InfContext))
1062     {
1063         if (SetupGetIntField(&InfContext, 1, &nValue))
1064         {
1065             if (nValue >= 0)
1066             {
1067                 LockoutInfo->LockoutThreshold = nValue;
1068             }
1069         }
1070     }
1071 
1072     if (SetupFindFirstLineW(hSecurityInf,
1073                             pszSectionName,
1074                             L"ResetLockoutCount",
1075                             &InfContext))
1076     {
1077         if (SetupGetIntField(&InfContext, 1, &nValue))
1078         {
1079             if (nValue >= 0)
1080             {
1081                 LockoutInfo->LockoutObservationWindow.QuadPart = (LONGLONG)nValue * TICKS_PER_MINUTE;
1082             }
1083         }
1084     }
1085 
1086     if (SetupFindFirstLineW(hSecurityInf,
1087                             pszSectionName,
1088                             L"LockoutDuration",
1089                             &InfContext))
1090     {
1091         if (SetupGetIntField(&InfContext, 1, &nValue))
1092         {
1093             if (nValue == -1)
1094             {
1095                 LockoutInfo->LockoutDuration.QuadPart = 0x8000000000000000LL;
1096             }
1097             else if ((nValue >= 0) && (nValue < 100000))
1098             {
1099                 LockoutInfo->LockoutDuration.QuadPart = (LONGLONG)nValue * TICKS_PER_MINUTE;
1100             }
1101         }
1102     }
1103 
1104     Status = SamSetInformationDomain(DomainHandle,
1105                                      DomainLockoutInformation,
1106                                      LockoutInfo);
1107     if (!NT_SUCCESS(Status))
1108     {
1109         DPRINT1("SamSetInformationDomain() failed (Status %08lx)\n", Status);
1110         goto done;
1111     }
1112 
1113 done:
1114     if (LockoutInfo != NULL)
1115         SamFreeMemory(LockoutInfo);
1116 
1117     if (DomainHandle != NULL)
1118         SamCloseHandle(DomainHandle);
1119 
1120     if (ServerHandle != NULL)
1121         SamCloseHandle(ServerHandle);
1122 
1123     if (OrigInfo != NULL)
1124         LsaFreeMemory(OrigInfo);
1125 
1126     if (PolicyHandle != NULL)
1127         LsaClose(PolicyHandle);
1128 }
1129 
1130 
1131 static
1132 VOID
SetLsaAnonymousNameLookup(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName)1133 SetLsaAnonymousNameLookup(
1134     _In_ HINF hSecurityInf,
1135     _In_ PWSTR pszSectionName)
1136 {
1137 #if 0
1138     INFCONTEXT InfContext;
1139     INT nValue = 0;
1140 
1141     DPRINT1("SetLsaAnonymousNameLookup()\n");
1142 
1143     if (!SetupFindFirstLineW(hSecurityInf,
1144                              pszSectionName,
1145                              L"LSAAnonymousNameLookup",
1146                              &InfContext))
1147     {
1148         return;
1149     }
1150 
1151     if (!SetupGetIntField(&InfContext, 1, &nValue))
1152     {
1153         return;
1154     }
1155 
1156     if (nValue == 0)
1157     {
1158     }
1159     else
1160     {
1161     }
1162 #endif
1163 }
1164 
1165 
1166 static
1167 VOID
EnableAccount(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName,_In_ PWSTR pszValueName,_In_ SAM_HANDLE DomainHandle,_In_ DWORD dwAccountRid)1168 EnableAccount(
1169     _In_ HINF hSecurityInf,
1170     _In_ PWSTR pszSectionName,
1171     _In_ PWSTR pszValueName,
1172     _In_ SAM_HANDLE DomainHandle,
1173     _In_ DWORD dwAccountRid)
1174 {
1175     INFCONTEXT InfContext;
1176     SAM_HANDLE UserHandle = NULL;
1177     PUSER_CONTROL_INFORMATION ControlInfo = NULL;
1178     INT nValue = 0;
1179     NTSTATUS Status;
1180 
1181     DPRINT("EnableAccount()\n");
1182 
1183     if (!SetupFindFirstLineW(hSecurityInf,
1184                             pszSectionName,
1185                             pszValueName,
1186                             &InfContext))
1187         return;
1188 
1189     if (!SetupGetIntField(&InfContext, 1, &nValue))
1190     {
1191         DPRINT1("No valid integer value\n");
1192         goto done;
1193     }
1194 
1195     DPRINT("Value: %d\n", nValue);
1196 
1197     Status = SamOpenUser(DomainHandle,
1198                          USER_READ_ACCOUNT | USER_WRITE_ACCOUNT,
1199                          dwAccountRid,
1200                          &UserHandle);
1201     if (!NT_SUCCESS(Status))
1202     {
1203         DPRINT1("SamOpenUser() failed (Status: 0x%08lx)\n", Status);
1204         goto done;
1205     }
1206 
1207     Status = SamQueryInformationUser(UserHandle,
1208                                      UserControlInformation,
1209                                      (PVOID*)&ControlInfo);
1210     if (!NT_SUCCESS(Status))
1211     {
1212         DPRINT1("SamQueryInformationUser() failed (Status: 0x%08lx)\n", Status);
1213         goto done;
1214     }
1215 
1216     if (nValue == 0)
1217     {
1218         ControlInfo->UserAccountControl |= USER_ACCOUNT_DISABLED;
1219     }
1220     else
1221     {
1222         ControlInfo->UserAccountControl &= ~USER_ACCOUNT_DISABLED;
1223     }
1224 
1225     Status = SamSetInformationUser(UserHandle,
1226                                    UserControlInformation,
1227                                    ControlInfo);
1228     if (!NT_SUCCESS(Status))
1229     {
1230         DPRINT1("SamSetInformationUser() failed (Status: 0x%08lx)\n", Status);
1231     }
1232 
1233 done:
1234     if (ControlInfo != NULL)
1235         SamFreeMemory(ControlInfo);
1236 
1237     if (UserHandle != NULL)
1238         SamCloseHandle(UserHandle);
1239 }
1240 
1241 
1242 static
1243 VOID
SetNewAccountName(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName,_In_ PWSTR pszValueName,_In_ SAM_HANDLE DomainHandle,_In_ DWORD dwAccountRid)1244 SetNewAccountName(
1245     _In_ HINF hSecurityInf,
1246     _In_ PWSTR pszSectionName,
1247     _In_ PWSTR pszValueName,
1248     _In_ SAM_HANDLE DomainHandle,
1249     _In_ DWORD dwAccountRid)
1250 {
1251     INFCONTEXT InfContext;
1252     DWORD dwLength = 0;
1253     PWSTR pszName = NULL;
1254     SAM_HANDLE UserHandle = NULL;
1255     USER_NAME_INFORMATION NameInfo;
1256     NTSTATUS Status;
1257 
1258     DPRINT("SetNewAccountName()\n");
1259 
1260     if (!SetupFindFirstLineW(hSecurityInf,
1261                             pszSectionName,
1262                             pszValueName,
1263                             &InfContext))
1264         return;
1265 
1266     SetupGetStringFieldW(&InfContext,
1267                          1,
1268                          NULL,
1269                          0,
1270                          &dwLength);
1271     if (dwLength == 0)
1272         return;
1273 
1274     ASSERT(dwLength <= UNICODE_STRING_MAX_CHARS);
1275 
1276     pszName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength * sizeof(WCHAR));
1277     if (pszName == NULL)
1278     {
1279         DPRINT1("HeapAlloc() failed\n");
1280         return;
1281     }
1282 
1283     if (!SetupGetStringFieldW(&InfContext,
1284                               1,
1285                               pszName,
1286                               dwLength,
1287                               &dwLength))
1288     {
1289         DPRINT1("No valid string value\n");
1290         goto done;
1291     }
1292 
1293     DPRINT("NewAccountName: '%S'\n", pszName);
1294 
1295     Status = SamOpenUser(DomainHandle,
1296                          USER_WRITE_ACCOUNT,
1297                          dwAccountRid,
1298                          &UserHandle);
1299     if (!NT_SUCCESS(Status))
1300     {
1301         DPRINT1("SamOpenUser() failed (Status: 0x%08lx)\n", Status);
1302         goto done;
1303     }
1304 
1305     NameInfo.UserName.Length = (USHORT)wcslen(pszName) * sizeof(WCHAR);
1306     NameInfo.UserName.MaximumLength = NameInfo.UserName.Length + sizeof(WCHAR);
1307     NameInfo.UserName.Buffer = pszName;
1308     NameInfo.FullName.Length = 0;
1309     NameInfo.FullName.MaximumLength = 0;
1310     NameInfo.FullName.Buffer = NULL;
1311 
1312     Status = SamSetInformationUser(UserHandle,
1313                                    UserNameInformation,
1314                                    &NameInfo);
1315     if (!NT_SUCCESS(Status))
1316     {
1317         DPRINT1("SamSetInformationUser() failed (Status: 0x%08lx)\n", Status);
1318     }
1319 
1320 done:
1321     if (UserHandle != NULL)
1322         SamCloseHandle(UserHandle);
1323 
1324     if (pszName != NULL)
1325         HeapFree(GetProcessHeap(), 0, pszName);
1326 }
1327 
1328 
1329 static
1330 VOID
ApplyAccountSettings(_In_ HINF hSecurityInf,_In_ PWSTR pszSectionName)1331 ApplyAccountSettings(
1332     _In_ HINF hSecurityInf,
1333     _In_ PWSTR pszSectionName)
1334 {
1335     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
1336     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
1337     LSA_HANDLE PolicyHandle = NULL;
1338     SAM_HANDLE ServerHandle = NULL;
1339     SAM_HANDLE DomainHandle = NULL;
1340     NTSTATUS Status;
1341 
1342     DPRINT("ApplyAccountSettings()\n");
1343 
1344     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
1345     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
1346 
1347     Status = LsaOpenPolicy(NULL,
1348                            &ObjectAttributes,
1349                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
1350                            &PolicyHandle);
1351     if (Status != STATUS_SUCCESS)
1352     {
1353         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
1354         return;
1355     }
1356 
1357     Status = LsaQueryInformationPolicy(PolicyHandle,
1358                                        PolicyAccountDomainInformation,
1359                                        (PVOID *)&OrigInfo);
1360     if (!NT_SUCCESS(Status))
1361     {
1362         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
1363         goto done;
1364     }
1365 
1366     Status = SamConnect(NULL,
1367                         &ServerHandle,
1368                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1369                         NULL);
1370     if (!NT_SUCCESS(Status))
1371     {
1372         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
1373         goto done;
1374     }
1375 
1376     Status = SamOpenDomain(ServerHandle,
1377                            DOMAIN_LOOKUP,
1378                            OrigInfo->DomainSid,
1379                            &DomainHandle);
1380     if (!NT_SUCCESS(Status))
1381     {
1382         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
1383         goto done;
1384     }
1385 
1386     SetLsaAnonymousNameLookup(hSecurityInf,
1387                               pszSectionName);
1388 
1389     EnableAccount(hSecurityInf,
1390                   pszSectionName,
1391                   L"EnableAdminAccount",
1392                   DomainHandle,
1393                   DOMAIN_USER_RID_ADMIN);
1394 
1395     EnableAccount(hSecurityInf,
1396                   pszSectionName,
1397                   L"EnableGuestAccount",
1398                   DomainHandle,
1399                   DOMAIN_USER_RID_GUEST);
1400 
1401     SetNewAccountName(hSecurityInf,
1402                       pszSectionName,
1403                       L"NewAdministratorName",
1404                       DomainHandle,
1405                       DOMAIN_USER_RID_ADMIN);
1406 
1407     SetNewAccountName(hSecurityInf,
1408                       pszSectionName,
1409                       L"NewGuestName",
1410                       DomainHandle,
1411                       DOMAIN_USER_RID_GUEST);
1412 
1413 done:
1414     if (DomainHandle != NULL)
1415         SamCloseHandle(DomainHandle);
1416 
1417     if (ServerHandle != NULL)
1418         SamCloseHandle(ServerHandle);
1419 
1420     if (OrigInfo != NULL)
1421         LsaFreeMemory(OrigInfo);
1422 
1423     if (PolicyHandle != NULL)
1424         LsaClose(PolicyHandle);
1425 }
1426 
1427 
1428 static
1429 VOID
ApplyAuditEvents(_In_ HINF hSecurityInf)1430 ApplyAuditEvents(
1431     _In_ HINF hSecurityInf)
1432 {
1433     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
1434     INFCONTEXT InfContext;
1435     WCHAR szOptionName[256];
1436     INT nValue;
1437     LSA_HANDLE PolicyHandle = NULL;
1438     POLICY_AUDIT_EVENTS_INFO AuditInfo;
1439     PULONG AuditOptions = NULL;
1440     NTSTATUS Status;
1441 
1442     DPRINT("ApplyAuditEvents(%p)\n", hSecurityInf);
1443 
1444     if (!SetupFindFirstLineW(hSecurityInf,
1445                              L"Event Audit",
1446                              NULL,
1447                              &InfContext))
1448     {
1449         DPRINT1("SetupFindFirstLineW failed\n");
1450         return;
1451     }
1452 
1453     ZeroMemory(&ObjectAttributes, sizeof(LSA_OBJECT_ATTRIBUTES));
1454 
1455     Status = LsaOpenPolicy(NULL,
1456                            &ObjectAttributes,
1457                            POLICY_SET_AUDIT_REQUIREMENTS,
1458                            &PolicyHandle);
1459     if (!NT_SUCCESS(Status))
1460     {
1461         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
1462         return;
1463     }
1464 
1465     AuditOptions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1466                              (AuditCategoryAccountLogon + 1) * sizeof(ULONG));
1467     if (AuditOptions == NULL)
1468     {
1469         DPRINT1("Failed to allocate the auditiing options array!\n");
1470         goto done;
1471     }
1472 
1473     AuditInfo.AuditingMode = TRUE;
1474     AuditInfo.EventAuditingOptions = AuditOptions;
1475     AuditInfo.MaximumAuditEventCount = AuditCategoryAccountLogon + 1;
1476 
1477     do
1478     {
1479         /* Retrieve the group name */
1480         if (!SetupGetStringFieldW(&InfContext,
1481                                   0,
1482                                   szOptionName,
1483                                   ARRAYSIZE(szOptionName),
1484                                   NULL))
1485         {
1486             DPRINT1("SetupGetStringFieldW() failed\n");
1487             continue;
1488         }
1489 
1490         DPRINT("Option: '%S'\n", szOptionName);
1491 
1492         if (!SetupGetIntField(&InfContext,
1493                               1,
1494                               &nValue))
1495         {
1496             DPRINT1("SetupGetStringFieldW() failed\n");
1497             continue;
1498         }
1499 
1500         DPRINT("Value: %d\n", nValue);
1501 
1502         if ((nValue < POLICY_AUDIT_EVENT_UNCHANGED) || (nValue > POLICY_AUDIT_EVENT_NONE))
1503         {
1504             DPRINT1("Invalid audit option!\n");
1505             continue;
1506         }
1507 
1508         if (_wcsicmp(szOptionName, L"AuditSystemEvents") == 0)
1509         {
1510             AuditOptions[AuditCategorySystem] = (ULONG)nValue;
1511         }
1512         else if (_wcsicmp(szOptionName, L"AuditLogonEvents") == 0)
1513         {
1514             AuditOptions[AuditCategoryLogon] = (ULONG)nValue;
1515         }
1516         else if (_wcsicmp(szOptionName, L"AuditObjectAccess") == 0)
1517         {
1518             AuditOptions[AuditCategoryObjectAccess] = (ULONG)nValue;
1519         }
1520         else if (_wcsicmp(szOptionName, L"AuditPrivilegeUse") == 0)
1521         {
1522             AuditOptions[AuditCategoryPrivilegeUse] = (ULONG)nValue;
1523         }
1524         else if (_wcsicmp(szOptionName, L"AuditProcessTracking") == 0)
1525         {
1526             AuditOptions[AuditCategoryDetailedTracking] = (ULONG)nValue;
1527         }
1528         else if (_wcsicmp(szOptionName, L"AuditPolicyChange") == 0)
1529         {
1530             AuditOptions[AuditCategoryPolicyChange] = (ULONG)nValue;
1531         }
1532         else if (_wcsicmp(szOptionName, L"AuditAccountManage") == 0)
1533         {
1534             AuditOptions[AuditCategoryAccountManagement] = (ULONG)nValue;
1535         }
1536         else if (_wcsicmp(szOptionName, L"AuditDSAccess") == 0)
1537         {
1538             AuditOptions[AuditCategoryDirectoryServiceAccess] = (ULONG)nValue;
1539         }
1540         else if (_wcsicmp(szOptionName, L"AuditAccountLogon") == 0)
1541         {
1542             AuditOptions[AuditCategoryAccountLogon] = (ULONG)nValue;
1543         }
1544         else
1545         {
1546             DPRINT1("Invalid auditing option '%S'\n", szOptionName);
1547         }
1548     }
1549     while (SetupFindNextLine(&InfContext, &InfContext));
1550 
1551     Status = LsaSetInformationPolicy(PolicyHandle,
1552                                      PolicyAuditEventsInformation,
1553                                      (PVOID)&AuditInfo);
1554     if (Status != STATUS_SUCCESS)
1555     {
1556         DPRINT1("LsaSetInformationPolicy() failed (Status 0x%08lx)\n", Status);
1557     }
1558 
1559 done:
1560     if (AuditOptions != NULL)
1561         HeapFree(GetProcessHeap(), 0, AuditOptions);
1562 
1563     if (PolicyHandle != NULL)
1564         LsaClose(PolicyHandle);
1565 }
1566 
1567 
1568 VOID
InstallSecurity(VOID)1569 InstallSecurity(VOID)
1570 {
1571     HINF hSecurityInf;
1572     PWSTR pszSecurityInf;
1573 
1574 //    if (IsServer())
1575 //        pszSecurityInf = L"defltsv.inf";
1576 //    else
1577         pszSecurityInf = L"defltwk.inf";
1578 
1579     InstallBuiltinAccounts();
1580 
1581     hSecurityInf = SetupOpenInfFileW(pszSecurityInf,
1582                                      NULL,
1583                                      INF_STYLE_WIN4,
1584                                      NULL);
1585     if (hSecurityInf != INVALID_HANDLE_VALUE)
1586     {
1587         InstallPrivileges(hSecurityInf);
1588         ApplyRegistryValues(hSecurityInf);
1589 
1590         ApplyEventlogSettings(hSecurityInf, L"Application Log", L"Application");
1591         ApplyEventlogSettings(hSecurityInf, L"Security Log", L"Security");
1592         ApplyEventlogSettings(hSecurityInf, L"System Log", L"System");
1593 
1594         ApplyPasswordSettings(hSecurityInf, L"System Access");
1595         ApplyLockoutSettings(hSecurityInf, L"System Access");
1596         ApplyAccountSettings(hSecurityInf, L"System Access");
1597 
1598         ApplyAuditEvents(hSecurityInf);
1599 
1600         SetupCloseInfFile(hSecurityInf);
1601     }
1602 
1603     /* Hack */
1604     SetPrimaryDomain(L"WORKGROUP", NULL);
1605 }
1606 
1607 
1608 NTSTATUS
SetAdministratorPassword(LPCWSTR Password)1609 SetAdministratorPassword(LPCWSTR Password)
1610 {
1611     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
1612     PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
1613     USER_SET_PASSWORD_INFORMATION PasswordInfo;
1614     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
1615     LSA_HANDLE PolicyHandle = NULL;
1616     SAM_HANDLE ServerHandle = NULL;
1617     SAM_HANDLE DomainHandle = NULL;
1618     SAM_HANDLE UserHandle = NULL;
1619     NTSTATUS Status;
1620 
1621     DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
1622 
1623     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
1624     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
1625 
1626     Status = LsaOpenPolicy(NULL,
1627                            &ObjectAttributes,
1628                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
1629                            &PolicyHandle);
1630     if (Status != STATUS_SUCCESS)
1631     {
1632         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
1633         return Status;
1634     }
1635 
1636     Status = LsaQueryInformationPolicy(PolicyHandle,
1637                                        PolicyAccountDomainInformation,
1638                                        (PVOID *)&OrigInfo);
1639     if (!NT_SUCCESS(Status))
1640     {
1641         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
1642         goto done;
1643     }
1644 
1645     Status = SamConnect(NULL,
1646                         &ServerHandle,
1647                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1648                         NULL);
1649     if (!NT_SUCCESS(Status))
1650     {
1651         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
1652         goto done;
1653     }
1654 
1655     Status = SamOpenDomain(ServerHandle,
1656                            DOMAIN_LOOKUP,
1657                            OrigInfo->DomainSid,
1658                            &DomainHandle);
1659     if (!NT_SUCCESS(Status))
1660     {
1661         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
1662         goto done;
1663     }
1664 
1665     Status = SamOpenUser(DomainHandle,
1666                          USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
1667                          DOMAIN_USER_RID_ADMIN,
1668                          &UserHandle);
1669     if (!NT_SUCCESS(Status))
1670     {
1671         DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
1672         goto done;
1673     }
1674 
1675     RtlInitUnicodeString(&PasswordInfo.Password, Password);
1676     PasswordInfo.PasswordExpired = FALSE;
1677 
1678     Status = SamSetInformationUser(UserHandle,
1679                                    UserSetPasswordInformation,
1680                                    &PasswordInfo);
1681     if (!NT_SUCCESS(Status))
1682     {
1683         DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
1684         goto done;
1685     }
1686 
1687     Status = SamQueryInformationUser(UserHandle,
1688                                      UserAccountNameInformation,
1689                                      (PVOID*)&AccountNameInfo);
1690     if (!NT_SUCCESS(Status))
1691     {
1692         DPRINT1("SamQueryInformationUser() failed (Status 0x%08lx)\n", Status);
1693         goto done;
1694     }
1695 
1696     AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
1697                                      HEAP_ZERO_MEMORY,
1698                                      AccountNameInfo->UserName.Length + sizeof(WCHAR));
1699     if (AdminInfo.Name != NULL)
1700         RtlCopyMemory(AdminInfo.Name,
1701                       AccountNameInfo->UserName.Buffer,
1702                       AccountNameInfo->UserName.Length);
1703 
1704     AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
1705                                        HEAP_ZERO_MEMORY,
1706                                        OrigInfo->DomainName.Length + sizeof(WCHAR));
1707     if (AdminInfo.Domain != NULL)
1708         RtlCopyMemory(AdminInfo.Domain,
1709                       OrigInfo->DomainName.Buffer,
1710                       OrigInfo->DomainName.Length);
1711 
1712     AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
1713                                          0,
1714                                          (wcslen(Password) + 1) * sizeof(WCHAR));
1715     if (AdminInfo.Password != NULL)
1716         wcscpy(AdminInfo.Password, Password);
1717 
1718     DPRINT("Administrator Name: %S\n", AdminInfo.Name);
1719     DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
1720     DPRINT("Administrator Password: %S\n", AdminInfo.Password);
1721 
1722 done:
1723     if (AccountNameInfo != NULL)
1724         SamFreeMemory(AccountNameInfo);
1725 
1726     if (OrigInfo != NULL)
1727         LsaFreeMemory(OrigInfo);
1728 
1729     if (PolicyHandle != NULL)
1730         LsaClose(PolicyHandle);
1731 
1732     if (UserHandle != NULL)
1733         SamCloseHandle(UserHandle);
1734 
1735     if (DomainHandle != NULL)
1736         SamCloseHandle(DomainHandle);
1737 
1738     if (ServerHandle != NULL)
1739         SamCloseHandle(ServerHandle);
1740 
1741     DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
1742 
1743     return Status;
1744 }
1745 
1746 
1747 VOID
SetAutoAdminLogon(VOID)1748 SetAutoAdminLogon(VOID)
1749 {
1750     WCHAR szAutoAdminLogon[2];
1751     HKEY hKey = NULL;
1752     DWORD dwType;
1753     DWORD dwSize;
1754     LONG lError;
1755 
1756     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1757                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1758                            0,
1759                            KEY_READ | KEY_WRITE,
1760                            &hKey);
1761     if (lError != ERROR_SUCCESS)
1762         return;
1763 
1764     dwSize = 2 * sizeof(WCHAR);
1765     lError = RegQueryValueExW(hKey,
1766                               L"AutoAdminLogon",
1767                               NULL,
1768                               &dwType,
1769                               (LPBYTE)szAutoAdminLogon,
1770                               &dwSize);
1771     if (lError != ERROR_SUCCESS)
1772         goto done;
1773 
1774     if (wcscmp(szAutoAdminLogon, L"1") == 0)
1775     {
1776         RegSetValueExW(hKey,
1777                        L"DefaultDomainName",
1778                        0,
1779                        REG_SZ,
1780                        (LPBYTE)AdminInfo.Domain,
1781                        (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
1782 
1783         RegSetValueExW(hKey,
1784                        L"DefaultUserName",
1785                        0,
1786                        REG_SZ,
1787                        (LPBYTE)AdminInfo.Name,
1788                        (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
1789 
1790         RegSetValueExW(hKey,
1791                        L"DefaultPassword",
1792                        0,
1793                        REG_SZ,
1794                        (LPBYTE)AdminInfo.Password,
1795                        (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
1796     }
1797 
1798 done:
1799     if (hKey != NULL)
1800         RegCloseKey(hKey);
1801 }
1802 
1803 
1804 /* EOF */
1805 
1806