What permissions are required for the Win32 LogonUser function? - winapi

Suppose that I want to run the LogonUser function in my code for a user with uid Bob, what permissions must Bob have for me to be able to call this function to log in as Bob successfully?

I don't know if there is a list anywhere since parts of the security system can use custom "plugins" (Authentication Packages, Security Support Provider Interface/Security packages and GINA/Credential Providers) and they might have other requirements.
On a default system it probably goes something like this:
The named user account passed to LogonUser needs the SE_*_LOGON_NAME account right that matches the logon type (LOGON32_LOGON_*) and the logon needs to pass the LSA and/or domain controller requirements (Logon hours, password not expired etc)
The process calling LogonUser needs SE_CHANGE_NOTIFY_NAME (Everyone has this by default), maybe SE_TCB_NAME (Required on Win2000). If you are going to call CreateProcessAsUser on the returned token you also need SE_INCREASE_QUOTA_NAME and maybe SE_ASSIGNPRIMARYTOKEN_NAME...
If you just want to start a process as another user you might want to use CreateProcessWithLogonW, if you just want to validate the credentials this KB article has a code example that does not use LogonUser (It seems like it might have some guest account issues though)

Related

G Suite Martkeplace: Get user who granted domain wide delegation to an app

Assume we have an app on G Suite Marketplace, and a G Suite domain administrator wants to delegate domain-wide access to the domain's users' data (as explained here).
For signup purposes, the 3rd service itself needs to know the domain name and the username of the administrator who performed domain-wide delegation of authority. This is needed to be able to use the Directory API (see note here)
I can easily get the domain name (by using Universal Navigation Extension, and adding ${DOMAIN_NAME} to the callback URL, as explained here). However, I didn't find a way to programmatically access the username of the administrator who performed DWD.
Any hints how to do that? Or if that is possible at all?
Thanks in advance!
Method 1:
When the user clicks in the launcher link (or just during installation with the configuration link you can configure) you need to do the OAuth2 flow and obtain the user email. Then you use the email assuming it is from an admin and it usually should be. If not, just return an error and wait for the admin login.
Method 2: ONLY TO GET THE DOMAIN, not the user.
Use the Marketplace License API https://developers.google.com/gsuite/marketplace/v2/reference
You can periodically use the list endpoint and find the user that installs (or removes) your application.
In any case you should store the list of domain super admins to be used when necessary.

Access denied when using Directory.Move() in impersonation with UserLogon with Interactive [duplicate]

I am running a WindowsService on Windows Server 2012 and it needs to impersonate a domain admin user (who is also added to the local administrators group on the machine).
UAC is enabled on the system and Calling LogonUser using the credentials with a LogonType of LOGON32_LOGON_INTERACTIVE, seems to return a restricted token instead of a full token.
This is causing the administrative task i'm trying to do to fail.
What is the right way to call LogonUser in this situation so that a full token is returned instead of an restricted token?
PS: I came across a related question here How can I get elevated permissions (UAC) via impersonation under a non-interactive login?
but it does not show the exact calls that need to be made to get the full token.
You can get an unfiltered token from LogonUser() by using the LOGON32_LOGON_BATCH option instead of the LOGON32_LOGON_INTERACTIVE option.
There is some sample code in this answer which shows the use of LOGON32_LOGON_BATCH and the LogonUser() function to obtain an administrative token.
Addendum:
If you have SeTcbPrivilege, you have another option: you can use LOGON32_LOGON_INTERACTIVE when calling LogonUser() and then use the TokenLinkedToken option in GetTokenInformation() to obtain a handle to the elevated token that is linked to the filtered token.
SeTcbPrivilege is also known as "Act as part of the operating system" and is usually only available when you are running in local system context.
If you do not have SeTcbPrivilege, you can still call GetTokenInformation() to fetch a copy of the linked token, but in this case you get an impersonation token at SecurityIdentification level so it is of no use if you are wanting to create a new process. (Credit to RbMm for pointing this out.)

How to call LogonUser() to get a non-restricted full token inside a Windows Service with UAC enabled?

