Complete Golang redesign


1 issue   (1 closed — 0 open)

LDAP-2-CardDAV Phone Book Gateway (l2cpbg)

An LDAP to CardDav (1 way read) Phone Book Gateway.

Use case

Most modern (business) voice phones have the capability to do
comfortable LDAP directory look-up like:

  • Directory search by alphabet letters
  • Reverse lookup for in- or out-bound calls
  • Reverse lookup by entering parts or the phone number

Unfortunately, most of the 'smaller' companies (i guess companies beyond
100 employee) don't have an 'enterprise' LDAP directory, much less than
private persons.

Most of such companies do have something like a cloud address book,
often based on WebDAV / CardDAV (i.e. Nextcloud, Ownlcoud, Baïkal,
Daylite, ...).

This is, where this Gateway might make your live easier.

If this program get started on some kind of hardware (Windows, macOS or Linux), it will do the following:

  1. Query your CardDAV Server for relevant entries, and cache them to a small local database
  2. Wait and answer for LDAP requests from your voice phone(s)


  • Query your CardDAV address book(s) by entering the alphabetic letters (or parts of the telephone number) in your (LDAP capable) phone (and dial one of the matching numbers).
  • Reverse lookup inbound calls and display matching contact informations on the phone.
  • Work with local formatted (non- E.164) CardDAV entered phone numbers like: '040-123456' or '001 807 1234567' as well as '+49 (0)40 1234567-8' = no need to enter your phone numbers within your CardDAV server in a special notation.
  • Supports internal (extension) phone numbers.
  • Support dial prefix for external line.


You need some kind of 24/7 machine where this gateway live. Windows PC,
Linux, macOS, Raspberry or the like.

In this early 'beta' version, it runs in foreground. So, if you require
to log off out of your machine, run it i.e. via 'screen'.

No installation required. Only a simple executable an a configuration file. Place it wherever you like, but I advice to start it as normal (non-root/non-administrative) user.

By default it will look for a configuration file in the following places (in the
given order):

  1. ./l2cpbg.conf
  2. /etc/l2cpbg.conf

It will write to a small local database directory (defaults to '/tmp/l2cpbg.db').


There are some hotkeys available on the console.

Hotkey Description

Configfile syntax

Since version 0.9.0 the config file syntax has changed from 'ini' to 'toml'. Not a big deal, but you need to adapt some entries. Mainly strings have to be entered within quotes!

Following a quick minimal sample:

# Comments get started with a hash character

# The Gateway will act as LDAP Server, listening
# for requests from your phone(s).
  host      = ""
  #port     = 1389
  base      = "dc=example, dc=com"

  dn   = "cn=pbx"
  pass = "your-password"

# Your CardDAV server where this Gateway get the contacts from
  server       = ""
  user         = "cloud-login-name"
  pass         = "cloud-login-password"

  int           = 1     # Your international code. 1 = US, 49 = Germany, ...
  area          = 807   # Your local area code (without a leading 0)
  maxarealength = 7
  country       = "EN"

Config file description (by section)

[ldap] = LDAP Server settings

host : Which IP to listen for LDAP requests. Defaults to "" = 'Listen on all interfaces'. You've to point your LDAP phone settings to this machines IP/hostname.

port : Which port to listen for LDAP requests. Defaults to port 1389. The standard LDAP port is 389, so you need to change your phone to the port you configure here.

base : This LDAP's 'base DN'. Choose whatever you want, but use the same settings within your phone's LDAP settings. Defaults to 'dc=example, dc=com'.

[ldap.bind] = LDAP bind/auth settings

dn : Distinguish name. Name, how the phone has to log into/authorize
to the gateway.

pass : Related 'dn' password, a phone has to use when logging in/authorize to the gateway.

[dav] = WebDav/CardDav server settings

server : Your WebDAV/CardDAV server address/URL. Please see 'Limitations'!

user : WebDav username with read access to the relevant addressbook which shall be requested for phone book lookups. Might also be a 'shared' address book.

pass : Related user password.

addressbooks : Optional regular expression string of matchable addressbook(s)
used for phone book lookups. If unsure, enter something. l2cpbg will log
all found address books of the logged in CardDav user during startup and
log them as 'Non-matching' or 'Matching' address book(s).

syncinterval : Interval of CardDav sync checks. Given as string with suffix 'm' for minutes, or 'h' as hours. Has to be greater than "2m".

chunksize : If an address book get loaded the first time, it get loaded in "chunks of contacts" in this given size. You may increase this value for quicker initial load, but if your CardDAV server answer with an "507 Insufficient Storage" error or similar, you need to lower this value. Default to 200. This option was added in L2CPBG version 0.8.1.

