Archived
AddNewUser ready for testing
This commit is contained in:
1 parent
166a02e7cb
commit
92fe8b221f
11 files changed
+159
-48
No files matched your search
@@ -9,14 +9,14 @@
|
||||
python manage.py runserver
|
||||
|
||||
## LDAP
|
||||
sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ROOTPASS="toor" -p 389:389 -d osixia/openldap
|
||||
ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f test/testdata.ldif
|
||||
sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ADMIN_PWD="toor" -p 389:389 -d nikolaik/docker-openldap
|
||||
ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f test/testdata.ldif # Testdata
|
||||
# Verify import
|
||||
ldapsearch -x -b dc=neuf,dc=no
|
||||
# Login with test@example.com:test
|
||||
|
||||
## Inside
|
||||
# create the Inside database tables, if they don't exist already
|
||||
# create the Inside database tables, if they don't exist already:
|
||||
python manage.py syncdb --database=inside
|
||||
|
||||
For simple dev you need at least:
|
||||
@@ -25,30 +25,25 @@ For simple dev you need at least:
|
||||
* 1 UserGroupRelationShip (din_usergrouprelationship)
|
||||
|
||||
## RADIUS
|
||||
# create the radius database tables, if they don't exist already
|
||||
# create the radius database tables, if they don't exist already:
|
||||
python manage.py syncdb --database=radius
|
||||
|
||||
|
||||
# External dependencies:
|
||||
- LDAP: Read the tutorial on [Howto setup a LDAP server with Docker](https://edb.neuf.no/wiki/index.php?title=Howto_setup_a_LDAP_server_with_Docker)
|
||||
- Kerberos: TODO
|
||||
- RADIUS: TODO
|
||||
- Inside: Never going away! See https://git.neuf.no/edb/inside#tab-readme for code and installation
|
||||
|
||||
## Homedirs
|
||||
- settings.FILESERVER_HOST:~/.ssh/authorized_keys must contain the public key of settings.FILESERVER_USER
|
||||
- settings.FILESERVER_USER might need some sudo access
|
||||
|
||||
# TODO
|
||||
- Rewrite usersync.neuf.no as one or more endpoints
|
||||
- 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
|
||||
- Rewrite usersync.neuf.no as one or more endpoints [DONE?]
|
||||
- On password update, then update ldap hash on InsideUser.ldap_password
|
||||
- allow non LDAP-users (conditional LDAP-stuff), because we don't want LDAP filled with non-active members
|
||||
- Integrity check view which provides two way diffs for the following:
|
||||
- user vs user group
|
||||
- user vs kerberos principal
|
||||
- user vs auto mount entry
|
||||
- Add email addr alias (usernam@s.no, firstname.lastname@s.n)
|
||||
- On password update, then update ldap hash on InsideUser.ldap_password
|
||||
- allow non LDAP-users (conditional LDAP-stuff), because we don't want LDAP filled with non-active members
|
||||
|
||||
# External dependencies:
|
||||
- LDAP: Read the tutorial on [Howto setup a LDAP server with Docker](https://edb.neuf.no/wiki/index.php?title=Howto_setup_a_LDAP_server_with_Docker)
|
||||
- Kerberos: TODO
|
||||
- RADIUS: Standard MySQL.
|
||||
- Inside: Never going away! See https://git.neuf.no/edb/inside#tab-readme for code and installation
|
||||
+21
-5
@@ -31,13 +31,13 @@ def get_kerberos_principal(username):
|
||||
|
||||
|
||||
def set_kerberos_password(username, raw_password):
|
||||
principal = "{0}@{1}".format(username, settings.KERBEROS_REALM)
|
||||
kadmin_query = " -p {0} -w {1} -q 'change_password -pw {2} {3}'".format(
|
||||
principal = "{}@{}".format(username, settings.KERBEROS_REALM)
|
||||
kadmin_query = " -p {} -w {} -q 'change_password -pw {} {}'".format(
|
||||
settings.KERBEROS_PASSWORD_CHANGING_PRINCIPAL,
|
||||
settings.KERBEROS_PASSWORD,
|
||||
raw_password,
|
||||
principal)
|
||||
# FIXME: Running this shell command needs escaping: http://qntm.org/bash
|
||||
# FIXME: Running this shell command could need escaping: http://qntm.org/bash
|
||||
p = Popen('kadmin' + kadmin_query, shell=True, stdout=PIPE, stderr=PIPE)
|
||||
output, error = p.communicate()
|
||||
if error:
|
||||
@@ -56,5 +56,21 @@ def format_krb5_date(date):
|
||||
|
||||
|
||||
def kerberos_create_principal(user):
|
||||
# TODO
|
||||
pass
|
||||
principal = "{}@{}".format(user['username'], settings.KERBEROS_REALM)
|
||||
kadmin_query = " -p '{}' -w {} -q 'add_principal {} -pw {}'".format(
|
||||
settings.KERBEROS_PASSWORD_CHANGING_PRINCIPAL,
|
||||
settings.KERBEROS_PASSWORD,
|
||||
principal,
|
||||
user['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
|
||||
|
||||
return True
|
||||
+45
-1
@@ -91,4 +91,48 @@ class LdapGroup(ldapdb.models.Model):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
# TODO Automount: http://www.openldap.org/faq/data/cache/599.html
|
||||
|
||||
class LdapAutomountMap(ldapdb.models.Model):
|
||||
"""
|
||||
Represents an LDAP automountMap
|
||||
Ref: http://www.openldap.org/faq/data/cache/599.html
|
||||
"""
|
||||
|
||||
connection_name = 'ldap'
|
||||
|
||||
# LDAP meta-data
|
||||
base_dn = settings.LDAP_AUTOMOUNT_DN
|
||||
object_classes = ['automountMap']
|
||||
|
||||
ou = CharField(db_column='ou', primary_key=True) # F.ex auto.home
|
||||
|
||||
def __unicode__(self):
|
||||
return self.ou
|
||||
|
||||
|
||||
class LdapAutomountHome(ldapdb.models.Model):
|
||||
"""
|
||||
Represents an LDAP automount with hardcoded 'auto.home' in the base_dn (!)
|
||||
Ref: http://www.openldap.org/faq/data/cache/599.html
|
||||
Ref: http://lists.bolloretelecom.eu/pipermail/django-ldapdb/2012-April/000113.html
|
||||
"""
|
||||
|
||||
connection_name = 'ldap'
|
||||
|
||||
# LDAP meta-data
|
||||
base_dn = 'ou=auto.home,{}'.format(settings.LDAP_AUTOMOUNT_DN)
|
||||
object_classes = ['automount']
|
||||
|
||||
username = CharField(db_column='cn', primary_key=True)
|
||||
automountInformation = CharField(db_column='automountInformation')
|
||||
|
||||
def set_automount_info(self, username=None):
|
||||
krb5_automount_info = "-fstype=nfs4,rw,sec=krb5 {}:{}/{}".format(
|
||||
settings.FILESERVER_HOST,
|
||||
settings.FILESERVER_HOME_PATH,
|
||||
username if username is not None else self.username)
|
||||
|
||||
self.automountInformation = krb5_automount_info
|
||||
|
||||
def __unicode__(self):
|
||||
return self.username
|
||||
+13
-8
@@ -1,11 +1,9 @@
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
import json
|
||||
from django.conf import settings
|
||||
|
||||
import logging
|
||||
import os
|
||||
from passlib.hash import ldap_salted_sha1
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -63,12 +61,14 @@ def ldap_create_user(user):
|
||||
user_groups = LdapGroup.objects.filter(gid__gte=settings.LDAP_USER_GID_MIN, gid__lte=settings.LDAP_USER_GID_MAX)
|
||||
user_groups = user_groups.order_by('-gid').values_list('gid', flat=True)
|
||||
|
||||
if len(user_groups) == 0:
|
||||
return settings.LDAP_USER_GID_MIN
|
||||
|
||||
if len(user_groups) > 0 and user_groups[0] >= settings.LDAP_USER_GID_MAX:
|
||||
logger.exception("UID larger than LDAP_USER_GID_MAX")
|
||||
|
||||
return user_groups[0] + 1
|
||||
|
||||
groups = user.pop('groups')
|
||||
# User
|
||||
full_name = '{} {}'.format(user['firstname'], user['lastname'])
|
||||
user_data = {
|
||||
@@ -92,15 +92,20 @@ def ldap_create_user(user):
|
||||
ldap_user_group.save()
|
||||
|
||||
# Add groups
|
||||
ldap_groups = LdapGroup.objects.filter(name__in=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()
|
||||
|
||||
# Finito!
|
||||
return True
|
||||
|
||||
|
||||
def ldap_create_automount(user):
|
||||
# TODO
|
||||
pass
|
||||
def ldap_create_automount(username):
|
||||
from neuf_ldap.models import LdapAutomountHome
|
||||
automount = LdapAutomountHome(username=username)
|
||||
automount.set_automount_info()
|
||||
automount.save()
|
||||
|
||||
return True
|
||||
@@ -27,4 +27,5 @@ def set_radius_password(username, raw_password):
|
||||
|
||||
|
||||
def radius_create_user(username, password):
|
||||
set_radius_password(username, password)
|
||||
set_radius_password(username, password)
|
||||
return True
|
||||
@@ -0,0 +1,41 @@
|
||||
from django.conf import settings
|
||||
from fabric.api import settings as fab_settings
|
||||
from fabric.operations import run
|
||||
import logging
|
||||
import os
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_home_dir(username):
|
||||
"""
|
||||
Create homedir for username
|
||||
- Copy /etc/skel
|
||||
- make user
|
||||
This use fabric (SSH) for running remote commands
|
||||
|
||||
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
|
||||
"""
|
||||
host = settings.FILESERVER_HOST
|
||||
path = os.path.join(settings.FILESERVER_HOME_PATH, username)
|
||||
host_string = '{}@{}'.format(settings.FILESERVER_USER, host)
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
run('cp -r /etc/skel {}'.format(path))
|
||||
run('chown -R {0}:{0} {1}'.format(username, path))
|
||||
run('chmod -R 700 {}'.format(path))
|
||||
|
||||
return True
|
||||
@@ -48,9 +48,4 @@ def decrypt_rijndael(key, encoded):
|
||||
padded_text += r.decrypt(ciphertext[start:start+BLOCK_SIZE])
|
||||
|
||||
plaintext = padded_text.split('\x00', 1)[0]
|
||||
return plaintext
|
||||
|
||||
|
||||
def create_homedir(username):
|
||||
# TODO
|
||||
pass
|
||||
return plaintext
|
||||
@@ -21,7 +21,7 @@ from neuf_ldap.models import LdapGroup, LdapUser
|
||||
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.utils import create_homedir
|
||||
from neuf_userinfo.ssh import create_home_dir
|
||||
|
||||
|
||||
def index(request):
|
||||
@@ -153,12 +153,12 @@ class AddNewUserView(View):
|
||||
results = {
|
||||
'user': user,
|
||||
'ldap_user': ldap_create_user(user),
|
||||
'ldap_automount': ldap_create_automount(user),
|
||||
'homedir': create_home_dir(user['username']),
|
||||
'ldap_automount': ldap_create_automount(user['username']),
|
||||
'kerberos_principal': kerberos_create_principal(user),
|
||||
'homedir': create_homedir(user['username']), # FIXME run ssh script?
|
||||
'radius': radius_create_user(user['username'], user['password'])
|
||||
}
|
||||
# import pprint; pprint.pprint(results)
|
||||
import pprint; pprint.pprint(results)
|
||||
|
||||
return JsonResponse({'results': 'success'})
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ django-auth-ldap==1.2.0
|
||||
django-extensions==1.5.0
|
||||
django-ldapdb==0.3.2
|
||||
dj-static==0.0.6
|
||||
Fabric==1.10.1
|
||||
mysqlclient==1.3.5
|
||||
passlib==1.6.2
|
||||
python-ldap==2.4.15
|
||||
@@ -61,3 +61,15 @@ cn: edbadmin
|
||||
gidNumber: 3
|
||||
description: Group account
|
||||
memberUid: test
|
||||
|
||||
# Root dn for all automounts
|
||||
dn: ou=Automount,dc=neuf,dc=no
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
ou: Automount
|
||||
|
||||
# Automount map for auto.home
|
||||
dn: ou=auto.home,ou=Automount,dc=neuf,dc=no
|
||||
objectClass: top
|
||||
objectClass: automountMap
|
||||
ou: auto.home
|
||||
@@ -213,8 +213,9 @@ INSIDE_USERSYNC_API_KEY = ''
|
||||
INSIDE_USERSYNC_ENC_KEY = ''
|
||||
|
||||
# Home dir
|
||||
FILESERVER_HOST = "wii.neuf.no"
|
||||
FILESERVER_HOME_PATH = "/fileserver/homes"
|
||||
FILESERVER_HOST = "localhost"
|
||||
FILESERVER_USER = 'nikolark' # change this to your own user for development
|
||||
FILESERVER_HOME_PATH = "/tmp/homes"
|
||||
|
||||
try:
|
||||
from local_settings import *
|
||||
|
||||
Reference in new issue
Block a user