From c78dbaa7f130346e0229f66e3bc95317026454ae Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Sep 30 2019 18:24:04 +0000 Subject: info: infoldap: Decode values to unicode if possible python-ldap doesn't know the LDAP schema, so all attribute values are returned in binary since the value could be anything. However, ipsilon expects that all info data is in string format. Try to convert the value to unicode, maintaining the original binary value if the decoding fails. With python2, things worked OK as long as the values were ASCII. For python3, attribute values will be passed around as bytes, which will definitely do the wrong thing. Signed-off-by: Dan Nicholson --- diff --git a/ipsilon/info/infoldap.py b/ipsilon/info/infoldap.py index 203eaf6..29c62b9 100644 --- a/ipsilon/info/infoldap.py +++ b/ipsilon/info/infoldap.py @@ -114,6 +114,24 @@ Info plugin that uses LDAP to retrieve user data. """ return conn + @classmethod + def _try_decode_value(cls, value): + """Decode values to unicode if possible + + python-ldap doesn't know the LDAP schema, so all attribute + values are returned in binary since the value could be anything. + However, ipsilon expects that all info data is in string format. + Try to convert the value to unicode, maintaining the original + binary value if the decoding fails. + """ + if isinstance(value, list): + return [cls._try_decode_value(v) for v in value] + else: + try: + return value.decode('utf-8') + except UnicodeDecodeError: + return value + def _get_user_data(self, conn, dn): result = conn.search_s(dn, ldap.SCOPE_BASE) if result is None or result == []: @@ -124,7 +142,7 @@ Info plugin that uses LDAP to retrieve user data. """ for name, value in six.iteritems(result[0][1]): if isinstance(value, list) and len(value) == 1: value = value[0] - data[name] = value + data[name] = self._try_decode_value(value) return data def _get_user_groups(self, conn, base, username): @@ -137,7 +155,7 @@ Info plugin that uses LDAP to retrieve user data. """ groups = [] for r in results: if 'cn' in r[1]: - groups.append(r[1]['cn'][0]) + groups.append(self._try_decode_value(r[1]['cn'][0])) return groups def get_user_data_from_conn(self, conn, dn, base, username):