Exemple #1
0
def test_acl_default_allow_self_write_nsuser(topology):
    """
    Testing nsusers can self write and self read. This it a sanity test
    so that our default entries have their aci's checked.

    :id: 4f0fb01a-36a6-430c-a2ee-ebeb036bd951

    :setup: Standalone instance

    :steps:
        1. Testing comparison of two different users.

    :expectedresults:
        1. Should fail to compare
    """
    topology.standalone.enable_tls()
    nsusers = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX)
    # Create a user as dm.
    user = nsusers.create(
        properties={
            'uid': 'test_nsuser',
            'cn': 'test_nsuser',
            'displayName': 'testNsuser',
            'legalName': 'testNsuser',
            'uidNumber': '1001',
            'gidNumber': '1001',
            'homeDirectory': '/home/testnsuser',
            'userPassword': USER_PASSWORD,
        })
    # Create a new con and bind as the user.
    user_conn = user.bind(USER_PASSWORD)

    user_nsusers = nsUserAccounts(user_conn, DEFAULT_SUFFIX)
    self_ent = user_nsusers.get(dn=user.dn)

    # Can we self read x,y,z
    check = self_ent.get_attrs_vals_utf8([
        'uid',
        'cn',
        'displayName',
        'legalName',
        'uidNumber',
        'gidNumber',
        'homeDirectory',
    ])
    for k in check.values():
        # Could we read the values?
        assert (isinstance(k, list))
        assert (len(k) > 0)
    # Can we self change a,b,c
    self_ent.ensure_attr_state({
        'legalName': ['testNsuser_update'],
        'displayName': ['testNsuser_update'],
        'nsSshPublicKey': ['testkey'],
    })
    # self change pw
    self_ent.change_password(USER_PASSWORD, NEW_USER_PASSWORD)
def test_entryuuid_with_replication(topo_m2):
    """ Check that entryuuid works with replication

    :id: a5f15bf9-7f63-473a-840c-b9037b787024

    :setup: two node mmr

    :steps:
        1. Create an entry on one server
        2. Wait for replication
        3. Assert it is on the second

    :expectedresults:
        1. Success
        1. Success
        1. Success
    """

    server_a = topo_m2.ms["supplier1"]
    server_b = topo_m2.ms["supplier2"]
    server_a.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.TRACE))
    server_b.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.TRACE))

    repl = ReplicationManager(DEFAULT_SUFFIX)

    account_a = nsUserAccounts(server_a,
                               DEFAULT_SUFFIX).create_test_user(uid=2000)
    euuid_a = account_a.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_a)
    assert (euuid_a is not None)
    assert (len(euuid_a) == 1)

    repl.wait_for_replication(server_a, server_b)

    account_b = nsUserAccounts(server_b, DEFAULT_SUFFIX).get("test_user_2000")
    euuid_b = account_b.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_b)

    server_a.config.loglevel(vals=(ErrorLog.DEFAULT, ))
    server_b.config.loglevel(vals=(ErrorLog.DEFAULT, ))

    assert (euuid_b is not None)
    assert (len(euuid_b) == 1)
    assert (euuid_b == euuid_a)

    account_b.set("description", "update")
    repl.wait_for_replication(server_b, server_a)

    euuid_c = account_a.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_c)
    assert (euuid_c is not None)
    assert (len(euuid_c) == 1)
    assert (euuid_c == euuid_a)
