#include <unistd.h> #include <sys/types.h> #include <pwd.h> #include <grp.h> #include <errno.h> #include <lua.h> static int drop(lua_State *L, const char* root, const char* user, const char* group) { const int am_root = ((geteuid() ==0) || (getuid() == 0)) ? 1 : 0; struct passwd *u; struct group *g; if (!am_root) { /* generate error about not being root */ lua_error(L, "Can't chroot when non-root"); return 0; } errno = 0; u = getpwnam(user); if (u == NULL) { /* generate error about invalid user */ lua_error(L, "Unknown user to change to"); return 0; } errno = 0; g = getgrnam(group); if (g == NULL) { /* generate error about invalid group */ lua_error(L, "Unknown group to change to"); return 0; } chdir(root); chroot(root); seteuid(0); setuid(0); setuid(u->pw_uid); setgid(g->gr_gid); return 0; } static int lua_drop(lua_State *L) { drop(L, lua_tostring(L,1), lua_tostring(L,2), lua_tostring(L,3)); return 0; } void drop_register(lua_State *L) { lua_pushcclosure(L, lua_drop, 0); lua_setglobal(L, "drop"); }