From bc5b32bcead1e6e2388e80ce80dd3f061c330286 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 12 Jan 2015 23:52:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0useradd=E7=9A=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect.py | 8 +-- juser/views.py | 165 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 159 insertions(+), 14 deletions(-) diff --git a/connect.py b/connect.py index 61bace914..3d52e727b 100755 --- a/connect.py +++ b/connect.py @@ -34,12 +34,12 @@ except ImportError: time.sleep(3) sys.exit() -CURRENT_DIR = os.path.dirname(__file__) +BASE_DIR = os.path.dirname(__file__) CONF = ConfigParser() -CONF.read(os.path.join(CURRENT_DIR, 'jumpserver.conf')) -LOG_DIR = os.path.join(CURRENT_DIR, 'logs') +CONF.read(os.path.join(BASE_DIR, 'jumpserver.conf')) +LOG_DIR = os.path.join(BASE_DIR, 'logs') # Web generate user ssh_key dir. -SSH_KEY_DIR = os.path.join(CURRENT_DIR, 'keys') +SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys') # User upload the server key to this dir. SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server') # The key of decryptor. diff --git a/juser/views.py b/juser/views.py index 814a38ca4..7b2252669 100644 --- a/juser/views.py +++ b/juser/views.py @@ -3,23 +3,35 @@ # Email: ibuler@qq.com import time +import os import hashlib import random +import subprocess +import ldap +from ldap import modlist +from Crypto.PublicKey import RSA +import crypt from django.shortcuts import render_to_response from juser.models import UserGroup, User from connect import PyCrypt, KEY +from connect import BASE_DIR +from connect import CONF cryptor = PyCrypt(KEY) +ldap_host_url = CONF.get('ldap', 'host_url') +ldap_base_dn = CONF.get('ldap', 'base_dn') +ldap_root_dn = CONF.get('ldap', 'root_dn') +ldap_root_pwd = CONF.get('ldap', 'root_pw') def md5_crypt(string): return hashlib.new("md5", string).hexdigest() -def gen_rand_pass(num): +def gen_rand_pwd(num): """生成随机密码""" seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" salt_list = [] @@ -29,10 +41,74 @@ def gen_rand_pass(num): return salt +def bash(cmd): + """执行bash命令""" + return subprocess.call(cmd, shell=True) + + +def is_dir(dir_name, mode=0755): + if not os.path.isdir(dir_name): + os.makedirs(dir_name) + os.chmod(dir_name, mode) + + class AddError(Exception): pass +class LDAPMgmt(): + def __init__(self, + host_url=ldap_host_url, + base_dn=ldap_base_dn, + root_cn=ldap_root_dn, + root_pw=ldap_root_pwd): + self.ldap_host = host_url + self.ldap_base_dn = base_dn + self.conn = ldap.initialize(host_url) + self.conn.set_option(ldap.OPT_REFERRALS, 0) + self.conn.protocol_version = ldap.VERSION3 + self.conn.simple_bind_s(root_cn, root_pw) + + def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None): + result = {} + try: + ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr) + for entry in ldap_result: + name, data = entry + for k, v in data.items(): + print '%s: %s' % (k, v) + result[k] = v + return result + except ldap.LDAPError, e: + print e + + def add(self, dn, attrs): + try: + ldif = modlist.addModlist(attrs) + self.conn.add_s(dn, ldif) + except ldap.LDAPError, e: + print e + + def modify(self, dn, attrs): + try: + attr_s = [] + for k, v in attrs.items(): + attr_s.append((2, k, v)) + self.conn.modify_s(dn, attr_s) + except ldap.LDAPError, e: + print e + + def delete(self, dn): + try: + self.conn.delete_s(dn) + except ldap.LDAPError, e: + print e + + +def gen_sha512(salt, password): + return crypt.crypt(password, '$6$%s$' % salt) + + def group_add(request): error = '' msg = '' @@ -63,15 +139,13 @@ def group_add(request): else: msg = u'添加组 %s 成功' % group_name - return render_to_response('juser/group_add.html', - locals()) + return render_to_response('juser/group_add.html', locals()) def group_list(request): header_title, path1, path2 = '查看属组 | Add Group', 'juser', 'group_add' groups = UserGroup.objects.all() - return render_to_response('juser/group_list.html', - locals()) + return render_to_response('juser/group_list.html', locals()) def user_list(request): @@ -89,6 +163,71 @@ def db_add_user(**kwargs): user.user_group = group_select +def gen_ssh_key(username, password=None, length=2048): + private_key_dir = os.path.join(BASE_DIR, 'keys/jumpserver/') + private_key_file = os.path.join(private_key_dir, username) + public_key_dir = '/home/%s/.ssh/' % username + public_key_file = os.path.join(public_key_dir, 'authorized_keys') + is_dir(private_key_dir) + is_dir(public_key_dir, mode=0700) + + key = RSA.generate(length) + with open(private_key_file, 'w') as pri_f: + pri_f.write(key.exportKey('PEM', password)) + os.chmod(private_key_file, 0600) + + pub_key = key.publickey() + with open(public_key_file, 'w') as pub_f: + pub_f.write(pub_key.exportKey('OpenSSH')) + os.chmod(public_key_file, 0600) + os.chown(public_key_file, username, username) + + +def server_add_user(username, password, ssh_key_pwd1): + bash('useradd %s; echo %s | passwd --stdin %s' % (username, password, username)) + gen_ssh_key(username, ssh_key_pwd1) + + +def ldap_add_user(username, ldap_pwd): + user_dn = "uid=%s,ou=People,%s" % (username, ldap_base_dn) + password_sha512 = gen_sha512(gen_rand_pwd(6), ldap_pwd) + user = User.objects.get(username=username) + + user_attr = {'uid': [str(username)], + 'cn': [str(username)], + 'objectClass': ['account', 'posixAccount', 'top', 'shadowAccount'], + 'userPassword': ['{crypt}%s' % password_sha512], + 'shadowLastChange': ['16328'], + 'shadowMin': ['0'], + 'shadowMax': ['99999'], + 'shadowWarning': ['7'], + 'loginShell': ['/bin/bash'], + 'uidNumber': [str(user.id)], + 'gidNumber': [str(user.id)], + 'homeDirectory': [str('/home/%s' % username)]} + + group_dn = "cn=%s,ou=Group,%s" % (username, ldap_base_dn) + group_attr = {'objectClass': ['posixGroup', 'top'], + 'cn': [str(username)], + 'userPassword': ['{crypt}x'], + 'gidNumber': [str(user.id)]} + + sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, ldap_base_dn) + sudo_attr = {'objectClass': ['top', 'sudoRole'], + 'cn': ['%s' % str(username)], + 'sudoCommand': ['/bin/pwd'], + 'sudoHost': ['192.168.1.1'], + 'sudoOption': ['!authenticate'], + 'sudoRunAsUser': ['root'], + 'sudoUser': ['%s' % str(username)]} + + ldap_conn = LDAPMgmt() + + ldap_conn.add(user_dn, user_attr) + ldap_conn.add(group_dn, group_attr) + ldap_conn.add(sudo_dn, sudo_attr) + + def db_del_user(username): user = User.objects.get(username=username) user.delete() @@ -111,6 +250,7 @@ def user_add(request): ssh_pwd = request.POST.get('ssh_pwd', None) ssh_key_pwd1 = request.POST.get('ssh_key_pwd1', None) is_active = request.POST.get('is_active', '1') + ldap_pwd = gen_rand_pwd(16) try: if None in [username, password, ssh_key_pwd1, name, groups, role_post, is_active]: @@ -125,12 +265,17 @@ def user_add(request): pass else: time_now = time.time() - db_add_user(username=username, password=password, name=name, email=email, - groups=groups, role=role_post, ssh_pwd=ssh_pwd, ssh_key_pwd1=ssh_key_pwd1, - is_active=is_active, date_joined=time_now) + db_add_user(username=username, + password=md5_crypt(password), + name=name, email=email, + groups=groups, role=role_post, + ssh_pwd=cryptor.encrypt(ssh_pwd), + ssh_key_pwd1=cryptor.encrypt(ssh_key_pwd1), + ldap_pwd=cryptor.encrypt(ldap_pwd), + is_active=is_active, + date_joined=time_now) msg = u'添加用户成功' - return render_to_response('juser/user_add.html', - locals()) + return render_to_response('juser/user_add.html', locals())