If I’m an Administrator, Why Do I Get Access Denied?

User Account Control (UAC) can seem mysterious. After all, if I’m a member of the Administrators group, shouldn’t I have access to everything?  If you’re a developer, you’ll run into a UAC issue sooner or later.  In this post, I’ll cover the basics that every developer should know.

Standard User by Default

Running applications as “Standard User” by default is what UAC is all about. Running processes with as few rights and privileges as possible is a common security defense in depth technique. UAC accomplishes this during the logon process. The traditional NT security model created a single access token at logon that all processes on the desktop use. The token contained privileges based on the groups the logged on user belonged.  With UAC enabled, the logon process creates the traditional “full” token and also creates a limited “filtered” token.  The filtered token contains only “standard user” privileges.

Here’s a slide to help illustrate the “by default” part.

image

The magic happens when explorer.exe is started using the filtered token.  Explorer.exe is your taskbar and is responsible for starting everything on the desktop. By default, child processes are started with the same token as their parent. Therefore, since explorer.exe is started with the filtered token, everything that is launched by the taskbar is standard user by default (presto!).

Bonus question: What token is used to start explorer.exe with UAC disabled? Answer: The full administrator token.  This is why Windows 7 (and Vista) behave like traditional NT with UAC disabled.

What if you want to use the full token?  You can run you application elevated (right click and select “Run as Administrator”). This will start the application with the full token instead of the filtered token. As an application developer, if you have a good reason to always start an application with the full token, you would set the appropriate run level in the manifest.

Let’s take a look at two different command prompts to illustrate this concept.

The following is a command prompt started from the taskbar:

image

The following is a elevated command prompt started from the taskbar via right clicking and choosing “Run as Administrator”:

image

We can see that the user name and the SID are identical.  However, the non-elevated command prompt only has the privileges of a standard user.

What’s a Standard User?

A standard user is only allowed to change their own settings and environment (per user).  An administrator can change system wide settings (per machine). Here’s a table of examples of what you can and can’t do as a standard user:

Allowed Not Allowed
Run most applications Install applications
Change per user settings Change system components
Read from per user and per machine locations Change per machine settings
Create local objects Perform operations requiring Admin privileges
Write to per machine locations
Create global objects

 

Just by simply limiting the scope of changes a user/application can perform can have a big impact on security, reliability, and stability of a machine. Enterprise guys who manage lots of desktops like the concept of standard user because it helps lower their TCO.

Finding UAC Issues

The first step to determine if you have a UAC issue is to try running the application elevated (right click – Run as Administrator). You can also try turning UAC off.  If your application works in one of these scenarios, you probably have a UAC issue.

UAC issues are caused by an application trying to make a change system wide. This means it’s trying to write to a per machine location or create something globally across all users.

Is your application trying to:

  • Write to Program Files, Windows, System32, HKLM/Software, or Root?
  • Create anything “globally” like a memory mapped file?
  • Send Windows messages between an app running as standard user to one running elevated? (See: this post)

If so, this is where to start looking for the problem.

After you have an idea of where the problem might be, Process Monitor is a great tool to start isolating the issue.  Process Monitor will log all file and registry activity and will usually point you in the right direction.

Here’s a snip from a Process Monitor log where an application is trying to write to the HKLM hive in the registry. HKLM is protected by UAC and Mandatory Integrity Control (MIC).  Therefore, you will get an Access Denied:

image

We can see in the log what key is trying to be opened for write and the result of ACCESS DENIED.

Looking for UAC issues can be tricky. You need to watch out for UAC Virtualization as well.  UAC Virtualization may allow your program to avoid access denied errors. However, when you manifest your app, it will disable this mitigation. See my post on Demystifying UAC Virtualization.

Here’s a sample app trying to write junk.txt to Program Files. Program Files is protected by UAC and MIC. However, the program doesn’t fail because of UAC Virtualization in this case:

image

We see that we try to write to Program Files but get a “REPARSE” result. This is UAC Virtualization intercepting the access denied. We then see the file being written to the virtual store instead.

Next Steps

The goal of this post was to give you a base understanding of UAC from a developer perspective. UAC is a really big topic. There’s a lot of good resources. Here are some of my favorites:

Application Compatibility Cookbook: User Account Control Inside Windows Vista User Account Control – Read this one first :-)

Inside Windows 7 User Account Control MSDN: User Account Control