The fundamental distinction between ldapadd
and ldapmodify
lies in their default behaviors:
# ldapadd always performs ADD operations
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f entries.ldif
# ldapmodify expects MODIFY operations by default
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f changes.ldif
When you encounter the "modify operation type is missing" error, your LDIF file needs explicit operation specifications:
# Incorrect format (causes error)
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
uid: jsmith
cn: John Smith
sn: Smith
The solution is to either:
- Use
-a
flag with ldapmodify to indicate add operations - Properly format your LDIF with operation types
# Correct format for ldapmodify
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: modify
add: objectClass
objectClass: inetOrgPerson
-
add: uid
uid: jsmith
-
add: cn
cn: John Smith
For bulk operations where you need to both create new entries and update existing ones, consider these approaches:
Method 1: Combined Script
#!/bin/bash
ldapadd -x -c -D "cn=admin,dc=example,dc=com" -W -f data.ldif 2>&1 | \
grep -v "Already exists" | \
grep -q "error" && \
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f data.ldif
Method 2: LDIF with changetype
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
uid: jsmith
cn: John Smith
sn: Smith
userPassword: {SSHA}hashedpassword
dn: uid=existinguser,ou=people,dc=example,dc=com
changetype: modify
replace: cn
cn: New Name
For more complex scenarios, you might want to:
- Use
ldapsearch
first to check entry existence - Generate dynamic LDIF files based on search results
- Implement transaction handling with
ldapmodify -t
# Example of conditional modification
ldapsearch -x -b "dc=example,dc=com" "(uid=jsmith)" dn | \
awk '/dn:/ {print $0; print "changetype: modify"; \
print "replace: description"; print "description: Updated"; print "-"}' | \
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W
The fundamental distinction between ldapadd
and ldapmodify
lies in their default behaviors:
# ldapadd is actually a symbolic link to ldapmodify -a
# Default behavior is to CREATE new entries only
$ ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f entries.ldif
# ldapmodify defaults to MODIFY operations
$ ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f changes.ldif
When you encounter the modify operation type is missing
error with ldapmodify
, it's because your LDIF file needs explicit operation specifications:
# Correct format for modification:
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: modify
replace: mail
mail: j.smith@newdomain.com
-
add: title
title: Senior Developer
To handle both creation and modification in one operation, use this approach:
#!/bin/bash
LDIF_FILE="data.ldif"
TEMP_FILE=$(mktemp)
# Convert LDIF to have both add and modify operations
while read -r line; do
if [[ $line =~ ^dn: ]]; then
if grep -q "^$line$" <(ldapsearch -x -b "$line" -s base 2>/dev/null); then
echo "$line" >> "$TEMP_FILE"
echo "changetype: modify" >> "$TEMP_FILE"
else
echo "$line" >> "$TEMP_FILE"
echo "changetype: add" >> "$TEMP_FILE"
fi
else
echo "$line" >> "$TEMP_FILE"
fi
done < "$LDIF_FILE"
ldapmodify -x -c -D "cn=admin,dc=example,dc=com" -W -f "$TEMP_FILE"
rm "$TEMP_FILE"
Here are complete examples showing both operations:
# Add new entry example
dn: uid=newuser,ou=people,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
uid: newuser
cn: New User
sn: User
mail: new.user@example.com
# Modify existing entry example
dn: uid=existinguser,ou=people,dc=example,dc=com
changetype: modify
replace: mail
mail: updated.email@example.com
-
add: telephoneNumber
telephoneNumber: +1 555 123 4567
For large-scale migrations, consider these options:
# Using ldapmodify with -a (add) flag for mixed operations
$ ldapmodify -a -x -c -D "cn=admin,dc=example,dc=com" -W -f bulk_operations.ldif
# Alternative using slapadd for offline operations (requires server stop)
$ slapadd -l bulk_operations.ldif -n 0