Problem using AddIPAddress when impersonating an Admin User - c++

I am attempting to add a temporary IP address to a NIC using AddIPAddress when logged in as a non-admin user. The MSDN documentation for AddIPAddress states that ERROR_INVALID_HANDLE is returned as as error if the function is called by a non-admin user.
Given that I have preceeded the call to AddIPAddress with API calls to LogonUser() and ImpersonateLoggedOnUser(). Now my application thinks it's logged in as an Admin, but AddIPAddress still fails with ERROR_INVALID_HANDLE.
MSDN also states that..
"Note Group policies, enterprise policies, and other restrictions on the network may prevent these functions from completing successfully. Ensure that the application has the necessary network permissions before attempting to use these functions."
Is it possible to call AddIPAddress using impersonation? if so how? I'm guessing I need to change the permissions mentioned above but I am at a loss as to what to chnage in this area.
Any help would be appreciated!
Additonal: I've also drawn a blank while attempting to call out to netsh (again logged in as a normal user) using CreateProcessAsUser using a handle to an impersonated admin user to launch the process. Always returns errors indicating insufficent priviledges.

If you are using windows Vista you may need to elevate privileges.
In Vista by default UAC is enabled. This makes it so that even as an administrator you are using a limited user token unless you explicitly elevate. When you do this the user is presented with a dialog to allow or deny the request.
For more information on this see Windows Vista Application Development Requirements for User Account Control Compatibility.
You may want to try using CheckTokenMembership to verify you are properly elevated after you log on as admin. I would suspect you are getting the limited user token and thus failing requests for privileged resources.
Best of luck.

Related

Missing business_management permission when trying to create token for system user

I'm trying to create a system user token for one of my apps as described here in the Facebook API documentation: https://developers.facebook.com/docs/marketing-api/businessmanager/systemuser/#systemusertoken
I'm using the Graph API explorer to make the call, include the correct parameters (appsecret_proof, business_app etc.) but receive the following error:
(#200) Requires business_management permission to manage the object
It is true that the access_token I'm using when making the call does not have the business_management permission, but I don't understand why. The user that is making the call is Administrator for the app in question and has all rights I could possibly give. Also, for my other app, the permission shows up correctly when creating the user token and I cannot spot any difference in the configuration of the two apps.
I'm wondering if I need to put the app (which is a mobile game) through app review, but that seems kind of wrong because I don't want to request that permission from users or anything, I just want to use my administrator account to generate a system user token, which is a one-time action. The other app that correctly shows the permission also didn't go through app review, and both apps don't use Facebook for anything user facing, not even for logging in.
I feel like I'm completely on the wrong track and probably don't see the real problem here, but I'm also out of ideas. Is there something obvious I'm missing or anything else that could cause this permission not to show up?
I solved it now by putting the app back into development mode, which apparently allows all permissions to be granted. Creating a system user token worked fine and the system user is able to make API calls even after the app is set back to "live".

How to invoke a function impersonating another user instead of SYSTEM

A Win32 API was invoked in my DLL, which will be loaded by SYSTEM user, and that API returns different results depending on current user, so I cannot get the results corresponding to the current user, how can I invoke that API under current logon user context when the DLL is running in SYSTEM context?
I've made some research and concluded this (I'm not a Win32 API expert, but I'm really interested in it):
You can use ImpersonateLoggedOnUser, which asks for a primary or an impersonation token handle (with at least TOKEN_QUERY in both, TOKEN_DUPLICATE on a primary token, or TOKEN_IMPERSONATE on an impersonation token).
It would be very easy, if you had the current logged on user token, and the right privileges, you'd just use ImpersonateLoggedOnUser, call the API function that you want, and then call RevertToSelf to return to its original owner token.
But it's not that easy to get the current logged on user token. You'd have to either use LogonUser specifying the user's name and password (which doesn't seem right), or own a Windows service with sufficient privileges to let you call WTSQueryUserToken, which may differ from what type of project you are developing.
Or, if you are really willing to do this with an ordinary process, you could also explore the Authentication Functions, where you can take advantage of the newly Windows UAC and security contexts, which may be a little complex to work with.
There is also this method which I'm not sure if it works: Impersonate standard user (getting the token by using OpenProcessToken on explorer.exe).
Some links I found useful:
MSDN - Client Impersonation (Windows)
MSDN - Access Tokens (Windows)
MSDN - LsaLogonUser function (Windows)
A Simple Impersonation Program Example
CodeProject - User Impersonation
CodeProject - Vista UAC: The Definitive Guide
I suggest: make sure you really need to impersonate an user when calling the API function you mentioned, before going on. See if there is another path to accomplish what you want.
You could also specify which API function you are trying to use, which may redirect you to another simpler question.

On Non-Admin Account OpenSCManager() function returns null

