mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Combine get_user/group by dn/cn into get_entry_by_cn/dn.
Also a couple double-escaping fixes I missed in the last patch.
This commit is contained in:
parent
aaa992b744
commit
2b38769b50
@ -56,7 +56,7 @@ def parse_options():
|
|||||||
|
|
||||||
def get_group(client, group_cn):
|
def get_group(client, group_cn):
|
||||||
try:
|
try:
|
||||||
group = client.get_group_by_cn(group_cn)
|
group = client.get_entry_by_cn(group_cn)
|
||||||
except ipa.ipaerror.IPAError, e:
|
except ipa.ipaerror.IPAError, e:
|
||||||
print "%s" % e.message
|
print "%s" % e.message
|
||||||
return None
|
return None
|
||||||
|
@ -26,6 +26,7 @@ if "/usr/share/ipa" not in sys.path:
|
|||||||
|
|
||||||
from ipaserver import funcs
|
from ipaserver import funcs
|
||||||
import ipa.rpcclient as rpcclient
|
import ipa.rpcclient as rpcclient
|
||||||
|
import entity
|
||||||
import user
|
import user
|
||||||
import group
|
import group
|
||||||
import ipa
|
import ipa
|
||||||
@ -53,6 +54,22 @@ class IPAClient:
|
|||||||
if self.local:
|
if self.local:
|
||||||
self.transport.set_krbccache(krbccache)
|
self.transport.set_krbccache(krbccache)
|
||||||
|
|
||||||
|
# General searches
|
||||||
|
|
||||||
|
def get_entry_by_dn(self,dn,sattrs=None):
|
||||||
|
"""Get a specific entry by dn. If sattrs is set then only those
|
||||||
|
attributes will be returned, otherwise all available attributes
|
||||||
|
are returned."""
|
||||||
|
result = self.transport.get_entry_by_dn(dn,sattrs)
|
||||||
|
return entity.Entity(result)
|
||||||
|
|
||||||
|
def get_entry_by_cn(self,cn,sattrs=None):
|
||||||
|
"""Get a specific entry by cn. If sattrs is set then only those
|
||||||
|
attributes will be returned, otherwise all available attributes
|
||||||
|
are returned."""
|
||||||
|
result = self.transport.get_entry_by_cn(cn,sattrs)
|
||||||
|
return entity.Entity(result)
|
||||||
|
|
||||||
# User support
|
# User support
|
||||||
def get_user_by_uid(self,uid,sattrs=None):
|
def get_user_by_uid(self,uid,sattrs=None):
|
||||||
"""Get a specific user by uid. If sattrs is set then only those
|
"""Get a specific user by uid. If sattrs is set then only those
|
||||||
@ -61,13 +78,6 @@ class IPAClient:
|
|||||||
result = self.transport.get_user_by_uid(uid,sattrs)
|
result = self.transport.get_user_by_uid(uid,sattrs)
|
||||||
return user.User(result)
|
return user.User(result)
|
||||||
|
|
||||||
def get_user_by_dn(self,dn,sattrs=None):
|
|
||||||
"""Get a specific user by dn. If sattrs is set then only those
|
|
||||||
attributes will be returned, otherwise all available attributes
|
|
||||||
are returned."""
|
|
||||||
result = self.transport.get_user_by_dn(dn,sattrs)
|
|
||||||
return user.User(result)
|
|
||||||
|
|
||||||
def get_user_by_principal(self,principal,sattrs=None):
|
def get_user_by_principal(self,principal,sattrs=None):
|
||||||
"""Get a specific user by uid. If sattrs is set then only those
|
"""Get a specific user by uid. If sattrs is set then only those
|
||||||
attributes will be returned, otherwise all available attributes
|
attributes will be returned, otherwise all available attributes
|
||||||
@ -154,20 +164,6 @@ class IPAClient:
|
|||||||
|
|
||||||
# Groups support
|
# Groups support
|
||||||
|
|
||||||
def get_group_by_cn(self,cn,sattrs=None):
|
|
||||||
"""Get a specific group by cn. If sattrs is set then only those
|
|
||||||
attributes will be returned, otherwise all available attributes
|
|
||||||
are returned."""
|
|
||||||
result = self.transport.get_group_by_cn(cn,sattrs)
|
|
||||||
return group.Group(result)
|
|
||||||
|
|
||||||
def get_group_by_dn(self,dn,sattrs=None):
|
|
||||||
"""Get a specific group by cn. If sattrs is set then only those
|
|
||||||
attributes will be returned, otherwise all available attributes
|
|
||||||
are returned."""
|
|
||||||
result = self.transport.get_group_by_dn(dn,sattrs)
|
|
||||||
return group.Group(result)
|
|
||||||
|
|
||||||
def get_groups_by_member(self,member_dn,sattrs=None):
|
def get_groups_by_member(self,member_dn,sattrs=None):
|
||||||
"""Gets the groups that member_dn belongs to.
|
"""Gets the groups that member_dn belongs to.
|
||||||
If sattrs is not None then only those
|
If sattrs is not None then only those
|
||||||
|
@ -66,7 +66,42 @@ class RPCClient:
|
|||||||
obj[k] = ent[k]
|
obj[k] = ent[k]
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
# General searches
|
||||||
|
|
||||||
|
def get_entry_by_dn(self,dn,sattrs=None):
|
||||||
|
"""Get a specific entry. If sattrs is not None then only those
|
||||||
|
attributes will be returned, otherwise all available
|
||||||
|
attributes are returned. The result is a dict."""
|
||||||
|
server = self.setup_server()
|
||||||
|
if sattrs is None:
|
||||||
|
sattrs = "__NONE__"
|
||||||
|
try:
|
||||||
|
result = server.get_entry_by_dn(dn, sattrs)
|
||||||
|
except xmlrpclib.Fault, fault:
|
||||||
|
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
||||||
|
except socket.error, (value, msg):
|
||||||
|
raise xmlrpclib.Fault(value, msg)
|
||||||
|
|
||||||
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
|
def get_entry_by_cn(self,cn,sattrs=None):
|
||||||
|
"""Get a specific entry by cn. If sattrs is not None then only those
|
||||||
|
attributes will be returned, otherwise all available
|
||||||
|
attributes are returned. The result is a dict."""
|
||||||
|
server = self.setup_server()
|
||||||
|
if sattrs is None:
|
||||||
|
sattrs = "__NONE__"
|
||||||
|
try:
|
||||||
|
result = server.get_entry_by_cn(cn, sattrs)
|
||||||
|
except xmlrpclib.Fault, fault:
|
||||||
|
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
||||||
|
except socket.error, (value, msg):
|
||||||
|
raise xmlrpclib.Fault(value, msg)
|
||||||
|
|
||||||
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
|
|
||||||
# User support
|
# User support
|
||||||
|
|
||||||
def get_user_by_uid(self,uid,sattrs=None):
|
def get_user_by_uid(self,uid,sattrs=None):
|
||||||
@ -84,22 +119,6 @@ class RPCClient:
|
|||||||
raise xmlrpclib.Fault(value, msg)
|
raise xmlrpclib.Fault(value, msg)
|
||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
def get_user_by_dn(self,dn,sattrs=None):
|
|
||||||
"""Get a specific user. If sattrs is not None then only those
|
|
||||||
attributes will be returned, otherwise all available
|
|
||||||
attributes are returned. The result is a dict."""
|
|
||||||
server = self.setup_server()
|
|
||||||
if sattrs is None:
|
|
||||||
sattrs = "__NONE__"
|
|
||||||
try:
|
|
||||||
result = server.get_user_by_dn(dn, sattrs)
|
|
||||||
except xmlrpclib.Fault, fault:
|
|
||||||
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
|
||||||
except socket.error, (value, msg):
|
|
||||||
raise xmlrpclib.Fault(value, msg)
|
|
||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
|
||||||
|
|
||||||
def get_user_by_principal(self,principal,sattrs=None):
|
def get_user_by_principal(self,principal,sattrs=None):
|
||||||
"""Get a specific user. If sattrs is not None then only those
|
"""Get a specific user. If sattrs is not None then only those
|
||||||
@ -258,38 +277,6 @@ class RPCClient:
|
|||||||
return ipautil.unwrap_binary_data(result)
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
# Group support
|
# Group support
|
||||||
|
|
||||||
def get_group_by_cn(self,cn,sattrs=None):
|
|
||||||
"""Get a specific group. If sattrs is not None then only those
|
|
||||||
attributes will be returned, otherwise all available
|
|
||||||
attributes are returned. The result is a dict."""
|
|
||||||
server = self.setup_server()
|
|
||||||
if sattrs is None:
|
|
||||||
sattrs = "__NONE__"
|
|
||||||
try:
|
|
||||||
result = server.get_group_by_cn(cn, sattrs)
|
|
||||||
except xmlrpclib.Fault, fault:
|
|
||||||
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
|
||||||
except socket.error, (value, msg):
|
|
||||||
raise xmlrpclib.Fault(value, msg)
|
|
||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
|
||||||
|
|
||||||
def get_group_by_dn(self,dn,sattrs=None):
|
|
||||||
"""Get a specific group. If sattrs is not None then only those
|
|
||||||
attributes will be returned, otherwise all available
|
|
||||||
attributes are returned. The result is a dict."""
|
|
||||||
server = self.setup_server()
|
|
||||||
if sattrs is None:
|
|
||||||
sattrs = "__NONE__"
|
|
||||||
try:
|
|
||||||
result = server.get_group_by_dn(dn, sattrs)
|
|
||||||
except xmlrpclib.Fault, fault:
|
|
||||||
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
|
|
||||||
except socket.error, (value, msg):
|
|
||||||
raise xmlrpclib.Fault(value, msg)
|
|
||||||
|
|
||||||
return ipautil.unwrap_binary_data(result)
|
|
||||||
|
|
||||||
def get_groups_by_member(self,member_dn,sattrs=None):
|
def get_groups_by_member(self,member_dn,sattrs=None):
|
||||||
"""Gets the groups that member_dn belongs to.
|
"""Gets the groups that member_dn belongs to.
|
||||||
|
@ -84,7 +84,7 @@ class GroupController(IPAController):
|
|||||||
# on any error, we redirect to the _edit_ group page.
|
# on any error, we redirect to the _edit_ group page.
|
||||||
# this code does data setup, similar to groupedit()
|
# this code does data setup, similar to groupedit()
|
||||||
#
|
#
|
||||||
group = client.get_group_by_cn(kw['cn'], group_fields)
|
group = client.get_entry_by_cn(kw['cn'], group_fields)
|
||||||
group_dict = group.toDict()
|
group_dict = group.toDict()
|
||||||
member_dicts = []
|
member_dicts = []
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ class GroupController(IPAController):
|
|||||||
client = self.get_ipaclient()
|
client = self.get_ipaclient()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
group = client.get_group_by_cn(cn, group_fields)
|
group = client.get_entry_by_cn(cn, group_fields)
|
||||||
|
|
||||||
group_dict = group.toDict()
|
group_dict = group.toDict()
|
||||||
|
|
||||||
@ -186,9 +186,8 @@ class GroupController(IPAController):
|
|||||||
member_dns = [member_dns]
|
member_dns = [member_dns]
|
||||||
|
|
||||||
# TODO: convert this into an efficient (single) function call
|
# TODO: convert this into an efficient (single) function call
|
||||||
# Note: this isn't quite right, since it can be users and groups.
|
|
||||||
members = map(
|
members = map(
|
||||||
lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn',
|
lambda dn: client.get_entry_by_dn(dn, ['dn', 'givenname', 'sn',
|
||||||
'uid', 'cn']),
|
'uid', 'cn']),
|
||||||
member_dns)
|
member_dns)
|
||||||
members.sort(self.sort_group_member)
|
members.sort(self.sort_group_member)
|
||||||
@ -346,7 +345,7 @@ class GroupController(IPAController):
|
|||||||
client = self.get_ipaclient()
|
client = self.get_ipaclient()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
group = client.get_group_by_cn(cn, group_fields)
|
group = client.get_entry_by_cn(cn, group_fields)
|
||||||
group_dict = group.toDict()
|
group_dict = group.toDict()
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -359,9 +358,8 @@ class GroupController(IPAController):
|
|||||||
member_dns = [member_dns]
|
member_dns = [member_dns]
|
||||||
|
|
||||||
# TODO: convert this into an efficient (single) function call
|
# TODO: convert this into an efficient (single) function call
|
||||||
# Note: this isn't quite right, since it can be users and groups.
|
|
||||||
members = map(
|
members = map(
|
||||||
lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn',
|
lambda dn: client.get_entry_by_dn(dn, ['dn', 'givenname', 'sn',
|
||||||
'uid', 'cn']),
|
'uid', 'cn']),
|
||||||
member_dns)
|
member_dns)
|
||||||
members.sort(self.sort_group_member)
|
members.sort(self.sort_group_member)
|
||||||
|
@ -411,7 +411,7 @@ class UserController(IPAController):
|
|||||||
user_manager = None
|
user_manager = None
|
||||||
try:
|
try:
|
||||||
if user.manager:
|
if user.manager:
|
||||||
user_manager = client.get_user_by_dn(user.manager,
|
user_manager = client.get_entry_by_dn(user.manager,
|
||||||
['givenname', 'sn', 'uid'])
|
['givenname', 'sn', 'uid'])
|
||||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
pass
|
pass
|
||||||
|
@ -65,7 +65,7 @@ from ipagui.helpers import ipahelper
|
|||||||
function renderMemberInfo(newdiv, info) {
|
function renderMemberInfo(newdiv, info) {
|
||||||
if (info.type == "group") {
|
if (info.type == "group") {
|
||||||
newdiv.appendChild(document.createTextNode(
|
newdiv.appendChild(document.createTextNode(
|
||||||
info.name.escapeHTML() + " "));
|
info.name + " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -36,7 +36,7 @@ from ipagui.helpers import ipahelper
|
|||||||
function renderMemberInfo(newdiv, info) {
|
function renderMemberInfo(newdiv, info) {
|
||||||
if (info.type == "group") {
|
if (info.type == "group") {
|
||||||
newdiv.appendChild(document.createTextNode(
|
newdiv.appendChild(document.createTextNode(
|
||||||
info.name.escapeHTML() + " "));
|
info.name + " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -323,7 +323,26 @@ class IPAServer:
|
|||||||
partial_match_filter += ")"
|
partial_match_filter += ")"
|
||||||
|
|
||||||
return (exact_match_filter, partial_match_filter)
|
return (exact_match_filter, partial_match_filter)
|
||||||
|
|
||||||
|
# General searches
|
||||||
|
|
||||||
|
def get_entry_by_dn (self, dn, sattrs=None, opts=None):
|
||||||
|
"""Get a specific entry. Return as a dict of values.
|
||||||
|
Multi-valued fields are represented as lists.
|
||||||
|
"""
|
||||||
|
|
||||||
|
filter = "(objectClass=*)"
|
||||||
|
return self.__get_entry(dn, filter, sattrs, opts)
|
||||||
|
|
||||||
|
def get_entry_by_cn (self, cn, sattrs=None, opts=None):
|
||||||
|
"""Get a specific entry by cn. Return as a dict of values.
|
||||||
|
Multi-valued fields are represented as lists.
|
||||||
|
"""
|
||||||
|
|
||||||
|
cn = self.__safe_filter(cn)
|
||||||
|
filter = "(cn=" + cn + ")"
|
||||||
|
return self.__get_entry(self.basedn, filter, sattrs, opts)
|
||||||
|
|
||||||
# User support
|
# User support
|
||||||
|
|
||||||
def __is_user_unique(self, uid, opts):
|
def __is_user_unique(self, uid, opts):
|
||||||
@ -345,14 +364,6 @@ class IPAServer:
|
|||||||
uid = self.__safe_filter(uid)
|
uid = self.__safe_filter(uid)
|
||||||
filter = "(uid=" + uid + ")"
|
filter = "(uid=" + uid + ")"
|
||||||
return self.__get_entry(self.basedn, filter, sattrs, opts)
|
return self.__get_entry(self.basedn, filter, sattrs, opts)
|
||||||
|
|
||||||
def get_user_by_dn (self, dn, sattrs=None, opts=None):
|
|
||||||
"""Get a specific user's entry. Return as a dict of values.
|
|
||||||
Multi-valued fields are represented as lists.
|
|
||||||
"""
|
|
||||||
|
|
||||||
filter = "(objectClass=*)"
|
|
||||||
return self.__get_entry(dn, filter, sattrs, opts)
|
|
||||||
|
|
||||||
def get_user_by_principal(self, principal, sattrs=None, opts=None):
|
def get_user_by_principal(self, principal, sattrs=None, opts=None):
|
||||||
"""Get a user entry searching by Kerberos Principal Name.
|
"""Get a user entry searching by Kerberos Principal Name.
|
||||||
@ -649,23 +660,6 @@ class IPAServer:
|
|||||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def get_group_by_cn (self, cn, sattrs=None, opts=None):
|
|
||||||
"""Get a specific group's entry. Return as a dict of values.
|
|
||||||
Multi-valued fields are represented as lists.
|
|
||||||
"""
|
|
||||||
|
|
||||||
cn = self.__safe_filter(cn)
|
|
||||||
filter = "(cn=" + cn + ")"
|
|
||||||
return self.__get_entry(self.basedn, filter, sattrs, opts)
|
|
||||||
|
|
||||||
def get_group_by_dn (self, dn, sattrs=None, opts=None):
|
|
||||||
"""Get a specific group's entry. Return as a dict of values.
|
|
||||||
Multi-valued fields are represented as lists.
|
|
||||||
"""
|
|
||||||
|
|
||||||
filter = "(objectClass=*)"
|
|
||||||
return self.__get_entry(dn, filter, sattrs, opts)
|
|
||||||
|
|
||||||
def get_groups_by_member (self, member_dn, sattrs=None, opts=None):
|
def get_groups_by_member (self, member_dn, sattrs=None, opts=None):
|
||||||
"""Get a specific group's entry. Return as a dict of values.
|
"""Get a specific group's entry. Return as a dict of values.
|
||||||
Multi-valued fields are represented as lists.
|
Multi-valued fields are represented as lists.
|
||||||
@ -787,7 +781,7 @@ class IPAServer:
|
|||||||
"""Add a member to an existing group.
|
"""Add a member to an existing group.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_group = self.get_group_by_dn(group_dn, None, opts)
|
old_group = self.get_entry_by_dn(group_dn, None, opts)
|
||||||
if old_group is None:
|
if old_group is None:
|
||||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
||||||
new_group = copy.deepcopy(old_group)
|
new_group = copy.deepcopy(old_group)
|
||||||
@ -834,7 +828,7 @@ class IPAServer:
|
|||||||
"""Remove a member_dn from an existing group.
|
"""Remove a member_dn from an existing group.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_group = self.get_group_by_dn(group_dn, None, opts)
|
old_group = self.get_entry_by_dn(group_dn, None, opts)
|
||||||
if old_group is None:
|
if old_group is None:
|
||||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
||||||
new_group = copy.deepcopy(old_group)
|
new_group = copy.deepcopy(old_group)
|
||||||
@ -1002,7 +996,7 @@ class IPAServer:
|
|||||||
The memberOf plugin handles removing the group from any other
|
The memberOf plugin handles removing the group from any other
|
||||||
groups.
|
groups.
|
||||||
"""
|
"""
|
||||||
group = self.get_group_by_dn(group_dn, ['dn', 'cn'], opts)
|
group = self.get_entry_by_dn(group_dn, ['dn', 'cn'], opts)
|
||||||
|
|
||||||
if len(group) != 1:
|
if len(group) != 1:
|
||||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
||||||
@ -1020,12 +1014,12 @@ class IPAServer:
|
|||||||
tgroup is the DN of the target group to be added to
|
tgroup is the DN of the target group to be added to
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_group = self.get_group_by_dn(tgroup, None, opts)
|
old_group = self.get_entry_by_dn(tgroup, None, opts)
|
||||||
if old_group is None:
|
if old_group is None:
|
||||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
||||||
new_group = copy.deepcopy(old_group)
|
new_group = copy.deepcopy(old_group)
|
||||||
|
|
||||||
group_dn = self.get_group_by_dn(group, ['dn', 'cn', 'objectclass'], opts)
|
group_dn = self.get_entry_by_dn(group, ['dn', 'cn', 'objectclass'], opts)
|
||||||
if group_dn is None:
|
if group_dn is None:
|
||||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
|
||||||
|
|
||||||
|
@ -317,8 +317,9 @@ def handler(req, profiling=False):
|
|||||||
try:
|
try:
|
||||||
f = funcs.IPAServer()
|
f = funcs.IPAServer()
|
||||||
h = ModXMLRPCRequestHandler()
|
h = ModXMLRPCRequestHandler()
|
||||||
|
h.register_function(f.get_entry_by_dn)
|
||||||
|
h.register_function(f.get_entry_by_cn)
|
||||||
h.register_function(f.get_user_by_uid)
|
h.register_function(f.get_user_by_uid)
|
||||||
h.register_function(f.get_user_by_dn)
|
|
||||||
h.register_function(f.get_user_by_principal)
|
h.register_function(f.get_user_by_principal)
|
||||||
h.register_function(f.get_users_by_manager)
|
h.register_function(f.get_users_by_manager)
|
||||||
h.register_function(f.add_user)
|
h.register_function(f.add_user)
|
||||||
@ -329,8 +330,6 @@ def handler(req, profiling=False):
|
|||||||
h.register_function(f.delete_user)
|
h.register_function(f.delete_user)
|
||||||
h.register_function(f.mark_user_deleted)
|
h.register_function(f.mark_user_deleted)
|
||||||
h.register_function(f.modifyPassword)
|
h.register_function(f.modifyPassword)
|
||||||
h.register_function(f.get_group_by_cn)
|
|
||||||
h.register_function(f.get_group_by_dn)
|
|
||||||
h.register_function(f.get_groups_by_member)
|
h.register_function(f.get_groups_by_member)
|
||||||
h.register_function(f.add_group)
|
h.register_function(f.add_group)
|
||||||
h.register_function(f.find_groups)
|
h.register_function(f.find_groups)
|
||||||
|
Loading…
Reference in New Issue
Block a user