Directory Listener Module not working as expected

Hello,

ich have developed a custom directory listener following the documentation I found here (https://wiki.univention.de/index.php?title=Entwicklung_von_Univention_Directory_Listener-Modulen) and here (https://www.univention.de/blog-de/2017/06/sync-und-kontrolle-aller-aenderungen-im-openldap-ueber-listener-module/)

The code is as follows:

__package__ = ""  # workaround for PEP 366

import univention.debug as ud
import requests

name = "test"
description = "test module"
filter = '''\(|(&(objectClass=posixAccount)(objectClass=shadowAccount))(objectClass=univentionMail)(objectClass=sambaSamAccount)(&(objectClass=person)(objectClass=organizationalPerson)(objectClass=inetOrgPerson)))'''
attributes = ["givenname", "employeenumber"]

def handler(dn, new, old):
    try:
        if new and old:
            _handle_change(dn, new, old)
        elif new and not old:            
            _handle_add(dn, new)
        if old and not new:
            _handle_remove(dn, old)
    finally:
        pass

def _handle_add(dn, new):
    # if a user is created
    ud.debug(ud.LISTENER, ud.ERROR, 'user created')

def _handle_change(dn, new, old):
    # if a user is changed
    ud.debug(ud.LISTENER, ud.ERROR, 'user changed')    

def _handle_remove(dn, old):
    # if a user is deleted
    ud.debug(ud.LISTENER, ud.ERROR, 'user deleted')

Basically, this code is working, but only as long as I keep the attributes array empty. With the values given in the code, the script is never executed, no matter what user property I change.

Can anyone tell me what I am doing wrong?

Important: the documentation in the second link (see top) has an error:

name = "web_connector"
description = "Der Web-Connector spricht eine Web-API an."
filter = "(objectClass=ucsschoolTeacher)"
attribute = ["ucsschoolSchool", "departmentNumber:"]

Note the “attributes” property is “attribute” there, which is wrong.

Thanks in advance!
Kind regards, Tom

  1. There is no reason to start a multi-line string, when there is only 1 line. Just enclose it in 1 ".
  2. The \ at the start of the filter is not required, and probably the reason no object ever matches and the listener module is never triggered.

You can try out your LDAP filters using the command line univention-ldapsearch:

univention-ldapsearch -LLL '$FILTER` $ATTRIBUTES
# in your case:
univention-ldapsearch -LLL '(|(&(objectClass=posixAccount)...(objectClass=inetOrgPerson)))` givenname employeenumber

What is the reason to make the filter that complicated?
If you are looking for user objects, just use the following filter: (univentionObjectType=users/user)

Instead of using the old listener module interface, I suggest using the newer, more Pythonic, one: 6.2. High-level Listener modules API — Univention Corporate Server - Manual for developers

Basically you copy this example module and adapt it to your needs.
There is also an example for a rather complex module. But you’ll most likely won’t need it.

The example works out of the box. Just copy it to /usr/lib/univention-directory-listener/system/, restart the listener and it’ll run.

Greetings
Daniel Tröder

Hi Daniel,

thanks for your reply.

The simple reason for most of your questions is: I am a developer, but have barely ever handled Python nor LDAP, so please forgive my ignorance. I was just setting up a proof of concept and the given example just did not work correctly.

The complicated filter comes directly from an (Univention) example taken from the first link of my first post; yes, it is multiline there, I just did not care.

Thanks for the good advice you give; I will have a more detailed look on it now.

Kind regards,
Tom

Mastodon