tags:

views:

411

answers:

5

Update

Got it! See my solution (fifth comment)

Here is my problen:

I have created a small binary called "jail" and in /etc/password I have made it the default shell for a test user.

Here is the -- simplified -- source code:

#define HOME "/home/user"
#define SHELL "/bin/bash"
...
if(chdir(HOME) || chroot(HOME)) return -1;
...
char *shellargv[] = { SHELL, "-login", "-rcfile", "/bin/myscript", 0 };
execvp(SHELL, shellargv);

Well, no matter how hard I try, it seems that, when my test user logs in, /bin/myscript will never be sourced. Similarly, if I drop a .bashrc file in user's home directory, it will be ignored as well.

Why would bash snob these guys?

--

Some precisions, not necessarily relevant, but to clear out some of the points made in the comments:

  • The 'jail' binary is actually suid, thus allowing it to chroot() successfully.
  • I have used 'ln' to make the appropriate binaries available - my jail cell is nicely padded :)
  • The issue does not seem to be with chrooting the user...something else is remiss.
+2  A: 

The shell isn't interactive. Try adding -i to the list of arguments.

dexedrine
+3  A: 

As Jason C says, the exec'ed shell isn't interactive.

His solution will force the shell to be interactive if it accepts -i to mean that (and bash does):

char *shellargv[] = { SHELL, "-i", "-login", ... };
execvp(SHELL, shellargv);

I want to add, though, that traditionally a shell will act as a login shell if ARGV[0] begins with a dash.

char *shellargv[] = {"-"SHELL, "-i", ...};
execvp(SHELL, shellargv);

Usually, though, Bash will autodetect whether it should run interactively or not. Its failure to in your case may be because of missing /dev/* nodes.

ephemient
+1  A: 

By the time your user is logging in and their shell tries to source this file, it's running under their UID. The chroot() system call is only usable by root -- you'll need to be cleverer than this.

Also, chrooting to a user's home directory will make their shell useless, as (unless they have a lot of stuff in there) they won't have access to any binaries. Useful things like ls, for instance.

DusK
+2  A: 

I can identify with wanting to do this yourself, but if you haven't already, check out jail chroot project and jailkit for some drop in tools to create a jail shell.

drsnyder
+1  A: 

Thanks for your help, guys,

I figured it out:

I forgot to setuid()/setgid(), chroot(), setuid()/setgid() back, then pass a proper environment using execve()

Oh, and, if I pass no argument to bash, it will source ~/.bashrc

If I pass "-l" if will source /etc/profile

Cheers!

Fusion
Ah, I had (falsely) assumed that either your chroot had everything in the same places as the typical system, or you were fixing up the environment first. Lacking the setuid/gid back shouldn't break this (although it would eliminate the security benefit to chrooting).
ephemient