Skip to content

Commit

Permalink
src/klish-plugin-infix: new symbol shell@infix with user tracking
Browse files Browse the repository at this point in the history
This patch adds a new klish symbol, shell@infix, which performs proper
droprivs before calling the configured shell.

Fix #298: track user id so shell command gets correct user

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
  • Loading branch information
troglobit committed Feb 4, 2024
1 parent 14eee45 commit f7f6fce
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
6 changes: 6 additions & 0 deletions package/klish-plugin-infix/klish-plugin-infix.mk
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ else
KLISH_PLUGIN_INFIX_CONF_OPTS += --disable-shell
endif

ifeq ($(BR2_PACKAGE_BASH),y)
KLISH_PLUGIN_INFIX_CONF_OPTS += --with-shell=/bin/bash
else
KLISH_PLUGIN_INFIX_CONF_OPTS += --with-shell=/bin/sh
endif

define KLISH_PLUGIN_INFIX_INSTALL_DOC
$(INSTALL) -t $(TARGET_DIR)/usr/share/infix/cli -D -m 0644 \
$(wildcard $(BR2_EXTERNAL_INFIX_PATH)/doc/cli/*.md)
Expand Down
41 changes: 40 additions & 1 deletion src/klish-plugin-infix/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AC_PREREQ(2.61)
AC_INIT([klish-plugin-infix], [1.0.0],
[https://github.com/kernelkit/infix/issues])
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
AM_SILENT_RULES(yes)
AM_SILENT_RULES(no)

LT_INIT

Expand All @@ -26,6 +26,10 @@ AC_ARG_ENABLE(shell,
AS_HELP_STRING([--enable-shell], [Enable shell access from CLI]),,[
enable_shell=no])

AC_ARG_WITH(shell,
AS_HELP_STRING([--with-shell=shell], [Path to shell to use, default: /bin/sh]),
[shell=$withval], [shell=yes])

# Check for pkg-config first, warn if it's not installed
PKG_PROG_PKG_CONFIG

Expand All @@ -37,6 +41,12 @@ AC_CHECK_LIB([klish], [kplugin_new],, AC_MSG_ERROR([Klish not found]))
AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"])
AM_CONDITIONAL(SHELL, [test "x$enable_shell" != "xno"])

AS_IF([test "x$with_shell" != "xno"], [
AS_IF([test "x$shell" = "xyes"], [shell=/bin/sh])
with_shell=$shell
AC_DEFINE_UNQUOTED(SHELL, "$shell", [Default: /bin/sh])],[
AC_DEFINE_UNQUOTED(SHELL, "/bin/sh")])

test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

Expand All @@ -47,3 +57,32 @@ KLISHCONFDIR=`eval echo $sysconfdir/klish`
AC_SUBST(KLISHCONFDIR)

AC_OUTPUT

cat <<EOF

------------------ Summary ------------------
$PACKAGE_NAME version $PACKAGE_VERSION
Prefix................: $prefix
Exec prefix...........: $eprefix
Sysconfdir............: `eval echo $sysconfdir`
Localstatedir.........: `eval echo $localstatedir`
Default fstab.........: `eval echo $fstab`
System environment....: ${sysconfig_path:-${sysconfig}}
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
Linker................: $LD $LLDP_LDFLAGS $LLDP_BIN_LDFLAGS $LDFLAGS $LIBS

Optional features:
Container support ....: $enable_containers
Allow shell access ...: $enable_shell
Shell to use .........: $with_shell

------------- Compiler version --------------
$($CC --version || true)
-------------- Linker version ---------------
$($LD --version || true)
---------------------------------------------

Check the above options and compile with:
${MAKE-make}

EOF
48 changes: 48 additions & 0 deletions src/klish-plugin-infix/src/infix.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
Expand All @@ -14,6 +15,7 @@
#include <sysrepo/values.h>

#include <klish/kplugin.h>
#include <klish/ksession.h>
#include <klish/kcontext.h>

#include <libyang/libyang.h>
Expand Down Expand Up @@ -527,6 +529,51 @@ int infix_commit(kcontext_t *ctx)
return -1;
}

int infix_shell(kcontext_t *ctx)
{
const char *user = "root";
ksession_t *session;
pid_t pid;
int rc;

session = kcontext_session(ctx);
if (session) {
user = ksession_user(session);
if (!user)
user = "root";
}

pid = fork();
if (pid == -1)
return -1;

if (!pid) {
struct passwd *pw;
char *args[] = {
"env", "CLISH=yes",
SHELL, "-il",
NULL
};

pw = getpwnam(user);
if (setgid(pw->pw_gid) || setuid(pw->pw_uid))
fprintf(stderr, "Failed dropping privileges to (UID:%d GID:%d): %s\n",
pw->pw_uid, pw->pw_gid, strerror(errno));

_exit(execvp(args[0], args));
}

while (waitpid(pid, &rc, 0) != pid)
;

if (WIFEXITED(rc))
rc = WEXITSTATUS(rc);
else if (WIFSIGNALED(rc))
rc = -2;

return rc;
}

int infix_rpc(kcontext_t *ctx)
{
kpargv_pargs_node_t *iter;
Expand Down Expand Up @@ -612,6 +659,7 @@ int kplugin_infix_init(kcontext_t *ctx)
kplugin_add_syms(plugin, ksym_new("erase", infix_erase));
kplugin_add_syms(plugin, ksym_new("files", infix_files));
kplugin_add_syms(plugin, ksym_new("ifaces", infix_ifaces));
kplugin_add_syms(plugin, ksym_new("shell", infix_shell));
kplugin_add_syms(plugin, ksym_new("rpc", infix_rpc));

return 0;
Expand Down
2 changes: 1 addition & 1 deletion src/klish-plugin-infix/xml/shell.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<VIEW name="main">

<COMMAND name="shell" help="Enter system shell">
<ACTION sym="script" in="tty" out="tty" interrupt="true">/usr/bin/env CLISH=yes bash -l</ACTION>
<ACTION sym="shell@infix" in="tty" out="tty" interrupt="true" />
</COMMAND>

</VIEW>
Expand Down

0 comments on commit f7f6fce

Please sign in to comment.