C# - Show "Get file permission" dialog to get access - c#

I want to be able to have my user get read/write privileges to folders that they don't have access to without them having to do extra work. I'd like for the box to appear below, then they can simply hit "continue", then the program will progress.
I'm able to make the box appear by using
Process.Start(filePath);
but then that also opens the folder, which is a bit clunky. Is there a way to just show this dialog, wait for the user to interact, then continue execution?

What I will do in this case:
test permission on file, you can add what ever is needed (read, execute, traverse)
public static bool HasWritePermissionOnDir(string path)
{
var writeAllow = false;
var writeDeny = false;
var accessControlList = Directory.GetAccessControl(path);
if (accessControlList == null)
return false;
var accessRules = accessControlList.GetAccessRules(true, true,
typeof(System.Security.Principal.SecurityIdentifier));
if (accessRules ==null)
return false;
foreach (FileSystemAccessRule rule in accessRules)
{
if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
continue;
if (rule.AccessControlType == AccessControlType.Allow)
writeAllow = true;
else if (rule.AccessControlType == AccessControlType.Deny)
writeDeny = true;
}
return writeAllow && !writeDeny;
}
source
then if there is no access
// Add the access control entry to the file.
AddFileSecurity(fileName, #"DomainName\AccountName",
FileSystemRights.ReadData, AccessControlType.Allow);
FileSystemRights - set as needed source
Put all operations in try-catch blocks as dealing with files are always gona to have issues :-)
Ensure that you user has a privilege to change permissions (run as Admin)

Related

Check network file permission in .NET

I have to check if user, that login into system and run the application, have a specified permissions on some file.
User that run the application is in "BUILTIN\Administrators" group.
While file is local all going fine. I use that code (adopted version from that answers Checking for directory and file write permissions in .NET):
private static bool HasPermission(FileSystemRights permission, AuthorizationRuleCollection accessRules )
{
var allow = false;
var inheritedDeny = false;
var inheritedAllow = false;
if (accessRules == null)
return false;
var currentUser = WindowsIdentity.GetCurrent();
var currentPrincipal = new WindowsPrincipal(currentUser);
foreach (FileSystemAccessRule rule in accessRules)
{
if ((permission & rule.FileSystemRights) != permission)
continue;
if (!currentPrincipal.IsInRole(rule.IdentityReference.Value))
{
continue;
}
if (rule.AccessControlType == AccessControlType.Allow)
{
if (rule.IsInherited)
inheritedAllow = true;
else
allow = true;
}
else if (rule.AccessControlType == AccessControlType.Deny)
{
if (!rule.IsInherited)
return false;
inheritedDeny = true;
}
}
var combined = allow || (inheritedAllow && !inheritedDeny);
return combined;
}
But when I try to check permissions on network shared file I have issue.
For example file shared with FullControl access rule for remote computer user, that remote user also in "BUILTIN/Administrators" group. For "Everyone" group user it is ReadOnly file.
So when I check this with my current, local, log in user by using that code:
if (!currentPrincipal.IsInRole(rule.IdentityReference.Value))
{
continue;
}
I do not go inside of IF condition due my log-in user also in "BUILTIN/Administrators" group.
So code returns TRUE, but in real life I have no write access to that file.
How do can I distinct local and remote Administrator's group users?
PS: I do not want to use exceptions to check accessibility, this will be the "last hope code"

what is the best way to check in C# .NET if a directory has access to list files or a unauthorized access exception would rise

how would I check in the best way in .NET 2.0 C# if I have access to a specified directory
for listing top directory files e.g. a system directory or system volume information folder etc.
My code for it looks now like this, but I think it is not the best way to check for it since it produces an exception each time which is handled by the check function and returning based on it a result.
I would like to use a function which doesn't throw an error to check if in the specified directory is access to list files or maybe my code can be improved or optimized. I might have to check through a thousand directories if exists an access or not. Raising thousand exceptions might cause a problem, but I don't know.
//here my code using System.IO;
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(DirectoryCanListFiles("C:\\Windows\\Prefetch").ToString());
}
public static bool DirectoryCanListFiles(string DirectoryPath)
{
try
{
Directory.GetFiles(DirectoryPath, "*", SearchOption.TopDirectoryOnly);
}
catch { return false; }
return true;
}
The best way to check the permission, is try to access the direcoty (read/write/list) & catch the UnauthorizedAccessException.
However for some reason out there, if you want to check permissions, following code should satisfy your need.
You need to read Access Rules for the directory.
private bool DirectoryCanListFiles(string folder)
{
bool hasAccess = false;
//Step 1. Get the userName for which, this app domain code has been executing
string executingUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
NTAccount acc = new NTAccount(executingUser);
SecurityIdentifier secId = acc.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
DirectorySecurity dirSec = Directory.GetAccessControl(folder);
//Step 2. Get directory permission details for each user/group
AuthorizationRuleCollection authRules = dirSec.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule ar in authRules)
{
if (secId.CompareTo(ar.IdentityReference as SecurityIdentifier) == 0)
{
var fileSystemRights = ar.FileSystemRights;
Console.WriteLine(fileSystemRights);
//Step 3. Check file system rights here, read / write as required
if (fileSystemRights == FileSystemRights.Read ||
fileSystemRights == FileSystemRights.ReadAndExecute ||
fileSystemRights == FileSystemRights.ReadData ||
fileSystemRights == FileSystemRights.ListDirectory)
{
hasAccess = true;
}
}
}
return hasAccess;
}

