I was writing a smallish application to parse a file on a network accessible share and display in human readable form, the contents of the file.
I previously had the program 90% complete on a previous platform configuration, but since then we have changed configuration, still XP Desktops, but different Server Infrastructure. On this new configuration, the program failed with an exception as soon as it attempted to perform directory listing of files in the network share.
string[] RevFiles = Directory.GetFiles(@"\\VMS\DREADM\","*")
Exception raised was System.Security.SecurityException
Additional information: Request for permission of type System.Security.Permissions.FileIOPermission, mscorlib ... Failed.
I have read about, only lightly Code Access Security, I guess now is as good a time as any to find out what the problem is by some further analysis.
First thing to do is isolate the problem into as small a chunk of code as possible, this ended up as just a simple console Application with 2 lines of code, the first being shown above and the second being merely to output all of the returned strings to the console window. I subsequently found that I could then no-longer evenlist files on my own C: drive, the following fragment still raised the security exception.
string[] RevFiles = Directory.GetFiles(@"C:\","b*")
After further investigation into how the .NET Code Access Security worked, the following was my situation:
- Application was stored on a Network Accessable Share
- Application was attempting to perform direct file IO
- Being on a Network Share, my application inherited the "LocalIntranet" Permission Set
- "LocalIntranet" Permission set did not allow the "FileIOPermission" by default.
There appeared to be no way to modify the default settings of the "LocalIntranet" security zone (More in a later blog if I find out how)
The next thing was how was my code evaluated to use the "LocalIntranet" Permission Set ?
That was found out by examining the Runtime Security Policy. The "User, All_Code" code group, if you look at its properties, has a permission set of "Full Access" so this was not stopping anything.The "Machine, All_Code" code group has a sub-code group of "LocalIntranet Zone". Its properties showed that its permission set was "LocalIntranet". I believe that this was the link I was looking for.
A quick step back to Permission Sets for the Machine, I am allowed to create a new Permission Set. Called "Mikes"for simplicity, I copied the contents of the "LocalIntranet" Permission set and merely added "File IO", Unrestricted Access for simplicity. Now hopping back into the Machine/LocalIntranet Zone Code group, I could assign the Permission Set "Mikes" to the"LocalIntranet" code group. Logging off as Administrator and back on as lowly user account, my small test harness started finally to display files in its console window.
Result!
So, what have I learnt ?
- Do not automatically assume that apps will work when migrated from one system to the other.
- .NET Code Access Security is a very large subject area.
- I think that I have probably frigged a solution to my problem, given more time, I may re-visit.
- Why did this work on my previous platform ? Answer, It was stored on a local drive.
- It is a pain to keep logging out of Non admin account and into administrator and back. Fortunately my friendly System Administrator showed me how to access the .NET Config via command line command (MMC) and use "Run-As". Good job I am trusted with the Administrator password!
- I believe that I may focus some of my .NET time and energy into this area.
Wish me luck!