跳到主要内容

ldap批量操作

ldap批量操作组

shell脚本方式

编辑组文件

cat > ous.txt << EOF
ou_name1
ou_name2
ou_name3
EOF

批量增加组

说明
  • 全称Organizational Unit

  • 用途:表示一个组织单元(相当于文件夹 / 部门目录),主要用来分组

  • 例子

    ou=People,dc=example,dc=com
    ou=Groups,dc=example,dc=com
    • People 可以存放用户对象
    • Groups 可以存放组对象
  • 基本配置文件

    参数说明
    dn: ou=People,dc=example,dc=com完整路径(OU=People 在 dc=example,dc=com 下面)
    objectClass: top所有结构类(structural objectClass)的 基类
    objectClass: organizationalUnit表示这是一个 OU
    ou: PeopleOU 的名字
    dn: ou=People,dc=example,dc=com
    objectClass: top
    objectClass: organizationalUnit
    ou: People
cat > add-ous.sh << 'AAA'
#!/bin/bash

# ========================
# 配置部分
# ========================
BASE_DN="dc=ops,dc=com" # LDAP 根
BIND_DN="cn=admin,dc=ops,dc=com" # 管理员账号
BIND_PWD="admin" # 管理员密码
LDAP_HOST="localhost" # LDAP 域名/IP
LDAP_HOST_PORT="389" # LDAP 端口

OU_FILE="ous.txt" # OU 文件,每行一个 OU 名

# ========================
# DN 转义函数(RFC4514)
# ========================
escape_dn() {
local dn="$1"
dn="${dn//\\/\\\\}" # \ 转义
dn="${dn//+/\\+}" # + 转义
dn="${dn//#/\\#}" # # 转义
dn="${dn//,/\\,}" # , 转义
dn="${dn//=/\\=}" # = 转义
dn="${dn//;/\\;}" # ; 转义
dn="${dn//</\\<}" # < 转义
dn="${dn//>/\\>}" # > 转义
dn="${dn//\"/\\\"}" # " 转义
echo "$dn"
}

