about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--bin/mongrel_rails33
-rw-r--r--lib/mongrel.rb21
2 files changed, 48 insertions, 6 deletions
diff --git a/bin/mongrel_rails b/bin/mongrel_rails
index 36392af..14858bf 100644
--- a/bin/mongrel_rails
+++ b/bin/mongrel_rails
@@ -3,6 +3,7 @@ require 'rubygems'
 require 'yaml'
 require 'mongrel'
 require 'mongrel/rails'
+require 'etc'
 
 
 class Version < GemPlugin::Plugin "/commands"
@@ -34,7 +35,9 @@ class Start < GemPlugin::Plugin "/commands"
       ['-B', '--debug', "Enable debugging mode", :@debug, false],
       ['-C', '--config PATH', "Use a config file", :@config_file, nil],
       ['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
-      ['-G', '--generate CONFIG', "Generate a config file for -C", :@generate, nil]
+      ['-G', '--generate CONFIG', "Generate a config file for -C", :@generate, nil],
+      ['-u', '--user USER', "User to run as", :@user, nil],
+      ['-g', '--group GROUP', "Group to run as", :@group, nil]
     ]
   end
 
@@ -51,9 +54,32 @@ class Start < GemPlugin::Plugin "/commands"
     valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
     valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
     valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
+    valid_user? @user if @user
+    valid_group? @group if @group
+    
     return @valid
   end
-
+  
+  def valid_user?(user)
+    valid?(Process.uid == 0, "You must be root to change the user.")
+    begin
+      Etc.getpwnam(user)
+    rescue
+      failure "User does not exist: #{user}"
+      @valid = false
+    end
+  end
+  
+  def valid_group?(group)
+    valid?(Process.uid == 0, "You must be root to change the group.")
+    begin
+      Etc.getgrnam(group)
+    rescue
+      failure "Group does not exist: #{group}"
+      @valid = false
+    end
+  end
+  
   def run
 
     # command line setting override config file settings
@@ -61,7 +87,8 @@ class Start < GemPlugin::Plugin "/commands"
       :log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
       :docroot => @docroot, :mime_map => @mime_map, :daemon => @daemon,
       :debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
-      :num_processors => @num_procs, :timeout => @timeout
+      :num_processors => @num_procs, :timeout => @timeout,
+      :user => @user, :group => @group
     }
 
     if @generate
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 3cc6beb..9e525a2 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -9,7 +9,8 @@ require 'mongrel/command'
 require 'mongrel/tcphack'
 require 'yaml'
 require 'time'
-require 'rubygems'
+require 'rubygems'
+require 'etc'
 
 
 begin
@@ -692,12 +693,26 @@ module Mongrel
       @listeners = {}
       @defaults = defaults
       @needs_restart = false
-
+      
+      change_privilege(@defaults[:user], @defaults[:group])
+      
       if blk
         cloaker(&blk).bind(self).call
       end
     end
-
+    
+    # Change privilege of the process to specified user and group.
+    def change_privilege(user, group)
+      if user
+        log "Changing user to #{user}."
+        Process::UID.change_privilege(Etc.getpwnam(user).uid)
+      end
+      if group
+        log "Changing group to #{group}."
+        Process::GID.change_privilege(Etc.getgrnam(group).gid)
+      end
+    end
+    
     # generates a class for cloaking the current self and making the DSL nicer
     def cloaking_class
       class << self