is it possible to use LogonUser API without password? - c++

I am developing a c++ application and this application runs as a windows service.
I need to impersonate the current user to access the network location and for this I am using Windows API LogonUser and ImpersonateLoggedOnUser.
The problem is that I only have username and domain information but not the password. So is it possible to call the LogonUser without providing the password to get the user handle?

No, that would be a rather obvious security leak.
You may however use a named pipe between a UI process for the current user and your service. Your service can then impersonate the other side of the named pipe. This is secure because you control both ends of the pipe.

Related

Send Notification to specific RDP user from a WTS app that runs as a Windows service

I am trying to send a user a message from a C++ app that runs as a service on a WTS server.
Multiple users are logged in via RDP, so I just want to send User X a notification.
I have done this using WTSSendMessage(). I am just looking for a more modern elegant method.
Any suggestions?
The usual approach is to run a GUI app in each user session, launched during login (it's possible for the service to spawn this but much simpler to use any of the conventional autorun techniques) and have it connect to the service via interprocess communication (named pipe is very common).
The service can impersonate the named pipe client in order to securely determine the associated user (unlike having the client simply report its username through the pipe) and then maintain a table of user IDs to pipe connections which it can use to deliver notifications.

How to launch an elevated process in a logon user session from a local service?

I need to launch an elevated process in an interactive logon user session from my local service. For that I use the code very similar to this one.
But I'm not sure how to specify elevation in the user token returned by WTSQueryUserToken API, and to make it work on Windows XP and up?

LogonUser returns ERROR_NO_LOGON_SERVERS

I have an application which needs to check the Windows session password of the user.
For this, I am using the LogonUser function from Windows API. The user can be connected to a domain.
result = LogonUserW(wUsername, wDomain, wPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pH);
When the user is connected to the domain, the function works well, however, when the user turns off the wifi, or unplug the lan-cable so that he is offline, the function always returns with the error code 1311, which has the meaning "There are currrently no logon servers available to service the logon request".
The LogonUser function has as fourth parameter the type of logon operation to perform. The documentation says that if the value of this parameter is "LOGON32_LOGON_INTERACTIVE", the logon type has the additional expense of caching logon information for disconnected operations, so shouldn't this work in the case the user is in the field?
Thanks in advance for your help.
I ended up using the Security Support Provider Interface (SSPI) as described as an alternative to the LogonUser API in this page : How to validate user credentials on Microsoft operating systems
Using the SSPLogonUser function as provided in the code snippet allowed me to check for the user credentials while connected to the domain, but also when the domain controller wasn't reachable (where in that case, it failed with the LogonUser API).

Using LogonUser() only to Validate Credentials

We are developing an application with an internal user accounts system, but would like to be able to use credentials from Active Directory and/or Windows accounts. To that end we store the User SID in a field in the application's users table. Our login mechanism functions like this:
Prompt user for domain, login, password
Call LogonUser(logon, domain, password, logon_type, logon_provider, &hToken)
If successful, get User SID from hToken
Close hToken
Search our application's database for a user with the given SID; if found, we are considered logged in to that account.
The problem that has come up is this: we have been using LOGON32_LOGON_NETWORK for the logon_type, but we have now run into some security configurations where "Access this computer from the network" is denied, meaning the Network logon type is prohibited.
My question is what logon type should we be using for this situation? Interactive? We are not actually using the Logon token for anything other than extracting the user's SID. Our application has its own internal groups and permissions; we do not use Windows groups or permissions in any way. From the perspective of Windows and the domain controller, all we are doing is logging on and quickly logging off.
Or are we looking at this in a completely wrong way, and we should be using some other login method entirely?
Thanks
I also have been surprised to find out that the LogonUser() with the LOGON32_LOGON_NETWORK type fails when user right "Access this computer from the network" is not granted for Everyone on local computer.
I use the following workaround:
First try LogonUser() with the LOGON32_LOGON_NETWORK type.
If it fails with error ERROR_LOGON_TYPE_NOT_GRANTED, call LogonUser() with the LOGON32_LOGON_NEW_CREDENTIALS type and the LOGON32_PROVIDER_WINNT50 logon provider.
You can communicate with the SSPI services to validate a user's credentials and acquire a token, without requiring special privileges. This requires a lot of obscure code and
See http://support.microsoft.com/kb/180548 for an example; the SSPLogonUser function is where the token is acquired.
The convention is to use LOGON32_LOGON_BATCH, as documented:
This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention. This type is also for higher performance servers that process many plaintext authentication attempts at a time, such as mail or web servers.
(emphasis mine).
The system administrators may still need to reconfigure the server to grant batch logon access to the users in question, but because this does not grant the user access to any Windows functionality (e.g., the ability to use Remote Desktop, to connect to a network share, or to log on interactively if they somehow gain access to the console) this should not be a problem.

How CreateProcessAsUser on Windows Using Delegated Credentials from SSPI?

I work on a Kerberos logon infrastructure (Single Sign-On) with:
A client which is authenticated to the Kerberos Key Distribution
Center.
A principal service server using Kerberos as authentication.
Server Program is coded in C++.
I have no problem to create a context between my principal (client) and my service principal (server).
I also delegated my client credentials to the server, because I need to create a process on the server using client user credentials.
And this is my problem, on the server side, I have a SSPI context and I need to CreateProcessAsUser using a Windows type pHandle.
I do not know how to use my SSPI credentials to create on my server a process as the client user.
I take a look at LsaLogonUser, which seems to do what I want (create a handle from kerberos user credentials) but my problem is the same, I do not know how to use the SSPI Token with this LsaLogonUser.
Thanks in Advance, for your help
Though it is very late but you could obtain a token by doing following:
HANDLE tempHandle;
if (!QuerySecurityContextToken(hctxt, &tempHandle))
{
MyDbg("Could not obtain token for user");
}
I just posted a question regarding something related to what you are doing. I am using a session 0 Windows service to launch an application into session 1. The code I used (and asked about) is included in that post, and works well except that paths normally available to a user in session 1 are not accessible when launced this way. In any case, Even though I have some questions about this code, I hope it can start you on the right path.
Ryyker
I finally found a solution to my problem.
The best way to do it is to:
write delegated credentials in a temporary file.
set KRB5CCNAME environment variable to the path of this file.
It Works ;)