Hello I have a problem with deleting and replacing files at share folder
I have full access.
"access to the path was denied"
The copy function works well in both directions.
(but I have to delete files manually).
SERVER - >>> PC
SERVER <<< - PC
The program connects to the file server under another user and manipulate with files (copy files worked fine, delete files doesn't work replace doesn't work).
private void replaceFile(string source, string sourceName ,string destination)
{
try
{
using (new Impersonator(username(), domain(), password()))
{
//File.delete(destination);
//File.Copy(source, destination, true);
File.Replace(source, destination, null);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private void copyFile(string source, string destination)
{
try
{
using (new Impersonator(username(), domain(), password()))
{
File.Copy(source, destination, true);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
namespace IFS_FileManager
{
public enum LogonType
{
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Win2K or higher
LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
};
public enum LogonProvider
{
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT50 = 3
};
public enum ImpersonationLevel
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
class Win32NativeMethods
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int LogonUser(string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
}
public class Impersonator : IDisposable
{
private WindowsImpersonationContext _wic;
public Impersonator(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
{
Impersonate(userName, domainName, password, logonType, logonProvider);
}
public Impersonator(string userName, string domainName, string password)
{
Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
}
public Impersonator() { }
public void Dispose()
{
UndoImpersonation();
}
public void Impersonate(string userName, string domainName, string password)
{
Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
}
public void Impersonate(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
{
UndoImpersonation();
IntPtr logonToken = IntPtr.Zero;
IntPtr logonTokenDuplicate = IntPtr.Zero;
try
{
// revert to the application pool identity, saving the identity of the current requestor
_wic = WindowsIdentity.Impersonate(IntPtr.Zero);
// do logon & impersonate
if (Win32NativeMethods.LogonUser(userName,domainName,password,(int)logonType,(int)logonProvider,ref logonToken) != 0)
{
if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation, ref logonTokenDuplicate) != 0)
{
var wi = new WindowsIdentity(logonTokenDuplicate);
wi.Impersonate();
// discard the returned identity context (which is the context of the application pool)
}
else
MessageBox.Show("\n " + Marshal.GetLastWin32Error(), "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
MessageBox.Show("\n " + Marshal.GetLastWin32Error(), "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (logonToken != IntPtr.Zero)
Win32NativeMethods.CloseHandle(logonToken);
if (logonTokenDuplicate != IntPtr.Zero)
Win32NativeMethods.CloseHandle(logonTokenDuplicate);
}
}
/// <summary>
/// Stops impersonation.
/// </summary>
private void UndoImpersonation()
{
// restore saved requestor identity
if (_wic != null)
_wic.Undo();
_wic = null;
}
}
}
Related
I have an application that runs with the system user. I need that some code in the app runs on user context (with the user itself). For example i need to use the webclient in user context because that way my firewall recognize the username, but later i need to run some other code ex. Running a exe in system context (with system user) because i need the privileges.
Is there a way to do this?.
Thanks!!!
I have used this code to impersonate certain operations
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
using NLog;
namespace Core.Impersonation
{
public class ImpersonatedUser : IDisposable
{
private static Logger logger = LogManager.GetCurrentClassLogger();
IntPtr userHandle;
WindowsImpersonationContext impersonationContext;
public ImpersonatedUser(string user, string domain, string password)
{
logger.Debug("Impersonating user: " + domain + #"\" + user);
userHandle = IntPtr.Zero;
bool loggedOn = LogonUser(
user,
domain,
password,
LogonType.Interactive,
LogonProvider.Default,
out userHandle);
if (!loggedOn)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Begin impersonating the user
impersonationContext = WindowsIdentity.Impersonate(userHandle);
}
public void Dispose()
{
if (userHandle != IntPtr.Zero)
{
CloseHandle(userHandle);
userHandle = IntPtr.Zero;
impersonationContext.Undo();
logger.Debug("Finished Impersonating user");
}
}
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
LogonType dwLogonType,
LogonProvider dwLogonProvider,
out IntPtr phToken
);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hHandle);
enum LogonType : int
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
NetworkCleartext = 8,
NewCredentials = 9,
}
enum LogonProvider : int
{
Default = 0,
}
}
}
and then usage:
using (var i = new ImpersonatedUser("someLogin", "someDomain", "thePassword"))
{
var u = System.Environment.UserName;
}
My objective is to copy a folder from my system to a remote computer in c#.
I searched everywhere and found some information on how to do that. I am calling the LogonUser function with the domain, username and password, but it it fails and returns 0.
below is my piece of code. Can you please help me figure out the problem?
class Program
{
#region Assembly Functions
[DllImport("advapi32.dll")]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr handle);
#endregion
static void Main(string[] args)
{
SafeTokenHandle safeTokenHandle;
WindowsImpersonationContext impersonatedUser = null;
WindowsIdentity newId;
IntPtr tokenHandle;
IntPtr userHandle = IntPtr.Zero;
tokenHandle = IntPtr.Zero;
Console.WriteLine("Enter your domain.");
string domain = Console.ReadLine();
Console.WriteLine("Enter you user name.");
string uname = Console.ReadLine();
Console.WriteLine("Enter your password (Caution, password won't be hidden).");
string password = Console.ReadLine();
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
bool logon = LogonUser(uname, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
if (false == logon)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new System.ComponentModel.Win32Exception(ret);
}
if (logon)
{
newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
using (impersonatedUser = newId.Impersonate())
{
// Check the identity.
Console.WriteLine("After impersonation: "
+ WindowsIdentity.GetCurrent().Name);
}
File.Copy(#"c:\result.xml", #"C:\result.xml", true);
}
//Undo impersonation
if (impersonatedUser != null)
{
impersonatedUser.Undo();
}
if (tokenHandle != IntPtr.Zero)
{
CloseHandle(tokenHandle);
}
}
}
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);
}
}
Why not use "Windows API Code Pack 1.1" which shows (among other things) how to use the shell to do e.g. drag and drop - which is what you essentially try to do.
If using the Shell, you don't have to think about how to logon and 1000 other things needed to support various situations.
Download the "Windows API Code Pack 1.1" package and look for DragAndDropWindow sample or some of the other samples.
I have a website in which I create a file and save it in a remote share folder. I have a account which have write access to that share folder. So I impersonate that account while saving the file in that path. This logic works when I run the application from my visual studio locally in my machine. When I deploy the code in the development server, It does't work. I get the following error.
"Logon failure: the user has not been granted the requested logon type at this computer"
can someone help.
Here is the impersonation code from codeproject
using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;
public class Impersonator :
IDisposable
{
public Impersonator(
string userName,
string domainName,
string password)
{
ImpersonateValidUser(userName, domainName, password);
}
// ------------------------------------------------------------------
#endregion
#region IDisposable member.
// ------------------------------------------------------------------
public void Dispose()
{
UndoImpersonation();
}
// ------------------------------------------------------------------
#endregion
#region P/Invoke.
// ------------------------------------------------------------------
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(
string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(
IntPtr handle);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
// ------------------------------------------------------------------
#endregion
#region Private member.
// ------------------------------------------------------------------
/// <summary>
/// Does the actual impersonation.
/// </summary>
/// <param name="userName">The name of the user to act as.</param>
/// <param name="domainName">The domain name of the user to act as.</param>
/// <param name="password">The password of the user to act as.</param>
private void ImpersonateValidUser(
string userName,
string domain,
string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if (RevertToSelf())
{
if (LogonUser(
userName,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}
/// <summary>
/// Reverts the impersonation.
/// </summary>
private void UndoImpersonation()
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
private WindowsImpersonationContext impersonationContext = null;
// ------------------------------------------------------------------
#endregion
}
I found the answer myself. I changed the logon type to 8 and it worked.. Thanks everyone
This theme are not new. But I need help of some professional.
I am making a windows form application which will run on local system(not domain's computer). The application would creating folder and some files on Active Directory domain's shared folder.
I have read about Impersonation and have tried to make some thing like this: Impersonation by using LogonUser
Then I wrote the next code:
using System.Security.Principal;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
private enum LogonSessionType : uint
{
Interactive = 2,
Network,
Batch,
Service,
NetworkCleartext = 8,
NewCredentials
}
private enum LogonProvider : uint
{
Default = 0,
WinNT35,
WinNT40,
WinNT50
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(
string principal,
string authority,
string password,
LogonSessionType logonType,
LogonProvider logonProvider,
out IntPtr token);
public Form1()
{
InitializeComponent();
}
protected void btnConnect_Click(object sender, EventArgs e)
{
IntPtr token = IntPtr.Zero;
WindowsImpersonationContext impersonateUser = null;
try
{
bool result = LogonUser("Administrator#mydomain.ru", "192.168.1.1", "SomeP#ssWorD",
LogonSessionType.Network, LogonProvider.Default, out token);
if(result)
{
WindowsIdentity id = new WindowsIdentity(token);
impersonateUser = id.Impersonate();
string showtext = string.Format("Identity: {0}", WindowsIdentity.GetCurrent().Name);
MessageBox.Show(showtext);
}
else
{
string showtext = string.Format("Identity: {0}", "Fail");
MessageBox.Show(showtext);
}
}
catch
{
}
finally
{
if(impersonateUser!=null)
impersonateUser.Undo();
if (token != IntPtr.Zero)
CloseHandle(token);
}
}
}
But bool result is always = false. What am I doing wrong?
i was wrong about understanding of LogonUser function. I was thinking that this function get remote token, but it generate.
Here is the right using:
bool result = LogonUser("Administrator", "mydomain.ru", "SomePa$$worD", LogonSessionType.NewCredentials, LogonProvider.Default, out safeTokenHandle);
I'm getting the following exception when going through some legacy impersonation logic:
Unable to find an entry point named 'LogonUser' in DLL 'advapi32.dll'
I understand that the error means that my app can't find the LogonUser method in the advapi32.dll.
The code looks something like this:
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
if(LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _tokenHandle))
{
//do stuff...
}
Has anyone had a similar error - any suggestions on how to fix it or why it is happening? Is there a better way to do this besides using the advapi32.dll (its a .net 3.5 solution but there are lots of legacy classes)?
Maybe it has something to do with the "ExactSpelling = true"
This seems to work:
public enum LogonType : int
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkCleartText = 8,
NewCredentials = 9,
}
public enum LogonProvider : int
{
Default = 0,
}
public class Impersonation : IDisposable
{
#region Dll Imports
[DllImport("kernel32.dll")]
private static extern Boolean CloseHandle(IntPtr hObject);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool LogonUser(string username, string domain,
string password, LogonType logonType,
LogonProvider logonProvider,
out IntPtr userToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool DuplicateToken(IntPtr token, int impersonationLevel,
ref IntPtr duplication);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool ImpersonateLoggedOnUser(IntPtr userToken);
#endregion
#region Private members
private bool _disposed;
private WindowsImpersonationContext _impersonationContext;
#endregion
#region Constructors
public Impersonation(String username, String domain, String password)
{
IntPtr userToken = IntPtr.Zero;
IntPtr userTokenDuplication = IntPtr.Zero;
// Logon with user and get token.
bool loggedOn = LogonUser(username, domain, password,
LogonType.Interactive, LogonProvider.Default,
out userToken);
if (loggedOn)
{
try
{
// Create a duplication of the usertoken, this is a solution
// for the known bug that is published under KB article Q319615.
if (DuplicateToken(userToken, 2, ref userTokenDuplication))
{
// Create windows identity from the token and impersonate the user.
WindowsIdentity identity = new WindowsIdentity(userTokenDuplication);
_impersonationContext = identity.Impersonate();
}
else
{
// Token duplication failed!
// Use the default ctor overload
// that will use Mashal.GetLastWin32Error();
// to create the exceptions details.
throw new Exception("Could not copy token");
}
}
finally
{
// Close usertoken handle duplication when created.
if (!userTokenDuplication.Equals(IntPtr.Zero))
{
// Closes the handle of the user.
CloseHandle(userTokenDuplication);
userTokenDuplication = IntPtr.Zero;
}
// Close usertoken handle when created.
if (!userToken.Equals(IntPtr.Zero))
{
// Closes the handle of the user.
CloseHandle(userToken);
userToken = IntPtr.Zero;
}
}
}
else
{
throw new Exception("Login failed");
}
}
~Impersonation()
{
Dispose(false);
}
#endregion
#region Public methods
public void Revert()
{
if (_impersonationContext != null)
{
// Revert to previous user.
_impersonationContext.Undo();
_impersonationContext = null;
}
}
#endregion
#region IDisposable implementation.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
Revert();
_disposed = true;
}
}
#endregion
}
Have you tried using the version of LogonUser's signature provided on pinvoke.net?