This is not actually my own code and I don't have a way to change and compile it, but I'm trying to debug a program and all it does is download a file and store it locally. It's literally something like:
try {
using var client = new WebClient();
client.DownloadFile( URL, filename );
log("File successfully downloaded");
}
catch (Exception e) {
log("Download failed.");
}
URL and filename are passed as arguments so I can actually change those. If filename is a local path, like for instance "/home/myusername/test.dat", it works fine. So I know the code works. But if filename resides on a mounted NAS (ie "/mnt/NetworkDrive/test.dat"), it gives the "Download failed" error.
It looks like the user the code runs under, does not have write permission to the mounted network share. But I mounted the network share with the noperm option, and creating files manually always succeeds, no matter what user I try it as.
The network share is mounted through /etc/fstab:
//192.168.1.131/sharedfolder /mnt/NetworkDrive cifs guest,_netdev,vers=1.0,noperm 0 0
Where 192.168.1.131 is ofcourse the IP address of the NAS. It's an older NAS which uses SMBv1 which is why I mount it with "vers=1.0" And like I said, I can access the NAS just fine. I can create files and delete files from the command prompt without problems. As any user. But the above code fails to write to it.
What could be causing this?
Again, this is not my code so I can't change anything. But I'm sure the code is fine and something else is at play here.
UPDATE #1 (Mar 31)
So it turns out writing to the NAS is denied, which is weird because if I test it (from the command prompt), I can create and write to a file on the NAS without problems. As root or any other user.
UPDATE #2 (Mar 31)
I've been troubleshooting all day and I'm at a loss. Any user has full access to the NAS and can read/write/delete/create/modify files. I can create a new user on the system and it too has full access. But WebClient.DownloadFile always fails with a "Permission Denied" as soon as it tries to write the downloaded file to the NAS. If I write it to a local path, it works fine.
Related
I tried to create a C# Windows Forms tool to copy entire content from my local machine to another machines on the domain.
The problem that most solutions to copy just file not entire directory is not working.
I can't using Impersonation to change user context and then use File.Copy() to copy content cause the users on the remote machines different than the user on my local machine.
using ( new Impersonator( "yourUsername", "yourDomain", "yourPassword" ) )
{
// The following code is executed under the impersonated user.
}
Also to use File.Copy() like that:
File.Copy(
#"C:\Users\user\Desktop\file.txt",
#"\\remote\Users\user\Desktop\file.txt"
);
the remote path should be a shared path, and this is not the case here as i have a credentials to servers but want to copy the directory to specific not shared location.
I found another solution that uses PSexec tool to activate listener on the server and then send files to it from my local machine (Socket programming) but it's not stable: you can find it here
I also think about writing a powershell script that can do that and i run it from my C# program.
So is it another solution for doing that in a correct way, Copying entire directory/directories from local to remote machines.
I have an application, it first maps a network drive using credentials entered by a user. The drives successfully map, however when it tries to run a program from Process.Start(). I get Directory Name is invalid.
From my research I've read to put the working directory for when using a username/password in the StartInfo. However this doesn't work. The working directory is a mapped drive. Before this starts I do a if (File.exists(w:\folder\filename)..Process.start....
I tried to hardcode the working directory to C:\ but it still failed as it stated it could not find the file.
So when running the Process.Start as another user you cannot use a network path, even though that path was mapped by the same account? Am I forced to download the app locally so the Process.Start can work properly?
Any help would be greatly appreciated.
You are correct, network shares are a per user token. Running a process as another user (or as the same user in a elevated state) causes a new user token to be created and therefor all active shares are "unmapped" from the perspective of the new process.
You have a few options. The first thing I would try using is use the full UNC path instead of a mapped network drive letter. It may just work if you try that (the new user you are running as will need permissions to connect to the share)
If you are forced to use a drive letter instead of a UNC path then write a small loader program that you launch as the new user, have that map the network drive in the context of the new user token, then start up your program that relies on the drive.
P.S.) Using C:\ did not work as the working directly likely because C:\ is a protected folder that only administrators can write files to. If you created a sub folder C:\MyTestFolder\ and set the proper permissions on it I bet it would have worked.
I've written a console app to help load code to servers, but I'm running into an issue running it. I'm getting a "System.UnauthorizedAccessException: Access to the path '\...' is denied.
The app is comparing files, and those that are different it copies from a staging area to the server. It runs fine until I try to copy, then I get this error (e.g. I can read and compare the files, but not modify them). If I (manually) simply copy a file from one area to the other, no issues.
I was under the impression that a console app runs as the person who executes it.
The offending code is this:
File.Copy("correct staging path", "correct live path", true);
I was able to verify that the application is running as me using:
Environment.UserName (WindowsIdentity.GetCurrent().Name shows the same)
The destination path is a network share (e.g. \\servername\path)
I have made a little app that's running on a Win7-PC. All it does, is to check the content of a network drive at 1:00 O'clock in the morning (and compare it to a folder on its local hard drive), and if thereĀ“s differences, copy the differences to this folder.
The problem is, sometimes it can not find the network drive.
When the app starts up, the network drive is found using a button on the app which starts OpenFileDialog, and the resulting drive letter is put into a textbox beside the button. From that point it should just run by itself. The PC is never turned off.
When it says the network drive can not be found, I can manually press the button on the very same app, select the drive in the OpenFileDialog (the drive letter never changes), and the app will run flawless in a couple of days. Then the problem occurs again.
The question is: Why can the network drive be accessed through the OpenFileDialog on my app, but my app can not?
My app start the copy-process using this function (called with "Y:\") to determine whether the drive is present or not:
public bool fn_drive_exists(string par_string)
{
DirectoryInfo di_dir = new DirectoryInfo(par_string);
if (di_dir.Exists)
{
return true;
}
return false;
}
...and sometimes it returns a False, until I "wake it up" using the OpenFileDialog.
What does OpenFileDialog do, that my app do not?
According to this SO post, the problem should be gone if you use UNC path instead of mapped network drive.
If your destination has a static ip address, I suggest you use that ip address instead of domain name for network drive
This SO post describes a similar scenario to what you've described.
One of the links posted as a response to that question led me to this MSDN article which provides a variety of reasons as to why one might encounter errors when trying to access shared network drives by using a mapped drive letter.
Microsoft's suggestion (see below) is to simply use a UNC path.
A service (or any process running in a different security context) that must access a remote resource should use the Universal Naming Convention (UNC) name to access the resource.
To answer your actual question more specifically, with regards to why it suddenly can't access the network share, I would venture a guess to say that the network share is being disconnected by Windows due to an idle timeout, as discussed in KB297684. Any attempt to access the disconnected drive will be met with a small wait as the connection to the network share is re-established, which could presumably be what is causing your issue.
To test this theory, try writing some data to a file on the network drive at a relatively short interval (every 10 minutes, perhaps?) to try and convince Windows that the drive is still active.
You can also try to use:
System.IO.Directory.Exists(par_string);
instead of writing Your own method for the same thing. I would expect a framework method to be able to "wake" the network drive.
Note: Method also works for UNC paths (something like \\<server name or IP address>\<shared folder>)
Like Harvey says, use the UNC path to access the folder, for instance \\server\sharedfolder. In place of \\server use the name of the server. Your computer has a name and so does the server. You can also use the IP address if you know it. You replace \sharedfolder with the path to the files. Some examples:
\\AppsServer\c$\Program Files(x86)
\\FileServer1\d$\Users\John\My Documents
The c$ represents that the C drive is the shared folder. If the entire drive is not shared, you will need to share the specific folder. You can do that by logging onto the server, right clicking the folder, and selecting Properties. Then you go to the Sharing tab and check the Share this folder checkbox. If your shared folder is called MyShare, then your UNC path to access the folder will be
\\server\MyShare
I have a Windows service, running using the login localhost\administrator. This service is meant to invoke another executable (MyProcess.exe), which is supposed to write some stuff to a log file. The service uses Process.Start() to create the process, like so:
var p = new Process();
p.StartInfo.FileName = processFileName;
p.StartInfo.Arguments = arg;
p.Start();
Problem is, it appears that MyProcess.exe is being denied rights to write to the log file, even though localhost\administrator unquestionably has rights to the log folder. If I run MyProcess.exe from a command line, it works perfectly.
So, is it possible that the process is being executed using a different user login?
Can you think of any other reason why MyProcess.exe is being denied rights to write the log file?
UPDATE: the log file is being written to the local machine, but using a network address, i.e. \\MyPC\LogFolder. When I change the code to refer to C:\MyFolder, everything works fine. It's obviously having a problem with the network address (even though it's local).
What sharing settings do I need to put on the folder so that the local system account can access the file?
If you are using impersonating, than it impersonates a user that can be the currrent or a specified user. if not it will run under the Local System, with the privileges of the local system.
p.StartInfo.Domain = "UserName";
p.StartInfo.Password = "Passw0rd!";
You can get the username from:
Thread.CurrentPrincipal.Identity.Name
I've worked it out.
The problem, as noted in my update, is that the process was addressing the log folder using a network share address, \\MyPC\LogFolder, and when we switched the configuration so that it wrote instead to c:\Logfolder, it worked fine.
So it seems that when you address a local folder, the localhost\Administrator account is deemed to have sufficient rights. But when you go via the network share, you need to present valid network credentials, and localhost\Administrator just doesn't cut it. If you change to use MYDOMAIN\MyUser, it works even using the network share address.