#!/bin/bash -e # # update-ldap-schema # # Copyright (c) 2008 Philipp Kaluza # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # STATEFILE="/var/lib/ldap-schema-common/schema.state" SCHEMADIR="/usr/share/ldap-schema-common/schema" METHODS="slapd slapd_confd" SLAPD_CONF_DIR="/etc/ldap/slapd.d/" usage() { echo "Usage:" >&2 echo " update-ldap-schema --enable " >&2 echo " update-ldap-schema --disable " >&2 exit $1 } error() { echo "update-ldap-schema: Error: $*" >&2 exit 1 } warning() { echo "update-ldap-schema: Warning: $*" >&2 } assert_statefile() { if [ ! -f "$STATEFILE" ] ; then # symlink attack ? [ -e "$STATEFILE" ] && error "$STATEFILE is weird - not touching it !" touch "$STATEFILE" >/dev/null 2>&1 || error "cannot create state file $STATEFILE." echo "## File autogenerated by update-ldap-schema, do not edit manually !" > "$STATEFILE" echo "##" >> "$STATEFILE" fi } schema_enabled() { case "$1" in /*) FILENAME=$1 ;; ../*|./*) error "You're trying to do something weird.";; *.schema) FILENAME="$SCHEMADIR/$1";; *) FILENAME="$SCHEMADIR/$1.schema";; esac if fgrep "$FILENAME" "$STATEFILE" >/dev/null 2>&1 ; then return 0 else return 1 fi } enable_schema() { assert_statefile if schema_enabled "$1" ; then warning "Schema $1 already enabled." 2>&1 return fi if [ ! -f "$FILENAME" ] ; then error "nothing known about schema \"$1\"" >&2 fi echo "$FILENAME" >> "$STATEFILE" for i in $METHODS ; do ${i}_enable "$FILENAME" done echo "Schema $1 installed into server(s)." } disable_schema() { assert_statefile STATE="$(cat $STATEFILE)" if ! schema_enabled "$1" ; then echo "Note: schema $1 already disabled" >&2 return fi STATE="$(fgrep -v $FILENAME $STATEFILE || /bin/true)" echo "$STATE" > "$STATEFILE" for i in $METHODS ; do ${i}_disable "$FILENAME" done echo "Schema $1 uninstalled from server(s)" } # server-specific methods slapd_enable() { # my job ? [ -e "/usr/sbin/slapd" -a -e "/etc/ldap/slapd.conf" ] || return echo "This looks like a job for slapd !" CONFFILE="/etc/ldap/slapd-schema.conf" # sanity checking: if [ -e "$CONFFILE" -a ! -f "$CONFFILE" ] ; then error "Cannot regenerate $CONFFILE: not a regular file." fi echo "## File autogenerated by update-ldap-schema, do not edit manually !" > "$CONFFILE" echo "##" >> "$CONFFILE" echo "" >> "$CONFFILE" echo "# Additional schema and objectClass definitions" >> "$CONFFILE" while read a ; do case "$a" in \#*) ;; *) if [ -e "$a" ] ; then echo "include \"$a\"" >> "$CONFFILE" else warning "schema file $a disappeared silently; disabling." >&2 echo "#include \"$a\"" >> "$CONFFILE" fi;; esac done <"$STATEFILE" } slapd_disable() { slapd_enable } slapd_confd_create_ldif() { bn="$(basename $1 .schema)" tmpldif="$(mktemp -t)" chmod a+r "$tmpldif" cat >"$tmpldif" <<-EOF ## LDIF version of schema $bn, autogenerated by update-ldap-schema dn: cn=$bn,cn=schema,cn=config objectClass: olcSchemaConfig cn: $bn EOF sed -n -f - "$1" >>"$tmpldif" <<-SEDMAGIC # skip comment lines /#/D # append all followup-lines to hold buffer /^[ \t]/ { H } # for lines starting a new ASN.1 block: /^[^ \t]/ { # make line starts look like LDIF s/^objectIdentifier[ \t]*/olcObjectIdentifier: / s/^attributetype[ \t]*/olcAttributeTypes: / s/^objectclass[ \t]*/olcObjectClasses: / # swap with hold buffer; old block is ready x # empty block ? then skip /^[ \t\n]*$/d # convert newlines to spaces, and print s/\n[ \t]*/ /g p d } # at the end of the file, empty the hold buffer $ { x s/\n[ \t]*/ /g p d } SEDMAGIC # old regex: s/^attributetype[ \t]*([ \t]*\(.*\)[ \t]*)[ \t]*$/olcAttributeTypes: \1/ } slapd_confd_enable() { # my job ? [ -e "/usr/sbin/slapd" -a -d "$SLAPD_CONF_DIR/cn=config/" ] || return echo "This looks like a job for slapd_config !" slapd_confd_create_ldif "$1" /etc/init.d/slapd stop # let slapadd format the file as it likes su openldap -s /usr/sbin/slapadd -- -b cn=config -F "$SLAPD_CONF_DIR" -l "$tmpldif" -s -q /etc/init.d/slapd start rm "$tmpldif" } slapd_confd_disable() { # my job ? [ -e "/usr/sbin/slapd" -a -d "$SLAPD_CONF_DIR/cn=config/" ] || return echo "This looks like a job for slapd_config !" bn="$(basename $1 .schema)" # XXX: can we make this more robust ? if [ -f "$SLAPD_CONF_DIR/cn=config/cn=schema/cn="*"$bn.ldif" ] ; then rm "$SLAPD_CONF_DIR/cn=config/cn=schema/cn="*"$bn.ldif" else warning "schema $bn missing in slapd.d" return fi /etc/init.d/slapd force-reload } #verbose=0 mode=NaN while [ $# -gt 0 ]; do case "$1" in --enable|-e) mode="enable";; --disable|-d) mode="disable";; # --verbose|-v) # verbose=1;; --help|-h) usage 0;; --test) slapd_confd_create_ldif "/usr/share/ldap-schema-common/schema/evolutionperson.schema" cat "$tmpldif" rm "$tmpldif" ;; --*|-*) usage 1;; *) case $mode in enable) enable_schema "$1";; disable) disable_schema "$1";; *) usage 1;; esac;; esac shift done # for hooks: run-parts