xref: /reactos/dll/win32/syssetup/security.c (revision 5100859e)
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 < 10; 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(VOID)
275 {
276     HINF hSecurityInf = INVALID_HANDLE_VALUE;
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     hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer,
291                                      NULL,
292                                      INF_STYLE_WIN4,
293                                      NULL);
294     if (hSecurityInf == INVALID_HANDLE_VALUE)
295     {
296         DPRINT1("SetupOpenInfFileW failed\n");
297         return;
298     }
299 
300     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
301 
302     Status = LsaOpenPolicy(NULL,
303                            &ObjectAttributes,
304                            POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
305                            &PolicyHandle);
306     if (!NT_SUCCESS(Status))
307     {
308         DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
309         goto done;
310     }
311 
312     if (!SetupFindFirstLineW(hSecurityInf,
313                              L"Privilege Rights",
314                              NULL,
315                              &InfContext))
316     {
317         DPRINT1("SetupFindfirstLineW failed\n");
318         goto done;
319     }
320 
321     do
322     {
323         /* Retrieve the privilege name */
324         if (!SetupGetStringFieldW(&InfContext,
325                                   0,
326                                   szPrivilegeString,
327                                   256,
328                                   NULL))
329         {
330             DPRINT1("SetupGetStringFieldW() failed\n");
331             goto done;
332         }
333         DPRINT("Privilege: %S\n", szPrivilegeString);
334 
335         for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
336         {
337             if (!SetupGetStringFieldW(&InfContext,
338                                       i + 1,
339                                       szSidString,
340                                       256,
341                                       NULL))
342             {
343                 DPRINT1("SetupGetStringFieldW() failed\n");
344                 goto done;
345             }
346             DPRINT("SID: %S\n", szSidString);
347 
348             if (szSidString[0] == UNICODE_NULL)
349                 continue;
350 
351             if (szSidString[0] == L'*')
352             {
353                 DPRINT("Account Sid: %S\n", &szSidString[1]);
354 
355                 if (!ConvertStringSidToSid(&szSidString[1], &AccountSid))
356                 {
357                     DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError());
358                     continue;
359                 }
360             }
361             else
362             {
363                 DPRINT("Account name: %S\n", szSidString);
364                 continue;
365 
366             }
367 
368             RtlInitUnicodeString(&RightString, szPrivilegeString);
369             Status = LsaAddAccountRights(PolicyHandle,
370                                          (AccountSid != NULL) ? AccountSid : Sids[0].Sid,
371                                          &RightString,
372                                          1);
373             if (!NT_SUCCESS(Status))
374             {
375                 DPRINT1("LsaAddAccountRights() failed (Status %08lx)\n", Status);
376             }
377 
378             if (Sids != NULL)
379             {
380                 LsaFreeMemory(Sids);
381                 Sids = NULL;
382             }
383 
384             if (AccountSid != NULL)
385             {
386                 LocalFree(AccountSid);
387                 AccountSid = NULL;
388             }
389         }
390 
391     }
392     while (SetupFindNextLine(&InfContext, &InfContext));
393 
394 done:
395     if (PolicyHandle != NULL)
396         LsaClose(PolicyHandle);
397 
398     if (hSecurityInf != INVALID_HANDLE_VALUE)
399         SetupCloseInfFile(hSecurityInf);
400 }
401 
402 
403 VOID
404 InstallSecurity(VOID)
405 {
406     InstallBuiltinAccounts();
407     InstallPrivileges();
408 
409     /* Hack */
410     SetPrimaryDomain(L"WORKGROUP", NULL);
411 }
412 
413 
414 NTSTATUS
415 SetAdministratorPassword(LPCWSTR Password)
416 {
417     PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
418     PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
419     USER_SET_PASSWORD_INFORMATION PasswordInfo;
420     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
421     LSA_HANDLE PolicyHandle = NULL;
422     SAM_HANDLE ServerHandle = NULL;
423     SAM_HANDLE DomainHandle = NULL;
424     SAM_HANDLE UserHandle = NULL;
425     NTSTATUS Status;
426 
427     DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
428 
429     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
430     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
431 
432     Status = LsaOpenPolicy(NULL,
433                            &ObjectAttributes,
434                            POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
435                            &PolicyHandle);
436     if (Status != STATUS_SUCCESS)
437     {
438         DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
439         return Status;
440     }
441 
442     Status = LsaQueryInformationPolicy(PolicyHandle,
443                                        PolicyAccountDomainInformation,
444                                        (PVOID *)&OrigInfo);
445     if (!NT_SUCCESS(Status))
446     {
447         DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
448         goto done;
449     }
450 
451     Status = SamConnect(NULL,
452                         &ServerHandle,
453                         SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
454                         NULL);
455     if (!NT_SUCCESS(Status))
456     {
457         DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
458         goto done;
459     }
460 
461     Status = SamOpenDomain(ServerHandle,
462                            DOMAIN_LOOKUP,
463                            OrigInfo->DomainSid,
464                            &DomainHandle);
465     if (!NT_SUCCESS(Status))
466     {
467         DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
468         goto done;
469     }
470 
471     Status = SamOpenUser(DomainHandle,
472                          USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
473                          DOMAIN_USER_RID_ADMIN,
474                          &UserHandle);
475     if (!NT_SUCCESS(Status))
476     {
477         DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
478         goto done;
479     }
480 
481     RtlInitUnicodeString(&PasswordInfo.Password, Password);
482     PasswordInfo.PasswordExpired = FALSE;
483 
484     Status = SamSetInformationUser(UserHandle,
485                                    UserSetPasswordInformation,
486                                    (PVOID)&PasswordInfo);
487     if (!NT_SUCCESS(Status))
488     {
489         DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
490         goto done;
491     }
492 
493     Status = SamQueryInformationUser(UserHandle,
494                                      UserAccountNameInformation,
495                                      (PVOID*)&AccountNameInfo);
496     if (!NT_SUCCESS(Status))
497     {
498         DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
499         goto done;
500     }
501 
502     AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
503                                      HEAP_ZERO_MEMORY,
504                                      AccountNameInfo->UserName.Length + sizeof(WCHAR));
505     if (AdminInfo.Name != NULL)
506         RtlCopyMemory(AdminInfo.Name,
507                       AccountNameInfo->UserName.Buffer,
508                       AccountNameInfo->UserName.Length);
509 
510     AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
511                                        HEAP_ZERO_MEMORY,
512                                        OrigInfo->DomainName.Length + sizeof(WCHAR));
513     if (AdminInfo.Domain != NULL)
514         RtlCopyMemory(AdminInfo.Domain,
515                       OrigInfo->DomainName.Buffer,
516                       OrigInfo->DomainName.Length);
517 
518     AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
519                                          0,
520                                          (wcslen(Password) + 1) * sizeof(WCHAR));
521     if (AdminInfo.Password != NULL)
522         wcscpy(AdminInfo.Password, Password);
523 
524     DPRINT("Administrator Name: %S\n", AdminInfo.Name);
525     DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
526     DPRINT("Administrator Password: %S\n", AdminInfo.Password);
527 
528 done:
529     if (AccountNameInfo != NULL)
530         SamFreeMemory(AccountNameInfo);
531 
532     if (OrigInfo != NULL)
533         LsaFreeMemory(OrigInfo);
534 
535     if (PolicyHandle != NULL)
536         LsaClose(PolicyHandle);
537 
538     if (UserHandle != NULL)
539         SamCloseHandle(UserHandle);
540 
541     if (DomainHandle != NULL)
542         SamCloseHandle(DomainHandle);
543 
544     if (ServerHandle != NULL)
545         SamCloseHandle(ServerHandle);
546 
547     DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
548 
549     return Status;
550 }
551 
552 
553 VOID
554 SetAutoAdminLogon(VOID)
555 {
556     WCHAR szAutoAdminLogon[2];
557     HKEY hKey = NULL;
558     DWORD dwType;
559     DWORD dwSize;
560     LONG lError;
561 
562     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
563                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
564                            0,
565                            KEY_READ | KEY_WRITE,
566                            &hKey);
567     if (lError != ERROR_SUCCESS)
568         return;
569 
570     dwSize = 2 * sizeof(WCHAR);
571     lError = RegQueryValueExW(hKey,
572                               L"AutoAdminLogon",
573                               NULL,
574                               &dwType,
575                               (LPBYTE)szAutoAdminLogon,
576                               &dwSize);
577     if (lError != ERROR_SUCCESS)
578         goto done;
579 
580     if (wcscmp(szAutoAdminLogon, L"1") == 0)
581     {
582         RegSetValueExW(hKey,
583                        L"DefaultDomain",
584                        0,
585                        REG_SZ,
586                        (LPBYTE)AdminInfo.Domain,
587                        (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
588 
589         RegSetValueExW(hKey,
590                        L"DefaultUserName",
591                        0,
592                        REG_SZ,
593                        (LPBYTE)AdminInfo.Name,
594                        (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
595 
596         RegSetValueExW(hKey,
597                        L"DefaultPassword",
598                        0,
599                        REG_SZ,
600                        (LPBYTE)AdminInfo.Password,
601                        (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
602     }
603 
604 done:
605     if (hKey != NULL)
606         RegCloseKey(hKey);
607 }
608 
609 
610 /* EOF */
611 
612