Exclude user from using systemwide installed programs
I recently created a new user. I want to allow this user to use only one or two programs, but I have lots of systemwide installed apps. Is there an easy way to exclude a specific user from using apps (without reinstalling everything again)?
Below a combination of measures you can take, to restrict users locally from using defined applications. They are not meant (nor fit) for unattended usage, in public spaces for example, but do create a usable restricted desktop. It is mainly the combination of measures that makes it more difficult to bypass. Furthermore if someone manages to launch a "forbidden" application, it will be logged.
The answer is a bit extensive. The setup is not, and you are assisted by two scripts.
What the setup exists of
- A selection of software, made unavailable from the interface by editing their local desktop file by a script (further below)
- Making the terminal only available via password, so running applications from the terminal is made more difficult.
- Changing the default keycombination of opening the terminal, instead of ctrlaltt
- Logging the usage of a "blacklist" of software you define, in case some smart user might surpass your setup
How to setup
Setting up a broad selection of software, unavailable from the interface.
- Log in, to the user account you want to restrict
- Make a (temporary) folder (no matter where, on the desktop for example) to edit some files.
- Browse into the directory
/usr/share/applications
Select all (desktop files of) applications you want the user to be excluded from (don't select all of them without looking, some of them are necessary to set up your desktop) - Copy these desktop files into the temporary directory you created, for bulk-editing.
- Copy the text below, paste it into an empty file, save it in the same temporary folder as
no_openapp.py
. - CD into the directory(!) and run it with the command:
python3 no_openapp.py
.
The script did a few things:
1] Create a blacklist of commands (for later use, see further below) 2] Edit the desktop files to show a message instead of running the application. If you move the desktop files to ~/.local/share/applications
, on next login the applications will not run from Unity or Dash.
#!/usr/bin/python3
import os
import getpass
import subprocess
desktopfile_dir = os.getcwd()
file_list = os.listdir(os.getcwd())
edit_subjects = [desktopfile_dir+"/"+item for item in file_list]
def create_blacklist():
command_list = []
for item in edit_subjects:
with open(item) as blacklist_source:
searchlines = blacklist_source.readlines()
try:
native_command = [
line for line in searchlines if line.startswith("Exec=")
][0].replace("Exec=", "").replace("\n", "")
cleaned_command = native_command.split(" ")[0]
command_list.append(cleaned_command)
except IndexError:
pass
with open(desktopfile_dir+"/blacklist.txt", "wt") as created_blacklist:
created_blacklist.write(str(command_list))
def make_unavailable():
for item in edit_subjects:
try:
with open(item, "r") as make_unav:
lines = make_unav.readlines()
line_range = range(0, len(lines))
for index in line_range:
if lines[index].startswith("Exec="):
lines[index] = 'Exec=zenity --info --text="You are not allowed to use this application"\n'
else:
pass
with open(item, "wt") as make_unav:
for line in lines:
make_unav.write(line)
except (IsADirectoryError, IndexError, PermissionError):
pass
create_blacklist()
make_unavailable()
Restrict the use of the terminal
- make the terminal accesible with a password, like in this post.
-
if the user is familiar with the key combination of ctrlaltt, change the default combination:
System>Preferences>Keyboard Shortcuts > key combinations (tab).
In case you have a wizzkid bypass your measures, catch him
- In case a user manages to get a forbidden application running, make sure you catch him. for this, we use the blacklist, created in step one.
- create a folder on a hidden location. Copy the "blacklist.txt", created in step one to the directory.
- copy the text below, paste it into an empty textfile and save it to the same directory as the blacklist, as
processes.py
. -
open a terminal window, type
crontab -e
. add the following line to the crontab file:* * * * * cd /path/to/script; python3 processes.py
The blacklist is a list of process names. The script checks every minute if one of the black-listed applications is running, and keeps record in a log file (in the same directory as where the script is located). The name of the log file is log.txt. Optionally, you can make the script kill the forbidden application (not the default). To make it kill the application(s), change the line kill_apps = "no"
into kill_apps = "yes"
(in the head section of the sript).
#!/usr/bin/python3
import os
import datetime
import subprocess
import getpass
curr_dir = os.getcwd()
curruser = getpass.getuser()
# should forbidden applications be killed?
kill_apps = "yes"
def produce_commands_ofapp():
with open(curr_dir+"/blacklist.txt", "r") as blacklist:
blacklist = eval(blacklist.read())
return blacklist
def createlist_runningprocs():
processesb = subprocess.Popen(["ps", "-u", curruser], stdout=subprocess.PIPE)
process_listb = (processesb.communicate()[0].decode("utf-8")).split("\n")
return process_listb
def runsornot():
check_blacklist = produce_commands_ofapp()
runningprocs_list = createlist_runningprocs()
found_matches = [item for item in check_blacklist
if item[:15] in str(runningprocs_list)]
if len(found_matches) != 0:
with open(curr_dir+"/log.txt", "a+") as logfile:
logfile.write(str(found_matches)+" "+str(datetime.datetime.now())+"\n")
else:
pass
if kill_apps == "yes":
for application in found_matches:
kill_forbidden(application)
else:
pass
def kill_forbidden(app_command):
# get the pid length of system
get_size = subprocess.Popen(
["cat", "/proc/sys/kernel/pid_max"],
stdout=subprocess.PIPE
)
size = len((get_size.communicate()[0].decode("utf-8")).replace("\n", ""))
# get the appropriate pid line & pid
process_list = createlist_runningprocs()
appr_pid = [
line for line in process_list if \
app_command[:15] in line][0][:size+1].replace(" ", "")
# kill the found process
subprocess.Popen(["kill", "-9", appr_pid])
runsornot()
As said, the setup can be bypassed. However, the combination of measures, and the fact that you have to know what they are, make it a reasonable defence in case of an avarage usere with an average knowledge on how to manipulate the system.
Thanks for your answers. I have reached this already by manipulating the permissions of the programs bin-files. I installed the old gnome user-administration tool, which allows to manage groups. Unchecked group games for the user, which is not allowed to open certain programs. Then changed group and permissions of the bin-files:
sudo chgrp games /path/to/game
sudo chmod 750 /path/to/game
Now the user can see the desktop files in the Dash, but they won't run after click.
Greetings