| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- import os
- import sys
- import time
- import ldap
- import logging
- import pytest
- from lib389 import DirSrv, Entry, tools, tasks
- from lib389.tools import DirSrvTools
- from lib389._constants import *
- from lib389.properties import *
- from lib389.tasks import *
- from lib389.utils import *
- logging.getLogger(__name__).setLevel(logging.DEBUG)
- log = logging.getLogger(__name__)
- TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
- # Well, it's better than "password" or "password1"
- TEST_PASS = 'banana cream pie'
- class TopologyStandalone(object):
- def __init__(self, standalone):
- standalone.open()
- self.standalone = standalone
- @pytest.fixture(scope="module")
- def topology(request):
- # Creating standalone instance ...
- standalone = DirSrv(verbose=False)
- args_instance[SER_HOST] = HOST_STANDALONE
- args_instance[SER_PORT] = PORT_STANDALONE
- args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
- args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
- args_standalone = args_instance.copy()
- standalone.allocate(args_standalone)
- instance_standalone = standalone.exists()
- if instance_standalone:
- standalone.delete()
- standalone.create()
- standalone.open()
- # Delete each instance in the end
- def fin():
- standalone.delete()
- request.addfinalizer(fin)
- # Clear out the tmp dir
- standalone.clearTmpDir(__file__)
- return TopologyStandalone(standalone)
- def test_ticket48363(topology):
- """
- Test the implementation of rfc3673, '+' for all operational attributes.
- Please see: https://tools.ietf.org/html/rfc3673
- """
- # Test the implementation of the supportFeatures
- # Section 2:
- # Servers supporting this feature SHOULD publish the Object Identifier
- # 1.3.6.1.4.1.4203.1.5.1 as a value of the 'supportedFeatures'
- # [RFC3674] attribute in the root DSE.
- results = topology.standalone.search_s('', ldap.SCOPE_BASE, 'objectClass=*', ['supportedFeatures'] )[0]
- if results.hasAttr('supportedfeatures') is False:
- assert False
- if results.hasValue('supportedfeatures', '1.3.6.1.4.1.4203.1.5.1') is False:
- assert False
- # Section 2:
- # The presence of the attribute description "+" (ASCII 43) in the list
- # of attributes in a Search Request [RFC2251] SHALL signify a request
- # for the return of all operational attributes.
- # Test the two backends, rootdse, and a real ldbm backend
- # Root DSE
- results = topology.standalone.search_s('', ldap.SCOPE_BASE, 'objectClass=*', ['+'] )[0]
- # There are a number of obvious ones in rootdse. These are:
- rootdse_op_attrs = [
- 'supportedExtension',
- 'supportedControl',
- 'supportedFeatures',
- 'supportedSASLMechanisms',
- 'supportedLDAPVersion',
- 'vendorName',
- 'vendorVersion',
- ]
- for opattr in rootdse_op_attrs:
- if results.hasAttr(opattr) is False:
- assert False
- # LDBM backend
- # We are going to examine the root of the suffix, as it's a good easy target
- dc_op_attrs = [
- 'nsuniqueid',
- 'entrydn',
- 'entryid',
- 'aci',
- ]
- dc_user_attrs = [
- 'objectClass',
- 'dc',
- ]
- # We should show that the following work:
- # '+'
- results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+'] )[0]
- for opattr in dc_op_attrs:
- if results.hasAttr(opattr) is False:
- assert False
- for userattr in dc_user_attrs:
- if results.hasAttr(userattr) is False:
- assert True
- # '+' '*'
- results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+', '*'] )[0]
- for opattr in dc_op_attrs:
- if results.hasAttr(opattr) is False:
- assert False
- for userattr in dc_user_attrs:
- if results.hasAttr(userattr) is False:
- assert False
- # Section 2:
- # Client implementors should also note
- # that certain operational attributes may be returned only if requested
- # by name even when "+" is present.
- # We do not currently have any types that are excluded.
- # However, we should ensure that a search for "+ namedType" returns
- # both all operational and the namedType
- # '+' dc
- results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+', 'dc'] )[0]
- for opattr in dc_op_attrs:
- if results.hasAttr(opattr) is False:
- assert False
- if results.hasAttr('dc') is False:
- assert False
- if results.hasAttr('objectclass') is False:
- assert True
- # '*' nsUniqueId
- results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['*', 'nsuniqueid'] )[0]
- for userattr in dc_user_attrs:
- if results.hasAttr(userattr) is False:
- assert False
- if results.hasAttr('nsuniqueid') is False:
- assert False
- if results.hasAttr('entrydn') is False:
- assert True
- # Section 2:
- # As with all search requests, client implementors should note that
- # results may not include all requested attributes due to access
- # controls or other restrictions.
- # Test that with a user with limit read aci, that these are enforced on
- # the + request.
- # Create the user
- uentry = Entry(TEST_USER)
- uentry.setValues('objectclass', 'top', 'extensibleobject')
- uentry.setValues('uid', 'test')
- uentry.setValues('userPassword', TEST_PASS)
- topology.standalone.add_s(uentry)
- # Give them a limited read aci: We may need to purge other acis
- anonaci = '(targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn="ldap:///anyone";)'
- topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', anonaci)])
- # Now we need to create an aci that allows anon/all read to only a few attrs
- # Lets make one real, and one operational.
- anonaci = '(targetattr="objectclass || dc || nsuniqueid")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn="ldap:///anyone";)'
- topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', anonaci)])
- # bind as them, and test.
- topology.standalone.simple_bind_s(TEST_USER, TEST_PASS)
- results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['*', '+'] )[0]
- if results.hasAttr('dc') is False:
- assert False
- if results.hasAttr('nsuniqueid') is False:
- assert False
- if results.hasAttr('entrydn') is False:
- assert True
- log.info('Test complete')
- if __name__ == '__main__':
- # Run isolated
- # -s for DEBUG mode
- CURRENT_FILE = os.path.realpath(__file__)
- pytest.main("-s %s" % CURRENT_FILE)
|