2 * ReactOS MARTA provider
3 * Copyright (C) 2005 - 2006 ReactOS Team
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 /* $Id: ntmarta.c 31176 2007-12-12 07:04:12Z weiden $
21 * PROJECT: ReactOS MARTA provider
22 * FILE: lib/ntmarta/ntmarta.c
23 * PURPOSE: ReactOS MARTA provider
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
34 HINSTANCE hDllInstance
;
37 AccpGetAceAccessMode(IN PACE_HEADER AceHeader
)
39 ACCESS_MODE Mode
= NOT_USED_ACCESS
;
41 switch (AceHeader
->AceType
)
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
:
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
:
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
;
72 AccpGetAceStructureSize(IN PACE_HEADER AceHeader
)
76 switch (AceHeader
->AceType
)
78 case ACCESS_ALLOWED_ACE_TYPE
:
79 case ACCESS_DENIED_ACE_TYPE
:
80 Size
= FIELD_OFFSET(ACCESS_ALLOWED_ACE
,
83 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
84 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
85 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE
,
88 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
89 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
91 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
92 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
,
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
);
100 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
101 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
103 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
104 Size
= FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE
,
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
);
113 case SYSTEM_AUDIT_ACE_TYPE
:
114 Size
= FIELD_OFFSET(SYSTEM_AUDIT_ACE
,
117 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE
:
118 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE
,
121 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
123 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
124 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE
,
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
);
132 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
134 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
135 Size
= FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE
,
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
);
144 case SYSTEM_MANDATORY_LABEL_ACE_TYPE
:
145 Size
= FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE
,
154 AccpGetAceSid(IN PACE_HEADER AceHeader
)
156 return (PSID
)((ULONG_PTR
)AceHeader
+ AccpGetAceStructureSize(AceHeader
));
160 AccpGetAceAccessMask(IN PACE_HEADER AceHeader
)
162 return *((PACCESS_MASK
)(AceHeader
+ 1));
166 AccpIsObjectAce(IN PACE_HEADER AceHeader
)
170 switch (AceHeader
->AceType
)
172 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
173 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
174 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
175 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
176 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
177 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
190 AccpGetTrusteeObjects(IN PTRUSTEE_W Trustee
,
191 OUT GUID
*pObjectTypeGuid OPTIONAL
,
192 OUT GUID
*pInheritedObjectTypeGuid OPTIONAL
)
196 switch (Trustee
->TrusteeForm
)
198 case TRUSTEE_IS_OBJECTS_AND_NAME
:
200 POBJECTS_AND_NAME_W pOan
= (POBJECTS_AND_NAME_W
)Trustee
->ptstrName
;
202 /* pOan->ObjectsPresent should always be 0 here because a previous
203 call to AccpGetTrusteeSid should have rejected these trustees
205 ASSERT(pOan
->ObjectsPresent
== 0);
207 Ret
= pOan
->ObjectsPresent
;
211 case TRUSTEE_IS_OBJECTS_AND_SID
:
213 POBJECTS_AND_SID pOas
= (POBJECTS_AND_SID
)Trustee
->ptstrName
;
215 if (pObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
216 *pObjectTypeGuid
= pOas
->ObjectTypeGuid
;
218 if (pInheritedObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
219 *pObjectTypeGuid
= pOas
->InheritedObjectTypeGuid
;
221 Ret
= pOas
->ObjectsPresent
;
226 /* Any other trustee forms have no objects attached... */
235 AccpCalcNeededAceSize(IN PSID Sid
,
236 IN DWORD ObjectsPresent
)
240 Ret
= sizeof(ACE
) + GetLengthSid(Sid
);
242 /* This routine calculates the generic size of the ACE needed.
243 If no objects are present it is assumed that only a standard
244 ACE is to be created. */
246 if (ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
248 if (ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
251 if (ObjectsPresent
!= 0)
252 Ret
+= sizeof(DWORD
); /* Include the Flags member to make it an object ACE */
258 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader
)
260 GUID
*ObjectType
= NULL
;
262 switch (AceHeader
->AceType
)
264 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
265 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
267 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
268 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
269 ObjectType
= &Ace
->ObjectType
;
272 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
273 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
275 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
276 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
277 ObjectType
= &Ace
->ObjectType
;
281 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
283 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
284 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
285 ObjectType
= &Ace
->ObjectType
;
288 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
290 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
291 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
292 ObjectType
= &Ace
->ObjectType
;
301 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader
)
303 GUID
*ObjectType
= NULL
;
305 switch (AceHeader
->AceType
)
307 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
308 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
310 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
311 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
313 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
314 ObjectType
= &Ace
->InheritedObjectType
;
316 ObjectType
= &Ace
->ObjectType
;
320 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
321 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
323 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
324 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
326 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
327 ObjectType
= &Ace
->InheritedObjectType
;
329 ObjectType
= &Ace
->ObjectType
;
334 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
336 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
337 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
339 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
340 ObjectType
= &Ace
->InheritedObjectType
;
342 ObjectType
= &Ace
->ObjectType
;
346 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
348 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
349 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
351 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
352 ObjectType
= &Ace
->InheritedObjectType
;
354 ObjectType
= &Ace
->ObjectType
;
364 AccpOpenLSAPolicyHandle(IN LPWSTR SystemName
,
365 IN ACCESS_MASK DesiredAccess
,
366 OUT PLSA_HANDLE pPolicyHandle
)
368 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes
= {0};
369 LSA_UNICODE_STRING LsaSystemName
, *psn
;
372 if (SystemName
!= NULL
&& SystemName
[0] != L
'\0')
374 LsaSystemName
.Buffer
= SystemName
;
375 LsaSystemName
.Length
= wcslen(SystemName
) * sizeof(WCHAR
);
376 LsaSystemName
.MaximumLength
= LsaSystemName
.Length
+ sizeof(WCHAR
);
377 psn
= &LsaSystemName
;
384 Status
= LsaOpenPolicy(psn
,
385 &LsaObjectAttributes
,
388 if (!NT_SUCCESS(Status
))
389 return LsaNtStatusToWinError(Status
);
391 return ERROR_SUCCESS
;
395 AccpGetTrusteeName(IN PTRUSTEE_W Trustee
)
397 switch (Trustee
->TrusteeForm
)
399 case TRUSTEE_IS_NAME
:
400 return Trustee
->ptstrName
;
402 case TRUSTEE_IS_OBJECTS_AND_NAME
:
403 return ((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ptstrName
;
411 AccpLookupSidByName(IN LSA_HANDLE PolicyHandle
,
416 LSA_UNICODE_STRING LsaNames
[1];
417 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains
= NULL
;
418 PLSA_TRANSLATED_SID2 TranslatedSid
= NULL
;
420 DWORD Ret
= ERROR_SUCCESS
;
422 LsaNames
[0].Buffer
= Name
;
423 LsaNames
[0].Length
= wcslen(Name
) * sizeof(WCHAR
);
424 LsaNames
[0].MaximumLength
= LsaNames
[0].Length
+ sizeof(WCHAR
);
426 Status
= LsaLookupNames2(PolicyHandle
,
428 sizeof(LsaNames
) / sizeof(LsaNames
[0]),
433 if (!NT_SUCCESS(Status
))
434 return LsaNtStatusToWinError(Status
);
436 if (TranslatedSid
->Use
== SidTypeUnknown
|| TranslatedSid
->Use
== SidTypeInvalid
)
438 Ret
= LsaNtStatusToWinError(STATUS_NONE_MAPPED
); /* FIXME- what error code? */
442 SidLen
= GetLengthSid(TranslatedSid
->Sid
);
445 *pSid
= LocalAlloc(LMEM_FIXED
, (SIZE_T
)SidLen
);
452 Ret
= GetLastError();
454 LocalFree((HLOCAL
)*pSid
);
459 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
462 LsaFreeMemory(ReferencedDomains
);
463 LsaFreeMemory(TranslatedSid
);
470 AccpGetTrusteeSid(IN PTRUSTEE_W Trustee
,
471 IN OUT PLSA_HANDLE pPolicyHandle
,
475 DWORD Ret
= ERROR_SUCCESS
;
480 if (Trustee
->pMultipleTrustee
|| Trustee
->MultipleTrusteeOperation
!= NO_MULTIPLE_TRUSTEE
)
482 /* This is currently not supported */
483 return ERROR_INVALID_PARAMETER
;
486 switch (Trustee
->TrusteeForm
)
488 case TRUSTEE_IS_OBJECTS_AND_NAME
:
489 if (((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ObjectsPresent
!= 0)
491 /* This is not supported as there is no way to interpret the
492 strings provided, and we need GUIDs for the ACEs... */
493 Ret
= ERROR_INVALID_PARAMETER
;
498 case TRUSTEE_IS_NAME
:
499 if (*pPolicyHandle
== NULL
)
501 Ret
= AccpOpenLSAPolicyHandle(NULL
, /* FIXME - always local? */
504 if (Ret
!= ERROR_SUCCESS
)
507 ASSERT(*pPolicyHandle
!= NULL
);
510 Ret
= AccpLookupSidByName(*pPolicyHandle
,
511 AccpGetTrusteeName(Trustee
),
513 if (Ret
== ERROR_SUCCESS
)
515 ASSERT(*ppSid
!= NULL
);
520 case TRUSTEE_IS_OBJECTS_AND_SID
:
521 *ppSid
= ((POBJECTS_AND_SID
)Trustee
->ptstrName
)->pSid
;
525 *ppSid
= (PSID
)Trustee
->ptstrName
;
529 Ret
= ERROR_INVALID_PARAMETER
;
537 /**********************************************************************
538 * AccRewriteGetHandleRights EXPORTED
543 AccRewriteGetHandleRights(HANDLE handle
,
544 SE_OBJECT_TYPE ObjectType
,
545 SECURITY_INFORMATION SecurityInfo
,
550 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
552 PSECURITY_DESCRIPTOR pSD
= NULL
;
558 /* save the last error code */
559 LastErr
= GetLastError();
565 /* allocate a buffer large enough to hold the
566 security descriptor we need to return */
570 pSD
= LocalAlloc(LMEM_FIXED
,
575 PSECURITY_DESCRIPTOR newSD
;
577 newSD
= LocalReAlloc((HLOCAL
)pSD
,
586 Ret
= GetLastError();
590 /* perform the actual query depending on the object type */
593 case SE_REGISTRY_KEY
:
595 Ret
= (DWORD
)RegGetKeySecurity((HKEY
)handle
,
603 /* FIXME - handle console handles? */
604 case SE_KERNEL_OBJECT
:
606 Status
= NtQuerySecurityObject(handle
,
611 if (!NT_SUCCESS(Status
))
613 Ret
= RtlNtStatusToDosError(Status
);
620 if (!QueryServiceObjectSecurity((SC_HANDLE
)handle
,
626 Ret
= GetLastError();
631 case SE_WINDOW_OBJECT
:
633 if (!GetUserObjectSecurity(handle
,
639 Ret
= GetLastError();
647 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
652 } while (Ret
== ERROR_INSUFFICIENT_BUFFER
);
654 if (Ret
== ERROR_SUCCESS
)
656 BOOL Present
, Defaulted
;
658 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
&& ppsidOwner
!= NULL
)
661 if (!GetSecurityDescriptorOwner(pSD
,
665 Ret
= GetLastError();
670 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
&& ppsidGroup
!= NULL
)
673 if (!GetSecurityDescriptorGroup(pSD
,
677 Ret
= GetLastError();
682 if (SecurityInfo
& DACL_SECURITY_INFORMATION
&& ppDacl
!= NULL
)
685 if (!GetSecurityDescriptorDacl(pSD
,
690 Ret
= GetLastError();
695 if (SecurityInfo
& SACL_SECURITY_INFORMATION
&& ppSacl
!= NULL
)
698 if (!GetSecurityDescriptorSacl(pSD
,
703 Ret
= GetLastError();
708 *ppSecurityDescriptor
= pSD
;
715 LocalFree((HLOCAL
)pSD
);
719 /* restore the last error code */
720 SetLastError(LastErr
);
726 /**********************************************************************
727 * AccRewriteSetHandleRights EXPORTED
732 AccRewriteSetHandleRights(HANDLE handle
,
733 SE_OBJECT_TYPE ObjectType
,
734 SECURITY_INFORMATION SecurityInfo
,
735 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
739 DWORD Ret
= ERROR_SUCCESS
;
741 /* save the last error code */
742 LastErr
= GetLastError();
744 /* set the security according to the object type */
747 case SE_REGISTRY_KEY
:
749 Ret
= (DWORD
)RegSetKeySecurity((HKEY
)handle
,
751 pSecurityDescriptor
);
756 /* FIXME - handle console handles? */
757 case SE_KERNEL_OBJECT
:
759 Status
= NtSetSecurityObject(handle
,
761 pSecurityDescriptor
);
762 if (!NT_SUCCESS(Status
))
764 Ret
= RtlNtStatusToDosError(Status
);
771 if (!SetServiceObjectSecurity((SC_HANDLE
)handle
,
773 pSecurityDescriptor
))
775 Ret
= GetLastError();
780 case SE_WINDOW_OBJECT
:
782 if (!SetUserObjectSecurity(handle
,
784 pSecurityDescriptor
))
786 Ret
= GetLastError();
794 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
800 /* restore the last error code */
801 SetLastError(LastErr
);
808 AccpOpenNamedObject(LPWSTR pObjectName
,
809 SE_OBJECT_TYPE ObjectType
,
810 SECURITY_INFORMATION SecurityInfo
,
817 ACCESS_MASK DesiredAccess
= (ACCESS_MASK
)0;
818 DWORD Ret
= ERROR_SUCCESS
;
820 /* determine the required access rights */
823 case SE_REGISTRY_KEY
:
825 case SE_KERNEL_OBJECT
:
827 case SE_WINDOW_OBJECT
:
830 SetSecurityAccessMask(SecurityInfo
,
831 (PDWORD
)&DesiredAccess
);
835 QuerySecurityAccessMask(SecurityInfo
,
836 (PDWORD
)&DesiredAccess
);
844 /* make a copy of the path if we're modifying the string */
847 case SE_REGISTRY_KEY
:
849 lpPath
= (LPWSTR
)LocalAlloc(LMEM_FIXED
,
850 (wcslen(pObjectName
) + 1) * sizeof(WCHAR
));
853 Ret
= GetLastError();
862 lpPath
= pObjectName
;
866 /* open a handle to the path depending on the object type */
871 IO_STATUS_BLOCK IoStatusBlock
;
872 OBJECT_ATTRIBUTES ObjectAttributes
;
873 UNICODE_STRING FileName
;
875 if (!RtlDosPathNameToNtPathName_U(pObjectName
,
880 Ret
= ERROR_INVALID_NAME
;
884 InitializeObjectAttributes(&ObjectAttributes
,
886 OBJ_CASE_INSENSITIVE
,
890 Status
= NtOpenFile(Handle
,
894 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
895 FILE_SYNCHRONOUS_IO_NONALERT
);
897 RtlFreeHeap(RtlGetProcessHeap(),
901 if (!NT_SUCCESS(Status
))
903 Ret
= RtlNtStatusToDosError(Status
);
908 case SE_REGISTRY_KEY
:
916 {HKEY_CLASSES_ROOT
, L
"CLASSES_ROOT"},
917 {HKEY_CURRENT_USER
, L
"CURRENT_USER"},
918 {HKEY_LOCAL_MACHINE
, L
"MACHINE"},
919 {HKEY_USERS
, L
"USERS"},
920 {HKEY_CURRENT_CONFIG
, L
"CONFIG"},
922 LPWSTR lpMachineName
, lpRootKeyName
, lpKeyName
;
923 HKEY hRootKey
= NULL
;
926 /* parse the registry path */
927 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
929 lpMachineName
= lpPath
;
931 lpRootKeyName
= wcschr(lpPath
+ 2,
933 if (lpRootKeyName
== NULL
)
936 *(lpRootKeyName
++) = L
'\0';
940 lpMachineName
= NULL
;
941 lpRootKeyName
= lpPath
;
944 lpKeyName
= wcschr(lpRootKeyName
,
946 if (lpKeyName
!= NULL
)
948 *(lpKeyName
++) = L
'\0';
952 i
!= sizeof(AccRegRootKeys
) / sizeof(AccRegRootKeys
[0]);
955 if (!wcsicmp(lpRootKeyName
,
956 AccRegRootKeys
[i
].szRootKey
))
958 hRootKey
= AccRegRootKeys
[i
].hRootKey
;
963 if (hRootKey
== NULL
)
966 /* FIXME - right error code? */
967 Ret
= ERROR_INVALID_PARAMETER
;
971 /* open the registry key */
972 if (lpMachineName
!= NULL
)
974 Ret
= RegConnectRegistry(lpMachineName
,
978 if (Ret
!= ERROR_SUCCESS
)
981 hRootKey
= (HKEY
)(*Handle2
);
984 Ret
= RegOpenKeyEx(hRootKey
,
987 (REGSAM
)DesiredAccess
,
989 if (Ret
!= ERROR_SUCCESS
)
991 if (*Handle2
!= NULL
)
993 RegCloseKey((HKEY
)(*Handle2
));
1003 LPWSTR lpServiceName
, lpMachineName
;
1005 /* parse the service path */
1006 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
1008 DesiredAccess
|= SC_MANAGER_CONNECT
;
1010 lpMachineName
= lpPath
;
1012 lpServiceName
= wcschr(lpPath
+ 2,
1014 if (lpServiceName
== NULL
)
1016 /* FIXME - right error code? */
1017 Ret
= ERROR_INVALID_PARAMETER
;
1021 *(lpServiceName
++) = L
'\0';
1025 lpMachineName
= NULL
;
1026 lpServiceName
= lpPath
;
1029 /* open the service */
1030 *Handle2
= (HANDLE
)OpenSCManager(lpMachineName
,
1032 (DWORD
)DesiredAccess
);
1033 if (*Handle2
== NULL
)
1035 goto FailOpenService
;
1038 DesiredAccess
&= ~SC_MANAGER_CONNECT
;
1039 *Handle
= (HANDLE
)OpenService((SC_HANDLE
)(*Handle2
),
1041 (DWORD
)DesiredAccess
);
1042 if (*Handle
== NULL
)
1044 if (*Handle2
!= NULL
)
1046 CloseServiceHandle((SC_HANDLE
)(*Handle2
));
1050 Ret
= GetLastError();
1059 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
1065 if (lpPath
!= NULL
&& lpPath
!= pObjectName
)
1067 LocalFree((HLOCAL
)lpPath
);
1075 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType
,
1079 ASSERT(Handle
!= NULL
);
1081 /* close allocated handlees depending on the object type */
1084 case SE_REGISTRY_KEY
:
1085 RegCloseKey((HKEY
)Handle
);
1086 if (Handle2
!= NULL
)
1087 RegCloseKey((HKEY
)Handle2
);
1090 case SE_FILE_OBJECT
:
1094 case SE_KERNEL_OBJECT
:
1095 case SE_WINDOW_OBJECT
:
1096 CloseHandle(Handle
);
1100 CloseServiceHandle((SC_HANDLE
)Handle
);
1101 ASSERT(Handle2
!= NULL
);
1102 CloseServiceHandle((SC_HANDLE
)Handle2
);
1111 /**********************************************************************
1112 * AccRewriteGetNamedRights EXPORTED
1117 AccRewriteGetNamedRights(LPWSTR pObjectName
,
1118 SE_OBJECT_TYPE ObjectType
,
1119 SECURITY_INFORMATION SecurityInfo
,
1124 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1126 HANDLE Handle
= NULL
;
1127 HANDLE Handle2
= NULL
;
1131 /* save the last error code */
1132 LastErr
= GetLastError();
1134 /* create the handle */
1135 Ret
= AccpOpenNamedObject(pObjectName
,
1142 if (Ret
== ERROR_SUCCESS
)
1144 ASSERT(Handle
!= NULL
);
1146 /* perform the operation */
1147 Ret
= AccRewriteGetHandleRights(Handle
,
1154 ppSecurityDescriptor
);
1156 /* close opened handles */
1157 AccpCloseObjectHandle(ObjectType
,
1162 /* restore the last error code */
1163 SetLastError(LastErr
);
1169 /**********************************************************************
1170 * AccRewriteSetNamedRights EXPORTED
1175 AccRewriteSetNamedRights(LPWSTR pObjectName
,
1176 SE_OBJECT_TYPE ObjectType
,
1177 SECURITY_INFORMATION SecurityInfo
,
1178 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1180 HANDLE Handle
= NULL
;
1181 HANDLE Handle2
= NULL
;
1185 /* save the last error code */
1186 LastErr
= GetLastError();
1188 /* create the handle */
1189 Ret
= AccpOpenNamedObject(pObjectName
,
1196 if (Ret
== ERROR_SUCCESS
)
1198 ASSERT(Handle
!= NULL
);
1200 /* perform the operation */
1201 Ret
= AccRewriteSetHandleRights(Handle
,
1204 pSecurityDescriptor
);
1206 /* close opened handles */
1207 AccpCloseObjectHandle(ObjectType
,
1212 /* restore the last error code */
1213 SetLastError(LastErr
);
1219 /**********************************************************************
1220 * AccRewriteSetEntriesInAcl EXPORTED
1225 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries
,
1226 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
1231 ACL_SIZE_INFORMATION SizeInformation
;
1233 BOOLEAN KeepAceBuf
[8];
1234 BOOLEAN
*pKeepAce
= NULL
;
1235 GUID ObjectTypeGuid
, InheritedObjectTypeGuid
;
1236 DWORD ObjectsPresent
;
1240 LSA_HANDLE PolicyHandle
= NULL
;
1243 DWORD Ret
= ERROR_SUCCESS
;
1245 /* save the last error code */
1246 LastErr
= GetLastError();
1250 /* Get information about previous ACL */
1253 if (!GetAclInformation(OldAcl
, &SizeInformation
, sizeof(ACL_SIZE_INFORMATION
), AclSizeInformation
))
1255 Ret
= GetLastError();
1259 if (SizeInformation
.AceCount
> sizeof(KeepAceBuf
) / sizeof(KeepAceBuf
[0]))
1261 pKeepAce
= (BOOLEAN
*)LocalAlloc(LMEM_FIXED
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1264 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1269 pKeepAce
= KeepAceBuf
;
1271 memset(pKeepAce
, TRUE
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1275 ZeroMemory(&SizeInformation
, sizeof(ACL_SIZE_INFORMATION
));
1276 SizeInformation
.AclBytesInUse
= sizeof(ACL
);
1279 /* Get size required for new entries */
1280 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1282 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1286 if (Ret
!= ERROR_SUCCESS
)
1289 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1293 switch (pListOfExplicitEntries
[i
].grfAccessMode
)
1297 /* Discard all accesses for the trustee... */
1298 for (j
= 0; j
< SizeInformation
.AceCount
; j
++)
1302 if (!GetAce(OldAcl
, j
, (PVOID
*)&pAce
))
1304 Ret
= GetLastError();
1308 pSid2
= AccpGetAceSid(pAce
);
1309 if (RtlEqualSid(pSid1
, pSid2
))
1311 pKeepAce
[j
] = FALSE
;
1312 SizeInformation
.AclBytesInUse
-= pAce
->AceSize
;
1315 if (pListOfExplicitEntries
[i
].grfAccessMode
== REVOKE_ACCESS
)
1317 /* ...and replace by the current access */
1321 SizeInformation
.AclBytesInUse
+= AccpCalcNeededAceSize(pSid1
, ObjectsPresent
);
1323 case SET_AUDIT_SUCCESS
:
1324 case SET_AUDIT_FAILURE
:
1326 DPRINT1("Case not implemented!\n");
1329 DPRINT1("Unknown access mode 0x%x. Ignoring it\n", pListOfExplicitEntries
[i
].grfAccessMode
);
1334 LocalFree((HLOCAL
)pSid1
);
1337 /* OK, now create the new ACL */
1338 DPRINT("Allocating %u bytes for the new ACL\n", SizeInformation
.AclBytesInUse
);
1339 pNew
= (PACL
)LocalAlloc(LMEM_FIXED
, SizeInformation
.AclBytesInUse
);
1342 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1345 if (!InitializeAcl(pNew
, SizeInformation
.AclBytesInUse
, ACL_REVISION
))
1347 Ret
= GetLastError();
1352 /* 1a) New audit entries (SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE) */
1355 /* 1b) Existing audit entries */
1358 /* 2a) New denied entries (DENY_ACCESS) */
1359 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1361 if (pListOfExplicitEntries
[i
].grfAccessMode
== DENY_ACCESS
)
1363 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1364 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1368 if (Ret
!= ERROR_SUCCESS
)
1371 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1373 &InheritedObjectTypeGuid
);
1375 if (ObjectsPresent
== 0)
1377 /* FIXME: Call AddAccessDeniedAceEx instead! */
1378 bRet
= AddAccessDeniedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1382 /* FIXME: Call AddAccessDeniedObjectAce */
1383 DPRINT1("Object ACEs not yet supported!\n");
1384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1388 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1391 Ret
= GetLastError();
1397 /* 2b) Existing denied entries */
1400 /* 3a) New allow entries (GRANT_ACCESS, SET_ACCESS) */
1401 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1403 if (pListOfExplicitEntries
[i
].grfAccessMode
== SET_ACCESS
||
1404 pListOfExplicitEntries
[i
].grfAccessMode
== GRANT_ACCESS
)
1406 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1407 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1411 if (Ret
!= ERROR_SUCCESS
)
1414 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1416 &InheritedObjectTypeGuid
);
1418 if (ObjectsPresent
== 0)
1420 /* FIXME: Call AddAccessAllowedAceEx instead! */
1421 bRet
= AddAccessAllowedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1425 /* FIXME: Call AddAccessAllowedObjectAce */
1426 DPRINT1("Object ACEs not yet supported!\n");
1427 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1431 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1434 Ret
= GetLastError();
1440 /* 3b) Existing allow entries */
1446 if (pKeepAce
&& pKeepAce
!= KeepAceBuf
)
1447 LocalFree((HLOCAL
)pKeepAce
);
1449 if (pNew
&& Ret
!= ERROR_SUCCESS
)
1450 LocalFree((HLOCAL
)pNew
);
1453 LsaClose(PolicyHandle
);
1455 /* restore the last error code */
1456 SetLastError(LastErr
);
1462 /**********************************************************************
1463 * AccGetInheritanceSource EXPORTED
1468 AccGetInheritanceSource(LPWSTR pObjectName
,
1469 SE_OBJECT_TYPE ObjectType
,
1470 SECURITY_INFORMATION SecurityInfo
,
1472 GUID
** pObjectClassGuids
,
1475 PFN_OBJECT_MGR_FUNCTS pfnArray
,
1476 PGENERIC_MAPPING pGenericMapping
,
1477 PINHERITED_FROMW pInheritArray
)
1480 return ERROR_CALL_NOT_IMPLEMENTED
;
1484 /**********************************************************************
1485 * AccFreeIndexArray EXPORTED
1490 AccFreeIndexArray(PINHERITED_FROMW pInheritArray
,
1492 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
1494 PINHERITED_FROMW pLast
;
1496 UNREFERENCED_PARAMETER(pfnArray
);
1498 pLast
= pInheritArray
+ AceCnt
;
1499 while (pInheritArray
!= pLast
)
1501 if (pInheritArray
->AncestorName
!= NULL
)
1503 LocalFree((HLOCAL
)pInheritArray
->AncestorName
);
1504 pInheritArray
->AncestorName
= NULL
;
1510 return ERROR_SUCCESS
;
1514 /**********************************************************************
1515 * AccRewriteGetExplicitEntriesFromAcl EXPORTED
1520 AccRewriteGetExplicitEntriesFromAcl(PACL pacl
,
1521 PULONG pcCountOfExplicitEntries
,
1522 PEXPLICIT_ACCESS_W
* pListOfExplicitEntries
)
1524 PACE_HEADER AceHeader
;
1525 PSID Sid
, SidTarget
;
1526 ULONG ObjectAceCount
= 0;
1527 POBJECTS_AND_SID ObjSid
;
1529 PEXPLICIT_ACCESS_W peaw
;
1530 DWORD LastErr
, SidLen
;
1532 DWORD ErrorCode
= ERROR_SUCCESS
;
1534 /* save the last error code */
1535 LastErr
= GetLastError();
1539 if (pacl
->AceCount
!= 0)
1541 Size
= (SIZE_T
)pacl
->AceCount
* sizeof(EXPLICIT_ACCESS_W
);
1543 /* calculate the space needed */
1546 (LPVOID
*)&AceHeader
))
1548 Sid
= AccpGetAceSid(AceHeader
);
1549 Size
+= GetLengthSid(Sid
);
1551 if (AccpIsObjectAce(AceHeader
))
1557 Size
+= ObjectAceCount
* sizeof(OBJECTS_AND_SID
);
1559 ASSERT(pacl
->AceCount
== AceIndex
);
1561 /* allocate the array */
1562 peaw
= (PEXPLICIT_ACCESS_W
)LocalAlloc(LMEM_FIXED
,
1567 ObjSid
= (POBJECTS_AND_SID
)(peaw
+ pacl
->AceCount
);
1568 SidTarget
= (PSID
)(ObjSid
+ ObjectAceCount
);
1570 /* initialize the array */
1573 (LPVOID
*)&AceHeader
))
1575 Sid
= AccpGetAceSid(AceHeader
);
1576 SidLen
= GetLengthSid(Sid
);
1578 peaw
[AceIndex
].grfAccessPermissions
= AccpGetAceAccessMask(AceHeader
);
1579 peaw
[AceIndex
].grfAccessMode
= AccpGetAceAccessMode(AceHeader
);
1580 peaw
[AceIndex
].grfInheritance
= AceHeader
->AceFlags
& VALID_INHERIT_FLAGS
;
1586 if (AccpIsObjectAce(AceHeader
))
1588 BuildTrusteeWithObjectsAndSid(&peaw
[AceIndex
].Trustee
,
1590 AccpGetObjectAceObjectType(AceHeader
),
1591 AccpGetObjectAceInheritedObjectType(AceHeader
),
1596 BuildTrusteeWithSid(&peaw
[AceIndex
].Trustee
,
1600 SidTarget
= (PSID
)((ULONG_PTR
)SidTarget
+ SidLen
);
1604 /* copying the SID failed, treat it as an fatal error... */
1605 ErrorCode
= GetLastError();
1607 /* free allocated resources */
1617 *pcCountOfExplicitEntries
= AceIndex
;
1618 *pListOfExplicitEntries
= peaw
;
1621 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1631 *pcCountOfExplicitEntries
= 0;
1632 *pListOfExplicitEntries
= NULL
;
1635 /* restore the last error code */
1636 SetLastError(LastErr
);
1642 /**********************************************************************
1643 * AccTreeResetNamedSecurityInfo EXPORTED
1648 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName
,
1649 SE_OBJECT_TYPE ObjectType
,
1650 SECURITY_INFORMATION SecurityInfo
,
1656 FN_PROGRESSW fnProgress
,
1657 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1661 return ERROR_CALL_NOT_IMPLEMENTED
;
1666 DllMain(IN HINSTANCE hinstDLL
,
1668 IN LPVOID lpvReserved
)
1672 case DLL_PROCESS_ATTACH
:
1673 hDllInstance
= hinstDLL
;
1674 DisableThreadLibraryCalls(hinstDLL
);
1677 case DLL_PROCESS_DETACH
: