Ldap – Getting openldap + postgres working

ldapopenldappostgresql

I'm having an issue configuring openldap v2.4.46 + postgres (9.6.x), I'm running into a problem i cannot find an answer to.

Installation steps

yum install -y vim libacl-devel libblkid-devel gnutls-devel readline-devel python-devel autoconf gcc-c++ gcc glibc-devel glibc-headers kernel-headers libgomp libstdc++-devel openssl-devel e2fsprogs-devel keyutils-libs-devel krb5-devel libselinux-devel libsepol-devel libtool-ltdl-devel postgresql-odbc.x86_64 postgresql-client wget postgresql-devel librpcsecgss unixODBC-devel
export HISTCONTROL=erasedups:ignorespace
export HISTSIZE=""
wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-2.4.46.tgz
tar xvf openldap-2.4.46.tgz
cd openldap-2.4.46 && ./configure --prefix=/ --enable-sql --without-cyrus-sasl --disable-bdb --enable-crypt --disable-hdb && make depend && make && make install && cd -

psql -h postgres -U postgres -c 'DROP DATABASE ldap'
psql -h postgres -U postgres -c 'CREATE DATABASE ldap'
cat /openldap-2.4.46/servers/slapd/back-sql/rdbms_depend/pgsql/backsql_create.sql | psql -h postgres -U postgres ldap 

/etc/openldap/slap.conf

include     /etc/openldap/schema/core.schema 
include     /etc/openldap/schema/cosine.schema
include     /etc/openldap/schema/nis.schema
include     /etc/openldap/schema/inetorgperson.schema
include     /etc/openldap/schema/ppolicy.schema

pidfile     /var/run/slapd.pid
argsfile    /var/run/slapd.args

database        sql
suffix         "dc=my-domain,dc=com"
rootdn         "cn=Manager,dc=my-domain,dc=com"
rootpw          secret
dbname          ldap
dbuser          postgres
dbpasswd        postgres
insentry_stmt  "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
upper_func      "upper"
strcast_func    "text"
concat_pattern  "?||?"
has_ldapinfo_dn_ru      no

lastmod off

/etc/odbc.ini

;  odbc.ini
;
[ODBC Data Sources]
ldap=PostgreSQL

[ldap]
; WARNING: The old psql odbc driver psqlodbc.so is now renamed psqlodbcw.so
; in version 08.x. Note that the library can also be installed under an other
; path than /usr/local/lib/ following your installation.
Driver=/usr/lib64/psqlodbcw.so
Description=Connection to LDAP/POSTGRESQL
Servername=postgres
Port=5432
Protocol=6.4
FetchBufferSize=99
Username=postgres
Password=postgres
Database=ldap
ReadOnly=no
Debug=1
CommLog=1

[ODBC]
InstallDir=/usr/local/lib

Running the app

$ /usr/libexec/slapd -f /etc/openldap/slapd.conf -d 3

group.ldif

dn: dc=my-domain,dc=com
objectClass: domain
dc: my-domain 

dn: ou=people,dc=my-domain,dc=com
ou: people
objectClass: organizationalUnit

dn: ou=groups,dc=my-domain,dc=com
ou: groups
objectClass: organizationalUnit

Problem

$ ldapadd -f groups.ldif -h localhost -D "cn=Manager,dc=my-domain,dc=com" -w secret
adding new entry "dc=my-domain,dc=com"
ldap_add: Server is unwilling to perform (53)
    additional info: operation not permitted within namingContext

Debug from the server

