UnauthorizedAccessException when creating directory but only when impersonating myself - c#

I'm currently running into an odd little problem in an installation wizard. On one single test VM--all the others are fine--I cannot create subdirectories in a directory I created. On the first screen I select an install location and, if it doesn't exist, create it:
c:\Program Files\Foo
Then a couple screens later, I get user credentials for the software to use and, to make sure they have the appropriate permissions, use them via impersonation to create subdirectories under Foo, say Bar and Baz. The impersonation I'm using is based on link.
The thing is, if I'm logged in as myself, that first directory is created just fine. But if I put my EXACT SAME CREDENTIALS into that later screen, it fails to create those subdirs. Despite the fact that it's the same creds that the program itself are currently running under.
Also, as I said, this works literally everywhere else except this one machine. So it doesn't make any sense. All we can figure is something broken about the impersonation system. That's all we can figure. But you'd think it would show up elsewhere. If it was something with the VM, then how did we create the Foo directory in the first place?
Anyway, any suggestions would be most welcome. This is really nutso.
EDIT: I have verified my account is local Admin on the VM. Nothing helpful in the Event viewer. Also, fixed link to MS impersonator code.

Related

How to grant ownership of Files and Folders in Windows

I came across a very anoying problem and it took me a while to solve it. Since 99% of the internet was telling me it was not possible and i could not find the answer on stackoverflow i decided to post it here.
I was trying to change the ownership of an folder/file in my windows machine. This is not much of a problem since DirectorySecurtiy has a nice function for it: "SetOwner()". I got this to work for my current account but i could not get it to work for someone else. Everytime i tried to grant someone else ownership i got this error: “The security identifier is not allowed to be the owner of this object”.
// Get folder or creates if not exists
DirectoryInfo dInfo = Directory.CreateDirectory(folderPath);
// Get user
IdentityReference user = new NTAccount(username);
// Set owner
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.SetOwner(user);
dInfo.SetAccessControl(dSecurity);
So this code does work if i want to grant myself ownership but not if i want to grant someoneelse ownership. What to do?
After searching the internet further I found the solution in this blog: https://fixingitpro.com/2011/07/08/set-owner-with-powershell-%E2%80%9Cthe-security-identifier-is-not-allowed-to-be-the-owner-of-this-object%E2%80%9D/
It is very strange and i dont know why but if you use unc pathing it will work.
UNC names identify network resources using a specific notation. These names consist of three parts: a host device name, a share name, and an optional file path.
These three elements are combined using backslashes: \host-name\share-name\file_path
So what used to work for myself only: D:\{folderName} had to be: \\{IP or servername}\d$\{foldername}. If you test the exact same code agian only than with a different path it will work. Would be nice if someone could explain me why routing back to your own computer does work by a normal path does not.
Dont forget to run your application as administrator

Directory.exists returns false for mapped drive in c# coding

I am using Directory.Exists() in my windows service (that is programmed in C#, 3.5 framework)to check to see whether a particular directory exists in the drive. When I run in local machine it works fine, meaning I am able to access the directory.
But when I deploy the windows service on a Virtual Machine, and start the service, it is not able to find the directory even though the directory exists. The directory is mapped on as
Q: drive, Q:\\temp\\local\\ folder
But the windows services always returns false for the Directory.Exists().
However when I give C:\ drive in place of Q:\ it works, but does not work for a mapped drive. I have tried with the UNC path, and I have made sure the mapped drive have the administrative rights and infact the read, write and execute permission. But it still returns false.
Can anyone please tell me why? And how to resolve?
Make sure the drive is mapped under the same user as the Service is running. If you map the drive as user A, it is not automatically mapped for anyone else too.
Mapped drives are only restored during interactive login which services generally do not perform:
Map a network drive to be used by a service
Short version: You can't do it, use the full UNC path instead.
This is most probably a problem with privileges. Your Windows service is probably running under an account which doesn´t have enough privileges to access the network path.
This is a possible duplicate: Accessing mapped folder from a Windows Service written in C#
Another possible solution is to use impersonation, check it out:
http://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.90).aspx
UPDATE
Came to think of it;
Try changing the identity of the application pool to a user with the same rights as your user.
As #Sriram pointed out the Directory.Exists() method will fail if any error occurs. What sort of exception do you get if you try to access the path?
Eg (for both mapped and UNC in case there is something going on there):
DirectoryInfo diMapped = new DirectoryInfo(#"Q:\temp\local\folder");
DirectoryInfo diUNC = new DirectoryInfo(#"\\servername\fnsw\tmp\126");
Note: Assuming that the white space before 'folder' in your path is a typo?
Steps to troubleshoot
Try accessing the network path manually in "Run" [WindowKey + R]
Try to access your map drive i.e.: M:\
Make sure you are the account owner of the mapping (mapping should be done under your account)
Go to Property and see if "Run As Administrator" is unchecked.
Remove mapping and re-add the mapping.
Make sure available offline (or sync offline) is turned off and folder is available from another computer.
Hope this helps!

C# - Access to mounted networkdrive

I have some networkshares mounted to my PC. I can see them in the Windows Explorer, with drive letters etc. If I try to read or write with c#, I always get a DirectoryNotFoundException.
The method to check if the directory exists
Directory.Exists(#"N:\test")
returns false (N:\ is the mounted share). If I open the path in the Explorer, the path exists.
Can you imagine, what the problem could be?
Thank you!
I just tested to see if this works when I run the application as administrator and it failed. So the reason is most probably because the user under which you execute the code doesn't have access to the path.
As you confirmed that you were indeed running the application with elevated privileges, you should follow the indications that are also suggested in this answer :https://stackoverflow.com/a/11268410/674700:
(...) open an administrative command prompt - where you have an
elevated token all the time - and create a matching drive mapping from
there (net use h: \server\share1). Since the standard user and the
elevated administrator have a common understanding of what "H:" drive
means, everything runs okay.
Well, I just try to assume why you can get this exception, here it is;
First of all, Directory.Exists() method works fine for network mounted drives. There could be a few more reason that why you get DirectoryNotFoundException in your work.
From MSDN;
The Exists method returns false if any error occurs while trying to
determine if the specified file exists. This can occur in situations
that raise exceptions such as passing a file name with invalid
characters or too many characters, a failing or missing disk, or if
the caller does not have permission to read the file.
I believe you have one of this but since we can't acces your computer, we can't know the real reason :)

Writing to appdata folder - permission issue?

I've had a scout around some answers to similar questions but they haven't really helped me much.
I have an app, into which I've embedded some resources. At launch the app checks to see if the resources exist in the appdata folder and if not copies the template files from the embedded resources to the appdata folder before loading them and then using the ones in the appdata folder as the working copies.
I have a helper class which amongst other things returns the appdata and resources subfolder as follows:
class Folders
{
static public String GetUserFolder()
{
return Application.LocalUserAppDataPath;
}
static public String GetResourcesFolder()
{
// If the resources folder does not exist then create it
String userFolder = GetUserFolder();
String resourcesFolder = userFolder + "\\Resources";
if (!Directory.Exists(resourcesFolder))
{
Directory.CreateDirectory(resourcesFolder);
}
return resourcesFolder;
}
...
So my code calls the GetResourcesFolder method which returns the path (creating the folder in the process if it needs to) checks to see if the file exists and if it doesn't tries to write to it using something like:
String filename = Helpers.IO.Folders.GetResourcesFolder() + "\\data.dat";
FileStream outFile = System.IO.File.OpenWrite(filename);
So I've set the scene and this code is working on all the machines I had in the development office. However a couple of off site colleagues have complained it "crashes" on their machines - in each case an XP machine - but otherwise not a lot of useful information coming back from them - working on trying to get something more informative from them. I have XP machines in the office that it has worked on without problems.
After digging out some really old dev machines that were "archived" a while ago, I've managed to have a crash on two xp (sp2) machines also. On both occasions the crash seems to be related to write permissions and running the app using "Run As..." has resolved the problem and it executes correctly. However once the app has been successfully run once the app no longer crashes, even if I delete the files/folders it created from the appdata folder it will still create the successfully on subsequent executions even if I don't elevate permissions.
The problem I have is that I can now no longer repeat the crash on any dev machines available to me and I don't know how to go about putting the machine back into the state where I can.
Anybody got any ideas on what might be causing the problem, or how I may be able to return the machines to a "virgin" state to be able repeat the crash and help me track it down.
One course of action is to create a Virtual Machine of XP. You can save the state of the machine before install for testing. After your install just revert back to the previous state to test again. There are a few Vendors with free Virtual Machines:
http://www.microsoft.com/windows/virtual-pc/
https://www.virtualbox.org/
As too the related problem itself, I don't know a better way than to install VS on a virtual machine for testing purposes.
+1 to Erik's VM solutions for reporducing the issue.
For tracking down permissions issues consider using ProcMon ( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx ) - will show enverything you ever wanted (and not :) ) about file/regisstry access made by a process. I'd recommend trying it several times first on machine where you program works fine to get filtering setup for your process and get a sense of what should be happening.

Directory.Move() works in debug mode, but not when deployed

I have a webapp which has read/write/execute access to an aliased directory. When I am in debug mode in Visual Studio, the following statement works:
Directory.Move("\\\\localhost\\Alias\\oldDirectory","\\\\localhost\\Alias\\newDirectory");
The net result is that, oldDirectory is now newDirectory in the aliased directory.
But, when I'm testing this code in pre-production, I have oldDirectory and newDirectory in the aliased directory. Directory.Move is now behaving as if it is only copying oldDirectory to newDirectory.
Why is this happening?
This is most likely a permissions issue.
The user account that is executing this command probably has Create / Write permissions but not Delete permissions in the aliased directory. I would check whether the user account that the program is executing under has Delete / Delete Subfolders and Files permissions.
Edit:
To test this theory, I would temporarily grant the Users group Full Control over the folder to see if the problem goes away.
Make sure the folder is not under write-protection and no process is accessing any files at the moment you are trying to move the folder.
Also check whether you gave the security permissions to the correct user, by verifing under which user account the applicationpool is running.
You might also want to consider developing on a local IIS to prevent such situations in the future (I've been there; not nice)
I believe that, instead of using Directory (which is static) I used DirectoryInfo which solved my problem. I think that the heart of the issue was that Directory does more security checks than an instance of DirectoryInfo does. I'm still unclear why this is, but it seemed to work.

Categories

Resources