Please help me soon.
I am writing a c++ code to run a service, it works fine on administrator account
but on Non-Admin user account, OpenSCManager() function return null.
Please tell me how to grant permission to non-admin user account to start and stop services.
Or do i need to do something else.
Please reply soon
Probably you're calling OpenSCManager specifying the SC_MANAGER_ALL_ACCESS flag, which actually requires a set of privileges that are given by default only to admins. To start/stop services here you just need to specify the SC_MANAGER_CONNECT flag, which is given by default to any authenticated user.
Now that you have a handle to the service manager, you have to use OpenService to get a handle to the service. To have rights to start/stop the service you should specify GENERIC_READ | GENERIC_EXECUTE as desired access (actually I think you can even narrow down the needed rights to just SERVICE_START and SERVICE_STOP and, if necessary, SERVICE_INTERROGATE).
Here is the problem: standard services DACL don't grant such rights to normal users, so you should change the DACL of the service you need to start to allow normal users to start/stop it; see here. For more info about access rights for services, see here.
If, instead of a single service, you want to allow a normal user to start/stop any service, I don't know if it is possible without changing all the DACLs, but in my opinion it's definitely a bad idea.
Note that even in the single service case, if the service is running under a privileged account (e.g. LocalSystem) or if it's a vital system service, letting unprivileged users mess with it it's still a bad idea. You should allow users to start/stop only services that aren't all that important for the system.
Out of curiosity, why do you need to let users start/stop services?

Open default browser as standard user (C++)

I'm currently using ShellExecute "open" to open a URL in the user's browser, but running into a bit of trouble in Win7 and Vista because the program runs elevated as a service.
When ShellExecute opens the browser, it seems to read the "Local Admin" profile instead of the user's. So for example, if the user at the keyboard has Firefox as his default browser, it may open IE (which is the admin's default).
I know that the "runas" verb can be used to elevate, but how do you do it the other way around? Is there a way to open a URL in the default browser on a standard user's desktop from a service?
ShellExecute will execute the program in the context of the same session and same user as the process you are running.
If you'd like to use a different session or user token you can use the CreateProcessAsUser Win32 API.
There are several ways to obtain a user token, for example you can call the Win32 API:
LogonUser if you know the username and password
WTSQueryUserToken for any given session ID.
OpenProcessToken if you have another process handle
After a while of testing, the best way to determine the default browser is the following:
NOTE: It is strange but it's true...
It has nothing to say that an application is the default application for
some file type or web protocol like 'http'. What matters to determine the default
web browser is just what is registered in the start menu entry (see reg key below).
So forget all the HKCR\http, HKCU\Software\Classes\http, HKLM\Software\Classes\http and their friends.
read from "HKEY_CURRENT_USER\Software\Clients\StartMenuInternet"
read command line from "HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet\\shell\open\command"
truncate the command line after ".exe"
Of course you need to impersonate as the logged on user first.
If this solution does not work (like with w2k), use the handler for the http protocol.
To actually start the default browser from a service we use an extra process which is within the service using the logged on user-context. This process starts the above commandline (using ShellExecute on platforms >= Vista). Be sure to use same integrity level (medium) as a default user (else IE won't work because it uses DDE).
HTH.
Aaron Margosis has a seven-step native code example at http://blogs.msdn.com/aaron_margosis/archive/2009/06/06/faq-how-do-i-start-a-program-as-the-desktop-user-from-an-elevated-app.aspx. Won't help you from your service if that is what you have - I agree your service shouldn't be trying to launch an app as the logged in user, especially since there might not be one.

Impersonating users to access hives - various methods, what are the practical issues?

I am designing a Service to run under LocalSystem account on Win2000, XP and Vista. It will need access to users registry hives, sometimes for extended periods of time, both when the users are logged-in, and also, when they are not logged-in (IF the profile is local. If the profile is Roaming and not loaded, I will not attempt to load it.)
If the user is logged-on, I can get the Users access token by various means (E.g. from its Explorer process, or by receiving Logon events from the Service Control Manager) then use ImpersonateLoggedOnUser and RegOpenCurrentUser to access the User's hive. However, what are the implications if the User selects LogOff from the start menu while I am impersonating and have his hive open? Will the logoff be prevented? Will my impersonation be terminated?
If the user is not logged on, I can use RegLoadKey to directly open the hive NTUSER.DAT. (Impossible for a logged-on user). But what are the implications of this if the user decides to log-on (I suppose the hive will be locked and the logon either prevented, or may experience difficulty?)
I will be setting up some test projects to explore these ideas however, regardless of their apparent results, these questions are theoretical in terms of what type of problems might, or would, be caused by the user loggin in/out during these actions by the service.
Caveat: ImpersonateLoggedOnUser can ONLY be used either for a logged-on user (token obtained from process or SCM event) OR for a user for which I have the plaintext password to call WinLogon and obtain a token - TRUE / FALSE ? In other words although I have maximum permissions as LocalSystem and am able to change the user's password or even delete the user's account, if the user is not logged-on, it is totally impossible to create a new token to impersonate the user without having the the password?
Apparently, there is some risk of damaging a user's profile if it is already loaded by another process when the user logs in. In that case, the system will try to create a new subdirectory for the user.