Allow retrieval of the user's default login shell from /etc/passwd.

Allow the code to be built without support for the LOGIN service, as
calling /bin/login does not work well on Fedora.


git-svn-id: https://shellinabox.googlecode.com/svn/trunk@198 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac@gmail.com 2009-12-04 06:33:36 +00:00
parent 5caa8b7288
commit 0fcf50735e
16 changed files with 199 additions and 57 deletions

View file

@ -1,3 +1,11 @@
2009-12-03 Markus Gutschke <markus@shellinabox.com>
* Allow retrieval of the user's default login shell from
/etc/passwd.
* Allow the code to be built without support for the LOGIN
service, as calling /bin/login does not work well on Fedora.
2009-12-02 Markus Gutschke <markus@shellinabox.com> 2009-12-02 Markus Gutschke <markus@shellinabox.com>
* Added fallback code that dynamically computes the correct commandline * Added fallback code that dynamically computes the correct commandline

View file

@ -196,12 +196,18 @@ ${top_srcdir}/demo/vt100.js: ${top_srcdir}/shellinabox/vt100.js
shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \ @src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
echo preprocess "$$src" '>'"$@"; \ echo preprocess "$$src" '>'"$@"; \
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
grep 'HAVE_BIN_LOGIN' >/dev/null 2>&1; then \
sed -e '/^#ifndef *HAVE_BIN_LOGIN$$/,/^#endif$$/d' "$$src"; \
else \
sed -e '/^#ifdef *HAVE_BIN_LOGIN$$/,/^#endif$$/d' "$$src"; \
fi | \
if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \ if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\ egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\
wc -l` -eq 3 ]; then \ wc -l` -eq 3 ]; then \
sed -e '/^#ifndef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src"; \ sed -e '/^#ifndef *HAVE_OPENSSL$$/,/^#endif$$/d'; \
else \ else \
sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src"; \ sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d'; \
fi | \ fi | \
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \ if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \ grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \

View file

@ -1209,12 +1209,18 @@ ${top_srcdir}/demo/vt100.js: ${top_srcdir}/shellinabox/vt100.js
shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \ @src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
echo preprocess "$$src" '>'"$@"; \ echo preprocess "$$src" '>'"$@"; \
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
grep 'HAVE_BIN_LOGIN' >/dev/null 2>&1; then \
sed -e '/^#ifndef *HAVE_BIN_LOGIN$$/,/^#endif$$/d' "$$src"; \
else \
sed -e '/^#ifdef *HAVE_BIN_LOGIN$$/,/^#endif$$/d' "$$src"; \
fi | \
if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \ if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\ egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\
wc -l` -eq 3 ]; then \ wc -l` -eq 3 ]; then \
sed -e '/^#ifndef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src"; \ sed -e '/^#ifndef *HAVE_OPENSSL$$/,/^#endif$$/d'; \
else \ else \
sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src"; \ sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d'; \
fi | \ fi | \
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \ if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \ grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \

View file

@ -11,11 +11,16 @@ some tips on getting things working:
you start the daemon as "root". you start the daemon as "root".
To fix this problem, consider explicitly specifying a service definition. To fix this problem, consider explicitly specifying a service definition.
One of these two should work: One of these two should work:
--service /:AUTH:HOME:/bin/bash --service /:AUTH:HOME:SHELL
or or
--service /:SSH --service /:SSH
The latter requires that you have a locally running "sshd" daemon. The latter requires that you have a locally running "sshd" daemon.
- Alternatively, consider running "./configure --disable-login" before building
the daemon. This will completely remove support for the "LOGIN" service, and
shellinaboxd will instead use a default "SSH" service for both unprivileged
and for "root" users.
- On Fedora, PAM authentication does not work for shellinabox until you - On Fedora, PAM authentication does not work for shellinabox until you
explicitly configure it. This means, using "AUTH" in the service definition explicitly configure it. This means, using "AUTH" in the service definition
will not allow you to log in. will not allow you to log in.

View file

@ -1,11 +1,14 @@
/* config.h. Generated from config.h.in by configure. */ /* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */ /* config.h.in. Generated from configure.ac by autoheader. */
/* Set if you want support for calling /bin/login */
#define HAVE_BIN_LOGIN 1
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
/* Define to 1 if you have the `dlopen' function. */ /* Define to 1 if you have the `dlopen' function. */
/* #undef HAVE_DLOPEN */ #define HAVE_DLOPEN 1
/* Define to 1 if you have the `getgrgid_r' function. */ /* Define to 1 if you have the `getgrgid_r' function. */
#define HAVE_GETGRGID_R 1 #define HAVE_GETGRGID_R 1
@ -138,10 +141,10 @@
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Most recent revision number in the version control system */ /* Most recent revision number in the version control system */
#define VCS_REVISION "197" #define VCS_REVISION "198"
/* Version number of package */ /* Version number of package */
#define VERSION "2.10" #define VERSION "2.10"
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
#define const /**/ /* #undef const */

