Light-weight replacement for sudo
I posted a couple of days ago, taken out the 'sudo' package and just using 'su':
https://bkhome.org/news/202306/goodbye-sudo-package.html
On reflection, that has various limitations and potential issues, so had a rethink and came up with something else, that does not use 'su'. Starting from the beginning, a script, say /usr/sbin/bootmanager now has this at the beginning:
if [ "$(whoami)" != "root" ];then
if [ -x /usr/bin/sudo-sh ];then
exec sudo-sh ${PPID} ${0} ${@}
else
exec sudo -A ${0} ${@}
fi
fi
This checks for the existence of a binary executable, /usr/bin/sudo-sh and if exists will use it install of the normal sudo. 'sudo-sh' is a wrapper for a script, /usr/bin/sudo.sh. I got the idea from reading the posts here:
https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts
I came up with what looks like a secure way to run a script, 'sudo.sh'. This is the binary executable, /usr/bin/sudo-sh:
//wrapper to run sudo.sh, see /usr/sbin/bootmanager example.
//sudo-sh must be root:root 4711 (setuid). sudo.sh root:root 0700
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[], char *envp[]) {
setuid(0);
//execv("/usr/bin/sudo.sh",argv);
//the above works, but maybe, very maybe, a security weakness:
// https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts
//so do it this way, run the ash interpreter here...
//also, don't pass envp...
extern char **environ;
char *lang;
lang=getenv("LANG");
char langenv[] = "LANG=";
strcat(langenv,lang);
char *display;
display=getenv("DISPLAY");
char displayenv[] = "DISPLAY=";
strcat(displayenv,display);
char *envp2[] = { displayenv,
"XDG_CACHE_HOME=/root/.cache",
"XDG_CONFIG_DIRS=/etc/xdg",
"XDG_CONFIG_HOME=/root/.config",
"XDG_DATA_DIRS=/usr/share:/usr/local/share",
"XDG_DATA_HOME=/root/.local/share",
"XLIB_SKIP_ARGB_VISUALS=1",
"QT5DIR=/usr",
"QT_QPA_PLATFORMTHEME=gtk2",
"QT_XFT=true",
"RGBDEF=/usr/share/X11/rgb.txt",
"SHELL=/bin/bash",
"PULSE_RUNTIME_PATH=/run/pulse",
"PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin",
"OSTYPE=linux-gnu",
"MOZILLA_FIVE_HOME=/usr/lib/seamonkey",
"MOZ_DISABLE_PANGO=1",
"MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins",
"NO_AT_BRIDGE=1",
"OOO_FORCE_DESKTOP=gnome",
"LS_COLORS=bd=33:cd=33",
"LIBASOUND_THREAD_SAFE=0",
"INPUTRC=/etc/inputrc",
"GTK2_RC_FILES=/root/.gtkrc-2.0",
"G_FILENAME_ENCODING=@locale",
langenv,
NULL};
//i don't know C well enough to do this for an arbitrary # of params...
//note, argv[0] has name of this script. argv[1] has pid of caller-of-caller
char binash[] = "/bin/ash";
char ash[] = "ash";
char sudosh[] = "/usr/bin/sudo.sh";
//if (argc==2) execle(binash,ash,sudosh,argv[1],(char*) NULL,envp2);
if (argc==3) execle(binash,ash,sudosh,argv[1],argv[2],(char*) NULL,envp2);
if (argc==4) execle(binash,ash,sudosh,argv[1],argv[2],argv[3],(char*) NULL,envp2);
if (argc==5) execle(binash,ash,sudosh,argv[1],argv[2],argv[3],argv[4],(char*) NULL,envp2);
if (argc==6) execle(binash,ash,sudosh,argv[1],argv[2],argv[3],argv[4],argv[5],(char*) NULL,envp2);
if (argc==7) execle(binash,ash,sudosh,argv[1],argv[2],argv[3],argv[4],argv[5],argv[6],(char*) NULL,envp2);
}
'sudo-sh' has 4711 permissions, 'sudo.sh' has 0700. The binary passes control to the script, which can be seen here:
https://github.com/bkauler/woofq/commit/4abb23e6ce56495973cd0ab8508293c09e050501
If a non-root app tries to run 'bootmanager', this window will popup:
...the help button explains how permission to run bootmanager without password can be reverted, if you change your mind.
This is pretty neat. The default is to always ask for a password.
Another example is the /usr/bin/xdg-open script -- if a non-root
app tries to run it, that window will pop up.
An interesting point about xdg-open. If it is used to open the
browser, administrator password is requested; however, the browser
itself will still run non-root. Chromium as user
'chromium.
Tags: easy