summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/plugins/baseldap.py6
-rw-r--r--ipalib/plugins/dns.py4
-rw-r--r--ipalib/plugins/entitle.py1
-rw-r--r--ipalib/plugins/host.py4
-rw-r--r--ipalib/plugins/hostgroup.py3
-rw-r--r--ipalib/plugins/permission.py18
-rw-r--r--ipalib/plugins/pwpolicy.py2
-rw-r--r--ipalib/plugins/selinuxusermap.py3
-rw-r--r--ipalib/plugins/service.py3
-rw-r--r--ipalib/plugins/user.py3
-rw-r--r--tests/test_xmlrpc/test_permission_plugin.py74
11 files changed, 110 insertions, 11 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 58d53fd0d..93852a2dd 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -1857,9 +1857,9 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
for callback in self.POST_CALLBACKS:
if hasattr(callback, 'im_self'):
- callback(ldap, entries, truncated, *args, **options)
+ truncated = callback(ldap, entries, truncated, *args, **options)
else:
- callback(self, ldap, entries, truncated, *args, **options)
+ truncated = callback(self, ldap, entries, truncated, *args, **options)
if self.sort_result_entries:
if self.obj.primary_key:
@@ -1884,7 +1884,7 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
return (filters, base_dn, scope)
def post_callback(self, ldap, entries, truncated, *args, **options):
- pass
+ return truncated
def exc_callback(self, args, options, exc, call_func, *call_args, **call_kwargs):
raise exc
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index e26332d46..e2b5995b9 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -132,7 +132,7 @@ EXAMPLES:
SRV record: 0 3 389 fast.example.com, 0 1 389 slow.example.com, 1 1 389 backup.example.com
- Modify SRV record '0 3 389 fast.example.com'? Yes/No (default No):
+ Modify SRV record '0 3 389 fast.example.com'? Yes/No (default No):
Modify SRV record '0 1 389 slow.example.com'? Yes/No (default No): y
SRV Priority [0]: (keep the default value)
SRV Weight [1]: 2 (modified value)
@@ -2589,6 +2589,8 @@ class dnsrecord_find(LDAPSearch):
for entry in entries:
self.obj.postprocess_record(entry[1], **options)
+ return truncated
+
api.register(dnsrecord_find)
class dns_resolve(Command):
diff --git a/ipalib/plugins/entitle.py b/ipalib/plugins/entitle.py
index 6ade854c3..5ccdb6510 100644
--- a/ipalib/plugins/entitle.py
+++ b/ipalib/plugins/entitle.py
@@ -461,6 +461,7 @@ class entitle_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if len(entries) == 0:
raise errors.NotRegisteredError()
+ return truncated
api.register(entitle_find)
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 662cff311..96b73cc55 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -769,7 +769,7 @@ class host_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.get('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, entry_attrs) = entry
set_certificate_attrs(entry_attrs)
@@ -785,6 +785,8 @@ class host_find(LDAPSearch):
output_sshpubkey(ldap, dn, entry_attrs)
+ return truncated
+
api.register(host_find)
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index 2a9a0a533..b68c45842 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -182,10 +182,11 @@ class hostgroup_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.get('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, entry_attrs) = entry
self.obj.suppress_netgroup_memberof(dn, entry_attrs)
+ return truncated
api.register(hostgroup_find)
diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py
index 18fdcdddf..a484ff640 100644
--- a/ipalib/plugins/permission.py
+++ b/ipalib/plugins/permission.py
@@ -351,7 +351,7 @@ class permission_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.pop('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, attrs) = entry
try:
@@ -363,6 +363,15 @@ class permission_find(LDAPSearch):
attrs[attr] = aci[attr]
except errors.NotFound:
self.debug('ACI not found for %s' % attrs['cn'][0])
+ if truncated:
+ # size/time limit met, no need to search acis
+ return truncated
+
+ if 'sizelimit' in options:
+ max_entries = options['sizelimit']
+ else:
+ config = ldap.get_ipa_config()[1]
+ max_entries = config['ipasearchrecordslimit']
# Now find all the ACIs that match. Once we find them, add any that
# aren't already in the list along with their permission info.
@@ -398,7 +407,12 @@ class permission_find(LDAPSearch):
dn = permission['dn']
del permission['dn']
if (dn, permission) not in entries:
- entries.append((dn, permission))
+ if len(entries) < max_entries:
+ entries.append((dn, permission))
+ else:
+ truncated = True
+ break
+ return truncated
api.register(permission_find)
diff --git a/ipalib/plugins/pwpolicy.py b/ipalib/plugins/pwpolicy.py
index 7be590f2e..77e6f2c79 100644
--- a/ipalib/plugins/pwpolicy.py
+++ b/ipalib/plugins/pwpolicy.py
@@ -498,4 +498,6 @@ class pwpolicy_find(LDAPSearch):
except KeyError:
pass
+ return truncated
+
api.register(pwpolicy_find)
diff --git a/ipalib/plugins/selinuxusermap.py b/ipalib/plugins/selinuxusermap.py
index e6179cee9..160e68c96 100644
--- a/ipalib/plugins/selinuxusermap.py
+++ b/ipalib/plugins/selinuxusermap.py
@@ -318,10 +318,11 @@ all=True)['result']
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.get('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, attrs) = entry
self.obj._convert_seealso(ldap, attrs, **options)
+ return truncated
api.register(selinuxusermap_find)
diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index 333d5bbf3..24a0a0f87 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -399,11 +399,12 @@ class service_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.get('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, entry_attrs) = entry
self.obj.get_password_attributes(ldap, dn, entry_attrs)
set_certificate_attrs(entry_attrs)
+ return truncated
api.register(service_find)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 2e069bde3..b48e68022 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -625,13 +625,14 @@ class user_find(LDAPSearch):
def post_callback(self, ldap, entries, truncated, *args, **options):
if options.get('pkey_only', False):
- return
+ return truncated
for entry in entries:
(dn, attrs) = entry
self.obj._convert_manager(attrs, **options)
self.obj.get_password_attributes(ldap, dn, attrs)
convert_nsaccountlock(attrs)
output_sshpubkey(ldap, dn, attrs)
+ return truncated
msg_summary = ngettext(
'%(count)d user matched', '%(count)d users matched', 0
diff --git a/tests/test_xmlrpc/test_permission_plugin.py b/tests/test_xmlrpc/test_permission_plugin.py
index 28db7dc2f..d8ff14903 100644
--- a/tests/test_xmlrpc/test_permission_plugin.py
+++ b/tests/test_xmlrpc/test_permission_plugin.py
@@ -387,6 +387,80 @@ class test_permission(Declarative):
dict(
+ desc='Search for %r with a limit of 1 (truncated)' % permission1,
+ command=('permission_find', [permission1], dict(sizelimit=1)),
+ expected=dict(
+ count=1,
+ truncated=True,
+ summary=u'1 permission matched',
+ result=[
+ {
+ 'dn': lambda x: DN(x) == permission1_dn,
+ 'cn': [permission1],
+ 'member_privilege': [privilege1],
+ 'type': u'user',
+ 'permissions': [u'write'],
+ },
+ ],
+ ),
+ ),
+
+
+ dict(
+ desc='Search for %r with a limit of 2' % permission1,
+ command=('permission_find', [permission1], dict(sizelimit=2)),
+ expected=dict(
+ count=2,
+ truncated=False,
+ summary=u'2 permissions matched',
+ result=[
+ {
+ 'dn': lambda x: DN(x) == permission1_dn,
+ 'cn': [permission1],
+ 'member_privilege': [privilege1],
+ 'type': u'user',
+ 'permissions': [u'write'],
+ },
+ {
+ 'dn': lambda x: DN(x) == permission2_dn,
+ 'cn': [permission2],
+ 'type': u'user',
+ 'permissions': [u'write'],
+ },
+ ],
+ ),
+ ),
+
+
+ # This tests setting truncated to True in the post_callback of
+ # permission_find(). The return order in LDAP is not guaranteed
+ # but in practice this is the first entry it finds. This is subject
+ # to change.
+ dict(
+ desc='Search for permissions by attr with a limit of 1 (truncated)',
+ command=('permission_find', [], dict(attrs=u'ipaenabledflag',
+ sizelimit=1)),
+ expected=dict(
+ count=1,
+ truncated=True,
+ summary=u'1 permission matched',
+ result=[
+ {
+ 'dn': lambda x: DN(x) == DN(('cn', 'Modify HBAC rule'),
+ api.env.container_permission,api.env.basedn),
+ 'cn': [u'Modify HBAC rule'],
+ 'member_privilege': [u'HBAC Administrator'],
+ 'permissions' : [u'write'],
+ 'attrs': [u'servicecategory', u'sourcehostcategory', u'cn', u'description', u'ipaenabledflag', u'accesstime', u'usercategory', u'hostcategory', u'accessruletype', u'sourcehost'],
+ 'subtree' : u'ldap:///ipauniqueid=*,cn=hbac,%s' % api.env.basedn,
+ 'memberindirect': [u'cn=hbac administrator,cn=privileges,cn=pbac,%s' % api.env.basedn, u'cn=it security specialist,cn=roles,cn=accounts,%s' % api.env.basedn],
+ },
+ ],
+ ),
+ ),
+
+
+ dict(
desc='Update %r' % permission1,
command=(
'permission_mod', [permission1], dict(permissions=u'read', memberof=u'ipausers')