How to know whether I have admin authority in windows? - c++

Is there any APIs in windows to detect whether the current user(current now) has the admin authority?
BOOL IsHasAuthority()
{
}
Many Thanks!

How to Determine Whether a Process or Thread Is Running As an Administrator
Use this solution when you are writing
an application that must determine
whether any of the following is true:
The current user can perform administrative tasks. The current
user is a member of the
Administrators group. A supplied token handle represents an
administrator with an elevated token.
A token handle represents a user who is a member of the
Administrators group.
The program is running with an elevated token or needs to spawn a
child program that is elevated so it
can perform administrative tasks.

You can use the Windows API function CheckTokenMembership(). The MSDN documentation for that function has an example demonstrating how to check for membership in the Administrators local group.

Related

WMI ExecNotificationQuery Need Administrator Privileges to Query for Win32_ProcessStartTrace but not for __InstanceCreationEvent

When I attempt to make a call to ExecNotificationQuery with query "SELECT * FROM Win32_ProcessStartTrace" I get a WBEM_E_ACCESS_DENIED Error code returned.
If I instead make the query "SELECT * FROM __InstanceCreationEvent" The query returns successfully.
However if I run my program as administrator then both of these queries return successfully.
I have 2 questions related to this
Why does one class require Administrator privileges and the other doesn't
In the future how can I discover what WMI class queries will require admin privileges without having to test them I can't see anything on the class documentation about restricted access
Thank you
After further attempts to understand WMI events:
The difference here comes down to the where the event comes from.
__InstanceCreationEvent is an intrinsic event which means it's defined by and sent by WMI in reaction to changes in WMI's data model, these are accessible to non elevated users.
Win32_PorcessStartTrace on the other hand is an extrinsic event, Extrinsic events are defined and sent by entity's external to WMI in this case that's the Windows Kernel Trace Provider which provides the Win32_ProcessStartTrace event. When an event provider like the Windows Kernel Trace Provider defines extrinsic events it supplies access information to specify who can access these objects.
So to answer question 1): Because the Windows Kernel Trace Provider has defined it that way
To answer question 2): I have yet to experiment with it myself but probably by calling GetSecurityInfo() on the SECURITY_DESCRIPTOR retrieved from the queried event object, and inspecting the DACL(discretionary access control list).

How can an admin process open an application in the logged in user?

