Use classic unix users rather than systemd dynamic users

Dynamic Users are neat and probably very useful for a tmpnb
style situation. However, for regular use they have the following
problems:

1. Can't set ProtectHome=no, so you can never apt install or
   similar from inside admin accounts.
2. Dynamic uid / gid makes it hard to write sudo rules. We want
   admin users to have sudo.
3. Persistent uids / gids are very useful for ad-hoc ACLs between
   users. gid sharing isn't the most flexible sharing mechanism,
   but it is well known & quite useful.
4. /etc/skel is pretty useful!
This commit is contained in:
yuvipanda
2018-06-26 23:30:06 -07:00
parent 335ba3c8a6
commit f90a0fa540
5 changed files with 260 additions and 17 deletions

123
tljh/user.py Normal file
View File

@@ -0,0 +1,123 @@
"""
User management for tljh.
Supports user creation, deletion & sudo
"""
import pwd
import grp
import subprocess
def ensure_user(username):
"""
Make sure a given user exists
"""
# Check if user exists
try:
pwd.getpwnam(username)
# User exists, nothing to do!
return
except KeyError:
# User doesn't exist, time to create!
pass
subprocess.check_call([
'sudo',
'adduser',
'--disabled-password',
'--force-badname',
'--quiet',
username
])
def remove_user(username):
"""
Remove user from system if exists
"""
try:
pwd.getpwnam(username)
except KeyError:
# User doesn't exist, nothing to do
return
subprocess.check_call([
'sudo',
'deluser',
'--quiet',
username
])
def ensure_group(groupname):
"""
Ensure given group exists
"""
try:
grp.getgrnam(groupname)
# Group exists, nothing to do!
return
except KeyError:
pass
subprocess.check_call([
'sudo',
'addgroup',
'--quiet',
groupname
])
def remove_group(groupname):
"""
Remove user from system if exists
"""
try:
grp.getgrnam(groupname)
except KeyError:
# Group doesn't exist, nothing to do
return
subprocess.check_call([
'sudo',
'delgroup',
'--quiet',
groupname
])
def ensure_user_group(username, groupname):
"""
Ensure given user is member of given group
Group and User must already exist.
"""
group = grp.getgrnam(groupname)
if username in group.gr_mem:
return
subprocess.check_call([
'sudo',
'usermod',
'--append',
'--groups',
groupname,
username
])
def remove_user_group(username, groupname):
"""
Ensure given user is *not* a member of given group
"""
group = grp.getgrnam(groupname)
if username not in group.gr_mem:
return
subprocess.check_call([
'sudo',
'deluser',
'--quiet',
username,
groupname
])