WIP for on-the-fly users.
This commit is contained in:
parent
ab9a76326e
commit
c8c0be9804
@ -5,3 +5,7 @@ ports: http=80, https=443
|
||||
reload-command: kill -HUP ${SERVICE_PID}
|
||||
|
||||
%configuration nginx.conf
|
||||
|
||||
# They’re defined in the template, be careful to match.
|
||||
%file access.log
|
||||
%file error.log
|
||||
|
@ -14,5 +14,8 @@ dependencies:
|
||||
git: https://git.karchnu.fr/WeirdOS/recipes-parser
|
||||
crinja:
|
||||
github: straight-shoota/crinja
|
||||
passwd:
|
||||
git: https://git.karchnu.fr/WeirdOS/passwd.cr
|
||||
branch: master
|
||||
|
||||
license: MIT
|
||||
|
@ -1,5 +1,7 @@
|
||||
require "crinja"
|
||||
|
||||
require "passwd"
|
||||
|
||||
require "./service/service.cr"
|
||||
require "./config.cr"
|
||||
|
||||
@ -8,7 +10,7 @@ def sanitize_path(path)
|
||||
end
|
||||
|
||||
class Service
|
||||
alias CrinjaHash = Hash(String, Hash(String, Int32) | String | Crinja::Callable::Instance | Nil)
|
||||
alias CrinjaHash = Hash(String, Hash(String, Int32) | String | Crinja::Callable::Instance | Int32 | Nil)
|
||||
def to_genconfig
|
||||
CrinjaHash.new.tap do |entry|
|
||||
entry["name"] = name
|
||||
@ -18,6 +20,13 @@ class Service
|
||||
entry["domain"] = domain
|
||||
entry["ports"] = ports
|
||||
|
||||
user = Passwd.new("/etc/passwd", "/etc/group")
|
||||
.try &.get_user(user_name).not_nil!
|
||||
|
||||
entry["uid"] = user.uid
|
||||
entry["gid"] = user.gid
|
||||
entry["user"] = user.login
|
||||
|
||||
entry["consumers"] = Crinja.function do
|
||||
token = arguments.varargs[0].to_s
|
||||
|
||||
|
@ -25,13 +25,15 @@ module System
|
||||
|
||||
passwd = pointer.value
|
||||
|
||||
r = LibC.setgid passwd.pw_gid
|
||||
become_user passwd.pw_uid, passwd.pw_uid
|
||||
end
|
||||
|
||||
def self.become_user(uid, gid)
|
||||
r = LibC.setgid gid
|
||||
raise Errno.new "setgid" if r != 0
|
||||
|
||||
r = LibC.setuid passwd.pw_uid
|
||||
r = LibC.setuid uid
|
||||
raise Errno.new "setuid" if r != 0
|
||||
|
||||
passwd
|
||||
end
|
||||
end
|
||||
#def get_uid_gid(user_name : String)
|
||||
|
@ -2,6 +2,8 @@ require "yaml"
|
||||
require "colorize"
|
||||
require "file_utils"
|
||||
|
||||
require "passwd"
|
||||
|
||||
require "./context.cr"
|
||||
require "./service_definition.cr"
|
||||
require "./environment.cr"
|
||||
@ -215,6 +217,7 @@ class Service
|
||||
env["SERVICE_NAME"] = name
|
||||
env["SERVICE_ROOT"] = root
|
||||
env["SERVICE_ID"] = full_id
|
||||
env["SERVICE_USER"] = user_name
|
||||
if _pid = pid @context.pid_directory
|
||||
env["SERVICE_PID"] = _pid.to_s
|
||||
end
|
||||
@ -222,11 +225,10 @@ class Service
|
||||
env["ENVIRONMENT"] = @environment.name
|
||||
env["ENVIRONMENT_TYPE"] = @environment.type.to_s
|
||||
|
||||
|
||||
@providers.each do |token, provider|
|
||||
service_provider = @context.get_service_by_id provider
|
||||
|
||||
# FIXME: Warning?
|
||||
# FIXME: Warning if mandatory?
|
||||
next if service_provider.nil?
|
||||
|
||||
env["#{token.upcase}_PROVIDER"] = provider
|
||||
@ -294,9 +296,13 @@ class Service
|
||||
|
||||
context.info "Creating #{file.name}"
|
||||
|
||||
uid, gid = get_uid_gid
|
||||
|
||||
child = Process.fork do
|
||||
Dir.cd root
|
||||
|
||||
System.become_user uid, gid
|
||||
|
||||
Process.exec "sh", ["-c", creation_command],
|
||||
output: Process::Redirect::Inherit,
|
||||
error: Process::Redirect::Inherit,
|
||||
@ -319,7 +325,11 @@ class Service
|
||||
context.title "Starting #{to_s}"
|
||||
end
|
||||
|
||||
create_user_and_group!
|
||||
|
||||
uid, gid = get_uid_gid
|
||||
FileUtils.mkdir_p root
|
||||
File.chown root, uid, gid
|
||||
|
||||
build_files! context
|
||||
|
||||
@ -337,12 +347,7 @@ class Service
|
||||
LibC.dup2 stdout_file.fd, 1
|
||||
LibC.dup2 stderr_file.fd, 2
|
||||
|
||||
@reference.user.try do |user|
|
||||
unless System.become_user user
|
||||
STDERR << "service: child could not setuid() to user '#{user}'.\n"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
System.become_user uid, gid
|
||||
|
||||
Process.exec command, args,
|
||||
chdir: (@reference.directory.try { |x| evaluate x } || root),
|
||||
@ -583,7 +588,11 @@ class Service
|
||||
end
|
||||
end
|
||||
|
||||
remove_user_and_group!
|
||||
|
||||
File.delete "#{context.services_directory}/#{name}.#{@environment.name}.spec"
|
||||
|
||||
FileUtils.rm_rf root
|
||||
end
|
||||
|
||||
def is_id?(id)
|
||||
@ -660,6 +669,34 @@ class Service
|
||||
def get_consumers(token)
|
||||
@context.services.select(&.consumes?(token, self))
|
||||
end
|
||||
|
||||
def user_name
|
||||
full_id.sub('/', '.')
|
||||
end
|
||||
|
||||
def get_uid_gid
|
||||
passwd = Passwd.new("/etc/passwd", "/etc/group")
|
||||
|
||||
user = passwd.get_user(user_name).not_nil!
|
||||
|
||||
{user.uid, user.gid}
|
||||
end
|
||||
|
||||
def create_user_and_group!
|
||||
Passwd.new("/etc/passwd", "/etc/group").tap do |passwd|
|
||||
return if passwd.get_user user_name
|
||||
|
||||
passwd.add_user user_name,
|
||||
full_name: "Service[#{id}]"
|
||||
end
|
||||
end
|
||||
|
||||
def remove_user_and_group!
|
||||
Passwd.new("/etc/passwd", "/etc/group").tap do |passwd|
|
||||
passwd.remove_user user_name
|
||||
passwd.remove_group user_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -10,8 +10,8 @@ events {
|
||||
}
|
||||
|
||||
http {
|
||||
error_log /var/log/{{ service.id | replace("/", "_") }}_error.log warn;
|
||||
access_log /var/log/{{ service.id | replace("/", "_") }}_access.log;
|
||||
error_log {{ service.root }}/error.log warn;
|
||||
access_log {{ service.root }}/access.log;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
Loading…
Reference in New Issue
Block a user