Whats going to happen with COleTemplateServer::RegisterAll() in windows 7 - c++

Ok, so we have a C++ app that runs fine in Windows XP.
It has the following code in the initialization
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
Now like i said, it works fine in Windows XP, but as far I understand the program tries to register its COM interface Which is fine in XP, but this may be a problem in Windows Vista and Windows 7 because of the UAC. Especially if its is run as a standard user (with no elevated privileges).
If i understand it correctly this is needed for the program to run properly, but it cant execute this code without elevated privileges. If it will run every time the app runs (this usually runs when CWinApp::init() is run)
Before you say just use admin privileges, the user will not have them, there is no way to change that
So, now my questions are:
1) am i correct in my assumptions?
2) if I am correct, what is the best way around this? Can i just remove this? Do i need to set up some other thing? (we changed some VB modules to use a XML file instead of stuff in the registry
PS: the modules compiles into DLLs
PPS: UAC MUST be on

Take note that:
The documentation for these functions makes no mention of any privilege requirements; and
nobody online seems to be having trouble with these functions in limited privilege environments; and
it's 2012, I think someone would have noticed if these functions didn't work under UAC by now.
So (with nothing to suggest otherwise) I'd say It Just Works.
Notwithstanding the above, I looked at the implementation of COleObjectFactory::RegisterAll() and COleObjectFactory::UpdateRegistryAll().
RegisterAll
Ultimately calling RegisterAll ends up in olefact.cpp:135 where CoRegisterClassObject is called. From MSDN:
Registers an EXE class object with OLE so other applications can connect to it.
I believe this registration will be limited to the current user's session and the lifetime of the application. The Remarks section touches on privileges (As of Windows Server 2003...) but doesn't provide anything concrete.
There's an object known as the Running Object Table (ROT) that can be retrieved via GetRunningObjectTable. The documentation has this snippet:
Each workstation has a local ROT that maintains a table of the objects that have been registered as running on that computer.
The COM Elevation Moniker has some more information about the ROT and privileges (it suggests processes of various privilege levels work fine with it). The links on the left-hand side might help, too.
Overall it seems there's nothing to suggest that CoRegisterClassObject requires administrator permissions.
UpdateRegistryAll
This function ends up in olefact.cpp:375 where it opens HKEY_CLASSES_ROOT. At this point the documentation gets a bit better:
Registry functions such as RegOpenKeyEx or RegQueryValueEx allow you to specify the HKEY_CLASSES_ROOT key. When you call these functions from a process running in the interactive user account, the system merges the default settings in HKEY_LOCAL_MACHINE\Software\Classes with the interactive user's settings at HKEY_CURRENT_USER\Software\Classes.
Further on:
If you write keys to a key under HKEY_CLASSES_ROOT, the system stores the information under HKEY_LOCAL_MACHINE\Software\Classes
The documentation doesn't define what happens when you try to write to HKEY_CLASSES_ROOT under limited privileges (i.e. a standard user can't write to HKLM), but I believe that you'll end up writing to HKCU instead.
And finally, note:
Windows Server 2003 and Windows XP/2000: Applications can register dependent COM objects to either the per-machine or per-user COM configuration store (HKEY_LOCAL_MACHINE\Software\Classes or HKEY_CURRENT_USER\Software\Classes).
So if it falls through to HKCU, you should be fine.
Caveat Implementor: Don't rely on implementation details.

Related

Not able to access registrty beyond a certain level in windows registry, does it need admin rights? [duplicate]