5afc9875 slap_listener_activate(6): 
5afc9875 >>> slap_listener(ldap:///)
5afc9875 connection_get(10): got connid=1000
5afc9875 connection_read(10): checking for input on id=1000
ber_get_next
ldap_read: want=8, got=8
  0000:  30 30 02 01 01 60 2b 02                            00...`+.          
ldap_read: want=42, got=42
  0000:  01 03 04 1e 63 6e 3d 4d  61 6e 61 67 65 72 2c 64   ....cn=Manager,d  
  0010:  63 3d 6d 79 2d 64 6f 6d  61 69 6e 2c 64 63 3d 63   c=my-domain,dc=c  
  0020:  6f 6d 80 06 73 65 63 72  65 74                     om..secret        
ber_get_next: tag 0x30 len 48 contents:
5afc9875 op tag 0x60, time 1526503541
ber_get_next
ldap_read: want=8 error=Resource temporarily unavailable
5afc9875 conn=1000 op=0 do_bind
ber_scanf fmt ({imt) ber:
ber_scanf fmt (m}) ber:
5afc9875 >>> dnPrettyNormal: <cn=Manager,dc=my-domain,dc=com>
5afc9875 <<< dnPrettyNormal: <cn=Manager,dc=my-domain,dc=com>, <cn=manager,dc=my-domain,dc=com>
5afc9875 do_bind: version=3 dn="cn=Manager,dc=my-domain,dc=com" method=128
5afc9875 ==>backsql_bind()
5afc9875 conn=1000 op=0: rootdn="cn=Manager,dc=my-domain,dc=com" bind succeeded
5afc9875 <==backsql_bind(0)
5afc9875 do_bind: v3 bind: "cn=Manager,dc=my-domain,dc=com" to "cn=Manager,dc=my-domain,dc=com"
5afc9875 send_ldap_result: conn=1000 op=0 p=3
5afc9875 send_ldap_response: msgid=1 tag=97 err=0
ber_flush2: 14 bytes to sd 10
ldap_write: want=14, written=14
  0000:  30 0c 02 01 01 61 07 0a  01 00 04 00 04 00         0....a........    
5afc9875 connection_get(10): got connid=1000
5afc9875 connection_read(10): checking for input on id=1000
ber_get_next
ldap_read: want=8, got=8
  0000:  30 49 02 01 02 68 44 04                            0I...hD.          
ldap_read: want=67, got=67
  0000:  13 64 63 3d 6d 79 2d 64  6f 6d 61 69 6e 2c 64 63   .dc=my-domain,dc  
  0010:  3d 63 6f 6d 30 2d 30 17  04 0b 6f 62 6a 65 63 74   =com0-0...object  
  0020:  43 6c 61 73 73 31 08 04  06 64 6f 6d 61 69 6e 30   Class1...domain0  
  0030:  12 04 02 64 63 31 0c 04  0a 6d 79 2d 64 6f 6d 61   ...dc1...my-doma  
  0040:  69 6e 20                                           in                
ber_get_next: tag 0x30 len 73 contents:
5afc9875 op tag 0x68, time 1526503541
ber_get_next
ldap_read: want=8 error=Resource temporarily unavailable
5afc9875 conn=1000 op=1 do_add
ber_scanf fmt ({m) ber:
ber_scanf fmt ({m{W}}) ber:
ber_scanf fmt ({m{W}}) ber:
ber_scanf fmt (}) ber:
5afc9875 >>> dnPrettyNormal: <dc=my-domain,dc=com>
5afc9875 <<< dnPrettyNormal: <dc=my-domain,dc=com>, <dc=my-domain,dc=com>
5afc9875 ==>backsql_add("dc=my-domain,dc=com")
5afc9875 oc_check_required entry (dc=my-domain,dc=com), objectClass "domain"
5afc9875 oc_check_allowed type "objectClass"
5afc9875 oc_check_allowed type "dc"
5afc9875 oc_check_allowed type "structuralObjectClass"
5afc9875    backsql_add("dc=my-domain,dc=com"): cannot map structuralObjectClass "domain" -- aborting
5afc9875 send_ldap_result: conn=1000 op=1 p=3
5afc9875 send_ldap_response: msgid=2 tag=105 err=53
ber_flush2: 58 bytes to sd 10
ldap_write: want=58, written=58
  0000:  30 38 02 01 02 69 33 0a  01 35 04 00 04 2c 6f 70   08...i3..5...,op  
  0010:  65 72 61 74 69 6f 6e 20  6e 6f 74 20 70 65 72 6d   eration not perm  
  0020:  69 74 74 65 64 20 77 69  74 68 69 6e 20 6e 61 6d   itted within nam  
  0030:  69 6e 67 43 6f 6e 74 65  78 74                     ingContext        
5afc9875 <==backsql_add("dc=my-domain,dc=com"): 53 "operation not permitted within namingContext"
5afc9875 connection_get(10): got connid=1000
5afc9875 connection_read(10): checking for input on id=1000
ber_get_next
ldap_read: want=8, got=7
  0000:  30 05 02 01 03 42 00                               0....B.           
ber_get_next: tag 0x30 len 5 contents:
5afc9875 op tag 0x42, time 1526503541
ber_get_next
ldap_read: want=8, got=0

5afc9875 ber_get_next on fd 10 failed errno=0 (Success)
5afc9875 conn=1000 op=2 do_unbind
5afc9875 connection_close: conn=1000 sd=10

Best Answer

Turns out i was expecting sql to work similarly to mdb and.. it does not. Every relation needs to be defined now inside the db; kiss your import ....ldif goodbye and now add them into the db.

psql -h postgres -U postgres -c 'DROP DATABASE ldap'
psql -h postgres -U postgres -c 'CREATE DATABASE ldap'
psql -h postgres -U postgres ldap < /openldap-2.4.46/servers/slapd/back-sql/rdbms_depend/pgsql/backsql_create.sql
psql -h postgres -U postgres ldap < /openldap-2.4.46/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_create.sql
psql -h postgres -U postgres ldap < /openldap-2.4.46/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
psql -h postgres -U postgres ldap < /openldap-2.4.46/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_data.sql

for me this was more trouble than it was worth, so ive since abandoned this approach and have just gone with mdb.

If there is anyone out there that has a better way of doing this, please! I'm all ears.