# ========================
# 批量创建 OU
# ========================
while read -r OUNAME
do
# 跳过空行或注释
[[ -z "$OUNAME" || "$OUNAME" =~ ^# ]] && continue

ESCAPED_OUNAME=$(escape_dn "$OUNAME")
DN="ou=${ESCAPED_OUNAME},${BASE_DN}"

# 检查是否已存在
if ldapsearch -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" -b "${DN}" ou | grep -q "^ou:"; then
echo "[$OUNAME] already exists, skip."
else
# 创建 OU
ldapadd -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" <<EOF
dn: ${DN}
objectClass: top
objectClass: organizationalUnit
ou: ${OUNAME}
EOF
if [ $? -eq 0 ]; then
echo "[$OUNAME] created successfully."
else
echo "[$OUNAME] failed to create!"
fi
fi

done < "$OU_FILE"
AAA

批量删除组

cat > delete-entries.sh << 'EOF'
#!/bin/bash

# ========================
# 配置部分
# ========================
BASE_DN="dc=ops,dc=com" # LDAP 根
BIND_DN="cn=admin,dc=ops,dc=com" # 管理员账号
BIND_PWD="admin" # 管理员密码
LDAP_HOST="localhost"
LDAP_HOST_PORT="389"

ENTRY_FILE="entries.txt" # 待删除条目文件,每行一个 cn:xxx 或 ou:xxx

# ========================
# DN 转义函数(RFC4514)
# ========================
escape_dn() {
local dn="$1"
dn="${dn//\\/\\\\}" # \ 转义
dn="${dn//+/\\+}" # + 转义
dn="${dn//#/\\#}" # # 转义
dn="${dn//,/\\,}" # , 转义
dn="${dn//=/\\=}" # = 转义
dn="${dn//;/\\;}" # ; 转义
dn="${dn//</\\<}" # < 转义
dn="${dn//>/\\>}" # > 转义
dn="${dn//\"/\\\"}" # " 转义
echo "$dn"
}

# ========================
# 批量删除条目
# ========================
while read -r LINE
do
# 跳过空行或注释
[[ -z "$LINE" || "$LINE" =~ ^# ]] && continue

TYPE="${LINE%%:*}"
NAME="${LINE#*:}"
NAME="${NAME#"${NAME%%[![:space:]]*}"}" # 去掉前导空格
ESCAPED_NAME=$(escape_dn "$NAME")
DN="${TYPE}=${ESCAPED_NAME},${BASE_DN}"

# 检查条目是否存在
if ldapsearch -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" -b "${DN}" "${TYPE}" | grep -q "^${TYPE}:"; then
ldapdelete -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" "${DN}"
if [ $? -eq 0 ]; then
echo "[$TYPE:$NAME] deleted successfully."
else
echo "[$TYPE:$NAME] failed to delete!"
fi
else
echo "[$TYPE:$NAME] does not exist, skip."
fi

done < "$ENTRY_FILE"
EOF

ldap批量操作用户

shell脚本方式

编辑用户文件

cat > users.txt << EOF
user1
user2
user3
EOF

批量增加用户

说明

此脚本同时支持两种 用户 DN 格式

  • 模式1:只有 CNuid=xxx,cn=xxx,dc=ops,dc=com
  • 模式2:OU + CNuid=xxx,ou=xxx,cn=xxx,dc=ops,dc=com
cat > add-users.sh << 'AAA'
#!/bin/bash

# ======================
# 配置部分
# ======================
BASE_SUFFIX="dc=ops,dc=com"
USER_OU="" # 可选,留空则不加 OU,例如 "ou_name1"
GROUP_CN="go" # 组 CN,例如 "go"
GROUP_GID=1000
PASSWORD="{SSHA}uUFY4EJIccmbnIZBPMiq06QK4HG9vO/a" # 默认密码 admin
EMAIL_DOMAIN="ops.com"
LOGIN_SHELL=/bin/bash

BIND_DN="cn=admin,${BASE_SUFFIX}"
BIND_PWD="admin"
LDAP_HOST="localhost"
LDAP_HOST_PORT="389"

UID_START=1001
USER_FILE="users.txt"

# ======================
# 拼接用户 DN
# ======================
while read -r USERNAME
do
EMAIL="${USERNAME}@${EMAIL_DOMAIN}"
USER_UID=$UID_START

if [ -n "$USER_OU" ]; then
USER_DN="uid=${USERNAME},cn=${GROUP_CN},ou=${USER_OU},${BASE_SUFFIX}"
else
USER_DN="uid=${USERNAME},cn=${GROUP_CN},${BASE_SUFFIX}"
fi

echo "==> 正在创建 ${USER_DN}"

ldapadd -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" <<EOF
dn: ${USER_DN}
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
cn: ${USERNAME}
sn: ${USERNAME}
uid: ${USERNAME}
uidNumber: ${USER_UID}
gidNumber: ${GROUP_GID}
homeDirectory: /home/${USERNAME}
loginShell: ${LOGIN_SHELL}
mail: ${EMAIL}
userPassword: ${PASSWORD}
EOF

UID_START=$((UID_START+1))

done < "$USER_FILE"
AAA

批量删除用户

删除每一个用户前有确认提示

cat > del-users.sh << EOF
#!/bin/bash

BASE_DN="cn=go,dc=ops,dc=com"
BIND_DN="cn=admin,dc=ops,dc=com"
BIND_PWD="admin"
LDAP_HOST="localhost"
LDAP_HOST_PORT="389"
USER_FILE="users.txt"

while read -r USERNAME
do
DN="uid=\${USERNAME},\${BASE_DN}"

# 二次确认提示,保证读取终端
read -p "Are you sure you want to delete \${DN}? [y/N] " CONFIRM </dev/tty
if [[ "\$CONFIRM" =~ ^[Yy]\$ ]]; then
echo "Deleting \${DN} ..."
ldapdelete -x -H ldap://\${LDAP_HOST}:\${LDAP_HOST_PORT} -D "\${BIND_DN}" -w "\${BIND_PWD}" "\${DN}"
if [ \$? -eq 0 ]; then
echo "[\${USERNAME}] deleted successfully."
else
echo "[\${USERNAME}] failed to delete!"
fi
else
echo "Skipping \${DN}."
fi

done < "\$USER_FILE"
EOF

删除一个组前有确认提示

cat > del-go-users.sh << 'EOF'
#!/bin/bash

# LDAP 配置
BASE_DN="cn=go,dc=ops,dc=com"
BIND_DN="cn=admin,dc=ops,dc=com"
BIND_PWD="admin"
LDAP_HOST="localhost"
LDAP_HOST_PORT="389"
USER_FILE="users.txt"

# 提示即将删除的组
echo "You are about to delete all users under the group: ${BASE_DN}"
read -p "Are you sure? [y/N] " CONFIRM </dev/tty

if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then
while read -r USERNAME
do
DN="uid=${USERNAME},${BASE_DN}"
echo "Deleting ${DN} ..."
ldapdelete -x -H ldap://${LDAP_HOST}:${LDAP_HOST_PORT} -D "${BIND_DN}" -w "${BIND_PWD}" "${DN}"
if [ $? -eq 0 ]; then
echo "[${USERNAME}] deleted successfully."
else
echo "[${USERNAME}] failed to delete!"
fi
done < "$USER_FILE"
else
echo "Deletion cancelled."
fi
EOF
Bottom GIF
Top GIF