Exemple #3
0
def test_ldap_auth_token_disabled(topology):
    """ Assert when the feature is disabled that token operations are not able to progress

    :id: ccde5d0b-7f2d-49d5-b9d5-f7082f8f36a3

    :setup: Standalone instance

    :steps:
        1. Create a user
        2. Attempt to get a token.
        3. Enable the feature, get a token, then disable it.
        4. Attempt to auth

    :expectedresults:
        1. Success
        2. Fails to get a token
        3. Token is received
        4. Auth fails as token is disabled.
    """
    topology.standalone.enable_tls()
    topology.standalone.config.set('nsslapd-enable-ldapssotoken',
                                   'off')  # disable it.
    nsusers = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX)
    # Create a user as dm.
    user = nsusers.create(
        properties={
            'uid': 'test_nsuser1',
            'cn': 'test_nsuser1',
            'displayName': 'testNsuser1',
            'legalName': 'testNsuser1',
            'uidNumber': '1002',
            'gidNumber': '1002',
            'homeDirectory': '/home/testnsuser1',
            'userPassword': USER_PASSWORD,
        })
    # Create a new con and bind as the user.
    user_conn = user.bind(USER_PASSWORD)
    user_account = nsUserAccounts(user_conn,
                                  DEFAULT_SUFFIX).get('test_nsuser1')
    # From the user_conn do an extop_s for the token
    with pytest.raises(ldap.PROTOCOL_ERROR):
        user_account.request_sso_token()
    # Now enable it
    topology.standalone.config.set('nsslapd-enable-ldapssotoken', 'on')
    token = user_account.request_sso_token()
    # Now disable
    topology.standalone.config.set('nsslapd-enable-ldapssotoken', 'off')
    # Now attempt to bind (should fail)
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        user_account.authenticate_sso_token(token)
def test_dsidm_user_delete(topology_st, create_test_user):
    """ Test dsidm user delete option

    :id: 3704dc3a-9787-4f74-aaa8-45f38e4a6a52
    :setup: Standalone instance
    :steps:
         1. Run dsidm user delete on created user
         2. Check that a message is provided on deletion
         3. Check that user does not exist
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')
    output = 'Successfully deleted {}'.format(test_user.dn)

    args = FakeArgs()
    args.dn = test_user.dn

    log.info('Test dsidm user delete')
    delete(standalone,
           DEFAULT_SUFFIX,
           topology_st.logcap.log,
           args,
           warn=False)
    check_value_in_log_and_reset(topology_st, check_value=output)

    log.info('Check that user does not exist')
    assert not test_user.exists()
Exemple #5
0
def display(inst, basedn, log, args):

    users = nsUserAccounts(inst, basedn)
    groups = Groups(inst, basedn)

    schema_type = "rfc2307"
    try:
        mo_plugin = MemberOfPlugin(inst)
        if mo_plugin.status():
            schema_type = "rfc2307bis"
    except:
        schema_type = "unknown - likely access denied to memberof plugin config"

    # Get required information
    print(
        DISPLAY_TEMPLATE.format(
            ldap_uri=inst.ldapuri,
            ldap_dns_uri=basedn_to_ldap_dns_uri(basedn),
            basedn=basedn,
            schema_type=schema_type,
            user_basedn=users._basedn,
            user_filter=users._get_objectclass_filter(),
            user_id_filter=users._get_selector_filter('<PARAM>'),
            group_basedn=groups._basedn,
            group_filter=groups._get_objectclass_filter(),
            group_id_filter=groups._get_selector_filter('<PARAM>'),
            uuid_attr='nsUniqueId',
            user_rdn=users._filterattrs[0],
            group_rdn=groups._filterattrs[0],
            group_member='member',
        ))
def test_dsidm_user_list(topology_st, create_test_user):
    """ Test dsidm user list option

    :id: a7400ac2-b629-4507-bc05-c6402a5b437b
    :setup: Standalone instance
    :steps:
         1. Run dsidm user list option without json
         2. Check the output content is correct
         3. Run dsidm user list option with json
         4. Check the json content is correct
         5. Delete the user
         6. Check the user is not in the list with json
         7. Check the user is not in the list without json
    :expectedresults:
         1. Success
         2. Success
         3. Success
         4. Success
         5. Success
         6. Success
         7. Success
    """

    standalone = topology_st.standalone
    args = FakeArgs()
    args.json = False
    user_value = 'test_user_1000'
    json_list = ['type', 'list', 'items']

    log.info('Empty the log file to prevent false data to check about user')
    topology_st.logcap.flush()

    log.info('Test dsidm user list without json')
    list(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, check_value=user_value)

    log.info('Test dsidm user list with json')
    args.json = True
    list(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st,
                                 content_list=json_list,
                                 check_value=user_value)

    log.info('Delete the user')
    users = nsUserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
    testuser = users.get(user_value)
    testuser.delete()

    log.info('Test empty dsidm user list with json')
    list(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st,
                                 content_list=json_list,
                                 check_value_not=user_value)

    log.info('Test empty dsidm user list without json')
    args.json = False
    list(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, check_value_not=user_value)
def test_migrate_openldap_password_hash(topology_st):
    """Test import of an openldap password value into the directory and assert
    it can bind.

    :id: e4898e0d-5d18-4765-9249-84bcbf862fde
    :setup: Standalone Instance
    :steps:
        1. Import a hash
        2. Attempt a bind
        3. Goto 1

    :expectedresults:
        1. Success
        2. Success
        3. Success
    """
    inst = topology_st.standalone
    inst.config.set('nsslapd-allow-hashed-passwords', 'on')

    # You generate these with:
    # slappasswd -s password -o module-load=/usr/lib64/openldap/pw-argon2.so -h {ARGON2}
    pwds = [
        '{CRYPT}ZZKRwXSu3tt8s',
        '{SSHA}jdALDtX0+MVMkRsX0ilHz0O6Uos95D4s',
        '{MD5}X03MO1qnZdYdgyfeuILPmQ==',
        '{SMD5}RnexgcsjdBHMQ1yhB7+sD+a+qDI=',
        '{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=',
        '{SHA256}XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=',
        '{SSHA256}covFryM35UrKB3gMYxtYpQYTHbTn5kFphjcNHewfj581SLJwjA9jew==',
        '{SHA384}qLZLq9CsqRpZvbt3YbQh1PK7OCgNOnW6DyHyvrxFWD1EbFmGYMlM5oDEfRnDB4On',
        '{SSHA384}kNjTWdmyy2G1IgJF8WrOpq0N//Yc2Ec5TIQYceuiuHQXRXpC1bfnMqyOx0NxrSREjBWDwUpqXjo=',
        '{SHA512}sQnzu7wkTrgkQZF+0G1hi5AI3Qmzvv0bXgc5THBqi7mAsdd4Xll27ASbRt9fEyavWi6m0QP9B8lThf+rDKy8hg==',
        '{SSHA512}+7A8kA32q4mCBao4Cbatdyzl5imVwJ62ZAE7UOTP4pfrF90E9R2LabOfJFzx6guaYhTmUEVK2wRKC8bToqspdeTluX2d1BX2',
        # Need to check --
        '{PBKDF2}10000$IlfapjA351LuDSwYC0IQ8Q$saHqQTuYnjJN/tmAndT.8mJt.6w',
        '{PBKDF2-SHA1}10000$ZBEH6B07rgQpJSikyvMU2w$TAA03a5IYkz1QlPsbJKvUsTqNV',
        '{PBKDF2-SHA256}10000$henZGfPWw79Cs8ORDeVNrQ$1dTJy73v6n3bnTmTZFghxHXHLsAzKaAy8SksDfZBPIw',
        '{PBKDF2-SHA512}10000$Je1Uw19Bfv5lArzZ6V3EPw$g4T/1sqBUYWl9o93MVnyQ/8zKGSkPbKaXXsT8WmysXQJhWy8MRP2JFudSL.N9RklQYgDPxPjnfum/F2f/TrppA',
        # '{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$IyTQMsvzB2JHDiWx8fq7Ew$VhYOA7AL0kbRXI5g2kOyyp8St1epkNj7WZyUY4pAIQQ',
    ]

    accounts = nsUserAccounts(inst, basedn=DEFAULT_SUFFIX)
    account = accounts.create(
        properties={
            'uid': 'pw_migrate_test_user',
            'cn': 'pw_migrate_test_user',
            'displayName': 'pw_migrate_test_user',
            'uidNumber': '12345',
            'gidNumber': '12345',
            'homeDirectory': '/var/empty',
        })

    for pwhash in pwds:
        inst.log.debug(f"Attempting -> {pwhash}")
        account.set('userPassword', pwhash)
        nconn = account.bind('password')
Exemple #8
0
def syncstate_assert(st, sync):
    # How many entries do we have?
    r = st.search_ext_s(base=DEFAULT_SUFFIX,
                        scope=ldap.SCOPE_SUBTREE,
                        filterstr='(objectClass=*)',
                        attrsonly=1,
                        escapehatch='i am sure')

    # Initial sync
    log.debug("*test* initial")
    sync.syncrepl_search()
    sync.syncrepl_complete()
    # check we caught them all
    assert len(r) == len(sync.entries.keys())
    assert len(r) == len(sync.present)
    assert 0 == len(sync.delete)

    # Add a new entry

    account = nsUserAccounts(st, DEFAULT_SUFFIX).create_test_user()
    # Check
    log.debug("*test* add")
    sync.syncrepl_search()
    sync.syncrepl_complete()
    sync.check_cookie()
    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    assert 0 == len(sync.delete)

    # Mod
    account.replace('description', 'change')
    # Check
    log.debug("*test* mod")
    sync.syncrepl_search()
    sync.syncrepl_complete()
    sync.check_cookie()
    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    assert 0 == len(sync.delete)

    ## Delete
    account.delete()

    # Check
    log.debug("*test* del")
    sync.syncrepl_search()
    sync.syncrepl_complete()
    # In a delete, the cookie isn't updated (?)
    sync.check_cookie()
    log.debug(f'{sync.entries.keys()}')
    log.debug(f'{sync.present}')
    log.debug(f'{sync.delete}')
    assert 0 == len(sync.entries.keys())
    assert 0 == len(sync.present)
    assert 1 == len(sync.delete)
Exemple #9
0
def test_entryuuid_import_and_fixup_of_invalid_values(topology):
    """ Test that when we import a database with an invalid entryuuid
    that it is accepted *and* that subsequently we can fix the invalid
    entryuuid during a fixup.

    :id: ec8ef3a7-3cd2-4cbd-b6f1-2449fa17be75

    :setup: Standalone instance

    :steps:
        1. Import the db from the ldif
        2. Check the entryuuid is invalid
        3. Run the fixup
        4. Check the entryuuid is now valid (regenerated)

    :expectedresults:
        1. Success
        2. The entryuuid is invalid
        3. Success
        4. The entryuuid is valid
    """

    # 1. Import the db
    ldif_dir = topology.standalone.get_ldif_dir()
    target_ldif = os.path.join(ldif_dir, 'localhost-userRoot-invalid.ldif')
    import_ldif = os.path.join(DATADIR1, 'localhost-userRoot-invalid.ldif')
    shutil.copyfile(import_ldif, target_ldif)
    os.chmod(target_ldif, 0o777)

    be = Backends(topology.standalone).get('userRoot')
    task = be.import_ldif([target_ldif])
    task.wait()
    assert (task.is_complete() and task.get_exit_code() == 0)

    # 2. Check the entryuuid is invalid
    account = nsUserAccounts(topology.standalone,
                             DEFAULT_SUFFIX).get("demo_user")
    euuid = account.get_attr_val_utf8('entryUUID')
    assert (euuid == "INVALID_UUID")

    # 3. Run the fixup
    topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,
                                              ErrorLog.PLUGIN))
    plug = EntryUUIDPlugin(topology.standalone)
    task = plug.fixup(DEFAULT_SUFFIX)
    task.wait()
    assert (task.is_complete() and task.get_exit_code() == 0)
    topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT, ))

    # 4. Check the entryuuid is valid
    euuid = account.get_attr_val_utf8('entryUUID')
    print(f"❄️   account entryUUID -> {euuid}")
    assert (euuid != "INVALID_UUID")
    # Raises an error if invalid
    uuid.UUID(euuid)
def test_dsidm_user_get_rdn(topology_st, create_test_user):
    """ Test dsidm user get option

    :id: 8c7247cd-7588-45d3-817c-ac5a9f135b32
    :setup: Standalone instance
    :steps:
         1. Run dsidm get option for created user with json
         2. Check the output content is correct
         3. Run dsidm get option for created user without json
         4. Check the json content is correct
    :expectedresults:
         1. Success
         2. Success
         3. Success
         4. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
    testuser = users.get('test_user_1000')

    user_content = [
        'dn: {}'.format(testuser.dn), 'cn: {}'.format(testuser.rdn),
        'displayName: {}'.format(testuser.rdn), 'gidNumber: 2000',
        'homeDirectory: /home/{}'.format(testuser.rdn), 'objectClass: top',
        'objectClass: nsPerson', 'objectClass: nsAccount',
        'objectClass: nsOrgPerson', 'objectClass: posixAccount',
        'uid: {}'.format(testuser.rdn), 'uidNumber: 1000'
    ]

    json_content = [
        'attrs', 'objectclass', 'top', 'nsPerson', 'nsAccount', 'nsOrgPerson',
        'posixAccount', 'uid', testuser.rdn, 'cn', 'displayname', 'uidnumber',
        'gidnumber', '2000', 'homedirectory', '/home/{}'.format(testuser.rdn),
        'creatorsname', 'cn=directory manager', 'modifiersname',
        'createtimestamp', 'modifytimestamp', 'nsuniqueid', 'parentid',
        'entryid', 'entrydn', testuser.dn
    ]

    args = FakeArgs()
    args.json = False
    args.selector = 'test_user_1000'

    log.info('Empty the log file to prevent false data to check about user')
    topology_st.logcap.flush()

    log.info('Test dsidm user get without json')
    get(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, content_list=user_content)

    log.info('Test dsidm user get with json')
    args.json = True
    get(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, content_list=json_content)
