diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-12-07T00·16+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-12-07T00·16+0000 |
commit | 6a8e60913ac470c704510a733d40d3fab3ecb00d (patch) | |
tree | 5e089d76841c314608dbcb85c5f6a6f8ae86a1ea /src/libutil/util.cc | |
parent | 79875c5e42eca2e2d05f439da4b0da778385678a (diff) |
* Move killUser() to libutil so that the setuid helper can use it.
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r-- | src/libutil/util.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index ae5fe821e78b..5907adc80718 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -707,6 +707,53 @@ void Pid::setSeparatePG(bool separatePG) } +void killUser(uid_t uid) +{ + debug(format("killing all processes running under uid `%1%'") % uid); + + assert(uid != 0); /* just to be safe... */ + + /* The system call kill(-1, sig) sends the signal `sig' to all + users to which the current process can send signals. So we + fork a process, switch to uid, and send a mass kill. */ + + Pid pid; + pid = fork(); + switch (pid) { + + case -1: + throw SysError("unable to fork"); + + case 0: + try { /* child */ + + if (setuid(uid) == -1) abort(); + + while (true) { + if (kill(-1, SIGKILL) == 0) break; + if (errno == ESRCH) break; /* no more processes */ + if (errno != EINTR) + throw SysError(format("cannot kill processes for uid `%1%'") % uid); + } + + } catch (std::exception & e) { + std::cerr << format("killing processes beloging to uid `%1%': %1%\n") + % uid % e.what(); + quickExit(1); + } + quickExit(0); + } + + /* parent */ + if (pid.wait(true) != 0) + throw Error(format("cannot kill processes for uid `%1%'") % uid); + + /* !!! We should really do some check to make sure that there are + no processes left running under `uid', but there is no portable + way to do so (I think). The most reliable way may be `ps -eo + uid | grep -q $uid'. */ +} + ////////////////////////////////////////////////////////////////////// |