On Mon, Sep 01, 2003 at 11:31:51PM +0000, Andreas Schwarz wrote: > > The way to do it safely is for the program to bind to the port > > early and then set its effective user id to something else before > > doing anything else. > > Thanks, "Process.euid = 1000" works. What is the difference between uid > and euid? The euid is the one that matters for permission checks. The real uid is primarily informative, but it's also a constraint on the legal values of the euid. When you start up a new process on UNIX, that process inherits both uids from its parent. The effective uid is normally the same as the real uid; however, if a process exec()s a program which is owned by a different uid and has the setuid bit set, then the effective uid is set to match the owner of the executable file instead. You can actually change both values. If either uid is root, then you can set either uid to anything you want. If neither uid is root, then the only legal values for either uid are the current values of those uids. However, on modern POSIX-compliant systems, there's also a third uid, which is not directly accessible to the process, but is available as a legal value of the other uids. This is called the "saved" uid. It allows a program to start up as root, set both the real and effective uids to a non-root value, and then later set either one back to root, because the OS remembers that the process used to have a root uid. So for example, if I'm logged in as 'mreed' and I execute a program owned by 'aschwarz' that's setuid, then the new process will have a real uid of 'mreed' and an effective uid of 'aschwarz'. All file access checks, etc., made by that program will check against the permissions applicable to 'aschwarz', not 'mreed'. The program can then set its real uid to 'aschwarz' or its effective uid to 'mreed', or both simultaneously (via a system call called setreuid(2) that lets you set both values at once). Once the two values match, however, the program can no longer change either one. > I'm also interested in examples of some "real world" ruby servers, > because I would like to know how to limit the number of threads per > client, the number of total threads and things like that. I don't have any TCP servers written in Ruby, I'm afraid. But it seems like you can have a single process do the accept(), then check the configuration parameters and only start up a new Thread if within the limits. Serializing the accept()s within a single thread might be a performance bottleneck if you have a large number of nearly simultaneous requests, but if you're worried about DoS attacks, that's a good thing.