Is it possible to get a C++ application running in Windows to request administrator privileges from the operating system at run time?
I know it can be done at compile time, but can't seem to find anywhere whether it can be done at run time.
Thanks for your help!
EDIT: What if I want the current instance to have elevated privileges? For example, I might have data stored in memory which I want to keep.
If you want the application to always elevate, you can give it a manifest, either by building one in (not compiling technically) or by putting an external manifest in the same folder as the exe. If you want to decide, as a person, to run it elevated, you right click the exe or short cut and choose Run As Administrator. If you are launching it from code, then as #vcsjones comments, you use the runas verb when you launch that process. For example:
ShellExecute( NULL,
"runas",
"c:\\windows\\notepad.exe",
" c:\\temp\\report.txt",
NULL, // default dir
SW_SHOWNORMAL
);
You can elevate a process only during its creation. When a process already runs, there's no way to change its security token: it either runs elevated or not.
If your application needs to perform an administrative task, and it usually runs non-elevated, you have to create another .exe which will request elevation with its manifest. To start a process elevated, you have to use ShellExecute or ShellExecuteEx function. From your main process you will need a way to pass the commands to that new process that will run elevated.
For more information about UAC, read Designing UAC Applications for Windows Vista series.
Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.
Add a manifest file into your EXE as described here.
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Your process (and threads) have a token assinged to them. That token already have all your groups set up. Under UAC, the Administrator group is disabled. UAC will remove that disabled group so you end up with a full administrator token.
To acheive the same, you must have the TCB priviledge. In other words, to elevate a process at runtime, you will need help from a process running under the SYSTEM account, and Microsoft isn't providing one, nor an API to control the current UAC implementation. Otherwise, it would defeat the purpose.
For the sake of completness, there is a whitelist of process that can perform some elevated operations without prompting. In short, your executable needs :
To be signed by Microsoft
To perform predefined operations, like with IFileOperation
The best explanation I found is this hack. It has been fixed since then, but is sheds some light on the whole thing.

C++: MsiOpenDatabase fails with error 110 0x6e ERROR_OPEN_FAILED only when elevated / admin

