|
-
Jun 11th, 2001, 06:09 AM
#1
Thread Starter
New Member
Acess Control List Specification
Hello Friends
I was looking for API which gives me the access control to a set of NTFS objects. I came thru MSDN and found that there are some API namely GetSecurityInfo but i could not find declaration for this API in API Text Viewer.
If any one knows about which is the equivalent API for this GetSecurityInfo then let me know
-
Jun 11th, 2001, 08:34 AM
#2
If you want to read the NTFS access permissions for a file, I can post some code when I get home.
Tell me if this is what you want.
-
Jun 11th, 2001, 11:21 AM
#3
Add the following code to a .bas module.
Call the GetTokenSids function first, to get a list of the security identifiers in the users logon token.
Next call the GetFileRights function with three parameters.
The first parameter (in) is the path to the file to read the access rights from.
The Second parameter (out) will return the rights granted to the user on the specified file. This is a combination (Or'd together) of one or more of the File right constants (FILE_EXECUTE, FILE_READ_DATA etc)
The Third parameter (out) will return the rights denied to the user on the specified file.
To get the effective rights, combine them like this:
Effective_Rights = Granted And Not Denied
Code:
' Author: Frans Claessen
' Date : 11 juli 2000
' You are free to use this code in your projects
' as long as this comment is included.
Option Explicit
Private Const MAX_PATH = 260
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Const SE_FILE_OBJECT = 1&
Private Const DACL_SECURITY_INFORMATION = &H4&
Private Const READ_CONTROL = &H20000
Private Const FILE_READ_EA = &H8 ' file & directory
Private Const FILE_READ_ATTRIBUTES = &H80 ' all
Private Const FILE_READ_DATA = &H1 ' file & pipe
Private Const FILE_EXECUTE = &H20 ' file
Private Const F_READ = FILE_READ_DATA Or FILE_READ_ATTRIBUTES Or FILE_READ_EA Or READ_CONTROL
Public Const F_READ_EXECUTE = F_READ Or FILE_EXECUTE
Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const SECURITY_NT_AUTHORITY = &H5
Private Type Sid
bsid() As Byte
End Type
Private Const AclSizeInformation = 2& 'ACL size information
Private Type ACL_SIZE_INFORMATION
AceCount As Long
AclBytesInUse As Long
AclBytesFree As Long
End Type
Private Const ACCESS_ALLOWED_ACE_TYPE = 0
Private Const ACCESS_DENIED_ACE_TYPE = 1
Private Type ACE_HEADER
AceType As Byte
AceFlags As Byte
AceSize As Integer
End Type
Private Type ACCESS_ALLOWED_ACE
Header As ACE_HEADER
Mask As Long
SidStart As Long
End Type
Private Type SID_AND_ATTRIBUTES
Sid As Long
Attributes As Long
End Type
Private Const ANYSIZE_ARRAY = 20
Private Type TOKEN_GROUPS
GroupCount As Long
Groups(ANYSIZE_ARRAY) As SID_AND_ATTRIBUTES
End Type
Private Type TOKEN_USER
User As SID_AND_ATTRIBUTES
End Type
Private Type SID_IDENTIFIER_AUTHORITY
Value(0 To 5) As Byte
End Type
Private Const TokenUser = 1&
Private Const TokenGroups = 2&
Private Const TOKEN_QUERY = &H8
Private Const SE_GROUP_MANDATORY = &H1&
Private Const SE_GROUP_ENABLED_BY_DEFAULT = &H2&
Private Const SE_GROUP_ENABLED = &H4&
Private Const SE_GROUP_OWNER = &H8&
Private Const SE_GROUP_USE_FOR_DENY_ONLY = &H10&
Private Const SE_GROUP_LOGON_ID = &HC0000000
Private Const SECURITY_BUILTIN_DOMAIN_RID = &H20
Private Const DOMAIN_ALIAS_RID_ADMINS = &H220&
Private Const DOMAIN_GROUP_RID_ADMINS = &H200&
Private Const DOMAIN_USER_RID_ADMIN = &H1F4&
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (pTo As Any, uFrom As Any, ByVal lSize As Long)
Private Declare Function EqualSid Lib "advapi32.dll" (pSid1 As Any, pSid2 As Any) As Long
Private Declare Function GetFileSecurity Lib "advapi32.dll" Alias "GetFileSecurityA" (ByVal lpFileName As String, ByVal RequestedInformation As Long, pSecurityDescriptor As Byte, ByVal nLength As Long, lpnLengthNeeded As Long) As Long
Private Declare Function GetSecurityDescriptorDacl Lib "advapi32.dll" (pSecurityDescriptor As Byte, lpbDaclPresent As Long, pDacl As Long, lpbDaclDefaulted As Long) As Long
Private Declare Function GetAclInformation Lib "advapi32.dll" (pAcl As Long, pAclInformation As ACL_SIZE_INFORMATION, ByVal nAclInformationLength As Long, ByVal dwAclInformationClass As Long) As Long
Private Declare Function GetAce Lib "advapi32.dll" (pAcl As Long, ByVal dwAceIndex As Long, pAce As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetTokenInformation Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) As Long
Private Declare Function IsValidSid Lib "advapi32.dll" (ByVal pSid As Long) As Long
Private Declare Function GetLengthSid Lib "advapi32.dll" (ByVal pSid As Long) As Long
Private Declare Sub FreeSid Lib "Advapi32" (pSid As Any)
Private Declare Function AllocateAndInitializeSid Lib "Advapi32" _
(pIdentifierAuthority As SID_IDENTIFIER_AUTHORITY, _
ByVal nSubAuthorityCount As Byte, ByVal nSubAuthority0 As Long, _
ByVal nSubAuthority1 As Long, ByVal nSubAuthority2 As Long, _
ByVal nSubAuthority3 As Long, ByVal nSubAuthority4 As Long, _
ByVal nSubAuthority5 As Long, ByVal nSubAuthority6 As Long, _
ByVal nSubAuthority7 As Long, lpPSid As Long) As Long
Private TokenSids() As Sid
Private sidCount As Integer
Public Function GetTokenSids() As Boolean
Dim retVal As Long
Dim hToken As Long
Dim Success As Boolean
Dim Token() As Byte
Dim Leng As Long
Dim LengNeeded As Long
Dim Attributes As Long
Dim tUser As TOKEN_USER
Dim tGroups As TOKEN_GROUPS
Dim AddIt As Boolean
Dim psidAdmin As Long
Dim tpSidAuth As SID_IDENTIFIER_AUTHORITY
Dim i As Integer
Dim AdminAdded As Boolean
'UseAdminRights = False
AdminAdded = False
tpSidAuth.Value(5) = SECURITY_NT_AUTHORITY
Success = False
sidCount = 0
Erase TokenSids
retVal = OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hToken)
If retVal <> 0 Then
' first get the user sid
Leng = 1
ReDim Token(0)
' this should fail, because the buffer is to small
retVal = GetTokenInformation(hToken, TokenUser, Token(0), Leng, LengNeeded)
If retVal = 0 Then
Leng = LengNeeded
ReDim Token(Leng - 1)
' now it should succeed
retVal = GetTokenInformation(hToken, TokenUser, Token(0), Leng, LengNeeded)
If retVal <> 0 Then
' copy the first 8 bytes to the TOKEN_USER structure.
Call CopyMem(tUser, Token(0), Len(tUser))
' we have a pointer to the sid in the TOKEN_USER
' first check is the sid is valid
retVal = IsValidSid(tUser.User.Sid)
' now get the length
retVal = GetLengthSid(tUser.User.Sid)
' initialize the sidcount, redim the sids, and copy the sid to our sid array
sidCount = 1
ReDim TokenSids(0)
ReDim TokenSids(0).bsid(retVal - 1)
Call CopyMem(TokenSids(0).bsid(0), ByVal tUser.User.Sid, retVal)
' assume this all succeeded
Success = True
End If
End If
' now create an admin sid, so we can compare it with the sids in the groups we find later
retVal = AllocateAndInitializeSid(tpSidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, _
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdmin)
If IsValidSid(psidAdmin) Then
AdminAdded = True
End If
' ok, now get the groups
Leng = 1
ReDim Token(0)
' this should fail, because the buffer is to small
retVal = GetTokenInformation(hToken, TokenGroups, Token(0), Leng, LengNeeded)
If retVal = 0 Then
Leng = LengNeeded
ReDim Token(Leng - 1)
' now it should succeed
retVal = GetTokenInformation(hToken, TokenGroups, Token(0), Leng, LengNeeded)
If retVal <> 0 Then
' do some magic stuff
Call CopyMem(tGroups, Token(0), Len(tGroups))
' now loop through the group sids
For i = 0 To tGroups.GroupCount - 1
' check if the sid is valid
If IsValidSid(tGroups.Groups(i).Sid) Then
If (tGroups.Groups(i).Attributes And SE_GROUP_ENABLED) = SE_GROUP_ENABLED Then
AddIt = True
' if we succeeded in creating the admin sid, we check if the group sid is an admin sid
If AdminAdded Then
If EqualSid(ByVal tGroups.Groups(i).Sid, ByVal psidAdmin) Then
AddIt = MsgBox("Hey, you're an admin !!" & vbCrLf & "Who thought of that." & vbCrLf & "Do you want to use your admin rights?", vbYesNo + vbQuestion) = vbYes
End If
End If
If AddIt Then
' get the length
retVal = GetLengthSid(tGroups.Groups(i).Sid)
sidCount = sidCount + 1
ReDim Preserve TokenSids(sidCount - 1)
ReDim TokenSids(sidCount - 1).bsid(retVal - 1)
Call CopyMem(TokenSids(sidCount - 1).bsid(0), ByVal tGroups.Groups(i).Sid, retVal)
' assume this all succeeded
Success = True
End If
End If
End If
Next
End If
End If
End If
If psidAdmin Then Call FreeSid(psidAdmin)
GetTokenSids = Success
End Function
The post was too long, so I had to split it. Add the code of the next post to the .bas module.
-
Jun 11th, 2001, 11:23 AM
#4
OK, here is the second part. Add it to the same bas module as the previous post.
Code:
Public Sub GetFileRights(ByVal sPath As String, ByRef Granted As Long, ByRef Denied As Long)
Dim i As Long
Dim j As Long
Dim Leng As Long
Dim LengNeeded As Long
Dim SD() As Byte
Dim retVal As Long
Dim DaclPresent As Long
Dim DaclDefaulted As Long
Dim DaclPtr As Long
Dim AcePtr As Long
Dim AclInformation As ACL_SIZE_INFORMATION
Dim aceHeader As ACE_HEADER
Dim Ace As ACCESS_ALLOWED_ACE
ReDim SD(0)
Leng = 1
Granted = 0
Denied = 0
' now attempt to get the security descriptor, we want to get the DACL (discretionary access control list) for the file
retVal = GetFileSecurity(sPath, DACL_SECURITY_INFORMATION, SD(0), Leng, LengNeeded)
If retVal = 0 And LengNeeded > 0 Then
' now we now how big the buffer should be
ReDim SD(LengNeeded)
Leng = LengNeeded
' now it should work
retVal = GetFileSecurity(sPath, DACL_SECURITY_INFORMATION, SD(0), Leng, LengNeeded)
If retVal <> 0 Then
' we have the SD in the array, now we need to now were the DACL starts
retVal = GetSecurityDescriptorDacl(SD(0), DaclPresent, DaclPtr, DaclDefaulted)
' check if dacl is present, and no null dacl
If CBool(DaclPresent) And DaclPtr <> 0 Then
' now get the acl information
retVal = GetAclInformation(ByVal DaclPtr, AclInformation, Len(AclInformation), AclSizeInformation)
' we now know the number of ace's (access control entries) in the acl
' loop through the aces
For i = 0 To AclInformation.AceCount - 1
' find out were the ace starts
retVal = GetAce(ByVal DaclPtr, i, AcePtr)
If retVal <> 0 Then
' now we have a pointer to the start of the ace
Call CopyMem(Ace, ByVal AcePtr, Len(Ace))
' we now know the type of ace (allow or deny)
' we also get info about inheritance, this is not important for this purpose, the Rights are the same
' we also know the size of the ace
If Ace.Header.AceType = ACCESS_DENIED_ACE_TYPE Or Ace.Header.AceType = ACCESS_ALLOWED_ACE_TYPE Then
' ok we have an ace, now loop through the sids to check
For j = LBound(TokenSids) To UBound(TokenSids)
' check if the sid is the same as in the ace
' the sid starts 8 bytes after the start of the ace
retVal = EqualSid(ByVal (AcePtr + 8), TokenSids(j).bsid(0))
If CBool(retVal) Then
' we have a match
If Ace.Header.AceType = ACCESS_DENIED_ACE_TYPE Then
Denied = Denied Or Ace.Mask
Else
Granted = Granted Or Ace.Mask
End If
End If
Next j
End If
End If
Next i
Else
' no dacl found or a null dacl. All rights are granted
Denied = 0
Granted = &HFFFFFF
End If
Else
' function failed, so the user of this program probably not enough rights to read the dacl
' return no access granted, and also no access denied
Denied = 0
Granted = 0
End If
End If
End Sub
-
Jul 22nd, 2003, 04:19 AM
#5
Fanatic Member
Hi
Hi Can somebody please provide me the C equalent of the above.
Thanks,
Pradeep
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|