Skip to content

Instantly share code, notes, and snippets.

@jaseg
Last active March 26, 2024 14:21
Show Gist options
  • Save jaseg/8577024 to your computer and use it in GitHub Desktop.
Save jaseg/8577024 to your computer and use it in GitHub Desktop.
Convert openldap .schema files to .ldif files

This is old!

Hey there,

occassionally, people still seem to stumble across this script because it seems it shows up in some search results. Please be aware that I made this script ten years ago, and by now, there is probably a better way to achieve the same result.

Have a nice day!

#!/usr/bin/env bash
# convert OpenLDAP schema file to LDIF file
#
# Copyright 2012 NDE Netzdesign und -entwicklung AG, Hamburg
# Written by Jens-U. Mozdzen <jmozdzen@nde.ag>
# Copyright 2014 jaseg <github@jaseg.net>
#
# Permission is granted to use, modify and redistribute this file as long as
# - this copyright notice is left unmodified and included in the final code
# - the original author is notified via email if this code is re-distributed as part of a paid-for deliverable
# - the original author is not held liable for any damage, loss of profit, efforts or inconvenience of any sorts
# that may result from using, modifying or redistributing this software.
#
# Use at your own risk - this code may not be suitable for your needs or even cause damage when used.
# If you find any problems with this code, please let the author know so that it can be fixed or at least others
# can be warned.
#
# Usage: schema2ldif.sh <fully-qualified schema file name>
#
# This program will try to convert the source file to an LDIF-style file, placing the resulting .ldif file
# in the current directory.
rc=0
if [ $# -gt 0 ] ; then
slaptest=$(which slaptest 2>/dev/null ||ls /usr/sbin/slaptest||echo "")
if [ -x "$slaptest" ] ; then
schemaFile=$(readlink -f "$1")
shift
localdir=$(pwd)
if [ -r "$schemaFile" ] ; then
targetFile=$(basename "$schemaFile" .schema).ldif
if [ ! -e "$localdir/$targetFile" ] ; then
echo "$0: converting $schemaFile to LDIF $localdir/$targetFile"
# create temp dir and config file
tmpDir=$(mktemp -d)
cd "$tmpDir"
touch tmp.conf
for dependency in "$@"
do echo "include $dependency" >> tmp.conf
done
echo "include $schemaFile" >> tmp.conf
# convert
"$slaptest" -f tmp.conf -F "$tmpDir"
# 3. rename and sanitize
cd cn\=config/cn\=schema
filenametmp=$(echo cn\=*"$targetFile")
sed -r -e 's/^dn: cn=\{0\}(.*)$/dn: cn=\1,cn=schema,cn=config/' \
-e 's/cn: \{0\}(.*)$/cn: \1/' \
-e '/^structuralObjectClass: /d' \
-e '/^entryUUID: /d' \
-e '/^creatorsName: /d' \
-e '/^createTimestamp: /d' \
-e '/^entryCSN: /d' \
-e '/^modifiersName: /d' \
-e '/^modifyTimestamp: /d' \
-e '/^# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify./d' \
-e '/^# CRC32 [0-9a-f]+/d' \
-e 's/^cn: \{[0-9]*\}(.*)$/cn: \1/' \
-e 's/^dn: cn=\{[0-9]*\}(.*)$/dn: cn=\1,cn=schema,cn=config/' < "$filenametmp" > "$localdir/$targetFile"
# clean up
echo "$0: LDIF file successfully created as $localdir/$targetFile"
rc=0
rm -rf "$tmpDir"
else
echo "$0: target file $localdir/$targetFile already exists, aborting." >&2
rc=3
fi
else
echo "$0: source file $schemaFile could not be read, aborting." >&2
rc=2
fi
else
echo "$0: could not locate slaptest binary, exiting." >&2
rc=1
fi
else
echo "$0: usage: $0 <schemafile>" >&2
rc=99
fi
exit $rc
@quanah
Copy link

quanah commented Apr 4, 2022

This "tool" shows a complete lack of comprehension on how to use OpenLDAP and cn=config, I'd generally advise avoiding it. OpenLDAP ships with all standard schema in both a ".schema" file (for slapd.conf) and ".ldif" file for cn=config. ".ldif" file can be loaded into a cn=config database using the "ldapadd" utility (if it is online) or if one is doing a first time load of a cn=config database, one can simply use an include statement

@dukerobillard
Copy link

This "tool" shows a complete lack of comprehension on how to use OpenLDAP and cn=config, I'd generally advise avoiding it. OpenLDAP ships with all standard schema in both a ".schema" file (for slapd.conf) and ".ldif" file for cn=config. ".ldif" file can be loaded into a cn=config database using the "ldapadd" utility (if it is online) or if one is doing a first time load of a cn=config database, one can simply use an include statement

So, just recently, I had a .schema file that I wanted to load into a fresh OpenLDAP 2.6.2 which is using cn=config. I wanted to add it to my list of includes (after core.ldif and cosine.ldif and so on. But I didn't have an .ldif version. What should I have done, if not what this script does? I'm new to OpenLDAP, and I'm eager to do things the right way....

@quanah
Copy link

quanah commented May 10, 2022

Here's an example of how I converted the eduperson.schema file to a LDIF formatted schema file that can be used with ldapadd, etc:

mkdir -p /tmp/ldap/slapd.d
cp eduperson.schema /tmp/ldap
cd /tmp

I then created a slapd.conf file in /tmp/ldap with the following contents:

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /tmp/ldap/eduperson.schema

Then I converted this configuration over to cn=config format:

slaptest -f /tmp/ldap/slapd.conf -F /tmp/ldap/slapd.d

Then I exported just that schema file:

slapcat -n 0 -F /tmp/ldap/slapd.d -H "ldap:///???(cn={2}eduperson)" | grep -v ^structuralObjectClass: | grep -v ^entryUUID: | grep -v ^creatorsName: | grep -v ^createTimestamp: | grep -v ^entryCSN: | grep -v ^modifiersName: | grep -v ^modifyTimestamp: | sed -e "s/{2}eduperson/eduperson/" > eduperson.ldif

In the above example, the eduperson schema gets a weight of 2 because it was the 3rd schema file listed (core, cosine, eduperson). But now the end result is, I permanently have a converted form of the schema file I can use correctly with cn=config. We strip out the operational attributes as we would want those created fresh at import time (whether slapadd or ldapadd)

For an example of using an include statement with a cn=config database to use with slapadd, see my MMR blog post.

@dukerobillard
Copy link

Here's an example of how I converted the eduperson.schema file to a LDIF formatted schema file that can be used with ldapadd, etc:

Excellent, thanks!

It looks like the big difference between your procedure and the script in this repo, is the use of slapcat to pull the data out of the temporary "cn=config" area....have I got that right? The script just hacks on the file "cn=config" file directly. I can see how it would be safer to trust slapcat to get the data...sort of follows the principle of using the "published API" rather than going to the underlying data.

@quanah
Copy link

quanah commented May 19, 2022

@dukerobillard Generally, yes. You could also tweak it further to convert multiple schema at once and dump it directly to a file by using the -l option, and then pull out all of the schema you want converted in one go.

@tomtana
Copy link

tomtana commented Nov 19, 2023

Struggeled with the same task to convert schema to ldif files wondering why there is no straight forward conversion tool available. Well there is:

https://github.com/fusiondirectory/schema2ldif

It is also available in the ubuntu repository.

@quanah
Copy link

quanah commented Nov 22, 2023

slaptest literally is a straight forward conversion tool that ensures correctness of the result

@atilaromero
Copy link

slaptest literally is a straight forward conversion tool that ensures correctness of the result

Not quite, since you have to grep+sed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment