/*
/*   Copyright (c) 2003, David S. Madole
/*   All rights reserved.
/*
/*   For latest sources and information on this software, please
/*   go to http://www.madole.net/chroot
/*
/*   Questions, comments or suggestions should be directed to
/*   David S. Madole <david@madole.net>.
/*
/*   Redistribution and use in source and binary forms, with or without
/*   modification, are permitted provided that the following conditions
/*   are met:
/*
/*   1. Redistributions of source code must retain the above copyright
/*      notice unmodified, this list of conditions, and the following
/*      disclaimer.
/*
/*   2. Redistributions in binary form must reproduce the above copyright
/*      notice, this list of conditions and the following disclaimer in the
/*      documentation and/or other materials provided with the distribution.
/*
/*   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
/*   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
/*   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
/*   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
/*   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
/*   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
/*   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
/*   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
/*   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
/*   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
/*   SUCH DAMAGE.
*/


#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>

int main(int argc, char *argv[])
{
    struct passwd *user;
    char *defarg[] = { "/bin/sh", NULL };
    char *cmnd, *p;

    for (p = cmnd = argv[0]; *p; ) if (*p++ == '/') cmnd = p;

    if (argc < 3) {
	printf("usage: %s newroot newuser [command]\n", cmnd);
	return 1; }

    if ((user = getpwnam(argv[2])) == 0) {
	printf("%s: unknown login: %s\n", cmnd, argv[2]);
	return 1; }

    if (chdir(argv[1])) {
	printf("%s: %s: %s\n", cmnd, argv[1], strerror(errno));
	return 1; }

    if (chroot(argv[1])) {
	printf("%s: %s: %s\n", cmnd, argv[1], strerror(errno));
	return 1; }

    if (initgroups(argv[2], user->pw_gid)) {
	printf("%s: %s: permission denied\n", cmnd, argv[2]);
	return 1; }

    if (setgid(user->pw_gid)) {
	printf("%s: %s: permission denied\n", cmnd, argv[2]);
	return 1; }

    if (setuid(user->pw_uid)) {
	printf("%s: %s: permission denied\n", cmnd, argv[2]);
	return 1; }

    endpwent();

    if (argc > 3) execvp(argv[3], argv + 3);
    else execv(defarg[0], defarg);

    printf("%s: %s: %s\n", cmnd, argv[3], strerror(errno));
    return 1;
}
