[GH-ISSUE #160] After restoring without the -ro arguement ldap failed #128

Open
opened 2026-02-27 08:14:29 +03:00 by kerem · 6 comments
Owner

Originally created by @wh4u on GitHub (Apr 14, 2021).
Original GitHub issue: https://github.com/lucascbeyeler/zmbackup/issues/160

ISSUE TYPE
  • Bug Report
ENVIRONMENT VERSION
  • Zmbackup Version: 1.2.5
  • Zimbra Version: Release 8.8.15.GA.3869.UBUNTU18.64 UBUNTU18_64 FOSS edition, Patch 8.8.15_P20
  • Linux Distribution & Version: Ubuntu 18.04.5 LTS

i tried to restore a mailbox using
zmbackup -r -ro inc-20210413013001 user@mydomain.tld user@mydomain.tld

command finished successfully but the mailbox is empty.

I accidently submitted the command in one of my tries, forgot to give the -ro argument
zmbackup -r inc-20210413013001 user@mydomain.tld user@mydomain.tld

And then the ldap failed.

[] FATAL: failed to initialize LDAP client
com.zimbra.cs.ldap.LdapException: LDAP error: : invalid credentials

Originally created by @wh4u on GitHub (Apr 14, 2021). Original GitHub issue: https://github.com/lucascbeyeler/zmbackup/issues/160 ##### ISSUE TYPE - Bug Report ##### ENVIRONMENT VERSION - Zmbackup Version: 1.2.5 - Zimbra Version: Release 8.8.15.GA.3869.UBUNTU18.64 UBUNTU18_64 FOSS edition, Patch 8.8.15_P20 - Linux Distribution & Version: Ubuntu 18.04.5 LTS i tried to restore a mailbox using zmbackup -r -ro inc-20210413013001 user@mydomain.tld user@mydomain.tld command finished successfully but the mailbox is empty. I accidently submitted the command in one of my tries, forgot to give the -ro argument zmbackup -r inc-20210413013001 user@mydomain.tld user@mydomain.tld And then the ldap failed. [] FATAL: failed to initialize LDAP client com.zimbra.cs.ldap.LdapException: LDAP error: : invalid credentials
Author
Owner

@nugzarg commented on GitHub (Jun 2, 2021):

The same problem with version 1.2.6. After trying to restore account from backup, zimbra is completely damaged. Some services (like zmmaiboxd, zmlogd) are crashed. Starting of these services is not possible. It seems that this tool damages zimbras LDAP database.
This tool is very dangerous! Do not use it on production server! If you wish to test it, have a backup of LDAP database (make it with /opt/zimbra/libexec/zmslapcat).

<!-- gh-comment-id:852775684 --> @nugzarg commented on GitHub (Jun 2, 2021): The same problem with version 1.2.6. After trying to restore account from backup, zimbra is completely damaged. Some services (like zmmaiboxd, zmlogd) are crashed. Starting of these services is not possible. It seems that this tool damages zimbras LDAP database. This tool is very dangerous! Do not use it on production server! If you wish to test it, have a backup of LDAP database (make it with /opt/zimbra/libexec/zmslapcat).
Author
Owner

@mathcuei commented on GitHub (Aug 6, 2021):

The same problem with version 1.2.6. After trying to restore account from backup, zimbra is completely damaged. Some services (like zmmaiboxd, zmlogd) are crashed. Starting of these services is not possible. It seems that this tool damages zimbras LDAP database.
This tool is very dangerous! Do not use it on production server! If you wish to test it, have a backup of LDAP database (make it with /opt/zimbra/libexec/zmslapcat).

Same ENVIRONMENT and same problem. Corrupt ldap and services.

<!-- gh-comment-id:894386426 --> @mathcuei commented on GitHub (Aug 6, 2021): > The same problem with version 1.2.6. After trying to restore account from backup, zimbra is completely damaged. Some services (like zmmaiboxd, zmlogd) are crashed. Starting of these services is not possible. It seems that this tool damages zimbras LDAP database. > This tool is very dangerous! Do not use it on production server! If you wish to test it, have a backup of LDAP database (make it with /opt/zimbra/libexec/zmslapcat). Same ENVIRONMENT and same problem. Corrupt ldap and services.
Author
Owner

@FlorianHeigl commented on GitHub (Feb 18, 2026):

also hit that now, I think it's just the ldap zimbra password being somehow trashed not the ldap actively destroyed. but did no one open a bug for that?
or is it this... ok... hope i can get my brain to work for a moment to finally solve this

I'll try to compare the LDAP and passwords before and after - if i ever find a reliable way to query them in zimbra. it - zimbra - being so insufferably fragile.
not to mention how zimbra package uninstall just nukes /opt/zimbra/backup - in 2026.
Or that they leave this password:
mailboxd_truststore_password="changeit" for the keystore. the ansible zimbra installers do it better.

<!-- gh-comment-id:3920946755 --> @FlorianHeigl commented on GitHub (Feb 18, 2026): also hit that now, I think it's just the ldap zimbra password being somehow trashed not the ldap actively destroyed. but did no one open a bug for _that_? or is it this... ok... hope i can get my brain to work for a moment to finally solve this I'll try to compare the LDAP and passwords before and after - if i ever find a reliable way to query them in zimbra. it - zimbra - being so insufferably fragile. not to mention how zimbra package uninstall just nukes /opt/zimbra/backup - in 2026. Or that they leave this password: `mailboxd_truststore_password="changeit"` for the keystore. the ansible zimbra installers do it better.
Author
Owner

@FlorianHeigl commented on GitHub (Feb 18, 2026):

I think it comes from this:

  ldapdelete -r -x -H "$LDAPSERVER" -D "$LDAPADMIN" -c -w "$LDAPPASS" \
    "$(grep ^dn: "$WORKDIR"/"$1"/"$2".ldiff | awk 'print $2')" > /dev/null 2>&1

just by the looks, this is falling through to a recursive delete from some undesirable spot.
i'm not sure yet due to my brain not working, and i haven't yet managed to break back into the fried slapd (root also doesn't play nicely anymore), but...

  • just from experience, this is where i would point my finger
  • it's also where the awk error occurs
  • it's also missing validation
  • there's no error handling on the delete, only on the add.
  • IIRC there's some update style ldap argument that could make this easier (delete if exists, then add or something)

suggest to flip this around, put the logic inside awk, then it'll be easier to add validation and only run if the ... idk. forgot.

first immediate change should be to do break the delete into two bits, grep from the ldif
don't process a string including workdir, store it away and see if the leftover right half is something or nothing (consider WORKDIR/ and WORKDIR// are gonna do the same thing)
parse if it's a user dn and do smart things
if so, generate a delete command
or, if lazy, have a set -u right there, then it will at least bail out.

<!-- gh-comment-id:3921448602 --> @FlorianHeigl commented on GitHub (Feb 18, 2026): I think it comes from this: ``` ldapdelete -r -x -H "$LDAPSERVER" -D "$LDAPADMIN" -c -w "$LDAPPASS" \ "$(grep ^dn: "$WORKDIR"/"$1"/"$2".ldiff | awk 'print $2')" > /dev/null 2>&1 ``` just by the looks, this is falling through to a recursive delete from some undesirable spot. i'm not sure yet due to my brain not working, and i haven't yet managed to break back into the fried slapd (root also doesn't play nicely anymore), but... - just from experience, this is where i would point my finger - it's also where the awk error occurs - it's also missing validation - there's no error handling on the delete, only on the add. - IIRC there's some update style ldap argument that could make this easier (delete if exists, then add or something) suggest to flip this around, put the logic inside awk, then it'll be easier to add validation and only run if the ... idk. forgot. first immediate change should be to do break the delete into two bits, grep from the ldif don't process a string including workdir, store it away and see if the leftover right half is something or nothing (consider WORKDIR/ and WORKDIR// are gonna do the same thing) parse if it's a user dn and do smart things if so, generate a delete command or, if lazy, have a set -u right there, then it will at least bail out.
Author
Owner

@FlorianHeigl commented on GitHub (Feb 18, 2026):

ok this is taking forever to understand and solve. I had being so slow, anyway: verified now, it definitely nukes the LDAP!

[root@zmail cn=config]# pwd
/opt/zimbra/data/ldap/config/cn=config
[root@zmail cn=config]# grep -R "dn: uid=zimbra,cn=admins,cn=zimbra" *
[root@zmail cn=config]# 

you can still do an anonymous bind, but it will not be enlightening

[zimbra@zmail ~]$ ldapsearch -x  -H $ldap_master_url -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: namingContexts 
#

#
dn:
namingContexts:

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

A backup created with slapcat (as indicated up in the thread) will be restored as such:

ldap stop
/opt/zimbra/common/sbin/slapadd -q -b "" -F \
/opt/zimbra/data/ldap/config \
-cv -l /tmp/ldapback/ldap.bak
ldap start

Test the directory is working again like this:
(should show a number above 50, I only created a few domains without content)

[zimbra@zmail ~]$ ldapsearch -x -H $ldap_master_url -D $zimbra_ldap_userdn -w $zimbra_ldap_password  |grep numEntries
# numEntries: 68
<!-- gh-comment-id:3921682745 --> @FlorianHeigl commented on GitHub (Feb 18, 2026): ok this is taking forever to understand and solve. I had being so slow, anyway: verified now, it definitely nukes the LDAP! ``` [root@zmail cn=config]# pwd /opt/zimbra/data/ldap/config/cn=config [root@zmail cn=config]# grep -R "dn: uid=zimbra,cn=admins,cn=zimbra" * [root@zmail cn=config]# ``` you can still do an anonymous bind, but it will not be enlightening ``` [zimbra@zmail ~]$ ldapsearch -x -H $ldap_master_url -b '' -s base '(objectclass=*)' namingContexts # extended LDIF # # LDAPv3 # base <> with scope baseObject # filter: (objectclass=*) # requesting: namingContexts # # dn: namingContexts: # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1 ``` A backup created with slapcat (as indicated up in the thread) will be restored as such: ``` ldap stop /opt/zimbra/common/sbin/slapadd -q -b "" -F \ /opt/zimbra/data/ldap/config \ -cv -l /tmp/ldapback/ldap.bak ldap start ``` Test the directory is working again like this: (should show a number above 50, I only created a few domains without content) ``` [zimbra@zmail ~]$ ldapsearch -x -H $ldap_master_url -D $zimbra_ldap_userdn -w $zimbra_ldap_password |grep numEntries # numEntries: 68 ```
Author
Owner

@FlorianHeigl commented on GitHub (Feb 18, 2026):

ok i got my system back up - i had to use the zmmailboximport utility you mentioned in another bug. it was just not fruitful to try on.
all settings gone but I went over the COS and applied the most important stuff.

i would suggest that you include an initial step that creates a full ldap backup if a restore is run that would branch into ldap_restore. note this would need to be a unique-id/timestamped backup or they would quickly overwrite.

imo for the 2.0 you could add a test plan item that a restore can never be a success if there's less objects than before or if a login is no longer possible that was originally possible (think like detecting degradation)

<!-- gh-comment-id:3922915165 --> @FlorianHeigl commented on GitHub (Feb 18, 2026): ok i got my system back up - i had to use the zmmailboximport utility you mentioned in another bug. it was just not fruitful to try on. all settings gone but I went over the COS and applied the most important stuff. i would suggest that you include an initial step that creates a full ldap backup if a restore is run that would branch into ldap_restore. note this would need to be a unique-id/timestamped backup or they would quickly overwrite. imo for the 2.0 you could add a test plan item that a restore can never be a success if there's less objects than before or if a login is no longer possible that was originally possible (think like detecting degradation)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/zmbackup#128
No description provided.