Sei sulla pagina 1di 7

login

StackOverflowisaquestionandanswersiteforprofessionalandenthusiastprogrammers.It's100%free,no
registrationrequired.

tour

signup

help

stackoverflowcareers

Takethe2minutetour

C#Testifuserhaswriteaccesstoafolder

Ineedtotestifausercanwritetoafolderbeforeactuallyattemptingtodoso.
I'veimplementedthefollowingmethod(inC#2.0)thatattemptstoretrievethesecuritypermissionsforthefolderusing
Directory.GetAccessControl()method.
privateboolhasWriteAccessToFolder(stringfolderPath)
{
try
{
//Attempttogetalistofsecuritypermissionsfromthefolder.
//Thiswillraiseanexceptionifthepathisreadonlyordonothaveaccessto
viewthepermissions.
System.Security.AccessControl.DirectorySecurityds=
Directory.GetAccessControl(folderPath);
returntrue;
}
catch(UnauthorizedAccessException)
{
returnfalse;
}
}

WhenIwasgooglinghowtotestforwriteaccessnothinglikethiscameupanditappearedverycomplicatedtoactuallytestpermissionsin
Windows.IamconcernedthatIamoversimplifyingthingsandthatthismethodisnotrobust,althoughitdoesseemtowork.
Willmymethodtotestifthecurrentuserhaswriteaccessworkcorrectly?
c# permissions folder

editedAug28'12at9:03

askedSep11'09at10:14
ChrisB
1,047

19

36

4 Isnothavingaccesstoviewthepermissionsreallythesameasnotbeingallowedtowritetoit?
deed02392Sep19'13at15:02

16Answers

That'saperfectlyvalidwaytocheckforfolderaccessinC#.Theonlyplaceitmightfalldownisif
youneedtocallthisinatightloopwheretheoverheadofanexceptionmay beanissue.
Therehavebeenothersimilarquestions askedpreviously.
editedMar31'14at3:38

answeredSep11'09at10:18

AranMulholland
11.2k

10

73

Ash
157

33.7k

20

102

148

1 FunnilyenoughIhadoneofthoseotherquestionsopeninanothertabbuthadn'tseentheanswerabout
DirectorySecurity,teachmetoreadalltheanswersnotjusttheacceptedone) ChrisB Sep11'09at
10:45

Iappreciatethatthisisalittlelateinthedayforthispost,butyoumightfindthisbitofcode
useful.
stringpath=@"c:\temp";
stringNtAccountName=@"MyDomain\MyUserOrGroup";
DirectoryInfodi=newDirectoryInfo(path);

DirectorySecurityacl=di.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollectionrules=acl.GetAccessRules(true,true,typeof(NTAccount));
//GothroughtherulesreturnedfromtheDirectorySecurity
foreach(AuthorizationRuleruleinrules)
{
//Ifwefindonethatmatchestheidentitywearelookingfor
if
(rule.IdentityReference.Value.Equals(NtAccountName,StringComparison.CurrentCultureIgnoreCase
{
//CasttoaFileSystemAccessRuletocheckforaccessrights
if((((FileSystemAccessRule)rule).FileSystemRights&
FileSystemRights.WriteData)>0)
{
Console.WriteLine(string.Format("{0}haswriteaccessto{1}",NtAccountName,
path));
}
else
{
Console.WriteLine(string.Format("{0}doesnothavewriteaccessto{1}",
NtAccountName,path));
}
}
}
Console.ReadLine();

DropthatintoaConsoleappandseeifitdoeswhatyouneed.
editedMar22'11at16:48

answeredMar22'11at16:40
DuncanHowe
1,820

10

Rightontarget!Helpsmealot!smwikipediaNov30'11at2:27
Igetanexceptiononthecallto GetAccessControl butmysoftwareisactualycapableofwritingtothe
directoryI'mlookingat..?JonCageMay10'12at13:50
@JonCagewhatexceptionareyougetting?Thefirstthingthatleapstomindis,ironically,asecurity
problem.DoestheaccountthatyourappisrunningashavepermissiontogettheACLinformation?
DuncanHoweMay16'12at20:48
Thankyoumuch,thiscameinveryhandy.:)Love2LearnApr10'13at22:53
Niceworkhere.Thisdidn'tendupsolvingmyissue,though.Iftheappisrunningunderauserthatdoesnot
havewriteprivilegesonthefolder,GetAccessControlwillthrowanexception.ButthatgavemewhatI
neeededasimpletry/catch!wooters Apr9'14at2:14

publicboolIsDirectoryWritable(stringdirPath,boolthrowIfFails=false)
{
try
{
using(FileStreamfs=File.Create(
Path.Combine(
dirPath,
Path.GetRandomFileName()
),
1,
FileOptions.DeleteOnClose)
)
{}
returntrue;
}
catch
{
if(throwIfFails)
throw;
else
returnfalse;
}
}

editedOct17'14at18:27
JonD
78

answeredJun16'11at12:07
priit

189

2 Thisanswerwillcatchallexceptionsthatcouldoccurwhentryingtowriteafile,notjustpermission
violations.MattEllenJun17'11at9:42
Almostgood!buthowtodowithoutcreatinganactualfile..whatifafilewiththesamenamealreadyexists
there...nicetrythough:)G.YMay6'13at17:12
2 @G.Y, stringtempFileName=Path.GetRandomFileName(); ,evidently AlexeyKhoroshikhFeb5'14
at9:37
@Matt,thisanswersexactlytheaskedquestion"isthedirectoryiswritable"regardlessofthereasonof
failure,however.Youratheranswerto"whyican'twritetothedirectory".:)AlexeyKhoroshikhFeb5'14
at9:43

Igetafalsepositivewiththiscode.TheFile.Create()runsOK(andleavesatempfileifyouchangethe
lastoption)eventhoughtheexecutinguserhasnopermissiontowritetothatfolder.Reallyreallyodd
spentanhourtryingtofigureoutwhybutI'mstumped.NickGFeb10at11:49

Forexampleforallusers(Builtin\Users),thismethodworksfineenjoy.
publicstaticboolHasFolderWritePermission(stringdestDir)
{
if(string.IsNullOrEmpty(destDir)||!Directory.Exists(destDir))returnfalse;
try
{
DirectorySecuritysecurity=Directory.GetAccessControl(destDir);
SecurityIdentifierusers=newSecurityIdentifier(WellKnownSidType.BuiltinUsersSid,
null);
foreach(AuthorizationRuleruleinsecurity.GetAccessRules(true,true,
typeof(SecurityIdentifier)))
{
if(rule.IdentityReference==users)
{
FileSystemAccessRulerights=((FileSystemAccessRule)rule);
if(rights.AccessControlType==AccessControlType.Allow)
{
if(rights.FileSystemRights==(rights.FileSystemRights|
FileSystemRights.Modify))returntrue;
}
}
}
returnfalse;
}
catch
{
returnfalse;
}
}

answeredJun22'12at13:50
UGEEN
2,475

20

28

Yourcodegetsthe DirectorySecurity foragivendirectory,andhandlesanexception(dueto


yournothavingaccesstothesecurityinfo)correctly.However,inyoursampleyoudon'tactually
interrogatethereturnedobjecttoseewhataccessisallowedandIthinkyouneedtoaddthisin.
answeredSep11'09at10:23
VinaySajip
44.2k

80

97

+1IjustranintothisproblemwhereanexceptionwasnotthrownwhencallingGetAccessControlyetIget
anunauthorizedexceptionwhenattemptingtowritetothatsamedirectory.MayoJan20'11at15:49

