2f866f4d131f91a64a6d58153e8800d6aa8920e7
[reactos.git] / 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 DPRINT1("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 static
136 VOID
137 InstallBuiltinAccounts(VOID)
138 {
139 LPWSTR BuiltinAccounts[] = {
140 L"S-1-1-0", /* Everyone */
141 L"S-1-5-4", /* Interactive */
142 L"S-1-5-6", /* Service */
143 L"S-1-5-19", /* Local Service */
144 L"S-1-5-20", /* Network Service */
145 L"S-1-5-32-544", /* Administrators */
146 L"S-1-5-32-545", /* Users */
147 L"S-1-5-32-547", /* Power Users */
148 L"S-1-5-32-551", /* Backup Operators */
149 L"S-1-5-32-555"}; /* Remote Desktop Users */
150 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
151 NTSTATUS Status;
152 LSA_HANDLE PolicyHandle = NULL;
153 LSA_HANDLE AccountHandle = NULL;
154 PSID AccountSid;
155 ULONG i;
156
157 DPRINT("InstallBuiltinAccounts()\n");
158
159 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
160
161 Status = LsaOpenPolicy(NULL,
162 &ObjectAttributes,
163 POLICY_CREATE_ACCOUNT,
164 &PolicyHandle);
165 if (!NT_SUCCESS(Status))
166 {
167 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
168 return;
169 }
170
171 for (i = 0; i < 10; i++)
172 {
173 ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid);
174
175 Status = LsaCreateAccount(PolicyHandle,
176 AccountSid,
177 0,
178 &AccountHandle);
179 if (NT_SUCCESS(Status))
180 {
181 LsaClose(AccountHandle);
182 }
183
184 LocalFree(AccountSid);
185 }
186
187 LsaClose(PolicyHandle);
188 }
189
190
191 static
192 VOID
193 InstallPrivileges(VOID)
194 {
195 HINF hSecurityInf = INVALID_HANDLE_VALUE;
196 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
197 WCHAR szPrivilegeString[256];
198 WCHAR szSidString[256];
199 INFCONTEXT InfContext;
200 DWORD i;
201 PRIVILEGE_SET PrivilegeSet;
202 PSID AccountSid;
203 NTSTATUS Status;
204 LSA_HANDLE PolicyHandle = NULL;
205 LSA_HANDLE AccountHandle;
206
207 DPRINT("InstallPrivileges()\n");
208
209 hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer,
210 NULL,
211 INF_STYLE_WIN4,
212 NULL);
213 if (hSecurityInf == INVALID_HANDLE_VALUE)
214 {
215 DPRINT1("SetupOpenInfFileW failed\n");
216 return;
217 }
218
219 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
220
221 Status = LsaOpenPolicy(NULL,
222 &ObjectAttributes,
223 POLICY_CREATE_ACCOUNT,
224 &PolicyHandle);
225 if (!NT_SUCCESS(Status))
226 {
227 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
228 goto done;
229 }
230
231 if (!SetupFindFirstLineW(hSecurityInf,
232 L"Privilege Rights",
233 NULL,
234 &InfContext))
235 {
236 DPRINT1("SetupFindfirstLineW failed\n");
237 goto done;
238 }
239
240 PrivilegeSet.PrivilegeCount = 1;
241 PrivilegeSet.Control = 0;
242
243 do
244 {
245 /* Retrieve the privilege name */
246 if (!SetupGetStringFieldW(&InfContext,
247 0,
248 szPrivilegeString,
249 256,
250 NULL))
251 {
252 DPRINT1("SetupGetStringFieldW() failed\n");
253 goto done;
254 }
255 DPRINT("Privilege: %S\n", szPrivilegeString);
256
257 if (!LookupPrivilegeValueW(NULL,
258 szPrivilegeString,
259 &(PrivilegeSet.Privilege[0].Luid)))
260 {
261 DPRINT1("LookupPrivilegeNameW() failed\n");
262 goto done;
263 }
264
265 PrivilegeSet.Privilege[0].Attributes = 0;
266
267 for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
268 {
269 if (!SetupGetStringFieldW(&InfContext,
270 i + 1,
271 szSidString,
272 256,
273 NULL))
274 {
275 DPRINT1("SetupGetStringFieldW() failed\n");
276 goto done;
277 }
278 DPRINT("SID: %S\n", szSidString);
279
280 ConvertStringSidToSid(szSidString, &AccountSid);
281
282 Status = LsaOpenAccount(PolicyHandle,
283 AccountSid,
284 ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES,
285 &AccountHandle);
286 if (NT_SUCCESS(Status))
287 {
288 Status = LsaAddPrivilegesToAccount(AccountHandle,
289 &PrivilegeSet);
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status);
293 }
294
295 LsaClose(AccountHandle);
296 }
297
298 LocalFree(AccountSid);
299 }
300
301 }
302 while (SetupFindNextLine(&InfContext, &InfContext));
303
304 done:
305 if (PolicyHandle != NULL)
306 LsaClose(PolicyHandle);
307
308 if (hSecurityInf != INVALID_HANDLE_VALUE)
309 SetupCloseInfFile(hSecurityInf);
310 }
311
312 VOID
313 InstallSecurity(VOID)
314 {
315 InstallBuiltinAccounts();
316 InstallPrivileges();
317 }
318
319
320 NTSTATUS
321 SetAdministratorPassword(LPCWSTR Password)
322 {
323 PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
324 PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
325 USER_SET_PASSWORD_INFORMATION PasswordInfo;
326 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
327 LSA_HANDLE PolicyHandle = NULL;
328 SAM_HANDLE ServerHandle = NULL;
329 SAM_HANDLE DomainHandle = NULL;
330 SAM_HANDLE UserHandle = NULL;
331 NTSTATUS Status;
332
333 DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
334
335 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
336 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
337
338 Status = LsaOpenPolicy(NULL,
339 &ObjectAttributes,
340 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
341 &PolicyHandle);
342 if (Status != STATUS_SUCCESS)
343 {
344 DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
345 return Status;
346 }
347
348 Status = LsaQueryInformationPolicy(PolicyHandle,
349 PolicyAccountDomainInformation,
350 (PVOID *)&OrigInfo);
351 if (!NT_SUCCESS(Status))
352 {
353 DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
354 goto done;
355 }
356
357 Status = SamConnect(NULL,
358 &ServerHandle,
359 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
360 NULL);
361 if (!NT_SUCCESS(Status))
362 {
363 DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
364 goto done;
365 }
366
367 Status = SamOpenDomain(ServerHandle,
368 DOMAIN_LOOKUP,
369 OrigInfo->DomainSid,
370 &DomainHandle);
371 if (!NT_SUCCESS(Status))
372 {
373 DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
374 goto done;
375 }
376
377 Status = SamOpenUser(DomainHandle,
378 USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
379 DOMAIN_USER_RID_ADMIN,
380 &UserHandle);
381 if (!NT_SUCCESS(Status))
382 {
383 DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
384 goto done;
385 }
386
387 RtlInitUnicodeString(&PasswordInfo.Password, Password);
388 PasswordInfo.PasswordExpired = FALSE;
389
390 Status = SamSetInformationUser(UserHandle,
391 UserSetPasswordInformation,
392 (PVOID)&PasswordInfo);
393 if (!NT_SUCCESS(Status))
394 {
395 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
396 goto done;
397 }
398
399 Status = SamQueryInformationUser(UserHandle,
400 UserAccountNameInformation,
401 (PVOID*)&AccountNameInfo);
402 if (!NT_SUCCESS(Status))
403 {
404 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
405 goto done;
406 }
407
408 AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
409 HEAP_ZERO_MEMORY,
410 AccountNameInfo->UserName.Length + sizeof(WCHAR));
411 if (AdminInfo.Name != NULL)
412 RtlCopyMemory(AdminInfo.Name,
413 AccountNameInfo->UserName.Buffer,
414 AccountNameInfo->UserName.Length);
415
416 AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
417 HEAP_ZERO_MEMORY,
418 OrigInfo->DomainName.Length + sizeof(WCHAR));
419 if (AdminInfo.Domain != NULL)
420 RtlCopyMemory(AdminInfo.Domain,
421 OrigInfo->DomainName.Buffer,
422 OrigInfo->DomainName.Length);
423
424 AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
425 0,
426 (wcslen(Password) + 1) * sizeof(WCHAR));
427 if (AdminInfo.Password != NULL)
428 wcscpy(AdminInfo.Password, Password);
429
430 DPRINT("Administrator Name: %S\n", AdminInfo.Name);
431 DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
432 DPRINT("Administrator Password: %S\n", AdminInfo.Password);
433
434 done:
435 if (AccountNameInfo != NULL)
436 SamFreeMemory(AccountNameInfo);
437
438 if (OrigInfo != NULL)
439 LsaFreeMemory(OrigInfo);
440
441 if (PolicyHandle != NULL)
442 LsaClose(PolicyHandle);
443
444 if (UserHandle != NULL)
445 SamCloseHandle(UserHandle);
446
447 if (DomainHandle != NULL)
448 SamCloseHandle(DomainHandle);
449
450 if (ServerHandle != NULL)
451 SamCloseHandle(ServerHandle);
452
453 DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
454
455 return Status;
456 }
457
458
459 VOID
460 SetAutoAdminLogon(VOID)
461 {
462 WCHAR szAutoAdminLogon[2];
463 HKEY hKey = NULL;
464 DWORD dwType;
465 DWORD dwSize;
466 LONG lError;
467
468 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
469 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
470 0,
471 KEY_READ | KEY_WRITE,
472 &hKey);
473 if (lError != ERROR_SUCCESS)
474 return;
475
476 dwSize = 2 * sizeof(WCHAR);
477 lError = RegQueryValueExW(hKey,
478 L"AutoAdminLogon",
479 NULL,
480 &dwType,
481 (LPBYTE)szAutoAdminLogon,
482 &dwSize);
483 if (lError != ERROR_SUCCESS)
484 goto done;
485
486 if (wcscmp(szAutoAdminLogon, L"1") == 0)
487 {
488 RegSetValueExW(hKey,
489 L"DefaultDomain",
490 0,
491 REG_SZ,
492 (LPBYTE)AdminInfo.Domain,
493 (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
494
495 RegSetValueExW(hKey,
496 L"DefaultUserName",
497 0,
498 REG_SZ,
499 (LPBYTE)AdminInfo.Name,
500 (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
501
502 RegSetValueExW(hKey,
503 L"DefaultPassword",
504 0,
505 REG_SZ,
506 (LPBYTE)AdminInfo.Password,
507 (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
508 }
509
510 done:
511 if (hKey != NULL)
512 RegCloseKey(hKey);
513 }
514
515
516 /* EOF */
517