Handle UnauthorizedAccessException When Directory.CreateDirectory() Run - c#

I have a method that is helps to Create a Directory ifNotExist and Save the path of the File ,...
Now I have a little problem, There is an Exception casted when Directory.CreateDirectory(savePath); Runs. and I can't still get it right. I would like to know what I am doing wrong and how to fix it. Anyone Subjections is welcome. Thanks
Here is My Method:
protected void ASPxUpload_FileUploadComplete(object sender, DevExpress.Web.FileUploadCompleteEventArgs e)
{
if (e.IsValid)
{
String savepath = String.Format("{0}{1}\\", MapPath(#"~\TicketUploads\"), Session["lastcallid"]);
if (!Directory.Exists(savepath))
{
Directory.CreateDirectory(savepath);
}
String savefile = String.Format("{0}{1}", savepath, e.UploadedFile.FileName);
e.UploadedFile.SaveAs(savefile);
String urlPath = String.Format("{0}{1}\\{2}", #"~\TicketUploads\", Session["lastcallid"], e.UploadedFile.FileName);
fault_detail fltdet = session.GetObjectByKey<fault_detail>(Convert.ToInt32(Session["lastcallid"]));
fltdet.hasattachment = "Y";
fltdet.AttachUrl = urlPath;
fltdet.Save();
}
}
For more details of What I trying to do:
It simple allows the web server to identify the ID of the log user. and With that ID, We should therefore create a folder in Ticketuploads Folder. Which is like we are trying to create 2 folders at the same time. That is why I use: "{0}{1}\\"

please try this
string sessionVariable = Convert.ToString(Session["lastcallid"]);
string path = Path.Combine(MapPath(#"~\TicketUploads\"), sessionVariable);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
Also
I have Add Administration Permission to the Folder. As a Local user with IIS System. user Add Example: IIS_IUSRS(Username\IIS_IUSRS) That's it.

Related

System.UnauthorizedAccessException error? I tried the Envirorment.getfolderpath/running as admin, but nothing works

static void SendMail()
{
String SystemErrors = DateTime.Now.ToString("d");
String filepath = #"C:\Windows\Boot\";
string filepath2 = filepath + #"\SystemErrors\somefile.text";
{
if (!Directory.Exists(filepath2))
Directory.CreateDirectory(#"c:\Windows\Boot\SystemErrors\somefile.txt");
if (!File.Exists(filepath2))
File.Create(filepath2);
}
Im trying to create a new folder and file.text, but nothing seems to work.
I don't think you're using the Exists methods correctly.
You must call File.Exists when you want to check if a file exists, and you must provide the path to the file.
Directory.Exists must be called when you want to check if a directory exists, and you must provide the path to the directory.

How can I fix this DirectoryNotFoundException?

I have a DirectoryNotFoundException on a .txt file if I use the full path it's working but I don't want to use the full path because I want the program work no matter where it is placed (compatibilty with the maximum of computer)
Here's my code
private void SaveClose_Click(object sender, RoutedEventArgs e)
{
if (Windowed.IsChecked == true)
windowed = true;
else
windowed = false;
string textWriteWindowed;
if (windowed == true)
{
textWriteWindowed = "-screen-fullscreen 0" + Environment.NewLine;
}
else
{
textWriteWindowed = "-screen-fullscreen 1" + Environment.NewLine;
}
var selectedResolution = ResolutionBox.SelectedItem.ToString();
var split = selectedResolution.Split('x');
widthChoose = Int32.Parse(split[0]);
heightChoose = Int32.Parse(split[1]);
string textWriteWidth;
textWriteWidth = "-screen-width " + widthChoose + Environment.NewLine;
string textWriteHeight;
textWriteHeight = "-screen-height " + heightChoose + Environment.NewLine;
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
File.AppendAllText(#"\Resources\arguments.txt", textWriteWidth);
File.AppendAllText(#"\Resources\arguments.txt", textWriteHeight);
this.Close();
}
The first argument of File.WriteAllText takes a path as input. Whatever you have mentioned is not the absolute path but it is just the relative path of the file. WriteAllText creates the file but doesn't create the directory by itself. So something like:
File.WriteAllText(#"\arguments.txt", textWriteWindowed);
shall work (and create the file in the respective drive), but
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
shall not work. Hence, if you want to create a file in the path where the application resides, you can do something like:
string folder=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
File.WriteAllText(#"\arguments2.txt", "ABC");
If you want to create a directory, then you could do something like:
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
file.Directory.Create();// If the directory already exists, this method does nothing.
System.IO.File.WriteAllText(file.FullName, textWriteWindowed);
Hope this answers your query.
you have to check whether the folder is exist before save the file,
if folder not exist create it using
Directory.CreateDirectory(...)
Directory.Exists(..)
you can use to check folder existence
IF you wanted to get the local path of the file you are executing use this:
var fInfo = new FileInfo(System.Reflection.Assembly.GetCallingAssembly().Location);
From there, you would do the following:
var parentDir = new DirectoryInfo(fInfo.DirectoryName);
var subDir = new DirectoryInfo(parentDir.FullName + "Resource");
if(!subDir.Exists)
subDir.Create();
This would ensure that you always have a folder in the directory of your executable. But just so you know, this is absolutely horrible code and should never ever be implemented in a production like environment. What if some knucklehead sysAdmin decides to place your program/folder in an area that the current user does not have access/writes too? The best place to write to is %APPDATA%, this will ensure the user always has read/write permissions to what you are trying to accomplish.
I don't know how but doing that worked for me :
File.WriteAllText(#"./arguments.txt", textWriteWindowed);
File.AppendAllText(#"./arguments.txt", textWriteWidth);
File.AppendAllText(#"./arguments.txt", textWriteHeight);

Upload multiple files & create zip

I managed to upload two kinds of files successfully & store the respective filepaths on the database. Now,I'd also like to create a zip with both files attached to it.
I referenced the codes to this particular webpage regarding zip files & file uploads
http://www.c-sharpcorner.com/uploadfile/5089e0/how-to-create-zip-in-asp-net-using-c-sharp/
Upon clicking the submit button, a File Not Found exception is thrown.
An exception of type 'System.IO.FileNotFoundException' occurred in Ionic.Zip.dll but was not handled in user code
Additional information: C:\Users\seldarine\Desktop\Proj\PP_PJ\PP_Project\SFiles\Submissions\blueteam\MyCodesF.zip
The exception is thrown at this particular line - objZip.Save(Path.Combine(serverFilePath,zipName));
Here are a portion of my codes :
protected void btn_submit_Click(object sender, EventArgs e)
{
string input = "";
string pp, vv,zip;
string extPp, extVv;
if (f_slide.HasFile && f_video.HasFile)
{
//Get file name & extensions
pp = Path.GetFileName(f_slide.PostedFile.FileName);
extPp = Path.GetExtension(pp);
vv = Path.GetFileName(f_video.PostedFile.FileName);
extVv = Path.GetExtension(vv);
string user = Session["userid"].ToString();
//where zip name is named after the username (current user) logged in
string zipName = user + ".zip";
//To save to folders
string filePath = "SFiles/Submissions/" + user + "/";
string serverFilePath = Server.MapPath(filePath);
//If directory does not exist
if (!Directory.Exists(serverFilePath))
{ // if it doesn't exist, create
System.IO.Directory.CreateDirectory(serverFilePath);
}
//****To create zip file*****
using(ZipFile objZip = new ZipFile())
{
string zipSlidePath = Path.Combine(serverFilePath,pp);
string zipVideoPath = Path.Combine(serverFilePath,vv);
objZip.AddFile(zipSlidePath);
objZip.AddFile(zipVideoPath);
***objZip.Save(Path.Combine(serverFilePath,zipName));***
}
//Store files
f_slides.SaveAs(Path.Combine(serverFilePath, pp));
f_video.SaveAs(Path.Combine(serverFilePath, vv));
.....
Try adding another line above the crashing one and see if you can debug it and what result you get:
var savePath = Path.Combine(serverFilePath,zipName +".zip");
You might also want to try changing the savePath variable to something like c:\temp\test.zip and see if that works.
var savePath = "c:\\temp\\test.zip";
Make sure the user under which the server is running has write access to that folder (serverFilePath).

%AllUsersProfile%(%PROGRAMDATA%) gives a repetitive file path

I have an application written in C#, and I am seeking to write some information to the hidden ProgramData in order to access the same connection string from both the application's front end and back end.
I am accessing the directory using path variables as follows:
private bool ProgramDataWriteFile(string contentToWrite)
{
try
{
string strProgramDataPath = "%PROGRAMDATA%";
string directoryPath = Environment.ExpandEnvironmentVariables(strProgramDataPath) + "\\MyApp\\";
string path = Environment.ExpandEnvironmentVariables(strProgramDataPath)+"\\MyApp\\ConnectionInfo.txt";
if (Directory.Exists(directoryPath))
{
System.IO.StreamWriter file = new System.IO.StreamWriter(path);
file.Write(contentToWrite);
file.Close();
}
else
{
Directory.CreateDirectory(directoryPath);
System.IO.StreamWriter file = new System.IO.StreamWriter(path);
file.Write(contentToWrite);
file.Close();
}
return true;
}
catch (Exception e)
{
}
return false;
}
This seems to work correctly. However, my question is, when I used this path variable: %AllUsersProfile%(%PROGRAMDATA%)
instead, it expanded into an illegal(and redundant) file path : C:\ProgramData(C:\ProgramData)\
However, I thought that the latter path variable was the correct full name. Was I just using it incorrectly? I need to ensure that this connection info will be accessible to all users, will just using %PROGRAMDATA% allow that? I am using Windows 7 in case that is relevant.
From here:
FOLDERID_ProgramData / System.Environment.SpecialFolder.CommonApplicationData
The user would never want to browse here in Explorer, and settings changed here should affect every user on the machine. The default location is %systemdrive%\ProgramData, which is a hidden folder, on an installation of Windows Vista. You'll want to create your directory and set the ACLs you need at install time.
So, just use %PROGRAMDATA%, or better still:
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)

Checking File Path When Deleting A File

If I have a web method that deletes a file when called and it accepts three parameters (cNum, year, and fileName). Do I need to be worried about exploits of this method. The only thing I could think of would be using ..\..\..\ to drive the delete further up the folder structure. that should be pretty easy to remove that. But is there anything else that I should be worried about?
[WebMethod(EnableSession = true,
Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
try
{
if (String.IsNullOrEmpty(cNum)
|| String.IsNullOrEmpty(year)
|| String.IsNullOrEmpty(fileName))
throw new Exception();
string path = Server.MapPath(#"~\docs\custFiles\"
+ year + #"\"
+ cNum + #"\" + fileName);
File.Delete(path);
}
catch
{
throw new Exception("Unable to delete file");
}
return true;
}
I would recommend using the GetFileName method on the Path class to cleanse the filename parameter, like so:
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
// Cleanse fileName.
fileName = Path.GetFileName(fileName);
The GetFileName method strips all directory information from a path, which is exactly what you want to do here.
With input like:
..\..\..\filename.ext
You would get:
filename.ext
In return, you don't have to worry about someone injecting a path which would escape the directory that you are targeting (assuming that this filename is user-input or from an open endpoint where someone could enter any input they want).
This then allows you to then append your custom path to fileName.
This only works of course if all of your files are in a pre-defined directory, which it seems it is.
This does not however, do anything to handle deleting files that a user doesn't have access to. If the files belong to another user in that directory, then there's no check here to see if that's the case (but if all users have rights to delete these files, then it's ok).
Also, you might want to use the Combine method on the Path class to combine your paths, like so:
string path = Server.MapPath(#"~\docs\custFiles\")
path = Path.Combine(path, year);
path = Path.Combine(path, cNum);
path = Path.Combine(path, fileName);
If you're using .NET 4.0 or above, you can use the overload of the Combine method that takes the parts of the path as a parameter array:
string path = Path.Combine(
Server.MapPath(#"~\docs\custFiles\"),
year, cNum, fileName);
Finally, as Shai points out, if possible (for a complete solution), to make this even more secure you should be enabling permissions on the file-system level.
If you are impersonating the user or using a constrained user account to handle all of the requests, then you should grant that user access to just the ~\docs\custFiles\ directory (and any sub directories).
Anything above that directory the user account should have no access to.
It is a good idea to check the file names and directory names if they are valid file names or not, check them against this char array:
Path.GetInvalidFileNameChars
EDIT:
And you should probably also validate the year and number like this:
bool valid = int.TryParse(num, out temp);
You may also want to consider using built in security on the file system to prevent users from deleting files in unwanted directories. If the web app is running under a specific user that has rights to delete files in only one directory, no matter what the user tries, the app will not have the rights to perform the delete.
In addition, this would make maintenance (ie: adding new directories) pretty easy without redeploying the app.
You could then catch the attempt to access the invalid access attempt and do something with it if you so desire.
[WebMethod(EnableSession = true,
Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
try
{
if (String.IsNullOrEmpty(cNum) || String.IsNullOrEmpty(year) ||
String.IsNullOrEmpty(fileName))
throw new Exception();
string path =
Server.MapPath(#"~\docs\custFiles\" + year + #"\" + cNum +
#"\" + fileName);
File.Delete(path);
}
catch (System.Security.SecurityException e)
{
throw new Exception("Unauthorized attempt to delete file");
}
catch
{
throw new Exception("Unable to delete file");
}
return true;
}

Categories

Resources