Access denied when loading dependency .dll .NET - c#

We have a .NET WinForms application that has several .NET dll's it depends on, running on an XP machine, that is connected to a network in a large domain.
We deployed this application on a customers machine while logged in as an admin and all worked fine.
We then logged into a lower privalaged account, and low and behold the application failed to start, but that was expected.
So, we got their IT department to make the folder Read/Write access (as we use folders in there for holding temp files) and they allowed the .exe to be executable by that user.
Now starting the executable, the application runs (yay) but then we got it to perform an action that required code in one of it dependant (managed) dll's...
An Exeception is thrown, stating "The assembly "xxxx.dll" failed to load (access is denied)" I am assured by their IT department that the dll's have the same file permissions as the main executable (and by quick look at what the lower privilege user can see of security settings, it did appear that way) and they were not set as "blocked" as XP sometimes does.
So the question is more of a fish for possible ideas that may be causing this...
EDIT: Turns out it was file permissions that were the problem and that the IT department in question hadn't followed through checking that permissions had been applied to all child objects. As I can't accept all 4 of your answers for such good ideas I have given you all an up vote.

The user may have access to the DLL listed in the error message but do they have access to all of the DLLs that that DLL needs? Check out something like Dependency Walker to find any DLLs that might be required.

Several possible problems, some detailed here: http://msdn.microsoft.com/en-us/library/ab4eace3.aspx
You may be asking to load an assembly that makes security demands that are larger than your main application. (Requesting permissions: http://msdn.microsoft.com/en-us/library/yd267cce.aspx )
If you are running full trust this is unlikely, but if the DLL you are loading is on the network make sure you have that location trusted by .NET: (trusting a share: http://blogs.msdn.com/shawnfa/archive/2004/12/30/344554.aspx )

Does the DLL access the registry or some other system folder that the lower privilege user isn't allowed to access? What is it trying to do when the error occurs?
You could also check whether the domain has some kind of group policy that's interfering with what the DLL is trying to do.

.NET doesn't trust assemblies from non-local drives by default.
See http://msdn.microsoft.com/en-us/library/zdc263t0.aspx for instructions to allow specific network locations to be trusted.

Related

Where to store local service appdata?

I'm writing a windows service that will have a 'LocalService' account type. I have a file that stores what it has to do.
I also have a windows form GUI where that file is also accessed to add/remove instances of the action for the service to perform. (dont know if its relavant but the service downloads tables from a webservice and exports them to any database the user has access to. these downloads are scheduled to happen regularly)
The service will only be installed on a user account.
I was planning on storing the file in user appdata folder however while debugging the service I got the error "Access to path [path] is denied"
Where would you recommend storing this file so it is accessible from both programs?
Thanks
EDIT: Looking a bit more, I've realised that
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
finds a different path for the service and the windows form app..
And that that app cant access the service appdata just as the service cant seem to access user appdata. so the same question stands!
ANOTHER EDIT:
So it turns out
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
is accessible from a local service and a user program - doh
...but some places seem to be read only...
Three options as I see it:
Run the service under the user's login id
Upside - both processes will have identical access to the various parts of the file system, so should remove your immediate problem
Downside - if the user changes their password the two will get out of sync.
write to some "neutral" part of the file system (or perhaps the registry) where shared access won't be a problem. The trouble with AppData is that as you've found, Windows sets up all kinds of protection around it in order to ringfence different users from each other.
Upside - no problems writing
Downside - you're effectively inventing your own standard. 15 years ago this would have been a no-brainer, the registry, but these days I get the impression that the registry is frowned upon (even though ms still rely on it!). If you do go down the registry route, make sure you're aiming at hklm not hkcu else you'll have the same problem!
During your setup, do some tricks to set up access to the relevant folders. But this is basically tearing down the protection that Windows sets up. Doesn't sound too sensible to me.

Why is CASPol allowing my .NET application to run?

Curious to know why my 2.0 .net application is being allowed to execute when I have restricted the permissions assigned to the assembly.
I've created a new Code Group at the Enterprise level which will match for any assembly with a particular digital signature. The code group has been set so that only permissions from the associated permission set will be used and also that lower policy levels will not be evaluated.
Running the .Net 2.0 PermCalc states that my application needs the following permissions:
UnmanagedCode,
Environment
FileIO
Registry
Reflection
I've assigned to my custom code group the permission for unmanaged code but nothing else.
The first method in my application demands all of the above permissions upfront so I can display a sensible message to the user before exiting.
Running the .NET 2.0 Configuation "Evaluate Assembly" tool on my assembly indeed shows that my application will only be given the UnmanagedCode permission.
However when I execute my application is runs and completes, quite obviously doing various FileIO and Registry operations.
My app is signed with the digital signature that should match the restricted code group.
Can anyone explain why this works.
Note: My ultimate aim is to make sure that my application does not crash horribly if executed from a network share. I would have liked to check the assembly evidence zone is My_Computer but I can no longer do that with .NET 3.5 SP1. See FullTrust On the LocalIntranet
Thanks in advance for any help/suggestions.
If you have configured your CAS policy correctly, then chances are that your application isn't being denied the permissions you expect because it is not being run under the CLR whose policy you configured. Do you perhaps have 32-bit and 64-bit CLRs installed on the same machine?
Another possibility might be that your "early check" demand is in the wrong place. Is it directly in your application's Main method? If so, when the demand runs, there won't be any of your application code on the call stack that is verified. If this is the problem, simply moving the demand into another method invoked from Main should allow the demand to fail.
you can still check the assembly evidence zone in .NET 3.5 SP1 - http://msdn.microsoft.com/en-us/library/system.security.policy.zone.aspx.
For what caspol allows your assembly see http://msdn.microsoft.com/en-us/library/tx1dts55.aspx.
This http://blogs.msdn.com/b/brada/archive/2007/10/26/adhoc-poll-allowing-net-exes-to-run-off-a-network-share.aspx could affect what you see...
EDIT:
For checking when running from a network share you can still get Assembly.GetExecutingAssembly().Location and then check whether it a UNC or netowrk drive via DriveType for your location System.IO.DriveInfo[] (i.e. System.IO.DriveType.Network).

Running .net application over a network

I need to enable a .NET application to run over a network share, the problem is that this will be on clients' network shares and so the path will not be identical.
I've had a quick look at ClickOnce and the publish options in Visual Studio 2008 but it needs a specific network share location - and I'm assuming this location is stored somewhere when it does its thing.
At the moment the job is being done with an old VB6 application and so gets around all these security issues, but that application is poorly written and almost impossible to maintain so it really needs to go.
Is it possible for the domain controller to be set up to allow this specific .NET application to execute? Any other options would be welcomed as I want to get this little application is very business critical.
I ought to say that the client networks are schools, and thus are often quite locked down as are the client machines, so manually adding exceptions to each client machine is a big no no.
Apologies, I forgot to mention we're restricted to .NET 2.0 for the moment, we are planning to upgrade this to 4.0 but that won't happen immediately.
The deployment location in the manifest must match the location where it is deployed. You are going to HAVE to use a UNC path. There shouldn't be any problem with this. ClickOnce applications install under the user's profile, and require no administrative privileges. It only needs read access to the file share where the application is deployed.
The best answer is to create deployments for each school and for you to set the UNC path, because then you can just send them a signed deployment and they can put it on the file share. But that's a major p.i.t.a. if there are a lot of schools involved.
The next answer is: Who actually deploys the application to each school, i.e. puts it on the file share? Is there some kind of administrator?
What I would recommend (depending on who it is) is giving them mageUI.exe and teaching them how to change the deployment URL and re-sign the manifest (it will prompt). The problem with them re-signing the deployment is they have to have a certificate. You could give each school their own certificate (created with the "create test certificate" button in VS, or use MakeCert to create one [ask if you want more info]) or give them all the same key (not very secure, but hey, it would work).
If you at least updated to .NET 3.5 SP-1, you could deploy the application without signing it. (I'm not giving you a hard time about .NET 2.0, my company is in the same position, I'm just passing this information on.)
If the computers have internet access, you could probably find somewhere to host the deployment for $10/month, and push it to a webserver and let them all install from there. Then everyone would get updates at the same time, you would only have to deploy updates to one location. This would be the simpliest solution, assuming they have internet access.
RobinDotNet
Visit my ClickOnce blog!
On the "Publish" tab of your project properties there is a "Installation Folder Url" textbox. Visual Studio requires you to put something there. Just put in any random UNC path (\\someserver\randomfolder)
Click the "Options" button. Select "Manifests" and check "Exclude deployment provider URL". This will remove the path you were forced to add in step 1.
This should allow clients to put your deployment wherever they want. When their users install, their start menu shortcut will point back to where they put the deployment.
Here's the description from MSDN about that checkbox...
Exclude deployment provider URL
Specifies whether to exclude the
deployment provider URL from the
deployment manifest. Starting in
Visual Studio 2008 SP1, the deployment
provider URL can be excluded from the
manifest for scenarios in which
application updates should come from a
location unknown at the time of the
initial publication. After the
application is published, updates will
be checked from wherever the
application is installed from.
Perhaps, the link here could save you, if I am not mistaken, you are worried about the drive letter and handling UNC conventions? Take a look at this on CodeGuru, which contains code on how to map to a UNC share dynamically at run-time.
The problem is Security related to the .Net framework. Unfortunately i don't have much experience in this area, but maybe one of these links will help:
Microsoft is aware of this problem
Hint about mscorcfg.msc
Another hint from ID Automation
Last but not least: A google search
Can you use a UNC path?
\\\server\folder\app.exe?

Quick question regarding reflection and permissions. .net 2008

I have various projects that use reflection to access and invoke private or internal members in some of the framework classes.
These projects all work fine on my machine (running visual basic express 2008), but are they guaranteed to work on another machine, or, say, over a network?
I've had a look at ReflectionPermission, but I'm not sure if I need that granting to me or if I grant it to my project!
I'm not as stupid as this question sounds, honest!
The computer where the program runs needs to grant ReflectionPermission to the program.
This will be no problem if the user runs your program from the local filesystem. It may be a problem if the user runs your program from a network share, an intranet, the Internet, etc. depending on the policies of the computer where the program runs. Policies may also consider factors such as the originating URL or network share, whether the program is signed, etc. For example, if this is an intranet app, the network admins may allow high trust to programs that originate from http://our_site/approved_apps/ and are signed, but not to programs that originate from other parts of the intranet or are unsigned.
In any case, it is outside your control: your assembly can state that it needs ReflectionPermission, but whether it is granted is up to the configuration of the target system. (But again, if your program runs from the local file system, it shouldn't be a problem because it will then run with full trust unless someone has really locked down the machine.)
They should work fine on any machine as long as it is run from a local drive. By default running the executable from a network share on .NET up to 3.5SP1 would run you in a reduced trust mode (either Internet or Intranet) and you would not have access to the ReflectionPermission which means you will not be able to access protected or private members.
From 3.5SP1 onwards they have changed the operation of executables to give them full trust if run directly (as opposed to be loaded into another process via Assembly.Load and similar).
You can also grant specific permissions to an assembly using the caspol tool which is part of the framework. See this for more info about caspol.
If you can execute the code then you should be able use reflection to interrogate it.
From my reading of the ReflectionPermission MSDN page it seems that you need to use this to gain access to all members of objects:
Without ReflectionPermission, code can use reflection to access only the public members of objects. Code with ReflectionPermission and the appropriate ReflectionPermissionFlag flags can access the protected and private members of objects.

C# application-level permissions greater than user's?

Can user schmoe_j run an app that copies files to a directory that schmoe_j can't write to?
No, permissions on files are handled by the file system which is at a much lower level in the system than C# code runs as. C# code can't directly bypass file system security. If the application runs as schmoe_j it can't write to locations on disk that schmoe_j doesn't have write-access to.
One exception is if schmoe_j has backup & restore privileges, in which case he can write to anywhere on disk. Normal users don't have this privilege because it is a very dangerous privilege to grant.
There are other theoretical ways - for example, if an insecure service is on the box that can be persuaded by a standard user to write to an arbitrary place on disk. Any such cases is a security hole that should be fixed.
You can include an Manifest with your executable to request that the application is run with higher privileges.
See Adding a UAC Manifest to Managed Code.
I think normally the way this is handed is to use a service (or service application) which runs under elevated permissions but with a very small surface area and no GUI. The user interacts with an application running under lower permissions which would do things that user's account can do - place files in a dropoff folder, write to a database, etc. Think IIS, MMC, TrustedInstaller, etc.
The application will run under the user's rights, if the user can;t do it, the application can't do it.
HOWEVER, the application can attempt to impersonate another user, in which case it would be able to gain access to that directory. This involved the app temporarily gaining the rights of another user. this is how ASP.NET works quite often.
The up-shot is that the user would have to provide the credentials of the impersonated user.
Article demonstrating this.
Can he run the app? Yes. It will throw an UnauthorizedAccessException when it tries to copy those files, but not before.
Depending on the class being used, usually an exception will be thrown when you don't have proper permissions to write to a directory.
As an example, according to MSDN, when calling File.Create and File.Copy, an UnauthorizedAccessException will be thrown when the caller does not have the required permissions.

Categories