Archived
More Inside LDAP sync work and cleans, disables some krb5 and automount stuff
This commit is contained in:
1 parent
d24f22b4a4
commit
f963f11c88
10 files changed
+212
-103
No files matched your search
@@ -46,14 +46,11 @@ class InsideBackend(object):
|
||||
return self.user
|
||||
|
||||
def _update_user_details(self):
|
||||
sync_attrs = {
|
||||
'firstname': 'first_name',
|
||||
'lastname': 'last_name',
|
||||
'email': 'email'
|
||||
}
|
||||
for inside_attr, local_attr in sync_attrs.iteritems():
|
||||
sync_attrs = ['first_name', 'last_name', 'email']
|
||||
|
||||
for attr in sync_attrs:
|
||||
# Copy from Inside user to local Django user
|
||||
setattr(self.user, local_attr, getattr(self.inside_user, inside_attr))
|
||||
setattr(self.user, attr, getattr(self.inside_user, attr))
|
||||
|
||||
def _update_groups(self):
|
||||
existing_groups = list(self.user.groups.all())
|
||||
|
||||
+2
-2
@@ -338,8 +338,8 @@ class InsideUser(models.Model):
|
||||
cardno = models.IntegerField(unique=True, blank=True, null=True)
|
||||
username = models.CharField(unique=True, max_length=12)
|
||||
password = models.CharField(max_length=50)
|
||||
firstname = models.CharField(max_length=120)
|
||||
lastname = models.CharField(max_length=120)
|
||||
first_name = models.CharField(max_length=120, db_column='firstname')
|
||||
last_name = models.CharField(max_length=120, db_column='lastname')
|
||||
addresstype = models.CharField(max_length=3)
|
||||
valid_address = models.IntegerField()
|
||||
email = models.CharField(unique=True, max_length=120)
|
||||
|
||||
@@ -30,6 +30,10 @@ def get_kerberos_principal(username):
|
||||
return cleaned_output
|
||||
|
||||
|
||||
def has_kerberos_principal(username):
|
||||
return get_kerberos_principal(username) is not None
|
||||
|
||||
|
||||
def set_kerberos_password(username, raw_password):
|
||||
principal = "{}@{}".format(username, settings.KERBEROS_REALM)
|
||||
kadmin_query = " -p {} -w {} -q 'change_password -pw {} {}'".format(
|
||||
|
||||
+60
-8
@@ -1,5 +1,6 @@
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
import pprint
|
||||
from django.conf import settings
|
||||
import logging
|
||||
import os
|
||||
@@ -25,6 +26,7 @@ def set_ldap_password(username, raw_password):
|
||||
user = LdapUser.objects.get(username=username)
|
||||
user.set_password(raw_password)
|
||||
except LdapUser.DoesNotExist:
|
||||
# Ignore
|
||||
pass
|
||||
|
||||
|
||||
@@ -40,7 +42,7 @@ def ldap_username_exists(username):
|
||||
return len(LdapUser.objects.filter(username=username)) != 0
|
||||
|
||||
|
||||
def ldap_create_user(user):
|
||||
def ldap_create_user(user, dry_run=False):
|
||||
from neuf_ldap.models import LdapUser, LdapGroup
|
||||
|
||||
def _get_next_uid():
|
||||
@@ -70,10 +72,10 @@ def ldap_create_user(user):
|
||||
return user_groups[0] + 1
|
||||
|
||||
# User
|
||||
full_name = '{} {}'.format(user['firstname'], user['lastname'])
|
||||
full_name = '{} {}'.format(user['first_name'], user['last_name'])
|
||||
user_data = {
|
||||
'first_name': user['firstname'],
|
||||
'last_name': user['lastname'],
|
||||
'first_name': user['first_name'],
|
||||
'last_name': user['last_name'],
|
||||
'full_name': full_name,
|
||||
'display_name': full_name,
|
||||
'gecos': full_name,
|
||||
@@ -82,26 +84,76 @@ def ldap_create_user(user):
|
||||
'id': _get_next_uid(),
|
||||
'group': _get_next_user_gid(),
|
||||
'home_directory': os.path.join(settings.LDAP_HOME_DIRECTORY_PREFIX, user['username'])
|
||||
# TODO you are here: AttributeError: 'NoneType' object has no attribute 'startswith'
|
||||
# $ python manage.py sync_active_to_ldap --dry-run -v3
|
||||
}
|
||||
ldap_user = LdapUser(**user_data)
|
||||
ldap_user.set_password(user['password'], commit=False)
|
||||
ldap_user.save()
|
||||
|
||||
# User password
|
||||
pwd_type = None
|
||||
if user.get('password') is not None:
|
||||
ldap_user.set_password(user['password'], commit=False) # Raw
|
||||
pwd_type = 'raw'
|
||||
elif user.get('ldap_password') is not None:
|
||||
ldap_user.password = user['ldap_password'] # Hashed
|
||||
pwd_type = 'hashed'
|
||||
else:
|
||||
# No password
|
||||
logger.exception("User {} has no ldap_password (hashed) or password (raw)!".format(user['username']))
|
||||
|
||||
if dry_run:
|
||||
logger.debug('User saved with data: {} and password type \'{}\'.'.format(
|
||||
pprint.pformat(user_data),
|
||||
pwd_type))
|
||||
else:
|
||||
ldap_user.save()
|
||||
|
||||
# Add user group
|
||||
ldap_user_group = LdapGroup(name=user['username'], gid=user_data['group'], members=[user['username']])
|
||||
ldap_user_group.save()
|
||||
if not dry_run:
|
||||
ldap_user_group.save()
|
||||
else:
|
||||
logger.debug('User group {} created'.format(user['username']))
|
||||
|
||||
# Add groups
|
||||
ldap_groups = LdapGroup.objects.filter(name__in=user['groups'])
|
||||
for g in ldap_groups:
|
||||
if user['username'] not in g.members:
|
||||
g.members.append(user['username'])
|
||||
g.save()
|
||||
if not dry_run:
|
||||
g.save()
|
||||
else:
|
||||
logger.debug('User {} added to group {}'.format(user['username'], g.name))
|
||||
|
||||
# Finito!
|
||||
return True
|
||||
|
||||
|
||||
def ldap_update_user_details(inside_user, dry_run=False):
|
||||
from neuf_ldap.models import LdapUser
|
||||
diff_attributes = ['username', 'email', 'groups']
|
||||
ldap_user = LdapUser.objects.get(username=inside_user['username'])
|
||||
|
||||
for attr in diff_attributes:
|
||||
setattr(ldap_user, attr, inside_user[attr])
|
||||
|
||||
name_changed = inside_user['first_name'] != ldap_user.first_name or inside_user['last_name'] != ldap_user.last_name
|
||||
if name_changed:
|
||||
full_name = '{} {}'.format(inside_user['first_name'], inside_user['last_name'])
|
||||
name_data = {
|
||||
'first_name': inside_user['first_name'],
|
||||
'last_name': inside_user['last_name'],
|
||||
'full_name': full_name,
|
||||
'display_name': full_name,
|
||||
'gecos': full_name,
|
||||
}
|
||||
for key, value in name_data.iteritems():
|
||||
setattr(ldap_user, key, value)
|
||||
|
||||
if not dry_run:
|
||||
ldap_user.save()
|
||||
|
||||
|
||||
def ldap_create_automount(username):
|
||||
from neuf_ldap.models import LdapAutomountHome
|
||||
automount = LdapAutomountHome(username=username)
|
||||
|
||||
+16
-7
@@ -15,12 +15,11 @@ from django.utils.translation import ugettext as _
|
||||
from inside.models import InsideUser
|
||||
from inside.utils import set_inside_password
|
||||
|
||||
from neuf_kerberos.utils import set_kerberos_password
|
||||
from neuf_ldap.models import LdapGroup, LdapUser
|
||||
from neuf_kerberos.utils import set_kerberos_password, has_kerberos_principal
|
||||
from neuf_radius.utils import set_radius_password
|
||||
from neuf_ldap.utils import set_ldap_password, ldap_username_exists, ldap_user_group_exists
|
||||
from neuf_userinfo.utils import decrypt_rijndael
|
||||
from neuf_userinfo.validators import PasswordValidator, UsernameValidator
|
||||
from neuf_userinfo.validators import UsernameValidator, validate_password
|
||||
|
||||
|
||||
class NeufSetPasswordForm(SetPasswordForm):
|
||||
@@ -42,17 +41,19 @@ class NeufSetPasswordForm(SetPasswordForm):
|
||||
set_inside_password(username, password)
|
||||
|
||||
# Active services
|
||||
set_kerberos_password(username, password)
|
||||
set_radius_password(username, password)
|
||||
set_radius_password(username, password) # creates user if non-existant
|
||||
set_ldap_password(username, password)
|
||||
|
||||
if has_kerberos_principal(username):
|
||||
set_kerberos_password(username, password)
|
||||
|
||||
return self.user # Local Django User
|
||||
|
||||
def clean_new_password1(self):
|
||||
raw_password = self.cleaned_data.get('new_password1')
|
||||
|
||||
MinLengthValidator(8)(raw_password)
|
||||
PasswordValidator(raw_password)
|
||||
validate_password(raw_password)
|
||||
|
||||
return raw_password
|
||||
|
||||
@@ -144,10 +145,18 @@ class NewUserForm(forms.Form):
|
||||
def clean_password(self):
|
||||
raw_password = self.cleaned_data['password']
|
||||
password = decrypt_rijndael(settings.INSIDE_USERSYNC_ENC_KEY, raw_password)
|
||||
PasswordValidator(password)
|
||||
MinLengthValidator(8)(raw_password)
|
||||
validate_password(password)
|
||||
|
||||
return password
|
||||
|
||||
def clean_groups(self):
|
||||
groups = self.cleaned_data['groups']
|
||||
return groups.strip().split(',')
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(NewUserForm, self).clean()
|
||||
# Rename firstname to first_name and lastname to last_name
|
||||
cleaned_data['first_name'] = cleaned_data.pop('firstname')
|
||||
cleaned_data['last_name'] = cleaned_data.pop('lastname')
|
||||
return cleaned_data
|
||||
@@ -3,69 +3,51 @@ from django.core.management.base import BaseCommand
|
||||
|
||||
from inside.models import InsideGroup, InsideUser
|
||||
from neuf_ldap.models import LdapGroup, LdapUser
|
||||
from neuf_ldap.utils import ldap_create_user
|
||||
from neuf_ldap.utils import ldap_create_user, ldap_update_user_details
|
||||
|
||||
from optparse import make_option
|
||||
from neuf_userinfo.utils import add_new_user
|
||||
|
||||
ACTIVE_USERS_GROUP = 'dns-aktiv'
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Syncs users in group dns-aktiv from Inside to LDAP'
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
dest='dry_run',
|
||||
default=False,
|
||||
help='Dry run of syncronization, nothing is saved.'
|
||||
),)
|
||||
|
||||
DIFF_ATTRIBUTES = ['username', 'first_name', 'last_name', 'email', 'groups']
|
||||
COUNTS = dict(create=0, update=0, in_sync=0)
|
||||
options = {}
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.options = options
|
||||
|
||||
# Get all active user from Inside
|
||||
inside_users_diffable = self.get_inside_users_diffable()
|
||||
if options['verbosity'] == '3':
|
||||
self.stdout.write('Found {} Inside users'.format(len(inside_users_diffable)))
|
||||
|
||||
# Get existing users in LDAP
|
||||
ldap_users_diffable = self.get_ldap_users_diffable()
|
||||
if options['verbosity'] == '3':
|
||||
self.stdout.write('Found {} LDAP users'.format(len(ldap_users_diffable)))
|
||||
|
||||
self.sync_users(inside_users_diffable, ldap_users_diffable, options)
|
||||
# Do actual sync
|
||||
self.sync_users(inside_users_diffable, ldap_users_diffable)
|
||||
|
||||
self.obsolete_users(inside_users_diffable, ldap_users_diffable, options)
|
||||
# Are any LDAP users stale?
|
||||
self.stale_ldap_users(inside_users_diffable, ldap_users_diffable)
|
||||
|
||||
self.log_totals(options)
|
||||
# Voila
|
||||
self.log_totals()
|
||||
|
||||
def sync_users(self, inside_users_diffable, ldap_users_diffable, options):
|
||||
for username, u in inside_users_diffable.iteritems():
|
||||
# Diff by username
|
||||
if username not in ldap_users_diffable:
|
||||
# TODO create
|
||||
# ldap_create_user(u)
|
||||
self.COUNTS['create'] += 1
|
||||
if int(options['verbosity']) >= 2:
|
||||
self.stdout.write('Inside user {} is not in LDAP'.format(username))
|
||||
elif not self.user_details_in_sync(u, ldap_users_diffable[username]):
|
||||
# TODO update
|
||||
# ldap_update_user(u)
|
||||
self.COUNTS['update'] += 1
|
||||
if int(options['verbosity']) >= 2:
|
||||
self.stdout.write('Inside user {} is out of sync with LDAP'.format(username))
|
||||
else:
|
||||
self.COUNTS['in_sync'] += 1
|
||||
if int(options['verbosity']) == 3:
|
||||
self.stdout.write('Inside user {} is in sync with LDAP'.format(username))
|
||||
|
||||
def obsolete_users(self, inside_users_diffable, ldap_users_diffable, options):
|
||||
for username, u in ldap_users_diffable.iteritems():
|
||||
if username not in inside_users_diffable:
|
||||
if int(options['verbosity']) >= 2:
|
||||
self.stdout.write('LDAP user {} is not in Inside'.format(username))
|
||||
|
||||
def log_totals(self, options):
|
||||
if self.COUNTS['create'] != 0:
|
||||
self.stdout.write('{} Inside users not found in LDAP'.format(self.COUNTS['create']))
|
||||
if self.COUNTS['update'] != 0:
|
||||
self.stdout.write('{} LDAP users were were update with info '.format(self.COUNTS['update']))
|
||||
if int(options['verbosity']) >= 2:
|
||||
self.stdout.write('{} Inside users in sync with LDAP users '.format(self.COUNTS['in_sync']))
|
||||
# Voila!
|
||||
|
||||
def get_inside_users_diffable(self):
|
||||
inside_users_diffable = {}
|
||||
group = InsideGroup.objects.get(posix_group='dns-aktiv')
|
||||
group = InsideGroup.objects.get(posix_group=ACTIVE_USERS_GROUP)
|
||||
inside_users = InsideUser.objects.filter(group_rels__group=group)
|
||||
|
||||
for u in inside_users:
|
||||
@@ -73,17 +55,20 @@ class Command(BaseCommand):
|
||||
inside_groups = inside_groups.values_list('posix_group', flat=True)
|
||||
inside_users_diffable[u.ldap_username] = {
|
||||
'username': u.ldap_username,
|
||||
'first_name': u.firstname,
|
||||
'last_name': u.lastname,
|
||||
'password': u.ldap_password,
|
||||
'first_name': u.first_name,
|
||||
'last_name': u.last_name,
|
||||
'ldap_password': u.ldap_password,
|
||||
'email': u.email,
|
||||
'groups': inside_groups
|
||||
}
|
||||
if self.options['verbosity'] == '3':
|
||||
self.stdout.write('Found {} Inside users'.format(len(inside_users_diffable)))
|
||||
|
||||
return inside_users_diffable
|
||||
|
||||
def get_ldap_users_diffable(self):
|
||||
ldap_users_diffable = {}
|
||||
ldap_active_members = LdapGroup.objects.get(name="dns-aktiv").members
|
||||
ldap_active_members = LdapGroup.objects.get(name=ACTIVE_USERS_GROUP).members
|
||||
ldap_users = LdapUser.objects.filter(username__in=ldap_active_members)
|
||||
|
||||
for u in ldap_users:
|
||||
@@ -95,8 +80,47 @@ class Command(BaseCommand):
|
||||
'email': u.email,
|
||||
'groups': ldap_groups
|
||||
}
|
||||
if self.options['verbosity'] == '3':
|
||||
self.stdout.write('Found {} LDAP users'.format(len(ldap_users_diffable)))
|
||||
|
||||
return ldap_users_diffable
|
||||
|
||||
def sync_users(self, inside_users_diffable, ldap_users_diffable):
|
||||
for username, u in inside_users_diffable.iteritems():
|
||||
if username not in ldap_users_diffable:
|
||||
# Create
|
||||
add_new_user(u, dry_run=self.options['dry_run'])
|
||||
|
||||
self.COUNTS['create'] += 1
|
||||
if int(self.options['verbosity']) >= 2:
|
||||
self.stdout.write('Inside user {} is not in LDAP'.format(username))
|
||||
elif not self.user_details_in_sync(u, ldap_users_diffable[username]):
|
||||
# Update
|
||||
ldap_update_user_details(u, dry_run=self.options['dry_run'])
|
||||
|
||||
self.COUNTS['update'] += 1
|
||||
if int(self.options['verbosity']) >= 2:
|
||||
self.stdout.write('Inside user {} is out of sync with LDAP'.format(username))
|
||||
else:
|
||||
# In sync :-)
|
||||
self.COUNTS['in_sync'] += 1
|
||||
if int(self.options['verbosity']) == 3:
|
||||
self.stdout.write('Inside user {} is in sync with LDAP'.format(username))
|
||||
|
||||
def stale_ldap_users(self, inside_users_diffable, ldap_users_diffable):
|
||||
for username, u in ldap_users_diffable.iteritems():
|
||||
if username not in inside_users_diffable:
|
||||
if int(self.options['verbosity']) >= 2:
|
||||
self.stdout.write('LDAP user {} is not in Inside'.format(username))
|
||||
|
||||
def log_totals(self):
|
||||
if self.COUNTS['create'] != 0:
|
||||
self.stdout.write('{} Inside users not found in LDAP'.format(self.COUNTS['create']))
|
||||
if self.COUNTS['update'] != 0:
|
||||
self.stdout.write('{} LDAP users were were update with info '.format(self.COUNTS['update']))
|
||||
if int(self.options['verbosity']) >= 2:
|
||||
self.stdout.write('{} Inside users in sync with LDAP users '.format(self.COUNTS['in_sync']))
|
||||
|
||||
def user_details_in_sync(self, inside_user, ldap_user):
|
||||
for attr in self.DIFF_ATTRIBUTES:
|
||||
if inside_user[attr] != ldap_user[attr]:
|
||||
|
||||
+14
-4
@@ -7,7 +7,7 @@ import os
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_home_dir(username):
|
||||
def create_home_dir(username, dry_run=False):
|
||||
"""
|
||||
Create homedir for username
|
||||
- Copy /etc/skel
|
||||
@@ -34,8 +34,18 @@ def create_home_dir(username):
|
||||
logger.error("Path '{}:{}' already exists, doing nothing.".format(host, path))
|
||||
return False
|
||||
|
||||
run('cp -r /etc/skel {}'.format(path))
|
||||
run('chown -R {0}:{0} {1}'.format(username, path))
|
||||
run('chmod -R 700 {}'.format(path))
|
||||
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)
|
||||
else:
|
||||
logger.debug('Creating homedir on {} with cmds: {} {} {}'.format(
|
||||
host_string,
|
||||
cp_skel_cmd,
|
||||
chown_cmd,
|
||||
chmod_cmd))
|
||||
|
||||
return True
|
||||
+28
-1
@@ -1,11 +1,38 @@
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
import base64
|
||||
|
||||
from neuf_ldap.utils import ldap_create_user
|
||||
from neuf_radius.utils import radius_create_user
|
||||
from neuf_userinfo.ssh import create_home_dir
|
||||
import rijndael
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def add_new_user(user, dry_run=False):
|
||||
"""
|
||||
- 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 wii
|
||||
- Set RADIUS password
|
||||
- (Create automount entry)
|
||||
- (Create kerberos principal and set password)
|
||||
"""
|
||||
results = {
|
||||
'user': user,
|
||||
'ldap_user': ldap_create_user(user, dry_run=dry_run),
|
||||
'homedir': create_home_dir(user['username'], dry_run=dry_run),
|
||||
# 'ldap_automount': ldap_create_automount(user['username']), # FIXME disabled
|
||||
# 'kerberos_principal': kerberos_create_principal(user['username'], user['password']), # FIXME disabled
|
||||
}
|
||||
if user.get('password'):
|
||||
results['radius'] = radius_create_user(user['username'], user['password'])
|
||||
|
||||
logger.debug(results)
|
||||
|
||||
"""
|
||||
Rijndael stuff, thank you SO!
|
||||
Ref: http://stackoverflow.com/questions/8217269/decrypting-strings-in-python-that-were-encrypted-with-mcrypt-rijndael-256-in-php#answers-header
|
||||
@@ -48,4 +75,4 @@ def decrypt_rijndael(key, encoded):
|
||||
padded_text += r.decrypt(ciphertext[start:start+BLOCK_SIZE])
|
||||
|
||||
plaintext = padded_text.split('\x00', 1)[0]
|
||||
return plaintext
|
||||
return plaintext
|
||||
@@ -1,9 +1,14 @@
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import RegexValidator
|
||||
import re
|
||||
|
||||
# Passwords should not contain "
|
||||
password_re = re.compile(r'(?<!\")', re.IGNORECASE)
|
||||
PasswordValidator = RegexValidator(password_re, u'Enter a valid password')
|
||||
|
||||
username_re = re.compile(r'^[a-z][a-z0-9]*$') # TODO Length
|
||||
UsernameValidator = RegexValidator(username_re, u'Enter a valid username')
|
||||
def validate_password(value):
|
||||
# Passwords should not contain " and '
|
||||
blacklist = ['"', '\'']
|
||||
for c in blacklist:
|
||||
if c in value:
|
||||
raise ValidationError(u'Enter a valid password.', code='invalid')
|
||||
|
||||
username_re = re.compile(r'^[a-z][a-z0-9]{2,31}$') # From 3-32 alphanum chars (man useradd), starting with a char
|
||||
UsernameValidator = RegexValidator(username_re, u'Enter a valid username.')
|
||||
+3
-22
@@ -17,11 +17,8 @@ from django.views.generic import View
|
||||
import logging
|
||||
|
||||
from inside.models import InsideUser
|
||||
from neuf_kerberos.utils import kerberos_create_principal
|
||||
from neuf_ldap.utils import ldap_create_user, ldap_create_automount
|
||||
from neuf_radius.utils import radius_create_user
|
||||
from neuf_userinfo.forms import NewUserForm
|
||||
from neuf_userinfo.ssh import create_home_dir
|
||||
from neuf_userinfo.utils import add_new_user
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -117,15 +114,7 @@ def password_reset_confirm(request, uidb64=None, token=None,
|
||||
class AddNewUserView(View):
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
- 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 automount entry
|
||||
- Create kerberos principal and set password
|
||||
- Create homedir on wii
|
||||
- Set RADIUS password
|
||||
"""
|
||||
""" Adds a new user to all our internal services. See .utils.add_new_user for details. """
|
||||
|
||||
if not self.validate_api_key(request.GET.get('api_key', '')):
|
||||
return JsonResponse({'errors': 'Invalid api_key'})
|
||||
@@ -136,15 +125,7 @@ class AddNewUserView(View):
|
||||
|
||||
user = form.cleaned_data
|
||||
|
||||
results = {
|
||||
'user': user,
|
||||
'ldap_user': ldap_create_user(user),
|
||||
'homedir': create_home_dir(user['username']),
|
||||
'ldap_automount': ldap_create_automount(user['username']),
|
||||
'kerberos_principal': kerberos_create_principal(user['username'], user['password']),
|
||||
'radius': radius_create_user(user['username'], user['password'])
|
||||
}
|
||||
logger.debug(results)
|
||||
add_new_user(user)
|
||||
|
||||
return JsonResponse({'results': 'success'})
|
||||
|
||||
|
||||
Reference in new issue
Block a user