diff --git a/README b/README index 723c7f6..1449e9b 100644 --- a/README +++ b/README @@ -30,12 +30,9 @@ For simple dev you need at least: ## Homedirs - settings.FILESERVER_HOST:~/.ssh/authorized_keys must contain the public key of settings.FILESERVER_USER - - settings.FILESERVER_USER might need some sudo access + - settings.FILESERVER_USER needs sudo access to FILESERVER_CREATE_HOMEDIR_SCRIPT # TODO - - Add management command that creates LDAP users... - - when user is in Inside group dns-aktiv - - and not in LDAP allready - Integrity check view which provides two way diffs for the following: - user vs user group - user vs kerberos principal diff --git a/neuf_kerberos/utils.py b/neuf_kerberos/utils.py index 135beec..0b1ac7f 100644 --- a/neuf_kerberos/utils.py +++ b/neuf_kerberos/utils.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) def get_kerberos_principal(username): principal = "{0}@{1}".format(username, settings.KERBEROS_REALM) kadmin_query = " -p '{0}' -w {1} -q 'get_principal {2}'".format( - settings.KERBEROS_PASSWORD_CHANGING_PRINCIPAL, + settings.KERBEROS_ADMIN_PRINCIPAL, settings.KERBEROS_PASSWORD, principal) p = Popen('kadmin' + kadmin_query, shell=True, stdout=PIPE, stderr=PIPE) @@ -37,7 +37,7 @@ def has_kerberos_principal(username): def set_kerberos_password(username, raw_password): principal = "{}@{}".format(username, settings.KERBEROS_REALM) kadmin_query = " -p {} -w {} -q 'change_password -pw {} {}'".format( - settings.KERBEROS_PASSWORD_CHANGING_PRINCIPAL, + settings.KERBEROS_ADMIN_PRINCIPAL, settings.KERBEROS_PASSWORD, raw_password, principal) @@ -59,22 +59,25 @@ def format_krb5_date(date): return formatted_date -def kerberos_create_principal(username, password): +def add_kerberos_principal(username, password, dry_run=False): principal = "{}@{}".format(username, settings.KERBEROS_REALM) kadmin_query = " -p '{}' -w {} -q 'add_principal {} -pw {}'".format( - settings.KERBEROS_PASSWORD_CHANGING_PRINCIPAL, + settings.KERBEROS_ADMIN_PRINCIPAL, settings.KERBEROS_PASSWORD, principal, password) - p = Popen('kadmin' + kadmin_query, shell=True, stdout=PIPE, stderr=PIPE) - output, error = p.communicate() - if error: - # KADM5_AUTH_ADD (requires "add" privilege) - # KADM5_BAD_MASK (shouldn't happen) - # KADM5_DUP (principal exists already) - # KADM5_UNK_POLICY (policy does not exist) - # KADM5_PASS_Q_* (password quality violations) - logger.error(error) - return False + if dry_run: + logger.debug('Kerberos principal {} added'.format(principal)) + else: + p = Popen('kadmin' + kadmin_query, shell=True, stdout=PIPE, stderr=PIPE) + output, error = p.communicate() + if error: + # KADM5_AUTH_ADD (requires "add" privilege) + # KADM5_BAD_MASK (shouldn't happen) + # KADM5_DUP (principal exists already) + # KADM5_UNK_POLICY (policy does not exist) + # KADM5_PASS_Q_* (password quality violations) + logger.error(error) + return False return True \ No newline at end of file diff --git a/neuf_ldap/utils.py b/neuf_ldap/utils.py index 37eb936..7f02498 100644 --- a/neuf_ldap/utils.py +++ b/neuf_ldap/utils.py @@ -42,7 +42,7 @@ def ldap_username_exists(username): return len(LdapUser.objects.filter(username=username)) != 0 -def ldap_create_user(user, dry_run=False): +def create_ldap_user(user, dry_run=False): from neuf_ldap.models import LdapUser, LdapGroup def _get_next_uid(): @@ -152,10 +152,14 @@ def ldap_update_user_details(inside_user, dry_run=False): ldap_user.save() -def ldap_create_automount(username): +def create_ldap_automount(username, dry_run=False): from neuf_ldap.models import LdapAutomountHome automount = LdapAutomountHome(username=username) automount.set_automount_info() - automount.save() + + if dry_run: + logger.debug('Automount {} added for user {}'.format(automount.automountInformation, username)) + else: + automount.save() return True diff --git a/neuf_radius/utils.py b/neuf_radius/utils.py index e8de51f..d045cc5 100644 --- a/neuf_radius/utils.py +++ b/neuf_radius/utils.py @@ -31,7 +31,7 @@ def set_radius_password(username, raw_password): radius_user.save() -def radius_create_user(username, password, dry_run=False): +def create_radius_user(username, password, dry_run=False): if not dry_run: set_radius_password(username, password) else: diff --git a/neuf_userinfo/management/commands/sync_active_to_ldap.py b/neuf_userinfo/management/commands/sync_active_to_ldap.py index 1984e27..39398d4 100644 --- a/neuf_userinfo/management/commands/sync_active_to_ldap.py +++ b/neuf_userinfo/management/commands/sync_active_to_ldap.py @@ -1,13 +1,12 @@ -from django.conf import settings from django.core.management.base import BaseCommand from django.db.models import Q from inside.models import InsideGroup, InsideUser from neuf_ldap.models import LdapGroup, LdapUser -from neuf_ldap.utils import ldap_create_user, ldap_update_user_details +from neuf_ldap.utils import create_ldap_user, ldap_update_user_details, create_ldap_automount from optparse import make_option -from neuf_userinfo.utils import add_new_user +from neuf_userinfo.ssh import create_home_dir ACTIVE_USERS_GROUP = 'dns-aktiv' @@ -94,7 +93,9 @@ class Command(BaseCommand): for username, user in inside_users_diffable.iteritems(): if username not in ldap_users_diffable: # Create - add_new_user(user, dry_run=self.options['dry_run']) + create_ldap_user(user, dry_run=self.options['dry_run']) + create_home_dir(user['username'], dry_run=self.options['dry_run']) + create_ldap_automount(user['username'], dry_run=self.options['dry_run']) self.COUNTS['create'] += 1 if int(self.options['verbosity']) >= 2: diff --git a/neuf_userinfo/ssh.py b/neuf_userinfo/ssh.py index 518aa4c..395cb4c 100644 --- a/neuf_userinfo/ssh.py +++ b/neuf_userinfo/ssh.py @@ -1,51 +1,30 @@ from django.conf import settings from fabric.api import settings as fab_settings -from fabric.operations import run +from fabric.operations import sudo import logging -import os logger = logging.getLogger(__name__) def create_home_dir(username, dry_run=False): """ - Create homedir for username - - Copy /etc/skel - - make user - This use fabric (SSH) for running remote commands + Create homedir for username via shell script on fileserver host - Ref: - - http://stackoverflow.com/questions/4888568/can-i-catch-error-codes-when-using-fabric-to-run-calls-in-a-remote-shell - - http://stackoverflow.com/questions/6741523/using-python-fabric-without-the-command-line-tool-fab + This use fabric (SSH) for running the remote command + + Ref: http://stackoverflow.com/questions/6741523/using-python-fabric-without-the-command-line-tool-fab """ - host = settings.FILESERVER_HOST - path = os.path.join(settings.FILESERVER_HOME_PATH, username) - host_string = '{}@{}'.format(settings.FILESERVER_USER, host) + host_string = '{}@{}'.format(settings.FILESERVER_USER, settings.FILESERVER_HOST) + path = settings.FILESERVER_HOME_PATH with fab_settings(host_string=host_string, warn_only=True): - user_does_not_exist = run('id -u {}'.format(username)) - if user_does_not_exist: - logger.error("User '{}' does not exist, user must exist in LDAP before creating home dir.".format(username)) - return False + script_cmd = '{} {} {}'.format(settings.FILESERVER_CREATE_HOMEDIR_SCRIPT, path, username) - # FIXME: just sudo with one script sudo('some_command', shell=False) instead? - path_exists = run('[ -d "{}" ]; echo $?'.format(path)) - if path_exists: - logger.error("Path '{}:{}' already exists, doing nothing.".format(host, path)) - return False - - cp_skel_cmd = 'cp -r /etc/skel {}'.format(path) - chown_cmd = 'chown -R {0}:{0} {1}'.format(username, path) - chmod_cmd = 'chmod -R 700 {}'.format(path) - if not dry_run: - run(cp_skel_cmd) - run(chown_cmd) - run(chmod_cmd) + if dry_run: + logger.debug('Created homedir on {} with command: {}'.format(host_string, script_cmd)) else: - logger.debug('Creating homedir on {} with cmds: {} {} {}'.format( - host_string, - cp_skel_cmd, - chown_cmd, - chmod_cmd)) + return_val = sudo(script_cmd, shell=False) + if not return_val: + return False return True diff --git a/neuf_userinfo/utils.py b/neuf_userinfo/utils.py index 609e2b0..d6aa943 100644 --- a/neuf_userinfo/utils.py +++ b/neuf_userinfo/utils.py @@ -1,9 +1,10 @@ # coding: utf-8 from __future__ import unicode_literals import base64 +from neuf_kerberos.utils import add_kerberos_principal -from neuf_ldap.utils import ldap_create_user -from neuf_radius.utils import radius_create_user +from neuf_ldap.utils import create_ldap_user, create_ldap_automount +from neuf_radius.utils import create_radius_user from neuf_userinfo.ssh import create_home_dir import rijndael import logging @@ -11,26 +12,25 @@ import logging logger = logging.getLogger(__name__) -def add_new_user(user, dry_run=False): +def add_new_user(user): """ - Create new user in LDAP (username, first_name, last_name, email) - Add to groups (usergroup, dns-alle), it not exists, create - Set LDAP password - Create homedir on fileserver - - (Create automount entry) - - (Create kerberos principal and set password) + - Create automount entry + - Create kerberos principal and set password - Set RADIUS password """ - if not ldap_create_user(user, dry_run=dry_run): + if not create_ldap_user(user): return - create_home_dir(user['username'], dry_run=dry_run) - # ldap_create_automount(user['username']), # FIXME disabled + create_home_dir(user['username']) + create_ldap_automount(user['username']), - # Needs raw password - if user.get('password'): - # kerberos_create_principal(user['username'], user['password']), # FIXME disabled - radius_create_user(user['username'], user['password'], dry_run=dry_run) + # Requires raw password + add_kerberos_principal(user['username'], user['password']) + create_radius_user(user['username'], user['password']) """ Rijndael stuff, thank you SO! diff --git a/scripts/create_home_directory.sh b/scripts/create_home_directory.sh new file mode 100755 index 0000000..2f7f7d8 --- /dev/null +++ b/scripts/create_home_directory.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Usage: ./create_home_directory.sh + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root." 1>&2 + exit 1 +fi + +if [ $# -ne 2 ] ; then + echo "USAGE $0 " + exit 1 +fi + +HOME_DIR_PATH=$1 +USERNAME=$2 + +if ! id -u $USERNAME; then + echo "Cannot find user ${USERNAME}. Be sure the user is added to the ldap directory before running this script." + exit 1 +fi + +if [ -d "${HOME_DIR_PATH}${USERNAME}" ] ; then + echo "Cannot create home directory, it already exists..." + exit 1 +fi + +cp -r /etc/skel ${HOME_DIR_PATH}${USERNAME} +chown -R ${USERNAME}:${USERNAME} ${HOME_DIR_PATH}${USERNAME} +chmod -R 751 ${HOME_DIR_PATH}${USERNAME} diff --git a/userinfosite/settings.py b/userinfosite/settings.py index a03712c..0f64c64 100644 --- a/userinfosite/settings.py +++ b/userinfosite/settings.py @@ -199,7 +199,7 @@ AUTH_LDAP_E_ALWAYS_UPDATE_USER = AUTH_LDAP_U_ALWAYS_UPDATE_USER # Kerberos realm KERBEROS_REALM = "NEUF.NO" -KERBEROS_PASSWORD_CHANGING_PRINCIPAL = 'brukerinfo' +KERBEROS_ADMIN_PRINCIPAL = 'brukerinfo' KERBEROS_PASSWORD = '' # Inside @@ -215,7 +215,8 @@ INSIDE_USERSYNC_ENC_KEY = '' # Home dir FILESERVER_HOST = "localhost" FILESERVER_USER = 'nikolark' # change this to your own user for development -FILESERVER_HOME_PATH = "/tmp/homes" +FILESERVER_HOME_PATH = "/tmp/" +FILESERVER_CREATE_HOMEDIR_SCRIPT = os.path.join(BASE_DIR, 'scripts', 'create_home_directory.sh') # Wordpress sync WP_PHP_SCRIPT_PATH = os.path.join(BASE_DIR, 'scripts')