change root für ssh

Ingo Luetkebohle ingo at devconsult.de
Son Mai 23 19:25:44 CEST 1999


Hoi Rene,

wie kommts eigentlich, daß Du an die Ostwestfalen und an die Thüringer
scheibst? Liegt ja nicht gerade nah aneinander :-)

On Sat, 22 May 1999, Rene Lange wrote:
> Wie kann ich für eine ssh Sitzung eines Benutzers das root Directory auf ~/
> setzen? 

Wie bereits des öfteren erwähnt wurde, ist das nicht ganz einfach, da man
normalerweise ein funktionables Environment im Homeverzeichnis des
Benutzers anlegen müsste. Es geht aber auch anders und zwar mit der sash
("System Administrators SHell"), einer kleinen Shell, die die wichtigsten
Utilities (ls, rm, cp, tar, gzip, etc) in einer reduzierten Version
mitbringt und mit ca. 380kb noch vertretbar gross bleibt. Bei RH ist die
sash seit V5 dabei, bei anderen Distributionen weiss ichs nicht, aber
dafür gibts ja den Source :-)

Du brauchst allerdings noch ein Programm, das Du anstelle der Shell in die
/etc/passwd eintragen kannst und das ein chroot auf das Homeverzeichnis
des Users ausführt. Ich habe mal "xchroot" beigefügt, das kannst Du
kompilieren und als Shell eintragen. Es muss setuid-root sein, damit der
chroot-Call ausgeführt werden kann (ich hoffe mal, ich habe keine Fehler
eingebaut -- aber in ca. 50 Zeilen Code sollte das vermeidbar sein) und
ruft dann im Homeverzeichnis des Benutzers "/sbin/sash" (oder was man eben
am Anfang einträgt) auf, so daß der Benutzer in seiner chroot Umgebung
landet.
 
---Ingo, 21st Century Digital Boy
-------------- nächster Teil --------------
/* xchroot -- change root the home directory of the effective user id
	      and execute a program there
	      to modify calling parameters, see below

		Copyright (C) 1999, ingo at devcon.net
		All Rights Reserved

  $Id: xchroot.c,v 1.1 1999/05/23 17:04:21 ingo Exp ingo $
*/

#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>

#define BUFSIZE 256
#define ARGSIZE 64
#define ENVSIZE 64

#define SHELL "/sbin/sash"

/* arguments and the environment are set here */
static char* const args[ARGSIZE] = { SHELL, NULL };
static char* const envp[ENVSIZE] = { "SHELL=" SHELL, "HOME=/", NULL };

/**
 * prints an error message and exits with specified return code
 */
void err_exit(int ret, char *fmt, ...)
{
	va_list ap;
	char buf[BUFSIZE];
	int s_errno = errno;

	/* format error message */
	va_start(ap, fmt);
	vsnprintf(buf, BUFSIZE, fmt, ap);
	if (ret) {
		strncat(buf, ": ", BUFSIZE);
		strncat(buf, strerror(s_errno), BUFSIZE);
	};
	va_end(ap);

	/* print and exit */
	printf("%s\n", buf);
	exit(ret);
}

int main(int argc, char *argv[])
{
	struct passwd *pw = 0;
	uid_t ruid;

	/* get real user information */
	ruid = getuid();
	if(!(pw = getpwuid(ruid)) || !pw->pw_dir)
		err_exit(255, "can't get home-directory for uid %d", ruid);

	/* change root */
	if(chdir(pw->pw_dir) || chroot(pw->pw_dir))
		err_exit(255, "can't change root to %s", pw->pw_dir);

	/* drop priviledges and execute shell */
	if(setreuid(ruid, ruid))
		err_exit(255, "can't set real user id to %d", ruid);
	execve(SHELL, args, envp);

	/* replace the above call with this one, to keep environment
	execvp(SHELL, args);
	*/


	/* execve doesn't return, so if we get here, an error occured */
	err_exit(255, "execve failed");
	return 255;
}
-------------- nächster Teil --------------
alias cp -cp
alias rm -rm
alias tar -tar
alias gzip -gzip
alias gunzip -gunzip
alias ls -ls
alias printenv -printenv
alias mkdir -mkdir
alias rmdir -rmdir