1 |
#!/bin/sh |
2 |
#--------------------------------------------- |
3 |
# xdg-su |
4 |
# |
5 |
# Utility script to run a command as an alternate user, generally |
6 |
# the root user, with a graphical prompt for the root |
7 |
# password if needed |
8 |
# |
9 |
# Refer to the usage() function below for usage. |
10 |
# |
11 |
# Copyright 2006, Jeremy White <jwhite@codeweavers.com> |
12 |
# Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at> |
13 |
# Copyright 2009, Aurelien Lefebvre <alefebvre@mandriva.com> |
14 |
# |
15 |
# LICENSE: |
16 |
# |
17 |
# Permission is hereby granted, free of charge, to any person obtaining a |
18 |
# copy of this software and associated documentation files (the "Software"), |
19 |
# to deal in the Software without restriction, including without limitation |
20 |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
21 |
# and/or sell copies of the Software, and to permit persons to whom the |
22 |
# Software is furnished to do so, subject to the following conditions: |
23 |
# |
24 |
# The above copyright notice and this permission notice shall be included |
25 |
# in all copies or substantial portions of the Software. |
26 |
# |
27 |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
28 |
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
29 |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
30 |
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
31 |
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
32 |
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
33 |
# OTHER DEALINGS IN THE SOFTWARE. |
34 |
# |
35 |
#--------------------------------------------- |
36 |
|
37 |
distrib=`test -f /etc/lsb-release && |
38 |
cat /etc/lsb-release | |
39 |
grep "DISTRIB_ID" | |
40 |
sed 's/DISTRIB_ID=\([A-Za-z]\+\)/\1/'` |
41 |
if [ -z $distrib ]; then |
42 |
distrib="Unknown" |
43 |
fi |
44 |
|
45 |
|
46 |
manualpage() |
47 |
{ |
48 |
cat << _MANUALPAGE |
49 |
Name |
50 |
|
51 |
xdg-su - run a GUI program as root after prompting for the root password |
52 |
|
53 |
Synopsis |
54 |
|
55 |
xdg-su [-u user] -c command |
56 |
|
57 |
xdg-su { --help | --manual | --version } |
58 |
|
59 |
Description |
60 |
|
61 |
xdg-su provides a graphical dialog that prompts the user for a password to run |
62 |
command as user or as root if no user was specified. |
63 |
|
64 |
xdg-su is for use inside a desktop session only. |
65 |
|
66 |
xdg-su discards any stdout and stderr output from command. |
67 |
|
68 |
Options |
69 |
|
70 |
-u user |
71 |
run command as user. The default is to run as root. |
72 |
--help |
73 |
Show command synopsis. |
74 |
--manual |
75 |
Show this manualpage. |
76 |
--version |
77 |
Show the xdg-utils version information. |
78 |
|
79 |
Exit Codes |
80 |
|
81 |
An exit code of 0 indicates success while a non-zero exit code indicates |
82 |
failure. The following failure codes can be returned: |
83 |
|
84 |
1 |
85 |
Error in command line syntax. |
86 |
2 |
87 |
One of the files passed on the command line did not exist. |
88 |
3 |
89 |
A required tool could not be found. |
90 |
4 |
91 |
The action failed. |
92 |
|
93 |
See Also |
94 |
|
95 |
su(1) |
96 |
|
97 |
Examples |
98 |
|
99 |
xdg-su -u root -c "/opt/shinythings/bin/install-GUI --install fast" |
100 |
|
101 |
Runs the /opt/shinythings/bin/install-GUI command with root permissions. |
102 |
|
103 |
_MANUALPAGE |
104 |
} |
105 |
|
106 |
usage() |
107 |
{ |
108 |
cat << _USAGE |
109 |
xdg-su - run a GUI program as root after prompting for the root password |
110 |
|
111 |
Synopsis |
112 |
|
113 |
xdg-su [-u user] -c command |
114 |
|
115 |
xdg-su { --help | --manual | --version } |
116 |
|
117 |
_USAGE |
118 |
} |
119 |
|
120 |
#@xdg-utils-common@ |
121 |
|
122 |
#---------------------------------------------------------------------------- |
123 |
# Common utility functions included in all XDG wrapper scripts |
124 |
#---------------------------------------------------------------------------- |
125 |
|
126 |
DEBUG() |
127 |
{ |
128 |
[ ${XDG_UTILS_DEBUG_LEVEL-0} -lt $1 ] && return 0; |
129 |
shift |
130 |
echo "$@" >&2 |
131 |
} |
132 |
|
133 |
#------------------------------------------------------------- |
134 |
# Exit script on successfully completing the desired operation |
135 |
|
136 |
exit_success() |
137 |
{ |
138 |
if [ $# -gt 0 ]; then |
139 |
echo "$@" |
140 |
echo |
141 |
fi |
142 |
|
143 |
exit 0 |
144 |
} |
145 |
|
146 |
|
147 |
#----------------------------------------- |
148 |
# Exit script on malformed arguments, not enough arguments |
149 |
# or missing required option. |
150 |
# prints usage information |
151 |
|
152 |
exit_failure_syntax() |
153 |
{ |
154 |
if [ $# -gt 0 ]; then |
155 |
echo "xdg-su: $@" >&2 |
156 |
echo "Try 'xdg-su --help' for more information." >&2 |
157 |
else |
158 |
usage |
159 |
echo "Use 'man xdg-su' or 'xdg-su --manual' for additional info." |
160 |
fi |
161 |
|
162 |
exit 1 |
163 |
} |
164 |
|
165 |
#------------------------------------------------------------- |
166 |
# Exit script on missing file specified on command line |
167 |
|
168 |
exit_failure_file_missing() |
169 |
{ |
170 |
if [ $# -gt 0 ]; then |
171 |
echo "xdg-su: $@" >&2 |
172 |
fi |
173 |
|
174 |
exit 2 |
175 |
} |
176 |
|
177 |
#------------------------------------------------------------- |
178 |
# Exit script on failure to locate necessary tool applications |
179 |
|
180 |
exit_failure_operation_impossible() |
181 |
{ |
182 |
if [ $# -gt 0 ]; then |
183 |
echo "xdg-su: $@" >&2 |
184 |
fi |
185 |
|
186 |
exit 3 |
187 |
} |
188 |
|
189 |
#------------------------------------------------------------- |
190 |
# Exit script on failure returned by a tool application |
191 |
|
192 |
exit_failure_operation_failed() |
193 |
{ |
194 |
if [ $# -gt 0 ]; then |
195 |
echo "xdg-su: $@" >&2 |
196 |
fi |
197 |
|
198 |
exit 4 |
199 |
} |
200 |
|
201 |
#------------------------------------------------------------ |
202 |
# Exit script on insufficient permission to read a specified file |
203 |
|
204 |
exit_failure_file_permission_read() |
205 |
{ |
206 |
if [ $# -gt 0 ]; then |
207 |
echo "xdg-su: $@" >&2 |
208 |
fi |
209 |
|
210 |
exit 5 |
211 |
} |
212 |
|
213 |
#------------------------------------------------------------ |
214 |
# Exit script on insufficient permission to read a specified file |
215 |
|
216 |
exit_failure_file_permission_write() |
217 |
{ |
218 |
if [ $# -gt 0 ]; then |
219 |
echo "xdg-su: $@" >&2 |
220 |
fi |
221 |
|
222 |
exit 6 |
223 |
} |
224 |
|
225 |
check_input_file() |
226 |
{ |
227 |
if [ ! -e "$1" ]; then |
228 |
exit_failure_file_missing "file '$1' does not exist" |
229 |
fi |
230 |
if [ ! -r "$1" ]; then |
231 |
exit_failure_file_permission_read "no permission to read file '$1'" |
232 |
fi |
233 |
} |
234 |
|
235 |
check_vendor_prefix() |
236 |
{ |
237 |
file=`basename "$1"` |
238 |
case "$file" in |
239 |
[a-zA-Z]*-*) |
240 |
return |
241 |
;; |
242 |
esac |
243 |
|
244 |
echo "xdg-su: filename '$file' does not have a proper vendor prefix" >&2 |
245 |
echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 |
246 |
echo 'with a dash ("-"). An example filename is '"'example-$file'" >&2 |
247 |
echo "Use --novendor to override or 'xdg-su --manual' for additional info." >&2 |
248 |
exit 1 |
249 |
} |
250 |
|
251 |
check_output_file() |
252 |
{ |
253 |
# if the file exists, check if it is writeable |
254 |
# if it does not exists, check if we are allowed to write on the directory |
255 |
if [ -e "$1" ]; then |
256 |
if [ ! -w "$1" ]; then |
257 |
exit_failure_file_permission_write "no permission to write to file '$1'" |
258 |
fi |
259 |
else |
260 |
DIR=`dirname "$1"` |
261 |
if [ ! -w "$DIR" -o ! -x "$DIR" ]; then |
262 |
exit_failure_file_permission_write "no permission to create file '$1'" |
263 |
fi |
264 |
fi |
265 |
} |
266 |
|
267 |
#---------------------------------------- |
268 |
# Checks for shared commands, e.g. --help |
269 |
|
270 |
check_common_commands() |
271 |
{ |
272 |
while [ $# -gt 0 ] ; do |
273 |
parm="$1" |
274 |
shift |
275 |
|
276 |
case "$parm" in |
277 |
--help) |
278 |
usage |
279 |
echo "Use 'man xdg-su' or 'xdg-su --manual' for additional info." |
280 |
exit_success |
281 |
;; |
282 |
|
283 |
--manual) |
284 |
manualpage |
285 |
exit_success |
286 |
;; |
287 |
|
288 |
--version) |
289 |
echo "xdg-su 1.0beta2" |
290 |
exit_success |
291 |
;; |
292 |
esac |
293 |
done |
294 |
} |
295 |
|
296 |
check_common_commands "$@" |
297 |
if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then |
298 |
# Be silent |
299 |
xdg_redirect_output=" > /dev/null 2> /dev/null" |
300 |
else |
301 |
# All output to stderr |
302 |
xdg_redirect_output=" >&2" |
303 |
fi |
304 |
|
305 |
#-------------------------------------- |
306 |
# Checks for known desktop environments |
307 |
# set variable DE to the desktop environments name, lowercase |
308 |
|
309 |
detectDE() |
310 |
{ |
311 |
if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; |
312 |
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; |
313 |
elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; |
314 |
fi |
315 |
} |
316 |
|
317 |
#---------------------------------------------------------------------------- |
318 |
|
319 |
|
320 |
|
321 |
su_kde() |
322 |
{ |
323 |
if [ x"$KDE_SESSION_VERSION" = x"4" ]; then |
324 |
KDESU=`kde4-config --locate kdesu --path exe 2>/dev/null` |
325 |
else |
326 |
KDESU=`which kdesu 2>/dev/null` |
327 |
if [ $? -ne 0 -a $distrib = "Ubuntu" ] ; then |
328 |
KDESU=`which kdesudo 2>/dev/null` |
329 |
fi |
330 |
fi |
331 |
if [ $? -eq 0 ] ; then |
332 |
if [ -z "$user" ] ; then |
333 |
if [ $distrib = "Ubuntu" ]; then |
334 |
/usr/bin/kdesudo "$cmd" |
335 |
else |
336 |
$KDESU -c "$cmd" |
337 |
fi |
338 |
else |
339 |
if [ $distrib = "Ubuntu" ]; then |
340 |
/usr/bin/kdesudo -u "$user" "$cmd" |
341 |
else |
342 |
$KDESU -u "$user" -c "$cmd" |
343 |
fi |
344 |
fi |
345 |
|
346 |
if [ $? -eq 0 ]; then |
347 |
exit_success |
348 |
else |
349 |
exit_failure_operation_failed |
350 |
fi |
351 |
else |
352 |
su_generic |
353 |
fi |
354 |
} |
355 |
|
356 |
su_gnome() |
357 |
{ |
358 |
GSU=`which gnomesu 2>/dev/null` |
359 |
if [ $? -ne 0 ] ; then |
360 |
GSU=`which xsu 2>/dev/null` |
361 |
fi |
362 |
if [ $? -eq 0 ] ; then |
363 |
if [ -z "$user" ] ; then |
364 |
$GSU -c "$cmd" |
365 |
else |
366 |
$GSU -u "$user" -c "$cmd" |
367 |
fi |
368 |
|
369 |
if [ $? -eq 0 ]; then |
370 |
exit_success |
371 |
else |
372 |
exit_failure_operation_failed |
373 |
fi |
374 |
else |
375 |
su_generic |
376 |
fi |
377 |
} |
378 |
|
379 |
sudo_gnome() |
380 |
{ |
381 |
GSU=`which gksudo 2>/dev/null` |
382 |
if [ $? -eq 0 ] ; then |
383 |
if [ -z "$user" ] ; then |
384 |
$GSU "$cmd" |
385 |
else |
386 |
$GSU -u "$user" "$cmd" |
387 |
fi |
388 |
|
389 |
if [ $? -eq 0 ]; then |
390 |
exit_success |
391 |
else |
392 |
exit_failure_operation_failed |
393 |
fi |
394 |
else |
395 |
su_generic |
396 |
fi |
397 |
} |
398 |
|
399 |
sudo_kde() |
400 |
{ |
401 |
GSU=`which kdesudo 2>/dev/null` |
402 |
if [ $? -eq 0 ] ; then |
403 |
if [ -z "$user" ] ; then |
404 |
$GSU "$cmd" |
405 |
else |
406 |
$GSU -u "$user" "$cmd" |
407 |
fi |
408 |
|
409 |
if [ $? -eq 0 ]; then |
410 |
exit_success |
411 |
else |
412 |
exit_failure_operation_failed |
413 |
fi |
414 |
else |
415 |
su_generic |
416 |
fi |
417 |
} |
418 |
|
419 |
su_generic() |
420 |
{ |
421 |
|
422 |
QUOTE=1 |
423 |
TERMINAL="" |
424 |
[ -z "$TERMINAL" ] && TERMINAL=`which xterm 2> /dev/null` && QUOTE=0 |
425 |
[ -z "$TERMINAL" ] && TERMINAL=`which gnome-terminal 2> /dev/null` |
426 |
#[ -z "$TERMINAL" ] && TERMINAL=`which konsole 2> /dev/null` |
427 |
[ -z "$TERMINAL" ] && TERMINAL=`which aterm 2> /dev/null` && QUOTE=0 |
428 |
[ -z "$TERMINAL" ] && TERMINAL=`which Eterm 2> /dev/null` |
429 |
[ -z "$TERMINAL" ] && TERMINAL=`which kterm 2> /dev/null` && QUOTE=0 |
430 |
[ -z "$TERMINAL" ] && TERMINAL=`which lxterminal 2> /dev/null` |
431 |
|
432 |
if [ $distrib = "Ubuntu" ]; then |
433 |
if [ $QUOTE -eq 1 ]; then |
434 |
$TERMINAL -e "sudo $cmd" |
435 |
else |
436 |
$TERMINAL -e sudo "$cmd" |
437 |
fi |
438 |
else |
439 |
if [ $QUOTE -eq 1 ]; then |
440 |
$TERMINAL -e "su -c \"$cmd\"" |
441 |
else |
442 |
$TERMINAL -e su -c "$cmd" |
443 |
fi |
444 |
fi |
445 |
|
446 |
if [ $? -eq 0 ]; then |
447 |
exit_success |
448 |
else |
449 |
exit_failure_operation_failed |
450 |
fi |
451 |
} |
452 |
|
453 |
[ x"$1" != x"" ] || exit_failure_syntax |
454 |
|
455 |
user= |
456 |
cmd= |
457 |
while [ $# -gt 0 ] ; do |
458 |
parm="$1" |
459 |
shift |
460 |
|
461 |
case "$parm" in |
462 |
-u) |
463 |
if [ -z "$1" ] ; then |
464 |
exit_failure_syntax "user argument missing for -u" |
465 |
fi |
466 |
user="$1" |
467 |
shift |
468 |
;; |
469 |
|
470 |
-c) |
471 |
if [ -z "$1" ] ; then |
472 |
exit_failure_syntax "command argument missing for -c" |
473 |
fi |
474 |
cmd="$1" |
475 |
shift |
476 |
;; |
477 |
|
478 |
-*) |
479 |
exit_failure_syntax "unexpected option '$parm'" |
480 |
;; |
481 |
|
482 |
*) |
483 |
exit_failure_syntax "unexpected argument '$parm'" |
484 |
;; |
485 |
esac |
486 |
done |
487 |
|
488 |
if [ -z "${cmd}" ] ; then |
489 |
exit_failure_syntax "command missing" |
490 |
fi |
491 |
|
492 |
detectDE |
493 |
|
494 |
if [ x"$DE" = x"" ]; then |
495 |
DE=generic |
496 |
fi |
497 |
|
498 |
case "$DE" in |
499 |
kde) |
500 |
if [ $distrib = "Ubuntu" ]; then |
501 |
sudo_kde |
502 |
else |
503 |
su_kde |
504 |
fi |
505 |
;; |
506 |
|
507 |
gnome) |
508 |
if [ $distrib = "Ubuntu" ]; then |
509 |
sudo_gnome |
510 |
else |
511 |
su_gnome |
512 |
fi |
513 |
;; |
514 |
|
515 |
generic) |
516 |
su_generic |
517 |
;; |
518 |
|
519 |
*) |
520 |
[ x"$user" = x"" ] && user=root |
521 |
exit_failure_operation_impossible "no graphical method available for invoking '$cmd' as '$user'" |
522 |
;; |
523 |
esac |