patch - forceshell

Don Mahurin dmahurin at berkeley.innomedia.com
Thu Oct 4 12:36:40 EST 2001


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;
}



More information about the openssh-unix-dev mailing list