Read Files from Remote Drive in Intranet App - c#

I want to read file names of pdfs from a folder on a network share that match certain parameters and provide a link to view them on a details page for my model. All I need to get is the file name. I don't need any file management/read/write at this time.
I'm able to display a .pdf in the browser if I have the path (IE will open "file://" links). The part I'm missing is getting file names from the remote (but same domain) directory at run-time.
We've set up a virtual directory for the app to use and that has worked fine in the past if the resolved physical folder is on the same server, but that is not the case here.
I've tried Impersonation, but that doesn't seem to work as I'm still getting an access is denied error.
I realize this would probably be a security issue and is why it isn't allowed, but is there an IIS configuration or other avenue that needs to be set-up to allow this? I can't seem to find a way with just code that opens the directory for reading.
Example code of how I might normally read some info from one file in a virtual directory:
// This example code is inside a controller action, so Server refers to HttpContextBase
var path = Server.MapPath("~/MyVirtualDirectory/" + fileName);
var fileExists = System.IO.File.Exists(path);
var fileLastModified = System.IO.File.LastWriteTime(path);
To enumerate over matching files in a directory, I've used DirectoryInfo
var pdfFileNames = new List<string>();
var dir = new DirectoryInfo(Server.MapPath("~/VirtualDirectory/"));
var pdfs = dir.EnumerateFiles("*.pdf");
foreach (var pdf in pdfs)
{
pdfFileNames.Add(pdf.Name);
}
As I mentioned, these methods work fine when the physical folder is on the same server, but once the directory is on a remote drive, then it no longer works. I have permissions to open the desired directory and my collegue said he gave the appropriate permissions to the virtual directory and server. Not sure what else to try at this point.
Edit: Now that it is working, I display the files using the Virtual Directory
http://server/appName/virtualDirectory/pdfFileName

By default, IIS application pools run under a specific local Windows identity named IIS APPPOOL\[NameOfYourAppPool]. This is a local user and it will not be possible to grant permissions to this identity to access resources located on a different machine.
If both servers are inside the same domain, you can try the following solutions:
Run the IIS application under a domain user and grant the required permissions to this domain user.
Run the IIS application under the NetworkService identity and grant permissions to the DOMAIN\MACHINENAME$ account of the IIS server.

Related

Access to the path is denied in ASP.Net

I have an ASP.Net application running in IIS which creates a file in a specified location using CsvWriter. If I use the full UNC path I get error that Access to the path is denied, however if I use Drive letter it works fine. What is puzzling me is that it does work with UNC path in development environment.
This code which creates the file
using (var writer = new StreamWriter(fileName))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteField("Foo");
csv.WriteField("Bar");
csv.NextRecord();
}
Following advice various posts such as Access to the path is denied and IIS7 Permissions Overview - ApplicationPoolIdentity and MS Documentation: Application Pool Identities. I was initially convinced my problem was security related. This was supported by the fact that the application would run perfectly in development environment (IIS Express) which uses my user credentials but not under IIS which uses Application Pool Identity. I gave MyApplicationPoolIdentity full access to the specific directory to no avail.
However, I discovered that if I use the drive letter (C:\myDirectory\mySubDirectory\myFile.csv) as opposed to the UNC path (\\myServer\myDirectory\mySubDirectory\myFile.csv) in production the file is created perfectly. Even though I have the application working my concern is that I may have some configuration issue with IIS or my server which may bite me later. So my question is what would cause the create file/write to fail using UNC path and not using Drive letter?
I am using Windows Server 2016.
Thanks
Tony
I think it is caused by permission issues. First, did you get any related error messages? Or you can try the following methods:
1.you can use Process Monitor to see which account is being used to access the share and what permission are required.
2.Check to ensure the account that IIS is running under has needed rights to the troublesome UNC.

Denied acces to a file

I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.

The Directory Name is Invalid, mapped drives & username

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.

Permission error when uploading files

