colloquy-1.35.30/
colloquy-1.35.30/data/lang/
colloquy-1.35.30/data/misc/
colloquy-1.35.30/docs/
#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");
}