The introduction of the .Net Framework brought along another layer of permissions that is often overlooked. In addition to the normal NTFS and Share permissions that you're probably already familiar with, the Framework itself has added a new set of permissions called Code Access Security (CAS).
For example, if you attempt to run a .Net application from a network share,you might not have permissions to execute the application. Again, this has nothing to do with NTFS and Share permissions... it's the configuration of the .Net Framework itself on the local PC that determines if you have permission.
Note: Programmers are often confused by this... "My program runs just fine on my PC, but when I copy it to the server, I can't run it". They think the problem is somehow related to their program... it's not!
Part of the confusion is the poorly worded Code Access Security exception message that is generated. Remember, this message is being generated by the Framework itself, not your code, so it's rather ugly.
Huh? I don't get it
Consider this... your program needs to read and write to the registry. In the "old days", before the .Net Framework, the only way to allow/deny the rights to read and write from the registry would be:
- NTFS/Share permissions on the application
- Permissions on the registry keys
- A home-brew authentication/authorization scheme that you include in your program
But, do you see a problem? For these steps to be effective, you must trust that the program has your best interests at heart. The .Net Framework attempts to fill in that gap... what if the program was sloppy, careless, or malicious? What then?
That's where Code Access Security comes in... to protect you from a rogue application. In this example, the Framework can be configured to deny access to the local registry for any "untrusted" .Net application.
A little deeper into CAS
So, how does the .Net Framework determine if my application is trusted or not? The answer is in two parts:
- Where is the application located
- What does the application do
As you've already seen, your application runs just fine on your local PC, but doesn't run from a network share. That's an example of the first condition... the location of the program. That's because the network share is in a different "security zone" from the local PC. Typically the network shares on a LAN are in the "Local Intranet" zone.
Note: The .Net Framework uses the same security zones as the Internet Explorer... more about that later.
The second condition is all about what the program will do. The following list of things your program might do that are considered "potentially dangerous" enough to warrant this extra level of protection:
- Reading/Writing to the local filesystem
- Reading/Writing to the Registry
- Using unmanaged APIs
There are some exceptions to the rule... certain areas of the local filesystem and registry are allowed to be read without triggering a CAS exception.
Code Access Security utilities
So, in order to run your application from a network share, you must adjust the default CAS permissions on every client PC. Yes, I said... every client PC.
Typically you'd do this by either running the "Microsoft .Net Framework 2.0 Configuration" (mscorcfg.msc) control panel applet or by using the Code Access Security Policy Tool (Caspol.exe) utility.
Let's start with the "Microsoft .Net Framework 2.0 Configuration" (mscorcfg.msc)... as the control panel applet is typically easier to use than the command-line utility.
Using the mscorcfg.msc applet
But wait... here is where the fun starts. When the older 1.0 and 1.1 versions of the .Net Framework were installed on the client PCs, they got new control panel applets installed in the "Administrative Tools" section called "Microsoft .Net Framework 1.x Configuration" and "Microsoft .Net Framework 1.x Wizard". However, starting with version 2.0, these control panel applets are no longer installed with the .Net Framework.
What? Are you sure... I've got it on my PC! Yes, the installation of Visual Studio or the Software Development Kit (SDK) includes the mscorcfg.msc applet. So, you've got it on your development PC, however, ordinary PCs with just the .Net Framework do not get the applet installed.
Note: See below if you are missing the control panel applet on your development PC.
So, then how the heck am I supposed to adjust CAS on the client PCs? Well, you can use the control panel applet on your development PC to adjust CAS and then create an MSI file that you can distribute to the other client PCs.
Here is a step-by-step "walk through" using the mscorcfg.msc applet. Let's assume that you've got a normal corporate LAN, where client PCs routinely connect to network shares and now you want to adjust CAS to allow .Net applications to be run from those shares.
- From a development PC, open the Control Panel, navigate to the "Administrative Tools" section
- Click on the "Microsoft .Net Framework 2.0 Configuration" applet
- Click on the "Configure Code Access Security Policy" link
- Click on the "Adjust Zone Security" link
- Keep the default "Make changes to this computer", click the "Next" button
- Click on the "Local Intranet" icon
- Move the vertical slider to "Full Trust", Click the "Next" button
- Click "Finish" at the summary screen
CAS has now been configured on the development PC. Now we need to create a deployment package so that we can install those changes on the client PCs on the LAN.
- Click on the "Create Deployment Package" link
- Select the "Machine" level
- Fill in the full path to where the MSI file will be created, click the "Next" button
- Click "Finish" at the summary screen
Note: The distribution of the MSI file to the client PCs is beyond the scope of this article.
Using the caspol.exe utility
Another technique that can be used is via a command-line utility. The CASPOL utility is nice, but it can't create an MSI file for distributing the changes to other PCs. Using CASPOL, you'd have to execute the command at each PC. The command-line equivalent for setting the Intranet zone to "Full Trust" is as follows:
cd C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727 Caspol -machine -chggroup LocalIntranet_Zone FullTrust
Note: I'd recommend the MSI solution to anyone who has an Active Directory domain, since it's easy to distribute the MSI file via a Group Policy Object (GPO).
There are 3 steps to deploy Code Access Security changes to client PCs
- Configure the settings. On a development PC, use the applet to set the security settings the way you want.
- Create an MSI file. From inside the applet, create an MSI file which contains the settings you've just changed.
- Deploy the MSI file. Typically you'd drop that MSI file into a GPO and let Active Directory do its thing... or you can deploy it via any number of methods.
Frequently Asked Questions
Do I have to do this for every application? No, once you adjust CAS for the Intranet zone (as described above), all applications at that location will successfully run.
I adjusted CAS on my PC and it works, but the other PCs still don't run the application. That's correct, you must adjust Code Access Security on every client PC. I suggest you deploy an MSI file (described above) via Group Policy Object (GPO).
I can't find the "Microsoft .Net Framework 2.0 Configuration" applet. The applet is no longer distributed with the .Net Framework. It only gets installed on PCs that have either Visual Studio or the SDK installed. See the unsupported technique below to install just the applet.
I have Visual Studio installed, but I still don't have the control panel applet. The applet is not installed with the Express Editions of Visual Studio. I've also seen a situation where a user had uninstalled Visual Studio 2005 and installed Visual Studio 2008, and the uninstall apparently took away too much. See the unsupported technique below for a fix.
I used the "Microsoft .Net Framework 1.1 Configuration" applet, but it doesn't work. That's because changes to the v1.1 Framework have no impact on v2.0 Framework applications. Use version 2.0 of applet for configuring v2.0 (and above) applications.
I successfully configure CAS, but it still does work. Are you sure you used the correct version of the applet for .Net Framework 2.0? Also, you need to verify that the Internet Explorer security zones are correct. See below.
How do I determine what "security zone" I'm in? Just use Windows Explorer to navigate to the network resource where the application is (either by a UNC-style name "\\Server\Share" or via a mapped drive letter), and look at the status bar to see which zone you're in. Note: If your Status Bar is not visible.. use View/Status Bar.
My server is in the wrong zone, how do I fix it? Using the Internet Explorer on the client PC, navigate to: Tools, Internet Options, Security "tab", Local Intranet "icon", Sites button. Sometimes the default setting of "Automatically detect intranet network" doesn't work, and you have to click on each of the checkboxes. You might have to poke around the other zones to make sure there isn't an exception or overlap in order to find the problem.
How do I adjust the zone for every client PC in my network? You can adjust IE setting via a Group Policy Object (GPO), however, that's outside the scope of this article.
Do I have to configure CAS on the server too? No, there is no need to set Code Access Security on the file server that "hosts" the application. However, if that server needs to access an application on some other server, then it will be required.
I've got a 64-bit version of Windows, and it still doesn't work. That's because the 64-bit OS actually has two versions of the framework installed... a 32-bit version and a 64-bit version. You must configure both versions separately. The MSI technique does not work well in this situation... instead, you should use the CASPOL utility from both C:\Windows\Microsoft.NET\Framework\v2.0.50727 and C:\Windows\Microsoft.NET\Framework64\v2.0.50727
How do you configure CAS for .Net Framework v3.0 or v3.5? These versions of the Framework are really just an "add on" to the .Net Framework v2.0, so using the control panel applet for v2.0 is sufficient... there is no separate configuration utility for v3.0 or v3.5
Is there a way to catch a CAS exception inside my code? Yes, you can start your program from a class that has only very minimal requirements and then test the CAS requirements of your application one at a time. This allows you to produce an error message that might be more meaningful to the user. Take a look at the TestPerm.vb file in the SOSOS application for an example of this technique.
The only supported way to get mscorcfg.msc installed on a PC is to download and install the .Net Framework SDK. However, the SDK is huge and seems like a lot of work just to get one little utility.
The technique described below may be in violation of some Microsoft Use Agreement, so you are encouraged to investigate this issue yourself. Use at your own risk.
- Start at some PC where the MSCORCFG.MSC is already installed. This would typically be a development PC with either Visual Studio or the SDK installed.
- Drill down to either "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727", "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin", or "C:\Program Files\Microsoft.NET\SDK\v2.0\Bin" to find the files below
- Copy the following files to a flash drive (or network location)
- Distribute these files to the client PC in the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 directory
- Register the DLLs using the Cas.reg file included in the download below
- Create a shortcut to the mscorcfg.msc file in the Administrative Tools section of the control panel (also included in download)
This article only covers one small example of the use of Code Access Security. There are many other ways to configure programs to be trusted that I did not cover.
If you need a more "surgical" approach to setting the trust level for a program, I suggest you take a look the documentation links below:
Download the files referenced in this article: CAS.zip