Viper - hints, tips, best practices
Viper server on Ubuntu
Viper server start on Ubuntu may fail with the following error:
Starting OpenLDAP: slapd - failed:
Error Can't locate strict.pm in @INC (@INC contains: /etc/perl
/usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10
/usr/local/lib/site_perl . /etc/ldap/viper) at
/etc/ldap/viper/Viper.pm line 52.
BEGIN failed--compilation aborted at /etc/ldap/viper/Viper.pm line 52. Compilation failed in require at (eval 2) line 1.
BEGIN failed--compilation aborted at (eval 2) line 1.
Can't call method "config" on an undefined value.
This is due to AppArmor, which is installed by default on Ubuntu, preventing slapd from accessing files in "unauthorized" locations.
The simplest fix is invoke-rc.d apparmor stop.
A proper solution is editing /etc/apparmor.d/usr.sbin.slapd and adding the following in there:
And reloading apparmor.
Keeping directory data in LDIF
Modifying or re-loading LDAP data can be inconvenient without a
suitable LDAP client. The approach I use during development (but that is
also showing long-term viability) is to keep all
data in LDIF format under ldifs/ subdirectory, which allows for
simple text editing, then deleting
and re-loading everything from LDIFs to LDAP.
See subdirectory ldifs/ where this is working, and where you can modify existing or add your own .ldifs, then run make to reload everything.
Editing live LDAP data in a text editor
There exists a LDAP editor called ldapvi that is basically "Vi for LDAP".
ldapvi -b cn=h2,ou=hosts,o=c1.com,ou=clients -D cn=admin,ou=clients -w blah
Extracting LDAP data back to LDIF format
Viper-enabled LDAP server already keeps data as files on disk in LDIF format.
So one option is to just copy directory /var/lib/ldap/viper. Another, possibly better option, is to find all the .ldif files in there and concatenate them to a single file that you can modify and reload with 'make' (as explained above).
find /var/lib/ldap/viper -name '*.ldif' | xargs cat > alldata.ldif
Base64 encoded values
When an attribute value starts with a space or contains any non-standard
formatting or characters, it is Base64-encoded when exported to LDIF, to
preserve the value.
An example might look like this:
extendedDescription:: UGxlYXNlIGVudGVyIHRoZSBob3N0bmFtZSBvZiB0aGUgbWlycm9yIGZy b20gd2hpY2ggRGViaWFuIHdpbGwgYmUgZG93bmxvYWRlZC4KCkFuIGFsdGVybmF0ZSBwb3J0IGNhb iBiZSBzcGVjaWZpZWQgdXNpbmcgdGhlIHN0YW5kYXJkIFtob3N0bmFtZV06W3BvcnRdIGZvcm1hdC 4=
You can use 'base64 -d' on the command line to print decoded value. Note that you should remove the attribute name (extendedDescription::), newlines and spaces to turn the whole base64-encoded value into a single line, then paste the line into base64 -d.
$ base64 -d UGxlYXNlIGVudGVyIHRoZSBob3N0bmFtZSBvZiB0aGUgbWlycm9yIGZyb20gd2hpY2ggRGViaWFuIHdpbGwgYmUgZG93bmxvYWRlZC4KCkFuIGFsdGVybmF0ZSBwb3J0IGNhbiBiZSBzcGVjaWZpZWQgdXNpbmcgdGhlIHN0YW5kYXJkIFtob3N0bmFtZV06W3BvcnRdIGZvcm1hdC4= [Enter][Ctrl+d] Reveals the actual text: "Please enter the hostname of the mirror from which Debian will be downloaded. An alternate port can be specified using the standard [hostname]:[port] format."
Reading LDAP data as filesystem operation
It is possible to use ldapfs to "mount" part of the LDAP tree as disk files. This is an elegant solution if you want to query data from shell scripts or other places where writing a direct LDAP interface may be inconvenient.
Starting / re-starting Viper/LDAP
You should be able to start, stop or restart the server just as a regular slapd server, invoke-rc.d slapd <start|stop|restart...>.
This works because /etc/default/slapd exports LD_PRELOAD=/usr/lib/libperl.so.5.10 which is needed by slapd to run when using Perl-based backend.
In case you do not preload libperl, you get an error similar to:
/usr/sbin/slapd: symbol lookup error: /usr/lib/perl/5.10/auto/IO/IO.so: undefined symbol: Perl_Istack_sp_ptr
So you should be using that line in /etc/default/slapd. If not, you can specify it manually when managing slapd:
LD_PRELOAD=/usr/lib/libperl.so.5.10 invoke-rc.d slapd <start|stop|restart...>