I have the following code:
var saveFolder = Path.Combine(Properties.Settings.Default.DropBoxFolder, guid.ToString("N"));
// Create folder, if it does not exist (for the first attachment, it shouldn't exist)
if (!Directory.Exists(saveFolder))
{
Directory.CreateDirectory(saveFolder);
}
var saveFilePath = Path.Combine(saveFolder, file.FileName);
file.SaveAs(saveFilePath);
I'm using GUIDs to generate folders for uploads on my IIS server. The .NET web application is configured to impersonate the user. I granted modify permissions to the target folder (it is a local path on the web server) for Domain Users, Local Service and Everyone, but some users still can't upload files. I can and other people on my team can.
The weird part is that the exception says this:
Could not find a part of the path 'C:\Users\USERID\Desktop\FILENAME'
That path is the path to the file the user selected to upload (their local file path). I feel it is safe to say that the user has permission to his own file on his own desktop. I don't use user impersonation much, so I am wondering what I missed in my configuration or permissions. Any suggestions for debugging this issue? Thanks!
Note: the CreateDirectory method works just fine, even when the exception is thrown. I would have thought that if the user didn't have permission the directory creation would have failed first.

How can I grant permissions for a FTP Folder for users of the active directory

I have a asp.net web application that creates a Folder on a FTP site, but I need to grant permissions to that folder to some users of the active directory.
How can I do that programatically, inside my app when I create the folder?
Standard FTP does not allow for changing of permissions or file ownership, but it is reasonably common for FTP servers to allow this sort of thing through custom SITE commands. At least, this is common for UNIX hosted FTP servers.
Try connecting to the server with a standard FTP client and typing site help. That should give you a list of the custom SITE commands available. You can then get the usage for a specific command by typing site help <cmd>.
I'm not sure what your options will be against a Windows-based server, as the permissions model is more granular than with standard UNIX permissions. On a UNIX server, you can often change the group ownership and the permissions, but changing the file owner is not allowed unless you're root. I shouldn't have to say that logging into an FTP server as root is a really bad idea.
I hope that's some help.
R
You don't say what kind of FTP server you are running, or in what manner you want the AD user to interact with the new folder. I'm assuming that you are using IIS's FTP Service, and that you need your AD users to be able to use FTP to access the new folder.
IIS uses the same access rights as other file access methods in Windows (accessed from the Security tab on the folder's Properties view).
I created a WinForm that would do the following: create a new local user account (and add them to a group), create a new directory under our FTP Server's base directory, create a new Virtual FTP Folder (so that a user could map a connection to the folder), and finally give the new user full control of the new directory (and because the directory was a Virtual Folder, the new user has full control via FTP).
It sounds like you don't need to create the new user, you just need to give them permission to make changes to the new directory. In my app I shell out to invoke a batch file and pass it a few parameter.
The command for modifying a directory (or file's) access rights is:
cacls [The path to your new directory] /E /P [The AD user name]:C
I don't recall what those parameters mean any more; I suggest you research the command to make sure it does exactly what you want.
To execute this from VB.Net:
Shell(System.Configuration.ConfigurationSettings.AppSettings.Item("CACLS_batPath") & " " & strFolderPath & " " & _strUserName, AppWinStyle.NormalFocus, True, -1)
That will open a visible command window and execute the batch file, passing it the parameters. (It just occured to me that I'm doing this in WinForms and it might not be that easy to call from ASP.Net, check here for information about executing a batch file from ASP.Net: http://codebetter.com/blogs/brendan.tompkins/archive/2004/05/13/13484.aspx)
The contents of the BAT file are:
echo "update file permissions"
cacls %1 /E /P %2:C
REM PAUSE
Good Luck!
I'm assuming that you are creating the folder and want to set the permissions in a c# application.
You want to look at the DirectorySecurity class (msdn)
You create a directorySecurity class for the newly created directory and then you add FileSystemAccessRules to define the appropriate access based on AD users and groups.

Categories

Resources