Terminal Services: Get Client Name While Running As Administrator - vb.net

Under normal circumstances, a VB.NET application of mine can check the ClientName environmental variable to get the name of the workstation the user is connecting from.
So when WorkstationX RDPs into ServerA:
ComputerName=ServerA
ClientName=WorkstationX
That works fine.
If I right-click on the application and choose Run As Administrator, the ClientName variable is not set.
Does anyone know of a way of easily getting the workstation name of the client connected to the terminal server, even when the application is launched via "Run As Administrator"?

If you don't want to deal with the P/Invoke business yourself, you can use Cassia, which wraps it for you:
New Cassia.TerminalServicesManager().CurrentSession.ClientName

The terminal services API might be your answer. I use it in a VB.NET app to log off user sessions on a given server, and to retrieve the names of the workstations connected to those sessions. The code I have has a lot of p-invoke stuff and is rather unwieldy, but I can post it if you want.

Related

Check if a process is running against a specified username on Remote computer (Vb .Net)

Good Day All,
We have a component service which runs on remote domain computer. I am very much a newbie for this sort of Vb automation. Although I could not find a code to assist finding if the component service is runnning or not, I did notice that this particular Component Service runs as "dllhost.exe" process against a username which we specify under the Identity tab of Properties.
However, there may be other "dllhost.exe" processes running on same machine and hence I am looking for some sample VB Net code that will retun if my Component Service is Running or Not; by supplying the remote machine name, "dllhost.exe" as the process name and the User Name.
Any suggestions / tips are welcome.

Aministartor Rights for a set of code

