jzhu,
Thanks for the pointer. This appears to be what I am looking for.
However, I can not quite get it to work. The Security Descriptor pointer
returned by GetKernelObjectSecurity appears to be invalid. At least that is
what 'IsValidSecurityDescriptor' returns. When I try to use it in
'GetSecurityDescriptorOwner' it blows up with 'Object reference not set to
an instance of an object'. Any idea what I am doing wrong?
Dave
My Code:
*****************************************
'Structures and Functions
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LUID
Public LowPart As Integer
Public HighPart As Integer
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LUID_AND_ATTRIBUTES
Public pLuid As LUID
Public Attributes As Integer
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure TOKEN_PRIVILEGES
Public PrivilegeCount As Integer
Public Privileges As LUID_AND_ATTRIBUTES
End Structure
Private Const TOKEN_ADJUST_PRIVILEGES As Integer = &H20
Private Const TOKEN_QUERY As Integer = &H8
Private Const SE_PRIVILEGE_ENABLED As Integer = &H2
Private Const FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
Private Const EWX_FORCE As Integer = 4
Private Declare Ansi Function OpenProcessToken Lib "advapi32" ( _
ByVal ProcessHandle As IntPtr, _
ByVal DesiredAccess As Integer, _
ByRef TokenHandle As IntPtr) As Integer
Private Declare Ansi Function LookupPrivilegeValue Lib "advapi32" _
Alias "LookupPrivilegeValueA" ( _
ByVal lpSystemName As String, _
ByVal lpName As String, _
ByRef lpLuid As LUID) As Integer
Private Declare Ansi Function AdjustTokenPrivileges Lib "advapi32" ( _
ByVal TokenHandle As IntPtr, _
ByVal DisableAllPrivileges As Integer, _
ByRef NewState As TOKEN_PRIVILEGES, _
ByVal BufferLength As Integer, _
ByRef PreviousState As TOKEN_PRIVILEGES, _
ByRef ReturnLength As Integer) As Integer
Private Declare Function CreateFile Lib "kernel32.dll" _
Alias "CreateFileA" ( _
ByVal sFileName As String, _
ByVal iDesiredAccess As Integer, _
ByVal iSharedMode As Integer, _
ByVal iSecurityAttributes As Integer, _
ByVal iCreationDisposition As Integer, _
ByVal iFlagsAndAttributes As Integer, _
ByVal hTemplateFile As Integer) As IntPtr
Private Declare Function GetKernelObjectSecurity Lib "advapi32.dll" ( _
ByVal hFileHandle As IntPtr, _
ByVal SecurityInformation As SECURITY_INFORMATION, _
ByRef pSD As IntPtr, _
ByVal iLength As Integer, _
ByRef iLengthRequired As Integer) As Integer
Private Declare Function GetSecurityDescriptorOwner Lib "advapi32.dll"
( _
ByVal pSD As IntPtr, _
ByRef pOwner As IntPtr, _
ByRef pOwnerDefaulted As Boolean) As Integer
Private Declare Function IsValidSecurityDescriptor Lib "advapi32.dll"
( _
ByVal pSD As IntPtr) As Integer
*****************************************
Calling Code
Dim tokenHandle As IntPtr
Dim privilegeLUID As LUID
Dim newPrivileges As TOKEN_PRIVILEGES
Dim tokenPrivileges As TOKEN_PRIVILEGES
Dim bSuccess As Integer
If OpenProcessToken(Process.GetCurrentProcess.Handle, _
TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, tokenHandle) = 0 Then
MsgBox(Err.LastDllError)
End If
If LookupPrivilegeValue("", privilege, privilegeLUID) = 0 Then
MsgBox(Err.LastDllError)
End If
tokenPrivileges.PrivilegeCount = 1
tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED
tokenPrivileges.Privileges.pLuid = privilegeLUID
bSuccess = AdjustTokenPrivileges(tokenHandle, 0, tokenPrivileges, _
4 + (12 * tokenPrivileges.PrivilegeCount), _
newPrivileges, 4 + (12 * newPrivileges.PrivilegeCount))
If bSuccess = 0 Then
MsgBox(Err.LastDllError)
End If
Dim hFileHandle As IntPtr
hFileHandle = CreateFile(sPath, READ_CONTROL, _
FILE_SHARE_READ, Nothing, OPEN_EXISTING, _
FILE_FLAG_BACKUP_SEMANTICS, Nothing)
If hFileHandle.ToString = INVALID_HANDLE_VALUE Then
MsgBox("CreateFile Failed")
Else
MsgBox("CreateFile Succeeded")
End If
Dim pSD As IntPtr
Dim iLen As Integer
Dim iLenReq As Integer
bSuccess = GetKernelObjectSecurity(hFileHandle, _
SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, pSD, iLen,
iLenReq)
bSuccess = GetKernelObjectSecurity(hFileHandle, _
SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, pSD, iLenReq,
0)
If bSuccess = 0 Then
MsgBox("GetKernelErr " & Err.LastDllError)
Else
MsgBox("GetKernelObjSec Suceeded")
End If
MsgBox(IsValidSecurityDescriptor(pSD))
Dim pOwner As IntPtr
Dim dft As Boolean
bSuccess = GetSecurityDescriptorOwner(pSD, pOwner, dft)
*****************************************
"jzhu" <jz**@discussions.microsoft.com> wrote in message
news:19**********************************@microsof t.com...
Take a look at Knowledge Base article Q240184:
INFO: Reading/Modifying DACL of a File or Folder with Backup and Restore
Privileges
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/enu_kbwin32sdk/en-us/win32sdk
/Q240184.htm
To use the privileges, check out:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/enu_kbwin32sdk/en-us/win32sdk
/Q240184.htm
If you need addtional Win32 security APIs in VB.NET, check out
http://www.DataMarvel.com
It has samples on enabling privileges through a higher level wraper, which
is much simplier than the raw PInvoke Win32 APIs.
"Dave Coate" wrote:
Hello again,
I am going to re-post a question. I got some excellent suggestions
from Rob and Mattias on this but their ideas did not solve the problem. Here
is the original post:
************************************************** ***
I am looking for a way to 'override' file security and read the
Owner of a file to which I have no access. I am a system administrator, as such I
have administrative rights to all the computers in the company. Some of
my user base has full control rights to their files and have elected to
remove my access to some files. It is possible for an administrator to regain
access, but it is a messy process and can be time consuming. I have had
more than one long night copying data to a larger partition having to wach
the job for files that will not copy and go back to clean it up.
I have written a vb.net program that uses Windows API functions to
automate this. It takes ownership of problem files, grants
administrative access, copies the file or folder plus the security information and then
sets everything back the way it was. There is only one hitch. I have
been unsuccessful reading the owner of a file using Win APIs such as
GetNamedSecurityInfo when I do not have access to the file. I can WRITE
a new owner to such a file, but not read it. I need to be able to do this
so I can subsequently restore the original owner after I copy the file.
My current work around is to make a command shell call to
fileacl.exe. This utility will read a file's owner regardless of permissions if you
use the /force switch. This works, but I am not very happy with it and I
would like to do the whole job with Win APIs. For one thing it makes the
program more portable because I do not need to remember to have the fileacl.exe
utility on every server/computer from which I run this program.
Since the fileacl utility does read the file owner without
permissions, it must be possible. Can anyone give me a hint on how this might be
accomplished?
************************************************** ***
I tried placing myself in the backup operators group and that did not
help. I have tried adjusting my token with the SeRestorePrivilege and
SeBackupPrivilege and that did not help either. (I am not certain I am
doing the latter properly, but the code I wrote does not return any errors,
including dll errors.) Does anyone have any other suggestions? Keep in
mind, I am an administrator on all boxes for which I have tried this.
Dave Coate