[SYSSETUP]
[reactos.git] / reactos / dll / win32 / syssetup / security.c
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 SetAccountDomain(LPCWSTR DomainName,
25 PSID DomainSid)
26 {
27 PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
28 POLICY_ACCOUNT_DOMAIN_INFO Info;
29 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
30 LSA_HANDLE PolicyHandle;
31
32 SAM_HANDLE ServerHandle = NULL;
33 SAM_HANDLE DomainHandle = NULL;
34 DOMAIN_NAME_INFORMATION DomainNameInfo;
35
36 NTSTATUS Status;
37
38 DPRINT("SYSSETUP: SetAccountDomain\n");
39
40 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
41 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
42
43 Status = LsaOpenPolicy(NULL,
44 &ObjectAttributes,
45 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
46 &PolicyHandle);
47 if (Status != STATUS_SUCCESS)
48 {
49 DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
50 return Status;
51 }
52
53 Status = LsaQueryInformationPolicy(PolicyHandle,
54 PolicyAccountDomainInformation,
55 (PVOID *)&OrigInfo);
56 if (Status == STATUS_SUCCESS && OrigInfo != NULL)
57 {
58 if (DomainName == NULL)
59 {
60 Info.DomainName.Buffer = OrigInfo->DomainName.Buffer;
61 Info.DomainName.Length = OrigInfo->DomainName.Length;
62 Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength;
63 }
64 else
65 {
66 Info.DomainName.Buffer = (LPWSTR)DomainName;
67 Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
68 Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
69 }
70
71 if (DomainSid == NULL)
72 Info.DomainSid = OrigInfo->DomainSid;
73 else
74 Info.DomainSid = DomainSid;
75 }
76 else
77 {
78 Info.DomainName.Buffer = (LPWSTR)DomainName;
79 Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
80 Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
81 Info.DomainSid = DomainSid;
82 }
83
84 Status = LsaSetInformationPolicy(PolicyHandle,
85 PolicyAccountDomainInformation,
86 (PVOID)&Info);
87 if (Status != STATUS_SUCCESS)
88 {
89 DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
90 }
91
92 if (OrigInfo != NULL)
93 LsaFreeMemory(OrigInfo);
94
95 LsaClose(PolicyHandle);
96
97 DomainNameInfo.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
98 DomainNameInfo.DomainName.MaximumLength = (wcslen(DomainName) + 1) * sizeof(WCHAR);
99 DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName;
100
101 Status = SamConnect(NULL,
102 &ServerHandle,
103 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
104 NULL);
105 if (NT_SUCCESS(Status))
106 {
107 Status = SamOpenDomain(ServerHandle,
108 DOMAIN_WRITE_OTHER_PARAMETERS,
109 Info.DomainSid,
110 &DomainHandle);
111 if (NT_SUCCESS(Status))
112 {
113 Status = SamSetInformationDomain(DomainHandle,
114 DomainNameInformation,
115 (PVOID)&DomainNameInfo);
116 if (!NT_SUCCESS(Status))
117 {
118 DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status);
119 }
120
121 SamCloseHandle(DomainHandle);
122 }
123 else
124 {
125 DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status);
126 }
127
128 SamCloseHandle(ServerHandle);
129 }
130
131 return Status;
132 }
133
134
135 /* Hack */
136 static
137 NTSTATUS
138 SetPrimaryDomain(LPCWSTR DomainName,
139 PSID DomainSid)
140 {
141 PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL;
142 POLICY_PRIMARY_DOMAIN_INFO Info;
143 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
144 LSA_HANDLE PolicyHandle;
145 NTSTATUS Status;
146
147 DPRINT1("SYSSETUP: SetPrimaryDomain()\n");
148
149 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
150 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
151
152 Status = LsaOpenPolicy(NULL,
153 &ObjectAttributes,
154 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
155 &PolicyHandle);
156 if (Status != STATUS_SUCCESS)
157 {
158 DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
159 return Status;
160 }
161
162 Status = LsaQueryInformationPolicy(PolicyHandle,
163 PolicyPrimaryDomainInformation,
164 (PVOID *)&OrigInfo);
165 if (Status == STATUS_SUCCESS && OrigInfo != NULL)
166 {
167 if (DomainName == NULL)
168 {
169 Info.Name.Buffer = OrigInfo->Name.Buffer;
170 Info.Name.Length = OrigInfo->Name.Length;
171 Info.Name.MaximumLength = OrigInfo->Name.MaximumLength;
172 }
173 else
174 {
175 Info.Name.Buffer = (LPWSTR)DomainName;
176 Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR);
177 Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
178 }
179
180 if (DomainSid == NULL)
181 Info.Sid = OrigInfo->Sid;
182 else
183 Info.Sid = DomainSid;
184 }
185 else
186 {
187 Info.Name.Buffer = (LPWSTR)DomainName;
188 Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR);
189 Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
190 Info.Sid = DomainSid;
191 }
192
193 Status = LsaSetInformationPolicy(PolicyHandle,
194 PolicyPrimaryDomainInformation,
195 (PVOID)&Info);
196 if (Status != STATUS_SUCCESS)
197 {
198 DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
199 }
200
201 if (OrigInfo != NULL)
202 LsaFreeMemory(OrigInfo);
203
204 LsaClose(PolicyHandle);
205
206 return Status;
207 }
208
209
210 static
211 VOID
212 InstallBuiltinAccounts(VOID)
213 {
214 LPWSTR BuiltinAccounts[] = {
215 L"S-1-1-0", /* Everyone */
216 L"S-1-5-4", /* Interactive */
217 L"S-1-5-6", /* Service */
218 L"S-1-5-19", /* Local Service */
219 L"S-1-5-20", /* Network Service */
220 L"S-1-5-32-544", /* Administrators */
221 L"S-1-5-32-545", /* Users */
222 L"S-1-5-32-547", /* Power Users */
223 L"S-1-5-32-551", /* Backup Operators */
224 L"S-1-5-32-555"}; /* Remote Desktop Users */
225 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
226 NTSTATUS Status;
227 LSA_HANDLE PolicyHandle = NULL;
228 LSA_HANDLE AccountHandle = NULL;
229 PSID AccountSid;
230 ULONG i;
231
232 DPRINT("InstallBuiltinAccounts()\n");
233
234 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
235
236 Status = LsaOpenPolicy(NULL,
237 &ObjectAttributes,
238 POLICY_CREATE_ACCOUNT,
239 &PolicyHandle);
240 if (!NT_SUCCESS(Status))
241 {
242 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
243 return;
244 }
245
246 for (i = 0; i < 10; i++)
247 {
248 if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid))
249 {
250 DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError());
251 continue;
252 }
253
254 Status = LsaCreateAccount(PolicyHandle,
255 AccountSid,
256 0,
257 &AccountHandle);
258 if (NT_SUCCESS(Status))
259 {
260 LsaClose(AccountHandle);
261 }
262
263 LocalFree(AccountSid);
264 }
265
266 LsaClose(PolicyHandle);
267 }
268
269
270 static
271 VOID
272 InstallPrivileges(VOID)
273 {
274 HINF hSecurityInf = INVALID_HANDLE_VALUE;
275 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
276 WCHAR szPrivilegeString[256];
277 WCHAR szSidString[256];
278 INFCONTEXT InfContext;
279 DWORD i;
280 PRIVILEGE_SET PrivilegeSet;
281 PSID AccountSid;
282 NTSTATUS Status;
283 LSA_HANDLE PolicyHandle = NULL;
284 LSA_HANDLE AccountHandle;
285
286 DPRINT("InstallPrivileges()\n");
287
288 hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer,
289 NULL,
290 INF_STYLE_WIN4,
291 NULL);
292 if (hSecurityInf == INVALID_HANDLE_VALUE)
293 {
294 DPRINT1("SetupOpenInfFileW failed\n");
295 return;
296 }
297
298 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
299
300 Status = LsaOpenPolicy(NULL,
301 &ObjectAttributes,
302 POLICY_CREATE_ACCOUNT,
303 &PolicyHandle);
304 if (!NT_SUCCESS(Status))
305 {
306 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
307 goto done;
308 }
309
310 if (!SetupFindFirstLineW(hSecurityInf,
311 L"Privilege Rights",
312 NULL,
313 &InfContext))
314 {
315 DPRINT1("SetupFindfirstLineW failed\n");
316 goto done;
317 }
318
319 PrivilegeSet.PrivilegeCount = 1;
320 PrivilegeSet.Control = 0;
321
322 do
323 {
324 /* Retrieve the privilege name */
325 if (!SetupGetStringFieldW(&InfContext,
326 0,
327 szPrivilegeString,
328 256,
329 NULL))
330 {
331 DPRINT1("SetupGetStringFieldW() failed\n");
332 goto done;
333 }
334 DPRINT("Privilege: %S\n", szPrivilegeString);
335
336 if (!LookupPrivilegeValueW(NULL,
337 szPrivilegeString,
338 &(PrivilegeSet.Privilege[0].Luid)))
339 {
340 DPRINT1("LookupPrivilegeNameW() failed\n");
341 goto done;
342 }
343
344 PrivilegeSet.Privilege[0].Attributes = 0;
345
346 for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
347 {
348 if (!SetupGetStringFieldW(&InfContext,
349 i + 1,
350 szSidString,
351 256,
352 NULL))
353 {
354 DPRINT1("SetupGetStringFieldW() failed\n");
355 goto done;
356 }
357 DPRINT("SID: %S\n", szSidString);
358
359 if (!ConvertStringSidToSid(szSidString, &AccountSid))
360 {
361 DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError());
362 continue;
363 }
364
365 Status = LsaOpenAccount(PolicyHandle,
366 AccountSid,
367 ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES,
368 &AccountHandle);
369 if (NT_SUCCESS(Status))
370 {
371 Status = LsaAddPrivilegesToAccount(AccountHandle,
372 &PrivilegeSet);
373 if (!NT_SUCCESS(Status))
374 {
375 DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status);
376 }
377
378 LsaClose(AccountHandle);
379 }
380
381 LocalFree(AccountSid);
382 }
383
384 }
385 while (SetupFindNextLine(&InfContext, &InfContext));
386
387 done:
388 if (PolicyHandle != NULL)
389 LsaClose(PolicyHandle);
390
391 if (hSecurityInf != INVALID_HANDLE_VALUE)
392 SetupCloseInfFile(hSecurityInf);
393 }
394
395
396 VOID
397 InstallSecurity(VOID)
398 {
399 InstallBuiltinAccounts();
400 InstallPrivileges();
401
402 /* Hack */
403 SetPrimaryDomain(L"WORKGROUP", NULL);
404 }
405
406
407 NTSTATUS
408 SetAdministratorPassword(LPCWSTR Password)
409 {
410 PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
411 PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
412 USER_SET_PASSWORD_INFORMATION PasswordInfo;
413 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
414 LSA_HANDLE PolicyHandle = NULL;
415 SAM_HANDLE ServerHandle = NULL;
416 SAM_HANDLE DomainHandle = NULL;
417 SAM_HANDLE UserHandle = NULL;
418 NTSTATUS Status;
419
420 DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
421
422 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
423 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
424
425 Status = LsaOpenPolicy(NULL,
426 &ObjectAttributes,
427 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
428 &PolicyHandle);
429 if (Status != STATUS_SUCCESS)
430 {
431 DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
432 return Status;
433 }
434
435 Status = LsaQueryInformationPolicy(PolicyHandle,
436 PolicyAccountDomainInformation,
437 (PVOID *)&OrigInfo);
438 if (!NT_SUCCESS(Status))
439 {
440 DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
441 goto done;
442 }
443
444 Status = SamConnect(NULL,
445 &ServerHandle,
446 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
447 NULL);
448 if (!NT_SUCCESS(Status))
449 {
450 DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
451 goto done;
452 }
453
454 Status = SamOpenDomain(ServerHandle,
455 DOMAIN_LOOKUP,
456 OrigInfo->DomainSid,
457 &DomainHandle);
458 if (!NT_SUCCESS(Status))
459 {
460 DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
461 goto done;
462 }
463
464 Status = SamOpenUser(DomainHandle,
465 USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
466 DOMAIN_USER_RID_ADMIN,
467 &UserHandle);
468 if (!NT_SUCCESS(Status))
469 {
470 DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
471 goto done;
472 }
473
474 RtlInitUnicodeString(&PasswordInfo.Password, Password);
475 PasswordInfo.PasswordExpired = FALSE;
476
477 Status = SamSetInformationUser(UserHandle,
478 UserSetPasswordInformation,
479 (PVOID)&PasswordInfo);
480 if (!NT_SUCCESS(Status))
481 {
482 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
483 goto done;
484 }
485
486 Status = SamQueryInformationUser(UserHandle,
487 UserAccountNameInformation,
488 (PVOID*)&AccountNameInfo);
489 if (!NT_SUCCESS(Status))
490 {
491 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
492 goto done;
493 }
494
495 AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
496 HEAP_ZERO_MEMORY,
497 AccountNameInfo->UserName.Length + sizeof(WCHAR));
498 if (AdminInfo.Name != NULL)
499 RtlCopyMemory(AdminInfo.Name,
500 AccountNameInfo->UserName.Buffer,
501 AccountNameInfo->UserName.Length);
502
503 AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
504 HEAP_ZERO_MEMORY,
505 OrigInfo->DomainName.Length + sizeof(WCHAR));
506 if (AdminInfo.Domain != NULL)
507 RtlCopyMemory(AdminInfo.Domain,
508 OrigInfo->DomainName.Buffer,
509 OrigInfo->DomainName.Length);
510
511 AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
512 0,
513 (wcslen(Password) + 1) * sizeof(WCHAR));
514 if (AdminInfo.Password != NULL)
515 wcscpy(AdminInfo.Password, Password);
516
517 DPRINT("Administrator Name: %S\n", AdminInfo.Name);
518 DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
519 DPRINT("Administrator Password: %S\n", AdminInfo.Password);
520
521 done:
522 if (AccountNameInfo != NULL)
523 SamFreeMemory(AccountNameInfo);
524
525 if (OrigInfo != NULL)
526 LsaFreeMemory(OrigInfo);
527
528 if (PolicyHandle != NULL)
529 LsaClose(PolicyHandle);
530
531 if (UserHandle != NULL)
532 SamCloseHandle(UserHandle);
533
534 if (DomainHandle != NULL)
535 SamCloseHandle(DomainHandle);
536
537 if (ServerHandle != NULL)
538 SamCloseHandle(ServerHandle);
539
540 DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
541
542 return Status;
543 }
544
545
546 VOID
547 SetAutoAdminLogon(VOID)
548 {
549 WCHAR szAutoAdminLogon[2];
550 HKEY hKey = NULL;
551 DWORD dwType;
552 DWORD dwSize;
553 LONG lError;
554
555 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
556 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
557 0,
558 KEY_READ | KEY_WRITE,
559 &hKey);
560 if (lError != ERROR_SUCCESS)
561 return;
562
563 dwSize = 2 * sizeof(WCHAR);
564 lError = RegQueryValueExW(hKey,
565 L"AutoAdminLogon",
566 NULL,
567 &dwType,
568 (LPBYTE)szAutoAdminLogon,
569 &dwSize);
570 if (lError != ERROR_SUCCESS)
571 goto done;
572
573 if (wcscmp(szAutoAdminLogon, L"1") == 0)
574 {
575 RegSetValueExW(hKey,
576 L"DefaultDomain",
577 0,
578 REG_SZ,
579 (LPBYTE)AdminInfo.Domain,
580 (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
581
582 RegSetValueExW(hKey,
583 L"DefaultUserName",
584 0,
585 REG_SZ,
586 (LPBYTE)AdminInfo.Name,
587 (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
588
589 RegSetValueExW(hKey,
590 L"DefaultPassword",
591 0,
592 REG_SZ,
593 (LPBYTE)AdminInfo.Password,
594 (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
595 }
596
597 done:
598 if (hKey != NULL)
599 RegCloseKey(hKey);
600 }
601
602
603 /* EOF */
604