Bug 54780 - Environments with multiple "custom" AD-Connectors break after update to UCS 5.0
Environments with multiple "custom" AD-Connectors break after update to UCS 5.0
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: AD Connector
UCS 5.0
Other Linux
: P5 normal (vote)
: UCS 5.0-2-errata
Assigned To: Florian Best
Arvid Requate
https://git.knut.univention.de/univen...
:
Depends on: 55087
Blocks:
  Show dependency treegraph
 
Reported: 2022-05-20 14:07 CEST by Arvid Requate
Modified: 2024-02-23 13:46 CET (History)
5 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 7: Crash: Bug causes crash or data loss
Who will be affected by this bug?: 1: Will affect a very few installed domains
How will those affected feel about the bug?: 5: Blocking further progress on the daily work
User Pain: 0.200
Enterprise Customer affected?: Yes
School Customer affected?:
ISV affected?:
Waiting Support: Yes
Flags outvoted (downgraded) after PO Review:
Ticket number: 2022042821000388
Bug group (optional): Regression
Max CVSS v3 score:
requate: Patch_Available+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arvid Requate univentionstaff 2022-05-20 14:07:13 CEST
A partner has a larger number of multiple AD-connectors that are configured each with their own sec of UCR-Variables like connector-foo/ad/ldap/base

have their own start script /usr/sbin/univention-ad-connector-foo.

After updating to UCS 5.0 none of the connectors is running any longer. The log files are empty and show no tracebacks.

During remote debugging I started the connector in foreground which showed this traceback:
```
root@ucsbackup:~# /usr/sbin/univention-ad-connector-foo -d 4 -n -L 1.log
Fri May 20 13:20:46 2022
Fri May 20 13:20:46 2022
--- connect failed, failure was: ---
Traceback (most recent call last):
 File "/usr/lib/python3/dist-packages/univention/connector/ad/main.py", line 244, in main
   connect(options)
 File "/usr/lib/python3/dist-packages/univention/connector/ad/main.py", line 116, in connect
   ad.init_ldap_connections()
 File "/usr/lib/python3/dist-packages/univention/connector/ad/__init__.py", line 572, in init_ldap_connections
   prop.con_default_dn = self.dn_mapped_to_base(prop.con_default_dn, self.lo_ad.base)
 File "/usr/lib/python3/dist-packages/univention/connector/__init__.py", line 517, in dn_mapped_to_base
   return self._subtree_replace(dn, base.lower(), base)
 File "/usr/lib/python3/dist-packages/univention/connector/__init__.py", line 1463, in _subtree_replace
   _dn = ldap.dn.str2dn(dn.lower())
 File "/usr/lib/python3/dist-packages/ldap/dn.py", line 52, in str2dn
   return ldap.functions._ldap_function_call(None,_ldap.str2dn,dn,flags)
 File "/usr/lib/python3/dist-packages/ldap/functions.py", line 55, in _ldap_function_call
   result = func(*args,**kwargs)
ldap.DECODING_ERROR
```

Looks like the value of con_default_dn ist not initialized properly for these multiple AD Connectors. I printed out the value from init_ldap_connections:

```
prop.con_default_dn: cn=users,None (<class 'str'>)
```

And when I look into /usr/lib/python3/dist-packages/univention/connector/ad/mapping.py I see:
```
ad_mapping = {
        'user': univention.connector.property(
                ucs_default_dn='cn=users,%(ldap/base)s' % configRegistry,
                con_default_dn='cn=users,%(connector/ad/ldap/base)s' % configRegistry,
```

That shows that the wrong UCR variables are used here and they are not parameterized by configbasename. Unfortunately, during the `import univention.connector.ad.mapping` in univention.connector.ad.main I don't have access to the "global" configbasename, so it looks like cannot do a quick fix.

There are multiple lines in mapping.py that need to be fixed, I guess.
Comment 1 Florian Best univentionstaff 2022-05-20 14:51:52 CEST
we should not create a copy of the whole mapping and put it into localmapping.py of the corresponding configbase.
Instead the mapping should be created via a function instead of during import time.

A Draft for this is in MR: https://git.knut.univention.de/univention/ucs/-/merge_requests/398
Comment 2 Arvid Requate univentionstaff 2022-05-20 14:52:53 CEST
This is what we did as a workaround:
```
CONFIGBASENAME=connector-foo
mkdir -p /etc/univention/"$CONFIGBASENAME"/ad
cp -a /usr/lib/python3/dist-packages/univention/connector/ad/mapping.py \
         /etc/univention/"$CONFIGBASENAME"/ad/localmapping.py
sed -i "s|@%@connector/ad/|@%@$CONFIGBASENAME/ad/|g;s|'connector/ad/|'$CONFIGBASENAME/ad/|g;s|(connector/ad/|($CONFIGBASENAME/ad/|g" \
    /etc/univention/"$CONFIGBASENAME"/ad/localmapping.py
echo -e '\ndef mapping_hook(org_mapping):\n return ad_mapping' >> /etc/univention/"$CONFIGBASENAME"/ad/localmapping.py 
```

But Florian also provided a proper fix, see MR in the URL field above.
Comment 4 Florian Best univentionstaff 2022-08-09 13:37:58 CEST
The mapping is now generated with respect to the configbasename. Therefor forking a mapping file for another instance is not necessary anymore. 

univention-ad-connector.yaml
54a925558118 | Bug #54780: get mapping with respect to configbasename

univention-ad-connector (14.0.10-2)
54a925558118 | Bug #54780: get mapping with respect to configbasename
92e7e8f112ef | Bug #54780: reindent
Comment 5 Arvid Requate univentionstaff 2022-08-29 17:34:15 CEST
/var/log/univention/connector2-ad-status.log shows:
==================================================
 --- connect failed, failure was: ---
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/univention/connector/ad/main.py", line 247, in main
    connect(options)
  File "/usr/lib/python3/dist-packages/univention/connector/ad/main.py", line 118, in connect
    ad = univention.connector.ad.ad.main(ucr, options.configbasename, logfilename=options.log_file, debug_level=options.debug)
  File "/usr/lib/python3/dist-packages/univention/connector/ad/__init__.py", line 439, in main
    **kwargs
  File "/usr/lib/python3/dist-packages/univention/connector/ad/__init__.py", line 443, in __init__
    univention.connector.ucs.__init__(self, CONFIGBASENAME, property, configRegistry, listener_dir, logfilename, debug_level)
  File "/usr/lib/python3/dist-packages/univention/connector/__init__.py", line 495, in __init__
    self.config = configdb(configdbfile)
  File "/usr/lib/python3/dist-packages/univention/connector/__init__.py", line 162, in __init__
    self._dbcon = lite.connect(self.filename)
sqlite3.OperationalError: unable to open database file
==================================================

The commit 54a925558118 removed the creation of that directory, which additionally is required
in the prepare-new-instance script as criterion to check if the selected connector instance name
is already in use or not.
Comment 6 Florian Best univentionstaff 2022-08-29 17:42:57 CEST
re-create directory in the prepare-new-instance script:

univention-ad-connector (14.0.10-4)
c50af326c42c | Bug #54780: create /etc/univention/"$CONFIGBASENAME"/ad directory again
Comment 7 Arvid Requate univentionstaff 2022-08-29 18:16:53 CEST
Verified:
* Code review
* Functional test
* Test case: would be nice to have, but currently out of scope
* Documentation update not required
* Will not break non-updated systems
* Advisory