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
20 * PROJECT: ReactOS MARTA provider
21 * FILE: lib/ntmarta/ntmarta.c
22 * PURPOSE: ReactOS MARTA provider
23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
34 HINSTANCE hDllInstance
;
36 /* FIXME: Vista+ API */
39 SetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
40 OUT LPDWORD DesiredAccess
)
44 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
45 *DesiredAccess
|= WRITE_OWNER
;
47 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
48 *DesiredAccess
|= WRITE_DAC
;
50 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
51 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
54 /* FIXME: Vista+ API */
57 QuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
58 OUT LPDWORD DesiredAccess
)
62 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
|
63 GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
65 *DesiredAccess
|= READ_CONTROL
;
68 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
69 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
73 AccpGetAceAccessMode(IN PACE_HEADER AceHeader
)
75 ACCESS_MODE Mode
= NOT_USED_ACCESS
;
77 switch (AceHeader
->AceType
)
79 case ACCESS_ALLOWED_ACE_TYPE
:
80 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
81 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
82 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
86 case ACCESS_DENIED_ACE_TYPE
:
87 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
88 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
89 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
93 case SYSTEM_AUDIT_ACE_TYPE
:
94 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE
:
95 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
96 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
97 if (AceHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
)
98 Mode
= SET_AUDIT_FAILURE
;
99 else if (AceHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
100 Mode
= SET_AUDIT_SUCCESS
;
108 AccpGetAceStructureSize(IN PACE_HEADER AceHeader
)
112 switch (AceHeader
->AceType
)
114 case ACCESS_ALLOWED_ACE_TYPE
:
115 case ACCESS_DENIED_ACE_TYPE
:
116 Size
= FIELD_OFFSET(ACCESS_ALLOWED_ACE
,
119 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
120 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
121 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE
,
124 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
125 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
127 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
128 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
,
130 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
131 Size
+= sizeof(Ace
->ObjectType
);
132 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
133 Size
+= sizeof(Ace
->InheritedObjectType
);
136 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
137 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
139 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
140 Size
= FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE
,
142 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
143 Size
+= sizeof(Ace
->ObjectType
);
144 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
145 Size
+= sizeof(Ace
->InheritedObjectType
);
149 case SYSTEM_AUDIT_ACE_TYPE
:
150 Size
= FIELD_OFFSET(SYSTEM_AUDIT_ACE
,
153 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE
:
154 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE
,
157 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
159 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
160 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE
,
162 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
163 Size
+= sizeof(Ace
->ObjectType
);
164 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
165 Size
+= sizeof(Ace
->InheritedObjectType
);
168 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
170 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
171 Size
= FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE
,
173 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
174 Size
+= sizeof(Ace
->ObjectType
);
175 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
176 Size
+= sizeof(Ace
->InheritedObjectType
);
180 case SYSTEM_MANDATORY_LABEL_ACE_TYPE
:
181 Size
= FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE
,
190 AccpGetAceSid(IN PACE_HEADER AceHeader
)
192 return (PSID
)((ULONG_PTR
)AceHeader
+ AccpGetAceStructureSize(AceHeader
));
196 AccpGetAceAccessMask(IN PACE_HEADER AceHeader
)
198 return *((PACCESS_MASK
)(AceHeader
+ 1));
202 AccpIsObjectAce(IN PACE_HEADER AceHeader
)
206 switch (AceHeader
->AceType
)
208 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
209 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
210 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
211 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
212 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
213 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
226 AccpGetTrusteeObjects(IN PTRUSTEE_W Trustee
,
227 OUT GUID
*pObjectTypeGuid OPTIONAL
,
228 OUT GUID
*pInheritedObjectTypeGuid OPTIONAL
)
232 switch (Trustee
->TrusteeForm
)
234 case TRUSTEE_IS_OBJECTS_AND_NAME
:
236 POBJECTS_AND_NAME_W pOan
= (POBJECTS_AND_NAME_W
)Trustee
->ptstrName
;
238 /* pOan->ObjectsPresent should always be 0 here because a previous
239 call to AccpGetTrusteeSid should have rejected these trustees
241 ASSERT(pOan
->ObjectsPresent
== 0);
243 Ret
= pOan
->ObjectsPresent
;
247 case TRUSTEE_IS_OBJECTS_AND_SID
:
249 POBJECTS_AND_SID pOas
= (POBJECTS_AND_SID
)Trustee
->ptstrName
;
251 if (pObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
252 *pObjectTypeGuid
= pOas
->ObjectTypeGuid
;
254 if (pInheritedObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
255 *pObjectTypeGuid
= pOas
->InheritedObjectTypeGuid
;
257 Ret
= pOas
->ObjectsPresent
;
262 /* Any other trustee forms have no objects attached... */
271 AccpCalcNeededAceSize(IN PSID Sid
,
272 IN DWORD ObjectsPresent
)
276 Ret
= sizeof(ACE
) + GetLengthSid(Sid
);
278 /* This routine calculates the generic size of the ACE needed.
279 If no objects are present it is assumed that only a standard
280 ACE is to be created. */
282 if (ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
284 if (ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
287 if (ObjectsPresent
!= 0)
288 Ret
+= sizeof(DWORD
); /* Include the Flags member to make it an object ACE */
294 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader
)
296 GUID
*ObjectType
= NULL
;
298 switch (AceHeader
->AceType
)
300 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
301 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
303 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
304 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
305 ObjectType
= &Ace
->ObjectType
;
308 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
309 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
311 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
312 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
313 ObjectType
= &Ace
->ObjectType
;
317 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
319 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
320 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
321 ObjectType
= &Ace
->ObjectType
;
324 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
326 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
327 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
328 ObjectType
= &Ace
->ObjectType
;
337 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader
)
339 GUID
*ObjectType
= NULL
;
341 switch (AceHeader
->AceType
)
343 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
344 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
346 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
347 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
349 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
350 ObjectType
= &Ace
->InheritedObjectType
;
352 ObjectType
= &Ace
->ObjectType
;
356 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
357 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
359 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
360 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
362 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
363 ObjectType
= &Ace
->InheritedObjectType
;
365 ObjectType
= &Ace
->ObjectType
;
370 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
372 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
373 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
375 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
376 ObjectType
= &Ace
->InheritedObjectType
;
378 ObjectType
= &Ace
->ObjectType
;
382 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
384 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
385 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
387 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
388 ObjectType
= &Ace
->InheritedObjectType
;
390 ObjectType
= &Ace
->ObjectType
;
400 AccpOpenLSAPolicyHandle(IN LPWSTR SystemName
,
401 IN ACCESS_MASK DesiredAccess
,
402 OUT PLSA_HANDLE pPolicyHandle
)
404 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes
= {0};
405 LSA_UNICODE_STRING LsaSystemName
, *psn
;
408 if (SystemName
!= NULL
&& SystemName
[0] != L
'\0')
410 LsaSystemName
.Buffer
= SystemName
;
411 LsaSystemName
.Length
= wcslen(SystemName
) * sizeof(WCHAR
);
412 LsaSystemName
.MaximumLength
= LsaSystemName
.Length
+ sizeof(WCHAR
);
413 psn
= &LsaSystemName
;
420 Status
= LsaOpenPolicy(psn
,
421 &LsaObjectAttributes
,
424 if (!NT_SUCCESS(Status
))
425 return LsaNtStatusToWinError(Status
);
427 return ERROR_SUCCESS
;
431 AccpGetTrusteeName(IN PTRUSTEE_W Trustee
)
433 switch (Trustee
->TrusteeForm
)
435 case TRUSTEE_IS_NAME
:
436 return Trustee
->ptstrName
;
438 case TRUSTEE_IS_OBJECTS_AND_NAME
:
439 return ((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ptstrName
;
447 AccpLookupSidByName(IN LSA_HANDLE PolicyHandle
,
452 LSA_UNICODE_STRING LsaNames
[1];
453 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains
= NULL
;
454 PLSA_TRANSLATED_SID2 TranslatedSid
= NULL
;
456 DWORD Ret
= ERROR_SUCCESS
;
458 LsaNames
[0].Buffer
= Name
;
459 LsaNames
[0].Length
= wcslen(Name
) * sizeof(WCHAR
);
460 LsaNames
[0].MaximumLength
= LsaNames
[0].Length
+ sizeof(WCHAR
);
462 Status
= LsaLookupNames2(PolicyHandle
,
464 sizeof(LsaNames
) / sizeof(LsaNames
[0]),
469 if (!NT_SUCCESS(Status
))
470 return LsaNtStatusToWinError(Status
);
472 if (TranslatedSid
->Use
== SidTypeUnknown
|| TranslatedSid
->Use
== SidTypeInvalid
)
474 Ret
= LsaNtStatusToWinError(STATUS_NONE_MAPPED
); /* FIXME- what error code? */
478 SidLen
= GetLengthSid(TranslatedSid
->Sid
);
481 *pSid
= LocalAlloc(LMEM_FIXED
, (SIZE_T
)SidLen
);
488 Ret
= GetLastError();
490 LocalFree((HLOCAL
)*pSid
);
495 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
498 LsaFreeMemory(ReferencedDomains
);
499 LsaFreeMemory(TranslatedSid
);
506 AccpGetTrusteeSid(IN PTRUSTEE_W Trustee
,
507 IN OUT PLSA_HANDLE pPolicyHandle
,
511 DWORD Ret
= ERROR_SUCCESS
;
516 if (Trustee
->pMultipleTrustee
|| Trustee
->MultipleTrusteeOperation
!= NO_MULTIPLE_TRUSTEE
)
518 /* This is currently not supported */
519 return ERROR_INVALID_PARAMETER
;
522 switch (Trustee
->TrusteeForm
)
524 case TRUSTEE_IS_OBJECTS_AND_NAME
:
525 if (((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ObjectsPresent
!= 0)
527 /* This is not supported as there is no way to interpret the
528 strings provided, and we need GUIDs for the ACEs... */
529 Ret
= ERROR_INVALID_PARAMETER
;
534 case TRUSTEE_IS_NAME
:
535 if (*pPolicyHandle
== NULL
)
537 Ret
= AccpOpenLSAPolicyHandle(NULL
, /* FIXME - always local? */
540 if (Ret
!= ERROR_SUCCESS
)
543 ASSERT(*pPolicyHandle
!= NULL
);
546 Ret
= AccpLookupSidByName(*pPolicyHandle
,
547 AccpGetTrusteeName(Trustee
),
549 if (Ret
== ERROR_SUCCESS
)
551 ASSERT(*ppSid
!= NULL
);
556 case TRUSTEE_IS_OBJECTS_AND_SID
:
557 *ppSid
= ((POBJECTS_AND_SID
)Trustee
->ptstrName
)->pSid
;
561 *ppSid
= (PSID
)Trustee
->ptstrName
;
565 Ret
= ERROR_INVALID_PARAMETER
;
573 /**********************************************************************
574 * AccRewriteGetHandleRights EXPORTED
579 AccRewriteGetHandleRights(HANDLE handle
,
580 SE_OBJECT_TYPE ObjectType
,
581 SECURITY_INFORMATION SecurityInfo
,
586 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
588 PSECURITY_DESCRIPTOR pSD
= NULL
;
594 /* save the last error code */
595 LastErr
= GetLastError();
601 /* allocate a buffer large enough to hold the
602 security descriptor we need to return */
606 pSD
= LocalAlloc(LMEM_FIXED
,
611 PSECURITY_DESCRIPTOR newSD
;
613 newSD
= LocalReAlloc((HLOCAL
)pSD
,
622 Ret
= GetLastError();
626 /* perform the actual query depending on the object type */
629 case SE_REGISTRY_KEY
:
631 Ret
= (DWORD
)RegGetKeySecurity((HKEY
)handle
,
639 /* FIXME - handle console handles? */
640 case SE_KERNEL_OBJECT
:
642 Status
= NtQuerySecurityObject(handle
,
647 if (!NT_SUCCESS(Status
))
649 Ret
= RtlNtStatusToDosError(Status
);
656 if (!QueryServiceObjectSecurity((SC_HANDLE
)handle
,
662 Ret
= GetLastError();
667 case SE_WINDOW_OBJECT
:
669 if (!GetUserObjectSecurity(handle
,
675 Ret
= GetLastError();
683 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
688 } while (Ret
== ERROR_INSUFFICIENT_BUFFER
);
690 if (Ret
== ERROR_SUCCESS
)
692 BOOL Present
, Defaulted
;
694 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
&& ppsidOwner
!= NULL
)
697 if (!GetSecurityDescriptorOwner(pSD
,
701 Ret
= GetLastError();
706 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
&& ppsidGroup
!= NULL
)
709 if (!GetSecurityDescriptorGroup(pSD
,
713 Ret
= GetLastError();
718 if (SecurityInfo
& DACL_SECURITY_INFORMATION
&& ppDacl
!= NULL
)
721 if (!GetSecurityDescriptorDacl(pSD
,
726 Ret
= GetLastError();
731 if (SecurityInfo
& SACL_SECURITY_INFORMATION
&& ppSacl
!= NULL
)
734 if (!GetSecurityDescriptorSacl(pSD
,
739 Ret
= GetLastError();
744 *ppSecurityDescriptor
= pSD
;
751 LocalFree((HLOCAL
)pSD
);
755 /* restore the last error code */
756 SetLastError(LastErr
);
762 /**********************************************************************
763 * AccRewriteSetHandleRights EXPORTED
768 AccRewriteSetHandleRights(HANDLE handle
,
769 SE_OBJECT_TYPE ObjectType
,
770 SECURITY_INFORMATION SecurityInfo
,
771 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
775 DWORD Ret
= ERROR_SUCCESS
;
777 /* save the last error code */
778 LastErr
= GetLastError();
780 /* set the security according to the object type */
783 case SE_REGISTRY_KEY
:
785 Ret
= (DWORD
)RegSetKeySecurity((HKEY
)handle
,
787 pSecurityDescriptor
);
792 /* FIXME - handle console handles? */
793 case SE_KERNEL_OBJECT
:
795 Status
= NtSetSecurityObject(handle
,
797 pSecurityDescriptor
);
798 if (!NT_SUCCESS(Status
))
800 Ret
= RtlNtStatusToDosError(Status
);
807 if (!SetServiceObjectSecurity((SC_HANDLE
)handle
,
809 pSecurityDescriptor
))
811 Ret
= GetLastError();
816 case SE_WINDOW_OBJECT
:
818 if (!SetUserObjectSecurity(handle
,
820 pSecurityDescriptor
))
822 Ret
= GetLastError();
830 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
836 /* restore the last error code */
837 SetLastError(LastErr
);
844 AccpOpenNamedObject(LPWSTR pObjectName
,
845 SE_OBJECT_TYPE ObjectType
,
846 SECURITY_INFORMATION SecurityInfo
,
853 ACCESS_MASK DesiredAccess
= (ACCESS_MASK
)0;
854 DWORD Ret
= ERROR_SUCCESS
;
856 /* determine the required access rights */
859 case SE_REGISTRY_KEY
:
861 case SE_KERNEL_OBJECT
:
863 case SE_WINDOW_OBJECT
:
866 SetSecurityAccessMask(SecurityInfo
,
867 (PDWORD
)&DesiredAccess
);
871 QuerySecurityAccessMask(SecurityInfo
,
872 (PDWORD
)&DesiredAccess
);
880 /* make a copy of the path if we're modifying the string */
883 case SE_REGISTRY_KEY
:
885 lpPath
= (LPWSTR
)LocalAlloc(LMEM_FIXED
,
886 (wcslen(pObjectName
) + 1) * sizeof(WCHAR
));
889 Ret
= GetLastError();
898 lpPath
= pObjectName
;
902 /* open a handle to the path depending on the object type */
907 IO_STATUS_BLOCK IoStatusBlock
;
908 OBJECT_ATTRIBUTES ObjectAttributes
;
909 UNICODE_STRING FileName
;
911 if (!RtlDosPathNameToNtPathName_U(pObjectName
,
916 Ret
= ERROR_INVALID_NAME
;
920 InitializeObjectAttributes(&ObjectAttributes
,
922 OBJ_CASE_INSENSITIVE
,
926 Status
= NtOpenFile(Handle
,
927 DesiredAccess
| SYNCHRONIZE
,
930 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
931 FILE_SYNCHRONOUS_IO_NONALERT
);
933 RtlFreeHeap(RtlGetProcessHeap(),
937 if (!NT_SUCCESS(Status
))
939 Ret
= RtlNtStatusToDosError(Status
);
944 case SE_REGISTRY_KEY
:
952 {HKEY_CLASSES_ROOT
, L
"CLASSES_ROOT"},
953 {HKEY_CURRENT_USER
, L
"CURRENT_USER"},
954 {HKEY_LOCAL_MACHINE
, L
"MACHINE"},
955 {HKEY_USERS
, L
"USERS"},
956 {HKEY_CURRENT_CONFIG
, L
"CONFIG"},
958 LPWSTR lpMachineName
, lpRootKeyName
, lpKeyName
;
959 HKEY hRootKey
= NULL
;
962 /* parse the registry path */
963 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
965 lpMachineName
= lpPath
;
967 lpRootKeyName
= wcschr(lpPath
+ 2,
969 if (lpRootKeyName
== NULL
)
972 *(lpRootKeyName
++) = L
'\0';
976 lpMachineName
= NULL
;
977 lpRootKeyName
= lpPath
;
980 lpKeyName
= wcschr(lpRootKeyName
,
982 if (lpKeyName
!= NULL
)
984 *(lpKeyName
++) = L
'\0';
988 i
!= sizeof(AccRegRootKeys
) / sizeof(AccRegRootKeys
[0]);
991 if (!wcsicmp(lpRootKeyName
,
992 AccRegRootKeys
[i
].szRootKey
))
994 hRootKey
= AccRegRootKeys
[i
].hRootKey
;
999 if (hRootKey
== NULL
)
1002 /* FIXME - right error code? */
1003 Ret
= ERROR_INVALID_PARAMETER
;
1007 /* open the registry key */
1008 if (lpMachineName
!= NULL
)
1010 Ret
= RegConnectRegistry(lpMachineName
,
1014 if (Ret
!= ERROR_SUCCESS
)
1017 hRootKey
= (HKEY
)(*Handle2
);
1020 Ret
= RegOpenKeyEx(hRootKey
,
1023 (REGSAM
)DesiredAccess
,
1025 if (Ret
!= ERROR_SUCCESS
)
1027 if (*Handle2
!= NULL
)
1029 RegCloseKey((HKEY
)(*Handle2
));
1039 LPWSTR lpServiceName
, lpMachineName
;
1041 /* parse the service path */
1042 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
1044 DesiredAccess
|= SC_MANAGER_CONNECT
;
1046 lpMachineName
= lpPath
;
1048 lpServiceName
= wcschr(lpPath
+ 2,
1050 if (lpServiceName
== NULL
)
1052 /* FIXME - right error code? */
1053 Ret
= ERROR_INVALID_PARAMETER
;
1057 *(lpServiceName
++) = L
'\0';
1061 lpMachineName
= NULL
;
1062 lpServiceName
= lpPath
;
1065 /* open the service */
1066 *Handle2
= (HANDLE
)OpenSCManager(lpMachineName
,
1068 (DWORD
)DesiredAccess
);
1069 if (*Handle2
== NULL
)
1071 goto FailOpenService
;
1074 DesiredAccess
&= ~SC_MANAGER_CONNECT
;
1075 *Handle
= (HANDLE
)OpenService((SC_HANDLE
)(*Handle2
),
1077 (DWORD
)DesiredAccess
);
1078 if (*Handle
== NULL
)
1080 if (*Handle2
!= NULL
)
1082 CloseServiceHandle((SC_HANDLE
)(*Handle2
));
1086 Ret
= GetLastError();
1095 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
1101 if (lpPath
!= NULL
&& lpPath
!= pObjectName
)
1103 LocalFree((HLOCAL
)lpPath
);
1111 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType
,
1115 ASSERT(Handle
!= NULL
);
1117 /* close allocated handlees depending on the object type */
1120 case SE_REGISTRY_KEY
:
1121 RegCloseKey((HKEY
)Handle
);
1122 if (Handle2
!= NULL
)
1123 RegCloseKey((HKEY
)Handle2
);
1126 case SE_FILE_OBJECT
:
1130 case SE_KERNEL_OBJECT
:
1131 case SE_WINDOW_OBJECT
:
1132 CloseHandle(Handle
);
1136 CloseServiceHandle((SC_HANDLE
)Handle
);
1137 ASSERT(Handle2
!= NULL
);
1138 CloseServiceHandle((SC_HANDLE
)Handle2
);
1147 /**********************************************************************
1148 * AccRewriteGetNamedRights EXPORTED
1153 AccRewriteGetNamedRights(LPWSTR pObjectName
,
1154 SE_OBJECT_TYPE ObjectType
,
1155 SECURITY_INFORMATION SecurityInfo
,
1160 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1162 HANDLE Handle
= NULL
;
1163 HANDLE Handle2
= NULL
;
1167 /* save the last error code */
1168 LastErr
= GetLastError();
1170 /* create the handle */
1171 Ret
= AccpOpenNamedObject(pObjectName
,
1178 if (Ret
== ERROR_SUCCESS
)
1180 ASSERT(Handle
!= NULL
);
1182 /* perform the operation */
1183 Ret
= AccRewriteGetHandleRights(Handle
,
1190 ppSecurityDescriptor
);
1192 /* close opened handles */
1193 AccpCloseObjectHandle(ObjectType
,
1198 /* restore the last error code */
1199 SetLastError(LastErr
);
1205 /**********************************************************************
1206 * AccRewriteSetNamedRights EXPORTED
1211 AccRewriteSetNamedRights(LPWSTR pObjectName
,
1212 SE_OBJECT_TYPE ObjectType
,
1213 SECURITY_INFORMATION SecurityInfo
,
1214 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1216 HANDLE Handle
= NULL
;
1217 HANDLE Handle2
= NULL
;
1221 /* save the last error code */
1222 LastErr
= GetLastError();
1224 /* create the handle */
1225 Ret
= AccpOpenNamedObject(pObjectName
,
1232 if (Ret
== ERROR_SUCCESS
)
1234 ASSERT(Handle
!= NULL
);
1236 /* perform the operation */
1237 Ret
= AccRewriteSetHandleRights(Handle
,
1240 pSecurityDescriptor
);
1242 /* close opened handles */
1243 AccpCloseObjectHandle(ObjectType
,
1248 /* restore the last error code */
1249 SetLastError(LastErr
);
1255 /**********************************************************************
1256 * AccRewriteSetEntriesInAcl EXPORTED
1261 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries
,
1262 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
1267 ACL_SIZE_INFORMATION SizeInformation
;
1269 BOOLEAN KeepAceBuf
[8];
1270 BOOLEAN
*pKeepAce
= NULL
;
1271 GUID ObjectTypeGuid
, InheritedObjectTypeGuid
;
1272 DWORD ObjectsPresent
;
1276 LSA_HANDLE PolicyHandle
= NULL
;
1279 DWORD Ret
= ERROR_SUCCESS
;
1281 /* save the last error code */
1282 LastErr
= GetLastError();
1286 /* Get information about previous ACL */
1289 if (!GetAclInformation(OldAcl
, &SizeInformation
, sizeof(ACL_SIZE_INFORMATION
), AclSizeInformation
))
1291 Ret
= GetLastError();
1295 if (SizeInformation
.AceCount
> sizeof(KeepAceBuf
) / sizeof(KeepAceBuf
[0]))
1297 pKeepAce
= (BOOLEAN
*)LocalAlloc(LMEM_FIXED
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1300 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1305 pKeepAce
= KeepAceBuf
;
1307 memset(pKeepAce
, TRUE
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1311 ZeroMemory(&SizeInformation
, sizeof(ACL_SIZE_INFORMATION
));
1312 SizeInformation
.AclBytesInUse
= sizeof(ACL
);
1315 /* Get size required for new entries */
1316 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1318 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1322 if (Ret
!= ERROR_SUCCESS
)
1325 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1329 switch (pListOfExplicitEntries
[i
].grfAccessMode
)
1333 /* Discard all accesses for the trustee... */
1334 for (j
= 0; j
< SizeInformation
.AceCount
; j
++)
1338 if (!GetAce(OldAcl
, j
, (PVOID
*)&pAce
))
1340 Ret
= GetLastError();
1344 pSid2
= AccpGetAceSid(pAce
);
1345 if (RtlEqualSid(pSid1
, pSid2
))
1347 pKeepAce
[j
] = FALSE
;
1348 SizeInformation
.AclBytesInUse
-= pAce
->AceSize
;
1351 if (pListOfExplicitEntries
[i
].grfAccessMode
== REVOKE_ACCESS
)
1353 /* ...and replace by the current access */
1357 SizeInformation
.AclBytesInUse
+= AccpCalcNeededAceSize(pSid1
, ObjectsPresent
);
1359 case SET_AUDIT_SUCCESS
:
1360 case SET_AUDIT_FAILURE
:
1362 DPRINT1("Case not implemented!\n");
1365 DPRINT1("Unknown access mode 0x%x. Ignoring it\n", pListOfExplicitEntries
[i
].grfAccessMode
);
1370 LocalFree((HLOCAL
)pSid1
);
1373 /* Succeed, if no ACL needs to be allocated */
1374 if (SizeInformation
.AclBytesInUse
== 0)
1377 /* OK, now create the new ACL */
1378 DPRINT("Allocating %u bytes for the new ACL\n", SizeInformation
.AclBytesInUse
);
1379 pNew
= (PACL
)LocalAlloc(LMEM_FIXED
, SizeInformation
.AclBytesInUse
);
1382 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1385 if (!InitializeAcl(pNew
, SizeInformation
.AclBytesInUse
, ACL_REVISION
))
1387 Ret
= GetLastError();
1392 /* 1a) New audit entries (SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE) */
1395 /* 1b) Existing audit entries */
1398 /* 2a) New denied entries (DENY_ACCESS) */
1399 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1401 if (pListOfExplicitEntries
[i
].grfAccessMode
== DENY_ACCESS
)
1403 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1404 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1408 if (Ret
!= ERROR_SUCCESS
)
1411 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1413 &InheritedObjectTypeGuid
);
1415 if (ObjectsPresent
== 0)
1417 /* FIXME: Call AddAccessDeniedAceEx instead! */
1418 bRet
= AddAccessDeniedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1422 /* FIXME: Call AddAccessDeniedObjectAce */
1423 DPRINT1("Object ACEs not yet supported!\n");
1424 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1428 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1431 Ret
= GetLastError();
1437 /* 2b) Existing denied entries */
1440 /* 3a) New allow entries (GRANT_ACCESS, SET_ACCESS) */
1441 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1443 if (pListOfExplicitEntries
[i
].grfAccessMode
== SET_ACCESS
||
1444 pListOfExplicitEntries
[i
].grfAccessMode
== GRANT_ACCESS
)
1446 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1447 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1451 if (Ret
!= ERROR_SUCCESS
)
1454 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1456 &InheritedObjectTypeGuid
);
1458 if (ObjectsPresent
== 0)
1460 /* FIXME: Call AddAccessAllowedAceEx instead! */
1461 bRet
= AddAccessAllowedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1465 /* FIXME: Call AddAccessAllowedObjectAce */
1466 DPRINT1("Object ACEs not yet supported!\n");
1467 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1471 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1474 Ret
= GetLastError();
1480 /* 3b) Existing allow entries */
1486 if (pKeepAce
&& pKeepAce
!= KeepAceBuf
)
1487 LocalFree((HLOCAL
)pKeepAce
);
1489 if (pNew
&& Ret
!= ERROR_SUCCESS
)
1490 LocalFree((HLOCAL
)pNew
);
1493 LsaClose(PolicyHandle
);
1495 /* restore the last error code */
1496 SetLastError(LastErr
);
1502 /**********************************************************************
1503 * AccGetInheritanceSource EXPORTED
1508 AccGetInheritanceSource(LPWSTR pObjectName
,
1509 SE_OBJECT_TYPE ObjectType
,
1510 SECURITY_INFORMATION SecurityInfo
,
1512 GUID
** pObjectClassGuids
,
1515 PFN_OBJECT_MGR_FUNCTS pfnArray
,
1516 PGENERIC_MAPPING pGenericMapping
,
1517 PINHERITED_FROMW pInheritArray
)
1520 return ERROR_CALL_NOT_IMPLEMENTED
;
1524 /**********************************************************************
1525 * AccFreeIndexArray EXPORTED
1530 AccFreeIndexArray(PINHERITED_FROMW pInheritArray
,
1532 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
1534 PINHERITED_FROMW pLast
;
1536 UNREFERENCED_PARAMETER(pfnArray
);
1538 pLast
= pInheritArray
+ AceCnt
;
1539 while (pInheritArray
!= pLast
)
1541 if (pInheritArray
->AncestorName
!= NULL
)
1543 LocalFree((HLOCAL
)pInheritArray
->AncestorName
);
1544 pInheritArray
->AncestorName
= NULL
;
1550 return ERROR_SUCCESS
;
1554 /**********************************************************************
1555 * AccRewriteGetExplicitEntriesFromAcl EXPORTED
1560 AccRewriteGetExplicitEntriesFromAcl(PACL pacl
,
1561 PULONG pcCountOfExplicitEntries
,
1562 PEXPLICIT_ACCESS_W
* pListOfExplicitEntries
)
1564 PACE_HEADER AceHeader
;
1565 PSID Sid
, SidTarget
;
1566 ULONG ObjectAceCount
= 0;
1567 POBJECTS_AND_SID ObjSid
;
1569 PEXPLICIT_ACCESS_W peaw
;
1570 DWORD LastErr
, SidLen
;
1572 DWORD ErrorCode
= ERROR_SUCCESS
;
1574 /* save the last error code */
1575 LastErr
= GetLastError();
1579 if (pacl
->AceCount
!= 0)
1581 Size
= (SIZE_T
)pacl
->AceCount
* sizeof(EXPLICIT_ACCESS_W
);
1583 /* calculate the space needed */
1586 (LPVOID
*)&AceHeader
))
1588 Sid
= AccpGetAceSid(AceHeader
);
1589 Size
+= GetLengthSid(Sid
);
1591 if (AccpIsObjectAce(AceHeader
))
1597 Size
+= ObjectAceCount
* sizeof(OBJECTS_AND_SID
);
1599 ASSERT(pacl
->AceCount
== AceIndex
);
1601 /* allocate the array */
1602 peaw
= (PEXPLICIT_ACCESS_W
)LocalAlloc(LMEM_FIXED
,
1607 ObjSid
= (POBJECTS_AND_SID
)(peaw
+ pacl
->AceCount
);
1608 SidTarget
= (PSID
)(ObjSid
+ ObjectAceCount
);
1610 /* initialize the array */
1613 (LPVOID
*)&AceHeader
))
1615 Sid
= AccpGetAceSid(AceHeader
);
1616 SidLen
= GetLengthSid(Sid
);
1618 peaw
[AceIndex
].grfAccessPermissions
= AccpGetAceAccessMask(AceHeader
);
1619 peaw
[AceIndex
].grfAccessMode
= AccpGetAceAccessMode(AceHeader
);
1620 peaw
[AceIndex
].grfInheritance
= AceHeader
->AceFlags
& VALID_INHERIT_FLAGS
;
1626 if (AccpIsObjectAce(AceHeader
))
1628 BuildTrusteeWithObjectsAndSid(&peaw
[AceIndex
].Trustee
,
1630 AccpGetObjectAceObjectType(AceHeader
),
1631 AccpGetObjectAceInheritedObjectType(AceHeader
),
1636 BuildTrusteeWithSid(&peaw
[AceIndex
].Trustee
,
1640 SidTarget
= (PSID
)((ULONG_PTR
)SidTarget
+ SidLen
);
1644 /* copying the SID failed, treat it as an fatal error... */
1645 ErrorCode
= GetLastError();
1647 /* free allocated resources */
1657 *pcCountOfExplicitEntries
= AceIndex
;
1658 *pListOfExplicitEntries
= peaw
;
1661 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1671 *pcCountOfExplicitEntries
= 0;
1672 *pListOfExplicitEntries
= NULL
;
1675 /* restore the last error code */
1676 SetLastError(LastErr
);
1682 /**********************************************************************
1683 * AccTreeResetNamedSecurityInfo EXPORTED
1688 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName
,
1689 SE_OBJECT_TYPE ObjectType
,
1690 SECURITY_INFORMATION SecurityInfo
,
1696 FN_PROGRESSW fnProgress
,
1697 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1701 return ERROR_CALL_NOT_IMPLEMENTED
;
1706 DllMain(IN HINSTANCE hinstDLL
,
1708 IN LPVOID lpvReserved
)
1712 case DLL_PROCESS_ATTACH
:
1713 hDllInstance
= hinstDLL
;
1714 DisableThreadLibraryCalls(hinstDLL
);
1717 case DLL_PROCESS_DETACH
: