6

Instead, it starts a new shell process with the new user ID. The original shell is blocked until the new shell completes and su exits. Why does it work like this?

Bruce
  • 143
  • 3
    If it would have worked as you are saying, then that would have created havoc. It's good, that a new process is forked. – mtk Dec 26 '12 at 17:52

2 Answers2

8

Simple: because it can't. There is no system call to change the uid of another process. If you don't want to leave the parent shell around waiting for su to exit, then prefix it with the exec builtin command, which causes the shell to directly exec without forking first. Of course if you get the password wrong, there will be no shell to return to, so your session will terminate.

psusi
  • 17,303
3

As has been pointed out, there is no way to do it. Of course, if there is a will, there is a way: that there is no such syscall is no reason why it couldn't be done. That said, as mtk touched on in a comment, imagine the havoc it could create having a syscall to change the security context of an unrelated process. If nothing else, I see a race condition erupting in three... two... one... (and let's not even get started on what changing the security context of init or getty could do.)

One other reason is that su not only invokes a new shell. It also has the ability to control which shell is launched (using -s or --shell), and control it by passing parameters via (in GNU) the -/-l/--login and -c (--command) parameters. The parameters passed to su can also have an effect on the new shell's environment. So even if you could just change the security context of the parent process, you would not necessarily want to do so.

user
  • 28,901