在Python 3.x中更改Active Directory用户密码

时间:2016-06-15 22:43:52

标签: python active-directory passwords ldap python-3.5

我正在尝试创建一个Python脚本,它将打开与运行AD的服务器的LDAP连接,获取搜索条目(在本例中为名称),搜索该条目并将该用户密码更改为随机生成的密码(以及设置登录时更改密码的选项),然后向他们发送包含新临时密码的自动安全电子邮件。

到目前为止,我已经能够连接到服务器,并搜索返回的单个DN。正在生成临时密码,并且正在发送电子邮件(尽管密码未经过哈希处理,并且电子邮件尚未安全)。但是,我找不到任何关于从这里去的地方的信息。

我发现Change windows user password with python但是我发现这对AD不起作用,我发现的Python文档中的其他LDAP似乎已经过时了2.x并且不再有效。 ldap3(https://media.readthedocs.org/pdf/ldap3/stable/ldap3.pdf)的文档似乎也没有真正提及它的任何内容,详尽的谷歌搜索没有结果。我不熟悉以前只有低水平或学术知识的这种编程,所以这有点让人沮丧,但Python是我最强的语言。

----------------编辑代码到当前状态-----------------------

#Takes input for name which will be used for search criterion
zid = input("ZID: ")
zid = str(zid).lower()
print(zid)

#Binds session to the server and opens a connection
try:
    server = ldap3.Server('ldap://<IP_Address>', get_info=all)
    conn = ldap3.Connection(server, '%s@something.com' %zid, password = "<something>", auto_bind=True) 
    print("Successfully bound to server.\n")
except:
    print("Unsucessful initialization of <IP_Address>")
    try:
        server = ldap3.Server('ldap://<IP_Address>', get_info=all)
        conn = ldap3.Connection(server, '%s@something.com' %zid, password = "<something>", auto_bind=True) 
        print("Successfully bound to server.\n")
    except:
        print("Unsucessful initialization of <IP_Address>")
        try:
            server = ldap3.Server('ldap://<IP_Address>', get_info=all)
            conn = ldap3.Connection(server, '%s@something.com', password = "<something>", auto_bind=True) %zid 
            print("Successfully bound to server.\n")
        except:
            print("Unsucessful initialization of <IP_Address>")
            sys.exit(0)

#Searches and prints LDAP entries
try:
    base_dn = 'DC=<something>,DC=<something>,DC=<something>,DC=<something>,DC=com'
    zid_filter = '(sAMAccountName=%s)' %zid
    conn.search(base_dn, zid_filter, attributes=['mail'])

    #i.e. "DN: CN=<First Last>,OU=<something>, DC= <something>
    user_dn = str(conn.entries)

    #i.e. "CN=<First Last>"
    front = user_dn.find('C')
    back = user_dn.find(',')
    user_cn = user_dn[front:back]

    #i.e. "<First Last>"
    display_name = user_cn[3:]

    #i.e. "first.last@<something>.com"
    raw_email = str(conn.entries)
    front = raw_email.find('mail: ')
    back = raw_email.find('@<something>.com')
    user_email = raw_email[front + 6:back] + '@<something>.com'
except:
    print("Could not search entries")

#Generates random 12 digit alpha-numeric password
try:
    new_password = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(12))
    print(new_password)
    print("New password successfully generated")
except:
    print("New password could not be generated")


#Set and replace AD Password
try:
    conn.extend.microsoft.modify_password(user_dn, None, new_password)
    print ("Active Directory password was set successfully!")
except:
    print('Error setting AD password')
    sys.exit(0)

在整个考验期间,出于安全考虑,如何获取/设置用户密码和哈希密码的任何建议?对于我想象的电子邮件,我可以强迫它使用HTTPS,这就足够了,但是通过new_password到服务器的连接我希望得到保护。

2 个答案:

答案 0 :(得分:2)

ldap3包含更改AD密码的特定方法,只需在生成新密码后添加以下内容:

dn = conn.entries[0].entry_get_dn() # supposing you got back a single entry conn.extend.microsoft.modify_password(dn, None, new_password)

这应该正确编码密码并将其存储在AD中。

答案 1 :(得分:0)

此代码适用于Windows 2012 R2 AD:

首先,安装最新的ldap3:

sudo pip3 install ldap

#!/usr/bin/python3

import ldap3

SERVER='127.0.0.1'
BASEDN="DC=domain,DC=com"
USER="user_domain_login_name@domain.com"
CURREENTPWD="current_password"
NEWPWD="new_password"

SEARCHFILTER='(&(userPrincipalName='+USER+')(objectClass=person))'

USER_DN=""
USER_CN=""

ldap_server = ldap3.Server(SERVER, get_info=ldap3.ALL)
conn = ldap3.Connection(ldap_server, USER, CURREENTPWD, auto_bind=True)
conn.start_tls()
print(conn)

conn.search(search_base = BASEDN,
         search_filter = SEARCHFILTER,
         search_scope = ldap3.SUBTREE,
         attributes = ['cn', 'givenName', 'userPrincipalName'],
         paged_size = 5)

for entry in conn.response:
    if entry.get("dn") and entry.get("attributes"):
        if entry.get("attributes").get("userPrincipalName"):
            if entry.get("attributes").get("userPrincipalName") == USER:
                USER_DN=entry.get("dn")
                USER_CN=entry.get("attributes").get("cn")

print("Found user:", USER_CN)

if USER_DN:
    print(USER_DN)
    print(ldap3.extend.microsoft.modifyPassword.ad_modify_password(conn, USER_DN, NEWPWD, CURREENTPWD,  controls=None))
else:
    print("User DN is missing!")