当前位置: 首页 > ops >正文

Openldap 数据迁移后用户条目中 memberOf 反向属性丢失

在这里插入图片描述

memberOf 反向属性丢失

最近的主旋律是降本增效,每隔一段时间就送走一批同事和服务器,也是没谁了。

历史包袱,有两套 openldap 服务,需要做腾退。

简单说就是把一台中的数据导出,然后导入到另一台中去。

导出导入本身很简单没什么可说的。

但是导入之后同事反馈查不到用户所在的组了。

这怎么可能的呢,我测过是好用的呀?

一番探究,同事用了 openldap memberof反向属性的能力。

memberOf 是一个 自动反向关联属性,当你把用户加入某个组(如 groupOfNames.member),OpenLDAP 自动在用户条目上加上 memberOf —— 但前提是:

  • 你启用了 memberof overlay
  • 并在 启用 overlay 后 添加的 member 才会触发,memberOf 属性不会自动补历史数据,你需要更新成员才会触发。这是关键。

启用 memberof overlay

# memberof_overlay.ldif
dn: olcOverlay=memberof,olcDatabase={6}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOfConfig
olcOverlay: memberof
olcMemberOfRefInt: TRUE
olcMemberOfDangling: ignore
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_overlay.ldif
systemctl restart slapd
systemctl status slapd

批量删除并重新添加组内成员

import ldapTEMP_MEMBER_DN = b"cn=temp,ou=people,dc=x,dc=com"def list_group_dns():ldap_uri = "ldap://ldap.x.com"bind_dn = "cn=ladm,dc=x,dc=com"bind_pw = "your_bind_pw"  # 替换成实际密码conn = ldap.initialize(ldap_uri)conn.simple_bind_s(bind_dn, bind_pw)# 搜索所有 groupOfNames 组group_results = conn.search_s("dc=x,dc=com",ldap.SCOPE_SUBTREE,"(objectClass=groupOfNames)",["member"])for dn, attrs in group_results:print(f"- {dn}")members = attrs.get("member", [])for member_dn in members:# 删除(如果不是唯一成员)if len(members) > 1:print(f"{dn} 成员数: {len(members)}")try:conn.modify_s(dn, [(ldap.MOD_DELETE, "member", member_dn)])# print(f"[OK] 删除成员: {member_dn.decode()}")try:print(f"重新添加成员: {member_dn.decode()} -> {dn}")# 添加conn.modify_s(dn, [(ldap.MOD_ADD, "member", member_dn)])except ldap.TYPE_OR_VALUE_EXISTS:print(f"[INFO] 已存在成员: {member_dn.decode()},跳过添加")except ldap.LDAPError as e:print(f"[ERROR] 添加成员失败: group={dn}, member={member_dn}, 错误: {e}")except ldap.NO_SUCH_ATTRIBUTE:print(f"[INFO] 成员不存在: {member_dn.decode()},跳过删除")except ldap.LDAPError as e:print(f"[ERROR] 删除成员失败: group={dn}, member={member_dn}, 错误: {e}")else:print(f"{dn} 仅剩一个成员,插入临时成员")conn.modify_s(dn, [(ldap.MOD_ADD, "member", TEMP_MEMBER_DN)])try:conn.modify_s(dn, [(ldap.MOD_DELETE, "member", member_dn)])try:print(f"重新添加成员: {member_dn.decode()} -> {dn}")# 添加conn.modify_s(dn, [(ldap.MOD_ADD, "member", member_dn)])except ldap.TYPE_OR_VALUE_EXISTS:print(f"[INFO] 已存在成员: {member_dn.decode()},跳过添加")except ldap.LDAPError as e:print(f"[ERROR] 添加成员失败: group={dn}, member={member_dn}, 错误: {e}")except ldap.NO_SUCH_ATTRIBUTE:print(f"[INFO] 成员不存在: {member_dn.decode()},跳过删除")except ldap.LDAPError as e:print(f"[ERROR] 删除成员失败: group={dn}, member={member_dn}, 错误: {e}")print(f"{dn} 删除临时成员")conn.modify_s(dn, [(ldap.MOD_DELETE, "member", TEMP_MEMBER_DN)])conn.unbind_s()def main():list_group_dns()if __name__ == "__main__":main()

测试验证

ldapsearch -x -H ldap://ldap.x.com -D "cn=adm,dc=x,dc=com" -W \-b "cn=alice,ou=people,dc=x,dc=com" "(objectClass=person)"dn: cn=alice,ou=people,dc=x,dc=com
memberOf: cn=enabled,ou=abc,ou=group,dc=x,dc=com
http://www.xdnf.cn/news/12239.html

相关文章:

  • 物料转运人形机器人适合应用于那些行业?解锁千行百业的智慧物流革命
  • 【Fiddler抓取手机数据包】
  • BT Panel密码修改
  • C语言| 指针引用数组元素
  • Windows上共享文件夹给Linux使用
  • 技术文档写作全攻略
  • 仿真每日一练 | Workbench手机后盖壳体类静力学分析
  • ROUGE评测指标深度解析
  • AD-线宽规则和过孔规则不生效
  • 在MATLAB中使用自定义的ROS2消息
  • MySQL中关于事务和锁的常见执行命令整理包括版本区别
  • Git Patch 使用详解:生成、应用与多提交合并导出
  • 炉石传说 第八次CCF-CSP计算机软件能力认证
  • 【大模型推理加速】MOE加速比与batchsize 关系
  • 某药监局药品详情sign值逆向
  • 第12期_网站搭建_几时网络验证1.3二改源码包2024 软件卡密系统 虚拟主机搭建笔记
  • linux下覆盖率测试总结
  • SQL Server相关的sql语句
  • React Hooks 指南:何时使用 useEffect ?
  • 鸿蒙APP测试实战:从HDC命令到专项测试
  • 【连接器专题】案例:FPC焊接金手指顶层和底层开窗/焊盘为什么要错位?
  • 《计算机是怎么跑起来的》第二章读后感
  • LeetCode 70 爬楼梯(Java)
  • 【深度学习】为什么2个3×3的卷积可以相当于一个5×5的卷积核?为什么3个3×3的卷积相当于一个7×7的卷积核,到底区别在哪里?我们该如何使用?
  • ESP32C3中BLE开发问题汇总
  • 数字图像处理第二次实验
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(32):そうやすいにくいすぎ(過ぎ)
  • 链表相关知识
  • 一键切换不同状态,3D数字孪生场景搭建更便捷!
  • 【iOS】cache_t分析