bazaarlabs/dante — pull request #1 by mckern (2012-06-21 03:08:58+00:00)
Title: Fix for logging, privilege reassignment, and a cleaner shutdown message

I had to use these particular features of Dante, and I noticed that user and group reassignment weren't functioning correctly. While fixing them I also discovered that logfile redirection wasn't working right either (logs were being buffered and flushed on close, instead of being synced to disk in real time). I rewrote both pieces of functionality.

Privilege dropping was rewritten following the guidelines laid out by [Joe Damato](http://timetobleed.com/5-things-you-dont-know-about-user-ids-that-will-destroy-you/), and work as expected (with the added bonus that user and group will accept UID or GID numbers in addition to user names now). The original behavior was verified using this script:

```ruby
#!/usr/bin/env ruby

require 'rubygems'
require 'dante'

Dante.run('dante_test',
:log_path => './test.log',
:pid_path => './test.pid'
) do |opts|

puts "uid #{Process.uid}, euid #{Process.euid}, gid #{Process.gid}"

end
```

With Dante 0.1.3, that results in this outcome:

redrobot tmp # ./dante_test_privs.rb
Starting dante_test service...
uid 0, euid 0, gid 0

redrobot tmp # ./dante_test_privs.rb --user ryan
/usr/lib64/ruby/gems/1.9.1/gems/dante-0.1.3/lib/dante/runner.rb:56:in `euid=': can't convert String into Integer (TypeError)
from /usr/lib64/ruby/gems/1.9.1/gems/dante-0.1.3/lib/dante/runner.rb:56:in `execute'
from /usr/lib64/ruby/gems/1.9.1/gems/dante-0.1.3/lib/dante.rb:24:in `run'
from ./dante_test_privs.rb:6:in `

'

After this patch, behavior is as expected; UID/GID switching requires that the daemon be started as root, the same as any other UNIX/Linux daemon and GID changing has been moved ahead of UID changing, because if the UID is dropped than the ability the change GID is effectively limited. The results of that script are now:

redrobot tmp # ./dante_test_privs.rb
Starting dante_test service...
uid 0, euid 0, gid 0

redrobot tmp # ./dante_test_privs.rb --user ryan
Starting dante_test service...
uid 500, euid 500, gid 0

redrobot tmp # ./dante_test_privs.rb --group ryan
Starting dante_test service...
uid 0, euid 0, gid 500

Log file redirection has been slightly reworked to be a little bit more concise and to flush to disk in realtime and the `interrupt` method now catches the interrupt flag and processes it cleanly, without the accompanying stack trace.