I'm calling plink from C# code which is running as a certain Windows user. I call plink like
plink.exe user#hostname -pw password commands
Usually the plink process ends immediately after the commands have been run, but when the user which the code runs under is not logged into Windows, the plink process doesn't end.
As all these zombie processes build up there comes a point when new processes can't be created anymore...
Any idea why this would be happening?
This could be because the first time you connect to a new server PuTTY registers a host key in the registry, under the currently logged in user (under HKEY_CURRENT_USER). With that user not being logged in, that portion of the registry may be inaccessible.
Try moving the key to HKEY_LOCAL_SYSTEM. That process is described in detail here:
http://xxlinxx.wordpress.com/2009/03/23/set-up-an-ssh-tunnel-as-a-windows-service-using-putty-plink/
There is a final note on that page that could prove to be important too depending on your specific use case:
"Also, if the Windows SYSTEM user cannot see the host key for SSH connection, the tunnel cannot be established."
PS: There is another page here here that talks about moving the cert to HKEY_USERS.DEFAULT
Related
I need your help again :)
What I want to do:
I have a c# program which runs with normal user permissions - those can't be raised - and I want to change the system date (not time) from that program.
[EDIT] To be a bit more specific: I do have administrator credentials which could be embedded to the program (yikes, I know), but I want to avoid an UAC prompt.
When I launch cmd from outside Visual Studio and try to change the date, it fails with "missing client permission" (roughly translated from German). When I launch cmd as administrator, confirm the UAC prompt the same command succeeds.
I am writing from home, so I cant provide running code at the moment. But all my tries did compile and run without error but the date wasn't changed.
What I've tried:
Created a Process instance, applied admin credentials to ProcessStartInfo, set the FileName to c:\windows\system32\cmd.exe and the argument to /C date {thedate}. I redirected StandardOutput and StandardError and after execution StandardError contains the same message as stated above: "missing client permission"
I've modified this example MSDN: WindowsIdentity.Impersonate using PInvoke with AdvAPI32.LogonUser to raise permissions and Kernel32.SetSystemTime to change the system time. AdvAPI32.LogonUser succeeds and WindowsIdentity.GetCurrent().Name returns the admin name, but calling Kernel32.SetSystemTime fails with "missing client permission".
I've tried opening the current process AdvApi32.OpenCurrentProcess and adjusting the permissions using AdvApi32.AdjustTokenPrivileges following this example StackOverflow: Change system time programmaticaly using datetimepeaker and the code runs totally fine but Kernel32.SetSystemTime fails...
[EDIT] Solution:
I ended up writing a small program with an embedded app.manifest that requests administrator privilegs. This app is called from the main program so this can still be run by a normal user.
It is not possible to change the privileges of the process, once it's started. The original process has to start another process with elevated privileges. This second process can actually be the same .exe file, but with a command parameter that tells the process to do some small stuff and exit immediately.
To start a process with elevated privileges use Process.Start, but with .Verb = "runas", as described in another question. This will of course cause UAC prompt to pop up, if it's enabled on the machine. At least one UAC prompt has to be shown, because UAC prompt is the whole point if this defense mechanism.
If you want to reduce many UAC prompts to just one then you can set the original app to be started as administrator (UAC prompt shows when original process starts) and have just one process. Or have some interprocess communication between original process and elevated process, so that elevated process is started only once and made to finish when original process ends. In the second case UAC prompt shows the first time it's needed.
Can I ask why you are needing to change the system time from an unprivileged application?
If it is to influence other applications then you will need admin privilege since date time is such a vital system function to many other applications. However if you are just needing to adjust the date in your application only then I would suggest creating your own date/time provider that can return the date offset to the date that you desire in your application.
For example.
public DateTime GetDateWithOffset(int daysToOffset)
{
return DateTime.UtcNow.AddDays(daysToOffset);
}
I work with emergency services and they have an application that uses map files to let them know where they need to go and it uses GPS to let them know where they are. We have to update the map files as things change and before I started here they were being done through VB scripts which started to fail. I decided to code my own app in C# to do this which works fine.
I created a package in SCCM 2012 that caches all of the files locally and then it compares the files in the cache to what is on the machine and then replaces any older files. This all works fine but the application they use called MobileCAD locks the files so I have to kill this process and then do the file copy and start the application again. We never know when an emergency happens so this update may start when they are on the road so it is important that it starts the application again as soon as possible. If it does not start the application then the emergency services people may try to do so manually but if core files are being updated then it may not start or cause issues.
I coded my application which uses an app manifest to force it to run as an administrator for the file copy. This application is run through SCCM which uses the local 'System' account to do all of the work and killing MobileCAD and copying files which works great. What I originally found was that it does start MobileCAD but it does so under the System account and the process would be there but it was not visible. I think this is the same problem they were originally having so the emergency services people would need to reboot the computer and wait for it to log back in and then start the wireless service so they could get back into MobileCAD.
To address this issue I did research and found that I could use the ProcessStartInfo in .NET and force it to use another account. As we use an automatic logon for these machines the users name, password, and domain are all in the registry so it was easy to pull it out and inject it into the code. Awesome, looks like it is easy enough so I code it up and sure enough it works perfectly when run under my admin account. In my basic testing everything worked perfectly until I try the same in SCCM, now it fails with the following error message.
System.ComponentModel.Win32Exception (0x80004005): Access is denied
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at UpdateFDM.Program.StartProcess(String processName)
I am sorry for all of the words but I believe it helps if you have a good understanding of the issue and what I am trying to do. I have also hard coded the user information into the code instead of pulling it from the registry but I get the same error. Again, this works fine under my admin account but fails when it is pushed through SCCM and it is only launching MobileCAD that fails.
This is the code I am using for launching MobleCAD, do you see where my issue may lie? I know SCCM confuses it but SCCM basically runs things just as you would from the command line but it uses the local System account.
Thanks for any help.
// Declares the new start instance
ProcessStartInfo process = new ProcessStartInfo();
// Gets the process to start
process.FileName = processName;
// Maximizes the process windows at start-up
process.WindowStyle = ProcessWindowStyle.Maximized;
// Gets the user name from the autologon information
process.UserName = GetDefaultUserInfo("DefaultUserName");
// Gets the domain for the user
process.Domain = GetDefaultUserInfo("DefaultDomainName");
// Holds the password for the default user
SecureString password = new SecureString();
// Gets the raw password from the registry
string rawPassword = GetDefaultUserInfo("DefaultPassword");
// Copies the password in a secure string
foreach (char ch in rawPassword)
{
password.AppendChar(ch);
}
// Sets the password
process.Password = password;
// Needed to launch the app as the logged on user
process.LoadUserProfile = true;
process.UseShellExecute = false;
// Starts the process
Process.Start(process);
// Process started, return true
return true;
I know (and it works) that in C#, this property tells me if the current session is a RDP one:
System.Windows.Forms.SystemInformation.TerminalServerSession
Now, I have a service that receives logon/logoff and lock/unlock events, and I need a way to tell this service if the session being started is rdp or local.
Problem: the service runs as SYSTEM user, and the property above always returns false (I think because SYSTEM is always considered a local connected user)
I've tried to search in the register for the Volatile Environment subkey to check if there is the subkey that identify the RDP Session Name: this works in lock/unlock handler, but in the logon handler the subkey doesn't exists yet (subkey is created after login completes).
Any idea about how to work around this problem?
While a wait for the key creation for a limited amount of time works, I would like a less "kludgy" way to do it.
You can detect whether a session is a local or remote session by calling WTSQuerySessionInformation with the WTSInfoClass parameter set to WTSClientProtocolType. If you'd prefer to avoid the P/Invokes, you can use the Cassia library: new TerminalServicesManager().GetLocalServer().GetSession(sessionId).ClientProtocolType.
Caveats: This won't help you when processing session logoff messages because you will not (reliably) be able to fetch information about the session, since it's in the process of being destroyed (but that seems relatively easy to work around). Also, the ClientProtocolType Cassia property mentioned above has not yet been released, but you can grab a trunk build from the build server by logging in as a guest and using the artifacts link.
I am trying to achive a situation:
I am logged as a user on my account.
I've created a two more accounts which I will try to log on in the
"background"
And now I want to execute my code to log on different user in the background,
so that if i can click ctrl+alt+del and go to the switch user screen
i can see that another account was logged on the system.
During investigation I've read that this was possbile with some undocumented winapi methods before Microsoft implemented Fast User Switch(FUS) which replaced GINA.
I don't want to Impersonate code as user. I want to start up the whole windows session for a user from code.
I've tried to do sth with CreateProcessWithLogonW() but this was unsuccessful.
Big virtual beer for anybody who can give me a hand with this! :)
Okay had to do a bit of digging to figure this out my self.
Essentially you would need to run a command in command prompt.
This should load explorer.exe as a second user.
runas /user:*computer name\*account name explorer.exe
Follow this to get an idea on running a command line command via c#:
How To: Execute command line in C#, get STD OUT results
Other sources:
http://www.computerhope.com/runas.htm
http://lifehacker.com/290435/switch-user-accounts-from-the-command-prompt
I have got a project that can copy files to another client's desktops in my domain.There is 300+ client machine.But there is a problem.When i run this project in a non admin user account in my domain.It cant copy files getting error about Access Denied , user restrictions.I wanna do this program like this , in non admin user account when user start to copy files ;
first my program will get admin access by loggin in my admin user accoun to domain than will copy files.Than logout.How can i do this ? I wanna do this with C#.
I had a similar problem: Production needed to run one of my programs that processes files on a location on the network where they don't have any access.
I ended up using Impersonation, which allowed me to run the file processing thread under a set of credentials set at runtime by my program.
In AD I created a special user account with all required permissions for exclusive use by this program.
I know it’s not at all secure, but it works and the odds that it would even occur to someone to hack my program to get these credentials is remote.
Anyway, look into Impersonation I found these resources helpful:
Safely Impersonating Another User
Brian Low's ImpersonationHelper class
-Jay
You can switch privileges when starting the program from itself or from another program. You can do this with two programs, one that runs as the user account and then launches your privileged application. (or launch itself with a different command line to indicate the different run-mode.)
To launch a program in C# as a different user, do this,
// Create a secure version of the password
SecureString pass = new SecureString();
foreach ( char c in _pass.Text )
{
pass.AppendChar( c );
}
Process process = Process.Start( "PrivilegedProgram.exe", _arguments, _user.Text, pass, _domain.Text );
you need to change the thread to the context of an admin user. How you do that in a secure way is the challenge. This sounds like a quick utility program where the security may not be a big deal, however. Just change the admin's password once the utility has been run.