I am building a .net C# console program to deploy file to a windows file share server (folder that is being shared). The path is :: \\192.168.0.76\htdocs\public
On running I am getting the error:
[09:35:29]: [Step 1/3] Unhandled Exception: System.UnauthorizedAccessException: Access to the path '\\192.168.0.76\htdocs\public' is denied.
[09:35:29]: [Step 1/3] at DeployFileShare.Program.CopyDir(String source, String dest, String[] exclude, Boolean overwrite)
[09:35:29]: [Step 1/3] at DeployFileShare.Program.Deploy(String num, String source)
[09:35:29]: [Step 1/3] at DeployFileShare.Program.Main(String[] args)
[09:35:29]: [Step 1/3] Process exited with code -532459699
I think I need to authenticate myself. I've come across this:
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsIdentity idnt = new WindowsIdentity(username, password);
WindowsImpersonationContext context = idnt.Impersonate();
I've also tried:
AppDomain.CreateDomain("192.168.0.76").SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsIdentity idnt = new WindowsIdentity("user", "pass");
WindowsImpersonationContext context = idnt.Impersonate();
I am not sure how to use it. When I run the application I get:
C:\Users\Administrator>DeployFileShare 1 R:\BuildOutput\_PublishedWebsites\Web 2
1
Deploy Started Web, version 21
-- Deploy Prepared
-- Deploying to 1
Unhandled Exception: System.Security.SecurityException: There are currently no l
ogon servers available to service the logon request.
at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName,
String type)
at DeployFileShare.Program.Authenticate(String server)
at DeployFileShare.Program.Deploy(String num, String source)
at DeployFileShare.Program.Main(String[] args)
The Zone of the assembly that failed was:
MyComputer
Here is the basic code:
static void Main()
{
Copy();
}
static void Copy()
{
AppDomain.CreateDomain(GetServerInfo(server, "server")).SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsIdentity idnt = new WindowsIdentity(GetServerInfo(server, "user"), GetServerInfo(server, "pass"));
WindowsImpersonationContext context = idnt.Impersonate();
string source = "C:\\someDir";
string dest = "\\192.168.0.76\shareFolder"
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
foreach (string file in sourceFiles)
{
string local = file.Replace(source, "");
if (exclude.Contains(local))
continue;
if (!Directory.Exists(Path.GetDirectoryName(dest + "\\" + local)))
Directory.CreateDirectory(Path.GetDirectoryName(dest + "\\" + local));
File.Copy(file, dest + "\\" + local, overwrite);
Console.WriteLine("-- -- [copied] {0} -> {1}", file, dest + "\\" + local);
}
}
The code copy system in the for loop works, I've tested it on my local system.
If anyone knows how I should use WindowsIdentity and WindowsIdentity to get this to work please enlighten me. I've been looking around and window's documentation doesn't help much.
Basically how can I copy to a remote directory being shared by logging into the system?
To share a file or folder over a network in File Explorer, do the following: Right-click (or long-press) a file, and then select Show more options > Give access to > Specific people. Select a user on the network to share the file with, or select Everyone to give all network users access to the file.
Try using the net use command in your script to map the share first, because you can provide it credentials. Then, your copy command should use those credentials.
Double-click the name of the computer from which the folder you want to open is being shared. Select a folder. Double-click the folder you want to open. Enter a username and password if prompted.
In the Folder box, type the path of the folder or computer, or select Browse to find the folder or computer. To connect every time you log on to your PC, select the Reconnect at sign-in check box. ** This is the point where you should also choose "Connect using different credentials".
VB but easily translated to C#. Do this before your copy:
Private Sub Open_Remote_Connection(ByVal strComputer As String, ByVal strUserName As String, ByVal strPassword As String)
Dim ProcessStartInfo As New System.Diagnostics.ProcessStartInfo
ProcessStartInfo.FileName = "net"
ProcessStartInfo.Arguments = "use \\" & strComputer & "\c$ /USER:" & strUsername & " " & strPassword
ProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden
System.Diagnostics.Process.Start(ProcessStartInfo)
System.Threading.Thread.Sleep(2000)
End Sub
If you want to authenticate to a remote computer in order to move a file, you can use the LogonUser function to and WindowsIdentity to impersonate your user.
/// <summary>
/// Exécute une fonction en empruntant les credentials
/// </summary>
private T ApplyCredentials<T>(Func<T> func)
{
IntPtr token;
if (!LogonUser(
_credentials.UserName,
_credentials.Domain,
_credentials.Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
out token))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
try
{
// On doit être impersonifié seulement le temps d'ouvrir le handle.
using (var identity = new WindowsIdentity(token))
using (var context = identity.Impersonate())
{
return func();
}
}
finally
{
CloseHandle(token);
}
}
// ...
if (_credentials != null)
{
return this.ApplyCredentials(() => File.Open(path, mode, access, share));
}
return File.Open(path, mode, access, share);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With