Page MenuHomePhabricator

add parameter passing feature to su-to-root
Open, NormalPublic

Description

package: menu
script: /usr/bin/su-to-root

Unsupported: su-to-root -c command arg1 arg2 arg...
Unsupported: su-to-root command arg1 arg2 arg...
Supported: su-to-root -c 'whonix-setup-wizard setup'

Purpose:

  • Having a desktop environment agnostic tool that can be used rather than hardcoding kdesudo or gksudo in documentation.
  • Useful for whonix-setup-wizard, so we don't have to hardcode kdesudo or gksudo there.

Original Source:
http://sources.debian.net/src/menu/2.1.47/scripts/su-to-root/

Details

Impact
Normal

Event Timeline

Patrick raised the priority of this task from to Normal.
Patrick updated the task description. (Show Details)
Patrick added a project: bash.
Patrick added a subscriber: Patrick.
Patrick updated the task description. (Show Details)

Tested and working.

SU_TO_ROOT_SU=sux su-to-root -p root -c date +%s
SU_TO_ROOT_SU=sudo su-to-root -p root -c date +%s
SU_TO_ROOT_SU=su su-to-root -p root -c date +%s
SU_TO_ROOT_X=gksu su-to-root -X -p root -c dolphin /usr
SU_TO_ROOT_X=gksudo su-to-root -X -p root -c dolphin /usr
SU_TO_ROOT_X=kdesudo su-to-root -X -p root -c dolphin /usr
SU_TO_ROOT_X=sux su-to-root -X -p root -c dolphin /usr

Patch:

From f2fd7c39675b72128754f9052c42e0c7d5a7f5f1 Mon Sep 17 00:00:00 2001
From: Patrick Schleizer <adrelanos@riseup.net>
Date: Thu, 15 Jan 2015 02:24:47 +0000
Subject: [PATCH] added ability to pass command line parameters to applications

---
 scripts/su-to-root | 60 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 20 deletions(-)

diff --git a/scripts/su-to-root b/scripts/su-to-root
index 375975e..3a7e2af 100755
--- a/scripts/su-to-root
+++ b/scripts/su-to-root
@@ -17,7 +17,7 @@ gettext=$(which gettext 2>/dev/null)
 transl() {
   txt="$1";
   shift;
-  if [ -n "$gettext" ]; then 
+  if [ -n "$gettext" ]; then
     txt="$(gettext su-to-root "$txt")";
   fi
   printf "$txt" "$@"
@@ -35,14 +35,34 @@ usage () {
   exit 1
 }
 
+suwrapper() {
+  case $SU_TO_ROOT_SU in
+    sux)
+      sux -p "$pwuser" "$@"
+      ;;
+    sudo)
+      sudo -u "$pwuser" sh -c "$*"
+      ;;
+    *)
+      su -p "$pwuser" -c "$*"
+      ;;
+  esac
+}
+
 for i in "$@"; do
    case "$prev" in
      -p)
-       PRIV="$i";;
+       PRIV="$i"
+       shift 2
+       ;;
      -c)
-       COMMAND="$i";;
-     -X) 
-       NEEDS="X11";;
+       COMMAND="$i"
+       shift 1
+       ;;
+     -X)
+       NEEDS="X11"
+       shift 1
+       ;;
    esac
    prev="$i"
 done
@@ -54,7 +74,7 @@ fi
 euid=$(id -u)
 privid=$(id -u $PRIV)
 if test "$euid" = "$privid"; then
-  sh -c "$COMMAND"
+  sh -c "$*"
 else
   case $NEEDS in
   text)
@@ -65,14 +85,14 @@ else
     PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11:/usr/local/sbin:/usr/local/bin
     SHELL=`eshell $PRIV`
     case $SU_TO_ROOT_SU in
-      sux)  suname=sux; pwuser="$PRIV"; cmd='sux  -p "$PRIV" -c "$COMMAND"';;
-      sudo) suname=sudo;pwuser="$USER"; cmd='sudo -u "$PRIV" sh -c "$COMMAND"';;
-      *)    suname=su;  pwuser="$PRIV"; cmd='su   -p "$PRIV" -c "$COMMAND"';;
+      sux)  suname=sux; pwuser="$PRIV";;
+      sudo) suname=sudo;pwuser="$USER";;
+      *)    suname=su;  pwuser="$PRIV";;
     esac
     transl 'Using %s...\n' "$suname"
     transl 'Enter %s password at prompt.\n' "$pwuser"
     yesexpr=$(locale yesexpr)
