#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>

#ifdef DEBUG
#include <stdio.h>
#define DPRINTF(x...) fprintf(stderr, x)
#else
#define DPRINTF(x...) /**/
#endif

int main(void) {
	struct passwd *pwinfo=NULL;
	char *home=NULL, *home_tmp=NULL;
	uid_t uid;
	gid_t gid;

	uid=getuid();
	gid=getgid();

	/* Don't chroot for uid==0 */
	if (uid!=0) {
		pwinfo=getpwuid(uid);
		if (pwinfo==NULL) {
			DPRINTF("Couldn't locate user (uid=%i).\n", uid);
			return(1);
		}
		home_tmp=getenv("HOME");
		if (home_tmp) home=strdup(home_tmp);
		if (home!=NULL && pwinfo->pw_dir!=NULL) {
			if (strcmp(pwinfo->pw_dir, home)!=0) {
				/* Passwd entry for home dir and $HOME don't match */
				DPRINTF("$HOME [%s] and pwinfo->pw_dir [%s] don't match\n", home, pwinfo->pw_dir);
				return(2);
			}
		}
		if (home==NULL && pwinfo->pw_dir!=NULL) {
			home=pwinfo->pw_dir;
		}
		if (chroot(home)!=0) {
			DPRINTF("Couldn't chroot (%s).\n", home);
			return(3);
		}
	}

	/* Set our GID and UID, GID first. */
	if (setgid(gid)<0) return(5);
	if (setuid(uid)<0) return(6);

	/* Set the SHELL environment variable */
	if (putenv("SHELL=" SHELL)<0) return(7);

	/* Execute our shell. */
	execl(SHELL, SHELL_SHORT, NULL);
	DPRINTF("Couldn't run shell (%s).\n", SHELL);
	return(4);
}
