That's not what the su command does, so the question as presented
isn't meaningful. su exec's a new process. By default that's a shell
process, and it's a child of su, which is a child of the shell in
which the user ran su, so it inherits (most) of that shell's environment.
It only inherits the parent shell's command history if the shell makes
provisions for that - typically by keeping the command history in a
file associated with the tty name, so the new child shell can find it.
Taking "Windows" above to be "cmd.exe console windows", that second
sentence is true, though it's a property of cmd.exe and has nothing to
do with the window itself (so introducing the term isn't particularly
useful). But certainly many processes other than "the window manager"
(whatever that's supposed to refer to) are written to deal with
multiple tokens, so the second sentence is inaccurate and misleading,
if not outright wrong.
It's just a matter of parameters to CreateProcessAsUser: set
lpEnvironment to null to inherit the caller's environment, and set
dwCreationFlags to 0 to inherit the caller's console. Use LogonUser
first to get the primary token based on username and password, and
then CreateProcessAsUser to create a new cmd.exe in the same console
window.
However, neither the MKS su nor any other such program would change
the token of the current cmd.exe. They all start a new shell process.
The environment can, of course, be inherited by setting the
lpEnvironment parameter to null (though Unix su typically builds a new
environment, removing "unsafe" environment settings such as
dynamic-linker options). Since cmd.exe keeps its history in process
private memory, though, there's no way for the child cmd.exe to
inherit that.
Yes, if you write a custom shell that uses a console-style window, you
could write it to include access to multiple user contexts. But the
original question asked about instances of cmd, not other shells.
There's nothing special about cmd.exe in this regard. It works just as
any of the shells shipped with MKS do.
Nonono, if that word hadn't been the first word of a sentence, it would
have been lowercase. Not "Windows operating system," but "instance of a
window on the screen."
Nothing prevents a process with a visible window from switching
tokens, if it's written to do so. cmd.exe isn't, but that has nothing
to do with the fact that it owns a window on the desktop.
Let me rephrase. "The CMD shell doesn't deal with user contexts, so the
window in which it runs is always assumed to be of a single context."
Again, nothing to do with windows. It's a question of the security
token under which each thread in the process is running. cmd.exe
always uses the token with which it was created, but that's only
because it wasn't written to do something different.
The original poster wanted to know if you could force an instance of CMD
to jump to a different user context, or a different instance of CMD
under a different user context, in the same window. You can't.
I'm not so sure about that, either. I haven't tried it, but with
sufficient permissions I believe this ought to work:
- Get process ID of a cmd.exe process (trivial if the current process
is a child of that cmd.exe process)
- Create primary token with LogonUser
- Use DuplicateHandle to dup the token into the cmd.exe process
- Use any suitable code injection technique to get cmd.exe to call
ImpersonateLoggedOnUser(new-token) in its main thread
For the injection, I'd probably use WriteProcessMemory to build a
function A in cmd.exe that located the return address on the top of
the main thread's stack, saved it, and changed it to point to a new
block of code B (standard return-smashing technique). Block B would
make the ImpersonateLoggedOnUser call and then jump to the saved old
return address, letting the main thread continue with its business.
Then invoke the function A using CreateRemoteThread.
Of course, I haven't looked at how cmd.exe works. It may not create
new processes from its main thread, or do something else that'd
prevent that token from being inherited by new processes.
Hmm... come to think of it, CreateProcess uses the process token, not
the calling thread's impersonation token, doesn't it. So more radical
violence to the running cmd.exe process would likely be necessary, or
processes started by cmd.exe wouldn't run in the new security context.
(Builtin commands and operations, such as opening files for
redirection, should.) One possibility would be to suspend the main
thread and have the injected code take over all cmd.exe processing,
but substituting CreateProcessAsUser for CreateProcess; this would
require knowing enough about cmd.exe's internals that it's not really
worth doing (simpler to create a patched cmd.exe).
At any rate, though, the point is it's not safe to simply declare that
it's impossible to change the security context of a process.