[USERENV]
[reactos.git] / reactos / dll / win32 / userenv / misc.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * FILE: dll/win32/userenv/misc.c
23 * PURPOSE: User profile code
24 * PROGRAMMER: Eric Kohl
25 */
26
27 #include "precomp.h"
28
29 #define NDEBUG
30 #include <debug.h>
31
32 static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
33 static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
34
35 /* FUNCTIONS ***************************************************************/
36
37 LPWSTR
38 AppendBackslash(LPWSTR String)
39 {
40 ULONG Length;
41
42 Length = lstrlenW(String);
43 if (String[Length - 1] != L'\\')
44 {
45 String[Length] = L'\\';
46 Length++;
47 String[Length] = (WCHAR)0;
48 }
49
50 return &String[Length];
51 }
52
53
54 BOOL
55 GetUserSidFromToken(HANDLE hToken,
56 PSID *Sid)
57 {
58 PTOKEN_USER UserBuffer, nsb;
59 PSID pSid = NULL;
60 ULONG Length;
61 NTSTATUS Status;
62
63 Length = 256;
64 UserBuffer = LocalAlloc(LPTR, Length);
65 if (UserBuffer == NULL)
66 {
67 return FALSE;
68 }
69
70 Status = NtQueryInformationToken(hToken,
71 TokenUser,
72 (PVOID)UserBuffer,
73 Length,
74 &Length);
75 if (Status == STATUS_BUFFER_TOO_SMALL)
76 {
77 nsb = LocalReAlloc(UserBuffer, Length, LMEM_MOVEABLE);
78 if (nsb == NULL)
79 {
80 LocalFree(UserBuffer);
81 return FALSE;
82 }
83
84 UserBuffer = nsb;
85 Status = NtQueryInformationToken(hToken,
86 TokenUser,
87 (PVOID)UserBuffer,
88 Length,
89 &Length);
90 }
91
92 if (!NT_SUCCESS (Status))
93 {
94 LocalFree(UserBuffer);
95 return FALSE;
96 }
97
98 Length = RtlLengthSid(UserBuffer->User.Sid);
99
100 pSid = LocalAlloc(LPTR, Length);
101 if (pSid == NULL)
102 {
103 LocalFree(UserBuffer);
104 return FALSE;
105 }
106
107 Status = RtlCopySid(Length, pSid, UserBuffer->User.Sid);
108
109 LocalFree(UserBuffer);
110
111 if (!NT_SUCCESS (Status))
112 {
113 LocalFree(pSid);
114 return FALSE;
115 }
116
117 *Sid = pSid;
118
119 return TRUE;
120 }
121
122
123 BOOL
124 GetUserSidStringFromToken(HANDLE hToken,
125 PUNICODE_STRING SidString)
126 {
127 PTOKEN_USER UserBuffer, nsb;
128 ULONG Length;
129 NTSTATUS Status;
130
131 Length = 256;
132 UserBuffer = LocalAlloc(LPTR, Length);
133 if (UserBuffer == NULL)
134 return FALSE;
135
136 Status = NtQueryInformationToken(hToken,
137 TokenUser,
138 (PVOID)UserBuffer,
139 Length,
140 &Length);
141 if (Status == STATUS_BUFFER_TOO_SMALL)
142 {
143 nsb = LocalReAlloc(UserBuffer,
144 Length,
145 LMEM_MOVEABLE);
146 if (nsb == NULL)
147 {
148 LocalFree(UserBuffer);
149 return FALSE;
150 }
151
152 UserBuffer = nsb;
153 Status = NtQueryInformationToken(hToken,
154 TokenUser,
155 (PVOID)UserBuffer,
156 Length,
157 &Length);
158 }
159
160 if (!NT_SUCCESS (Status))
161 {
162 LocalFree(UserBuffer);
163 SetLastError(RtlNtStatusToDosError(Status));
164 return FALSE;
165 }
166
167 DPRINT("SidLength: %lu\n", RtlLengthSid (UserBuffer->User.Sid));
168
169 Status = RtlConvertSidToUnicodeString(SidString,
170 UserBuffer->User.Sid,
171 TRUE);
172
173 LocalFree(UserBuffer);
174
175 if (!NT_SUCCESS(Status))
176 {
177 SetLastError(RtlNtStatusToDosError(Status));
178 return FALSE;
179 }
180
181 DPRINT("SidString.Length: %lu\n", SidString->Length);
182 DPRINT("SidString.MaximumLength: %lu\n", SidString->MaximumLength);
183 DPRINT("SidString: '%wZ'\n", SidString);
184
185 return TRUE;
186 }
187
188
189 PSECURITY_DESCRIPTOR
190 CreateDefaultSecurityDescriptor(VOID)
191 {
192 PSID LocalSystemSid = NULL;
193 PSID AdministratorsSid = NULL;
194 PSID EveryoneSid = NULL;
195 PACL Dacl;
196 DWORD DaclSize;
197 PSECURITY_DESCRIPTOR pSD = NULL;
198
199 /* create the SYSTEM, Administrators and Everyone SIDs */
200 if (!AllocateAndInitializeSid(&LocalSystemAuthority,
201 1,
202 SECURITY_LOCAL_SYSTEM_RID,
203 0,
204 0,
205 0,
206 0,
207 0,
208 0,
209 0,
210 &LocalSystemSid) ||
211 !AllocateAndInitializeSid(&LocalSystemAuthority,
212 2,
213 SECURITY_BUILTIN_DOMAIN_RID,
214 DOMAIN_ALIAS_RID_ADMINS,
215 0,
216 0,
217 0,
218 0,
219 0,
220 0,
221 &AdministratorsSid) ||
222 !AllocateAndInitializeSid(&WorldAuthority,
223 1,
224 SECURITY_WORLD_RID,
225 0,
226 0,
227 0,
228 0,
229 0,
230 0,
231 0,
232 &EveryoneSid))
233 {
234 DPRINT1("Failed initializing the SIDs for the default security descriptor (0x%p, 0x%p, 0x%p)\n",
235 LocalSystemSid, AdministratorsSid, EveryoneSid);
236 goto Cleanup;
237 }
238
239 /* allocate the security descriptor and DACL */
240 DaclSize = sizeof(ACL) +
241 ((GetLengthSid(LocalSystemSid) +
242 GetLengthSid(AdministratorsSid) +
243 GetLengthSid(EveryoneSid)) +
244 (3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE,
245 SidStart)));
246
247 pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED,
248 (SIZE_T)DaclSize + sizeof(SECURITY_DESCRIPTOR));
249 if (pSD == NULL)
250 {
251 DPRINT1("Failed to allocate the default security descriptor and ACL\n");
252 goto Cleanup;
253 }
254
255 if (!InitializeSecurityDescriptor(pSD,
256 SECURITY_DESCRIPTOR_REVISION))
257 {
258 DPRINT1("Failed to initialize the default security descriptor\n");
259 goto Cleanup;
260 }
261
262 /* initialize and build the DACL */
263 Dacl = (PACL)((ULONG_PTR)pSD + sizeof(SECURITY_DESCRIPTOR));
264 if (!InitializeAcl(Dacl,
265 (DWORD)DaclSize,
266 ACL_REVISION))
267 {
268 DPRINT1("Failed to initialize the DACL of the default security descriptor\n");
269 goto Cleanup;
270 }
271
272 /* add the SYSTEM Ace */
273 if (!AddAccessAllowedAce(Dacl,
274 ACL_REVISION,
275 GENERIC_ALL,
276 LocalSystemSid))
277 {
278 DPRINT1("Failed to add the SYSTEM ACE\n");
279 goto Cleanup;
280 }
281
282 /* add the Administrators Ace */
283 if (!AddAccessAllowedAce(Dacl,
284 ACL_REVISION,
285 GENERIC_ALL,
286 AdministratorsSid))
287 {
288 DPRINT1("Failed to add the Administrators ACE\n");
289 goto Cleanup;
290 }
291
292 /* add the Everyone Ace */
293 if (!AddAccessAllowedAce(Dacl,
294 ACL_REVISION,
295 GENERIC_EXECUTE,
296 EveryoneSid))
297 {
298 DPRINT1("Failed to add the Everyone ACE\n");
299 goto Cleanup;
300 }
301
302 /* set the DACL */
303 if (!SetSecurityDescriptorDacl(pSD,
304 TRUE,
305 Dacl,
306 FALSE))
307 {
308 DPRINT1("Failed to set the DACL of the default security descriptor\n");
309
310 Cleanup:
311 if (pSD != NULL)
312 {
313 LocalFree((HLOCAL)pSD);
314 pSD = NULL;
315 }
316 }
317
318 if (LocalSystemSid != NULL)
319 {
320 FreeSid(LocalSystemSid);
321 }
322 if (AdministratorsSid != NULL)
323 {
324 FreeSid(AdministratorsSid);
325 }
326 if (EveryoneSid != NULL)
327 {
328 FreeSid(EveryoneSid);
329 }
330
331 return pSD;
332 }
333
334 /* Dynamic DLL loading interface **********************************************/
335
336 /* OLE32.DLL import table */
337 DYN_MODULE DynOle32 =
338 {
339 L"ole32.dll",
340 {
341 "CoInitialize",
342 "CoCreateInstance",
343 "CoUninitialize",
344 NULL
345 }
346 };
347
348
349 /*
350 * Use this function to load functions from other modules. We cannot statically
351 * link to e.g. ole32.dll because those dlls would get loaded on startup with
352 * winlogon and they may try to register classes etc when not even a window station
353 * has been created!
354 */
355 BOOL
356 LoadDynamicImports(PDYN_MODULE Module,
357 PDYN_FUNCS DynFuncs)
358 {
359 LPSTR *fname;
360 PVOID *fn;
361
362 ZeroMemory(DynFuncs, sizeof(DYN_FUNCS));
363
364 DynFuncs->hModule = LoadLibraryW(Module->Library);
365 if (!DynFuncs->hModule)
366 {
367 return FALSE;
368 }
369
370 fn = &DynFuncs->fn.foo;
371
372 /* load the imports */
373 for (fname = Module->Functions; *fname != NULL; fname++)
374 {
375 *fn = GetProcAddress(DynFuncs->hModule, *fname);
376 if (*fn == NULL)
377 {
378 FreeLibrary(DynFuncs->hModule);
379 DynFuncs->hModule = (HMODULE)0;
380
381 return FALSE;
382 }
383
384 fn++;
385 }
386
387 return TRUE;
388 }
389
390
391 VOID
392 UnloadDynamicImports(PDYN_FUNCS DynFuncs)
393 {
394 if (DynFuncs->hModule)
395 {
396 FreeLibrary(DynFuncs->hModule);
397 DynFuncs->hModule = (HMODULE)0;
398 }
399 }
400
401 /* EOF */