Attached is a simple patch which allows an auth param 'shell=' like
'command='
When specified, sshd will use this shell instead of the one in
/etc/passwd or the default shell.
This patch allows you can have some chrooted shell (actually any shell)
associated with a specific key.
You could do this with command=, but then the command given to ssh will
be ignored, and scp will not work.
changing the shell in /etc/passwd only works if you want that shell for
every key.
I suppose if there was a root= auth parameter which caused a chroot,
this could perform a similar task. Has someone already written that
code?
Attached also is a simple chrooted shell perl script.
-Don Mahurin
-------------- next part --------------
diff -ur openssh-2.9p2/auth-options.c openssh-2.9p2_forceshell/auth-options.c
--- openssh-2.9p2/auth-options.c Sun Mar 18 16:13:47 2001
+++ openssh-2.9p2_forceshell/auth-options.c Wed Oct 3 09:57:24 2001
@@ -29,6 +29,8 @@
/* "command=" option. */
char *forced_command = NULL;
+/* "shell=" option. */
+char *forced_shell = NULL;
/* "environment=" options. */
struct envstring *custom_environment = NULL;
@@ -98,6 +100,35 @@
packet_send_debug("Pty allocation disabled.");
no_pty_flag = 1;
opts += strlen(cp);
+ goto next_option;
+ }
+ cp = "shell=\"";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ opts += strlen(cp);
+ forced_shell = xmalloc(strlen(opts) + 1);
+ i = 0;
+ while (*opts) {
+ if (*opts == '"')
+ break;
+ if (*opts == '\\' && opts[1] == '"') {
+ opts += 2;
+ forced_shell[i++] = '"';
+ continue;
+ }
+ forced_shell[i++] = *opts++;
+ }
+ if (!*opts) {
+ debug("%.100s, line %lu: missing end quote",
+ file, linenum);
+ packet_send_debug("%.100s, line %lu: missing end quote",
+ file, linenum);
+ xfree(forced_shell);
+ forced_shell = NULL;
+ goto bad_option;
+ }
+ forced_shell[i] = 0;
+ packet_send_debug("Forced shell: %.900s", forced_shell);
+ opts++;
goto next_option;
}
cp = "command=\"";
diff -ur openssh-2.9p2/auth-options.h openssh-2.9p2_forceshell/auth-options.h
--- openssh-2.9p2/auth-options.h Sun Jan 21 21:34:40 2001
+++ openssh-2.9p2_forceshell/auth-options.h Wed Oct 3 09:57:33 2001
@@ -28,6 +28,7 @@
extern int no_x11_forwarding_flag;
extern int no_pty_flag;
extern char *forced_command;
+extern char *forced_shell;
extern struct envstring *custom_environment;
/*
diff -ur openssh-2.9p2/session.c openssh-2.9p2_forceshell/session.c
--- openssh-2.9p2/session.c Sat Jun 16 20:40:51 2001
+++ openssh-2.9p2_forceshell/session.c Wed Oct 3 09:58:44 2001
@@ -1195,7 +1195,12 @@
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
*/
+ if(forced_shell != NULL) {
+ shell = forced_shell;
+ }
+ else {
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+ }
#ifdef HAVE_LOGIN_CAP
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
#endif
-------------- next part --------------
#!/usr/bin/perl
# Changes root to APPROOT as current user and runs given command or bash
# -Don Mahurin
my(@command) = @ARGV;
if(@command)
{
if ($command[0] =~ m:^-:) { unshift(@command,"bash") } # assume
shell args
@command = untaint(@command);
}
else
{
@command = ( "bash" );
}
exit(1) unless(open(FILE, "/etc/rbusd/APPROOT"));
my($rdir) = <FILE>;
chomp($rdir);
close(FILE);
if($rdir =~ m:^(/mnt.*)$:) { $rdir = $1 } else { die "bad dir: $rdir";
}
chdir($rdir) || die "can't chdir: $dir";
chroot($rdir) || die "can't chroot: $dir";
$> = $<;
$ENV{PATH}="/bin:/usr/bin";
exec(@command);
sub untaint
{
my @out;
for (@_) { if ( /^(^.*)$/) { push(@out, $1) } }
return @out;
}