Overview
The Process
exe/dll compiled in C++ to be run
Scenario
Log in (win 7) to a standard user account (no admin)
run The Process as admin
The Process opens some app (exe) using ShellExecute
Problem
The app is opened in the scope of the admin user
Expecting
The app is opened in the scope of the standard user
Solutions
1. CreateProcessAsUser
Use CreateProcessAsUser (Assuming I managed to get hToken right that should have solved the issue).
However, I get the call failed with error code 1314 - ERROR_PRIVILEGE_NOT_HELD. Going back to the documentation tells me:
If this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the
CreateProcessWithLogonW function instead
So I digged in and found this CreateProcessAsUser Error 1314 which wasn't very helpful.
2. ImpersonateLoggedOnUser
using ImpersonateLoggedOnUser generated the same error code: 1314 - ERROR_PRIVILEGE_NOT_HELD.
3. CreateProcessWithLogonW
CreateProcessWithLogonW requires lpPassword which naturally I don't have
The Question
How can an admin process open an application in the logged in user?
Have you tried using CreateProcessWithTokenW which is mentioned in the CreateProcessWithLogonW documentation? It seems to require a much weaker privilege than CreateProcessAsUser, one you should posses (SE_IMPERSONATE_NAME rather than SE_ASSIGNPRIMARYTOKEN_NAME).
You said you already have a token for the interactive user so I won't go into it.
(Note: Strange bugs have been reported with all of this, including CreateProcessWithTokenW. Don't give up on the first attempt. A bug and a fix for example: why is CreateProcessWithTokenW failing with ERROR_ACCESS_DENIED )
hToken is not a "right". It's a token. What the error says is that you lack a privilege.
Holding a privilege is not a fundamental right! Some privileges are given to certain users by default. Others need to be given through the Local Security Policy (in the "User Right Assignment" node in the MMC snap-in or with LsaAddAccountRights - all of which is documented in the page Assigning Privileges to an Account).
Besides that you sometimes have to enable privileges using AdjustTokenPrivileges. This is documented in the sibling page Changing Privileges in a Token.
Some APIs enable them if you hold them. Others don't and require you to do so yourself. The obvious way to go is to enable a privilege before calling and API that's documented to require it.
The MS Forum link may not have been but the error message is quite clear. MSDN says about the function:
Typically, the process that calls the CreateProcessAsUser
function must have the SE_INCREASE_QUOTA_NAME privilege
and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege
if the token is not assignable.
and the error is (from the page you linked to!):
ERROR_PRIVILEGE_NOT_HELD
  1314 (0x522)
  A required privilege is not held by the client.
This is actually a very tricky Task you want to accomplish. There are very strict security policies which make it very difficult.
As far as I know you can do it with psexec. It has a commandline Switch which enables user interaction but running the process as admin. I think your command should look like the following:
psexec \\target-computer -i -s [your command]
Another way to do it is using WMI. But for this you Need to Change the security Settings of the target machine (probably using GPO's). You Need to connect to the target machine using impersonation Level deletgate see here. Additionally as said before, you Need to Change the security Settings. See here

How to logoff a user when the workstation is locked?

I wrote a Windows application that comes with two modules: service and user-mode applications. The service implements its own scheduler and may log-off a user at a predefined time. For that I was using the following call that is triggered from my user-mode module running in a logged-on user session that has to be logged off:
BOOL result = ExitWindowsEx(EWX_LOGOFF, reason);
This works fine, except of the situation when a user's account is locked. In that case that API doesn't seem to do anything at all even through I get 1 returned from it.
So I was curious, is there any other way to log off a user when their account is locked? (One condition I have in this case is that if that user had any unsaved documents then the log-off should not be forced.)
Try this:
DWORD dFlags = EWX_LOGOFF | EWX_FORCE | 0x10200;
BOOL result = ExitWindowsEx(dFlags, reason);

GetUserNameExA function cannot give user Details at system startup time(GINA)?

i am using c++ win32 API.
i tried to get user details using GetUserNameExA();
i have use this function into system logondialog source(GINA).
in my logfile,it gives
CN=ComputerName,CN=Computers,DC=JEGAN,DC=COM".
But it's used after logon on to system,at that time it gives user details like "CN=sanju,CN=USERS,DC=JEGAN,DC=COM" in my other solution.
i want user details only,but it gives system details at the logon time,how can i achieve user details at logontime?
note: i have already tried ADSI,LDAP functions & directoryservices cant able to use.so suggest any other system functions.
David is correct - the GINA DLL is loaded by the WinLogon.exe process. Check Task Manager and you'll see that WinLogon.exe runs as Local System. The GetUserName and GetUserNameEx functions provide information about the identity for the current thread:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx
From a 20,000 foot view, after a user's credentials have been validated, the GINA notifies all Network Providers of the successful login. After this, it loads the user's profile and creates the user's shell (Explorer.exe) which is then displayed.
You might try using a Network Provider instead. They are fully supported up through Windows 8 and multiple NPs can be defined for the system so you won't run into the 'chaining' issues that GINAs have.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378775.aspx
The NPLogonNotify function will receive the user's cleartext name, domain and password (sometimes you'll receive a UPN as username in which case the domain is blank). You can use this information as is, perform LDAP-based lookups to AD or use LogonUser & ImpersonateLoggedOnUser before calling GetUserNameEx. Be extremely careful with this last approach since network providers run as Local system within the WinLogon.exe process. Always call RevertToSelf and CloseHandle to undo/clean up the previous calls.
The only (quite quirky) workaround for what you are trying to do is to log on some other user account on the side which has access to the domain and can thus query user details (don't remember the permissions needed in detail, though). Otherwise I'd suggest you go with Gregg's answer.
With a thread impersonated as such user you should then be able to query the information for the user that you are going to log on (how do you even know by that time?) via NetUserGetInfo() and friends. Choose the USER_INFO_* struct that best suits your needs and simply ask the domain server for the information. This should also work on earlier and later systems (the functionality, not the GINA itself).

Trying to interpret user session states on Windows OS

If I call the following API from a local service running on Windows 7:
WTS_SESSION_INFO* pWSI;
DWORD nCntWSI;
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWSI, &nCntWSI);
and then go through all returned WTS_SESSION_INFO structs in pWSI and check WTS_CONNECTSTATE_CLASS State members, can someone explain what is the difference between WTSActive and WTSConnected?
Connected means the user has connected and has been (or soon will be) presented with a login screen but hasn't completed it and been verified yet. He might be typing his password, for example.
If the user has locked the workstation, it's been locked by a screensaver, or he has switched to another user account, it doesn't end his session. The user remains logged in and his session would remain marked active. So being connected but not active means there are no processes running under that user's account. (The one caveat being there could be a service or other process running in a separate session under that user's credentials, but that's a different matter.)