Desde mi aplicación necesito en un momento dado suplantar la identidad del usuario actual por la del administrador para depositar un fichero en esa carpeta, lo tengo hecho pero no funciona y no sé porqué.
He usado una clase que encontré por ahí:
Código:
Y para usarla hago esto:Imports System.Runtime.InteropServices Imports System.Security.Principal Imports System.Security.Permissions Public Class ImpersonateUser <DllImport("advapi32.dll", SetLastError:=True)> Public Shared Function LogonUser(lpszUsername As [String], lpszDomain As [String], lpszPassword As [String], dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean End Function <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> Public Shared Function CloseHandle(handle As IntPtr) As Boolean End Function Private Shared tokenHandle As New IntPtr(0) Private Shared impersonatedUser As WindowsImpersonationContext ' If you incorporate this code into a DLL, be sure to demand that it ' runs with FullTrust. <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> Public Sub Impersonate(domainName As String, userName As String, password As String) Try ' Use the unmanaged LogonUser function to get the user token for ' the specified user, domain, and password. Const LOGON32_PROVIDER_DEFAULT As Integer = 0 ' Passing this parameter causes LogonUser to create a primary token. Const LOGON32_LOGON_INTERACTIVE As Integer = 2 tokenHandle = IntPtr.Zero ' ---- Step - 1 ' Call LogonUser to obtain a handle to an access token. Dim returnValue As Boolean = LogonUser(userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle) ' tokenHandle - new security token If False = returnValue Then Dim ret As Integer = Marshal.GetLastWin32Error() Console.WriteLine("LogonUser call failed with error code : " & ret) Throw New System.ComponentModel.Win32Exception(ret) End If ' ---- Step - 2 Dim newId As New WindowsIdentity(tokenHandle) ' ---- Step - 3 impersonatedUser = newId.Impersonate() Catch ex As Exception Console.WriteLine("Exception occurred. " + ex.Message) End Try End Sub ' Stops impersonation Public Sub Undo() Try impersonatedUser.Undo() ' Free the tokens. If tokenHandle <> IntPtr.Zero Then CloseHandle(tokenHandle) End If Catch ex As Exception Console.WriteLine("Exception occurred. " + ex.Message) End Try End Sub End Class
Código:
El código funciona correctamente cuando el usuario que inicia sesión es el administrador, al usar otro usuario a pesar de que cambia correctamente el usuario da error de permisos al grabar el fichero. ¿?'Usuario actual MessageBox.Show(System.Security.Principal.WindowsIdentity.GetCurrent().Name) 'Reemplazamos el usuario que inició sesión por un administrador Dim iU As New ImpersonateUser() iU.Impersonate(My.Settings.Dominio, My.Settings.UserAdmin, My.Settings.PasswordAdmin) 'Ok, parece que lo ha cambiado: MessageBox.Show(System.Security.Principal.WindowsIdentity.GetCurrent().Name) 'Pero aquí da error de que no puede guardar el fichero Dim sw As New StreamWriter(Me.LblRuta.Text & "\" & NombreArchivo & ".txt", False, System.Text.Encoding.Default) 'Al acabar volvemos al usuario original iU.Undo()
¿Alguna idea?
Saludos.