Trythis:
try
{
DirectoryInfodi=newDirectoryInfo(path);
DirectorySecurityacl=di.GetAccessControl();
AuthorizationRuleCollectionrules=acl.GetAccessRules(true,true,typeof(NTAccount));
WindowsIdentitycurrentUser=WindowsIdentity.GetCurrent();
WindowsPrincipalprincipal=newWindowsPrincipal(currentUser);
foreach(AuthorizationRuleruleinrules)
{
FileSystemAccessRulefsAccessRule=ruleasFileSystemAccessRule;
if(fsAccessRule==null)
continue;
if((fsAccessRule.FileSystemRights&FileSystemRights.WriteData)>0)
{
NTAccountntAccount=rule.IdentityReferenceasNTAccount;
if(ntAccount==null)
{
continue;
}
if(principal.IsInRole(ntAccount.Value))
{
Console.WriteLine("Currentuserisinroleof{0},haswriteaccess",
ntAccount.Value);
continue;
}
Console.WriteLine("Currentuserisnotinroleof{0},doesnothavewrite
access",ntAccount.Value);
}
}
}
catch(UnauthorizedAccessException)

{
Console.WriteLine("doesnothavewriteaccess");
}

editedOct19'12at13:04

answeredOct19'12at13:01

AdiLester
12.2k

CsabaS
37

58

61

IMHOtheonly100%reliablewaytotestifyoucanwritetoadirectoryistoactuallywritetoitand
eventuallycatchexceptions.
answeredSep11'09at10:16
DarinDimitrov
573k

87

1886

1968

IusedthesamefunctionforcheckiffilehasWriteAccess:
privatestaticboolHasWriteAccessToFile(stringfilePath)
{
try
{
//Attempttogetalistofsecuritypermissionsfromthefile.
//Thiswillraiseanexceptionifthepathisreadonlyordonothaveaccess
toviewthepermissions.
File.GetAccessControl(filePath);
returntrue;
}
catch(UnauthorizedAccessException)
{
returnfalse;
}
}

answeredJul10'12at5:18
BrunoBieri
1,283

17

34

Itriedmostofthese,buttheygivefalsepositives,allforthesamereason..Itisnotenoughtotest
thedirectoryforanavailablepermission,youhavetocheckthattheloggedinuserisamember
ofagroupthathasthatpermission.Todothisyougettheusersidentity,andcheckifitisa
memberofagroupthatcontainstheFileSystemAccessRuleIdentityReference.Ihavetested
this,worksflawlessly..
///<summary>
///Testadirectoryforcreatefileaccesspermissions
///</summary>
///<paramname="DirectoryPath">Fullpathtodirectory</param>
///<paramname="AccessRight">FileSystemrighttested</param>
///<returns>State[bool]</returns>
publicstaticboolDirectoryHasPermission(stringDirectoryPath,FileSystemRights
AccessRight)
{
if(string.IsNullOrEmpty(DirectoryPath))returnfalse;
try
{
AuthorizationRuleCollectionrules=
Directory.GetAccessControl(DirectoryPath).GetAccessRules(true,true,
typeof(System.Security.Principal.SecurityIdentifier));
WindowsIdentityidentity=WindowsIdentity.GetCurrent();
foreach(FileSystemAccessRuleruleinrules)
{
if(identity.Groups.Contains(rule.IdentityReference))
{
if((AccessRight&rule.FileSystemRights)==AccessRight)
{
if(rule.AccessControlType==AccessControlType.Allow)
returntrue;
}
}
}
}
catch{}
returnfalse;
}

editedFeb24'14at19:00

answeredFeb24'14at18:48
John
117

Youhaveapotentialraceconditioninyourcodewhathappensiftheuserhaspermissionsto
writetothefolderwhenyoucheck,butbeforetheuseractuallywritestothefolderthis
permissioniswithdrawn?Thewritewillthrowanexceptionwhichyouwillneedtocatchand
handle.Sotheinitialcheckispointless.Youmightaswelljustdothewriteandhandleany
exceptions.Thisisthestandardpatternforyoursituation.
answeredSep11'09at11:08
ShellShock

YoucantryfollowingcodeblocktocheckifthedirectoryishavingWriteAccess.Itchecksthe
FileSystemAccessRule.
stringdirectoryPath="C:\\XYZ";//folderBrowserDialog.SelectedPath;
boolisWriteAccess=false;
try
{
AuthorizationRuleCollectioncollection=
Directory.GetAccessControl(directoryPath)
.GetAccessRules(true,true,typeof(System.Security.Principal.NTAccount));
foreach(FileSystemAccessRuleruleincollection)
{
if(rule.AccessControlType==AccessControlType.Allow)
{
isWriteAccess=true;
break;
}
}
}
catch(UnauthorizedAccessExceptionex)
{
isWriteAccess=false;
}
catch(Exceptionex)
{
isWriteAccess=false;
}
if(!isWriteAccess)
{
//handlenotifications
}

editedFeb25'14at16:06

answeredNov26'09at7:35

OlivierJacotDescombes

RockWorld

36k

1,021

28

60

10

21

1 Thisiswhatmycodealreadydoes ChrisB Nov26'09at16:34

http://www.codeproject.com/KB/files/UserFileAccessRights.aspx
VeryusefullClass,checkforimprovedversioninmessagesbellow.
answeredOct9'09at10:10
user187083

Simplytryingtoaccessthefileinquestionisn'tnecessarilyenough.Thetestwillrunwiththe
permissionsoftheuserrunningtheprogramWhichisn'tnecessarilytheuserpermissionsyou
wanttotestagainst.
answeredJun17'11at10:12
Mort
26

IagreewithAsh,thatshouldbefine.AlternativelyyoucouldusedeclarativeCASandactually
preventtheprogramfromrunninginthefirstplaceiftheydon'thaveaccess.
IbelievesomeoftheCASfeaturesmaynotbepresentinC#4.0fromwhatI'veheard,notsureif
thatmightbeanissueornot.
answeredSep11'09at10:21
Ian
15.4k

43

106

HereisamodifiedversionofCsabaS'sanswer,whichaccountsforexplicitdenyaccessrules.

ThefunctiongoesthroughallFileSystemAccessRulesforadirectory,andchecksifthecurrent
userisinarolewhichhasaccesstoadirectory.Ifnosuchrolesarefoundortheuserisinarole
withdeniedaccess,thefunctionreturnsfalse.Tocheckreadrights,pass
FileSystemRights.Readtothefunctionforwriterights,passFileSystemRights.Write.Ifyouwant
tocheckanarbitraryuser'srightsandnotthecurrentone's,substitutethecurrentUser
WindowsIdentityforthedesiredWindowsIdentity.Iwouldalsoadviseagainstrelyingonfunctions
likethistodetermineiftheusercansafelyusethedirectory.This answerperfectlyexplainswhy.
publicstaticboolUserHasDirectoryAccessRights(stringpath,FileSystemRights
accessRights)
{
varisInRoleWithAccess=false;
try
{
vardi=newDirectoryInfo(path);
varacl=di.GetAccessControl();
varrules=acl.GetAccessRules(true,true,typeof(NTAccount));
varcurrentUser=WindowsIdentity.GetCurrent();
varprincipal=newWindowsPrincipal(currentUser);
foreach(AuthorizationRuleruleinrules)
{
varfsAccessRule=ruleasFileSystemAccessRule;
if(fsAccessRule==null)
continue;
if((fsAccessRule.FileSystemRights&accessRights)>0)
{
varntAccount=rule.IdentityReferenceasNTAccount;
if(ntAccount==null)
continue;
if(principal.IsInRole(ntAccount.Value))
{
if(fsAccessRule.AccessControlType==AccessControlType.Deny)
returnfalse;
isInRoleWithAccess=true;
}
}
}
}
catch(UnauthorizedAccessException)
{
returnfalse;
}
returnisInRoleWithAccess;
}

answeredApr16'13at8:28
sdds
374

22

Icouldn'tgetGetAccessControl()tothrowanexceptiononWindows7asrecommendedinthe
acceptedanswer.
Iendedupusingavariationofsdds's answer:
try
{
boolwriteable=false;
WindowsPrincipalprincipal=new
WindowsPrincipal(WindowsIdentity.GetCurrent());
DirectorySecuritysecurity=Directory.GetAccessControl(pstrPath);
AuthorizationRuleCollectionauthRules=security.GetAccessRules(true,true,
typeof(SecurityIdentifier));
foreach(FileSystemAccessRuleaccessRuleinauthRules)
{
if(principal.IsInRole(accessRule.IdentityReferenceas
SecurityIdentifier))
{
if((FileSystemRights.WriteData&accessRule.FileSystemRights)==
FileSystemRights.WriteData)
{
if(accessRule.AccessControlType==AccessControlType.Allow)
{
writeable=true;
}
elseif(accessRule.AccessControlType==AccessControlType.Deny)
{
//DenyusuallyoverridesanyAllow
returnfalse;
}
}
}
}
returnwriteable;
}
catch(UnauthorizedAccessException)

{
returnfalse;
}

Hopethishelps.
answeredJan7'14at22:55
Patrick
1

Potrebbero piacerti anche