-    while ! eval $cmd; do
+    while ! suwrapper $@; do
       transl 'Incorrect password or command failed. Try again? (y/N)'
       read ans
       if echo "$ans" | perl -e "<> =~ /$yesexpr/ and exit(1);"; then
@@ -90,30 +110,30 @@ else
             SU_TO_ROOT_X=kde4su
           fi;
         fi;
-      elif which kdesu >/dev/null 2>&1 ; then 
+      elif which kdesu >/dev/null 2>&1 ; then
         SU_TO_ROOT_X=kdesu
       elif test -x /usr/lib/kde4/libexec/kdesu ; then
         SU_TO_ROOT_X=kde4su
       elif which ktsuss >/dev/null 2>&1 ; then
         SU_TO_ROOT_X=ktsuss
-      elif which sux >/dev/null 2>&1 ; then 
+      elif which sux >/dev/null 2>&1 ; then
         SU_TO_ROOT_X=sux
       else
         SU_TO_ROOT_X=su-to-root
       fi
     fi
     case $SU_TO_ROOT_X in
-      gksu) gksu -u "$PRIV" "$COMMAND";;
-      gksudo) gksudo -u "$PRIV" "$COMMAND";;
-      kdesu) kdesu -u "$PRIV" "$COMMAND";;
-      kdesudo) kdesudo -u "$PRIV" "$COMMAND";;
-      kde4su) /usr/lib/kde4/libexec/kdesu -u "$PRIV" "$COMMAND";;
-      ktsuss) ktsuss -u "$PRIV" "$COMMAND";;
+      gksu) gksu -u "$PRIV" "$@";;
+      gksudo) gksudo -u "$PRIV" "$@";;
+      kdesu) kdesu -u "$PRIV" "$@";;
+      kdesudo) kdesudo -u "$PRIV" "$@";;
+      kde4su) /usr/lib/kde4/libexec/kdesu -u "$PRIV" "$@";;
+      ktsuss) ktsuss -u "$PRIV" "$@";;
       sux) env SU_TO_ROOT_SU=sux \
-        x-terminal-emulator -e su-to-root -p "$PRIV" -c "$COMMAND";;
+        x-terminal-emulator -e su-to-root -p "$PRIV" -c "$@";;
   # As a last resort, open a new x-terminal-emulator and prompt for the password
   # Do not use -X here!
-      *) x-terminal-emulator -e su-to-root -p "$PRIV" -c "$COMMAND";;
+      *) x-terminal-emulator -e su-to-root -p "$PRIV" -c "$@";;
     esac;;
   esac
 fi
-- 
2.1.3

Patched script:

#!/bin/bash

if test -r /etc/su-to-rootrc; then
. /etc/su-to-rootrc
fi

if test -r ~/.su-to-rootrc; then
. ~/.su-to-rootrc
fi

PRIV=root
COMMAND=
NEEDS=text

gettext=$(which gettext 2>/dev/null)

transl() {
  txt="$1";
  shift;
  if [ -n "$gettext" ]; then
    txt="$(gettext su-to-root "$txt")";
  fi
  printf "$txt" "$@"
}

eshell() {
   getent passwd $1 | cut -f7 -d:
}

usage () {
  transl 'usage: %s [-X] [-p <user>] -c <command>
  -c command: command to execute as a string (mandatory)
  -p <user>: user to switch to (default: root)
  -X: command is a X11 program\n' "$0" >&2
  exit 1
}

suwrapper() {
  case $SU_TO_ROOT_SU in
    sux)
      sux -p "$pwuser" "$@"
      ;;
    sudo)
      sudo -u "$pwuser" sh -c "$*"
      ;;
    *)
      su -p "$pwuser" -c "$*"
      ;;
  esac
}

for i in "$@"; do
   case "$prev" in
     -p)
       PRIV="$i"
       shift 2
       ;;
     -c)
       COMMAND="$i"
       shift 1
       ;;
     -X)
       NEEDS="X11"
       shift 1
       ;;
   esac
   prev="$i"
done

if [ -z "$COMMAND" ] ; then
   usage;
fi

euid=$(id -u)
privid=$(id -u $PRIV)
if test "$euid" = "$privid"; then
  sh -c "$*"
