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>
33 HINSTANCE hDllInstance
;
36 AccpGetAceAccessMode(IN PACE_HEADER AceHeader
)
38 ACCESS_MODE Mode
= NOT_USED_ACCESS
;
40 switch (AceHeader
->AceType
)
42 case ACCESS_ALLOWED_ACE_TYPE
:
43 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
44 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
45 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
49 case ACCESS_DENIED_ACE_TYPE
:
50 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
51 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
52 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
56 case SYSTEM_AUDIT_ACE_TYPE
:
57 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE
:
58 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
59 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
60 if (AceHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
)
61 Mode
= SET_AUDIT_FAILURE
;
62 else if (AceHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
63 Mode
= SET_AUDIT_SUCCESS
;
71 AccpGetAceStructureSize(IN PACE_HEADER AceHeader
)
75 switch (AceHeader
->AceType
)
77 case ACCESS_ALLOWED_ACE_TYPE
:
78 case ACCESS_DENIED_ACE_TYPE
:
79 Size
= FIELD_OFFSET(ACCESS_ALLOWED_ACE
,
82 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
83 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
84 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE
,
87 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
88 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
90 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
91 Size
= FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
,
93 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
94 Size
+= sizeof(Ace
->ObjectType
);
95 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
96 Size
+= sizeof(Ace
->InheritedObjectType
);
99 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
100 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
102 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
103 Size
= FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE
,
105 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
106 Size
+= sizeof(Ace
->ObjectType
);
107 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
108 Size
+= sizeof(Ace
->InheritedObjectType
);
112 case SYSTEM_AUDIT_ACE_TYPE
:
113 Size
= FIELD_OFFSET(SYSTEM_AUDIT_ACE
,
116 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE
:
117 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE
,
120 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
122 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
123 Size
= FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE
,
125 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
126 Size
+= sizeof(Ace
->ObjectType
);
127 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
128 Size
+= sizeof(Ace
->InheritedObjectType
);
131 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
133 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
134 Size
= FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE
,
136 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
137 Size
+= sizeof(Ace
->ObjectType
);
138 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
139 Size
+= sizeof(Ace
->InheritedObjectType
);
143 case SYSTEM_MANDATORY_LABEL_ACE_TYPE
:
144 Size
= FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE
,
153 AccpGetAceSid(IN PACE_HEADER AceHeader
)
155 return (PSID
)((ULONG_PTR
)AceHeader
+ AccpGetAceStructureSize(AceHeader
));
159 AccpGetAceAccessMask(IN PACE_HEADER AceHeader
)
161 return *((PACCESS_MASK
)(AceHeader
+ 1));
165 AccpIsObjectAce(IN PACE_HEADER AceHeader
)
169 switch (AceHeader
->AceType
)
171 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
172 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
173 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
174 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
175 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
176 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
189 AccpGetTrusteeObjects(IN PTRUSTEE_W Trustee
,
190 OUT GUID
*pObjectTypeGuid OPTIONAL
,
191 OUT GUID
*pInheritedObjectTypeGuid OPTIONAL
)
195 switch (Trustee
->TrusteeForm
)
197 case TRUSTEE_IS_OBJECTS_AND_NAME
:
199 POBJECTS_AND_NAME_W pOan
= (POBJECTS_AND_NAME_W
)Trustee
->ptstrName
;
201 /* pOan->ObjectsPresent should always be 0 here because a previous
202 call to AccpGetTrusteeSid should have rejected these trustees
204 ASSERT(pOan
->ObjectsPresent
== 0);
206 Ret
= pOan
->ObjectsPresent
;
210 case TRUSTEE_IS_OBJECTS_AND_SID
:
212 POBJECTS_AND_SID pOas
= (POBJECTS_AND_SID
)Trustee
->ptstrName
;
214 if (pObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
215 *pObjectTypeGuid
= pOas
->ObjectTypeGuid
;
217 if (pInheritedObjectTypeGuid
!= NULL
&& pOas
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
218 *pObjectTypeGuid
= pOas
->InheritedObjectTypeGuid
;
220 Ret
= pOas
->ObjectsPresent
;
225 /* Any other trustee forms have no objects attached... */
234 AccpCalcNeededAceSize(IN PSID Sid
,
235 IN DWORD ObjectsPresent
)
239 Ret
= sizeof(ACE
) + GetLengthSid(Sid
);
241 /* This routine calculates the generic size of the ACE needed.
242 If no objects are present it is assumed that only a standard
243 ACE is to be created. */
245 if (ObjectsPresent
& ACE_OBJECT_TYPE_PRESENT
)
247 if (ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
250 if (ObjectsPresent
!= 0)
251 Ret
+= sizeof(DWORD
); /* Include the Flags member to make it an object ACE */
257 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader
)
259 GUID
*ObjectType
= NULL
;
261 switch (AceHeader
->AceType
)
263 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
264 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
266 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
267 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
268 ObjectType
= &Ace
->ObjectType
;
271 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
272 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
274 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
275 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
276 ObjectType
= &Ace
->ObjectType
;
280 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
282 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
283 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
284 ObjectType
= &Ace
->ObjectType
;
287 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
289 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
290 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
291 ObjectType
= &Ace
->ObjectType
;
300 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader
)
302 GUID
*ObjectType
= NULL
;
304 switch (AceHeader
->AceType
)
306 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
307 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
309 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace
= (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
;
310 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
312 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
313 ObjectType
= &Ace
->InheritedObjectType
;
315 ObjectType
= &Ace
->ObjectType
;
319 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
320 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
322 PACCESS_ALLOWED_OBJECT_ACE Ace
= (PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
;
323 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
325 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
326 ObjectType
= &Ace
->InheritedObjectType
;
328 ObjectType
= &Ace
->ObjectType
;
333 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
335 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE
)AceHeader
;
336 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
338 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
339 ObjectType
= &Ace
->InheritedObjectType
;
341 ObjectType
= &Ace
->ObjectType
;
345 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
347 PSYSTEM_AUDIT_OBJECT_ACE Ace
= (PSYSTEM_AUDIT_OBJECT_ACE
)AceHeader
;
348 if (Ace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
350 if (Ace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
351 ObjectType
= &Ace
->InheritedObjectType
;
353 ObjectType
= &Ace
->ObjectType
;
363 AccpOpenLSAPolicyHandle(IN LPWSTR SystemName
,
364 IN ACCESS_MASK DesiredAccess
,
365 OUT PLSA_HANDLE pPolicyHandle
)
367 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes
= {0};
368 LSA_UNICODE_STRING LsaSystemName
, *psn
;
371 if (SystemName
!= NULL
&& SystemName
[0] != L
'\0')
373 LsaSystemName
.Buffer
= SystemName
;
374 LsaSystemName
.Length
= wcslen(SystemName
) * sizeof(WCHAR
);
375 LsaSystemName
.MaximumLength
= LsaSystemName
.Length
+ sizeof(WCHAR
);
376 psn
= &LsaSystemName
;
383 Status
= LsaOpenPolicy(psn
,
384 &LsaObjectAttributes
,
387 if (!NT_SUCCESS(Status
))
388 return LsaNtStatusToWinError(Status
);
390 return ERROR_SUCCESS
;
394 AccpGetTrusteeName(IN PTRUSTEE_W Trustee
)
396 switch (Trustee
->TrusteeForm
)
398 case TRUSTEE_IS_NAME
:
399 return Trustee
->ptstrName
;
401 case TRUSTEE_IS_OBJECTS_AND_NAME
:
402 return ((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ptstrName
;
410 AccpLookupSidByName(IN LSA_HANDLE PolicyHandle
,
415 LSA_UNICODE_STRING LsaNames
[1];
416 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains
= NULL
;
417 PLSA_TRANSLATED_SID2 TranslatedSid
= NULL
;
419 DWORD Ret
= ERROR_SUCCESS
;
421 LsaNames
[0].Buffer
= Name
;
422 LsaNames
[0].Length
= wcslen(Name
) * sizeof(WCHAR
);
423 LsaNames
[0].MaximumLength
= LsaNames
[0].Length
+ sizeof(WCHAR
);
425 Status
= LsaLookupNames2(PolicyHandle
,
427 sizeof(LsaNames
) / sizeof(LsaNames
[0]),
432 if (!NT_SUCCESS(Status
))
433 return LsaNtStatusToWinError(Status
);
435 if (TranslatedSid
->Use
== SidTypeUnknown
|| TranslatedSid
->Use
== SidTypeInvalid
)
437 Ret
= LsaNtStatusToWinError(STATUS_NONE_MAPPED
); /* FIXME- what error code? */
441 SidLen
= GetLengthSid(TranslatedSid
->Sid
);
444 *pSid
= LocalAlloc(LMEM_FIXED
, (SIZE_T
)SidLen
);
451 Ret
= GetLastError();
453 LocalFree((HLOCAL
)*pSid
);
458 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
461 LsaFreeMemory(ReferencedDomains
);
462 LsaFreeMemory(TranslatedSid
);
469 AccpGetTrusteeSid(IN PTRUSTEE_W Trustee
,
470 IN OUT PLSA_HANDLE pPolicyHandle
,
474 DWORD Ret
= ERROR_SUCCESS
;
479 if (Trustee
->pMultipleTrustee
|| Trustee
->MultipleTrusteeOperation
!= NO_MULTIPLE_TRUSTEE
)
481 /* This is currently not supported */
482 return ERROR_INVALID_PARAMETER
;
485 switch (Trustee
->TrusteeForm
)
487 case TRUSTEE_IS_OBJECTS_AND_NAME
:
488 if (((POBJECTS_AND_NAME_W
)Trustee
->ptstrName
)->ObjectsPresent
!= 0)
490 /* This is not supported as there is no way to interpret the
491 strings provided, and we need GUIDs for the ACEs... */
492 Ret
= ERROR_INVALID_PARAMETER
;
497 case TRUSTEE_IS_NAME
:
498 if (*pPolicyHandle
== NULL
)
500 Ret
= AccpOpenLSAPolicyHandle(NULL
, /* FIXME - always local? */
503 if (Ret
!= ERROR_SUCCESS
)
506 ASSERT(*pPolicyHandle
!= NULL
);
509 Ret
= AccpLookupSidByName(*pPolicyHandle
,
510 AccpGetTrusteeName(Trustee
),
512 if (Ret
== ERROR_SUCCESS
)
514 ASSERT(*ppSid
!= NULL
);
519 case TRUSTEE_IS_OBJECTS_AND_SID
:
520 *ppSid
= ((POBJECTS_AND_SID
)Trustee
->ptstrName
)->pSid
;
524 *ppSid
= (PSID
)Trustee
->ptstrName
;
528 Ret
= ERROR_INVALID_PARAMETER
;
536 /**********************************************************************
537 * AccRewriteGetHandleRights EXPORTED
542 AccRewriteGetHandleRights(HANDLE handle
,
543 SE_OBJECT_TYPE ObjectType
,
544 SECURITY_INFORMATION SecurityInfo
,
549 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
551 PSECURITY_DESCRIPTOR pSD
= NULL
;
557 /* save the last error code */
558 LastErr
= GetLastError();
564 /* allocate a buffer large enough to hold the
565 security descriptor we need to return */
569 pSD
= LocalAlloc(LMEM_FIXED
,
574 PSECURITY_DESCRIPTOR newSD
;
576 newSD
= LocalReAlloc((HLOCAL
)pSD
,
585 Ret
= GetLastError();
589 /* perform the actual query depending on the object type */
592 case SE_REGISTRY_KEY
:
594 Ret
= (DWORD
)RegGetKeySecurity((HKEY
)handle
,
602 /* FIXME - handle console handles? */
603 case SE_KERNEL_OBJECT
:
605 Status
= NtQuerySecurityObject(handle
,
610 if (!NT_SUCCESS(Status
))
612 Ret
= RtlNtStatusToDosError(Status
);
619 if (!QueryServiceObjectSecurity((SC_HANDLE
)handle
,
625 Ret
= GetLastError();
630 case SE_WINDOW_OBJECT
:
632 if (!GetUserObjectSecurity(handle
,
638 Ret
= GetLastError();
646 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
651 } while (Ret
== ERROR_INSUFFICIENT_BUFFER
);
653 if (Ret
== ERROR_SUCCESS
)
655 BOOL Present
, Defaulted
;
657 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
&& ppsidOwner
!= NULL
)
660 if (!GetSecurityDescriptorOwner(pSD
,
664 Ret
= GetLastError();
669 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
&& ppsidGroup
!= NULL
)
672 if (!GetSecurityDescriptorGroup(pSD
,
676 Ret
= GetLastError();
681 if (SecurityInfo
& DACL_SECURITY_INFORMATION
&& ppDacl
!= NULL
)
684 if (!GetSecurityDescriptorDacl(pSD
,
689 Ret
= GetLastError();
694 if (SecurityInfo
& SACL_SECURITY_INFORMATION
&& ppSacl
!= NULL
)
697 if (!GetSecurityDescriptorSacl(pSD
,
702 Ret
= GetLastError();
707 *ppSecurityDescriptor
= pSD
;
714 LocalFree((HLOCAL
)pSD
);
718 /* restore the last error code */
719 SetLastError(LastErr
);
725 /**********************************************************************
726 * AccRewriteSetHandleRights EXPORTED
731 AccRewriteSetHandleRights(HANDLE handle
,
732 SE_OBJECT_TYPE ObjectType
,
733 SECURITY_INFORMATION SecurityInfo
,
734 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
738 DWORD Ret
= ERROR_SUCCESS
;
740 /* save the last error code */
741 LastErr
= GetLastError();
743 /* set the security according to the object type */
746 case SE_REGISTRY_KEY
:
748 Ret
= (DWORD
)RegSetKeySecurity((HKEY
)handle
,
750 pSecurityDescriptor
);
755 /* FIXME - handle console handles? */
756 case SE_KERNEL_OBJECT
:
758 Status
= NtSetSecurityObject(handle
,
760 pSecurityDescriptor
);
761 if (!NT_SUCCESS(Status
))
763 Ret
= RtlNtStatusToDosError(Status
);
770 if (!SetServiceObjectSecurity((SC_HANDLE
)handle
,
772 pSecurityDescriptor
))
774 Ret
= GetLastError();
779 case SE_WINDOW_OBJECT
:
781 if (!SetUserObjectSecurity(handle
,
783 pSecurityDescriptor
))
785 Ret
= GetLastError();
793 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
799 /* restore the last error code */
800 SetLastError(LastErr
);
807 AccpOpenNamedObject(LPWSTR pObjectName
,
808 SE_OBJECT_TYPE ObjectType
,
809 SECURITY_INFORMATION SecurityInfo
,
816 ACCESS_MASK DesiredAccess
= (ACCESS_MASK
)0;
817 DWORD Ret
= ERROR_SUCCESS
;
819 /* determine the required access rights */
822 case SE_REGISTRY_KEY
:
824 case SE_KERNEL_OBJECT
:
826 case SE_WINDOW_OBJECT
:
829 SetSecurityAccessMask(SecurityInfo
,
830 (PDWORD
)&DesiredAccess
);
834 QuerySecurityAccessMask(SecurityInfo
,
835 (PDWORD
)&DesiredAccess
);
843 /* make a copy of the path if we're modifying the string */
846 case SE_REGISTRY_KEY
:
848 lpPath
= (LPWSTR
)LocalAlloc(LMEM_FIXED
,
849 (wcslen(pObjectName
) + 1) * sizeof(WCHAR
));
852 Ret
= GetLastError();
861 lpPath
= pObjectName
;
865 /* open a handle to the path depending on the object type */
870 IO_STATUS_BLOCK IoStatusBlock
;
871 OBJECT_ATTRIBUTES ObjectAttributes
;
872 UNICODE_STRING FileName
;
874 if (!RtlDosPathNameToNtPathName_U(pObjectName
,
879 Ret
= ERROR_INVALID_NAME
;
883 InitializeObjectAttributes(&ObjectAttributes
,
885 OBJ_CASE_INSENSITIVE
,
889 Status
= NtOpenFile(Handle
,
893 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
894 FILE_SYNCHRONOUS_IO_NONALERT
);
896 RtlFreeHeap(RtlGetProcessHeap(),
900 if (!NT_SUCCESS(Status
))
902 Ret
= RtlNtStatusToDosError(Status
);
907 case SE_REGISTRY_KEY
:
915 {HKEY_CLASSES_ROOT
, L
"CLASSES_ROOT"},
916 {HKEY_CURRENT_USER
, L
"CURRENT_USER"},
917 {HKEY_LOCAL_MACHINE
, L
"MACHINE"},
918 {HKEY_USERS
, L
"USERS"},
919 {HKEY_CURRENT_CONFIG
, L
"CONFIG"},
921 LPWSTR lpMachineName
, lpRootKeyName
, lpKeyName
;
922 HKEY hRootKey
= NULL
;
925 /* parse the registry path */
926 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
928 lpMachineName
= lpPath
;
930 lpRootKeyName
= wcschr(lpPath
+ 2,
932 if (lpRootKeyName
== NULL
)
935 *(lpRootKeyName
++) = L
'\0';
939 lpMachineName
= NULL
;
940 lpRootKeyName
= lpPath
;
943 lpKeyName
= wcschr(lpRootKeyName
,
945 if (lpKeyName
!= NULL
)
947 *(lpKeyName
++) = L
'\0';
951 i
!= sizeof(AccRegRootKeys
) / sizeof(AccRegRootKeys
[0]);
954 if (!wcsicmp(lpRootKeyName
,
955 AccRegRootKeys
[i
].szRootKey
))
957 hRootKey
= AccRegRootKeys
[i
].hRootKey
;
962 if (hRootKey
== NULL
)
965 /* FIXME - right error code? */
966 Ret
= ERROR_INVALID_PARAMETER
;
970 /* open the registry key */
971 if (lpMachineName
!= NULL
)
973 Ret
= RegConnectRegistry(lpMachineName
,
977 if (Ret
!= ERROR_SUCCESS
)
980 hRootKey
= (HKEY
)(*Handle2
);
983 Ret
= RegOpenKeyEx(hRootKey
,
986 (REGSAM
)DesiredAccess
,
988 if (Ret
!= ERROR_SUCCESS
)
990 if (*Handle2
!= NULL
)
992 RegCloseKey((HKEY
)(*Handle2
));
1002 LPWSTR lpServiceName
, lpMachineName
;
1004 /* parse the service path */
1005 if (lpPath
[0] == L
'\\' && lpPath
[1] == L
'\\')
1007 DesiredAccess
|= SC_MANAGER_CONNECT
;
1009 lpMachineName
= lpPath
;
1011 lpServiceName
= wcschr(lpPath
+ 2,
1013 if (lpServiceName
== NULL
)
1015 /* FIXME - right error code? */
1016 Ret
= ERROR_INVALID_PARAMETER
;
1020 *(lpServiceName
++) = L
'\0';
1024 lpMachineName
= NULL
;
1025 lpServiceName
= lpPath
;
1028 /* open the service */
1029 *Handle2
= (HANDLE
)OpenSCManager(lpMachineName
,
1031 (DWORD
)DesiredAccess
);
1032 if (*Handle2
== NULL
)
1034 goto FailOpenService
;
1037 DesiredAccess
&= ~SC_MANAGER_CONNECT
;
1038 *Handle
= (HANDLE
)OpenService((SC_HANDLE
)(*Handle2
),
1040 (DWORD
)DesiredAccess
);
1041 if (*Handle
== NULL
)
1043 if (*Handle2
!= NULL
)
1045 CloseServiceHandle((SC_HANDLE
)(*Handle2
));
1049 Ret
= GetLastError();
1058 Ret
= ERROR_CALL_NOT_IMPLEMENTED
;
1064 if (lpPath
!= NULL
&& lpPath
!= pObjectName
)
1066 LocalFree((HLOCAL
)lpPath
);
1074 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType
,
1078 ASSERT(Handle
!= NULL
);
1080 /* close allocated handlees depending on the object type */
1083 case SE_REGISTRY_KEY
:
1084 RegCloseKey((HKEY
)Handle
);
1085 if (Handle2
!= NULL
)
1086 RegCloseKey((HKEY
)Handle2
);
1089 case SE_FILE_OBJECT
:
1093 case SE_KERNEL_OBJECT
:
1094 case SE_WINDOW_OBJECT
:
1095 CloseHandle(Handle
);
1099 CloseServiceHandle((SC_HANDLE
)Handle
);
1100 ASSERT(Handle2
!= NULL
);
1101 CloseServiceHandle((SC_HANDLE
)Handle2
);
1110 /**********************************************************************
1111 * AccRewriteGetNamedRights EXPORTED
1116 AccRewriteGetNamedRights(LPWSTR pObjectName
,
1117 SE_OBJECT_TYPE ObjectType
,
1118 SECURITY_INFORMATION SecurityInfo
,
1123 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1125 HANDLE Handle
= NULL
;
1126 HANDLE Handle2
= NULL
;
1130 /* save the last error code */
1131 LastErr
= GetLastError();
1133 /* create the handle */
1134 Ret
= AccpOpenNamedObject(pObjectName
,
1141 if (Ret
== ERROR_SUCCESS
)
1143 ASSERT(Handle
!= NULL
);
1145 /* perform the operation */
1146 Ret
= AccRewriteGetHandleRights(Handle
,
1153 ppSecurityDescriptor
);
1155 /* close opened handles */
1156 AccpCloseObjectHandle(ObjectType
,
1161 /* restore the last error code */
1162 SetLastError(LastErr
);
1168 /**********************************************************************
1169 * AccRewriteSetNamedRights EXPORTED
1174 AccRewriteSetNamedRights(LPWSTR pObjectName
,
1175 SE_OBJECT_TYPE ObjectType
,
1176 SECURITY_INFORMATION SecurityInfo
,
1177 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1179 HANDLE Handle
= NULL
;
1180 HANDLE Handle2
= NULL
;
1184 /* save the last error code */
1185 LastErr
= GetLastError();
1187 /* create the handle */
1188 Ret
= AccpOpenNamedObject(pObjectName
,
1195 if (Ret
== ERROR_SUCCESS
)
1197 ASSERT(Handle
!= NULL
);
1199 /* perform the operation */
1200 Ret
= AccRewriteSetHandleRights(Handle
,
1203 pSecurityDescriptor
);
1205 /* close opened handles */
1206 AccpCloseObjectHandle(ObjectType
,
1211 /* restore the last error code */
1212 SetLastError(LastErr
);
1218 /**********************************************************************
1219 * AccRewriteSetEntriesInAcl EXPORTED
1224 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries
,
1225 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
1230 ACL_SIZE_INFORMATION SizeInformation
;
1232 BOOLEAN KeepAceBuf
[8];
1233 BOOLEAN
*pKeepAce
= NULL
;
1234 GUID ObjectTypeGuid
, InheritedObjectTypeGuid
;
1235 DWORD ObjectsPresent
;
1239 LSA_HANDLE PolicyHandle
= NULL
;
1242 DWORD Ret
= ERROR_SUCCESS
;
1244 /* save the last error code */
1245 LastErr
= GetLastError();
1249 /* Get information about previous ACL */
1252 if (!GetAclInformation(OldAcl
, &SizeInformation
, sizeof(ACL_SIZE_INFORMATION
), AclSizeInformation
))
1254 Ret
= GetLastError();
1258 if (SizeInformation
.AceCount
> sizeof(KeepAceBuf
) / sizeof(KeepAceBuf
[0]))
1260 pKeepAce
= (BOOLEAN
*)LocalAlloc(LMEM_FIXED
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1263 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1268 pKeepAce
= KeepAceBuf
;
1270 memset(pKeepAce
, TRUE
, SizeInformation
.AceCount
* sizeof(*pKeepAce
));
1274 ZeroMemory(&SizeInformation
, sizeof(ACL_SIZE_INFORMATION
));
1275 SizeInformation
.AclBytesInUse
= sizeof(ACL
);
1278 /* Get size required for new entries */
1279 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1281 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1285 if (Ret
!= ERROR_SUCCESS
)
1288 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1292 switch (pListOfExplicitEntries
[i
].grfAccessMode
)
1296 /* Discard all accesses for the trustee... */
1297 for (j
= 0; j
< SizeInformation
.AceCount
; j
++)
1301 if (!GetAce(OldAcl
, j
, (PVOID
*)&pAce
))
1303 Ret
= GetLastError();
1307 pSid2
= AccpGetAceSid(pAce
);
1308 if (RtlEqualSid(pSid1
, pSid2
))
1310 pKeepAce
[j
] = FALSE
;
1311 SizeInformation
.AclBytesInUse
-= pAce
->AceSize
;
1314 if (pListOfExplicitEntries
[i
].grfAccessMode
== REVOKE_ACCESS
)
1316 /* ...and replace by the current access */
1320 SizeInformation
.AclBytesInUse
+= AccpCalcNeededAceSize(pSid1
, ObjectsPresent
);
1322 case SET_AUDIT_SUCCESS
:
1323 case SET_AUDIT_FAILURE
:
1325 DPRINT1("Case not implemented!\n");
1328 DPRINT1("Unknown access mode 0x%x. Ignoring it\n", pListOfExplicitEntries
[i
].grfAccessMode
);
1333 LocalFree((HLOCAL
)pSid1
);
1336 /* OK, now create the new ACL */
1337 DPRINT("Allocating %u bytes for the new ACL\n", SizeInformation
.AclBytesInUse
);
1338 pNew
= (PACL
)LocalAlloc(LMEM_FIXED
, SizeInformation
.AclBytesInUse
);
1341 Ret
= ERROR_NOT_ENOUGH_MEMORY
;
1344 if (!InitializeAcl(pNew
, SizeInformation
.AclBytesInUse
, ACL_REVISION
))
1346 Ret
= GetLastError();
1351 /* 1a) New audit entries (SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE) */
1354 /* 1b) Existing audit entries */
1357 /* 2a) New denied entries (DENY_ACCESS) */
1358 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1360 if (pListOfExplicitEntries
[i
].grfAccessMode
== DENY_ACCESS
)
1362 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1363 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1367 if (Ret
!= ERROR_SUCCESS
)
1370 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1372 &InheritedObjectTypeGuid
);
1374 if (ObjectsPresent
== 0)
1376 /* FIXME: Call AddAccessDeniedAceEx instead! */
1377 bRet
= AddAccessDeniedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1381 /* FIXME: Call AddAccessDeniedObjectAce */
1382 DPRINT1("Object ACEs not yet supported!\n");
1383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1387 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1390 Ret
= GetLastError();
1396 /* 2b) Existing denied entries */
1399 /* 3a) New allow entries (GRANT_ACCESS, SET_ACCESS) */
1400 for (i
= 0; i
< cCountOfExplicitEntries
; i
++)
1402 if (pListOfExplicitEntries
[i
].grfAccessMode
== SET_ACCESS
||
1403 pListOfExplicitEntries
[i
].grfAccessMode
== GRANT_ACCESS
)
1405 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */
1406 Ret
= AccpGetTrusteeSid(&pListOfExplicitEntries
[i
].Trustee
,
1410 if (Ret
!= ERROR_SUCCESS
)
1413 ObjectsPresent
= AccpGetTrusteeObjects(&pListOfExplicitEntries
[i
].Trustee
,
1415 &InheritedObjectTypeGuid
);
1417 if (ObjectsPresent
== 0)
1419 /* FIXME: Call AddAccessAllowedAceEx instead! */
1420 bRet
= AddAccessAllowedAce(pNew
, ACL_REVISION
, pListOfExplicitEntries
[i
].grfAccessPermissions
, pSid1
);
1424 /* FIXME: Call AddAccessAllowedObjectAce */
1425 DPRINT1("Object ACEs not yet supported!\n");
1426 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1430 if (needToClean
) LocalFree((HLOCAL
)pSid1
);
1433 Ret
= GetLastError();
1439 /* 3b) Existing allow entries */
1445 if (pKeepAce
&& pKeepAce
!= KeepAceBuf
)
1446 LocalFree((HLOCAL
)pKeepAce
);
1448 if (pNew
&& Ret
!= ERROR_SUCCESS
)
1449 LocalFree((HLOCAL
)pNew
);
1452 LsaClose(PolicyHandle
);
1454 /* restore the last error code */
1455 SetLastError(LastErr
);
1461 /**********************************************************************
1462 * AccGetInheritanceSource EXPORTED
1467 AccGetInheritanceSource(LPWSTR pObjectName
,
1468 SE_OBJECT_TYPE ObjectType
,
1469 SECURITY_INFORMATION SecurityInfo
,
1471 GUID
** pObjectClassGuids
,
1474 PFN_OBJECT_MGR_FUNCTS pfnArray
,
1475 PGENERIC_MAPPING pGenericMapping
,
1476 PINHERITED_FROMW pInheritArray
)
1479 return ERROR_CALL_NOT_IMPLEMENTED
;
1483 /**********************************************************************
1484 * AccFreeIndexArray EXPORTED
1489 AccFreeIndexArray(PINHERITED_FROMW pInheritArray
,
1491 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
1493 PINHERITED_FROMW pLast
;
1495 UNREFERENCED_PARAMETER(pfnArray
);
1497 pLast
= pInheritArray
+ AceCnt
;
1498 while (pInheritArray
!= pLast
)
1500 if (pInheritArray
->AncestorName
!= NULL
)
1502 LocalFree((HLOCAL
)pInheritArray
->AncestorName
);
1503 pInheritArray
->AncestorName
= NULL
;
1509 return ERROR_SUCCESS
;
1513 /**********************************************************************
1514 * AccRewriteGetExplicitEntriesFromAcl EXPORTED
1519 AccRewriteGetExplicitEntriesFromAcl(PACL pacl
,
1520 PULONG pcCountOfExplicitEntries
,
1521 PEXPLICIT_ACCESS_W
* pListOfExplicitEntries
)
1523 PACE_HEADER AceHeader
;
1524 PSID Sid
, SidTarget
;
1525 ULONG ObjectAceCount
= 0;
1526 POBJECTS_AND_SID ObjSid
;
1528 PEXPLICIT_ACCESS_W peaw
;
1529 DWORD LastErr
, SidLen
;
1531 DWORD ErrorCode
= ERROR_SUCCESS
;
1533 /* save the last error code */
1534 LastErr
= GetLastError();
1538 if (pacl
->AceCount
!= 0)
1540 Size
= (SIZE_T
)pacl
->AceCount
* sizeof(EXPLICIT_ACCESS_W
);
1542 /* calculate the space needed */
1545 (LPVOID
*)&AceHeader
))
1547 Sid
= AccpGetAceSid(AceHeader
);
1548 Size
+= GetLengthSid(Sid
);
1550 if (AccpIsObjectAce(AceHeader
))
1556 Size
+= ObjectAceCount
* sizeof(OBJECTS_AND_SID
);
1558 ASSERT(pacl
->AceCount
== AceIndex
);
1560 /* allocate the array */
1561 peaw
= (PEXPLICIT_ACCESS_W
)LocalAlloc(LMEM_FIXED
,
1566 ObjSid
= (POBJECTS_AND_SID
)(peaw
+ pacl
->AceCount
);
1567 SidTarget
= (PSID
)(ObjSid
+ ObjectAceCount
);
1569 /* initialize the array */
1572 (LPVOID
*)&AceHeader
))
1574 Sid
= AccpGetAceSid(AceHeader
);
1575 SidLen
= GetLengthSid(Sid
);
1577 peaw
[AceIndex
].grfAccessPermissions
= AccpGetAceAccessMask(AceHeader
);
1578 peaw
[AceIndex
].grfAccessMode
= AccpGetAceAccessMode(AceHeader
);
1579 peaw
[AceIndex
].grfInheritance
= AceHeader
->AceFlags
& VALID_INHERIT_FLAGS
;
1585 if (AccpIsObjectAce(AceHeader
))
1587 BuildTrusteeWithObjectsAndSid(&peaw
[AceIndex
].Trustee
,
1589 AccpGetObjectAceObjectType(AceHeader
),
1590 AccpGetObjectAceInheritedObjectType(AceHeader
),
1595 BuildTrusteeWithSid(&peaw
[AceIndex
].Trustee
,
1599 SidTarget
= (PSID
)((ULONG_PTR
)SidTarget
+ SidLen
);
1603 /* copying the SID failed, treat it as an fatal error... */
1604 ErrorCode
= GetLastError();
1606 /* free allocated resources */
1616 *pcCountOfExplicitEntries
= AceIndex
;
1617 *pListOfExplicitEntries
= peaw
;
1620 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1630 *pcCountOfExplicitEntries
= 0;
1631 *pListOfExplicitEntries
= NULL
;
1634 /* restore the last error code */
1635 SetLastError(LastErr
);
1641 /**********************************************************************
1642 * AccTreeResetNamedSecurityInfo EXPORTED
1647 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName
,
1648 SE_OBJECT_TYPE ObjectType
,
1649 SECURITY_INFORMATION SecurityInfo
,
1655 FN_PROGRESSW fnProgress
,
1656 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1660 return ERROR_CALL_NOT_IMPLEMENTED
;
1665 DllMain(IN HINSTANCE hinstDLL
,
1667 IN LPVOID lpvReserved
)
1671 case DLL_PROCESS_ATTACH
:
1672 hDllInstance
= hinstDLL
;
1673 DisableThreadLibraryCalls(hinstDLL
);
1676 case DLL_PROCESS_DETACH
: