File visible as normal user but not as Admin - c#

I am building an universal updater for my company, and when I try to access a mapped network drive, the program throws a file not found exception when run as admin. When the file is run as a normal user the files are visible, but throws an Unauthorized Exception due to the fact that the files are copied to the Program Files (company policy).
Edit
The code that throws the FileNotFound Exception is FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(rdrInner.GetString(2)); and the Unauthorized Exception is thrown by File.Copy(pi.RemotePath, pi.Path, true);

Mapped drives are part of the user profile, so you need to map the drive whilst logged in as the admin user. This is why using a mapped drive is a bad idea--can't you use a fully qualified UNC path instead? See http://msdn.microsoft.com/en-gb/library/gg465305.aspx for an explanation of UNC paths.

Related

How can I take ownership of files with incorrect security?

I have a folder structure on a (Server 2003 SP2) file server and I need to delete it using C#. I can't do that because I get System.UnauthorizedAccessException: Access to the path '\\xyz\blah\...' is denied. (where the path points to a sub-folder) because the permissions on the sub-folder are incorrect. So, I've been trying to take ownership of the files and this fails with System.UnauthorizedAccessException: and now I'm stuck.
Detail
I have an admin tool used by users with minimal privs. They need to delete folders and files to which they don't have access, so I wrote a UI which calls a web service. The web service runs under an AppPool with a domain account which is (now) a member of Administrators on the file server, so it should have access to delete the files and folders. But some of the folders have incorrect permissions. For example, when I log onto the file server with an account in Administrators and open the security tab for the folder, I see:
And for these folders my code doesn't work.
I've given the appPool account 'Take ownership of files or other objects' on the web server using Local Security Policy. Other posts (e.g. this one) have pointed out that you need to explicitly enable SeTakeOwnershipPrivilege in code and recommended Process Privileges which I'm using in my web service:
using (new PrivilegeEnabler(process, Privilege.TakeOwnership))
{
System.Diagnostics.Debug.WriteLine(String.Format(
"Privilege:TakeOwnership status: {0}.",
process.GetPrivilegeState(Privilege.TakeOwnership)));
SetFolderOwnerToCurrentUser(folderName, groupName);
}
When I run this, I see:
Privilege:TakeOwnership status: Enabled.
(Before adding the priv via LSP, I was seeing Privilege:TakeOwnership status: Removed.)
In SetFolderOwnerToCurrentUser if I just use
var directorySecurity = new System.Security.AccessControl.DirectorySecurity();
directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
System.IO.Directory.SetAccessControl(folderPath, directorySecurity);
I also get System.UnauthorizedAccessException: Access to the path '\\fs\blah' is denied. Again, it's the sub-folder it's complaining about.

System.UnauthorizedAccessException (A first chance exception)

I am getting the
A first chance exception of type 'System.UnauthorizedAccessException'
occurred in mscorlib.dll
exception from this bit of code:
string[] filesList = Directory.GetFiles(#"C:\Program Files (x86)\", "*.exe",
SearchOption.AllDirectories);
What its doing is listing all files with an .exe extention, although for certain directories it works, but some it throws this.
Any ideas on what I can do to resolve it would be greatly appreciated!
You need to run your app as admin.
Here's he right way to do it:
http://blogs.msdn.com/b/nikhiln/archive/2007/04/19/embed-a-manifest-to-make-an-application-elevate-in-vista.aspx
On some versions of windows, the program files directories are pretty well locked down. This prevents errant users from damaging the parts of the file system essential for correct OS running. If you run your debugger (and application) with elevated privileges then it will pass.
If you using Vista, Program Files folder is protected by operating system by UAC.
Applications written with the assumption that the user will be running
with administrator privileges experienced problems in earlier versions
of Windows when run from limited user accounts, often because they
attempted to write to machine-wide or system directories (such as
Program Files) or registry keys. UAC attempts to alleviate this
using File and Registry Virtualization, which redirects writes (and
subsequent reads) to a per-user location within the user’s profile.
For example, if an application attempts to write to “C:\program
files\appname\settings.ini” and the user doesn’t have permissions to
write to that directory, the write will get redirected to
“C:\Users\username\AppData\Local\VirtualStore\Program Files\appname\settings.ini”
And be aware, Program Files is special folder. If you want to get its path, you can use Environment.SpecialFolder enumeration. Like;
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)

System.IO.Directory.Move(tempPath, newFolder) throws exception access denied

I am trying to move a folder from one directory to another using this
System.IO.Directory.Move(tempPath, newFolder);
I am Administrator on my computer, so I should have full access. I cannot figure out why I get this exception once every two trying.
Access to the path 'D:\<myDirectory>' is denied.
Just because you're admin doesn't mean you can access everything. Among the things you can't necessarily access:
Files/directories owned by SYSTEM which don't explicitly allow admins (e.g. C:\System Volume Information)
Files locked by other processes with "share" settings which preclude your access

Can I tell the nonexistent path in case of DirectoryNotFound exception?

I am building an application which copies or moves files from and to various network drives. It seems to me that File.Move and File.Copy throws:
System.IO.DirectoryNotFoundException: Could not find a part of the
path
due to permission problems for user running the application. However, the exception message does not contain information of which folder the application fails to find (ex.Message is only Could not find a part of the path and there is no inner exception), so it is hard for the users to check which permission they need to check by looking at the exception message directly.
Is there a way to find which folder is causing the exception to be thrown? The documentation of the exception does not seem to show any property for this.

Open/browse a password protected mapped network drive

I want to open a mapped network drive from C# code, but it is password protected, so when I try to open it directly an exception is thrown. Can someone shed light on providing a username and password while opening the this drive? Exception details:
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(String fileName)
I am just calling System.Diagnostics.Process.Start("Z:")
Z: is not a file name. [edit: it's ok if it's not password protected, tried executing your code and it worked]
Try using a ProcessStartInfo object as a parameter, as it allows setting a username and password.
And about the FileName parameter from here:
The file name is any application or document. A document is defined to be any file type that has an open or default action associated with it. You can view registered file types and their associated applications for your computer by using the Folder Options dialog box, which is available through the operating system. The Advanced button leads to a dialog box that shows whether there is an open action associated with a specific registered file type.
Perhaps you might consider instead opening the UNC path that your "z drive" is meant to point to. A reminder that a PC user can disconnect the Z: and replace it with whatever path they wanted to...
It's not entirely clear what you mean by "launch directly" and "opening this drive" but if as your code snip suggests you're trying to launch the Explorer for the drive's folder then you could use the ProcessStartInfo as a mechanism to provide credentials.
If you're trying to programmatically get access to a file(s) on that share, then you might look into the term impersonation to run your file access code blocks under a different credential. This Accessing a Shared File (UNC) From a Remote, Non-Trusted Domain With Credentials looks particularly promising.
If you're trying to actually create the network drive using pre-specified credentials then there's another solution over here - https://serverfault.com/questions/47005/specifying-username-pass-as-part-of-a-unc-path-or-map-network-drives-for-a-window/47008#47008 (don't forget to disconnect it after).

Categories