e7bf1ddc2c0cc359f89cce60acc31271c7fb4464
[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 PUNICODE_STRING SidString)
57 {
58 PSID_AND_ATTRIBUTES SidBuffer, nsb;
59 ULONG Length;
60 NTSTATUS Status;
61
62 Length = 256;
63 SidBuffer = LocalAlloc(LMEM_FIXED,
64 Length);
65 if (SidBuffer == NULL)
66 return FALSE;
67
68 Status = NtQueryInformationToken(hToken,
69 TokenUser,
70 (PVOID)SidBuffer,
71 Length,
72 &Length);
73 if (Status == STATUS_BUFFER_TOO_SMALL)
74 {
75 nsb = LocalReAlloc(SidBuffer,
76 Length,
77 LMEM_MOVEABLE);
78 if (nsb == NULL)
79 {
80 LocalFree((HLOCAL)SidBuffer);
81 return FALSE;
82 }
83
84 SidBuffer = nsb;
85 Status = NtQueryInformationToken(hToken,
86 TokenUser,
87 (PVOID)SidBuffer,
88 Length,
89 &Length);
90 }
91
92 if (!NT_SUCCESS (Status))
93 {
94 LocalFree((HLOCAL)SidBuffer);
95 SetLastError(RtlNtStatusToDosError(Status));
96 return FALSE;
97 }
98
99 DPRINT("SidLength: %lu\n", RtlLengthSid (SidBuffer[0].Sid));
100
101 Status = RtlConvertSidToUnicodeString(SidString,
102 SidBuffer[0].Sid,
103 TRUE);
104
105 LocalFree((HLOCAL)SidBuffer);
106
107 if (!NT_SUCCESS(Status))
108 {
109 SetLastError(RtlNtStatusToDosError(Status));
110 return FALSE;
111 }
112
113 DPRINT("SidString.Length: %lu\n", SidString->Length);
114 DPRINT("SidString.MaximumLength: %lu\n", SidString->MaximumLength);
115 DPRINT("SidString: '%wZ'\n", SidString);
116
117 return TRUE;
118 }
119
120 PSECURITY_DESCRIPTOR
121 CreateDefaultSecurityDescriptor(VOID)
122 {
123 PSID LocalSystemSid = NULL;
124 PSID AdministratorsSid = NULL;
125 PSID EveryoneSid = NULL;
126 PACL Dacl;
127 DWORD DaclSize;
128 PSECURITY_DESCRIPTOR pSD = NULL;
129
130 /* create the SYSTEM, Administrators and Everyone SIDs */
131 if (!AllocateAndInitializeSid(&LocalSystemAuthority,
132 1,
133 SECURITY_LOCAL_SYSTEM_RID,
134 0,
135 0,
136 0,
137 0,
138 0,
139 0,
140 0,
141 &LocalSystemSid) ||
142 !AllocateAndInitializeSid(&LocalSystemAuthority,
143 2,
144 SECURITY_BUILTIN_DOMAIN_RID,
145 DOMAIN_ALIAS_RID_ADMINS,
146 0,
147 0,
148 0,
149 0,
150 0,
151 0,
152 &AdministratorsSid) ||
153 !AllocateAndInitializeSid(&WorldAuthority,
154 1,
155 SECURITY_WORLD_RID,
156 0,
157 0,
158 0,
159 0,
160 0,
161 0,
162 0,
163 &EveryoneSid))
164 {
165 DPRINT1("Failed initializing the SIDs for the default security descriptor (0x%p, 0x%p, 0x%p)\n",
166 LocalSystemSid, AdministratorsSid, EveryoneSid);
167 goto Cleanup;
168 }
169
170 /* allocate the security descriptor and DACL */
171 DaclSize = sizeof(ACL) +
172 ((GetLengthSid(LocalSystemSid) +
173 GetLengthSid(AdministratorsSid) +
174 GetLengthSid(EveryoneSid)) +
175 (3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE,
176 SidStart)));
177
178 pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED,
179 (SIZE_T)DaclSize + sizeof(SECURITY_DESCRIPTOR));
180 if (pSD == NULL)
181 {
182 DPRINT1("Failed to allocate the default security descriptor and ACL\n");
183 goto Cleanup;
184 }
185
186 if (!InitializeSecurityDescriptor(pSD,
187 SECURITY_DESCRIPTOR_REVISION))
188 {
189 DPRINT1("Failed to initialize the default security descriptor\n");
190 goto Cleanup;
191 }
192
193 /* initialize and build the DACL */
194 Dacl = (PACL)((ULONG_PTR)pSD + sizeof(SECURITY_DESCRIPTOR));
195 if (!InitializeAcl(Dacl,
196 (DWORD)DaclSize,
197 ACL_REVISION))
198 {
199 DPRINT1("Failed to initialize the DACL of the default security descriptor\n");
200 goto Cleanup;
201 }
202
203 /* add the SYSTEM Ace */
204 if (!AddAccessAllowedAce(Dacl,
205 ACL_REVISION,
206 GENERIC_ALL,
207 LocalSystemSid))
208 {
209 DPRINT1("Failed to add the SYSTEM ACE\n");
210 goto Cleanup;
211 }
212
213 /* add the Administrators Ace */
214 if (!AddAccessAllowedAce(Dacl,
215 ACL_REVISION,
216 GENERIC_ALL,
217 AdministratorsSid))
218 {
219 DPRINT1("Failed to add the Administrators ACE\n");
220 goto Cleanup;
221 }
222
223 /* add the Everyone Ace */
224 if (!AddAccessAllowedAce(Dacl,
225 ACL_REVISION,
226 GENERIC_EXECUTE,
227 EveryoneSid))
228 {
229 DPRINT1("Failed to add the Everyone ACE\n");
230 goto Cleanup;
231 }
232
233 /* set the DACL */
234 if (!SetSecurityDescriptorDacl(pSD,
235 TRUE,
236 Dacl,
237 FALSE))
238 {
239 DPRINT1("Failed to set the DACL of the default security descriptor\n");
240
241 Cleanup:
242 if (pSD != NULL)
243 {
244 LocalFree((HLOCAL)pSD);
245 pSD = NULL;
246 }
247 }
248
249 if (LocalSystemSid != NULL)
250 {
251 FreeSid(LocalSystemSid);
252 }
253 if (AdministratorsSid != NULL)
254 {
255 FreeSid(AdministratorsSid);
256 }
257 if (EveryoneSid != NULL)
258 {
259 FreeSid(EveryoneSid);
260 }
261
262 return pSD;
263 }
264
265 /* Dynamic DLL loading interface **********************************************/
266
267 /* OLE32.DLL import table */
268 DYN_MODULE DynOle32 =
269 {
270 L"ole32.dll",
271 {
272 "CoInitialize",
273 "CoCreateInstance",
274 "CoUninitialize",
275 NULL
276 }
277 };
278
279
280 /*
281 * Use this function to load functions from other modules. We cannot statically
282 * link to e.g. ole32.dll because those dlls would get loaded on startup with
283 * winlogon and they may try to register classes etc when not even a window station
284 * has been created!
285 */
286 BOOL
287 LoadDynamicImports(PDYN_MODULE Module,
288 PDYN_FUNCS DynFuncs)
289 {
290 LPSTR *fname;
291 PVOID *fn;
292
293 ZeroMemory(DynFuncs, sizeof(DYN_FUNCS));
294
295 DynFuncs->hModule = LoadLibraryW(Module->Library);
296 if (!DynFuncs->hModule)
297 {
298 return FALSE;
299 }
300
301 fn = &DynFuncs->fn.foo;
302
303 /* load the imports */
304 for (fname = Module->Functions; *fname != NULL; fname++)
305 {
306 *fn = GetProcAddress(DynFuncs->hModule, *fname);
307 if (*fn == NULL)
308 {
309 FreeLibrary(DynFuncs->hModule);
310 DynFuncs->hModule = (HMODULE)0;
311
312 return FALSE;
313 }
314
315 fn++;
316 }
317
318 return TRUE;
319 }
320
321
322 VOID
323 UnloadDynamicImports(PDYN_FUNCS DynFuncs)
324 {
325 if (DynFuncs->hModule)
326 {
327 FreeLibrary(DynFuncs->hModule);
328 DynFuncs->hModule = (HMODULE)0;
329 }
330 }
331
332 /* EOF */