2014-02-17 3 views
0

Мне нужно иметь возможность изменять права доступа файла, используя acct с более высокими привилегиями. Вот мой Impersonate код:Не удается GetAccessControl после выполнения олицетворения, получить ошибку

const int LOGON32_LOGON_INTERACTIVE = 2; 
    const int LOGON32_PROVIDER_DEFAULT = 0; 

    public Impersonation(string domain, string username, string password) 
    { 
     var ok = LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out this._handle); 
     if (!ok) 
     { 
      var errorCode = Marshal.GetLastWin32Error(); 
      throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode)); 
     } 

     this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle()); 
    } 

    public void Dispose() 
    { 
     this._context.Dispose(); 
     this._handle.Dispose(); 
    } 

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); 

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 
    { 
     private SafeTokenHandle() 
      : base(true) { } 

     [DllImport("kernel32.dll")] 
     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
     [SuppressUnmanagedCodeSecurity] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool CloseHandle(IntPtr handle); 

     protected override bool ReleaseHandle() 
     { 
      return CloseHandle(handle); 
     } 
    } 

Вот фрагмент использования Олицетворять:

using (new Impersonation("domain", "username", "pswd")) 
{ 
    FileInfo fi = new FileInfo(@"file name"); 
    FileSecurity fs = fi.GetAccessControl(); 
} 

Вот что я получаю, когда я пытаюсь сделать GetAccessControl. Любая помощь будет принята с благодарностью.

System.InvalidOperationException: Method failed with unexpected error code 3. 
    at System.Security.AccessControl.NativeObjectSecurity.CreateInternal(Resource 
Type resourceType, Boolean isContainer, String name, SafeHandle handle, AccessCo 
ntrolSections includeSections, Boolean createByName, ExceptionFromErrorCode exce 
ptionFromErrorCode, Object exceptionContext) 
    at System.Security.AccessControl.FileSystemSecurity..ctor(Boolean isContainer 
, String name, AccessControlSections includeSections, Boolean isDirectory) 
at System.Security.AccessControl.FileSecurity..ctor(String fileName, AccessCo 
ntrolSections includeSections) 
at System.IO.FileInfo.GetAccessControl() 
at ImpersonationDemo.Main(String[] args) in c:\Users\david.ohara\Documents\Vi 
sual Studio 2013\Projects\SecTest\SecTest\Program.cs:line 84 

ответ

0

Я сделал это раньше, но это в VB.NET не C#, код может помочь вам, хотя, так как это, безусловно, работал:

В псевдопользователей кодексе это:

LogonUserA(userName, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) 
DuplicateToken(token, 2, tokenDuplicate) 
_windowsIdentity = New WindowsIdentity(tokenDuplicate) 
_impersonationContext = _windowsIdentity.Impersonate() 
System.Threading.Thread.CurrentPrincipal = New System.Security.Principal.WindowsPrincipal(_windowsIdentity) 

Вот полный класс, который это делает. Это в VB.Net, поэтому вам нужно будет преобразовать его в C#:

Option Strict On 
#Region "Imports" 
Imports System.Security.Principal 
Imports System.Runtime.InteropServices 
Imports System 
Imports System.Net 
Imports System.Net.Security 
Imports System.Security 
Imports System.Security.Cryptography.X509Certificates 
Imports System.Text 
Imports System.IO 
Imports System.Security.Cryptography 
#End Region 

Public Class ABCSecurity 

#Region "Members" 
    Private Shared _impersonationContext As WindowsImpersonationContext 
    Private Shared _windowsIdentity As WindowsIdentity 
#End Region 