else
  case $NEEDS in
  text)
    if test "$euid" != 0; then
      transl 'About to execute %s.\n' "$COMMAND"
      transl 'This command needs %s privileges to be executed.\n' "$PRIV"
    fi
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11:/usr/local/sbin:/usr/local/bin
    SHELL=`eshell $PRIV`
    case $SU_TO_ROOT_SU in
      sux)  suname=sux; pwuser="$PRIV";;
      sudo) suname=sudo;pwuser="$USER";;
      *)    suname=su;  pwuser="$PRIV";;
    esac
    transl 'Using %s...\n' "$suname"
    transl 'Enter %s password at prompt.\n' "$pwuser"
    yesexpr=$(locale yesexpr)
    while ! suwrapper $@; do
      transl 'Incorrect password or command failed. Try again? (y/N)'
      read ans
      if echo "$ans" | perl -e "<> =~ /$yesexpr/ and exit(1);"; then
        exit 1
      fi
    done;;
  X11)
    if test -z "$SU_TO_ROOT_X"; then
      if which gksu >/dev/null 2>&1 ; then
        SU_TO_ROOT_X=gksu
        if test "X$KDE_FULL_SESSION" = "Xtrue" ; then
          if which kdesu >/dev/null 2>&1 ; then
            SU_TO_ROOT_X=kdesu
          elif test -x /usr/lib/kde4/libexec/kdesu ; then
            SU_TO_ROOT_X=kde4su
          fi;
        fi;
      elif which kdesu >/dev/null 2>&1 ; then
        SU_TO_ROOT_X=kdesu
      elif test -x /usr/lib/kde4/libexec/kdesu ; then
        SU_TO_ROOT_X=kde4su
      elif which ktsuss >/dev/null 2>&1 ; then
        SU_TO_ROOT_X=ktsuss
      elif which sux >/dev/null 2>&1 ; then
        SU_TO_ROOT_X=sux
      else
        SU_TO_ROOT_X=su-to-root
      fi
    fi
    case $SU_TO_ROOT_X in
      gksu) gksu -u "$PRIV" "$@";;
      gksudo) gksudo -u "$PRIV" "$@";;
      kdesu) kdesu -u "$PRIV" "$@";;
      kdesudo) kdesudo -u "$PRIV" "$@";;
      kde4su) /usr/lib/kde4/libexec/kdesu -u "$PRIV" "$@";;
      ktsuss) ktsuss -u "$PRIV" "$@";;
      sux) env SU_TO_ROOT_SU=sux \
        x-terminal-emulator -e su-to-root -p "$PRIV" -c "$@";;
  # As a last resort, open a new x-terminal-emulator and prompt for the password
  # Do not use -X here!
      *) x-terminal-emulator -e su-to-root -p "$PRIV" -c "$@";;
    esac;;
  esac
fi
Copyright (C) 1996-2003  Joost Witteveen, 
Modifications:
Copyright (C) 2002-2005  Bill Allombert and Morten Brix Pedersen.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License with
  the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL;
  if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
  Floor, Boston, MA 02110-1301, USA.

Sent to Bill by private e-mail for review.

upstream:

git clone  https://anonscm.debian.org/git/menu/menu.git

branch:
https://github.com/adrelanos/menu/tree/parameter_passing

commit (no changes):
https://github.com/adrelanos/menu/commit/8c46f20ad8688fbb4864ce0ad8eb3fa58724350d

test results:

## Untested - sux is not available in Debian jessie/sid.
SU_TO_ROOT_SU=sux su-to-root -p root -c "date +%s"

## Functional in Debian jessie.
SU_TO_ROOT_SU=sudo su-to-root -p root -c "date +%s"

## Functional in Debian jessie.
SU_TO_ROOT_SU=su su-to-root -p root -c "date +%s"

## Functional in Debian jessie.
SU_TO_ROOT_X=gksu su-to-root -X -p root -c "dolphin /usr"

## Functional in Debian jessie.
SU_TO_ROOT_X=gksudo su-to-root -X -p root -c "dolphin /usr"

## Functional in Debian jessie.
SU_TO_ROOT_X=kdesudo su-to-root -X -p root -c "dolphin /usr"

## Untested - sux is not available in Debian jessie/sid.
SU_TO_ROOT_X=sux su-to-root -X -p root -c "dolphin /usr"

Sent to Bill by private e-mail for review.

Bill just explained something to me. My conclusion from it... What currently works in jessie as is without any patch required:

su-to-root -c 'whonix-setup-wizard setup'

It would still be desirable to have it work without quotes.

Patrick set Impact to Normal.
Patrick added a subscriber: HulaHoop.