mirror of
https://github.com/kakwa/ldapcherry
synced 2024-11-22 09:24:21 +01:00
add some python 3 support in the LDAP and AD backends
python-ldap talks in bytes, as the rest of ldapcherry talks in unicode utf-8: * everything passed to python-ldap must be converted to bytes * everything coming from python-ldap must be converted to unicode The previous statement was true for python-ldap < version 3.X. With versions > 3.0.0 and python 3, it gets tricky, some parts of python-ldap takes string, specially the filters/escaper. so we have now: *_byte_p2 (unicode -> bytes conversion for python 2) *_byte_p3 (unicode -> bytes conversion for python 3) *_byte_p23 (unicode -> bytes conversion for python AND 3)
This commit is contained in:
parent
979d4eeda8
commit
10747cff93
@ -15,6 +15,7 @@ import ldapcherry.backend
|
|||||||
from ldapcherry.exceptions import UserDoesntExist, GroupDoesntExist
|
from ldapcherry.exceptions import UserDoesntExist, GroupDoesntExist
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class CaFileDontExist(Exception):
|
class CaFileDontExist(Exception):
|
||||||
@ -129,11 +130,11 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
self.dn_user_attr = 'cn'
|
self.dn_user_attr = 'cn'
|
||||||
self.key = 'sAMAccountName'
|
self.key = 'sAMAccountName'
|
||||||
self.objectclasses = [
|
self.objectclasses = [
|
||||||
'top',
|
self._byte_p23('top'),
|
||||||
'person',
|
self._byte_p23('person'),
|
||||||
'organizationalPerson',
|
self._byte_p23('organizationalPerson'),
|
||||||
'user',
|
self._byte_p23('user'),
|
||||||
'posixAccount',
|
self._byte_p23('posixAccount'),
|
||||||
]
|
]
|
||||||
self.group_attrs = {
|
self.group_attrs = {
|
||||||
'member': "%(dn)s"
|
'member': "%(dn)s"
|
||||||
@ -142,16 +143,25 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
self.attrlist = []
|
self.attrlist = []
|
||||||
self.group_attrs_keys = []
|
self.group_attrs_keys = []
|
||||||
for a in attrslist:
|
for a in attrslist:
|
||||||
self.attrlist.append(self._str(a))
|
self.attrlist.append(self._byte_p2(a))
|
||||||
|
|
||||||
if self._str('cn') not in self.attrlist:
|
if self._byte_p2('cn') not in self.attrlist:
|
||||||
raise MissingAttr()
|
raise MissingAttr()
|
||||||
|
|
||||||
if self._str('unicodePwd') not in self.attrlist:
|
if self._byte_p2('unicodePwd') not in self.attrlist:
|
||||||
raise MissingAttr()
|
raise MissingAttr()
|
||||||
|
|
||||||
|
if sys.version < '3':
|
||||||
|
@staticmethod
|
||||||
|
def _tobyte(in_int):
|
||||||
|
return str(in_int)
|
||||||
|
else:
|
||||||
|
@staticmethod
|
||||||
|
def _tobyte(in_int):
|
||||||
|
return in_int.to_bytes(4, byteorder='big')
|
||||||
|
|
||||||
def _search_group(self, searchfilter, groupdn):
|
def _search_group(self, searchfilter, groupdn):
|
||||||
searchfilter = self._str(searchfilter)
|
searchfilter = self._byte_p2(searchfilter)
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
try:
|
try:
|
||||||
r = ldap_client.search_s(
|
r = ldap_client.search_s(
|
||||||
@ -183,22 +193,24 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
|
|
||||||
if by_cn:
|
if by_cn:
|
||||||
dn = self._str('CN=%(cn)s,%(user_dn)s' % {
|
dn = self._byte_p2('CN=%(cn)s,%(user_dn)s' % {
|
||||||
'cn': name,
|
'cn': name,
|
||||||
'user_dn': self.userdn
|
'user_dn': self.userdn
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
dn = self._str(name)
|
dn = self._byte_p2(name)
|
||||||
|
|
||||||
attrs = {}
|
attrs = {}
|
||||||
|
|
||||||
attrs['unicodePwd'] = self._modlist(self._str(password_value))
|
attrs['unicodePwd'] = self._modlist(self._byte_p2(password_value))
|
||||||
|
|
||||||
ldif = modlist.modifyModlist({'unicodePwd': 'tmp'}, attrs)
|
ldif = modlist.modifyModlist({'unicodePwd': 'tmp'}, attrs)
|
||||||
ldap_client.modify_s(dn, ldif)
|
ldap_client.modify_s(dn, ldif)
|
||||||
|
|
||||||
del(attrs['unicodePwd'])
|
del(attrs['unicodePwd'])
|
||||||
attrs['UserAccountControl'] = self._modlist(str(NORMAL_ACCOUNT))
|
attrs['UserAccountControl'] = self._modlist(
|
||||||
|
self._tobyte(NORMAL_ACCOUNT)
|
||||||
|
)
|
||||||
ldif = modlist.modifyModlist({'UserAccountControl': 'tmp'}, attrs)
|
ldif = modlist.modifyModlist({'UserAccountControl': 'tmp'}, attrs)
|
||||||
ldap_client.modify_s(dn, ldif)
|
ldap_client.modify_s(dn, ldif)
|
||||||
|
|
||||||
@ -212,7 +224,7 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
if 'unicodePwd' in attrs:
|
if 'unicodePwd' in attrs:
|
||||||
password = attrs['unicodePwd']
|
password = attrs['unicodePwd']
|
||||||
del(attrs['unicodePwd'])
|
del(attrs['unicodePwd'])
|
||||||
userdn = self._get_user(self._str(username), NO_ATTR)
|
userdn = self._get_user(self._byte_p2(username), NO_ATTR)
|
||||||
self._set_password(userdn, password, False)
|
self._set_password(userdn, password, False)
|
||||||
super(Backend, self).set_attrs(username, attrs)
|
super(Backend, self).set_attrs(username, attrs)
|
||||||
|
|
||||||
@ -226,7 +238,7 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
|
|
||||||
def get_groups(self, username):
|
def get_groups(self, username):
|
||||||
username = ldap.filter.escape_filter_chars(username)
|
username = ldap.filter.escape_filter_chars(username)
|
||||||
userdn = self._get_user(self._str(username), NO_ATTR)
|
userdn = self._get_user(self._byte_p2(username), NO_ATTR)
|
||||||
|
|
||||||
searchfilter = self.group_filter_tmpl % {
|
searchfilter = self.group_filter_tmpl % {
|
||||||
'userdn': userdn,
|
'userdn': userdn,
|
||||||
@ -246,7 +258,7 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for entry in groups:
|
for entry in groups:
|
||||||
ret.append(entry[1]['cn'][0])
|
ret.append(self._uni(entry[1]['cn'][0]))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def auth(self, username, password):
|
def auth(self, username, password):
|
||||||
@ -256,8 +268,8 @@ class Backend(ldapcherry.backend.backendLdap.Backend):
|
|||||||
ldap_client = self._connect()
|
ldap_client = self._connect()
|
||||||
try:
|
try:
|
||||||
ldap_client.simple_bind_s(
|
ldap_client.simple_bind_s(
|
||||||
self._str(binddn),
|
self._byte_p2(binddn),
|
||||||
self._str(password)
|
self._byte_p2(password)
|
||||||
)
|
)
|
||||||
except ldap.INVALID_CREDENTIALS:
|
except ldap.INVALID_CREDENTIALS:
|
||||||
ldap_client.unbind_s()
|
ldap_client.unbind_s()
|
||||||
|
@ -76,7 +76,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
# objectclasses parameter is a coma separated list in configuration
|
# objectclasses parameter is a coma separated list in configuration
|
||||||
# split it to get a real list, and convert it to bytes
|
# split it to get a real list, and convert it to bytes
|
||||||
for o in re.split(r'\W+', self.get_param('objectclasses')):
|
for o in re.split(r'\W+', self.get_param('objectclasses')):
|
||||||
self.objectclasses.append(self._str(o))
|
self.objectclasses.append(self._byte_p23(o))
|
||||||
self.group_attrs = {}
|
self.group_attrs = {}
|
||||||
self.group_attrs_keys = set([])
|
self.group_attrs_keys = set([])
|
||||||
for param in config:
|
for param in config:
|
||||||
@ -89,7 +89,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
|
|
||||||
self.attrlist = []
|
self.attrlist = []
|
||||||
for a in attrslist:
|
for a in attrslist:
|
||||||
self.attrlist.append(self._str(a))
|
self.attrlist.append(self._byte_p2(a))
|
||||||
|
|
||||||
# exception handler (mainly to log something meaningful)
|
# exception handler (mainly to log something meaningful)
|
||||||
def _exception_handler(self, e):
|
def _exception_handler(self, e):
|
||||||
@ -302,7 +302,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
user_filter = self.user_filter_tmpl % {
|
user_filter = self.user_filter_tmpl % {
|
||||||
'username': self._uni(username)
|
'username': self._uni(username)
|
||||||
}
|
}
|
||||||
r = self._search(self._str(user_filter), attrs, self.userdn)
|
r = self._search(self._byte_p2(user_filter), attrs, self.userdn)
|
||||||
|
|
||||||
if len(r) == 0:
|
if len(r) == 0:
|
||||||
return None
|
return None
|
||||||
@ -319,23 +319,56 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
# as the rest of ldapcherry talks in unicode utf-8:
|
# as the rest of ldapcherry talks in unicode utf-8:
|
||||||
# * everything passed to python-ldap must be converted to bytes
|
# * everything passed to python-ldap must be converted to bytes
|
||||||
# * everything coming from python-ldap must be converted to unicode
|
# * everything coming from python-ldap must be converted to unicode
|
||||||
|
#
|
||||||
|
# The previous statement was true for python-ldap < version 3.X.
|
||||||
|
# With versions > 3.0.0 and python 3, it gets tricky,
|
||||||
|
# some parts of python-ldap takes string, specially the filters/escaper.
|
||||||
|
#
|
||||||
|
# so we have now:
|
||||||
|
# *_byte_p2 (unicode -> bytes conversion for python 2)
|
||||||
|
# *_byte_p3 (unicode -> bytes conversion for python 3)
|
||||||
|
# *_byte_p23 (unicode -> bytes conversion for python AND 3)
|
||||||
|
def _byte_p23(self, s):
|
||||||
|
"""unicode -> bytes conversion"""
|
||||||
|
if s is None:
|
||||||
|
return None
|
||||||
|
return s.encode('utf-8')
|
||||||
|
|
||||||
if sys.version < '3':
|
if sys.version < '3':
|
||||||
def _str(self, s):
|
def _byte_p2(self, s):
|
||||||
"""unicode -> bytes conversion"""
|
"""unicode -> bytes conversion (python 2)"""
|
||||||
if s is None:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
return s.encode('utf-8')
|
return s.encode('utf-8')
|
||||||
|
|
||||||
|
def _byte_p3(self, s):
|
||||||
|
"""pass through (does something in python 3)"""
|
||||||
|
return s
|
||||||
|
|
||||||
def _uni(self, s):
|
def _uni(self, s):
|
||||||
"""bytes -> unicode conversion"""
|
"""bytes -> unicode conversion"""
|
||||||
if s is None:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
return s.decode('utf-8', 'ignore')
|
return s.decode('utf-8', 'ignore')
|
||||||
|
|
||||||
|
def attrs_pretreatment(self, attrs):
|
||||||
|
attrs_srt = {}
|
||||||
|
for a in attrs:
|
||||||
|
attrs_srt[self._byte_p2(a)] = self._modlist(
|
||||||
|
self._byte_p2(attrs[a])
|
||||||
|
)
|
||||||
|
return attrs_srt
|
||||||
else:
|
else:
|
||||||
def _str(self, s):
|
def _byte_p2(self, s):
|
||||||
"""unicode -> bytes conversion"""
|
"""pass through (does something in python 2)"""
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def _byte_p3(self, s):
|
||||||
|
"""unicode -> bytes conversion"""
|
||||||
|
if s is None:
|
||||||
|
return None
|
||||||
|
return s.encode('utf-8')
|
||||||
|
|
||||||
def _uni(self, s):
|
def _uni(self, s):
|
||||||
"""bytes -> unicode conversion"""
|
"""bytes -> unicode conversion"""
|
||||||
if s is None:
|
if s is None:
|
||||||
@ -345,16 +378,24 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
else:
|
else:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def attrs_pretreatment(self, attrs):
|
||||||
|
attrs_srt = {}
|
||||||
|
for a in attrs:
|
||||||
|
attrs_srt[self._byte_p2(a)] = self._modlist(
|
||||||
|
self._byte_p3(attrs[a])
|
||||||
|
)
|
||||||
|
return attrs_srt
|
||||||
|
|
||||||
def auth(self, username, password):
|
def auth(self, username, password):
|
||||||
"""Authentication of a user"""
|
"""Authentication of a user"""
|
||||||
|
|
||||||
binddn = self._get_user(self._str(username), NO_ATTR)
|
binddn = self._get_user(self._byte_p2(username), NO_ATTR)
|
||||||
if binddn is not None:
|
if binddn is not None:
|
||||||
ldap_client = self._connect()
|
ldap_client = self._connect()
|
||||||
try:
|
try:
|
||||||
ldap_client.simple_bind_s(
|
ldap_client.simple_bind_s(
|
||||||
self._str(binddn),
|
self._byte_p2(binddn),
|
||||||
self._str(password)
|
self._byte_p2(password)
|
||||||
)
|
)
|
||||||
except ldap.INVALID_CREDENTIALS:
|
except ldap.INVALID_CREDENTIALS:
|
||||||
ldap_client.unbind_s()
|
ldap_client.unbind_s()
|
||||||
@ -368,36 +409,31 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _modlist(in_attr):
|
def _modlist(in_attr):
|
||||||
return in_attr
|
return in_attr
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _modlist(in_attr):
|
def _modlist(in_attr):
|
||||||
return [in_attr]
|
return [in_attr]
|
||||||
|
|
||||||
def attrs_pretreatment(self, attrs):
|
|
||||||
attrs_str = {}
|
|
||||||
for a in attrs:
|
|
||||||
attrs_str[self._str(a)] = self._modlist(self._str(attrs[a]))
|
|
||||||
return attrs_str
|
|
||||||
|
|
||||||
def add_user(self, attrs):
|
def add_user(self, attrs):
|
||||||
"""add a user"""
|
"""add a user"""
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
# encoding crap
|
# encoding crap
|
||||||
attrs_str = self.attrs_pretreatment(attrs)
|
attrs_srt = self.attrs_pretreatment(attrs)
|
||||||
|
|
||||||
attrs_str[self._str('objectClass')] = self.objectclasses
|
attrs_srt[self._byte_p2('objectClass')] = self.objectclasses
|
||||||
# construct is DN
|
# construct is DN
|
||||||
dn = \
|
dn = \
|
||||||
self._str(self.dn_user_attr) + \
|
self._byte_p2(self.dn_user_attr) + \
|
||||||
self._str('=') + \
|
self._byte_p2('=') + \
|
||||||
self._str(ldap.dn.escape_dn_chars(
|
self._byte_p2(ldap.dn.escape_dn_chars(
|
||||||
attrs[self.dn_user_attr]
|
attrs[self.dn_user_attr]
|
||||||
)
|
)
|
||||||
) + \
|
) + \
|
||||||
self._str(',') + \
|
self._byte_p2(',') + \
|
||||||
self._str(self.userdn)
|
self._byte_p2(self.userdn)
|
||||||
# gen the ldif first add_s and add the user
|
# gen the ldif first add_s and add the user
|
||||||
ldif = modlist.addModlist(attrs_str)
|
ldif = modlist.addModlist(attrs_srt)
|
||||||
try:
|
try:
|
||||||
ldap_client.add_s(dn, ldif)
|
ldap_client.add_s(dn, ldif)
|
||||||
except ldap.ALREADY_EXISTS as e:
|
except ldap.ALREADY_EXISTS as e:
|
||||||
@ -411,7 +447,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
"""delete a user"""
|
"""delete a user"""
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
# recover the user dn
|
# recover the user dn
|
||||||
dn = self._str(self._get_user(self._str(username), NO_ATTR))
|
dn = self._byte_p2(self._get_user(self._byte_p2(username), NO_ATTR))
|
||||||
# delete
|
# delete
|
||||||
if dn is not None:
|
if dn is not None:
|
||||||
ldap_client.delete_s(dn)
|
ldap_client.delete_s(dn)
|
||||||
@ -423,15 +459,15 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
def set_attrs(self, username, attrs):
|
def set_attrs(self, username, attrs):
|
||||||
""" set user attributes"""
|
""" set user attributes"""
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
tmp = self._get_user(self._str(username), ALL_ATTRS)
|
tmp = self._get_user(self._byte_p2(username), ALL_ATTRS)
|
||||||
if tmp is None:
|
if tmp is None:
|
||||||
raise UserDoesntExist(username, self.backend_name)
|
raise UserDoesntExist(username, self.backend_name)
|
||||||
dn = self._str(tmp[0])
|
dn = self._byte_p2(tmp[0])
|
||||||
old_attrs = tmp[1]
|
old_attrs = tmp[1]
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
bcontent = self._str(attrs[attr])
|
bcontent = self._byte_p2(attrs[attr])
|
||||||
battr = self._str(attr)
|
battr = self._byte_p2(attr)
|
||||||
new = {battr: self._modlist(bcontent)}
|
new = {battr: self._modlist(self._byte_p3(bcontent))}
|
||||||
# if attr is dn entry, use rename
|
# if attr is dn entry, use rename
|
||||||
if attr.lower() == self.dn_user_attr.lower():
|
if attr.lower() == self.dn_user_attr.lower():
|
||||||
ldap_client.rename_s(
|
ldap_client.rename_s(
|
||||||
@ -448,10 +484,12 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
if type(old_attrs[attr]) is list:
|
if type(old_attrs[attr]) is list:
|
||||||
tmp = []
|
tmp = []
|
||||||
for value in old_attrs[attr]:
|
for value in old_attrs[attr]:
|
||||||
tmp.append(self._str(value))
|
tmp.append(self._byte_p2(value))
|
||||||
bold_value = tmp
|
bold_value = tmp
|
||||||
else:
|
else:
|
||||||
bold_value = self._modlist(self._str(old_attrs[attr]))
|
bold_value = self._modlist(
|
||||||
|
self._byte_p3(old_attrs[attr])
|
||||||
|
)
|
||||||
old = {battr: bold_value}
|
old = {battr: bold_value}
|
||||||
# attribute is not set, just add it
|
# attribute is not set, just add it
|
||||||
else:
|
else:
|
||||||
@ -469,19 +507,19 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
def add_to_groups(self, username, groups):
|
def add_to_groups(self, username, groups):
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
# recover dn of the user and his attributes
|
# recover dn of the user and his attributes
|
||||||
tmp = self._get_user(self._str(username), ALL_ATTRS)
|
tmp = self._get_user(self._byte_p2(username), ALL_ATTRS)
|
||||||
dn = tmp[0]
|
dn = tmp[0]
|
||||||
attrs = tmp[1]
|
attrs = tmp[1]
|
||||||
attrs['dn'] = dn
|
attrs['dn'] = dn
|
||||||
self._normalize_group_attrs(attrs)
|
self._normalize_group_attrs(attrs)
|
||||||
dn = self._str(tmp[0])
|
dn = self._byte_p2(tmp[0])
|
||||||
# add user to all groups
|
# add user to all groups
|
||||||
for group in groups:
|
for group in groups:
|
||||||
group = self._str(group)
|
group = self._byte_p2(group)
|
||||||
# iterate on group membership attributes
|
# iterate on group membership attributes
|
||||||
for attr in self.group_attrs:
|
for attr in self.group_attrs:
|
||||||
# fill the content template
|
# fill the content template
|
||||||
content = self._str(self.group_attrs[attr] % attrs)
|
content = self._byte_p2(self.group_attrs[attr] % attrs)
|
||||||
self._logger(
|
self._logger(
|
||||||
severity=logging.DEBUG,
|
severity=logging.DEBUG,
|
||||||
msg="%(backend)s: adding user '%(user)s'"
|
msg="%(backend)s: adding user '%(user)s'"
|
||||||
@ -497,12 +535,14 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
)
|
)
|
||||||
ldif = modlist.modifyModlist(
|
ldif = modlist.modifyModlist(
|
||||||
{},
|
{},
|
||||||
{attr: self._modlist(content)}
|
{attr: self._modlist(self._byte_p3(content))}
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
print(ldif)
|
||||||
|
print(group)
|
||||||
ldap_client.modify_s(group, ldif)
|
ldap_client.modify_s(group, ldif)
|
||||||
# if already member, not a big deal, just log it and continue
|
# if already member, not a big deal, just log it and continue
|
||||||
except ldap.TYPE_OR_VALUE_EXISTS as e:
|
except (ldap.TYPE_OR_VALUE_EXISTS, ldap.ALREADY_EXISTS) as e:
|
||||||
self._logger(
|
self._logger(
|
||||||
severity=logging.INFO,
|
severity=logging.INFO,
|
||||||
msg="%(backend)s: user '%(user)s'"
|
msg="%(backend)s: user '%(user)s'"
|
||||||
@ -526,19 +566,19 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
# it follows the same logic than add_to_groups
|
# it follows the same logic than add_to_groups
|
||||||
# but with MOD_DELETE
|
# but with MOD_DELETE
|
||||||
ldap_client = self._bind()
|
ldap_client = self._bind()
|
||||||
tmp = self._get_user(self._str(username), ALL_ATTRS)
|
tmp = self._get_user(self._byte_p2(username), ALL_ATTRS)
|
||||||
if tmp is None:
|
if tmp is None:
|
||||||
raise UserDoesntExist(username, self.backend_name)
|
raise UserDoesntExist(username, self.backend_name)
|
||||||
dn = tmp[0]
|
dn = tmp[0]
|
||||||
attrs = tmp[1]
|
attrs = tmp[1]
|
||||||
attrs['dn'] = dn
|
attrs['dn'] = dn
|
||||||
self._normalize_group_attrs(attrs)
|
self._normalize_group_attrs(attrs)
|
||||||
dn = self._str(tmp[0])
|
dn = self._byte_p2(tmp[0])
|
||||||
for group in groups:
|
for group in groups:
|
||||||
group = self._str(group)
|
group = self._byte_p2(group)
|
||||||
for attr in self.group_attrs:
|
for attr in self.group_attrs:
|
||||||
content = self._str(self.group_attrs[attr] % attrs)
|
content = self._byte_p2(self.group_attrs[attr] % attrs)
|
||||||
ldif = [(ldap.MOD_DELETE, attr, content)]
|
ldif = [(ldap.MOD_DELETE, attr, self._byte_p3(content))]
|
||||||
try:
|
try:
|
||||||
ldap_client.modify_s(group, ldif)
|
ldap_client.modify_s(group, ldif)
|
||||||
except ldap.NO_SUCH_ATTRIBUTE as e:
|
except ldap.NO_SUCH_ATTRIBUTE as e:
|
||||||
@ -561,7 +601,9 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
def search(self, searchstring):
|
def search(self, searchstring):
|
||||||
"""Search users"""
|
"""Search users"""
|
||||||
# escape special char to avoid injection
|
# escape special char to avoid injection
|
||||||
searchstring = ldap.filter.escape_filter_chars(self._str(searchstring))
|
searchstring = ldap.filter.escape_filter_chars(
|
||||||
|
self._byte_p2(searchstring)
|
||||||
|
)
|
||||||
# fill the search string template
|
# fill the search string template
|
||||||
searchfilter = self.search_filter_tmpl % {
|
searchfilter = self.search_filter_tmpl % {
|
||||||
'searchstring': searchstring
|
'searchstring': searchstring
|
||||||
@ -586,7 +628,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
def get_user(self, username):
|
def get_user(self, username):
|
||||||
"""Gest a specific user"""
|
"""Gest a specific user"""
|
||||||
ret = {}
|
ret = {}
|
||||||
tmp = self._get_user(self._str(username), ALL_ATTRS)
|
tmp = self._get_user(self._byte_p2(username), ALL_ATTRS)
|
||||||
if tmp is None:
|
if tmp is None:
|
||||||
raise UserDoesntExist(username, self.backend_name)
|
raise UserDoesntExist(username, self.backend_name)
|
||||||
attrs_tmp = tmp[1]
|
attrs_tmp = tmp[1]
|
||||||
@ -600,7 +642,7 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
|
|
||||||
def get_groups(self, username):
|
def get_groups(self, username):
|
||||||
"""Get all groups of a user"""
|
"""Get all groups of a user"""
|
||||||
username = ldap.filter.escape_filter_chars(self._str(username))
|
username = ldap.filter.escape_filter_chars(self._byte_p2(username))
|
||||||
userdn = self._get_user(username, NO_ATTR)
|
userdn = self._get_user(username, NO_ATTR)
|
||||||
|
|
||||||
searchfilter = self.group_filter_tmpl % {
|
searchfilter = self.group_filter_tmpl % {
|
||||||
@ -611,5 +653,5 @@ class Backend(ldapcherry.backend.Backend):
|
|||||||
groups = self._search(searchfilter, NO_ATTR, self.groupdn)
|
groups = self._search(searchfilter, NO_ATTR, self.groupdn)
|
||||||
ret = []
|
ret = []
|
||||||
for entry in groups:
|
for entry in groups:
|
||||||
ret.append(entry[0])
|
ret.append(self._uni(entry[0]))
|
||||||
return ret
|
return ret
|
||||||
|
Loading…
Reference in New Issue
Block a user