[] = CardDav mapping

tel : CardDAV attribute which contain phone numbers. Normally (and
by default) 'TEL'. Don't change this, except your really know what you're doing.

[location] = Local area settings

int : International area code (1 = North America, ..., 44 = United
Kingdom, 49 = Germany, ...) of your location.

area : Local area code without leading 0 (20 = London (UK), 40 =
Hamburg (DE), ...).

maxarealength : Longest possible length of a telephone number within
your local area. If a found or received number is shorter or equal, it's
identified as a number without local area prefix.

country : Two-letter ISO 3166-1 alpha-2 country code (i.e. US, GB, DE, ...).

maxintlength : Maximum length of internal phone numbers. These numbers
don't get harmonized or E.164 converted.

extdialprefix : Optional external dial prefix for getting an external line. Get prefixed before the phone number if outgoing number length > maxintlength

[log] = Logging

level : Log level. Might be one of "trace", "debug", "info", "warn", "error" or "panic". Defaults to "info".

The log levels are organized as follows:

trace : This is the most verbose log level. It logs simply everything.
Never use it in production environment as it might produce an awful amount of log entries!

debug : Logs a lot internal stuff, probably interesting when searching
a solution for an issue. Should not be used in production environment as
it produce also a lot log entries!

info : This is the most usual log level. Logs only stuff which is relevant.

warn : Logs stuff which doesn't behave as expected. Not critical (generic functionality should be okay) but should be noticed/checked.

error : Something essential/critical happened. Functionality is limited or aborted at all.

panic : Game over.

[db] = Internal database

directory : An own directory where to store the internal database. Defaults to
'/tmp/l2cpbg.db' which is not very usefull on Linux based systems as it normally get cleaned after each reboot. Choose yourself where to store the database. Not much storage space needed. An CardDAV server with approx. 4 thousand contacts, take about 10 MByte storage.

[] = LDAP/CardDav mapping

Every LDAP attribute which is used within a phone(s) filter or response,
need to have a corresponding CardDav mapping which get done as follows:

First you need to define a separate block for the LDAP attribute in the
following syntax: [<ldap attribute name (case sensitive)>]
Within such a LDAP mapping block you have to define:

dav : Corresponding CardDav field/attribute name.

and optional define the following settings:

itypes : Regular expression (RE2 syntax) of including relevant CardDav types or Apple addressbook label (Apple Adressbook extension: X-ABLabel).

etypes : Regular expression (RE2 syntax) of excluding relevant CardDav types or Apple addressbook label (Apple Adressbook extension: X-ABLabel).

index : Zero based index in the case of a multi-value CardDav field.

For an overview of the predefined/default LDAP/CardDav mappings, take a
look into 'l2cpbg.sample.conf' file.

Phone configuration


Here's a configuration sample of a Gigaset N510 IP PRO:
Gigaset N510 IP PRO settings sample for L2CPBG 0.7.0
Take attention that 'Server Address' point to the machine where this gateway lives (as well as 'Serverport')

'BaseDN', 'Common User Name' and 'Common Password' get filled with the same values as defined in your L2CPG config file.


Another configuration sample of a Yealink SIP-T52S:
Yealink SIP-T52S settings sample for L2CPBG 0.7.0
Take attention that 'Server Address' point to the machine where this gateway lives (as well as 'Port').

'Base', 'User Name' and 'Password' get filled with the same values as defined in your L2CPG config file.


The LDAP configuration of Snom phones look similar to the ones of
Gigaset or Yealink.
But a user reported that entering (|(cn=*%*)(sn=*%*)(givenName=*%*)(company=*%*)) within 'LDAP name filter' did the trick for working name searches.


This version is tested with:

  • CardDAV Server:
  • Phone Extensions:
  • Gateway Host OS:
    • Debian Stretch 9.x, Buster 10.x (running at amd64 as well as ARMv7)
    • macOS ™ Sierra 10.12.6
    • Ubuntu 20.04 (Focal Fossa)

Limitations and Known Issues

There are already some known issues!!! Not sure which will get fixed, might depend on how much people are interested in.

  • The internal LDAP Server doesn't support LDAPS (encrypted LDAP communication) at the moment. Therefore it should not be used in an untrusted network!
  • 'Basic Authentication' over 'HTTPS' will work (for sure), but probably not with self signed certificates

Support & getting help

For getting help or discussing l2cpbg, please browse the L2CPBG
or check/open
the Tickets area.

Issues by


Go to top