Beruflich Dokumente
Kultur Dokumente
open file?
up How do I specify the username and password in order for my program to open a file
vote6do for reading? The program that needs to access the file is running from an account
wn vote favorite
that does not have read access to the folder the file is in. Program is written in C#
2 and .NET 2, running under XP and file is on a Windows Server 2003 machine.
up You want to impersonate a user who does have the rights to access the file.
vote11do
wn vote I recommend using a class like this
- http://www.codeproject.com/KB/cs/zetaimpersonator.aspx. It hides all the nasty
implementation of doing impersonation.
using (new Impersonator("myUsername", "myDomainname", "myPassword"))
{
string fileText = File.ReadAllText("c:\test.txt");
Console.WriteLine(fileText);
}
shareimprove this answer answered Oct 30 '08 at 8:41
James Newton-King
21.2k1378102
This works great. I found the file paths must be in UNC format if located on another machine. – Brian LeahyOct 30
at 11:12
1 Works for me too, took me a while get it to work because I missed the remark made on the referenced page:Please
note: The user context that initiates the impersonation (i.e. not the user context to which it is switched to) needs to h
the "Act as part of operating system" privilege set. – Lex Mar 7 '12 at 13:04
It's a shame that the codeproject's author never moved it into Nuget. My answer's commentary was only meant for f
for it is understood that you answered this 8 years ago before Nuget. – OmegaMan Feb 18 at 21:44
add a comment
up I have used the Nuget package NuGet Gallery | Simple Impersonation Library
vote1dow 1.1.0 but there are others; search on Impersonation for the others.
n vote Example usage using the interactive login to work with file structures:
using (Impersonation.LogonUser("{domain}",
"{UserName}",
"{Password}",
LogonType.Interactive))
{
var directory = @"\\MyCorpServer.net\alpha\cars";
Assert.IsTrue(Directory.Exists(directory));
}
This is kind of ironic that the person who has the most downloaded package on
Nuget does not even mention it. ;-)
shareimprove this answer edited Feb 19 at 22:07 answered Feb 18 at 21:41
OmegaMan
11.5k32442
Simple, thanks a lot! – Andrew Kilburn Feb 25 at 16:44
add a comment
up You can impersonate a user who has the necessary rights. There is an article on
vote0do MSDN that describes how to do this.
wn vote shareimprove this answer answered Oct 30 '08 at 8:21
http://stackoverflow.com/questions/249540/how-to-present-credentials-in-order-to-open-file
53 I know how to do this with Win32 functions (the WNet* family from mpr.dll), but
would like to do it with .Net (2.0) functionality.
What options are available?
The service is running under an account which has no rights on the share.
The user account needed for the share is not known on the client side.
Client and server are not members of the same domain.
c# .net winapi networking passwords
shareimprove this question edited Nov 17 '08 at 13:21 asked Nov 17 '08 at 13:07
gyrolf
1,19031619
4 While I'm not giving you a useful answer, I can supply an anti-answer.. Impersonation and spawning a process as
Marc posited will not work when the server and the client are not in the same domain, unless there is a trust
between the two domains. If there is a trust then I think it will work. I would have just replied as a comment to Ma
but I don't have enough rep to comment. :-/ – Moose Nov 17 '08 at 14:23
add a comment
11 Answers
activeoldest votes
Mark Brackett
61.8k1075124
2 The service isn't member of the target domain - impersonation cannot work since you wouldn't be able to create
security token locally and impersonate with it. PInvoke is the only way. – stephbu Nov 17 '08 at 17:31
any sample with full source code ? thx – Kiquenet Mar 13 '12 at 12:12
3 @Kiquenet - see Luke's answer for source: stackoverflow.com/a/1197430/2199 – Mark Brackett Mar 13 '12 at 13
@MarkBrackett I know this is an old answer, but maybe you still know... will the access be granted to the progra
only or also to the logged in user via explorer? – Breeze Mar 21 at 10:06
@Breeze - I haven't tested it, but I'd expect it authenticate for the logon session; so if your program is running as
logged on user, they'd have access as well (at least for the duration of the operation). – Mark Brackett Mar 21 at
15:45
up I liked Mark Brackett's answer so much that I did my own quick implementation.
vote183d Here it is if anyone else needs it in a hurry:
own vote public class NetworkConnection : IDisposable
{
string _networkName;
if (result != 0)
{
throw new Win32Exception(result, "Error connecting to
remote share");
}
}
~NetworkConnection()
{
Dispose(false);
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource
netResource,
string password, string username, int flags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int
flags,
bool force);
}
[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
public ResourceScope Scope;
public ResourceType ResourceType;
public ResourceDisplaytype DisplayType;
public int Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
Luke Quinane
10.7k74778
7 It really should be throw new Win32Exception(result);, since WNetAddConnection2 returns win32 erro
codes (ERROR_XXX) – torvin May 16 '11 at 8:22
1 @AngryHacker Thanks, I've updated the code to add that in. – Luke Quinane Aug 14 '12 at 23:16
1 +1 This is really awesome. I 'was in a hurry' and quickly used it with great results! Will be refactoring this and mo
it to our company framework soon. – julealgon Jul 4 '13 at 19:55
1 This is a brilliant little piece of code. Needed to logon to a UNIX system to get a directory listing for printing to an
MVC5 web application and this did the trick. +1!!! – Tay Jan 27 '14 at 9:07
up I searched lots of methods and i did it my own way. You have to open a connection
vote16d between two machine via command prompt NET USE command and after finishing
own vote your work clear the connection with command prompt NET USE "myconnection"
/delete.
You must use Command Prompt process from code behind like this:
SaveACopyfileToServer(filePath, savePath);
Here is functions:
using System.IO
using System.Diagnostics;
if (!directory.EndsWith("\\"))
filenameToSave = "\\" + filenameToSave;
command = "NET USE " + directory + " /user:" + username + " "
+ password;
ExecuteCommand(command, 5000);
ExecuteCommand(command, 5000);
shareimprove this answer edited Jul 17 '13 at 13:09 answered Nov 25 '11 at 16:20
Hakan KOSE
463513
+1 this solution worked great for me - i needed to copy a remote file on a network share to my local machine. The
network share required a user and pass. – Simon Jul 10 '12 at 7:37
Actually i jumped the gun, it does work, however it leaves cmd.exe processes running!! Couldnt shut down at the
of the day. I tried wrapping it up in using blocks but still didnt work :( – Simon Jul 11 '12 at 2:58
I updated the code now. It works better now. – Hakan KOSE Jul 12 '12 at 10:49
Would be better if people included namespaces with their code... – Liquid Core Jul 15 '13 at 16:37
add a comment
Question:
Is it possible to change the thread principal to an user with no account on the local
machine?
Answer:
Yes, you can change a thread principal even if the credentials you are using are not
defined locally or are outside the "forest".
I just ran into this problem when trying to connect to an SQL server with NTLM
authentication from a service. This call uses the credentials associated with the
process meaning that you need either a local account or a domain account to
authenticate before you can impersonate. Blah, blah...
But...
Calling LogonUser(..) with the attribute of ????_NEW_CREDENTIALS will return
a security token without trying to authenticate the credentials. Kewl.. Don't have to
define the account within the "forest". Once you have the token you might have to
call DuplicateToken() with the option to enable impersonation resulting in a new
token. Now call SetThreadToken( NULL, token ); (It might be &token?).. A call to
ImpersonateLoggedonUser( token ); might be required, but I don't think so. Look it
up..
No promises but this worked for me... This is off the top of my head (like my hair)
and I can't spell!!!
Craig Armstrong
311
add a comment
up The Luke Quinane solution looks good, but did work only partially in my ASP.NET
vote3do MVC application. Having two shares on the same server with different credentials I
wn vote could use the impersonation only for the first one.
[DllImport("kernel32.dll")]
public extern static bool CloseHandle(IntPtr handle);
_token = IntPtr.Zero;
bool logonSuccessfull = LogonUser(_username, _domain,
_password, LogonType.NewCredentials, LogonProvider.WinNT50, ref
_token);
if (!logonSuccessfull)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
WindowsIdentity identity = new WindowsIdentity(_token);
_context = identity.Impersonate();
Debug.WriteLine(WindowsIdentity.GetCurrent().Name);
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Leave()
{
if (!IsInContext)
return;
_context.Undo();
if (_token != IntPtr.Zero)
{
CloseHandle(_token);
}
_context = null;
}
}
Usage:
var impersonationContext = new WrappedImpersonationContext(Domain,
Username, Password);
impersonationContext.Enter();
impersonationContext.Leave();
shareimprove this answer edited Mar 18 '14 at 14:49 answered Mar 18 '14 at 13:55
VladL
7,75693054
this approach worked well for me, but noticed in my testing that when using a bad password with a domain user
account, that user is immediately throw into locked status. our domain policy calls for a 3 failed login attempts befo
that happens, but via this approach one bad attempt and you're locked. So, use with caution... – kellyb Oct 2 '15 at
17:46
add a comment
608k13917032175
i don't think the process thing is such a bad idea. google put out some whitepapers about the benefits of
multiprocessing in chrome. – Dustin Getz Nov 17 '08 at 13:26
Is it possible to change the thread principal to an user with no account on the local machine? – gyrolf Nov 17 '08 at
13:52
To be honest, I simply don't know... You'd have to try LogonUser with a different domain to find out. – Marc
Gravell♦ Nov 17 '08 at 14:00
add a comment
More Information.
shareimprove this answer answered Nov 17 '08 at 13:12
GEOCHET
15.9k155883
add a comment
up If you can't create an locally valid security token, it seems like you've ruled all out
vote1do every option bar Win32 API and WNetAddConnection*.
wn vote
Tons of information on MSDN about WNet - PInvoke information and sample code
that connects to a UNC path here:
http://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html#
MSDN Reference here:
http://msdn.microsoft.com/en-us/library/aa385391(VS.85).aspx
shareimprove this answer answered Nov 17 '08 at 14:35
stephbu
4,6291838
add a comment
up May not be possible with .NET 2.0, but certainly with .NET 4.5 (maybe with 3.0 and
vote1do 4.0 too). Refer tohttp://stackoverflow.com/a/22378883/828062 for answer.
shareimprove this answer answered Mar 13 '14 at 12:40
wn vote
zendu
11113
add a comment
type ResourceScope =
| Connected = 1
| GlobalNetwork = 2
| Remembered = 3
| Recent = 4
type ResourceType =
| Any = 0
| Disk = 1
| Print = 2
| Reserved = 8
type ResourceDisplayType =
| Generic = 0x0
| Domain = 0x01
| Server = 0x02
| Share = 0x03
| File = 0x04
| Group = 0x05
| Network = 0x06
| Root = 0x07
| Shareadmin = 0x08
| Directory = 0x09
| Tree = 0x0a
| Ndscontainer = 0x0b
do
let userName = if String.IsNullOrWhiteSpace credential.Domain
then credential.UserName
else credential.Domain + "\\" + credential.UserName
let resource = new NetResource(networkName)
let cleanup(disposing:bool) =
if not disposed then
disposed <- true
if disposing then () // TODO dispose managed resources here
disconnect(networkName, 0, true) |> ignore
type CopyPath =
| RemotePath of string * NetworkCredential
| LocalPath of string
let createDisposable() =
{
new IDisposable with
member __.Dispose() = ()
}
if copySubDirs then
for subdir in dirs do
let subdirSrc =
match srcPath with
| RemotePath(_, credential) -> RemotePath(Path.Combine(dest,
subdir.Name), credential)
| LocalPath(_) -> LocalPath(Path.Combine(dest, subdir.Name))
let subdirDest =
match destPath with
| RemotePath(_, credential) -> RemotePath(subdir.FullName,
credential)
| LocalPath(_) -> LocalPath(subdir.FullName)
copyDir copySubDirs filePattern subdirDest subdirSrc
shareimprove this answer answered Nov 10 '15 at 16:22
python_kaa
439312
add a comment
up For VB.lovers the VB.NET equivalent of Luke Quinane's code (thanks Luke!)
vote0do
Imports System
wn vote
Imports System.Net
Imports System.Runtime.InteropServices
Imports System.ComponentModel
<DllImport("mpr.dll")> _
Private Shared Function WNetAddConnection2(netResource As
NetResource, password As String, username As String, flags As Integer)
As Integer
End Function
<DllImport("mpr.dll")> _
Private Shared Function WNetCancelConnection2(name As String, flags
As Integer, force As Boolean) As Integer
End Function
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class NetResource
Public Scope As ResourceScope
Public ResourceType As ResourceType
Public DisplayType As ResourceDisplaytype
Public Usage As Integer
Public LocalName As String
Public RemoteName As String
Public Comment As String
Public Provider As String
End Class
http://stackoverflow.com/questions/295538/how-to-provide-user-name-and-password-when-
connecting-to-a-network-share