Good day.
I am developing a program that will be used in a corporate environment by the end users. The application will automatically fix certain errors as soon as the user selects the application name, chooses the symptom or error message and clicking on the fix button.
The idea behind is to decrease the amount of calls we receive at the IT Service Desk (The company's personal Call Centre for IT Issues) and at the same time assist the end user by resolving the issue within a minute (versus waiting on the phone for up to 15 minutes or more).
I've am not yet allowed to upload an image of the application, but imagine a small'ish windows form with 2 columns; Aplication name and Synptom. The user will choose the application's name, click on the error message and click on the FIX button. This basically automates whatever we has IT Techs would manually.
The problem I'm facing is that some of the code is supposed to be executed with adminsitartor rights, eg. Stop and Start a given service, adding regsitry entries for Local Machine, etc.
Given the fact that none of the users will be allowed to have elevated rights and the fact that they need to use this application as a sort of "self-help" alternative without the need to call the IT Service Desk, is there a way to give a set of code "administrator permissions"? The application should NOT request the user to enter ANY passwords.
Regards,
Willem
No way, AFAIK: the model in common operating systems is process-centric, so that the process is given permissions that are then inherited by its code. You can elevate such privileges at some point, but that will be for the whole future life of the process (or as long as the authentication token for it ceases to be valid).
In windows the right way to do that is to employ a back-end service: at boot, you start the service called IT_Auto_Fixer_Back_End with high permissions (try to avoid Administrator, NetworkService or LocalService could be enough for you). When the app IT_Auto_Fixer_Front_End is started with USER privileges, it operates until it needs something with high privileges. At that point it sends a request to the service, that will do it.
If you choose this way, some important advices:
The IT_Auto_Fixer_Back_End must not become a backdoor! If you use TCP as form of communication with IT_Auto_Fixer_Front_End, make it listen localhost only and use SSL (yes!) to encrypt local traffic
It must not be possible to invoke arbitrary commands using IT_Auto_Fixer_Back_End. You need to enumerate the possible requests that could be made (i.e. a command like stop_mysql_service rather than accepting directly the string net stop mysql - the application logic will translate your string into the real OS command)
Every input from the user could be used to perform command injection. To prevent this, use the Windows API that requires an array for the command - this way if the user adds options to a command (i.e. the name of the service in net stop) they won't be interpreted as another command (common scenario: when accepting the name of the service as a parameter, a malicious user that tries to execute something like net start mysql ; net user /add hacker t00E4sy). Authentication and encryption will not help you against this, you must escape any user input that goes inside the command.
Sanitize your ENVIRONMENT by using the API that executes commands setting the PATH (and other relevant variables), so that the user will not be able to taint the PATH, executing C:\temp\net.exe instead of C:\Windows\System32\Net.exe
IT_Auto_Fixer_Back_End service should be authenticated: it should check every time if the request comes form the user by checking if the Kerberos token is valid (Windows => you get a very nice Kerberos environment for free!). This will prevent someone else to break into the machine, use SSL to connect to the localhost port and elevate privileges through your service
The above (authentication) still stands when something else (i.e. shared memory, windows sockets, a file, etc...) is used as communication channel between IT_Auto_Fixer_Back_End and IT_Auto_Fixer_Front_End
Life gets harder when you want to properly implement something dealing with multiple level of permissions...

Windows Application ignores app.config and uses something to connect to local database

The application sits on a virtual environment and when I remote in and run the application, it connects to the remote database. However, when I remote in with a service account and double click the same .exe, it tries to connect to the local host database and ignores the app.config. The code is the same, only the login name I use is different. The login I use is part of the local admin group. Any ideas?
You haven't indicated whether or not this is the case in your question, but my first suspicion is that you are storing the connection strings in settings, but the connection string has been marked as a user-specific setting.
In the logic of the code it was doing a comparison of the SQL server setting in the config (Settings), which was entered in lower case, against the list of SQL servers (all in upper case). Since it couldn't find any match, the datasource was blank [datasource=;],hence causing the code to look local. My fix was to use String.Compare and ignore the case, which created the match and I was able to connect to the remote SQL server.

Connect different Windows User in SQL Server Management Studio (2005 or later)

Is there a way in SQL Server Management Studio 2005 (or later) to change the Windows Authentication user (as you could in SQL Server 2000 and older)?
This is the general connection properties dialog(note the greyed out UID/PWD when selecting Windows Auth):
FYI - One workaround is to use runas but I'm looking for a solution that will allow me to work with multiple Windows accounts across multiple servers (and across multiple domains).
While there's no way to connect to multiple servers as different users in a single instance of SSMS, what you're looking for is the following RUNAS syntax:
runas /netonly /user:domain\username program.exe
When you use the "/netonly" switch, you can log in using remote credentials on a domain that you're not currently a member of, even if there's no trust set up. It just tells runas that the credentials will be used for accessing remote resources - the application interacts with the local computer as the currently logged-in user, and interacts with remote computers as the user whose credentials you've given.
You'd still have to run multiple instances of SSMS, but at least you could connect as different windows users in each one.
For example: runas /netonly /user:domain\username ssms.exe
Hold shift and right click on SQL Server Mangement studion icon. You can Run as other windows account user.
One other way that I discovered is to go to "Start" > "Control Panel" > "Stored Usernames and passwords" (Administrative Tools > Credential Manager in Windows 7) and add the domain account that you would use with the "runas" command.
Then, in SQL Management Studio 2005, just select the "Windows Authentication" and input the server you wanna connect to (even though the user that you can see greyed out is still the local user)... and it works!
Don't ask me why ! :)
Edit:
Make sure to include ":1433" after the server name in Credential Manager or it may not connect due to not trusting the domain.
None of these answers did what I needed:
Login to a remote server using a different domain account than I was logged into on my local machine, and it's a client's domain across a vpn. I don't want to be on their domain!
Instead, on the connect to server dialog, select "Windows Authentication", click the Options button, and then on the Additional Connection Parameters tab, enter
user id=domain\user;password=password
SSMS won't remember, but it will connect with that account.
The runas /netonly /user:domain\username program.exe command only worked for me on Windows 10
saving it as a batch file
running it as an administrator,
when running the command batch as regular user I got the wrong password issue mentioned by some users on previous comments.
For Windows 10:
Go to the Sql Management Studio Icon, or Short Cut in the menu:
Right Click > Select Open File Location
Hold Shift and right Click the shortcut, or ssms.exe file that is in the folder. Holding shift will give you an extra option "Run as different user":
This will pop up a login box and you can type the credentials you would like your session to run under.
A bit of powershell magic will do the trick:
cmdkey /add:"SERVER:1433" /user:"DOMAIN\USERNAME" /pass:"PASSWORD"
Then just select windows authentication
There are many places where someone might want to deploy this kind of scenario, but due to the way integrated authentication works, it is not possible.
As gbn mentioned, integrated authentication uses a special token that corresponds to your Windows identity. There are coding practices called "impersonation" (probably used by the Run As... command) that allow you to effectively perform an activity as another Windows user, but there is not really a way to arbitrarily act as a different user (à la Linux) in Windows applications aside from that.
If you really need to administer multiple servers across several domains, you might consider one of the following:
Set up Domain Trust between your domains so that your account can access computers in the trusting domain
Configure a SQL user (using mixed authentication) across all the servers you need to administer so that you can log in that way; obviously, this might introduce some security issues and create a maintenance nightmare if you have to change all the passwords at some point.
Hopefully this helps!
Did anybody tried "plain" runas without parameters? Those /netonly /savcecred all of them sound ambiguous and to me utter nonsense.
C:\Windows\System32\runas.exe /user:DOMAINX\OtherUser02 "C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE\ssms.exe"
This works just fine. No matter what, runas WILL ask you for the user password. Just type it and be security audit compliant.
The only way to achieve what you want is opening several instances of SSMS by right clicking on shortcut and using the 'Run-as' feature.

Logoff script to change user

Using Windows 2003, I'm look for a way to create a "logoff script" that will continue with the current logoff then immediately login another user. So, "UserA" logs off. Script fires to login "UserB".
This is part of an application upgrade for a computer where we have written the 'shell'; similar to a kiosk application. For the upgrade we need to logon as 'Adminstrator' then, when the upgrade has completed, logoff 'Administrator' and logon as 'sample_user'. We would like to accomplish this WITHOUT rebooting.
Note, I do not want a script that will initiate the logoff (i.e. "shutdown"). I'm looking for a script that will run upon the user logging off (set via Group Policies). As above, the script should log a different user on.
Thanks.
Don't think it's possible in the stated way (script at logoff).
You'd have to set the machine to logon automatically as a specified account and then log off (having it log on automatically for you) and then you'd have to disable that feature again afterwards, by placing a temporary logon script... generally sounds messy.
The actual setting can be made using tools like Microsofts Shared Computer Toolkit or similar (not so sure how the "normal" registry auto-login behaves at manual logout but I've had an XP kiosk that would automatically log on instantly, even if you logged out manually - you had to override it using some key like shift+logoff to be able to manually specify the login again, so somehow it can be made).
The "easiest" way might be to replace msgina.dll with someone of your own making...
But why are you doing this? Just use runas and start whatever you need to do as that other user without logging off the console user - it's a multi-user system afterall? The desktop is just fluff ^^
(This will anyhow require that the user credentials are available to your script, which kind of makes it redundant as you compromise the security of that account - defying the purpose of having that second account in the first place, for whatever purpose it exists?)
I would try setting the registry to autologon with the user you want, and then simply logging off the admin user. That should log your kiosk-user right back on.
Not sure how to login another user once the current user logs off (not sure if windows would let you...)
But you can use shutdown to logoff:
shutdown /?
Here's some ideas that probaly fall into the "cheap hack" category:
How about logging in at UserB in the first place, and then using runas /user:userA <cmd> to run the first part of the install process?
If that's unacceptable, I know there's a way to make Windows workstations (those that aren't part of a Domain) automatically log in into a certain user account after a restart. Perhaps if you looked into which Registry changes happen, and duplicated them, a reboot would automatically log in that user. (Of course, as a final stage, after userB logs in, you would have to revert those changes :-)
It also occurs to me to wonder if perhaps there's a way for a service to force an open "login screen" to log in as a certain user. Maybe using some method like the way the Remote Desktop does it remotely... If that's possible, then you could create a service that you install before logoff of userA, that would trigger the login of userB.
You can script it with VNC (there are many free versions, take your pick). Set up a VNC server process on the machine to listen on localhost. When the user logs off, your logoff script will connect to the machine using VNC and send the keystrokes necessary to log on the next user. VNC uses the RFB (remote framebuffer) protocol; there are libraries for most popular languages, so you should be able to get something working quickly. Or there are related tools that might help.
If you were to run something like this as a normal script in a given language, it would most likely not work as when you log out of your account, all processes should be killed along with your running script.
You might be able to create some sort of 'service' that would run on a service account (i.e. always active) that would automatically do this user switching for you.
My bets are on Windows Powershell, although I'm not entirely sure what functionality it has as far as actually creating a service.
A quick search brings up the following (The second link is to a forum but it mentions running Powershell as a service and sending that service a parameter which would be the path to your user switching script)
How to Create a Windows Service using Powershel
Powershell Script as a Windows Service
I don't have a Windows 2003 server or a system with a "Group Policies" setup to test my hunch but you could take a look at SU ("switch user") for Windows. Originally part of the Resource Toolkit this has been extended to a new SUperior SU. Do post the results/script if this works.
You could approach this from the perspective of building a remote control utility (like VNC, etc). The big thing here is that if you want access to the Logon screen (i.e. the CTRL + ALT + DEL / username/password) part, the only kicker is that a Windows Service is the only component that can access this, so you'd have to create one.
The only problem I see with this technique as a whole is that even if you spent a great deal of effort getting it to work (and it would be a pretty big effort), the chances of this working successfully with the whole thing originating from a logoff script (i.e. when stuff is shutting down) are low even due to the number of things that can go wrong when logging back on as Administrator.
Just remember that for anything you need to run as an Administrator, there are easier ways in Windows to make that happen (such as Run As, changing the user permissions on the items that need to update, etc).