I am having a problem with calling the function MsiOpenDatabase (https://msdn.microsoft.com/en-us/library/aa370338(v=vs.85).aspx) from inside a program when I choose to "run as administrator". When I run it under an admin account but without explicitly starting the executable as elevated it all works just fine. This indicates that the path to MSI file etc should be correct.
So, when running elevated the MsiOpenDatabase() I get an error code of 110 (0x6e).
I have tried to call MsiGetLastErrorRecord as explained here (https://msdn.microsoft.com/en-us/library/aa370124(v=vs.85).aspx) but nothing happens when I try to print the code in a message box. It simply doesn't get there.
I do not have Visual studio for debuggning on the target machine, so debugging is a bit of a pain.
Target machine is Windows 7 x64. Application is 32-bit.
But just the pure fact that it works un-elevated but fails when run as an administrator...it feels like there should be some kind of answer to this which can be derived from this fact perhaps?
Thankful for any help!
EDIT:
I finally solved it!
Apparently I had to go to the network share where the MSI file is located (which I am trying to call MsiOpenDatabase on) and right cklick on a file there and choose "run as administrator" because then and only then did I get a UAC dialog box asking for credentials (I mean I was able to open Windows Explorer as admin and navigate to the network share without problem so I never thought that it would be what would give me these peoblems). After haing done that I was able to run my application and it did no longer fail on any MsiOpenDatabase call.
But, why must I do this procedure to get access to run file on a network share since I already had access (execute rights) with the same user but when not elevated? How come Windows needs to ask the same user for credentials if it is already running elevated on the very same account that already has access to the network share? Seems strange to me, but I suppose I am missing some crucial part?
SAMPLE CODE
LPCTSTR szPersist = MSIDBOPEN_READONLY;
MSIHANDLE handleDB;
UINT result = MsiOpenDatabase(strPath, szPersist, &handleDB); // strPath is something like _T("\\server\MSI\Setup.msi");
result variable has value 110 when this error occurrs as explained above and keep the part in the update section in mind. I find it strange, but perhaps someone knows UAC better than me and why I have to provide credentials again by going to a file on the netowrk share and choose to run as admin to get it working (since I have already provided credentials as non-admin with the same account earlier at that very same network share location)?
This is standard UAC behavior since Windows Vista and is not related to MSI at all. Do a google search for "uac network drives".
You should be closing your MSI handles though as I commented above. Use PMSIHANDLE instead of MSIHANDLE.

Can I have a COM interface in a service to be called from Windows Script Host?

My goal is to create a COM interface in my Windows local service, written with C++/MFC, whose methods could be called from a Windows Script Host JScript code running under a logged in interactive user account.
For instance, if I have a test.js that can be started with credentials of a logged in user, that does the following:
var Obj = new ActiveXObject("myservice.somename");
var Result = Obj.MyMethod("some data");
and then have MyMethod function processed in my service & return a value.
I know it's a general concept. At this stage I'm curious if such is possible (from a Windows security stand-point, i.e. calling system service from a user process) and if so, if there's any sample code that I can use as a basis for this?
I'm assuming that it must be some COM interface, right? But usually those go into a DLL. I've never tried to put them in a service.
Thank you!
I'm posting it for my own future reference, in despite of the treatment I got in the comments to my original post. It would've saved me a day of search if someone pointed me to this article...
This CodeGuru article, "COM in plain C, Part 2" explains how to create a COM interface that can be called from the Windows Script Host. His IExample2 project shows how to create an in-proc DLL that hosts the COM interface that can be called from a VBScript included in the same project. Then regiexample2 and unregiexample2 projects also show how to register/unregister the COM interface. The VBScript can be easily adjusted to work with JScript in my OP.
One word of caution though, that project is intended to be used for installation on a 32-bit OS. For 64-bit OS, you will need to build and register a 64-bit version of the in-proc COM Dll. The registration part from a 32-bit process is similar to the one shown, except that one needs to include the KEY_WOW64_64KEY flag when opening/creating registry keys.

When does an application absolutely require to be run as an administrator?

I have been dabbling with working nicely with UAC for a while and I found about a few things:
With UAC enabled, a program in the Startup folder, that requires to be run as admin (say by an embedded manifest), cannot be run according to this Stack Overflow thread.
Another method of running a program at startup is by creating a key containing the path to that application in: HKLM or HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or HKLM or HKCU\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run in 64 bit machines.
Yet another method is using the task scheduler setting the Run with highest privileges option. This is the only method that bypasses the problem stated in point 1.
Coming from a Linux background, I had no clue about all these admin rights related problems. If someone can list out scenarios which absolutely need administrator privileges, it would be of great help!
I'm asking this because when I'm developing some application, I keep encountering several problems during implementation mostly because my application required admin rights when it shouldn't.
If I know, at design time, all possible scenarios that require admin rights, I could possibly design a common service for all my applications that takes care of all the administrator tasks (I think services are the Windows way of doing things like this).
There really isn't a list of scenarios or API function calls that require elevation. Your best option will probably be to focus on what API calls require elevation. The reason for this is that it may be required only if certain values are passed to the function. For instance CreateFile can create a file in your home directory without elevation but requires it for creating a file in C:\Windows. If the directory is provided through user input the only way you can know if elevation is required is to check the error code when the call fails. If elevation is required the function will set the error status to ERROR_ACCESS_DENIED and return a value indicating failure.

Requesting administrator privileges at run time

Is it possible to get a C++ application running in Windows to request administrator privileges from the operating system at run time?
I know it can be done at compile time, but can't seem to find anywhere whether it can be done at run time.
Thanks for your help!
EDIT: What if I want the current instance to have elevated privileges? For example, I might have data stored in memory which I want to keep.
If you want the application to always elevate, you can give it a manifest, either by building one in (not compiling technically) or by putting an external manifest in the same folder as the exe. If you want to decide, as a person, to run it elevated, you right click the exe or short cut and choose Run As Administrator. If you are launching it from code, then as #vcsjones comments, you use the runas verb when you launch that process. For example:
ShellExecute( NULL,
"runas",
"c:\\windows\\notepad.exe",
" c:\\temp\\report.txt",
NULL, // default dir
SW_SHOWNORMAL
);
You can elevate a process only during its creation. When a process already runs, there's no way to change its security token: it either runs elevated or not.
If your application needs to perform an administrative task, and it usually runs non-elevated, you have to create another .exe which will request elevation with its manifest. To start a process elevated, you have to use ShellExecute or ShellExecuteEx function. From your main process you will need a way to pass the commands to that new process that will run elevated.
For more information about UAC, read Designing UAC Applications for Windows Vista series.
Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.
Add a manifest file into your EXE as described here.
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Your process (and threads) have a token assinged to them. That token already have all your groups set up. Under UAC, the Administrator group is disabled. UAC will remove that disabled group so you end up with a full administrator token.
To acheive the same, you must have the TCB priviledge. In other words, to elevate a process at runtime, you will need help from a process running under the SYSTEM account, and Microsoft isn't providing one, nor an API to control the current UAC implementation. Otherwise, it would defeat the purpose.
For the sake of completness, there is a whitelist of process that can perform some elevated operations without prompting. In short, your executable needs :
To be signed by Microsoft
To perform predefined operations, like with IFileOperation
The best explanation I found is this hack. It has been fixed since then, but is sheds some light on the whole thing.