vbhelper
June 21st, 2001, 08:24 AM
[Question]
In the background described in the next section, in copying file, I would like to let a VB program control to set a permission to a specific account. How can I do this? As I described in the [Cause] section below, I think
LookupAccountName() is not enough for this purpose. If you know any other function which allows this purpose, or any other tuning way, please let me know.
[Development Background]
In order to prevent any file from being modified or refered illegally, I let a VB program set-up a specific acceess permission (such as Administrator) when copying file. We plan to have the environment where more than one NT domains are there and they are trusted each other.
[Problem]
Using the program introduced later, this program always sets a local machine Administrator instead of a specific domain Administrator. So it can not do this purpose. The VB program is used as it is in the program which is introduced in the following KB:
http://www.microsoft.com/JAPAN/support/kb/articles/J022/7/50.htm
[Cause]
It is due to the limitation of the LookupAccountName() function, which is used in the access permission setup program attached in the bottom.
The limitation is:
"Note that LookupAccountName() returns the SID of the first user or a group which matches the name given in plszUserName."
[Possibility of Backup]
The problem can be workaround temporary by using a unique user acount throughout multiple domains + local domains. However, many customers think that the account for administrator should be Administrator. So this workaround is not best.
[Function Program] '===========================================================================
===
' Function Name : change the file access permission (NTFS).
' Function Summary : change the file access permission to Full Control
only if it is the file owner.
' Call Type : ChangeACE(FileName)
' Parameter : Files which support FileName String (full path).
' Return Value : Boolean
'===========================================================================
===
public Function ChangeACE(byval FileName as string) as Boolean
Dim lResult as Long ' Result of various API calls.
Dim bUserSid(255) as Byte ' This will contain your SID.
Dim lLengthUserName as Long ' Max length of user name.
Dim sUserName as string * 255 ' string to hold the current user name.
Dim sDomainName as string * 255 ' Domain the user belongs to.
Dim lDomainNameLength as Long ' Length of domain name needed.
Dim lSIDType AsLong ' The type of SID info we are getting back.
Dim sFileSD as SECURITY_DESCRIPTOR ' SD of the file we want.
Dim bSDBuf() as Byte ' Buffer that holds the security descriptor for this file.
Dim lFileSDSize as Long ' Size of the File SD.
Dim lSizeNeeded as Long ' Size needed for SD for file.
Dim sNewSD as SECURITY_DESCRIPTOR ' new security descriptor.
Dim sACL as ACL ' Used in grabbing the DACL from the File SD.
Dim lDaclPresent as Long ' Used in grabbing the DACL from the File SD.
Dim lDaclDefaulted as Long ' Used in grabbing the DACL from the File SD.
Dim sACLInfo as ACL_SIZE_INFORMATION ' Used in grabbing the ACL from the File SD.
Dim pAcl as Long ' Current ACL for this file.
Dim lNewACLSize as Long ' Size of new ACL to create.
Dim bNewACL() as Byte ' Buffer to hold new ACL.Dim
sCurrentACE as ACCESS_ALLOWED_ACE ' Current ACE.
' ----- set Flag -----
ChangeACE = false
' ----- Retrieve the user name who is currently logged on -----
lLengthUserName = 255
sUserName = Space(lLengthUserName)
lResult = GetUserName(sUserName, lLengthUserName)
If (lResult = 0) then Exit Function
' ----- Retrieve the security id (SID) for the log-in user -----
lResult = LookupAccountName(vbNullString, sUserName, bUserSid(0), 255, _
sDomainName, lDomainNameLength,lSIDType)
sDomainName = Space(lDomainNameLength)
lResult = LookupAccountName(vbNullString, sUserName, bUserSid(0), 255, _
sDomainName, lDomainNameLength, lSIDType)
If (lResult = 0) then Exit Function
' ----- Retrieve the security information from the file specified by the parameter -----
lFileSDSize = len(sFileSD)
lResult = GetFileSecurityN(FileName, DACL_SECURITY_INFORMATION, 0, 0, lSizeNeeded)
ReDim bSDBuf(lSizeNeeded)
lResult = GetFileSecurity(FileName, DACL_SECURITY_INFORMATION,_ bSDBuf(0),lSizeNeeded,lSizeNeeded)
If (lResult = 0) then Exit Function
' ----- Newly create SECURITY_DESCRIPTOR -----
lResult = InitializeSecurityDescriptor(sNewSD,SECURITY_DESCRIPTOR_REVISION)
If (lResult = 0) then Exit Function' ----- Retrieve the ACL, DACL pointer from 'SECURITY_DESCRIPTOR -----
lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, pAcl,lDaclDefaulted)
If (lResult = 0) then Exit Function
If (lDaclPresent = false) then Exit Function
' ----- Retrieve the ACL information from SECURITY_DESCRIPTOR -----
lResult = GetAclInformation(pAcl, sACLInfo, len(sACLInfo),ACL_REVISION2)
If (lResult = 0) then Exit Function
' ----- Use the retrieved ACL information, calculate the ACL size to beupdated -----
lNewACLSize = sACLInfo.AclBytesInUse + len(sCurrentACE) + GetLengthSid(bUserSid(0)) - 4
ReDim bNewACL(lNewACLSize)
' ----- Create the ACL to be updated -----
lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION2)
If (lResult = 0) then Exit Function
' ----- Newly create an ACL if there is already DACL -----
If (lDaclPresent) then
If (sACLInfo.AceCount > 0) then
' ----- set permission to the new ACL -----
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION2, GENERIC_ALL, bUserSid(0))
If (lResult = 0) then Exit Function
' ----- set the ACL information to SECURITY_DESCRIPTOR -----
lResult = SetSecurityDescriptorDacl(sNewSD, 1, bNewACL(0), 0)
If (lResult = 0) then Exit Function
' ----- set the security information to the target file -----
lResult = SetFileSecurity(FileName, DACL_SECURITY_INFORMATION,sNewSD)
If (lResult = 0) then Exit Function
End If
End If
ChangeACE = true
End Function
In the background described in the next section, in copying file, I would like to let a VB program control to set a permission to a specific account. How can I do this? As I described in the [Cause] section below, I think
LookupAccountName() is not enough for this purpose. If you know any other function which allows this purpose, or any other tuning way, please let me know.
[Development Background]
In order to prevent any file from being modified or refered illegally, I let a VB program set-up a specific acceess permission (such as Administrator) when copying file. We plan to have the environment where more than one NT domains are there and they are trusted each other.
[Problem]
Using the program introduced later, this program always sets a local machine Administrator instead of a specific domain Administrator. So it can not do this purpose. The VB program is used as it is in the program which is introduced in the following KB:
http://www.microsoft.com/JAPAN/support/kb/articles/J022/7/50.htm
[Cause]
It is due to the limitation of the LookupAccountName() function, which is used in the access permission setup program attached in the bottom.
The limitation is:
"Note that LookupAccountName() returns the SID of the first user or a group which matches the name given in plszUserName."
[Possibility of Backup]
The problem can be workaround temporary by using a unique user acount throughout multiple domains + local domains. However, many customers think that the account for administrator should be Administrator. So this workaround is not best.
[Function Program] '===========================================================================
===
' Function Name : change the file access permission (NTFS).
' Function Summary : change the file access permission to Full Control
only if it is the file owner.
' Call Type : ChangeACE(FileName)
' Parameter : Files which support FileName String (full path).
' Return Value : Boolean
'===========================================================================
===
public Function ChangeACE(byval FileName as string) as Boolean
Dim lResult as Long ' Result of various API calls.
Dim bUserSid(255) as Byte ' This will contain your SID.
Dim lLengthUserName as Long ' Max length of user name.
Dim sUserName as string * 255 ' string to hold the current user name.
Dim sDomainName as string * 255 ' Domain the user belongs to.
Dim lDomainNameLength as Long ' Length of domain name needed.
Dim lSIDType AsLong ' The type of SID info we are getting back.
Dim sFileSD as SECURITY_DESCRIPTOR ' SD of the file we want.
Dim bSDBuf() as Byte ' Buffer that holds the security descriptor for this file.
Dim lFileSDSize as Long ' Size of the File SD.
Dim lSizeNeeded as Long ' Size needed for SD for file.
Dim sNewSD as SECURITY_DESCRIPTOR ' new security descriptor.
Dim sACL as ACL ' Used in grabbing the DACL from the File SD.
Dim lDaclPresent as Long ' Used in grabbing the DACL from the File SD.
Dim lDaclDefaulted as Long ' Used in grabbing the DACL from the File SD.
Dim sACLInfo as ACL_SIZE_INFORMATION ' Used in grabbing the ACL from the File SD.
Dim pAcl as Long ' Current ACL for this file.
Dim lNewACLSize as Long ' Size of new ACL to create.
Dim bNewACL() as Byte ' Buffer to hold new ACL.Dim
sCurrentACE as ACCESS_ALLOWED_ACE ' Current ACE.
' ----- set Flag -----
ChangeACE = false
' ----- Retrieve the user name who is currently logged on -----
lLengthUserName = 255
sUserName = Space(lLengthUserName)
lResult = GetUserName(sUserName, lLengthUserName)
If (lResult = 0) then Exit Function
' ----- Retrieve the security id (SID) for the log-in user -----
lResult = LookupAccountName(vbNullString, sUserName, bUserSid(0), 255, _
sDomainName, lDomainNameLength,lSIDType)
sDomainName = Space(lDomainNameLength)
lResult = LookupAccountName(vbNullString, sUserName, bUserSid(0), 255, _
sDomainName, lDomainNameLength, lSIDType)
If (lResult = 0) then Exit Function
' ----- Retrieve the security information from the file specified by the parameter -----
lFileSDSize = len(sFileSD)
lResult = GetFileSecurityN(FileName, DACL_SECURITY_INFORMATION, 0, 0, lSizeNeeded)
ReDim bSDBuf(lSizeNeeded)
lResult = GetFileSecurity(FileName, DACL_SECURITY_INFORMATION,_ bSDBuf(0),lSizeNeeded,lSizeNeeded)
If (lResult = 0) then Exit Function
' ----- Newly create SECURITY_DESCRIPTOR -----
lResult = InitializeSecurityDescriptor(sNewSD,SECURITY_DESCRIPTOR_REVISION)
If (lResult = 0) then Exit Function' ----- Retrieve the ACL, DACL pointer from 'SECURITY_DESCRIPTOR -----
lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, pAcl,lDaclDefaulted)
If (lResult = 0) then Exit Function
If (lDaclPresent = false) then Exit Function
' ----- Retrieve the ACL information from SECURITY_DESCRIPTOR -----
lResult = GetAclInformation(pAcl, sACLInfo, len(sACLInfo),ACL_REVISION2)
If (lResult = 0) then Exit Function
' ----- Use the retrieved ACL information, calculate the ACL size to beupdated -----
lNewACLSize = sACLInfo.AclBytesInUse + len(sCurrentACE) + GetLengthSid(bUserSid(0)) - 4
ReDim bNewACL(lNewACLSize)
' ----- Create the ACL to be updated -----
lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION2)
If (lResult = 0) then Exit Function
' ----- Newly create an ACL if there is already DACL -----
If (lDaclPresent) then
If (sACLInfo.AceCount > 0) then
' ----- set permission to the new ACL -----
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION2, GENERIC_ALL, bUserSid(0))
If (lResult = 0) then Exit Function
' ----- set the ACL information to SECURITY_DESCRIPTOR -----
lResult = SetSecurityDescriptorDacl(sNewSD, 1, bNewACL(0), 0)
If (lResult = 0) then Exit Function
' ----- set the security information to the target file -----
lResult = SetFileSecurity(FileName, DACL_SECURITY_INFORMATION,sNewSD)
If (lResult = 0) then Exit Function
End If
End If
ChangeACE = true
End Function