def create_test_user(topology_st, request):
    log.info('Create test user')
    users = nsUserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
    test_user = users.create_test_user()

    def fin():
        log.info('Delete test user')
        if test_user.exists():
            test_user.delete()

    request.addfinalizer(fin)
Exemple #12
0
def test_account_reset_pw(topology):
    users = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX)
    testuser = users.create_test_user(uid=1001)

    # Make sure they are unlocked.
    testuser.unlock()

    testuser.reset_password("test_password")

    # Assert we can bind as the new PW
    c = testuser.bind('test_password')
    c.unbind_s()
def test_dsidm_config_display(topology_st, set_log_file):
    """ Test dsidm display option

    :id: 6e888ae2-8835-44d5-846b-e971d76aa461
    :setup: Standalone instance
    :steps:
         1. Run dsidm client_config display
         2. Enable MemberOfPlugin
         3. Run dsidm client_config display with MemberOfPlugin
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    groups = Groups(standalone, DEFAULT_SUFFIX)

    display_content_list = [
        'ldap_uri = ' + standalone.ldapuri,
        'ldap_uri = ldaps:///dc%3Dexample%2Cdc%3Dcom',
        'group_basedn = ' + groups._basedn, 'basedn = ' + DEFAULT_SUFFIX,
        'user_basedn = ' + users._basedn,
        'user_filter = (&(objectclass=nsPerson)(objectclass=nsAccount)(objectclass=nsOrgPerson)'
        '(objectclass=posixAccount))', 'unique id = nsUniqueId',
        'group member attribute = member', 'user rdn = uid',
        'user identifier = uid',
        'group_filter = (&(objectclass=groupOfNames))', 'group rdn = cn'
    ]

    schema_type = 'rfc2307'
    args = FakeArgs()

    log.info('Test dsidm display option')
    display(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if display option was successful')
    check_value_in_log_and_reset(display_content_list, check_value=schema_type)

    log.info('Enable MemberOf plugin')
    plugin = MemberOfPlugin(standalone)
    plugin.enable()
    standalone.restart()

    log.info('Test dsidm display option with MemberOf plugin')
    display(standalone, DEFAULT_SUFFIX, log, args)

    log.info(
        'Check if display option was successful with MemberOf plugin enabled')
    schema_type = 'rfc2307bis'
    check_value_in_log_and_reset(display_content_list, check_value=schema_type)
Exemple #14
0
def assert_data_present(inst):
    # Do we have the backend marker?
    d = Domain(inst, DEFAULT_SUFFIX)
    try:
        desc = d.get_attr_val_utf8('description')
        if desc == TEST_MARKER:
            return
    except:
        # Just reset everything.
        pass
    # Reset the backends
    bes = Backends(inst)
    try:
        be = bes.get(DEFAULT_SUFFIX)
        be.delete()
    except:
        pass

    be = bes.create(properties={
        'nsslapd-suffix': DEFAULT_SUFFIX,
        'cn': 'userRoot',
    })
    be.create_sample_entries('001004002')

    # Load our data
    # We can't use dbgen as that relies on local access :(

    # Add 40,000 groups
    groups = Groups(inst, DEFAULT_SUFFIX)
    for i in range(1, GROUP_MAX):
        rdn = 'group_{0:07d}'.format(i)
        groups.create(properties={
            'cn': rdn,
        })

    # Add 60,000 users
    users = nsUserAccounts(inst, DEFAULT_SUFFIX)
    for i in range(1, USER_MAX):
        rdn = 'user_{0:07d}'.format(i)
        users.create(
            properties={
                'uid': rdn,
                'cn': rdn,
                'displayName': rdn,
                'uidNumber': '%s' % i,
                'gidNumber': '%s' % i,
                'homeDirectory': '/home/%s' % rdn,
                'userPassword': rdn,
            })

    # Add the marker
    d.replace('description', TEST_MARKER)
def test_dsidm_user_modify(topology_st, create_test_user):
    """ Test dsidm user modify add, replace, delete option

    :id: 7a27be19-1a63-44d0-b11b-f877e06e1a9b
    :setup: Standalone instance
    :steps:
         1. Run dsidm user modify replace cn value
         2. Run dsidm user modify add telephoneNumber attribute to user
         3. Run dsidm user modify delete for telephoneNumber attribute
    :expectedresults:
         1. cn value is replaced with new name
         2. telephoneNumber attribute is present
         3. telephoneNumber attribute is deleted
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')
    output = 'Successfully modified {}'.format(test_user.dn)

    args = FakeArgs()
    args.selector = 'test_user_1000'
    args.changes = ['replace:cn:test']

    log.info('Test dsidm user modify replace')
    modify(standalone,
           DEFAULT_SUFFIX,
           topology_st.logcap.log,
           args,
           warn=False)
    check_value_in_log_and_reset(topology_st, check_value=output)

    log.info('Test dsidm user modify add')
    args.changes = ['add:telephoneNumber:1234567890']
    modify(standalone,
           DEFAULT_SUFFIX,
           topology_st.logcap.log,
           args,
           warn=False)
    check_value_in_log_and_reset(topology_st, check_value=output)
    assert test_user.present('telephoneNumber', '1234567890')

    log.info('Test dsidm user modify delete')
    args.changes = ['delete:telephoneNumber:1234567890']
    modify(standalone,
           DEFAULT_SUFFIX,
           topology_st.logcap.log,
           args,
           warn=False)
    check_value_in_log_and_reset(topology_st, check_value=output)
    assert not test_user.present('telephoneNumber', '1234567890')
