diff options
author | Natanael Copa <natanael.copa@gmail.com> | 2007-11-14 22:26:25 +0000 |
---|---|---|
committer | Natanael Copa <natanael.copa@gmail.com> | 2007-11-14 22:26:25 +0000 |
commit | 95cb7d3fe2bb50735757d9b69119d1c19bcec791 (patch) | |
tree | b4e40fa914baeba839c8113d880fa3b4c48014b8 | |
parent | 4d69d93c131b3dfd0e3c321da67e62ab44e42293 (diff) | |
download | acf-core-95cb7d3fe2bb50735757d9b69119d1c19bcec791.tar.bz2 acf-core-95cb7d3fe2bb50735757d9b69119d1c19bcec791.tar.xz |
added library for privilege separation
git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@306 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r-- | lib/privsep.lua | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/privsep.lua b/lib/privsep.lua new file mode 100644 index 0000000..d2edcb7 --- /dev/null +++ b/lib/privsep.lua @@ -0,0 +1,75 @@ + +module(..., package.seeall) + +require("json") +require("posix") + +local rpc = {} + +-- private privileged rpc server ------------------------------------ +local function rpcserver(r, w) + for line in r:lines() do + local handle = json.decode(line) + if type(rpc[handle.func]) == "function" then + response = rpc[handle.func](unpack(handle.data)) + else + response = nil + end + w:write(json.encode(response).."\n") + w:flush() + end +end + + +-- public func ---------------------------------------------------- +function drop_privs(user, group, privileged_funcs) + local k, v + local wrapper = {} + + -- communication pipes + local cr, pw = posix.pipe() + local pr, cw = posix.pipe() + + -- create wrapper table + for k,v in pairs(privileged_funcs or {}) do + if type(v) == "function" then + rpc[k] = v + wrapper[k] = function(...) + local handle = {} + handle.func = k + handle.data = {...} + cw:write(json.encode(handle).."\n") + cw:flush() + return (json.decode(cr:read("*line"))) + end + end + end + + pid = posix.fork() + if pid == nil then + cr:close() + cw:close() + pr:close() + cw:close() + return nil + end + + if pid == 0 then + -- child runs with privs + cr:close() + cw:close() + rpcserver(pr, pw) + pw:close() + pr:close() + os.exit() + end + + -- lets drop privs + if posix.setpid("g", group) and posix.setpid("u", user) then + return wrapper + else + posix.kill(pid) + return nil + end +end + |