#include #include #include #include #include "conn.h" #include "lua-privsep.h" #ifndef PRIVSEP_PATH #define PRIVSEP_PATH "./" #endif static int traceback (lua_State *L) { if (!lua_isstring(L, 1)) /* 'message' not a string? */ return 1; /* keep it intact */ fprintf(stderr, "traceback\n"); lua_getfield(L, LUA_GLOBALSINDEX, "debug"); if (!lua_istable(L, -1)) { fprintf(stderr, "traceback: debug\n"); lua_pop(L, 1); return 1; } lua_getfield(L, -1, "traceback"); if (!lua_isfunction(L, -1)) { fprintf(stderr, "traceback: traceback\n"); lua_pop(L, 2); return 1; } lua_pushvalue(L, 1); /* pass error message */ lua_pushinteger(L, 2); /* skip this function and traceback */ lua_call(L, 2, 1); /* call debug.traceback */ return 1; } int call_lua(int fd, const char *msg, size_t msglen) { const char *luamain = PRIVSEP_PATH "privileged-main.lua"; int traceback_index; const char *retbuf; size_t retsize; lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_pushcfunction(L, traceback); traceback_index = lua_gettop(L); if (luaL_loadfile(L, luamain)) return luaL_error(L, "%s", luamain); lua_pushlstring(L, msg, msglen); if (lua_pcall(L, 1, 1, traceback_index)) return luaL_error(L, "error"); if (!lua_isstring(L, -1)) error(L, "function must return string"); retbuf = lua_tolstring(L, -1, &retsize); return write(fd, retbuf, retsize); }