You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python ldap3修改用户sn属性报错:属性只读,求助原因

解决ldap3修改LDAP用户属性提示“attribute 'sn' is read only”的问题

问题重现

使用Python的ldap3库修改LDAP用户的sn(姓氏)等属性时,报错提示“attribute 'sn' is read only”,但同一账号通过ldp.exe工具可正常修改,确认账号具备权限且属性并非只读。

排查与解决方案

1. 移除本地entry对象的无效修改

代码中先修改本地entry.sn = new_last_name,再调用modify接口属于冗余操作——本地entry的修改不会同步到服务器,反而可能引发逻辑冲突。直接删除这行代码,保留modify调用即可:

if confirmation == '1':
    # 移除 entry.sn = new_last_name 这行
    ldap_connection.modify(entry.entry_dn, {'sn': [(MODIFY_REPLACE, [new_last_name])]})
    print("Nazwisko użytkownika zostało zmienione.")

2. 确保LDAP连接启用加密并绑定成功

部分LDAP服务器(如Active Directory)拒绝明文连接下的写入操作,需使用LDAPS(636端口)或StartTLS加密连接,同时确认账号绑定状态正常:

from ldap3 import Server, Connection, MODIFY_REPLACE, SUBTREE, START_TLS

# 方式1:使用LDAPS加密连接
server = Server('dc.test.local', use_ssl=True, port=636)
# 方式2:使用StartTLS加密
# server = Server('dc.test.local')

ldap_connection = Connection(server, 
                             user='CN=你的操作账号,DC=test,DC=local', 
                             password='账号密码', 
                             auto_bind=True)
                             # auto_bind_strategy=START_TLS)  # 用StartTLS时添加此行

3. 验证modify操作的参数格式

确保modify方法中属性值为列表格式(即使是单个值),代码中[new_last_name]的写法是正确的,避免传入单个字符串而非列表。

4. 添加连接与查询结果验证

在代码中增加绑定状态、用户查询结果的验证,提前排查异常:

# 验证连接绑定是否成功
if not ldap_connection.bind():
    print(f"绑定失败: {ldap_connection.result}")
    exit()

# 验证是否查询到用户
ldap_connection.search(...)
if not ldap_connection.entries:
    print("未找到对应PESEL的用户")
    ldap_connection.unbind()
    exit()

修正后的完整代码示例

from ldap3 import Server, Connection, MODIFY_REPLACE, SUBTREE

def is_valid_serial_number(pesel):
    # 保留你的PESEL验证逻辑
    return len(pesel) == 11

# 初始化加密LDAP连接
server = Server('dc.test.local', use_ssl=True, port=636)
ldap_connection = Connection(server, 
                             user='CN=Admin,DC=test,DC=local', 
                             password='AdminPass', 
                             auto_bind=True)

while True:
    pesel = input("Wprowadź PESEL użytkownika dla którego chcesz zmienić nazwisko: ")
    if not is_valid_serial_number(pesel):
        print("Nieprawidłowy numer PESEL.")
        continue
    break

ldap_connection.search(search_base=f'dc=test,dc=local', 
                       search_filter=f'(serialNumber={pesel})', 
                       search_scope=SUBTREE, 
                       attributes=['sAMAccountName', 'givenName', 'sn', 'serialNumber','cn'])

if not ldap_connection.entries:
    print("未找到对应PESEL的用户")
    ldap_connection.unbind()
    exit()

entry = ldap_connection.entries[0]
dn = entry.entry_dn
print(dn)
new_last_name = input("Wprowadź nowe nazwisko: ")

print(entry.entry_attributes_as_dict)
old_last_name = entry['sn'].value
print(f"Potwierdź, czy chcesz zmienić nazwisko dla użytkownika {entry.sAMAccountName.value} z {old_last_name} na {new_last_name}.")

confirmation = input("1. Tak\n2. Nie\nWybierz opcję: ")

if confirmation == '1':
    result = ldap_connection.modify(entry.entry_dn, {'sn': [(MODIFY_REPLACE, [new_last_name])]})
    if result:
        print("Nazwisko użytkownika zostało zmienione.")
    else:
        print(f"修改失败: {ldap_connection.result}")
else:
    print("Anulowano zmianę nazwiska.")

ldap_connection.unbind()

内容的提问来源于stack exchange,提问作者godelko ツ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:12:35