View file

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */ /* config.h.in. Generated from configure.ac by autoheader. */
/* Set if you want support for calling /bin/login */
#undef HAVE_BIN_LOGIN
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H #undef HAVE_DLFCN_H

47
configure vendored
View file

@ -861,6 +861,7 @@ with_pic
enable_fast_install enable_fast_install
with_gnu_ld with_gnu_ld
enable_libtool_lock enable_libtool_lock
enable_login
enable_ssl enable_ssl
enable_pam enable_pam
enable_runtime_loading enable_runtime_loading
@ -1500,6 +1501,11 @@ Optional Features:
--enable-fast-install[=PKGS] --enable-fast-install[=PKGS]
optimize for fast installation [default=yes] optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds) --disable-libtool-lock avoid locking (might break parallel builds)
--disable-login on some systems (e.g. Fedora), calling /bin/login
does not work well. If you know that your system
suffers from this problem, set this option to
remove support for the LOGIN keyword in the
service description.
--disable-ssl if available at built-time, support for SSL --disable-ssl if available at built-time, support for SSL
connections will be enabled. It can still be connections will be enabled. It can still be
disabled at run-time, either on the daemon's disabled at run-time, either on the daemon's
@ -2319,7 +2325,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_compiler_gnu=$ac_cv_c_compiler_gnu
VCS_REVISION=197 VCS_REVISION=198
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -4470,13 +4476,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:4473: $ac_compile\"" >&5) (eval echo "\"\$as_me:4479: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:4476: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval echo "\"\$as_me:4482: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:4479: output\"" >&5) (eval echo "\"\$as_me:4485: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
@ -5682,7 +5688,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 5685 "configure"' > conftest.$ac_ext echo '#line 5691 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@ -7208,11 +7214,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7211: $lt_compile\"" >&5) (eval echo "\"\$as_me:7217: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7215: \$? = $ac_status" >&5 echo "$as_me:7221: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -7547,11 +7553,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7550: $lt_compile\"" >&5) (eval echo "\"\$as_me:7556: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7554: \$? = $ac_status" >&5 echo "$as_me:7560: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -7652,11 +7658,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7655: $lt_compile\"" >&5) (eval echo "\"\$as_me:7661: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7659: \$? = $ac_status" >&5 echo "$as_me:7665: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -7707,11 +7713,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7710: $lt_compile\"" >&5) (eval echo "\"\$as_me:7716: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7714: \$? = $ac_status" >&5 echo "$as_me:7720: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -10090,7 +10096,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 10093 "configure" #line 10099 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -10186,7 +10192,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 10189 "configure" #line 10195 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -10680,6 +10686,17 @@ fi
rm -f core conftest.err conftest.$ac_objext \ rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext conftest$ac_exeext conftest.$ac_ext
# Check whether --enable-login was given.
if test "${enable_login+set}" = set; then :
enableval=$enable_login;
fi
if test "x$enable_login" != xno; then
$as_echo "#define HAVE_BIN_LOGIN 1" >>confdefs.h
fi
# Check whether --enable-ssl was given. # Check whether --enable-ssl was given.
if test "${enable_ssl+set}" = set; then : if test "${enable_ssl+set}" = set; then :
enableval=$enable_ssl; enableval=$enable_ssl;

View file

@ -2,7 +2,7 @@ AC_PREREQ(2.57)
dnl This is the one location where the authoritative version number is stored dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.10, markus@shellinabox.com) AC_INIT(shellinabox, 2.10, markus@shellinabox.com)
VCS_REVISION=197 VCS_REVISION=198
AC_SUBST(VCS_REVISION) AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}", AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system]) [Most recent revision number in the version control system])
@ -55,6 +55,19 @@ AC_TRY_LINK([#include <pthread.h>
[AC_DEFINE(HAVE_SIGWAIT, 1, [AC_DEFINE(HAVE_SIGWAIT, 1,
Define to 1 if you have a working sigwait)]) Define to 1 if you have a working sigwait)])
dnl On some systems, calling /bin/login does not work. Disable the LOGIN
dnl feature, if the user tells us that it does not do the right thing.
AC_ARG_ENABLE(login,
[ --disable-login on some systems (e.g. Fedora), calling /bin/login
does not work well. If you know that your system
suffers from this problem, set this option to
remove support for the LOGIN keyword in the
service description.])
if test "x$enable_login" != xno; then
AC_DEFINE(HAVE_BIN_LOGIN, 1,
Set if you want support for calling /bin/login)
fi
dnl We automatically detect SSL support, but allow users to disable it dnl We automatically detect SSL support, but allow users to disable it
AC_ARG_ENABLE(ssl, AC_ARG_ENABLE(ssl,
[ --disable-ssl if available at built-time, support for SSL [ --disable-ssl if available at built-time, support for SSL

View file

@ -1955,7 +1955,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.10 (revision 197)" + alert("VT100 Terminal Emulator " + "2.10 (revision 198)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };

View file

@ -727,29 +727,34 @@ static const struct passwd *getPWEnt(uid_t uid) {
struct passwd pwbuf, *pw; struct passwd pwbuf, *pw;
char *buf; char *buf;
#ifdef _SC_GETPW_R_SIZE_MAX #ifdef _SC_GETPW_R_SIZE_MAX
int len = sysconf(_SC_GETPW_R_SIZE_MAX); int len = sysconf(_SC_GETPW_R_SIZE_MAX);
if (len <= 0) { if (len <= 0) {
len = 4096; len = 4096;
} }
#else #else
int len = 4096; int len = 4096;
#endif #endif
check(buf = malloc(len)); check(buf = malloc(len));
check(!getpwuid_r(uid, &pwbuf, buf, len, &pw) && pw); check(!getpwuid_r(uid, &pwbuf, buf, len, &pw) && pw);
if (!pw->pw_name ) pw->pw_name = "";
if (!pw->pw_passwd) pw->pw_passwd = "";
if (!pw->pw_gecos ) pw->pw_gecos = "";
if (!pw->pw_dir ) pw->pw_dir = "";
if (!pw->pw_shell ) pw->pw_shell = "";
struct passwd *passwd; struct passwd *passwd;
check(passwd = calloc(sizeof(struct passwd) + check(passwd = calloc(sizeof(struct passwd) +
strlen(pw->pw_name) + strlen(pw->pw_name) +
strlen(pw->pw_passwd) + strlen(pw->pw_passwd) +
strlen(pw->pw_gecos) + strlen(pw->pw_gecos) +
strlen(pw->pw_dir) + strlen(pw->pw_dir) +
strlen(pw->pw_shell) + 5, 1)); strlen(pw->pw_shell) + 5, 1));
passwd->pw_uid = pw->pw_uid; passwd->pw_uid = pw->pw_uid;
passwd->pw_gid = pw->pw_gid; passwd->pw_gid = pw->pw_gid;
strncat(passwd->pw_shell = strrchr( strncat(passwd->pw_shell = strrchr(
strncat(passwd->pw_dir = strrchr( strncat(passwd->pw_dir = strrchr(
strncat(passwd->pw_gecos = strrchr( strncat(passwd->pw_gecos = strrchr(
strncat(passwd->pw_passwd = strrchr( strncat(passwd->pw_passwd = strrchr(
strncat(passwd->pw_name = (char *)(passwd + 1), strncat(passwd->pw_name = (char *)(passwd + 1),
pw->pw_name, strlen(pw->pw_name)), '\000') + 1, pw->pw_name, strlen(pw->pw_name)), '\000') + 1,
pw->pw_passwd, strlen(pw->pw_passwd)), '\000') + 1, pw->pw_passwd, strlen(pw->pw_passwd)), '\000') + 1,
pw->pw_gecos, strlen(pw->pw_gecos)), '\000') + 1, pw->pw_gecos, strlen(pw->pw_gecos)), '\000') + 1,
@ -946,6 +951,12 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp,
free((void *)fqdn); free((void *)fqdn);
free((void *)hostname); free((void *)hostname);
if (service->useDefaultShell) {
check(!service->cmdline);
service->cmdline = strdup(*pw->pw_shell ?
pw->pw_shell : "/bin/sh");
}
if (restricted && if (restricted &&
(service->uid != restricted || service->gid != pw->pw_gid)) { (service->uid != restricted || service->gid != pw->pw_gid)) {
puts("\nAccess denied!"); puts("\nAccess denied!");
@ -1226,8 +1237,19 @@ static void execService(int width, int height, struct Service *service,
extern char **environ; extern char **environ;
environ = environment; environ = environment;
char *cmd = strrchr(argv[0], '/'); char *cmd = strdup(argv[0]);
execvp(cmd ? cmd + 1: argv[0], argv); char *slash = strrchr(argv[0], '/');
if (slash) {
memmove(argv[0], slash + 1, strlen(slash));
}
if (service->useDefaultShell) {
int len = strlen(argv[0]);
check(argv[0] = realloc(argv[0], len + 2));
memmove(argv[0] + 1, argv[0], len);
argv[0][0] = '-';
argv[0][len + 1] = '\000';
}
execvp(cmd, argv);
} }
void setWindowSize(int pty, int width, int height) { void setWindowSize(int pty, int width, int height) {

View file

@ -83,6 +83,7 @@ void initService(struct Service *service, const char *arg) {
} }
arg = ptr + 1; arg = ptr + 1;
#ifdef HAVE_BIN_LOGIN
// The next part of the argument is either the word 'LOGIN' or the // The next part of the argument is either the word 'LOGIN' or the
// application definition. // application definition.
if (!strcmp(arg, "LOGIN")) { if (!strcmp(arg, "LOGIN")) {
@ -93,6 +94,7 @@ void initService(struct Service *service, const char *arg) {
service->useLogin = 1; service->useLogin = 1;
service->useHomeDir = 0; service->useHomeDir = 0;
service->authUser = 0; service->authUser = 0;
service->useDefaultShell = 0;
service->uid = 0; service->uid = 0;
service->gid = 0; service->gid = 0;
check(service->user = strdup("root")); check(service->user = strdup("root"));
@ -100,10 +102,13 @@ void initService(struct Service *service, const char *arg) {
check(service->cwd = strdup("/")); check(service->cwd = strdup("/"));
check(service->cmdline = strdup( check(service->cmdline = strdup(
"/bin/login -p -h ${peer}")); "/bin/login -p -h ${peer}"));
} else if (!strcmp(arg, "SSH") || !strncmp(arg, "SSH:", 4)) { } else
#endif
if (!strcmp(arg, "SSH") || !strncmp(arg, "SSH:", 4)) {
service->useLogin = 0; service->useLogin = 0;
service->useHomeDir = 0; service->useHomeDir = 0;
service->authUser = 2; service->authUser = 2;
service->useDefaultShell = 0;
service->uid = -1; service->uid = -1;
service->gid = -1; service->gid = -1;
service->user = NULL; service->user = NULL;
@ -204,7 +209,13 @@ void initService(struct Service *service, const char *arg) {
if (!*arg) { if (!*arg) {
goto error; goto error;
} }
check(service->cmdline = strdup(arg)); if (!strcmp(arg, "SHELL")) {
service->useDefaultShell = 1;
service->cmdline = NULL;
} else {
service->useDefaultShell = 0;
check(service->cmdline = strdup(arg));
}
} }
free(desc); free(desc);
} }

View file

@ -54,6 +54,7 @@ struct Service {
int useLogin; int useLogin;
int useHomeDir; int useHomeDir;
int authUser; int authUser;
int useDefaultShell;
int uid; int uid;
int gid; int gid;
const char *user; const char *user;

View file

@ -358,7 +358,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
}; };
ShellInABox.prototype.about = function() { ShellInABox.prototype.about = function() {
alert("Shell In A Box version " + "2.10 (revision 197)" + alert("Shell In A Box version " + "2.10 (revision 198)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com" + "For more information check http://shellinabox.com" +
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ? (typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?

View file

@ -765,10 +765,15 @@ static void usage(void) {
"be made available\n" "be made available\n"
"through the web interface:\n" "through the web interface:\n"
" SERVICE := <url-path> ':' APP\n" " SERVICE := <url-path> ':' APP\n"
" APP := 'LOGIN' | 'SSH' [ : <host> ] | " " APP := "
"USER ':' CWD ':' <cmdline>\n" #ifdef HAVE_BIN_LOGIN
"'LOGIN' | "
#endif
"'SSH' [ : <host> ] | "
"USER ':' CWD ':' CMD\n"
" USER := %s<username> ':' <groupname>\n" " USER := %s<username> ':' <groupname>\n"
" CWD := 'HOME' | <dir>\n" " CWD := 'HOME' | <dir>\n"
" CMD := 'SHELL' | <cmdline>\n"
"\n" "\n"
"<cmdline> supports variable expansion:\n" "<cmdline> supports variable expansion:\n"
" ${columns} - number of columns\n" " ${columns} - number of columns\n"
@ -1096,8 +1101,14 @@ static void parseArgs(int argc, char * const argv[]) {
// If the user did not register any services, provide the default service // If the user did not register any services, provide the default service
if (!getHashmapSize(serviceTable)) { if (!getHashmapSize(serviceTable)) {
addToHashMap(serviceTable, "/", (char *)newService(geteuid() ? ":SSH" : addToHashMap(serviceTable, "/",
":LOGIN")); (char *)newService(
#ifdef HAVE_BIN_LOGIN
geteuid() ? ":SSH" : ":LOGIN"
#else
":SSH"
#endif
));
} }
enumerateServices(serviceTable); enumerateServices(serviceTable);
deleteHashMap(serviceTable); deleteHashMap(serviceTable);

View file

@ -44,7 +44,7 @@
.\" The most up-to-date version of this program is always available from .\" The most up-to-date version of this program is always available from
.\" http://shellinabox.com .\" http://shellinabox.com
.\" .\"
.TH SHELLINABOXD 1 "Nov 21, 2009" .TH SHELLINABOXD 1 "Dec 03, 2009"
.SH NAME .SH NAME
shellinaboxd \- publish command line shell through AJAX interface shellinaboxd \- publish command line shell through AJAX interface
.SH SYNOPSIS .SH SYNOPSIS
@ -330,6 +330,7 @@ One or more services can be registered on different URL paths:
\fISERVICE\fP := <url-path> ':' \fIAPPLICATION\fP \fISERVICE\fP := <url-path> ':' \fIAPPLICATION\fP
.in .in
#ifdef HAVE_BIN_LOGIN
There is a pre-defined \fIapplication\fP, 'LOGIN', which causes the There is a pre-defined \fIapplication\fP, 'LOGIN', which causes the
daemon to invoke daemon to invoke
.B /bin/login .B /bin/login
@ -343,12 +344,34 @@ was defined. Starting
requires requires
.B root .B root
privileges. privileges.
#endif
There is another pre-defined \fIapplication\fP, 'SSH'. Instead of invoking There is
#ifdef HAVE_BIN_LOGIN
another
#endif
#ifndef HAVE_BIN_LOGIN
a
#endif
pre-defined \fIapplication\fP, 'SSH'.
#ifdef HAVE_BIN_LOGIN
Instead of invoking
.BR /bin/login , .BR /bin/login ,
it calls it
#endif
#ifndef HAVE_BIN_LOGIN
It
#endif
calls
.BR ssh . .BR ssh .
This is the default option for unprivileged users, if no This is the default
#ifdef HAVE_BIN_LOGIN
option for unprivileged users,
#endif
#ifndef HAVE_BIN_LOGIN
option,
#endif
if no
.B --service .B --service
was defined. This operation is available to both privileged and regular was defined. This operation is available to both privileged and regular
users. If the optional \fIhost\fP parameter is omitted, users. If the optional \fIhost\fP parameter is omitted,
@ -359,7 +382,12 @@ connects to
Alternatively, an \fIapplication\fP can be specified by providing a Alternatively, an \fIapplication\fP can be specified by providing a
\fIuser\fP description, a working directory, and a command line: \fIuser\fP description, a working directory, and a command line:
.in +4 .in +4
\fIAPPLICATION\fP := 'LOGIN' | 'SSH' [ ':' <host> ] | \fIUSER\fP ':' \fICWD\fP ':' <cmdline> #ifdef HAVE_BIN_LOGIN
\fIAPPLICATION\fP := 'LOGIN' | 'SSH' [ ':' <host> ] | \fIUSER\fP ':' \fICWD\fP ':' \fICMD\fP
#endif
#ifndef HAVE_BIN_LOGIN
\fIAPPLICATION\fP := 'SSH' [ ':' <host> ] | \fIUSER\fP ':' \fICWD\fP ':' \fICMD\fP
#endif
#ifdef HAVE_PAM #ifdef HAVE_PAM
.in .in
@ -383,6 +411,14 @@ can be the user's home directory:
\fICWD\fP := 'HOME' : <dir> \fICWD\fP := 'HOME' : <dir>
.in .in
The command that
.B shellinaboxd
executes can either be specified as the 'SHELL' keyword, denoting the user's
default login shell, or an arbitrary command line:
.in +4
\fICMD\fP := 'SHELL' : <cmdline>
.in
The <cmdline> supports expansion of variables of the form ${VAR}. The <cmdline> supports expansion of variables of the form ${VAR}.
Supported variables are: Supported variables are:
.RS .RS

View file

@ -1955,7 +1955,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.10 (revision 197)" + alert("VT100 Terminal Emulator " + "2.10 (revision 198)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };