使用Python在Microsoft AD中创建“有效”用户

e4eetjau  于 2023-03-21  发布在  Python
关注(0)|答案(2)|浏览(118)

有没有人成功地使用Python在Active Directory中创建了一个有效的“工作”用户?
我已经尽了最大的努力使用https://pypi.org/project/python-ldap/模块,但我的生活不能让它创建用户...
我最接近的一次是使用这段代码:

conn = ldap.initialize('ldap://' + ldap_hostname)
conn.protocol_version = 3 
conn.set_option(ldap.OPT_REFERRALS, 0)
conn.simple_bind_s(ldap_admin_dn, ldap_admin_pw)

attrs = {}
attrs['objectClass'] = ['top'.encode('utf-8'), 'person'.encode('utf-8'), 'organizationalPerson'.encode('utf-8'), 'user'.encode('utf-8')]
attrs['cn'] = "Test User".encode("utf-8")
attrs['userPrincipalName'] = "testuser@domain.com".encode("utf-8")
attrs['displayName'] = "Test User".encode("utf-8")
attrs['givenName'] = "Test".encode("utf-8")
attrs['sn'] = "User".encode("utf-8")
attrs['sAMAccountName'] = "testuser".encode("utf-8")
attrs['mail'] = "testuser@domain.com".encode("utf-8")
attrs['primaryGroupID'] = "513".encode("utf-8")

# Convert our dict to nice syntax for the add-function using
ldif = modlist.addModlist(attrs)

# Set up user dn
user_cn = "Test User"
user_dn = "CN={},{}".format(user_cn, ldap_users_ou_dn)

# Create user
conn.add_s(user_dn, ldif)

# Set initial password
password_value = "LaLaLaLaLa123123123!".encode('utf-16-le')

add_pass = [(ldap.MOD_REPLACE, 'unicodePwd', [password_value])]
conn.modify_s(user_dn, add_pass)

# Set user account control
mod_acct = [(ldap.MOD_REPLACE, 'userAccountControl', '66048')]
conn.modify_s(user_dn, mod_acct)

但不幸的是,它在conn.add_s上失败,并显示以下错误消息:

"errorMessage": "{'msgtype': 105, 'msgid': 2, 'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': \[\], 'info': '00000529: SvcErr: DSID-031A124C, problem 5003 (WILL\_NOT\_PERFORM), data 0\\n'}", "errorType": "UNWILLING\_TO\_PERFORM",

我是不是推错了参数?我是不是编码得不好?我做错了什么?任何帮助或“一段代码”,你们实际上用来使它工作将是可怕的...
同样,这是专门用于连接到MICROSOFT AD,而不是OpenLDAP。
谢谢!

yqkkidmi

yqkkidmi1#

“不愿意执行”总是意味着你做错了什么-通常分配一个不允许的值。
在你的情况下,我怀疑是这条线:

attrs['primaryGroupID'] = "513".encode("utf-8")

primaryGroupID属性是一个整数,而不是一个字符串。所以它应该看起来像这样:

attrs['primaryGroupID'] = 513

我不确定是否需要对所有字符串值使用.encode("utf-8")。如果在纠正primaryGroupID值后仍然不起作用,请尝试删除编码。

n8ghc7c1

n8ghc7c12#

unicodePwd的值必须 * 包括引号 * 作为字符串的一部分(大概是为了让服务器可以确认使用了正确的UTF-16编码),see protocol specification。服务器将在哈希密码之前丢弃引号。

attrs["unicodePwd"] = "\"Hello!\"".encode("utf-16le")

你应该在创建条目时立即设置unicodePwd,特别是userAccountControl--没有必要通过单独的修改操作来这样做。
另一方面,如果primaryGroupID是默认值,则不需要设置primaryGroupID;别说了。
我还建议使用常量,甚至enum,来处理像userAccountControl属性这样的东西,而不是硬编码“魔术数字”:

class UacFlags(enum.IntEnum):
    NORMAL_ACCOUNT       = 0x200
    DONT_EXPIRE_PASSWORD = 0x10000
    #NormalAccount        = 0x200
    #DontExpirePassword   = 0x10000

flags = int(UacFlags.NORMAL_ACCOUNT | UacFlags.DONT_EXPIRE_PASSWORD)

attrs["userAccountControl"] = str(flags).encode()

相关问题