Make use of Set/QuerySecurityAccessMask
[reactos.git] / reactos / dll / win32 / ntmarta / ntmarta.c
1 /*
2 * ReactOS MARTA provider
3 * Copyright (C) 2005 - 2006 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS MARTA provider
22 * FILE: lib/ntmarta/ntmarta.c
23 * PURPOSE: ReactOS MARTA provider
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 *
26 * UPDATE HISTORY:
27 * 07/26/2005 Created
28 */
29 #include <ntmarta.h>
30
31 #define NDEBUG
32 #include <debug.h>
33
34 HINSTANCE hDllInstance;
35
36 static ACCESS_MODE
37 AccpGetAceAccessMode(IN PACE_HEADER AceHeader)
38 {
39 ACCESS_MODE Mode = NOT_USED_ACCESS;
40
41 switch (AceHeader->AceType)
42 {
43 case ACCESS_ALLOWED_ACE_TYPE:
44 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
45 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
46 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
47 Mode = GRANT_ACCESS;
48 break;
49
50 case ACCESS_DENIED_ACE_TYPE:
51 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
52 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
53 case ACCESS_DENIED_OBJECT_ACE_TYPE:
54 Mode = DENY_ACCESS;
55 break;
56
57 case SYSTEM_AUDIT_ACE_TYPE:
58 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
59 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
60 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
61 if (AceHeader->AceFlags & FAILED_ACCESS_ACE_FLAG)
62 Mode = SET_AUDIT_FAILURE;
63 else if (AceHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
64 Mode = SET_AUDIT_SUCCESS;
65 break;
66 }
67
68 return Mode;
69 }
70
71 static UINT
72 AccpGetAceStructureSize(IN PACE_HEADER AceHeader)
73 {
74 UINT Size = 0;
75
76 switch (AceHeader->AceType)
77 {
78 case ACCESS_ALLOWED_ACE_TYPE:
79 case ACCESS_DENIED_ACE_TYPE:
80 Size = FIELD_OFFSET(ACCESS_ALLOWED_ACE,
81 SidStart);
82 break;
83 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
84 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
85 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE,
86 SidStart);
87 break;
88 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
89 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
90 {
91 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
92 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE,
93 ObjectType);
94 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
95 Size += sizeof(Ace->ObjectType);
96 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
97 Size += sizeof(Ace->InheritedObjectType);
98 break;
99 }
100 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
101 case ACCESS_DENIED_OBJECT_ACE_TYPE:
102 {
103 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
104 Size = FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE,
105 ObjectType);
106 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
107 Size += sizeof(Ace->ObjectType);
108 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
109 Size += sizeof(Ace->InheritedObjectType);
110 break;
111 }
112
113 case SYSTEM_AUDIT_ACE_TYPE:
114 Size = FIELD_OFFSET(SYSTEM_AUDIT_ACE,
115 SidStart);
116 break;
117 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
118 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE,
119 SidStart);
120 break;
121 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
122 {
123 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
124 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE,
125 ObjectType);
126 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
127 Size += sizeof(Ace->ObjectType);
128 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
129 Size += sizeof(Ace->InheritedObjectType);
130 break;
131 }
132 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
133 {
134 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
135 Size = FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE,
136 ObjectType);
137 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
138 Size += sizeof(Ace->ObjectType);
139 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
140 Size += sizeof(Ace->InheritedObjectType);
141 break;
142 }
143 }
144
145 return Size;
146 }
147
148 static PSID
149 AccpGetAceSid(IN PACE_HEADER AceHeader)
150 {
151 return (PSID)((ULONG_PTR)AceHeader + AccpGetAceStructureSize(AceHeader));
152 }
153
154 static ACCESS_MASK
155 AccpGetAceAccessMask(IN PACE_HEADER AceHeader)
156 {
157 return *((PACCESS_MASK)(AceHeader + 1));
158 }
159
160 static BOOL
161 AccpIsObjectAce(IN PACE_HEADER AceHeader)
162 {
163 BOOL Ret;
164
165 switch (AceHeader->AceType)
166 {
167 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
168 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
169 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
170 case ACCESS_DENIED_OBJECT_ACE_TYPE:
171 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
172 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
173 Ret = TRUE;
174 break;
175
176 default:
177 Ret = FALSE;
178 break;
179 }
180
181 return Ret;
182 }
183
184 static GUID*
185 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader)
186 {
187 GUID *ObjectType = NULL;
188
189 switch (AceHeader->AceType)
190 {
191 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
192 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
193 {
194 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
195 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
196 ObjectType = &Ace->ObjectType;
197 break;
198 }
199 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
200 case ACCESS_DENIED_OBJECT_ACE_TYPE:
201 {
202 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
203 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
204 ObjectType = &Ace->ObjectType;
205 break;
206 }
207
208 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
209 {
210 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
211 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
212 ObjectType = &Ace->ObjectType;
213 break;
214 }
215 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
216 {
217 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
218 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
219 ObjectType = &Ace->ObjectType;
220 break;
221 }
222 }
223
224 return ObjectType;
225 }
226
227 static GUID*
228 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader)
229 {
230 GUID *ObjectType = NULL;
231
232 switch (AceHeader->AceType)
233 {
234 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
235 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
236 {
237 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
238 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
239 {
240 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
241 ObjectType = &Ace->InheritedObjectType;
242 else
243 ObjectType = &Ace->ObjectType;
244 }
245 break;
246 }
247 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
248 case ACCESS_DENIED_OBJECT_ACE_TYPE:
249 {
250 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
251 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
252 {
253 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
254 ObjectType = &Ace->InheritedObjectType;
255 else
256 ObjectType = &Ace->ObjectType;
257 }
258 break;
259 }
260
261 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
262 {
263 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
264 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
265 {
266 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
267 ObjectType = &Ace->InheritedObjectType;
268 else
269 ObjectType = &Ace->ObjectType;
270 }
271 break;
272 }
273 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
274 {
275 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
276 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
277 {
278 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
279 ObjectType = &Ace->InheritedObjectType;
280 else
281 ObjectType = &Ace->ObjectType;
282 }
283 break;
284 }
285 }
286
287 return ObjectType;
288 }
289
290
291 /**********************************************************************
292 * AccRewriteGetHandleRights EXPORTED
293 *
294 * @unimplemented
295 */
296 DWORD WINAPI
297 AccRewriteGetHandleRights(HANDLE handle,
298 SE_OBJECT_TYPE ObjectType,
299 SECURITY_INFORMATION SecurityInfo,
300 PSID* ppsidOwner,
301 PSID* ppsidGroup,
302 PACL* ppDacl,
303 PACL* ppSacl,
304 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
305 {
306 PSECURITY_DESCRIPTOR pSD = NULL;
307 ULONG SDSize = 0;
308 NTSTATUS Status;
309 DWORD LastErr;
310 DWORD Ret;
311
312 /* save the last error code */
313 LastErr = GetLastError();
314
315 do
316 {
317 Ret = ERROR_SUCCESS;
318
319 /* allocate a buffer large enough to hold the
320 security descriptor we need to return */
321 SDSize += 0x100;
322 if (pSD == NULL)
323 {
324 pSD = LocalAlloc(LMEM_FIXED,
325 (SIZE_T)SDSize);
326 }
327 else
328 {
329 PSECURITY_DESCRIPTOR newSD;
330
331 newSD = LocalReAlloc((HLOCAL)pSD,
332 (SIZE_T)SDSize,
333 LMEM_MOVEABLE);
334 if (newSD != NULL)
335 pSD = newSD;
336 }
337
338 if (pSD == NULL)
339 {
340 Ret = GetLastError();
341 break;
342 }
343
344 /* perform the actual query depending on the object type */
345 switch (ObjectType)
346 {
347 case SE_REGISTRY_KEY:
348 {
349 Ret = (DWORD)RegGetKeySecurity((HKEY)handle,
350 SecurityInfo,
351 pSD,
352 &SDSize);
353 break;
354 }
355
356 case SE_FILE_OBJECT:
357 /* FIXME - handle console handles? */
358 case SE_KERNEL_OBJECT:
359 {
360 Status = NtQuerySecurityObject(handle,
361 SecurityInfo,
362 pSD,
363 SDSize,
364 &SDSize);
365 if (!NT_SUCCESS(Status))
366 {
367 Ret = RtlNtStatusToDosError(Status);
368 }
369 break;
370 }
371
372 case SE_SERVICE:
373 {
374 if (!QueryServiceObjectSecurity((SC_HANDLE)handle,
375 SecurityInfo,
376 pSD,
377 SDSize,
378 &SDSize))
379 {
380 Ret = GetLastError();
381 }
382 break;
383 }
384
385 case SE_WINDOW_OBJECT:
386 {
387 if (!GetUserObjectSecurity(handle,
388 &SecurityInfo,
389 pSD,
390 SDSize,
391 &SDSize))
392 {
393 Ret = GetLastError();
394 }
395 break;
396 }
397
398 default:
399 {
400 UNIMPLEMENTED;
401 Ret = ERROR_CALL_NOT_IMPLEMENTED;
402 break;
403 }
404 }
405
406 } while (Ret == ERROR_INSUFFICIENT_BUFFER);
407
408 if (Ret == ERROR_SUCCESS)
409 {
410 BOOL Present, Defaulted;
411
412 if (SecurityInfo & OWNER_SECURITY_INFORMATION && ppsidOwner != NULL)
413 {
414 *ppsidOwner = NULL;
415 if (!GetSecurityDescriptorOwner(pSD,
416 ppsidOwner,
417 &Defaulted))
418 {
419 Ret = GetLastError();
420 goto Cleanup;
421 }
422 }
423
424 if (SecurityInfo & GROUP_SECURITY_INFORMATION && ppsidGroup != NULL)
425 {
426 *ppsidOwner = NULL;
427 if (!GetSecurityDescriptorGroup(pSD,
428 ppsidGroup,
429 &Defaulted))
430 {
431 Ret = GetLastError();
432 goto Cleanup;
433 }
434 }
435
436 if (SecurityInfo & DACL_SECURITY_INFORMATION && ppDacl != NULL)
437 {
438 *ppDacl = NULL;
439 if (!GetSecurityDescriptorDacl(pSD,
440 &Present,
441 ppDacl,
442 &Defaulted))
443 {
444 Ret = GetLastError();
445 goto Cleanup;
446 }
447 }
448
449 if (SecurityInfo & SACL_SECURITY_INFORMATION && ppSacl != NULL)
450 {
451 *ppSacl = NULL;
452 if (!GetSecurityDescriptorSacl(pSD,
453 &Present,
454 ppSacl,
455 &Defaulted))
456 {
457 Ret = GetLastError();
458 goto Cleanup;
459 }
460 }
461
462 *ppSecurityDescriptor = pSD;
463 }
464 else
465 {
466 Cleanup:
467 if (pSD != NULL)
468 {
469 LocalFree((HLOCAL)pSD);
470 }
471 }
472
473 /* restore the last error code */
474 SetLastError(LastErr);
475
476 return Ret;
477 }
478
479
480 /**********************************************************************
481 * AccRewriteSetHandleRights EXPORTED
482 *
483 * @unimplemented
484 */
485 DWORD WINAPI
486 AccRewriteSetHandleRights(HANDLE handle,
487 SE_OBJECT_TYPE ObjectType,
488 SECURITY_INFORMATION SecurityInfo,
489 PSECURITY_DESCRIPTOR pSecurityDescriptor)
490 {
491 NTSTATUS Status;
492 DWORD LastErr;
493 DWORD Ret = ERROR_SUCCESS;
494
495 /* save the last error code */
496 LastErr = GetLastError();
497
498 /* set the security according to the object type */
499 switch (ObjectType)
500 {
501 case SE_REGISTRY_KEY:
502 {
503 Ret = (DWORD)RegSetKeySecurity((HKEY)handle,
504 SecurityInfo,
505 pSecurityDescriptor);
506 break;
507 }
508
509 case SE_FILE_OBJECT:
510 /* FIXME - handle console handles? */
511 case SE_KERNEL_OBJECT:
512 {
513 Status = NtSetSecurityObject(handle,
514 SecurityInfo,
515 pSecurityDescriptor);
516 if (!NT_SUCCESS(Status))
517 {
518 Ret = RtlNtStatusToDosError(Status);
519 }
520 break;
521 }
522
523 case SE_SERVICE:
524 {
525 if (!SetServiceObjectSecurity((SC_HANDLE)handle,
526 SecurityInfo,
527 pSecurityDescriptor))
528 {
529 Ret = GetLastError();
530 }
531 break;
532 }
533
534 case SE_WINDOW_OBJECT:
535 {
536 if (!SetUserObjectSecurity(handle,
537 &SecurityInfo,
538 pSecurityDescriptor))
539 {
540 Ret = GetLastError();
541 }
542 break;
543 }
544
545 default:
546 {
547 UNIMPLEMENTED;
548 Ret = ERROR_CALL_NOT_IMPLEMENTED;
549 break;
550 }
551 }
552
553
554 /* restore the last error code */
555 SetLastError(LastErr);
556
557 return Ret;
558 }
559
560
561 static DWORD
562 AccpOpenNamedObject(LPWSTR pObjectName,
563 SE_OBJECT_TYPE ObjectType,
564 SECURITY_INFORMATION SecurityInfo,
565 PHANDLE Handle,
566 PHANDLE Handle2,
567 BOOL Write)
568 {
569 LPWSTR lpPath;
570 NTSTATUS Status;
571 ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
572 DWORD Ret = ERROR_SUCCESS;
573
574 /* determine the required access rights */
575 switch (ObjectType)
576 {
577 case SE_REGISTRY_KEY:
578 case SE_FILE_OBJECT:
579 case SE_KERNEL_OBJECT:
580 case SE_SERVICE:
581 case SE_WINDOW_OBJECT:
582 if (Write)
583 {
584 SetSecurityAccessMask(SecurityInfo,
585 (PDWORD)&DesiredAccess);
586 }
587 else
588 {
589 QuerySecurityAccessMask(SecurityInfo,
590 (PDWORD)&DesiredAccess);
591 }
592 break;
593
594 default:
595 break;
596 }
597
598 /* make a copy of the path if we're modifying the string */
599 switch (ObjectType)
600 {
601 case SE_REGISTRY_KEY:
602 case SE_SERVICE:
603 lpPath = (LPWSTR)LocalAlloc(LMEM_FIXED,
604 (wcslen(pObjectName) + 1) * sizeof(WCHAR));
605 if (lpPath == NULL)
606 {
607 Ret = GetLastError();
608 goto Cleanup;
609 }
610
611 wcscpy(lpPath,
612 pObjectName);
613 break;
614
615 default:
616 lpPath = pObjectName;
617 break;
618 }
619
620 /* open a handle to the path depending on the object type */
621 switch (ObjectType)
622 {
623 case SE_FILE_OBJECT:
624 {
625 IO_STATUS_BLOCK IoStatusBlock;
626 OBJECT_ATTRIBUTES ObjectAttributes;
627 UNICODE_STRING FileName;
628
629 if (!RtlDosPathNameToNtPathName_U(pObjectName,
630 &FileName,
631 NULL,
632 NULL))
633 {
634 Ret = ERROR_INVALID_NAME;
635 goto Cleanup;
636 }
637
638 InitializeObjectAttributes(&ObjectAttributes,
639 &FileName,
640 OBJ_CASE_INSENSITIVE,
641 NULL,
642 NULL);
643
644 Status = NtOpenFile(Handle,
645 DesiredAccess,
646 &ObjectAttributes,
647 &IoStatusBlock,
648 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
649 FILE_SYNCHRONOUS_IO_NONALERT);
650
651 RtlFreeHeap(RtlGetProcessHeap(),
652 0,
653 FileName.Buffer);
654
655 if (!NT_SUCCESS(Status))
656 {
657 Ret = RtlNtStatusToDosError(Status);
658 }
659 break;
660 }
661
662 case SE_REGISTRY_KEY:
663 {
664 static const struct
665 {
666 HKEY hRootKey;
667 LPCWSTR szRootKey;
668 } AccRegRootKeys[] =
669 {
670 {HKEY_CLASSES_ROOT, L"CLASSES_ROOT"},
671 {HKEY_CURRENT_USER, L"CURRENT_USER"},
672 {HKEY_LOCAL_MACHINE, L"MACHINE"},
673 {HKEY_USERS, L"USERS"},
674 {HKEY_CURRENT_CONFIG, L"CONFIG"},
675 };
676 LPWSTR lpMachineName, lpRootKeyName, lpKeyName;
677 HKEY hRootKey = NULL;
678 UINT i;
679
680 /* parse the registry path */
681 if (lpPath[0] == L'\\' && lpPath[1] == L'\\')
682 {
683 lpMachineName = lpPath;
684
685 lpRootKeyName = wcschr(lpPath + 2,
686 L'\\');
687 if (lpRootKeyName == NULL)
688 goto ParseRegErr;
689 else
690 *(lpRootKeyName++) = L'\0';
691 }
692 else
693 {
694 lpMachineName = NULL;
695 lpRootKeyName = lpPath;
696 }
697
698 lpKeyName = wcschr(lpRootKeyName,
699 L'\\');
700 if (lpKeyName != NULL)
701 {
702 *(lpKeyName++) = L'\0';
703 }
704
705 for (i = 0;
706 i != sizeof(AccRegRootKeys) / sizeof(AccRegRootKeys[0]);
707 i++)
708 {
709 if (!wcsicmp(lpRootKeyName,
710 AccRegRootKeys[i].szRootKey))
711 {
712 hRootKey = AccRegRootKeys[i].hRootKey;
713 break;
714 }
715 }
716
717 if (hRootKey == NULL)
718 {
719 ParseRegErr:
720 /* FIXME - right error code? */
721 Ret = ERROR_INVALID_PARAMETER;
722 goto Cleanup;
723 }
724
725 /* open the registry key */
726 if (lpMachineName != NULL)
727 {
728 Ret = RegConnectRegistry(lpMachineName,
729 hRootKey,
730 (PHKEY)Handle2);
731
732 if (Ret != ERROR_SUCCESS)
733 goto Cleanup;
734
735 hRootKey = (HKEY)(*Handle2);
736 }
737
738 Ret = RegOpenKeyEx(hRootKey,
739 lpKeyName,
740 0,
741 (REGSAM)DesiredAccess,
742 (PHKEY)Handle);
743 if (Ret != ERROR_SUCCESS)
744 {
745 if (*Handle2 != NULL)
746 {
747 RegCloseKey((HKEY)(*Handle2));
748 }
749
750 goto Cleanup;
751 }
752 break;
753 }
754
755 case SE_SERVICE:
756 {
757 LPWSTR lpServiceName, lpMachineName;
758
759 /* parse the service path */
760 if (lpPath[0] == L'\\' && lpPath[1] == L'\\')
761 {
762 DesiredAccess |= SC_MANAGER_CONNECT;
763
764 lpMachineName = lpPath;
765
766 lpServiceName = wcschr(lpPath + 2,
767 L'\\');
768 if (lpServiceName == NULL)
769 {
770 /* FIXME - right error code? */
771 Ret = ERROR_INVALID_PARAMETER;
772 goto Cleanup;
773 }
774 else
775 *(lpServiceName++) = L'\0';
776 }
777 else
778 {
779 lpMachineName = NULL;
780 lpServiceName = lpPath;
781 }
782
783 /* open the service */
784 *Handle2 = (HANDLE)OpenSCManager(lpMachineName,
785 NULL,
786 (DWORD)DesiredAccess);
787 if (*Handle2 == NULL)
788 {
789 goto FailOpenService;
790 }
791
792 DesiredAccess &= ~SC_MANAGER_CONNECT;
793 *Handle = (HANDLE)OpenService((SC_HANDLE)(*Handle2),
794 lpServiceName,
795 (DWORD)DesiredAccess);
796 if (*Handle == NULL)
797 {
798 if (*Handle2 != NULL)
799 {
800 CloseServiceHandle((SC_HANDLE)(*Handle2));
801 }
802
803 FailOpenService:
804 Ret = GetLastError();
805 goto Cleanup;
806 }
807 break;
808 }
809
810 default:
811 {
812 UNIMPLEMENTED;
813 Ret = ERROR_CALL_NOT_IMPLEMENTED;
814 break;
815 }
816 }
817
818 Cleanup:
819 if (lpPath != NULL && lpPath != pObjectName)
820 {
821 LocalFree((HLOCAL)lpPath);
822 }
823
824 return Ret;
825 }
826
827
828 static VOID
829 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType,
830 HANDLE Handle,
831 HANDLE Handle2)
832 {
833 ASSERT(Handle != NULL);
834
835 /* close allocated handlees depending on the object type */
836 switch (ObjectType)
837 {
838 case SE_REGISTRY_KEY:
839 RegCloseKey((HKEY)Handle);
840 if (Handle2 != NULL)
841 RegCloseKey((HKEY)Handle2);
842 break;
843
844 case SE_FILE_OBJECT:
845 NtClose(Handle);
846 break;
847
848 case SE_KERNEL_OBJECT:
849 case SE_WINDOW_OBJECT:
850 CloseHandle(Handle);
851 break;
852
853 case SE_SERVICE:
854 CloseServiceHandle((SC_HANDLE)Handle);
855 ASSERT(Handle2 != NULL);
856 CloseServiceHandle((SC_HANDLE)Handle2);
857 break;
858
859 default:
860 break;
861 }
862 }
863
864
865 /**********************************************************************
866 * AccRewriteGetNamedRights EXPORTED
867 *
868 * @unimplemented
869 */
870 DWORD WINAPI
871 AccRewriteGetNamedRights(LPWSTR pObjectName,
872 SE_OBJECT_TYPE ObjectType,
873 SECURITY_INFORMATION SecurityInfo,
874 PSID* ppsidOwner,
875 PSID* ppsidGroup,
876 PACL* ppDacl,
877 PACL* ppSacl,
878 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
879 {
880 HANDLE Handle = NULL;
881 HANDLE Handle2 = NULL;
882 DWORD LastErr;
883 DWORD Ret;
884
885 /* save the last error code */
886 LastErr = GetLastError();
887
888 /* create the handle */
889 Ret = AccpOpenNamedObject(pObjectName,
890 ObjectType,
891 SecurityInfo,
892 &Handle,
893 &Handle2,
894 FALSE);
895
896 if (Ret == ERROR_SUCCESS)
897 {
898 ASSERT(Handle != NULL);
899
900 /* perform the operation */
901 Ret = AccRewriteGetHandleRights(Handle,
902 ObjectType,
903 SecurityInfo,
904 ppsidOwner,
905 ppsidGroup,
906 ppDacl,
907 ppSacl,
908 ppSecurityDescriptor);
909
910 /* close opened handles */
911 AccpCloseObjectHandle(ObjectType,
912 Handle,
913 Handle2);
914 }
915
916 /* restore the last error code */
917 SetLastError(LastErr);
918
919 return Ret;
920 }
921
922
923 /**********************************************************************
924 * AccRewriteSetNamedRights EXPORTED
925 *
926 * @unimplemented
927 */
928 DWORD WINAPI
929 AccRewriteSetNamedRights(LPWSTR pObjectName,
930 SE_OBJECT_TYPE ObjectType,
931 SECURITY_INFORMATION SecurityInfo,
932 PSECURITY_DESCRIPTOR pSecurityDescriptor)
933 {
934 HANDLE Handle = NULL;
935 HANDLE Handle2 = NULL;
936 DWORD LastErr;
937 DWORD Ret;
938
939 /* save the last error code */
940 LastErr = GetLastError();
941
942 /* create the handle */
943 Ret = AccpOpenNamedObject(pObjectName,
944 ObjectType,
945 SecurityInfo,
946 &Handle,
947 &Handle2,
948 TRUE);
949
950 if (Ret == ERROR_SUCCESS)
951 {
952 ASSERT(Handle != NULL);
953
954 /* perform the operation */
955 Ret = AccRewriteSetHandleRights(Handle,
956 ObjectType,
957 SecurityInfo,
958 pSecurityDescriptor);
959
960 /* close opened handles */
961 AccpCloseObjectHandle(ObjectType,
962 Handle,
963 Handle2);
964 }
965
966 /* restore the last error code */
967 SetLastError(LastErr);
968
969 return Ret;
970 }
971
972
973 /**********************************************************************
974 * AccRewriteSetEntriesInAcl EXPORTED
975 *
976 * @unimplemented
977 */
978 DWORD WINAPI
979 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries,
980 PEXPLICIT_ACCESS_W pListOfExplicitEntries,
981 PACL OldAcl,
982 PACL* NewAcl)
983 {
984 UNIMPLEMENTED;
985 return ERROR_CALL_NOT_IMPLEMENTED;
986 }
987
988
989 /**********************************************************************
990 * AccRewriteSetEntriesInAcl EXPORTED
991 *
992 * @unimplemented
993 */
994 DWORD WINAPI
995 AccGetInheritanceSource(LPWSTR pObjectName,
996 SE_OBJECT_TYPE ObjectType,
997 SECURITY_INFORMATION SecurityInfo,
998 BOOL Container,
999 GUID** pObjectClassGuids,
1000 DWORD GuidCount,
1001 PACL pAcl,
1002 PFN_OBJECT_MGR_FUNCTS pfnArray,
1003 PGENERIC_MAPPING pGenericMapping,
1004 PINHERITED_FROMW pInheritArray)
1005 {
1006 UNIMPLEMENTED;
1007 return ERROR_CALL_NOT_IMPLEMENTED;
1008 }
1009
1010
1011 /**********************************************************************
1012 * AccFreeIndexArray EXPORTED
1013 *
1014 * @implemented
1015 */
1016 DWORD WINAPI
1017 AccFreeIndexArray(PINHERITED_FROMW pInheritArray,
1018 USHORT AceCnt,
1019 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL)
1020 {
1021 PINHERITED_FROMW pLast;
1022
1023 UNREFERENCED_PARAMETER(pfnArray);
1024
1025 pLast = pInheritArray + AceCnt;
1026 while (pInheritArray != pLast)
1027 {
1028 if (pInheritArray->AncestorName != NULL)
1029 {
1030 LocalFree((HLOCAL)pInheritArray->AncestorName);
1031 pInheritArray->AncestorName = NULL;
1032 }
1033
1034 pInheritArray++;
1035 }
1036
1037 return ERROR_SUCCESS;
1038 }
1039
1040
1041 /**********************************************************************
1042 * AccRewriteGetExplicitEntriesFromAcl EXPORTED
1043 *
1044 * @implemented
1045 */
1046 DWORD WINAPI
1047 AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
1048 PULONG pcCountOfExplicitEntries,
1049 PEXPLICIT_ACCESS_W* pListOfExplicitEntries)
1050 {
1051 PACE_HEADER AceHeader;
1052 PSID Sid, SidTarget;
1053 ULONG ObjectAceCount = 0;
1054 POBJECTS_AND_SID ObjSid;
1055 SIZE_T Size;
1056 PEXPLICIT_ACCESS_W peaw;
1057 DWORD LastErr, SidLen;
1058 DWORD AceIndex = 0;
1059 DWORD ErrorCode = ERROR_SUCCESS;
1060
1061 /* save the last error code */
1062 LastErr = GetLastError();
1063
1064 if (pacl != NULL)
1065 {
1066 if (pacl->AceCount != 0)
1067 {
1068 Size = (SIZE_T)pacl->AceCount * sizeof(EXPLICIT_ACCESS_W);
1069
1070 /* calculate the space needed */
1071 while (GetAce(pacl,
1072 AceIndex,
1073 (LPVOID*)&AceHeader))
1074 {
1075 Sid = AccpGetAceSid(AceHeader);
1076 Size += GetLengthSid(Sid);
1077
1078 if (AccpIsObjectAce(AceHeader))
1079 ObjectAceCount++;
1080
1081 AceIndex++;
1082 }
1083
1084 Size += ObjectAceCount * sizeof(OBJECTS_AND_SID);
1085
1086 ASSERT(pacl->AceCount == AceIndex);
1087
1088 /* allocate the array */
1089 peaw = (PEXPLICIT_ACCESS_W)LocalAlloc(LMEM_FIXED,
1090 Size);
1091 if (peaw != NULL)
1092 {
1093 AceIndex = 0;
1094 ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount);
1095 SidTarget = (PSID)(ObjSid + ObjectAceCount);
1096
1097 /* initialize the array */
1098 while (GetAce(pacl,
1099 AceIndex,
1100 (LPVOID*)&AceHeader))
1101 {
1102 Sid = AccpGetAceSid(AceHeader);
1103 SidLen = GetLengthSid(Sid);
1104
1105 peaw[AceIndex].grfAccessPermissions = AccpGetAceAccessMask(AceHeader);
1106 peaw[AceIndex].grfAccessMode = AccpGetAceAccessMode(AceHeader);
1107 peaw[AceIndex].grfInheritance = AceHeader->AceFlags & VALID_INHERIT_FLAGS;
1108
1109 if (CopySid(SidLen,
1110 SidTarget,
1111 Sid))
1112 {
1113 if (AccpIsObjectAce(AceHeader))
1114 {
1115 BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee,
1116 ObjSid++,
1117 AccpGetObjectAceObjectType(AceHeader),
1118 AccpGetObjectAceInheritedObjectType(AceHeader),
1119 SidTarget);
1120 }
1121 else
1122 {
1123 BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
1124 SidTarget);
1125 }
1126
1127 SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen);
1128 }
1129 else
1130 {
1131 /* copying the SID failed, treat it as an fatal error... */
1132 ErrorCode = GetLastError();
1133
1134 /* free allocated resources */
1135 LocalFree(peaw);
1136 peaw = NULL;
1137 AceIndex = 0;
1138 break;
1139 }
1140
1141 AceIndex++;
1142 }
1143
1144 *pcCountOfExplicitEntries = AceIndex;
1145 *pListOfExplicitEntries = peaw;
1146 }
1147 else
1148 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1149 }
1150 else
1151 {
1152 goto EmptyACL;
1153 }
1154 }
1155 else
1156 {
1157 EmptyACL:
1158 *pcCountOfExplicitEntries = 0;
1159 *pListOfExplicitEntries = NULL;
1160 }
1161
1162 /* restore the last error code */
1163 SetLastError(LastErr);
1164
1165 return ErrorCode;
1166 }
1167
1168
1169 /**********************************************************************
1170 * AccTreeResetNamedSecurityInfo EXPORTED
1171 *
1172 * @unimplemented
1173 */
1174 DWORD WINAPI
1175 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName,
1176 SE_OBJECT_TYPE ObjectType,
1177 SECURITY_INFORMATION SecurityInfo,
1178 PSID pOwner,
1179 PSID pGroup,
1180 PACL pDacl,
1181 PACL pSacl,
1182 BOOL KeepExplicit,
1183 FN_PROGRESSW fnProgress,
1184 PROG_INVOKE_SETTING ProgressInvokeSetting,
1185 PVOID Args)
1186 {
1187 UNIMPLEMENTED;
1188 return ERROR_CALL_NOT_IMPLEMENTED;
1189 }
1190
1191
1192 BOOL WINAPI
1193 DllMain(IN HINSTANCE hinstDLL,
1194 IN DWORD dwReason,
1195 IN LPVOID lpvReserved)
1196 {
1197 switch (dwReason)
1198 {
1199 case DLL_PROCESS_ATTACH:
1200 hDllInstance = hinstDLL;
1201 DisableThreadLibraryCalls(hinstDLL);
1202 break;
1203
1204 case DLL_PROCESS_DETACH:
1205 break;
1206 }
1207 return TRUE;
1208 }
1209