summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <natanael.copa@gmail.com>2007-11-14 22:26:25 +0000
committerNatanael Copa <natanael.copa@gmail.com>2007-11-14 22:26:25 +0000
commit95cb7d3fe2bb50735757d9b69119d1c19bcec791 (patch)
treeb4e40fa914baeba839c8113d880fa3b4c48014b8
parent4d69d93c131b3dfd0e3c321da67e62ab44e42293 (diff)
downloadacf-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.lua75
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
+