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