Running daemons as a different user is now possible.

master
Luka Vandervelden 2019-06-09 17:14:18 +02:00
parent 61c9f33f89
commit 8a6829d803
3 changed files with 70 additions and 2 deletions

57
src/libc.cr Normal file
View File

@ -0,0 +1,57 @@
lib LibC
struct Passwd
pw_name : Char*
pw_passwd : Char*
pw_uid : UInt
pw_gid : UInt
pw_gecos : Char*
pw_dir : UInt
pw_shell : Char*
end
fun setuid(Int32) : Int32
fun setgid(Int32) : Int32
fun getpwnam(Char*) : Passwd*
end
module System
def self.become_user(user_name : String)
pointer = LibC.getpwnam user_name.to_unsafe
if pointer.null?
return nil
end
passwd = pointer.value
# FIXME: Probably should get some errno magic right now.
if 0 != LibC.setuid passwd.pw_uid
raise Exception.new "setuid failed"
end
if 0 != LibC.setgid passwd.pw_gid
raise Exception.new "setuid failed"
end
passwd
end
end
#def get_uid_gid(user_name : String)
# pointer = LibC.getpwnam user_name.to_unsafe
#
# if pointer.null?
# return nil
# end
#
# passwd = pointer.value
#
# {passwd.pw_uid, passwd.pw_gid}
#end
#uid, gid = get_uid_gid("http").not_nil!
#LibC.setuid uid
#LibC.setgid gid
#puts Process.run "whoami", output: Process::Redirect::Inherit

View File

@ -1,6 +1,8 @@
require "yaml"
require "colorize"
require "./libc.cr"
def split_command(string)
args = string.split /\ (?=([^\"]*\"[^\"]*\")*[^\"]*$)/
@ -138,8 +140,16 @@ class Service
puts " - #{check.name}"
# FIXME: Output? Only in debug mode?
child = Process.run "sh", ["-c", evaluate check.command], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit
child = Process.fork do
@reference.user.try do |user|
unless System.become_user user
STDERR << "service: child could not setuid() to user '#{user}'.\n"
exit 1
end
end
Process.exec "sh", ["-c", evaluate check.command], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit
end.wait
if child.exit_status != 0
raise Service::Exception.new "Child process exited with status “#{child.exit_status}”."

View File

@ -31,6 +31,7 @@ class ServiceDefinition
key: "stop-command"
},
directory: String?, # Place to chdir to before running @command.
user: String?, # User that should run the service.
environment: {
type: Environment,
default: Environment.root