#Region "Win32 APIs" 

    Private Shared LOGON32_LOGON_INTERACTIVE As Integer = 2 
    Private Shared LOGON32_PROVIDER_DEFAULT As Integer = 0 
    Private Shared LOGON32_LOGON_BATCH As Integer = 4 
    Private Shared LOGON32_LOGON_NETWORK As Integer = 3 


    Private Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As String, _ 
          ByVal lpszDomain As String, _ 
          ByVal lpszPassword As String, _ 
          ByVal dwLogonType As Integer, _ 
          ByVal dwLogonProvider As Integer, _ 
          ByRef phToken As IntPtr) As Integer 

    Private Declare Function DuplicateToken Lib "advapi32.dll" (_ 
          ByVal ExistingTokenHandle As IntPtr, _ 
          ByVal ImpersonationLevel As Integer, _ 
          ByRef DuplicateTokenHandle As IntPtr) As Integer 

    Private Declare Function RevertToSelf Lib "advapi32.dll"() As Integer 
    Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long 

    <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ 
    Public Shared Function GetShortPathName(ByVal longPath As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal ShortPath As StringBuilder, <MarshalAs(UnmanagedType.U4)> ByVal bufferSize As Integer) As Integer 
    End Function 

    Public Const FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000 


    <DllImport("Kernel32.dll")> _ 
    Public Shared Function FormatMessage(ByVal flags As Integer, ByVal [source] As IntPtr, ByVal messageId As Integer, ByVal languageId As Integer, ByVal buffer As StringBuilder, ByVal size As Integer, ByVal arguments As IntPtr) As Integer 
    End Function 
#End Region 

#Region "Shared Properties" 
    Public Shared ReadOnly Property CurrentlyLoggedOnUser() As String 
     Get 
      If IsImpersonating Then 
       Return _windowsIdentity.Name 
      Else 
       Return System.Threading.Thread.CurrentPrincipal.Identity.Name 
      End If 
     End Get 
    End Property 

    Private Shared _isImpersonating As Boolean = False 
    Public Shared ReadOnly Property IsImpersonating() As Boolean 
     Get 
      Return _isImpersonating 
     End Get 
    End Property 
#End Region 

#Region "Shared Methods" 

    Public Shared Function impersonateValidUser(ByVal userName As String, _ 
    ByVal domain As String, ByVal password As String) As Boolean 

     Dim token As IntPtr = IntPtr.Zero 
     Dim tokenDuplicate As IntPtr = IntPtr.Zero 
     Dim returnValue As Boolean = False 

     If RevertToSelf() <> 0 Then 
      If LogonUserA(userName, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then 
       If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then 
        _windowsIdentity = New WindowsIdentity(tokenDuplicate) 
        _impersonationContext = _windowsIdentity.Impersonate() 
        If Not _impersonationContext Is Nothing Then 
         returnValue = True 
         _isImpersonating = True 
         System.Threading.Thread.CurrentPrincipal = New System.Security.Principal.WindowsPrincipal(_windowsIdentity) '_impersonationContext 
        Else 
         returnValue = False 
         _isImpersonating = False 
         My.User.InitializeWithWindowsUser() 
        End If 
       End If 
      Else 
       'there was an error 
       returnValue = False 
       _isImpersonating = False 

       Dim errorNumber As Integer = Marshal.GetLastWin32Error() 
       If errorNumber = 1326 Then 
        Throw New Exception("Windows DomainAccount Authentication Failed ") 
       Else 
        Dim sbFormatMessage As New StringBuilder(1024) 
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errorNumber, 0, sbFormatMessage, sbFormatMessage.Capacity, IntPtr.Zero) 
        Throw New Exception("Error occured. GetLastError returns " & System.Runtime.InteropServices.Marshal.GetLastWin32Error.ToString & System.Environment.NewLine & _ 
        sbFormatMessage.ToString()) 
       End If 

       returnValue = False 
       _isImpersonating = False 
       My.User.InitializeWithWindowsUser() 
      End If 
     End If 

     If Not tokenDuplicate.Equals(IntPtr.Zero) Then 
      CloseHandle(tokenDuplicate) 
     End If 

     If Not token.Equals(IntPtr.Zero) Then 
      CloseHandle(token) 
     End If 

     Return returnValue 
    End Function 

    Public Shared Sub undoImpersonation() 
     If _impersonationContext IsNot Nothing Then 
      _impersonationContext.Undo() 
      _impersonationContext = Nothing 
      _isImpersonating = False 
      My.User.InitializeWithWindowsUser() 
     End If 
    End Sub 

#End Region 

End Class 
+0

Спасибо. Я попробую. – David

+0

Я построил решение VB.NET с этим кодом. Я получаю ту же ошибку, что и выше. – David

+0

Я решил это. Я использовал имя файла X: в GetAccessControl. Исправлено использование фактического пути к серверу. У Guerss нет отображения на олицетворении. – David

0

Я решил это. Я использовал имя файла X: в GetAccessControl. Исправлено использование фактического пути к серверу. Guerss нет отображения на олицетворении

Смежные вопросы