Exemple #16
0
def test_account_change_pw(topology):
    # This test requires a secure connection
    topology.standalone.enable_tls()

    users = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX)
    testuser = users.create_test_user(uid=1002)

    # Make sure they are unlocked.
    testuser.unlock()

    testuser.reset_password('password')
    testuser.change_password('password', "test_password")

    # Assert we can bind as the new PW
    c = testuser.bind('test_password')
    c.unbind_s()
Exemple #17
0
def test_entryuuid_fixup_task(topology):
    """Test that when an entries without UUID's can have one generated via
    the fixup process.

    :id: ad42bba2-ffb2-4c22-a37d-cbe7bcf73d6b

    :setup: Standalone instance

    :steps:
        1. Disable the entryuuid plugin
        2. Create an entry
        3. Enable the entryuuid plugin
        4. Run the fixup
        5. Assert the entryuuid now exists

    :expectedresults:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Suddenly EntryUUID!
    """
    # 1. Disable the plugin
    plug = EntryUUIDPlugin(topology.standalone)
    plug.disable()
    topology.standalone.restart()

    # 2. create the account
    account = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX).create_test_user(uid=2000)
    euuid = account.get_attr_val_utf8('entryUUID')
    assert(euuid is None)

    # 3. enable the plugin
    plug.enable()
    topology.standalone.restart()

    # 4. run the fix up
    # For now set the log level to high!
    topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,ErrorLog.TRACE))
    task = plug.fixup(DEFAULT_SUFFIX)
    task.wait()
    assert(task.is_complete() and task.get_exit_code() == 0)
    topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,))

    # 5. Assert the uuid.
    euuid = account.get_attr_val_utf8('entryUUID')
    assert(euuid is not None)
def create_test_user(topology_st, request):
    user_name = 'test_user_1000'
    users = nsUserAccounts(topology_st.standalone, DEFAULT_SUFFIX)

    log.info('Create test user')
    if users.exists(user_name):
        test_user = users.get(user_name)
        test_user.delete()
    else:
        test_user = users.create_test_user()

    def fin():
        log.info('Delete test user')
        if test_user.exists():
            test_user.delete()

    request.addfinalizer(fin)
