summaryrefslogtreecommitdiffstats
path: root/src/VBox/Installer/linux/runasroot.sh
blob: 5af497d51607b7c18a2955beb9a6a95ae1e196a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/bin/sh
# $Id: runasroot.sh $
## @file
# VirtualBox privileged execution helper script for Linux and Solaris
#

#
# Copyright (C) 2009-2023 Oracle and/or its affiliates.
#
# This file is part of VirtualBox base platform packages, as
# available from https://www.virtualbox.org.
#
# 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, in version 3 of the
# License.
#
# 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
# along with this program; if not, see <https://www.gnu.org/licenses>.
#
# SPDX-License-Identifier: GPL-3.0-only
#

# Deal with differing "which" semantics
mywhich() {
    which "$1" 2>/dev/null | grep -v "no $1"
}

# Get the name and execute switch for a useful terminal emulator
#
# Sets $gxtpath to the emulator path or empty
# Sets $gxttitle to the "title" switch for that emulator
# Sets $gxtexec to the "execute" switch for that emulator
# May clobber $gtx*
# Calls mywhich
getxterm() {
    # gnome-terminal uses -e differently to other emulators
    for gxti in "konsole --title -e" "gnome-terminal --title -x" "xterm -T -e"; do
        set $gxti
        gxtpath="`mywhich $1`"
        case "$gxtpath" in ?*)
            gxttitle=$2
            gxtexec=$3
            return
            ;;
        esac
    done
}

# Quotes its argument by inserting '\' in front of every character save
# for 'A-Za-z0-9/'.  Prints the result to stdout.
quotify() {
    echo "$1" | sed -e 's/\([^a-zA-Z0-9/]\)/\\\1/g'
}

ostype=`uname -s`
if test "$ostype" != "Linux" && test "$ostype" != "SunOS" ; then
  echo "Linux/Solaris not detected."
  exit 1
fi

HAS_TERMINAL=""
case "$1" in "--has-terminal")
    shift
    HAS_TERMINAL="yes"
    ;;
esac

case "$#" in "2"|"3")
    ;;
    *)
    echo "Usage: `basename $0` DESCRIPTION COMMAND [ADVICE]" >&2
    echo >&2
    echo "Attempt to execute COMMAND with root privileges, displaying DESCRIPTION if" >&2
    echo "possible and displaying ADVICE if possible if no su(1)-like tool is available." >&2
    exit 1
    ;;
esac

DESCRIPTION=$1
COMMAND=$2
ADVICE=$3
PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/X11/bin

case "$ostype" in SunOS)
    PATH=$PATH:/usr/sfw/bin:/usr/gnu/bin:/usr/xpg4/bin:/usr/xpg6/bin:/usr/openwin/bin:/usr/ucb
    GKSU_SWITCHES="-au root"
    ;;
    *)
    GKSU_SWITCHES=""
    ;;
esac

case "$HAS_TERMINAL" in "")
    case "$DISPLAY" in ?*)
        KDESUDO="`mywhich kdesudo`"
        case "$KDESUDO" in ?*)
            eval "`quotify "$KDESUDO"` --comment `quotify "$DESCRIPTION"` -- $COMMAND"
            exit
            ;;
        esac

        KDESU="`mywhich kdesu`"
        case "$KDESU" in ?*)
            "$KDESU" -c "$COMMAND"
            exit
            ;;
        esac

        GKSU="`mywhich gksu`"
        case "$GKSU" in ?*)
            # Older gksu does not grok --description nor '--' and multiple args.
            # @todo which versions do?
            # "$GKSU" --description "$DESCRIPTION" -- "$@"
            # Note that $GKSU_SWITCHES is NOT quoted in the following
            "$GKSU" $GKSU_SWITCHES "$COMMAND"
            exit
            ;;
        esac
        ;;
    esac # $DISPLAY
    ;;
esac # ! $HAS_TERMINAL

# pkexec may work for ssh console sessions as well if the right agents
# are installed.  However it is very generic and does not allow for any
# custom messages.  Thus it comes after gksu.
## @todo should we insist on either a display or a terminal?
# case "$DISPLAY$HAS_TERMINAL" in ?*)
PKEXEC="`mywhich pkexec`"
case "$PKEXEC" in ?*)
    eval "\"$PKEXEC\" $COMMAND"
    exit
    ;;
esac
#    ;;S
#esac

case "$HAS_TERMINAL" in ?*)
        USE_SUDO=
        grep -q Ubuntu /etc/lsb-release 2>/dev/null && USE_SUDO=true
        # On Ubuntu we need sudo instead of su.  Assume this works, and is only
        # needed for Ubuntu until proven wrong.
        case $USE_SUDO in true)
            SUDO_COMMAND="`quotify "$SUDO"` -- $COMMAND"
            eval "$SUDO_COMMAND"
            exit
            ;;
        esac

    SU="`mywhich su`"
    case "$SU" in ?*)
        "$SU" - root -c "$COMMAND"
        exit
        ;;
    esac
    ;;
esac

# The ultimate fallback is running 'su -' within an xterm.  We use the
# title of the xterm to tell what is going on.
case "$DISPLAY" in ?*)
    SU="`mywhich su`"
    case "$SU" in ?*)
        getxterm
        case "$gxtpath" in ?*)
            "$gxtpath" "$gxttitle" "$DESCRIPTION - su" "$gxtexec" su - root -c "$COMMAND"
            exit
            ;;
        esac
    esac
esac # $DISPLAY

# Failure...
case "$DISPLAY" in ?*)
    echo "Unable to locate 'pkexec', 'gksu' or 'su+xterm'. $ADVICE" >&2
    ;;
    *)
    echo "Unable to locate 'pkexec'. $ADVICE" >&2
    ;;
esac

exit 1