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

Bash openldap同步AD组织数据

将AD的ou同步到openldap(可支持全量同步和增量同步)

整体思路如下:

  • 从ad导出所有的数据,然后进行参数替换以及处理,处理后的文件称为A;
  • 从openldap导出所有的数据,然后进行参数替换以及处理,处理后的文件称为B;
  • 利用A,B进行全文对比,然后将差集和增量进行添加或删除(需要注意的是,这里的需求是openldap的数据完全跟AD保持一致,即便openldap有比ad多出的数据,也会被删除掉,除非不在 同步的ou下(即修改下面的 LDAP_BASE_DN))
#!/bin/bash
# 预定义参数
AD_DOMAIN="<Your AD's domain>"
AD_ADMIN_DN="CN=<Admin account name>,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX"
AD_ADMIN_PWD="<Your admin password>"
AD_BASE_DN="DC=XXX,DC=XXX,DC=XXX"
LDAP_DOMAIN="<Your OpenLDAP's domain>"
LDAP_ADMIN_DN="cn=Manager,dc=XXX,dc=XXX,dc=XXX"
LDAP_ADMIN_PWD="<Your admin password>"
LDAP_BASE_DN="OU=xxx,DC=xxx,DC=xxx"

# 先从AD上获取OU组织信息,并保存成ldif文件
/opt/bitnami/openldap/bin/ldapsearch -x -H ldap://${AD_DOMAIN} "(&(objectClass=top)(objectClass=organizationalUnit))" dn objectClass ou -D "${AD_ADMIN_DN}" -w "${AD_ADMIN_PWD}" -b "${AD_BASE_DN}" -L | perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print' > /opt/tmp_query_adgroup.ldif

# 全文将 ad的域(dc=aaa,dc=com) 替换为openldap的域(dc=bbb,dc=net)
sed -i 's#DC=aaa,DC=com#DC=bbb,DC=net#g' /opt/tmp_query_adgroup.ldif
# 全文将 :: 替换为 :
sed -i 's#::#:#g' /opt/tmp_query_adgroup.ldif
# 去掉以#开头的行
sed '/^#/d' /opt/tmp_query_adgroup.ldif > /opt/tmp_handle_adgroup.ldif



# 读取OPENLDAP上所有的ou
/opt/bitnami/openldap/bin/ldapsearch -x -H ldap://${LDAP_DOMAIN} "(&(objectClass=top)(objectClass=organizationalUnit))" dn objectClass ou -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PWD}" -b "${LDAP_BASE_DN}" -L | perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print' > /opt/tmp_query_opgroup.ldif
# 全文将 :: 替换为 :
sed -i 's#::#:#g' /opt/tmp_query_opgroup.ldif
sed '/^#/d' /opt/tmp_query_opgroup.ldif > /opt/tmp_handle_opgroup.ldif
# 将dc,ou大写
sed -i 's#dc=#DC=#g' /opt/tmp_handle_opgroup.ldif
sed -i 's#ou=#OU=#g' /opt/tmp_handle_opgroup.ldif

#==========================================================全文比对==========================================================

#openldap比ad多出来的ou
grep -vxFf /opt/tmp_handle_adgroup.ldif /opt/tmp_handle_opgroup.ldif > /opt/tmp_del_group.ldif
sed -i "/^ou:/d" /opt/tmp_del_group.ldif
# 去掉dn
sed -i "s#dn: ##g" /opt/tmp_del_group.ldif

# opldap比ad少的ou
grep -vxFf /opt/tmp_handle_opgroup.ldif /opt/tmp_handle_adgroup.ldif > /opt/tmp_add_group.ldif
# 首次全量添加的时候,不需要添加top、organizationalUnit 属性
if ! grep -q "objectClass: top"  /opt/tmp_add_group.ldif ; then
    # 只保留dn(因为dn是唯一的)
     sed -i "/^ou:/d" /opt/tmp_add_group.ldif
     while read LINE; do
       # 如果dn中包含 / 字符,则进行转义
       if [[ "$LINE" == *"/"* ]]; then
         LINE="${LINE//\//\\/}"
       fi
       tmp_ou=$(echo $LINE | grep -o 'OU=[^,]*' | head -n 1)
       sed -i "s#^OU=#OU: #g" /opt/tmp_add_group.ldif
       sed -i "/$LINE/a"$tmp_ou /opt/tmp_add_group.ldif
     done < /opt/tmp_add_group.ldif
     sed -i "/^OU:/i\objectClass: top" /opt/tmp_add_group.ldif
     sed -i "/^OU:/i\objectClass: organizationalUnit" /opt/tmp_add_group.ldif
fi
# changetype: add必须位于第二行,也就是dn下方
sed -i "/^dn:/a\changetype: add" /opt/tmp_add_group.ldif

# 添加换行符
sed -i "/^OU:/a\\\n" /opt/tmp_add_group.ldif
sed -i "/^ou:/a\\\n" /opt/tmp_add_group.ldif


#====================================对数据进行增加或者删除====================================

# openldap添加缺少ad的ou
/opt/bitnami/openldap/bin/ldapmodify -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -f  /opt/tmp_add_group.ldif >& /opt/tmp_add_group_rec.log
# 防止第一次执行不成功(因为ou是无序的)
while read LINE; do
  if grep -q "ldap_add: No such object (32)" /opt/tmp_add_group_rec.log ; then
    /opt/bitnami/openldap/bin/ldapmodify -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -f  /opt/tmp_add_group.ldif >& /opt/tmp_add_group_rec.log
    $(sleep 1s)
  fi
done < /opt/tmp_add_group_rec.log

# 最后一步执行 openldap删除多出来的ou
while read LINE; do
  /opt/bitnami/openldap/bin/ldapdelete  -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -r ${LINE} > /dev/null 2>&1
done < /opt/tmp_del_group.ldif

http://www.kler.cn/a/132527.html

相关文章:

  • 深入理解Redis(七)----Redis实现分布式锁
  • django-ninja 实现cors跨域请求
  • 高斯数据库Postgresql死锁和锁表解决方法
  • 深度解读混合专家模型(MoE):算法、演变与原理
  • MySQL 中的数据排序是怎么实现的
  • Java基础-Java中的常用类(上)
  • HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理
  • bug-xss 攻击漏洞问题
  • 技术架构 - 应用数据分离,应用服务集群架构
  • asp.net core mvc 控制器使用配置
  • 专注于绘画,不受限制!尝试Growly Draw for Mac的快速绘画应用
  • spider 网页爬虫中的 AWS 实例数据获取问题及解决方案
  • 阿里云服务器 手动搭建WordPress(CentOS 8)
  • AI Navigation导航系统_unity基础开发教程
  • 带你快速掌握Linux最常用的命令(图文详解)- 最新版(面试笔试常考)
  • 如何使用Java实现权限认证和登录jwt
  • 深入解析 binding:“required“ 与 validate:“required“ 的区别
  • python时间变化与字符串替换技术及读JSON文件等实践笔记
  • 如何利用TSINGSEE青犀智能分析网关算法从人员、设备、行为三大角度进行监狱智能化升级改造
  • 【LabVIEW学习】2.for,while,事件
  • UE5制作场景时的小技巧和注意事项
  • 【开源】基于Vue.js的音乐偏好度推荐系统的设计和实现
  • 在 el-table 中嵌入 el-checkbox el-input el-upload 多组件,实现复杂业务场景
  • 深度学习(五)softmax 回归之:分类算法介绍,如何加载 Fashion-MINIST 数据集
  • Java重写和重载的区别,
  • QT 使用mysql