views:

2043

answers:

7

I'm trying to find out if there is any way to elevate a specific function within an application. For example, I have an app with system and user settings that are stored in the registry, I only need elevation for when the system settings need to be changed.

Unfortunately all of the info I've come across talks about only starting a new process with elevated privileges.

+1  A: 

What you really need to do is store your settings the Application Data folder.

Joel Coehoorn
+2  A: 

Found a nice article that covers this here:

Most applications do not require administrator privileges at run time. If your application doesn't maintain cross-session state while it executes and doesn't do something like modifying the local security policy, it should be just fine running with a standard-user token. Sometimes certain parts of your application will require administrator privileges, and you should separate out those pieces into a separate process. I'll get into that a little later.

Looks like the article is talking about using C++, so I found another article that covers how to call this code using P/Invoke. So should be doable from .NET.

Bryant
+3  A: 

The best article I have seen is this one:

http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx

It explains down to the nitty gritty of whats going on behind the scenes when existing microsoft applications are bringing up the UAC prompt, and a bit of how to do it yourself, or at least you will know what your up against to make it work...

(note the examples he shows are managed c++)

uzbones
+10  A: 

It is impossible to elevate just one function or any other part of a single process, because the elevation level is a per-process attribute. Just like with pregnancy, your process can either be elevated or not. If you need some part of your code to be running elevated, you must start a separate process.

However, if you can implement your function as a COM object, you can run it elevated indirectly, by creating an elevated COM object, like this:

HRESULT 
CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
{
    WCHAR monikerName[1024];
    WCHAR clsid[1024];
    BIND_OPTS3 bo;

    StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);

    swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);

    memset (&bo, 0, sizeof (bo));
    bo.cbStruct = sizeof (bo);
    bo.hwnd = hwnd;
    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    // Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
    MSG paintMsg;
    int MsgCounter = 5000;  // Avoid endless processing of paint messages
    while (PeekMessage (&paintMsg, hwnd, 0, 0, PM_REMOVE | PM_QS_PAINT) != 0 && --MsgCounter > 0)
    {
        DispatchMessage (&paintMsg);
    }

    return CoGetObject (monikerName, &bo, iid, ppv);
}
Andrei Belogortseff
+2  A: 

The Windows SDK "Cross Technology Samples" have a "UACDemo" application which shows examples of a C# Windows Forms application which launches an administrator process to perform a task which requires elevation (i.e. writing to %programfiles%).

This is a great starting point for writing your own functionality. I've extended this sample to use .Net Remoting and IPC to call between my normal user process and my elevated process which allows me to keep the elevation executable generic and implement application-specific code within the application.

Aydsman
A: 

I think Aydsman is on the right track here. With the addition of Named Pipes support to .NET 3.5, you have a decent IPC mechanism for communicating with an elevated child process.

A: 

But if you have a generic elevated child process that will do whatever you tell it, isn't that a security risk? Is there anything preventing malware running with standard user rights from abusing your child process to perform administrative tasks? Of course it would have to be malware tailored to your administrator process, but still I was wondering...

f0k