#!/bin/bash # Ansible-generated LDAP backup script # # usage: ldap_backup.sh DN DIRECTORY KEEP # where: # DN is the base DN to backup # DIRECTORY is where to save the backup # KEEP number of backups to keep # utility functions msg(){ ${VERBOSE:-true} && echo ${@} ; } assert(){ [[ ${?} -eq 0 ]] || { [[ -n ${1} ]] && { msg ; msg ${@} ; } ; exit 1 ; } } warn(){ [[ ${?} -eq 0 ]] || { [[ -n ${1} ]] && msg ${@} ; return 1 ; } } # All DNs configured on this server ALL_DNs="{{ backup_domains | default([]) | union(['cn=config']) | join(' ')}}" BACKUP_DIR="{{ openldap_backup_dir }}" # Restaurar backup dado por argumento, puede ser un DN o un archivo de backup restaurar(){ local ARG=${1} local DN="" local LDIF="" if [[ -f "${ARG}" ]] then # el argumento es un archivo, se debe adivinar el DN DN="$(zcat -f ${ARG}| head -n1 | egrep '^dn:' | awk '{print $2}')" LDIF="$(realpath ${ARG})" else # se toma el argumento como un DN, se debe encontrar el archivo DN="${ARG}" LDIF=$(find ${BACKUP_DIR} -type f -iname "*.ldif*" -print0 | xargs -0 zegrep -l "^dn: ${DN}\$" | sort | tail -n1) fi [[ -n "${LDIF}" ]] assert "ERROR: no se encontró un backup para restaurar ${DN}. " \ "Por favor indíquelo como argumento." [[ "$(systemctl is-active slapd.service)" == "inactive" ]] assert "FATAL: El servicio slapd.service está activo." # # validar que el DN es el correcto # zcat -f "${LDIF}" | head -n1 | egrep -q "^dn: ${DN}\$" # assert -e "FATAL: El archivo ${LDIF} no corresponde al DN ${DN}.\n\n" \ # "Se esperaba como primer línea... dn: ${DN} \n" \ # "Sin embargo, se encontró........ $( zcat -f "${LDIF}" | head -n1 )\n" # Determinar directorio de la base de datos y opciones de slapadd # Caso general (datos) DATA_DIR="/var/lib/ldap/${DN}" SLAPADD_SW="{{ '-w' if openldap_provider else '' }}" # Caso especial cn=config [[ "${DN}" == "cn=config" ]] && { DATA_DIR="/etc/ldap/slapd.d" SLAPADD_SW="-F /etc/ldap/slapd.d/" } # Nombre de la carpeta de backup DATA_DIR_BAK="${DATA_DIR}.backup-$(date +%Y%m%d%H%M%S)" msg "Guardando backup en ${BACKUP_DIR}" mv "${DATA_DIR}" "${DATA_DIR_BAK}" mkdir "${DATA_DIR}" msg "Cargando datos de ${DN} desde ${LDIF}" zcat -f "${LDIF}" | slapadd -b "${DN}" ${SLAPADD_SW} assert -e "FATAL: Error durante la restauración.\n" \ "Puede volver al estado anterior renombrando ${DATA_DIR_BAK} -> ${DATA_DIR} " \ "antes de volver a iniciar slapd." msg "Cambiando owner de ${DATA_DIR}" chown -R openldap:openldap "${DATA_DIR}" msg "Se ha restaurado correctamente ${DN}." return 0 } ayuda() { cat< /dev/null assert "ERROR: no se encuentra 'slapadd', por favor instale ldap-utils." ${INTERACTIVO} && { msg -e "Se restaurarán los siguientes DNs/archivos:\n ${ARGS}" msg "Esto causará la PÉRDIDA DE LOS DATOS ACTUALES en el directorio." msg -n "¿Confirma que está seguro? (s/n) " read TECLA [[ "${TECLA,,}" == "s" ]] || { msg "Abortando operación: no se realiza ningún cambio." exit 3; } } # Detener servidor antes de restaurar msg "Deteniendo servicio slapd..." systemctl stop slapd.service # restaurar todo for ARG in ${ARGS} do restaurar ${ARG} done msg "Reiniciando servicio slapd..." systemctl start slapd.service