c_hubbard
asked on
change file ownership in windows XP
Hi,
I read and process Files dropped by users on our network.
Sometimes the user forgets to close the file.
Is it possible to change/override ownership of that file (i have admin rights) in Window XP.
BRegards
Ulrich
I read and process Files dropped by users on our network.
Sometimes the user forgets to close the file.
Is it possible to change/override ownership of that file (i have admin rights) in Window XP.
BRegards
Ulrich
ASKER
Hi Bob,
Thanks for your help. I need to do this in my program.
Uli
Thanks for your help. I need to do this in my program.
Uli
Here's some ways so far:
Seize File Ownership with Fileman.vbs
http://www.winnetmag.com/Windows/Article/ArticleID/8748/8748.html
SubInACL (SubInACL.exe)
http://www.microsoft.com/downloads/details.aspx?FamilyID=e8ba3e56-d8fe-4a91-93cf-ed6985e3927b&displaylang=en
Bob
Seize File Ownership with Fileman.vbs
http://www.winnetmag.com/Windows/Article/ArticleID/8748/8748.html
SubInACL (SubInACL.exe)
http://www.microsoft.com/downloads/details.aspx?FamilyID=e8ba3e56-d8fe-4a91-93cf-ed6985e3927b&displaylang=en
Bob
I think the only way to do this is via the API calls GetNamedSecurityInfo and SetNamedSecurityInfo.
I don't have an example handy that uses those APIs to take ownership, but I've got one for setting permissions (so let me know if you'd like me to post it).
'DWORD GetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID* ppsidOwner,
' PSID* ppsidGroup,
' PACL* ppDacl,
' PACL* ppSacl,
' PSECURITY_DESCRIPTOR* ppSecurityDescriptor
');
Declare Auto Function GetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByRef ppsidOwner As IntPtr, _
ByRef ppsidGroup As IntPtr, _
ByRef ppDacl As IntPtr, _
ByRef ppSacl As IntPtr, _
ByRef ppSecurityDescriptor As IntPtr) As Integer
'DWORD SetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID psidOwner,
' PSID psidGroup,
' PACL pDacl,
' PACL pSacl
');
Declare Auto Function SetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByVal psidOwner As IntPtr, _
ByVal psidGroup As IntPtr, _
ByVal pDacl As IntPtr, _
ByVal pSacl As IntPtr) As Integer
I don't have an example handy that uses those APIs to take ownership, but I've got one for setting permissions (so let me know if you'd like me to post it).
'DWORD GetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID* ppsidOwner,
' PSID* ppsidGroup,
' PACL* ppDacl,
' PACL* ppSacl,
' PSECURITY_DESCRIPTOR* ppSecurityDescriptor
');
Declare Auto Function GetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByRef ppsidOwner As IntPtr, _
ByRef ppsidGroup As IntPtr, _
ByRef ppDacl As IntPtr, _
ByRef ppSacl As IntPtr, _
ByRef ppSecurityDescriptor As IntPtr) As Integer
'DWORD SetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID psidOwner,
' PSID psidGroup,
' PACL pDacl,
' PACL pSacl
');
Declare Auto Function SetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByVal psidOwner As IntPtr, _
ByVal psidGroup As IntPtr, _
ByVal pDacl As IntPtr, _
ByVal pSacl As IntPtr) As Integer
ASKER
Hi,
Thanks for the reply.
It seems these API calls are possibly what i am looking for unfortunately i know little about security on networks especially how file ownerships is handled.
I tested the code using an Excel file that is held open by another user. If i try to open the file i get the usual "File in Use" message.
I can run the code passing the FileLocation, XP username and desired permissions.
The code runs fine without error but the ownership doesn't seem to change, i still can't open the file.. same error when i try to open it.
Do you need administrator permission to successfully run the code?
Whats happens to the "old user" whose ownership is taken away as he will still have the file open?
example:
'strUserName = firstname.lastname (thats my xp login)
' strPerm = "Full Control"
SetPermissions(ByRef strPath As String, ByVal strUserName As String, ByVal strPerm As String)
Dim pSecDesc, pNewDACL, pOldDACL As IntPtr
Dim ea As EXPLICIT_ACCESS
Dim Win32Error As Win32Exception
Dim ret, iPerm As Integer
Dim bIsFile As Boolean
' Do a quick sanity check!
bIsFile = True
If File.Exists(strPath) = False Then
If Directory.Exists(strPath) = False Then
Throw New Exception("File or Directory not found")
End If
bIsFile = False
End If
' Translate the desired permissions
Select Case strPerm
Case "Full Control"
iPerm = ALL_ACCESS
Case "Modify"
iPerm = ALL_ACCESS And Not (WRITE_DAC Or WRITE_OWNER Or DELETE_CHILD)
Case "Read & Execute"
iPerm = GENERIC_READ Or GENERIC_EXECUTE
Case "List Folder Contents"
If bIsFile = False Then
Throw New Exception("Permission argument not applicable to files")
End If
iPerm = GENERIC_EXECUTE
Case "Read"
iPerm = GENERIC_READ
Case "Write"
iPerm = GENERIC_WRITE
Case Else
Throw New Exception("Invalid permission argument")
End Select
ret = GetNamedSecurityInfo(strPa th, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION , pOldDACL, Nothing, Nothing, Nothing, pSecDesc)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' build an explicit access structure
BuildExplicitAccessWithNam e(ea, strUserName, iPerm, SET_ACCESS, CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)
' merge this Explict Access with the existing DACL
ret = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' write the new Security Descriptor/DACL back
ret = SetNamedSecurityInfo(strPa th, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, pNewDACL, Nothing)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' clean up and go home
LocalFree(pNewDACL)
LocalFree(pSecDesc)
Thanks for the reply.
It seems these API calls are possibly what i am looking for unfortunately i know little about security on networks especially how file ownerships is handled.
I tested the code using an Excel file that is held open by another user. If i try to open the file i get the usual "File in Use" message.
I can run the code passing the FileLocation, XP username and desired permissions.
The code runs fine without error but the ownership doesn't seem to change, i still can't open the file.. same error when i try to open it.
Do you need administrator permission to successfully run the code?
Whats happens to the "old user" whose ownership is taken away as he will still have the file open?
example:
'strUserName = firstname.lastname (thats my xp login)
' strPerm = "Full Control"
SetPermissions(ByRef strPath As String, ByVal strUserName As String, ByVal strPerm As String)
Dim pSecDesc, pNewDACL, pOldDACL As IntPtr
Dim ea As EXPLICIT_ACCESS
Dim Win32Error As Win32Exception
Dim ret, iPerm As Integer
Dim bIsFile As Boolean
' Do a quick sanity check!
bIsFile = True
If File.Exists(strPath) = False Then
If Directory.Exists(strPath) = False Then
Throw New Exception("File or Directory not found")
End If
bIsFile = False
End If
' Translate the desired permissions
Select Case strPerm
Case "Full Control"
iPerm = ALL_ACCESS
Case "Modify"
iPerm = ALL_ACCESS And Not (WRITE_DAC Or WRITE_OWNER Or DELETE_CHILD)
Case "Read & Execute"
iPerm = GENERIC_READ Or GENERIC_EXECUTE
Case "List Folder Contents"
If bIsFile = False Then
Throw New Exception("Permission argument not applicable to files")
End If
iPerm = GENERIC_EXECUTE
Case "Read"
iPerm = GENERIC_READ
Case "Write"
iPerm = GENERIC_WRITE
Case Else
Throw New Exception("Invalid permission argument")
End Select
ret = GetNamedSecurityInfo(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' build an explicit access structure
BuildExplicitAccessWithNam
' merge this Explict Access with the existing DACL
ret = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' write the new Security Descriptor/DACL back
ret = SetNamedSecurityInfo(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' clean up and go home
LocalFree(pNewDACL)
LocalFree(pSecDesc)
That's kinda funny that you're using my example code for setting permissions.... that's the code example that what I was offering to post! :)
Here is an example that should be of more help to you. I just finished banging it out a few minutes ago, so there might be a few rough edges somewhere...
Imports System.Runtime.InteropServ ices
Imports System.IO
Imports System.ComponentModel
Module ChgOwner
Private Const SE_FILE_OBJECT = 1&
Private Const OWNER_SECURITY_INFORMATION = &H1
Private Const NAME_SIZE = 64
Private Const SID_SIZE = 32
'DWORD GetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID* ppsidOwner,
' PSID* ppsidGroup,
' PACL* ppDacl,
' PACL* ppSacl,
' PSECURITY_DESCRIPTOR* ppSecurityDescriptor
');
Declare Auto Function GetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByRef ppsidOwner As IntPtr, _
ByRef ppsidGroup As IntPtr, _
ByRef ppDacl As IntPtr, _
ByRef ppSacl As IntPtr, _
ByRef ppSecurityDescriptor As IntPtr) As Integer
'DWORD SetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID psidOwner,
' PSID psidGroup,
' PACL pDacl,
' PACL pSacl
');
Declare Auto Function SetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByVal psidOwner As IntPtr, _
ByVal psidGroup As IntPtr, _
ByVal pDacl As IntPtr, _
ByVal pSacl As IntPtr) As Integer
'BOOL LookupAccountName(
' LPCTSTR lpSystemName,
' LPCTSTR lpAccountName,
' PSID Sid,
' LPDWORD cbSid,
' LPTSTR ReferencedDomainName,
' LPDWORD cchReferencedDomainName,
' PSID_NAME_USE peUse
');
Declare Auto Function LookupAccountName Lib "advapi32.dll" ( _
ByVal lpSystemName As String, _
ByVal lpAccountName As String, _
ByVal Sid As IntPtr, _
ByRef cbSid As Integer, _
ByVal lpReferencedDomainName As String, _
ByRef cchReferencedDomainName As Integer, _
ByRef peUse As IntPtr) As Boolean
Public Declare Function LocalFree Lib "kernel32" ( _
ByVal hMem As IntPtr) As Integer
Sub ChangeOwner(ByRef strPath As String, ByVal strUserName As String)
Dim pSecDesc, pNewOwner, pOldOwner, deUse As IntPtr
Dim Win32Error As Win32Exception
Dim domain_name As String
Dim ret, sid_len, domain_len As Integer
' Series of quick sanity checks before we proceed...
' Do we have the required Privilege?
'If SetPrivileges() = False Then
'Throw New Exception("Required privilege not held by the user")
'End If
' Does the file even exist?
If File.Exists(strPath) = False Then
If Directory.Exists(strPath) = False Then
Throw New Exception("File or Directory not found")
End If
End If
' Can we convert the name to a valid SID?
sid_len = SID_SIZE
pNewOwner = Marshal.AllocHGlobal(sid_l en)
domain_len = NAME_SIZE
domain_name = Space(domain_len)
If LookupAccountName(Nothing, strUserName, pNewOwner, sid_len, domain_name, domain_len, deUse) = False Then
ret = Marshal.GetLastWin32Error( )
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' get the Security Descriptor and Owner
ret = GetNamedSecurityInfo(strPa th, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION , Nothing, pOldOwner, Nothing, Nothing, pSecDesc)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' write the new Security Descriptor and Owner
ret = SetNamedSecurityInfo(strPa th, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION , pNewOwner, Nothing, Nothing, Nothing)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' clean up and go home
Marshal.FreeHGlobal(pNewOw ner)
LocalFree(pSecDesc)
End Sub
End Module
Here is an example that should be of more help to you. I just finished banging it out a few minutes ago, so there might be a few rough edges somewhere...
Imports System.Runtime.InteropServ
Imports System.IO
Imports System.ComponentModel
Module ChgOwner
Private Const SE_FILE_OBJECT = 1&
Private Const OWNER_SECURITY_INFORMATION
Private Const NAME_SIZE = 64
Private Const SID_SIZE = 32
'DWORD GetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID* ppsidOwner,
' PSID* ppsidGroup,
' PACL* ppDacl,
' PACL* ppSacl,
' PSECURITY_DESCRIPTOR* ppSecurityDescriptor
');
Declare Auto Function GetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByRef ppsidOwner As IntPtr, _
ByRef ppsidGroup As IntPtr, _
ByRef ppDacl As IntPtr, _
ByRef ppSacl As IntPtr, _
ByRef ppSecurityDescriptor As IntPtr) As Integer
'DWORD SetNamedSecurityInfo(
' LPTSTR pObjectName,
' SE_OBJECT_TYPE ObjectType,
' SECURITY_INFORMATION SecurityInfo,
' PSID psidOwner,
' PSID psidGroup,
' PACL pDacl,
' PACL pSacl
');
Declare Auto Function SetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
ByVal pObjectName As String, _
ByVal ObjectType As Integer, _
ByVal SecurityInfo As Integer, _
ByVal psidOwner As IntPtr, _
ByVal psidGroup As IntPtr, _
ByVal pDacl As IntPtr, _
ByVal pSacl As IntPtr) As Integer
'BOOL LookupAccountName(
' LPCTSTR lpSystemName,
' LPCTSTR lpAccountName,
' PSID Sid,
' LPDWORD cbSid,
' LPTSTR ReferencedDomainName,
' LPDWORD cchReferencedDomainName,
' PSID_NAME_USE peUse
');
Declare Auto Function LookupAccountName Lib "advapi32.dll" ( _
ByVal lpSystemName As String, _
ByVal lpAccountName As String, _
ByVal Sid As IntPtr, _
ByRef cbSid As Integer, _
ByVal lpReferencedDomainName As String, _
ByRef cchReferencedDomainName As Integer, _
ByRef peUse As IntPtr) As Boolean
Public Declare Function LocalFree Lib "kernel32" ( _
ByVal hMem As IntPtr) As Integer
Sub ChangeOwner(ByRef strPath As String, ByVal strUserName As String)
Dim pSecDesc, pNewOwner, pOldOwner, deUse As IntPtr
Dim Win32Error As Win32Exception
Dim domain_name As String
Dim ret, sid_len, domain_len As Integer
' Series of quick sanity checks before we proceed...
' Do we have the required Privilege?
'If SetPrivileges() = False Then
'Throw New Exception("Required privilege not held by the user")
'End If
' Does the file even exist?
If File.Exists(strPath) = False Then
If Directory.Exists(strPath) = False Then
Throw New Exception("File or Directory not found")
End If
End If
' Can we convert the name to a valid SID?
sid_len = SID_SIZE
pNewOwner = Marshal.AllocHGlobal(sid_l
domain_len = NAME_SIZE
domain_name = Space(domain_len)
If LookupAccountName(Nothing,
ret = Marshal.GetLastWin32Error(
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' get the Security Descriptor and Owner
ret = GetNamedSecurityInfo(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' write the new Security Descriptor and Owner
ret = SetNamedSecurityInfo(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' clean up and go home
Marshal.FreeHGlobal(pNewOw
LocalFree(pSecDesc)
End Sub
End Module
ASKER
Hi,
Thanks for the reply again.
Graye: i found this code on the web and adapted it for my use... sorry for nicking you code :)
I have the feeling i am chasing the wrong solution, like i said i know little about fileownerships on networks etc.
I believe there is a difference between an application having a lock on a file (having it open) and Fileownership. I treated them as the same :(
My problem is that a different networkuser has this file open with, in this case Excel and therefore this application has a lock on that file.
I want to force the file to be unlocked so that i can use it.
Can the AdvAPI32 libary handle things like this or are there other ways to do this programatically?
Thanks again for your help
ulrich
Thanks for the reply again.
Graye: i found this code on the web and adapted it for my use... sorry for nicking you code :)
I have the feeling i am chasing the wrong solution, like i said i know little about fileownerships on networks etc.
I believe there is a difference between an application having a lock on a file (having it open) and Fileownership. I treated them as the same :(
My problem is that a different networkuser has this file open with, in this case Excel and therefore this application has a lock on that file.
I want to force the file to be unlocked so that i can use it.
Can the AdvAPI32 libary handle things like this or are there other ways to do this programatically?
Thanks again for your help
ulrich
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Works perfect...
Thanks alot
ulrich
Thanks alot
ulrich
Bob