def test_dsidm_user_rename(topology_st, create_test_user):
    """ Test dsidm user rename option

    :id: fa569966-3954-465f-92b0-331a3a088b1b
    :setup: Standalone instance
    :steps:
         1. Run dsidm user rename option on created user
         2. Check the user does not have another uid attribute with the old rdn
         3. Check the old user is deleted
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')

    args = FakeArgs()
    args.selector = test_user.rdn
    args.new_name = 'my_user'
    args.keep_old_rdn = False

    log.info('Test dsidm user rename')
    args.new_name = 'my_user'
    rename(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    my_user = users.get(args.new_name)
    output = 'Successfully renamed to {}'.format(my_user.dn)
    check_value_in_log_and_reset(topology_st, check_value=output)

    log.info('New user should not have uid attribute with the old rdn')
    assert not my_user.present('uid', 'test_user_1000')
    assert my_user.get_attr_val_utf8('cn') == 'test_user_1000'
    assert my_user.get_attr_val_utf8('displayName') == 'test_user_1000'

    log.info('Old user dn should not exist.')
    assert not test_user.exists()

    log.info('Clean up')
    my_user.delete()
Exemple #20
0
def test_entryuuid_generation_on_add(topology):
    """ Test that when an entry is added, the entryuuid is added.

    :id: a7439b0a-dcee-4cd6-b8ef-771476c0b4f6

    :setup: Standalone instance

    :steps:
        1. Create a new entry in the db
        2. Check it has an entry uuid

    :expectedresults:
        1. Success
        2. An entry uuid is present
    """
    # Step one - create a user!
    account = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX).create_test_user()
    # Step two - does it have an entryuuid?
    euuid = account.get_attr_val_utf8('entryUUID')
    print(euuid)
    assert(euuid is not None)
def test_dsidm_user_rename_keep_old_rdn(topology_st, create_test_user):
    """ Test dsidm user rename option with keep-old-rdn

    :id: 3fd0827c-ab5e-4586-9493-55bc5076a887
    :setup: Standalone instance
    :steps:
         1. Run dsidm user rename option with keep-old-rdn
         2. Check the user does have another uid attribute with the old rdn
         3. Check the old user is deleted
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')

    args = FakeArgs()
    args.selector = test_user.rdn
    args.new_name = 'my_user'
    args.keep_old_rdn = True

    log.info('Test dsidm user rename')
    rename(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    my_user = users.get(args.new_name)
    output = 'Successfully renamed to {}'.format(my_user.dn)
    check_value_in_log_and_reset(topology_st, check_value=output)

    log.info('my_user should have uid attribute with the old rdn')
    assert my_user.present('uid', 'test_user_1000')
    assert my_user.get_attr_val_utf8('cn') == 'test_user_1000'
    assert my_user.get_attr_val_utf8('displayName') == 'test_user_1000'

    log.info('Old user dn should not exist')
    assert not test_user.exists()

    log.info('Clean up')
    my_user.delete()
def test_dsidm_user_create(topology_st):
    """ Test dsidm user create option

    :id: 862f5875-11fd-4e8e-92c1-397010386eb8
    :setup: Standalone instance
    :steps:
         1. Run dsidm user create
         2. Check that a message is provided on creation
         3. Check that created user exists
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    user_name = 'new_user'
    output = 'Successfully created {}'.format(user_name)

    args = FakeArgs()
    args.uid = user_name
    args.cn = user_name
    args.displayName = user_name
    args.uidNumber = '1030'
    args.gidNumber = '2030'
    args.homeDirectory = '/home/{}'.format(user_name)

    log.info('Test dsidm user create')
    create(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, check_value=output)

    log.info('Check that user is present')
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    new_user = users.get(user_name)
    assert new_user.exists()

    log.info('Clean up for next test')
    new_user.delete()
def test_dsidm_user_get_dn(topology_st, create_test_user):
    """ Test dsidm user get_dn option

    :id: 787bf278-87c3-402e-936e-6161799d098d
    :setup: Standalone instance
    :steps:
         1. Run dsidm user get_dn for created user
         2. Check the output content is correct
    :expectedresults:
         1. Success
         2. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')
    args = FakeArgs()
    args.dn = test_user.dn

    log.info('Empty the log file to prevent false data to check about user')
    topology_st.logcap.flush()

    log.info('Test dsidm user get_dn without json')
    get_dn(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
def test_install_aci(topology_st):
    """Assert our default aci's work as expected."""

    # Create some users and groups.
    users = nsUserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
    groups = PosixGroups(topology_st.standalone, DEFAULT_SUFFIX)

    user_basic = users.create(
        properties={
            'uid': 'basic',
            'cn': 'Basic',
            'displayName': 'Basic',
            'uidNumber': '100000',
            'gidNumber': '100000',
            'homeDirectory': '/home/basic',
            'userPassword': '******',
            'legalName': 'Super Secret PII',
        })

    user_modify = users.create(
        properties={
            'uid': 'modify',
            'cn': 'Modify',
            'displayName': 'Modify',
            'uidNumber': '100001',
            'gidNumber': '100001',
            'homeDirectory': '/home/modify',
            'userPassword': '******',
            'legalName': 'Super Secret PII',
        })

    user_admin = users.create(
        properties={
            'uid': 'admin',
            'cn': 'Admin',
            'displayName': 'Admin',
            'uidNumber': '100002',
            'gidNumber': '100002',
            'homeDirectory': '/home/admin',
            'userPassword': '******',
            'legalName': 'Super Secret PII',
        })

    user_pw_reset = users.create(
        properties={
            'uid': 'pw_reset',
            'cn': 'Password Reset',
            'displayName': 'Password Reset',
            'uidNumber': '100003',
            'gidNumber': '100003',
            'homeDirectory': '/home/pw_reset',
            'userPassword': '******',
            'legalName': 'Super Secret PII',
        })

    # Add users to various permissions.

    permissions = Groups(topology_st.standalone,
                         DEFAULT_SUFFIX,
                         rdn='ou=permissions')

    g_group_admin = permissions.get('group_admin')
    g_group_modify = permissions.get('group_modify')
    g_user_admin = permissions.get('user_admin')
    g_user_modify = permissions.get('user_modify')
    g_user_pw_reset = permissions.get('user_passwd_reset')

    g_group_admin.add_member(user_admin.dn)
    g_user_admin.add_member(user_admin.dn)

    g_group_modify.add_member(user_modify.dn)
    g_user_modify.add_member(user_modify.dn)

    g_user_pw_reset.add_member(user_pw_reset.dn)

    # Bind as a user and assert what we can and can not see
    c_user_basic = user_basic.bind(password='******')
    c_user_modify = user_modify.bind(password='******')
    c_user_admin = user_admin.bind(password='******')
    c_user_pw_reset = user_pw_reset.bind(password='******')

    c_user_basic_users = nsUserAccounts(c_user_basic, DEFAULT_SUFFIX)
    c_user_pw_reset_users = nsUserAccounts(c_user_pw_reset, DEFAULT_SUFFIX)
    c_user_modify_users = nsUserAccounts(c_user_modify, DEFAULT_SUFFIX)
    c_user_admin_users = nsUserAccounts(c_user_admin, DEFAULT_SUFFIX)

    # Should be able to see users, but not their legalNames
    user_basic_view_demo_user = c_user_basic_users.get('demo_user')
    assert user_basic_view_demo_user.get_attr_val_utf8('legalName') is None
    assert user_basic_view_demo_user.get_attr_val_utf8('uid') == 'demo_user'

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_basic_view_demo_user.replace('description', 'change value')

    user_pw_reset_view_demo_user = c_user_pw_reset_users.get('demo_user')
    assert user_pw_reset_view_demo_user.get_attr_val_utf8('legalName') is None
    assert user_pw_reset_view_demo_user.get_attr_val_utf8('uid') == 'demo_user'

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_pw_reset_view_demo_user.replace('description', 'change value')

    # The user admin and modify should be able to read it.
    user_modify_view_demo_user = c_user_modify_users.get('demo_user')
    assert user_modify_view_demo_user.get_attr_val_utf8(
        'legalName') == 'Demo User Name'
    assert user_modify_view_demo_user.get_attr_val_utf8('uid') == 'demo_user'
    user_modify_view_demo_user.replace('description', 'change value')

    user_admin_view_demo_user = c_user_admin_users.get('demo_user')
    assert user_admin_view_demo_user.get_attr_val_utf8(
        'legalName') == 'Demo User Name'
    assert user_admin_view_demo_user.get_attr_val_utf8('uid') == 'demo_user'
    user_admin_view_demo_user.replace('description', 'change value')

    # Assert only admin can create:

    test_user_properties = {
        'uid': 'test_user',
        'cn': 'Test User',
        'displayName': 'Test User',
        'uidNumber': '100005',
        'gidNumber': '100005',
        'homeDirectory': '/home/test_user',
        'legalName': 'Super Secret PII',
    }

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_basic_users.create(properties=test_user_properties)
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_pw_reset_users.create(properties=test_user_properties)
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_modify_users.create(properties=test_user_properties)

    test_user = c_user_admin_users.create(properties=test_user_properties)
    test_user.delete()

    # Assert on pw_reset can unlock/pw

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_basic_view_demo_user.lock()
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_modify_view_demo_user.lock()
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_admin_view_demo_user.lock()
    user_pw_reset_view_demo_user.lock()

    # Group test
    c_user_basic_groups = PosixGroups(c_user_basic, DEFAULT_SUFFIX)
    c_user_pw_reset_groups = PosixGroups(c_user_pw_reset, DEFAULT_SUFFIX)
    c_user_modify_groups = PosixGroups(c_user_modify, DEFAULT_SUFFIX)
    c_user_admin_groups = PosixGroups(c_user_admin, DEFAULT_SUFFIX)

    # Assert that members can be read, but only modify/admin can edit.
    user_basic_view_demo_group = c_user_basic_groups.get('demo_group')
    assert user_basic_view_demo_group.get_attr_val_utf8('cn') == 'demo_group'
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_basic_view_demo_group.add_member(user_basic.dn)

    user_pw_reset_view_demo_group = c_user_pw_reset_groups.get('demo_group')
    assert user_pw_reset_view_demo_group.get_attr_val_utf8(
        'cn') == 'demo_group'
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        user_pw_reset_view_demo_group.add_member(user_pw_reset.dn)

    user_modify_view_demo_group = c_user_modify_groups.get('demo_group')
    assert user_modify_view_demo_group.get_attr_val_utf8('cn') == 'demo_group'
    user_modify_view_demo_group.add_member(user_modify.dn)

    user_admin_view_demo_group = c_user_admin_groups.get('demo_group')
    assert user_admin_view_demo_group.get_attr_val_utf8('cn') == 'demo_group'
    user_admin_view_demo_group.add_member(user_admin.dn)

    # Assert that only admin can add new group.
    group_properties = {'cn': 'test_group', 'gidNumber': '100009'}

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_basic_groups.create(properties=group_properties)
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_pw_reset_groups.create(properties=group_properties)
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        c_user_modify_groups.create(properties=group_properties)
    c_user_admin_groups.create(properties=group_properties)
Exemple #25
0
def syncstate_assert(st, sync):
    # How many entries do we have?
    # We setup sync under ou=people so we can modrdn out of the scope.
    r = st.search_ext_s(
        base=OU_PEOPLE,
        scope=ldap.SCOPE_SUBTREE,
        filterstr='(objectClass=*)',
        attrsonly=1,
        escapehatch='i am sure'
    )

    # Initial sync
    log.debug("*test* initial")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    # check we caught them all
    assert len(r) == len(sync.entries.keys())
    assert len(r) == len(sync.present)
    assert 0 == len(sync.delete)
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    # Add a new entry
    account = nsUserAccounts(st, DEFAULT_SUFFIX).create_test_user()

    # Find the primary uuid we expect to see in syncrepl.
    # This will be None if not present.
    acc_uuid = account.get_attr_val_utf8('entryuuid')
    if not sync.openldap:
        nsid = account.get_attr_val_utf8('nsuniqueid')
        # nsunique has a diff format, so we change it up.
        # 431cf081-b44311ea-83fdb082-f24d490e
        # Add a hyphen V
        # 431cf081-b443-11ea-83fdb082-f24d490e
        nsid_a = nsid[:13] + '-' + nsid[13:]
        #           Add a hyphen V
        # 431cf081-b443-11ea-83fd-b082-f24d490e
        nsid_b = nsid_a[:23] + '-' + nsid_a[23:]
        #             Remove a hyphen V
        # 431cf081-b443-11ea-83fd-b082-f24d490e
        acc_uuid = nsid_b[:28] + nsid_b[29:]
        # Tada!
        # 431cf081-b443-11ea-83fd-b082f24d490e
        log.debug(f"--> expected sync uuid (from nsuniqueid): {acc_uuid}")
    else:
        log.debug(f"--> expected sync uuid (from entryuuid): {acc_uuid}")

    # Check
    log.debug("*test* add")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    sync.check_cookie()
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")

    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    ####################################
    assert sync.present == [acc_uuid]
    assert 0 == len(sync.delete)
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    # Mod
    account.replace('description', 'change')
    # Check
    log.debug("*test* mod")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    sync.check_cookie()
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")
    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    ####################################
    assert sync.present == [acc_uuid]
    assert 0 == len(sync.delete)
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    ## ModRdn (remain in scope)
    account.rename('uid=test1_modrdn')
    # newsuperior=None
    # Check
    log.debug("*test* modrdn (in scope)")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    sync.check_cookie()
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")
    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    ####################################
    assert sync.present == [acc_uuid]
    assert 0 == len(sync.delete)
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    # import time
    # print("attach now ....")
    # time.sleep(45)

    ## Modrdn (out of scope, then back into scope)
    account.rename('uid=test1_modrdn', newsuperior=DEFAULT_SUFFIX)

    # Check it's gone.
    log.debug("*test* modrdn (move out of scope)")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    sync.check_cookie()
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")
    assert 0 == len(sync.entries.keys())
    assert 0 == len(sync.present)
    ## WARNING: This test MAY FAIL here if you do not have a new enough python-ldap
    # due to an ASN.1 parsing bug. You require at least python-ldap 3.3.1
    assert 1 == len(sync.delete)
    assert sync.delete == [acc_uuid]
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    # Put it back
    account.rename('uid=test1_modrdn', newsuperior=OU_PEOPLE)
    log.debug("*test* modrdn (move in to scope)")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    sync.check_cookie()
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")
    assert 1 == len(sync.entries.keys())
    assert 1 == len(sync.present)
    ####################################
    assert sync.present == [acc_uuid]
    assert 0 == len(sync.delete)
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel

    ## Delete
    account.delete()

    # Check
    log.debug("*test* del")
    sync.syncrepl_search(base=OU_PEOPLE)
    sync.syncrepl_complete()
    # In a delete, the cookie isn't updated (?)
    sync.check_cookie()
    log.debug(f'{sync.entries.keys()}')
    log.debug(f'{sync.present}')
    log.debug(f'{sync.delete}')
    log.debug(f"sd: {sync.delete}, sp: {sync.present} sek: {sync.entries.keys()}")
    assert 0 == len(sync.entries.keys())
    assert 0 == len(sync.present)
    assert 1 == len(sync.delete)
    assert sync.delete == [acc_uuid]
    ####################################
    if sync.openldap:
        assert True == sync.refdel
    else:
        assert False == sync.refdel
def test_dsidm_account_entry_status_with_lock(topology_st, create_test_user):
    """ Test dsidm account entry-status option with account lock/unlock

    :id: d911bbf2-3a65-42a4-ad76-df1114caa396
    :setup: Standalone instance
    :steps:
         1. Create user account
         2. Run dsidm account entry status
         3. Run dsidm account lock
         4. Run dsidm account entry status
         5. Run dsidm account unlock
         6. Run dsidm account entry status
    :expectedresults:
         1. Success
         2. The state message should be Entry State: activated
         3. Success
         4. The state message should be Entry State: directly locked through nsAccountLock
         5. Success
         6. The state message should be Entry State: activated
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    test_user = users.get('test_user_1000')

    entry_list = [
        'Entry DN: {}'.format(test_user.dn), 'Entry Creation Date',
        'Entry Modification Date'
    ]

    state_lock = 'Entry State: directly locked through nsAccountLock'
    state_unlock = 'Entry State: activated'

    lock_msg = 'Entry {} is locked'.format(test_user.dn)
    unlock_msg = 'Entry {} is unlocked'.format(test_user.dn)

    args = FakeArgs()
    args.dn = test_user.dn
    args.json = False

    log.info('Test dsidm account entry-status')
    entry_status(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st,
                                 content_list=entry_list,
                                 check_value=state_unlock)

    log.info('Test dsidm account lock')
    lock(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, check_value=lock_msg)

    log.info('Test dsidm account entry-status with locked account')
    entry_status(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st,
                                 content_list=entry_list,
                                 check_value=state_lock)

    log.info('Test dsidm account unlock')
    unlock(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st, check_value=unlock_msg)

    log.info('Test dsidm account entry-status with unlocked account')
    entry_status(standalone, DEFAULT_SUFFIX, topology_st.logcap.log, args)
    check_value_in_log_and_reset(topology_st,
                                 content_list=entry_list,
                                 check_value=state_unlock)
Exemple #27
0
def test_ldap_auth_token_nsuser(topology):
    """
    Test that we can generate and authenticate with authentication tokens
    for users in the directory, as well as security properties around these
    tokens.

    :id: 65335341-c85b-457d-ac7d-c4079ac90a60

    :setup: Standalone instance

    :steps:
        1. Create an account
        2. Generate a token for the account
        3. Authenticate with the token
        4. Assert that a token can not be issued from a token-authed account
        5. Regenerate the server key
        6. Assert the token no longer authenticates

    :expectedresults:
        1. Account is created
        2. Token is generated
        3. Token authenticates
        4. Token is NOT issued
        5. The key is regenerated
        6. The token fails to bind.
    """
    topology.standalone.enable_tls()
    topology.standalone.config.set('nsslapd-enable-ldapssotoken',
                                   'on')  # enable it.
    nsusers = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX)
    # Create a user as dm.
    user = nsusers.create(
        properties={
            'uid': 'test_nsuser',
            'cn': 'test_nsuser',
            'displayName': 'testNsuser',
            'legalName': 'testNsuser',
            'uidNumber': '1001',
            'gidNumber': '1001',
            'homeDirectory': '/home/testnsuser',
            'userPassword': USER_PASSWORD,
        })
    # Create a new con and bind as the user.
    user_conn = user.bind(USER_PASSWORD)
    user_account = nsUserAccounts(user_conn, DEFAULT_SUFFIX).get('test_nsuser')
    # From the user_conn do an extop_s for the token
    token = user_account.request_sso_token()
    # Great! Now do a bind where the token is the pw:
    # user_conn_tok = user.bind(token)
    user_conn_tok = user.authenticate_sso_token(token)
    # Assert whoami.
    # Assert that user_conn_tok with the token can NOT get a new token.
    user_tok_account = nsUserAccounts(user_conn_tok,
                                      DEFAULT_SUFFIX).get('test_nsuser')
    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
        user_tok_account.request_sso_token()

    # Check with a lowered ttl (should deny)
    topology.standalone.config.set('nsslapd-ldapssotoken-ttl-secs',
                                   '1')  # Set a low ttl
    # Ensure it's past - the one time I'll allow a sleep ....
    time.sleep(2)
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        user.authenticate_sso_token(token)
    topology.standalone.config.set('nsslapd-ldapssotoken-ttl-secs',
                                   '3600')  # Set a reasonable

    # Regenerate the server token key
    topology.standalone.config.remove_all('nsslapd-ldapssotoken-secret')
    # check we fail to authenticate.
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        user.authenticate_sso_token(token)
    def _apply(self):
        # Create the base domain object
        domain = Domain(self._instance, dn=self._basedn)
        # Explode the dn to get the first bit.
        avas = dn.str2dn(self._basedn)
        dc_ava = avas[0][0][1]

        domain.create(properties={
            # I think in python 2 this forces unicode return ...
            'dc': dc_ava,
            'description': self._basedn,
            'aci': [
                # Allow reading the base domain object
                '(targetattr="dc || description || objectClass")(targetfilter="(objectClass=domain)")(version 3.0; acl "Enable anyone domain read"; allow (read, search, compare)(userdn="ldap:///anyone");)',
                # Allow reading the ou
                '(targetattr="ou || objectClass")(targetfilter="(objectClass=organizationalUnit)")(version 3.0; acl "Enable anyone ou read"; allow (read, search, compare)(userdn="ldap:///anyone");)'
            ]
            })

        # Create the 389 service container
        # This could also move to be part of core later ....
        hidden_containers = nsHiddenContainers(self._instance, self._basedn)
        ns389container = hidden_containers.create(properties={
            'cn': '389_ds_system'
            })

        # Create our ous.
        ous = OrganisationalUnits(self._instance, self._basedn)
        ous.create(properties = {
            'ou': 'groups',
            'aci': [
                # Allow anon partial read
                '(targetattr="cn || member || gidNumber || nsUniqueId || description || objectClass")(targetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enable anyone group read"; allow (read, search, compare)(userdn="ldap:///anyone");)',
                # Allow group_modify to modify but not create groups
                '(targetattr="member")(targetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enable group_modify to alter members"; allow (write)(groupdn="ldap:///cn=group_modify,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
                # Allow group_admin to fully manage groups (posix or not).
                '(targetattr="cn || member || gidNumber || description || objectClass")(targetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enable group_admin to manage groups"; allow (write, add, delete)(groupdn="ldap:///cn=group_admin,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
            ]
        })

        ous.create(properties = {
            'ou': 'people',
            'aci': [
                # allow anon partial read.
                '(targetattr="objectClass || description || nsUniqueId || uid || displayName || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn || memberOf || mail || nsSshPublicKey || nsAccountLock || userCertificate")(targetfilter="(objectClass=posixaccount)")(version 3.0; acl "Enable anyone user read"; allow (read, search, compare)(userdn="ldap:///anyone");)',
                # allow self partial mod
                '(targetattr="displayName || nsSshPublicKey")(version 3.0; acl "Enable self partial modify"; allow (write)(userdn="ldap:///self");)',
                # Allow self full read
                '(targetattr="legalName || telephoneNumber || mobile")(targetfilter="(objectClass=nsPerson)")(version 3.0; acl "Enable self legalname read"; allow (read, search, compare)(userdn="ldap:///self");)',
                # Allow reading legal name
                '(targetattr="legalName || telephoneNumber")(targetfilter="(objectClass=nsPerson)")(version 3.0; acl "Enable user legalname read"; allow (read, search, compare)(groupdn="ldap:///cn=user_private_read,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
                # These below need READ so they can read userPassword and legalName
                # Allow user admin create mod
                '(targetattr="uid || description || displayName || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalName || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objectClass=nsAccount))")(version 3.0; acl "Enable user admin create"; allow (write, add, delete, read)(groupdn="ldap:///cn=user_admin,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
                # Allow user mod mod only
                '(targetattr="uid || description || displayName || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalName || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objectClass=nsAccount))")(version 3.0; acl "Enable user modify to change users"; allow (write, read)(groupdn="ldap:///cn=user_modify,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
                # Allow user_pw_admin to nsaccountlock and password
                '(targetattr="userPassword || nsAccountLock || userCertificate || nsSshPublicKey")(targetfilter="(objectClass=nsAccount)")(version 3.0; acl "Enable user password reset"; allow (write, read)(groupdn="ldap:///cn=user_passwd_reset,ou=permissions,{BASEDN}");)'.format(BASEDN=self._basedn),
            ]
        })

        ous.create(properties = {
            'ou': 'permissions',
        })

        ous.create(properties = {
            'ou': 'services',
            'aci': [
                # Minimal service read
                '(targetattr="objectClass || description || nsUniqueId || cn || memberOf || nsAccountLock ")(targetfilter="(objectClass=netscapeServer)")(version 3.0; acl "Enable anyone service account read"; allow (read, search, compare)(userdn="ldap:///anyone");)',
            ]
        })

        # Create the demo user
        users = nsUserAccounts(self._instance, self._basedn)
        users.create(properties={
            'uid': 'demo_user',
            'cn': 'Demo User',
            'displayName': 'Demo User',
            'legalName': 'Demo User Name',
            'uidNumber': '99998',
            'gidNumber': '99998',
            'homeDirectory': '/var/empty',
            'loginShell': '/bin/false',
            'nsAccountlock': 'true'
        })

        # Create the demo group
        groups = PosixGroups(self._instance, self._basedn)
        groups.create(properties={
            'cn' : 'demo_group',
            'gidNumber': '99999'
        })

        # Create the permission groups required for the acis
        permissions = Groups(self._instance, self._basedn, rdn='ou=permissions')
        permissions.create(properties={
            'cn': 'group_admin',
        })
        permissions.create(properties={
            'cn': 'group_modify',
        })
        permissions.create(properties={
            'cn': 'user_admin',
        })
        permissions.create(properties={
            'cn': 'user_modify',
        })
        permissions.create(properties={
            'cn': 'user_passwd_reset',
        })
        permissions.create(properties={
            'cn': 'user_private_read',
        })
Exemple #29
0
def test_rename_large_subtree(topology_m2):
    """
    A report stated that the following configuration would lead
    to an operation failure:

    ou=int,ou=account,dc=...
    ou=s1,ou=int,ou=account,dc=...
    ou=s2,ou=int,ou=account,dc=...

    rename ou=s1 to re-parent to ou=account, leaving:

    ou=int,ou=account,dc=...
    ou=s1,ou=account,dc=...
    ou=s2,ou=account,dc=...

    The ou=s1 if it has < 100 entries below, is able to be reparented.

    If ou=s1 has > 400 entries, it fails.

    Other conditions was the presence of referential integrity - so one would
    assume that all users under s1 are a member of some group external to this.

    :id: 5915c38d-b3c2-4b7c-af76-8a1e002e27f7

    :setup: standalone instance

    :steps: 1. Enable automember plugin
            2. Add UCOUNT users, and ensure they are members of a group.
            3. Enable refer-int plugin
            4. Move ou=s1 to a new parent

    :expectedresults:
        1. The plugin is enabled
        2. The users are members of the group
        3. The plugin is enabled
        4. The rename operation of ou=s1 succeeds
    """

    st = topology_m2.ms["supplier1"]
    m2 = topology_m2.ms["supplier2"]

    # Create a default group
    gps = Groups(st, DEFAULT_SUFFIX)
    # Keep the group so we can get it's DN out.
    group = gps.create(properties={'cn': 'default_group'})

    _enable_plugins(st, group.dn)
    _enable_plugins(m2, group.dn)

    # Now unlike normal, we bypass the plural-create method, because we need control
    # over the exact DN of the OU to create.
    # Create the ou=account

    # We don't need to set a DN here because ...
    ou_account = OrganisationalUnit(st)

    # It's set in the .create step.
    ou_account.create(basedn=DEFAULT_SUFFIX, properties={'ou': 'account'})
    # create the ou=int,ou=account
    ou_int = OrganisationalUnit(st)
    ou_int.create(basedn=ou_account.dn, properties={'ou': 'int'})
    # Create the ou=s1,ou=int,ou=account
    ou_s1 = OrganisationalUnit(st)
    ou_s1.create(basedn=ou_int.dn, properties={'ou': 's1'})

    # Pause replication
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.disable_to_supplier(m2, [
        st,
    ])

    # Create the users 1 -> UCOUNT in ou=s1
    nsu = nsUserAccounts(st, basedn=ou_s1.dn, rdn=None)
    for i in range(1000, 1000 + UCOUNT):
        nsu.create_test_user(uid=i)

    # Enable replication

    repl.enable_to_supplier(m2, [
        st,
    ])

    # Assert they are in the group as we expect
    members = group.get_attr_vals_utf8('member')
    assert len(members) == UCOUNT

    # Wait for replication
    repl.wait_for_replication(st, m2, timeout=60)

    for i in range(0, 5):
        # Move ou=s1 to ou=account as parent. We have to provide the rdn,
        # even though it's not changing.
        ou_s1.rename('ou=s1', newsuperior=ou_account.dn)

        members = group.get_attr_vals_utf8('member')
        assert len(members) == UCOUNT
        # Check that we really did refer-int properly, and ou=int is not in the members.
        for member in members:
            assert 'ou=int' not in member

        # Now move it back
        ou_s1.rename('ou=s1', newsuperior=ou_int.dn)
        members = group.get_attr_vals_utf8('member')
        assert len(members) == UCOUNT
        for member in members:
            assert 'ou=int' in member

    # Check everythig on the other side is good.
    repl.wait_for_replication(st, m2, timeout=60)

    group2 = Groups(m2, DEFAULT_SUFFIX).get('default_group')

    members = group2.get_attr_vals_utf8('member')
    assert len(members) == UCOUNT
    for member in members:
        assert 'ou=int' in member