Check if directory is accessible in C#? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
.NET - Check if directory is accessible without exception handling
Im making a small file explorer in Visual Studio 2010 with NET 3.5 and C#, and I have this function to check if a directory is accessible:
RealPath=#"c:\System Volume Information";
public bool IsAccessible()
{
//get directory info
DirectoryInfo realpath = new DirectoryInfo(RealPath);
try
{
//if GetDirectories works then is accessible
realpath.GetDirectories();
return true;
}
catch (Exception)
{
//if exception is not accesible
return false;
}
}
But I think with big directories it could be slow trying to get all sub directories to check if directory is accesible.
Im using this function to prevent errors when trying to explore protected folders or cd/dvd drives without disc ("Device Not Ready" error).
Is there a better way (faster) to check if directory is accessible by the application (preferably in NET 3.5)?
According to MSDN, Directory.Exists should return false if you don't have read access to the directory. However, you can use Directory.GetAccessControl for this. Example:
public static bool CanRead(string path)
{
try
{
var readAllow = false;
var readDeny = false;
var accessControlList = Directory.GetAccessControl(path);
if(accessControlList == null)
return false;
//get the access rules that pertain to a valid SID/NTAccount.
var accessRules = accessControlList.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
if(accessRules ==null)
return false;
//we want to go over these rules to ensure a valid SID has access
foreach (FileSystemAccessRule rule in accessRules)
{
if ((FileSystemRights.Read & rule.FileSystemRights) != FileSystemRights.Read) continue;
if (rule.AccessControlType == AccessControlType.Allow)
readAllow = true;
else if (rule.AccessControlType == AccessControlType.Deny)
readDeny = true;
}
return readAllow && !readDeny;
}
catch(UnauthorizedAccessException ex)
{
return false;
}
}
Update
As mentioned in some comments, this may return an incorrect value in a case where a valid SID in an external DOMAIN has access. In order to check if the current user has access, you need something like:
foreach...
if (WindowsIdentity.GetCurrent().User.Value.equals(rule.IdentityReference.Value))
This will confirm if the SID of the current user matches the access rule identity reference but may throw a SecurityException as well.
I think you are looking for the GetAccessControl method, the System.IO.File.GetAccessControl method returns a FileSecurity object that encapsulates the access control for a file.

Unable to access file - WebClient.DownloadFile

So I've looked for the answer multiple times, and meddled around with permission stuff to no avail, but this code still won't let me download a file to a specified path.
WebClient client = new WebClient();
client.DownLoadFile("http://dl.dropbox.com/u/(My account)/Installer.jar", #"c:\Games\Name\libs");
client.DownLoadFile("http://dl.dropbox.com/u/(My account)/Name.zip", #"c:\Games\Name");
Always gives me: "Access to the path 'c:\Games\Name\libs' is denied."
Also note, using windows XP SP3.
Hi I tried the above code locally and got the same error "Access is denied":
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile("http://localhost:1929/2.png", #"C:\Z\)
Try specifying the filename at the end of the directory, saves locally no problem when i ran it:
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile("http://localhost:1929/2.png", #"C:\Z\FILENAME.jpg")
The App probably doesn't have the permission to write to that folder. If this is a client app, try to run it as an administrator. Otherwise, change the permissions on 'c:\Games\Name\libs' to full control for everyone.
If the access to there is denied try to run as administrator.
If it doesn't work, navigate to the folder C:\Games\Name\libs, right click it and go to Properties.
Choose the "Security" tab, select at the top list the group of users that will run your program. (Try to use Users (YourName-PC\Users)).
With it selected, click on Edit at the bottom of the list, and at the bottom list select Full control under Allow.
you may use code below to see if you have write permission on folder, if not set the failing rule using setaccesscontrol before downloading
public static bool HaveWritePermissionsForFolder(string path)
{
var rules = Directory.GetAccessControl(Path.GetDirectoryName(Path.GetDirectoryName(path))).GetAccessRules(true, true, typeof(SecurityIdentifier));
bool allowwrite = false;
bool denywrite = false;
foreach (FileSystemAccessRule rule in rules)
{
if (rule.AccessControlType == AccessControlType.Deny &&
(rule.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData &&
(groups.Contains(rule.IdentityReference) || rule.IdentityReference.Value == sidCurrentUser)
)
{
denywrite = true;
}
if (rule.AccessControlType == AccessControlType.Allow &&
(rule.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData &&
(groups.Contains(rule.IdentityReference) || rule.IdentityReference.Value == sidCurrentUser)
)
{
allowwrite = true;
}
}
if (allowwrite && !denywrite)
return true;
return false;
}

Checking for shared folder write access for current user

I have following method to check current user have write access to given network location
DirectorySecurity shareSecurity = new DirectoryInfo(this.GetFileServerRootPath).GetAccessControl();
foreach (FileSystemAccessRule fsRule in shareSecurity.GetAccessRules(true, true, typeof(NTAccount)))
{
// check write permission for current user
if (AccessControlType.Allow == fsRule.AccessControlType &&
FileSystemRights.Write == (fsRule.FileSystemRights & FileSystemRights.Write))
{
if (null != fsRule.IdentityReference &&
fsRule.IdentityReference.Value == WindowsIdentity.GetCurrent().Name)
{
return true;
}
}
}
return false;
but problem is when folder permission given to user group, above method is failed.
I don't want to check the permissions by writing a file and decide the write access permissions.
is there any way to find current user in the IdentityReference.Value? or suggestions to overcome this issue?
This may work for you:
FileIOPermission writePermission = new FileIOPermission(FileIOPermissionAccess.Write, this.GetFileServerRootPath);
try
{
writePermission.Demand();
return true;
}
catch (SecurityException s)
{
return false;
}
Just curious - why not just try/catch your write operation?
May be you should use DirectoryInfo on that directory to get its security policies.

Categories