#!/usr/bin/env python import ldap import commands import array from Crypto.Hash import MD4 from Crypto.Cipher import DES LDAP_SERVER_URI = "ldap://localhost:389" LDAP_SERVER_SUFFIX = "dc=watercooler" LDAP_ROOT_DN = "cn=Directory Manager" LDAP_ROOT_DN_PASSWD = "adminpasswd" server = ldap.initialize (LDAP_SERVER_URI) server.bind_s (LDAP_ROOT_DN, LDAP_ROOT_DN_PASSWD, ldap.AUTH_SIMPLE) def add_samba_user_attrs (server, suffix, username, samba_user_sid, samba_group_sid, nt_password, lm_password): server.modify_s ("uid=%s,ou=People,%s" % (username, suffix), [ ( ldap.MOD_ADD, "objectClass", [ "sambaSamAccount" ] ), ( ldap.MOD_ADD, "sambaSID", [ samba_user_sid ] ), ( ldap.MOD_ADD, "sambaPrimaryGroupSID", [ samba_group_sid ] ), ( ldap.MOD_ADD, "sambaNTPassword", [ nt_password ] ), ( ldap.MOD_ADD, "sambaLMPassword", [ lm_password ] ) ]) SAMBA_RID_MULTIPLIER = 2 SAMBA_RID_BASE = 1000 SAMBA_USER_RID_TYPE = 0x0 SAMBA_USER_GID_TYPE = 0x1 SAMBA_LM_HASH_MAGIC = "KGS!@#$%" def get_machine_sid (): output = commands.getoutput ("net getlocalsid") for line in output.split ("\n"): if line.startswith ("SID for domain"): parts = line.split (":") if len (parts) >= 2: return parts[1].strip () return None def get_user_sid (uid): machine_sid = get_machine_sid () user_rid = ((uid * SAMBA_RID_MULTIPLIER) + SAMBA_RID_BASE) | SAMBA_USER_RID_TYPE return machine_sid + "-" + str (user_rid) def get_group_sid (gid): machine_sid = get_machine_sid () group_rid = ((gid * SAMBA_RID_MULTIPLIER) + SAMBA_RID_BASE) | SAMBA_USER_GID_TYPE return machine_sid + "-" + str (group_rid) def get_nt_password (plaintext): hash = MD4.new () hash.update (plaintext.encode ("utf-16-le")) return hash.hexdigest ().upper () def get_lm_password (plaintext): def lm_hash (pw7): a7 = array.array ("B", pw7.upper ().encode ("850")) while len (a7) < 7: a7.append (0) a8 = array.array ("B") a8.append ( a7[0] >> 1 ) a8.append (((a7[0] & 0x01) << 6) | (a7[1] >> 2)) a8.append (((a7[1] & 0x03) << 5) | (a7[2] >> 3)) a8.append (((a7[2] & 0x07) << 4) | (a7[3] >> 4)) a8.append (((a7[3] & 0x0F) << 3) | (a7[4] >> 5)) a8.append (((a7[4] & 0x1F) << 2) | (a7[5] >> 6)) a8.append (((a7[5] & 0x3F) << 1) | (a7[6] >> 7)) a8.append ( a7[6] & 0x7F ) for i in range (8): a8[i] <<= 1 return DES.new (a8.tostring ()).encrypt (SAMBA_LM_HASH_MAGIC).encode ("hex").upper () return lm_hash (plaintext[0:7]) + lm_hash (plaintext[7:14]) add_samba_user_attrs (server, LDAP_SERVER_SUFFIX, username = "testuser", samba_user_sid = get_user_sid (1000), samba_group_sid = get_group_sid (1000), nt_password = get_nt_password ("testuser"), lm_password = get_lm_password ("testuser"))