I am running a WindowsService on Windows Server 2012 and it needs to impersonate a domain admin user (who is also added to the local administrators group on the machine).
UAC is enabled on the system and Calling LogonUser using the credentials with a LogonType of LOGON32_LOGON_INTERACTIVE, seems to return a restricted token instead of a full token.
This is causing the administrative task i'm trying to do to fail.
What is the right way to call LogonUser in this situation so that a full token is returned instead of an restricted token?
PS: I came across a related question here How can I get elevated permissions (UAC) via impersonation under a non-interactive login?
but it does not show the exact calls that need to be made to get the full token.
You can get an unfiltered token from LogonUser() by using the LOGON32_LOGON_BATCH option instead of the LOGON32_LOGON_INTERACTIVE option.
There is some sample code in this answer which shows the use of LOGON32_LOGON_BATCH and the LogonUser() function to obtain an administrative token.
Addendum:
If you have SeTcbPrivilege, you have another option: you can use LOGON32_LOGON_INTERACTIVE when calling LogonUser() and then use the TokenLinkedToken option in GetTokenInformation() to obtain a handle to the elevated token that is linked to the filtered token.
SeTcbPrivilege is also known as "Act as part of the operating system" and is usually only available when you are running in local system context.
If you do not have SeTcbPrivilege, you can still call GetTokenInformation() to fetch a copy of the linked token, but in this case you get an impersonation token at SecurityIdentification level so it is of no use if you are wanting to create a new process. (Credit to RbMm for pointing this out.)

SSO equivalents to Windows AccessCheck call

We have an windows app that runs as an Administrative account but we need to determine the access rights to files and directories of a particular user that is logged in to the app.
One solution we have used is to use the user name only to generate an access mask:
BuildTrusteeWithName(&trustee, username);
GetEffectiveRightsFromAcl(pSecurityInfo->pAcl, &trustee, pAccessMask);
The problem with this is that it takes quite a long time on some customer sites with complex DFS setups. We believe the time is taken in looking up the user's groups etc...
So another solution we have used is to cache the user name and password to 'impersonate' the user, temporarily caching a handle to the 'impersonation' token:
// Here we get the handle to the 'impersonation' token
LogonUser(owner, NULL, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pTempHandle);
DuplicateToken( *pTempHandle, DEFAULT_IMPERSONATION_LEVEL, pOwnerHandleCacheEntry->pHandle );
// This is then called for all files and directories traversed. pOwnerHandle is the handle of the 'impersonation' token obtained above.
// This means the overhead of getting the user's groups etc... is only done once.
AccessCheck(pSd, *pOwnerHandle, MAXIMUM_ALLOWED, &genericMapping, &privilegeSet, &dwPrivSetSize, &fileAccessMask, &accessStatus);
The problem with this is if we wish to introduce Single Sign On, we don't have access to the user's password. This will leave some sites that wish to use SSO with a system that doesn't perform very well as they will need to switch back to first solution (above).
So, my questions are:
1) Is there a way of caching the user information used to build the access rights using just the user name (in order to avoid doing lookups every time) ?
2) Failing question 1 (above), is there an equivalent of our preferred solution within an SSO environment (for example: impersonating a user using a kerberos ticket)?
Roughly speaking, the SSO equivalent of LogonUser is SSPI. SSPI allows a server to authenticate a client without needing the client's password. After successfully authenticating the client, the server will have access to a user token, but as with everything in SSPI it's complicated how to get it. From there, you can call AccessCheck which should be very fast.

How to switch user programmatically in windows

I would like to know if there are any API's available to switch users programmatically in windows.My application when provided with user credentials(account name & password) will try to logout any other user logged on and try to login the present user.
Any help would be greatly appreciated.
The function you are presumably looking for is LogonUser
However, you are probably better off using user impersonation in most cases.
Personally, I suspect you are likely better off user neither method and simply using security context of the running user, providing an privileged function via a windows service you wrote specifically for your application
Why don't you create a service to switch user credentials (by methods mentioned in the other answers), and install and run the service as "Administrator". From the logged in user account, you can invoke this service (Which is already running as admin), and make it switch user accounts without the permissions issue (as the service responsible to switching is already running as admin)

Resources