summaryrefslogtreecommitdiff
path: root/src/conf_mode/system-login.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/system-login.py')
-rwxr-xr-xsrc/conf_mode/system-login.py102
1 files changed, 51 insertions, 51 deletions
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index 23152fee0..43732cfae 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -14,36 +14,22 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import sys
import os
-import jinja2
+from jinja2 import FileSystemLoader, Environment
+from psutil import users
from pwd import getpwall, getpwnam
from stat import S_IRUSR, S_IWUSR, S_IRWXU, S_IRGRP, S_IXGRP
-from subprocess import Popen, PIPE, STDOUT
-from psutil import users
+from sys import exit
from vyos.config import Config
from vyos.configdict import list_diff
+from vyos.defaults import directories as vyos_data_dir
from vyos import ConfigError
+from vyos.util import cmd
+from vyos.util import call
radius_config_file = "/etc/pam_radius_auth.conf"
-radius_config_tmpl = """
-# Automatically generated by VyOS
-# RADIUS configuration file
-{%- if radius_server %}
-# server[:port] shared_secret timeout (s) source_ip
-{% for s in radius_server %}
-{%- if not s.disabled -%}
-{{ s.address }}:{{ s.port }} {{ s.key }} {{ s.timeout }} {% if radius_source_address -%}{{ radius_source_address }}{% endif %}
-{% endif %}
-{%- endfor %}
-
-priv-lvl 15
-mapped_priv_user radius_priv_user
-{% endif %}
-
-"""
default_config_data = {
'deleted': False,
@@ -67,10 +53,7 @@ def get_local_users():
def get_crypt_pw(password):
- command = '/usr/bin/mkpasswd --method=sha-512 {}'.format(password)
- p = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True)
- tmp = p.communicate()[0].strip()
- return tmp.decode()
+ return cmd(f'/usr/bin/mkpasswd --method=sha-512 {password}')
def get_config():
@@ -196,6 +179,14 @@ def verify(login):
if cur_user in login['del_users']:
raise ConfigError('Attempting to delete current user: {}'.format(cur_user))
+ for user in login['add_users']:
+ for key in user['public_keys']:
+ if not key['type']:
+ raise ConfigError('SSH public key type missing for "{}"!'.format(key['name']))
+
+ if not key['key']:
+ raise ConfigError('SSH public key for id "{}" missing!'.format(key['name']))
+
# At lease one RADIUS server must not be disabled
if len(login['radius_server']) > 0:
fail = True
@@ -221,7 +212,12 @@ def generate(login):
os.system("vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_set system login user '{}' authentication encrypted-password '{}' >/dev/null".format(user['name'], user['password_encrypted']))
if len(login['radius_server']) > 0:
- tmpl = jinja2.Template(radius_config_tmpl)
+ # Prepare Jinja2 template loader from files
+ tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'system-login')
+ fs_loader = FileSystemLoader(tmpl_path)
+ env = Environment(loader=fs_loader)
+
+ tmpl = env.get_template('pam_radius_auth.conf.tmpl')
config_text = tmpl.render(login)
with open(radius_config_file, 'w') as f:
f.write(config_text)
@@ -240,40 +236,44 @@ def apply(login):
for user in login['add_users']:
# make new user using vyatta shell and make home directory (-m),
# default group of 100 (users)
- cmd = "useradd -m -N"
+ command = "useradd -m -N"
# check if user already exists:
if user['name'] in get_local_users():
# update existing account
- cmd = "usermod"
+ command = "usermod"
# we need to use '' quotes when passing formatted data to the shell
# else it will not work as some data parts are lost in translation
- cmd += " -p '{}'".format(user['password_encrypted'])
- cmd += " -s /bin/vbash"
+ command += " -p '{}'".format(user['password_encrypted'])
+ command += " -s /bin/vbash"
if user['full_name']:
- cmd += " -c '{}'".format(user['full_name'])
+ command += " -c '{}'".format(user['full_name'])
if user['home_dir']:
- cmd += " -d '{}'".format(user['home_dir'])
+ command += " -d '{}'".format(user['home_dir'])
- cmd += " -G frrvty,vyattacfg,sudo,adm,dip,disk"
- cmd += " {}".format(user['name'])
+ command += " -G frrvty,vyattacfg,sudo,adm,dip,disk"
+ command += " {}".format(user['name'])
try:
- os.system(cmd)
+ call(command)
uid = getpwnam(user['name']).pw_uid
gid = getpwnam(user['name']).pw_gid
+ # we should not rely on the home dir value stored in user['home_dir']
+ # as if a crazy user will choose username root or any other system
+ # user this will fail. should be deny using root at all?
+ home_dir = getpwnam(user['name']).pw_dir
# install ssh keys
- key_dir = '{}/.ssh'.format(user['home_dir'])
- if not os.path.isdir(key_dir):
- os.mkdir(key_dir)
- os.chown(key_dir, uid, gid)
- os.chmod(key_dir, S_IRWXU | S_IRGRP | S_IXGRP)
-
- key_file = key_dir + '/authorized_keys';
- with open(key_file, 'w') as f:
+ ssh_key_dir = home_dir + '/.ssh'
+ if not os.path.isdir(ssh_key_dir):
+ os.mkdir(ssh_key_dir)
+ os.chown(ssh_key_dir, uid, gid)
+ os.chmod(ssh_key_dir, S_IRWXU | S_IRGRP | S_IXGRP)
+
+ ssh_key_file = ssh_key_dir + '/authorized_keys';
+ with open(ssh_key_file, 'w') as f:
f.write("# Automatically generated by VyOS\n")
f.write("# Do not edit, all changes will be lost\n")
@@ -285,8 +285,8 @@ def apply(login):
line += '{} {} {}\n'.format(id['type'], id['key'], id['name'])
f.write(line)
- os.chown(key_file, uid, gid)
- os.chmod(key_file, S_IRUSR | S_IWUSR)
+ os.chown(ssh_key_file, uid, gid)
+ os.chmod(ssh_key_file, S_IRUSR | S_IWUSR)
except Exception as e:
raise ConfigError('Adding user "{}" raised an exception: {}'.format(user['name'], e))
@@ -296,10 +296,10 @@ def apply(login):
# Logout user if he is logged in
if user in list(set([tmp[0] for tmp in users()])):
print('{} is logged in, forcing logout'.format(user))
- os.system('pkill -HUP -u {}'.format(user))
+ call('pkill -HUP -u {}'.format(user))
# Remove user account but leave home directory to be safe
- os.system('userdel -r {} 2>/dev/null'.format(user))
+ call('userdel -r {} 2>/dev/null'.format(user))
except Exception as e:
raise ConfigError('Deleting user "{}" raised an exception: {}'.format(user, e))
@@ -313,7 +313,7 @@ def apply(login):
os.system("DEBIAN_FRONTEND=noninteractive pam-auth-update --package --enable radius")
# Make NSS system aware of RADIUS, too
- cmd = "sed -i -e \'/\smapname/b\' \
+ command = "sed -i -e \'/\smapname/b\' \
-e \'/^passwd:/s/\s\s*/&mapuid /\' \
-e \'/^passwd:.*#/s/#.*/mapname &/\' \
-e \'/^passwd:[^#]*$/s/$/ mapname &/\' \
@@ -321,7 +321,7 @@ def apply(login):
-e \'/^group:[^#]*$/s/: */&mapname /\' \
/etc/nsswitch.conf"
- os.system(cmd)
+ call(command)
except Exception as e:
raise ConfigError('RADIUS configuration failed: {}'.format(e))
@@ -331,13 +331,13 @@ def apply(login):
# Disable RADIUS in PAM
os.system("DEBIAN_FRONTEND=noninteractive pam-auth-update --package --remove radius")
- cmd = "sed -i -e \'/^passwd:.*mapuid[ \t]/s/mapuid[ \t]//\' \
+ command = "sed -i -e \'/^passwd:.*mapuid[ \t]/s/mapuid[ \t]//\' \
-e \'/^passwd:.*[ \t]mapname/s/[ \t]mapname//\' \
-e \'/^group:.*[ \t]mapname/s/[ \t]mapname//\' \
-e \'s/[ \t]*$//\' \
/etc/nsswitch.conf"
- os.system(cmd)
+ call(command)
except Exception as e:
raise ConfigError('Removing RADIUS configuration failed'.format(e))
@@ -352,4 +352,4 @@ if __name__ == '__main__':
apply(c)
except ConfigError as e:
print(e)
- sys.exit(1)
+ exit(1)