Code: Select all
Structure SID
Revision.b
SubAuthorityCount.b
*IdentifierAuthority.SID_IDENTIFIER_AUTHORITY
SubAuthority.l[#ANYSIZE_ARRAY]
EndStructure
Enumeration ;ACL_INFORMATION_CLASS
#AclRevisionInformation = 1
#AclSizeInformation
EndEnumeration
Enumeration ; SID_NAME_USE
#SidTypeUser = 1
#SidTypeGroup
#SidTypeDomain
#SidTypeAlias
#SidTypeWellKnownGroup
#SidTypeDeletedAccount
#SidTypeInvalid
#SidTypeUnknown
#SidTypeComputer
#SidTypeLabel
EndEnumeration
#DACL_SECURITY_INFORMATION = $00000004 ; Include the discretionary access control List (DACL).
Procedure.q TopHiveKey(HiveKeyConvert$)
Protected HiveKeyx.q
If Right(HiveKeyConvert$, 1) = "\"
HiveKeyConvert$ = RemoveString(HiveKeyConvert$, "\", #PB_String_NoCase, Len(HiveKeyConvert$) - 1, 1)
EndIf
HiveKeya$=StringField(HiveKeyConvert$,1,"\")
HiveKeyTop$=UCase(HiveKeya$)
Select HiveKeyTop$
Case "HKEY_CLASSES_ROOT"
HiveKeyx = #HKEY_CLASSES_ROOT
Case "HKEY_CURRENT_USER"
HiveKeyx = #HKEY_CURRENT_USER
Case "HKEY_LOCAL_MACHINE"
HiveKeyx = #HKEY_LOCAL_MACHINE
Case "HKEY_USERS"
HiveKeyx = #HKEY_USERS
Case "HKEY_CURRENT_CONFIG"
HiveKeyx = #HKEY_CURRENT_CONFIG
Default
HiveKeyx = #Null
EndSelect
ProcedureReturn HiveKeyx
EndProcedure
Procedure.s KeyConvert(KeyToConvert$)
If Right(KeyToConvert$, 1) = "\"
KeyToConvert$ = RemoveString(KeyToConvert$, "\", #PB_String_NoCase, Len(KeyToConvert$) - 1, 1)
EndIf
GetBackSlash=FindString(KeyToConvert$,"\",1)
KeyNameX$=Right(KeyToConvert$,(Len(KeyToConvert$)-GetBackSlash))
If Left(KeyNameX$, 1) = "\"
KeyNameX$ = Right(KeyNameX$, Len(KeyNameX$) - 1)
EndIf
ProcedureReturn KeyNameX$
EndProcedure
Procedure.s Reg_EnumAccountKeyAccessPermission(Key.s, sel_out.i, sid_count.i)
Protected HiveKey.q, KeyName$, bRtnBool.b, FuncRet.i, retfunc.i, hKey.i
Protected *pSecDesc.SECURITY_DESCRIPTOR, *pDacl.ACL, *pAce.ACCESS_ALLOWED_ACE, aclSize.ACL_SIZE_INFORMATION
Protected szAccountName.s, szDomainName.s, dwAccountNameSize.i, dwDomainNameSize.i, snu.i
Protected bDaclDefault.b, bDaclPresent.b, nLengthNeeded.l = 0, aclAceCount.i, acl_ACECount.i
HiveKey = TopHiveKey(Key)
KeyName$ = KeyConvert(Key)
FuncRet = RegOpenKeyEx_(HiveKey, @KeyName$, 0, #KEY_ALL_ACCESS, @hKey)
If FuncRet = #ERROR_SUCCESS
retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION, #Null, @nLengthNeeded)
If retfunc = #ERROR_INSUFFICIENT_BUFFER
*pSecDesc = LocalAlloc_(#LPTR, nLengthNeeded) ; can't use LocalAlloc in final - swap for heap function in final
If *pSecDesc = #Null
ProcedureReturn ""
EndIf
retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION, *pSecDesc, @nLengthNeeded)
EndIf
If retfunc = #ERROR_SUCCESS
If *pSecDesc
GetSecurityDescriptorDacl_(*pSecDesc, @bDaclPresent, @*pDacl, @bDaclDefault)
If bDaclPresent = 0
RegCloseKey_(hKey)
ProcedureReturn "No DACL"
Else
GetAclInformation_(*pDacl, @aclSize, SizeOf(aclSize), #AclSizeInformation)
If sel_out = 0
acl_ACECount = aclSize\AceCount
LocalFree_(*pSecDesc); can't use LocalFree in final - swap for heap function in final
RegCloseKey_(hKey)
EndIf
If sel_out > 0 And sel_out < 4
;For aclAceCount = 0 To aclSize\AceCount
GetAce_(*pDacl, sid_count, @*pAce)
bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @snu)
szAccountName = Space(dwAccountNameSize)
szDomainName = Space(dwDomainNameSize)
bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @snu)
; If-EndIf section below to be replaced by array later
; Specific Access Rights
If *pAce\Mask & #KEY_QUERY_VALUE = #KEY_QUERY_VALUE
SpecificAcess$ + "KEY_QUERY_VALUE - "
If *pAce\Mask & #KEY_SET_VALUE = #KEY_SET_VALUE
SpecificAcess$ + "KEY_SET_VALUE - "
If *pAce\Mask & #KEY_CREATE_SUB_KEY = #KEY_CREATE_SUB_KEY
SpecificAcess$ + "KEY_CREATE_SUB_KEY - "
If *pAce\Mask & #KEY_ENUMERATE_SUB_KEYS = #KEY_ENUMERATE_SUB_KEYS
SpecificAcess$ + "KEY_ENUMERATE_SUB_KEYS - "
If *pAce\Mask & #KEY_NOTIFY = #KEY_NOTIFY
SpecificAcess$ + "KEY_NOTIFY - "
If *pAce\Mask & #KEY_CREATE_LINK = #KEY_CREATE_LINK
SpecificAcess$ + "KEY_CREATE_LINK - "
If *pAce\Mask & #KEY_READ = #KEY_READ
SpecificAcess$ + "KEY_READ - " ; ;KEY_EXECUTE (0x20019)
If *pAce\Mask & #KEY_WRITE = #KEY_WRITE
SpecificAcess$ + "KEY_WRITE - "
If *pAce\Mask & #KEY_EXECUTE = #KEY_EXECUTE
SpecificAcess$ + "KEY_EXECUTE - " ; same As KEY_READ (0x20019)
If *pAce\Mask & #KEY_ALL_ACCESS = #KEY_ALL_ACCESS
SpecificAcess$ + "KEY_ALL_ACCESS - "
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
SpecificAcess$ = RemoveString(SpecificAcess$, " - ", #PB_String_NoCase, Len(SpecificAcess$) - 3, 1) ; goes away later with string formatting
;Standard Access Rights
If *pAce\Mask & #DELETE = #DELETE
StandardAcess$ + "DELETE - "
If *pAce\Mask & #READ_CONTROL = #READ_CONTROL
StandardAcess$ + "READ_CONTROL - "
If *pAce\Mask & #WRITE_DAC = #WRITE_DAC
StandardAcess$ + "WRITE_DAC - "
If *pAce\Mask & #WRITE_OWNER = #WRITE_OWNER
StandardAcess$ + "WRITE_OWNER - "
If *pAce\Mask & #SYNCHRONIZE = #SYNCHRONIZE
StandardAcess$ + "SYNCHRONIZE - "
If *pAce\Mask & #STANDARD_RIGHTS_REQUIRED = #STANDARD_RIGHTS_REQUIRED
StandardAcess$ + "STANDARD_RIGHTS_REQUIRED - "
If *pAce\Mask & #STANDARD_RIGHTS_READ = #STANDARD_RIGHTS_READ
StandardAcess$ + "STANDARD_RIGHTS_READ - "
If *pAce\Mask & #STANDARD_RIGHTS_WRITE = #STANDARD_RIGHTS_WRITE
StandardAcess$ + "STANDARD_RIGHTS_WRITE - "
If *pAce\Mask & #STANDARD_RIGHTS_EXECUTE = #STANDARD_RIGHTS_EXECUTE
StandardAcess$ + "STANDARD_RIGHTS_EXECUTE - "
If *pAce\Mask & #STANDARD_RIGHTS_ALL = #STANDARD_RIGHTS_ALL
StandardAcess$ + "STANDARD_RIGHTS_ALL - "
If *pAce\Mask & #SPECIFIC_RIGHTS_ALL = #SPECIFIC_RIGHTS_ALL
StandardAcess$ + "SPECIFIC_RIGHTS_ALL - "
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
StandardAcess$ = RemoveString(StandardAcess$, " - ", #PB_String_NoCase, Len(StandardAcess$) - 3, 1); goes away later with string formatting
; ************* If-EndIf section above to be replaced by array later ********
; ************below not used this implementation - later use in framework
;Select snu
;Case #SidTypeUser
;sidtypeuse$ = "User SID"
;Case #SidTypeGroup
;sidtypeuse$ = "Group SID"
;Case #SidTypeDomain
;sidtypeuse$ = "Domain SID"
;Case #SidTypeAlias
;sidtypeuse$ = "Alias SID"
;Case #SidTypeWellKnownGroup
;sidtypeuse$ = "SID for a well-known group"
;Case #SidTypeDeletedAccount
;sidtypeuse$ = "SID for a deleted account"
;Case #SidTypeInvalid
;sidtypeuse$ = "SID that is not valid"
;Case #SidTypeUnknown
;sidtypeuse$ = "SID of unknown type"
;Case #SidTypeComputer
;sidtypeuse$ = "SID for a computer"
;Case #SidTypeLabel
;sidtypeuse$ = "Mandatory integrity label SID"
;Default
;sidtypeuse$ = "SID of unknown type"
;EndSelect
;************** end section not used this implementation
Select *pAce\Header\AceType
Case #ACCESS_ALLOWED_ACE_TYPE
AceType$ = "ACCESS_ALLOWED_ACE_TYPE"
;Break
Case #ACCESS_DENIED_ACE_TYPE
AceType$ = "ACCESS_DENIED_ACE_TYPE"
;Break
Case #SYSTEM_AUDIT_ACE_TYPE
AceType$ = "SYSTEM_AUDIT_ACE_TYPE"
;Break
Default
AceType$ = "Unknown ACE type"
;Break
EndSelect
;Next aclAceCount
LocalFree_(*pSecDesc); can't use LocalFree in final - swap for heap function in final
RegCloseKey_(hKey)
EndIf
EndIf
EndIf
EndIf
EndIf
Select sel_out
Case 0
procret$ = Str(acl_ACECount)
Case 1
procret$ = "Account = " + szAccountName + " Domain = " + szDomainName + " Specific Access Rights = " + SpecificAcess$ ; specific access rights
Case 2
procret$ = "Account = " + szAccountName + " Domain = " + szDomainName + " Standard Access Rights = " + StandardAcess$ ; standard access rights
Case 3
procret$ = "Account = " + szAccountName + " Domain = " + szDomainName + " ACE Type = " + AceType$; ACE Type
Default ; just for form and in case
procret$ = "Invalid output selection."
EndSelect
ProcedureReturn procret$
EndProcedure
; Reg_EnumAccountKeyAccessPermission(Key.s, sel_out.i, sid_count.i)
; Where: Key.s is the registry key we want permissions for - sel_out is the return we want (see last select -endselect in code) - sid_count is the account we are getting information for (0 to max available)
; first, get the acl ace count to find the max number of accounts with DACL we can query
acecnt_max_available.i = Val(Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel\TestKey", 0, 0))
Debug "Maximum available accounts with DACL = " + Str(acecnt_max_available) ; the number of accounts - the first account starts at 0 and goes to the max 'acecnt' (max available)
Debug ""
; now the loop to enum
For i = 0 To acecnt_max_available - 1
Debug Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel", 1, i)
Debug ""
Debug Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel", 2, i)
Debug ""
Debug Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel", 3, i)
Debug ""
Next
; notice the rem'd out loop in the code, thats for putting the stuff in an array later - and removing the 'sid_count' parameter - not implemented yet