Re: GetNamedSecurityInfo - Read Owner pt II

From: Dave Coate (coateds_at_comcast.net)
Date: 10/20/04


Date: Wed, 20 Oct 2004 09:57:33 -0700

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" <jzhu@discussions.microsoft.com> wrote in message
news:19F87BDB-B2EE-4A11-B162-02E3D20C85B2@microsoft.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
> >
> >
> >



Relevant Pages

  • Re: GetNamedSecurityInfo - Read Owner pt II
    ... The Security Descriptor pointer ... > is much simplier than the raw PInvoke Win32 APIs. ... I am a system administrator, ... >> unsuccessful reading the owner of a file using Win APIs such as ...
    (microsoft.public.dotnet.framework.interop)
  • RE: GetNamedSecurityInfo - Read Owner pt II
    ... To use the privileges, check out: ... If you need addtional Win32 security APIs in VB.NET, ... I am a system administrator, ... > unsuccessful reading the owner of a file using Win APIs such as ...
    (microsoft.public.dotnet.languages.vb)
  • RE: GetNamedSecurityInfo - Read Owner pt II
    ... To use the privileges, check out: ... If you need addtional Win32 security APIs in VB.NET, ... I am a system administrator, ... > unsuccessful reading the owner of a file using Win APIs such as ...
    (microsoft.public.dotnet.framework.interop)
  • Re: how do I change ownership of and "unknown" owner
    ... > The Administrator you are talking about should be the Administrator of the ... > to do with NT or machine level security. ... > Owner, in all my experience it's been corruption. ... > Microsoft Security Bulletin MS03-026? ...
    (microsoft.public.access.security)
  • Re: how do I change ownership of and "unknown" owner
    ... cases where they are joining to correct MDW file however the owner shows as ... Produced By Microsoft MimeOLE V6.00.2800.1106 ... |> to do with NT or machine level security. ...
    (microsoft.public.access.security)