예제 #1
0
def test_ticket47676_skip_oc_at(topology):
    '''
        This test ADD an entry on MASTER1 where 47676 is fixed. Then it checks that entry is replicated
        on MASTER2 (even if on MASTER2 47676 is NOT fixed). Then update on MASTER2.
        If the schema has successfully been pushed, updating Master2 should succeed
    '''
    topology.master1.log.info("\n\n######################### ADD ######################\n")

    # bind as 'cn=Directory manager'
    topology.master1.log.info("Bind as %s and add the add the entry with specific oc" % DN_DM)
    topology.master1.simple_bind_s(DN_DM, PASSWORD)

    # Prepare the entry with multivalued members
    entry = Entry(ENTRY_DN)
    entry.setValues('objectclass', 'top', 'person', 'OCticket47676')
    entry.setValues('sn', ENTRY_NAME)
    entry.setValues('cn', ENTRY_NAME)
    entry.setValues('postalAddress', 'here')
    entry.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry.setValues('member', members)

    topology.master1.log.info("Try to add Add  %s should be successful" % ENTRY_DN)
    topology.master1.add_s(entry)

    #
    # Now check the entry as been replicated
    #
    topology.master2.simple_bind_s(DN_DM, PASSWORD)
    topology.master1.log.info("Try to retrieve %s from Master2" % ENTRY_DN)
    loop = 0
    while loop <= 10:
        try:
            ent = topology.master2.getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
            break
        except ldap.NO_SUCH_OBJECT:
            time.sleep(2)
            loop += 1
    assert loop <= 10

    # Now update the entry on Master2 (as DM because 47676 is possibly not fixed on M2)
    topology.master1.log.info("Update  %s on M2" % ENTRY_DN)
    mod = [(ldap.MOD_REPLACE, 'description', 'test_add')]
    topology.master2.modify_s(ENTRY_DN, mod)

    topology.master1.simple_bind_s(DN_DM, PASSWORD)
    loop = 0
    while loop <= 10:
        ent = topology.master1.getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
        if ent.hasAttr('description') and (ent.getValue('description') == 'test_add'):
            break
        time.sleep(1)
        loop += 1

    assert ent.getValue('description') == 'test_add'
예제 #2
0
def add_group(topology):
    """Create a group for the user to have some rights to"""

    log.info("Create a group entry: %s" % TEST_GROUP)
    gentry = Entry(TEST_GROUP)
    gentry.setValues("objectclass", "top", "extensibleobject")
    gentry.setValues("cn", "testgroup")
    topology.instance.add_s(gentry)
예제 #3
0
def user(topology):
    """Create user entries"""

    for i in range(0, 2):
        uentry = Entry('uid=test%s,%s' % (i, DEFAULT_SUFFIX))
        uentry.setValues('objectclass', 'top', 'extensibleobject')
        uentry.setValues('uid', 'test')
        topology.standalone.add_s(uentry)
예제 #4
0
def user(topology):
    """Create user entries"""

    for i in range(0, 2):
        uentry = Entry('uid=test%s,%s' % (i, DEFAULT_SUFFIX))
        uentry.setValues('objectclass', 'top', 'extensibleobject')
        uentry.setValues('uid', 'test')
        topology.standalone.add_s(uentry)
예제 #5
0
def add_group(topology):
    """Create a group for the user to have some rights to"""

    log.info('Create a group entry: %s' % TEST_GROUP)
    gentry = Entry(TEST_GROUP)
    gentry.setValues('objectclass', 'top', 'extensibleobject')
    gentry.setValues('cn', 'testgroup')
    topology.instance.add_s(gentry)
예제 #6
0
def add_user(topology):
    """Create a user entry"""

    log.info('Create a user entry: %s' % TEST_USER)
    uentry = Entry(TEST_USER)
    uentry.setValues('objectclass', 'top', 'extensibleobject')
    uentry.setValues('uid', 'test')
    topology.instance.add_s(uentry)
예제 #7
0
def add_user(topology):
    """Create a user entry"""

    log.info("Create a user entry: %s" % TEST_USER)
    uentry = Entry(TEST_USER)
    uentry.setValues("objectclass", "top", "extensibleobject")
    uentry.setValues("uid", "test")
    topology.instance.add_s(uentry)
예제 #8
0
    def _test_ticket47560_setup():
        """
        - Create entry cn=group,SUFFIX
        - Create entry cn=member,SUFFIX
        - Update 'cn=member,SUFFIX' to add "memberOf: cn=group,SUFFIX"
        - Enable Memberof Plugins
        """
        log.debug("-------- > _test_ticket47560_setup\n")

        #
        # By default the memberof plugin is disabled create
        # - create a group entry
        # - create a member entry
        # - set the member entry as memberof the group entry
        #
        entry = Entry(group_DN)
        entry.setValues('objectclass', 'top', 'groupOfNames', 'inetUser')
        entry.setValues('cn', 'group')
        try:
            topology_st.standalone.add_s(entry)
        except ldap.ALREADY_EXISTS:
            log.debug("Entry %s already exists" % (group_DN))

        entry = Entry(member_DN)
        entry.setValues('objectclass', 'top', 'person', 'organizationalPerson',
                        'inetorgperson', 'inetUser')
        entry.setValues('uid', 'member')
        entry.setValues('cn', 'member')
        entry.setValues('sn', 'member')
        try:
            topology_st.standalone.add_s(entry)
        except ldap.ALREADY_EXISTS:
            log.debug("Entry %s already exists" % (member_DN))

        replace = [(ldap.MOD_REPLACE, 'memberof', ensure_bytes(group_DN))]
        topology_st.standalone.modify_s(member_DN, replace)

        #
        # enable the memberof plugin and restart the instance
        #
        _enable_disable_mbo('on')

        #
        # check memberof attribute is still present
        #
        filt = 'uid=member'
        ents = topology_st.standalone.search_s(member_DN, ldap.SCOPE_BASE,
                                               filt)
        assert len(ents) == 1
        ent = ents[0]
        # print ent
        value = ensure_str(ent.getValue('memberof'))
        # print "memberof: %s" % (value)
        assert value == group_DN
예제 #9
0
def makeADUserEnt(idnum):
    id = str(idnum)
    userid = 'testuser' + id
    cn = 'Test User' + id
    dn = 'cn=%s,%s,%s' % (cn, adusersubtree, suffix)
    ent = Entry(dn)
    ent.setValues('objectclass', aduserObjClasses)
    ent.setValues('cn', cn)
    ent.setValues('sn', 'User' + id)
    ent.setValues('userPrincipalName', '%s@%s' % (userid, realm))
    ent.setValues('sAMAccountName', userid)
    return ent
예제 #10
0
def makeADUserEnt(idnum):
    id = str(idnum)
    userid = 'testuser' + id
    cn = 'Test User' + id
    dn = 'cn=%s,%s,%s' % (cn, adusersubtree, suffix)
    ent = Entry(dn)
    ent.setValues('objectclass', aduserObjClasses)
    ent.setValues('cn', cn)
    ent.setValues('sn', 'User' + id)
    ent.setValues('userPrincipalName', '%s@%s' % (userid, realm))
    ent.setValues('sAMAccountName', userid)
    return ent
예제 #11
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def automemberExport(self, suffix=DEFAULT_SUFFIX, scope='sub',
                         fstr='objectclass=top', ldif_out=None, args=None):
        '''
        @param suffix - The suffix the task should examine - default is
                        "dc=example,dc=com"
        @param scope - The scope of the search to find entries
        @param fstr - The search filter to find entries
        @param ldif_out - The name for the output LDIF file
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of
                                     the task before to return
        @return exit code
        @raise ValueError: if ldif_out is not provided
        '''

        if not ldif_out:
            raise ValueError("Missing ldif_out")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=automember export updates,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        entry.setValues('filter', fstr)
        entry.setValues('scope', scope)
        entry.setValues('ldif', ldif_out)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Automember Export Updates task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Automember Export Updates task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "Automember Export Updates task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #12
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def automemberExport(self, suffix=DEFAULT_SUFFIX, scope='sub',
                         fstr='objectclass=top', ldif_out=None, args=None):
        '''
        @param suffix - The suffix the task should examine - default is
                        "dc=example,dc=com"
        @param scope - The scope of the search to find entries
        @param fstr - The search filter to find entries
        @param ldif_out - The name for the output LDIF file
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of
                                     the task before to return
        @return exit code
        @raise ValueError: if ldif_out is not provided
        '''

        if not ldif_out:
            raise ValueError("Missing ldif_out")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=automember export updates,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        entry.setValues('filter', fstr)
        entry.setValues('scope', scope)
        entry.setValues('ldif', ldif_out)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Automember Export Updates task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Automember Export Updates task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "Automember Export Updates task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #13
0
    def _test_ticket47560_setup():
        """
        - Create entry cn=group,SUFFIX
        - Create entry cn=member,SUFFIX
        - Update 'cn=member,SUFFIX' to add "memberOf: cn=group,SUFFIX"
        - Enable Memberof Plugins
        """
        log.debug("-------- > _test_ticket47560_setup\n")

        #
        # By default the memberof plugin is disabled create
        # - create a group entry
        # - create a member entry
        # - set the member entry as memberof the group entry
        #
        entry = Entry(group_DN)
        entry.setValues('objectclass', 'top', 'groupOfNames', 'inetUser')
        entry.setValues('cn', 'group')
        try:
            topology.standalone.add_s(entry)
        except ldap.ALREADY_EXISTS:
            log.debug("Entry %s already exists" % (group_DN))

        entry = Entry(member_DN)
        entry.setValues('objectclass', 'top', 'person', 'organizationalPerson', 'inetorgperson', 'inetUser')
        entry.setValues('uid', 'member')
        entry.setValues('cn', 'member')
        entry.setValues('sn', 'member')
        try:
            topology.standalone.add_s(entry)
        except ldap.ALREADY_EXISTS:
            log.debug("Entry %s already exists" % (member_DN))

        replace = [(ldap.MOD_REPLACE, 'memberof', group_DN)]
        topology.standalone.modify_s(member_DN, replace)

        #
        # enable the memberof plugin and restart the instance
        #
        _enable_disable_mbo('on')

        #
        # check memberof attribute is still present
        #
        filt = 'uid=member'
        ents = topology.standalone.search_s(member_DN, ldap.SCOPE_BASE, filt)
        assert len(ents) == 1
        ent = ents[0]
        #print ent
        value = ent.getValue('memberof')
        #print "memberof: %s" % (value)
        assert value == group_DN
예제 #14
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def syntaxValidate(self, suffix=DEFAULT_SUFFIX, fstr='objectclass=top', args=None):
        '''
        @param suffix - The suffix the task should validate - default is "dc=example,dc=com"
        @param fstr - The search filter to find entries
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=syntax validate,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        entry.setValues('filter', fstr)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Syntax Validate task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Syntax Validate (%s) exited with %d" % (cn, exitCode))
        else:
            self.log.info("Syntax Validate task (%s) completed successfully" % (cn))
        return exitCode
예제 #15
0
    def addIndex(self,
                 suffix,
                 be_name,
                 attr,
                 indexTypes,
                 matchingRules,
                 postReadCtrl=None):
        """Specify the suffix (should contain 1 local database backend),
            the name of the attribute to index, and the types of indexes
            to create e.g. "pres", "eq", "sub"
        """
        msg_id = None
        if be_name:
            dn = (
                'cn=%s,cn=index,cn=%s,cn=ldbm database,cn=plugins,cn=config' %
                (attr, be_name))
        else:
            entries_backend = self.conn.backend.list(suffix=suffix)
            # assume 1 local backend
            dn = "cn=%s,cn=index,%s" % (attr, entries_backend[0].dn)

        if postReadCtrl:
            add_record = [('nsSystemIndex', ['false']), ('cn', [attr]),
                          ('objectclass', ['top', 'nsindex']),
                          ('nsIndexType', indexTypes)]
            if matchingRules:
                add_record.append(('nsMatchingRule', matchingRules))

        else:
            entry = Entry(dn)
            entry.setValues('objectclass', 'top', 'nsIndex')
            entry.setValues('cn', attr)
            entry.setValues('nsSystemIndex', "false")
            entry.setValues('nsIndexType', indexTypes)
            if matchingRules:
                entry.setValues('nsMatchingRule', matchingRules)

        if MAJOR >= 3 or (MAJOR == 2 and MINOR >= 7):
            try:
                if postReadCtrl:
                    pr = PostReadControl(criticality=True, attrList=['*'])
                    msg_id = self.conn.add_ext(dn,
                                               add_record,
                                               serverctrls=[pr])
                else:
                    self.conn.add_s(entry)
            except ldap.LDAPError as e:
                raise e

        return msg_id
예제 #16
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def usnTombstoneCleanup(self, suffix=DEFAULT_SUFFIX, bename=None,
                            maxusn_to_delete=None, args=None):
        '''
        @param suffix - The suffix the task should cleanup - default is
                        "dc=example,dc=com"
        @param backend - The 'backend' the task should cleanup
        @param maxusn_to_delete - Maximum number of usn's to delete
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of
                                     the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=USN tombstone cleanup task,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if not bename:
            entry.setValues('suffix', suffix)
        else:
            entry.setValues('backend', bename)
        if maxusn_to_delete:
            entry.setValues('maxusn_to_delete')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add USN tombstone cleanup task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: USN tombstone cleanup task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "USN tombstone cleanup task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #17
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def usnTombstoneCleanup(self, suffix=DEFAULT_SUFFIX, bename=None,
                            maxusn_to_delete=None, args=None):
        '''
        @param suffix - The suffix the task should cleanup - default is
                        "dc=example,dc=com"
        @param backend - The 'backend' the task should cleanup
        @param maxusn_to_delete - Maximum number of usn's to delete
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of
                                     the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=USN tombstone cleanup task,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if not bename:
            entry.setValues('suffix', suffix)
        else:
            entry.setValues('backend', bename)
        if maxusn_to_delete:
            entry.setValues('maxusn_to_delete')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add USN tombstone cleanup task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: USN tombstone cleanup task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "USN tombstone cleanup task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #18
0
def add_user(topology):
    """
    Create a user entry
    """

    log.info('Create a user entry: %s' % TEST_USER)
    uentry = Entry(TEST_USER)
    uentry.setValues('objectclass', 'top', 'extensibleobject')
    uentry.setValues('uid', 'test')
    topology.instance.add_s(uentry)
    # This doesn't matter that we re-open the realm
    krb = MitKrb5(realm=REALM)
    krb.create_principal("test")
    # We extract the kt so we can kinit from it
    krb.create_keytab("test", "/tmp/test.keytab")
예제 #19
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def fixupTombstones(self, bename=None, args=None):
        '''
            Trigger a tombstone fixup task on the specified backend

            @param bename - 'commonname'/'cn' of the backend (e.g. 'userRoot').
                            Optional.
            @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return

            @return exit code

            @raise ValueError: if bename name does not exist
        '''

        if not bename:
            bename = DEFAULT_BENAME

        # Verify the backend name
        if bename:
            ents = self.conn.mappingtree.list(bename=bename)
            if len(ents) != 1:
                raise ValueError("invalid backend name: %s" % bename)

        cn = "fixupTombstone_" + time.strftime("%m%d%Y_%H%M%S",
                                               time.localtime())
        dn = "cn=%s,%s" % (cn, DN_TOMB_FIXUP_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('backend', bename)
        if args and args.get(TASK_TOMB_STRIP, False):
            entry.setValues('stripcsn', 'yes')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the fixup tombstone task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: tombstone fixup task %s for backend %s exited with %d"
                % (cn, bename, exitCode))
        else:
            self.log.info(
                "tombstone fixup task %s for backend %s completed successfully"
                % (cn, bename))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #20
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def cleanAllRUV(self, suffix=None, replicaid=None, force=None, args=None):
        '''
        @param replicaid - The replica ID to remove/clean
        @param force - True/False - Clean all the replicas, even if one is down
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return tuple (task dn, and the exit code)
        @raise ValueError: If missing replicaid
        '''

        if not replicaid:
            raise ValueError("Missing required paramter: replicaid")

        if not suffix:
            raise ValueError("Missing required paramter: suffix")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=cleanallruv,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('replica-base-dn', suffix)
        entry.setValues('replica-id', replicaid)
        if force:
            entry.setValues('replica-force-cleaning', 'yes')
        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add cleanAllRUV task")
            return (dn, -1)

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: cleanAllRUV task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("cleanAllRUV task (%s) completed successfully" %
                          (cn))

        self.dn = dn
        self.entry = entry

        return (dn, exitCode)
예제 #21
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def upgradeDB(self, nsArchiveDir=None, nsDatabaseType=None,
                  nsForceToReindex=None, args=None):
        '''
        @param nsArchiveDir - The archive directory
        @param nsDatabaseType - The database type - default is "ldbm database"
        @param nsForceToReindex - True/False - force reindexing to occur
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return exit code
        @raise ValueError: If missing nsArchiveDir
        '''

        if not nsArchiveDir:
            raise ValueError("Missing required paramter: nsArchiveDir")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=upgradedb,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('nsArchiveDir', nsArchiveDir)
        if nsDatabaseType:
            entry.setValues('nsDatabaseType', nsDatabaseType)
        if nsForceToReindex:
            entry.setValues('nsForceToReindex', 'True')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add upgradedb task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: upgradedb task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("Upgradedb task (%s) completed successfully" % (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #22
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def upgradeDB(self, nsArchiveDir=None, nsDatabaseType=None,
                  nsForceToReindex=None, args=None):
        '''
        @param nsArchiveDir - The archive directory
        @param nsDatabaseType - The database type - default is "ldbm database"
        @param nsForceToReindex - True/False - force reindexing to occur
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return exit code
        @raise ValueError: If missing nsArchiveDir
        '''

        if not nsArchiveDir:
            raise ValueError("Missing required paramter: nsArchiveDir")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=upgradedb,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('nsArchiveDir', nsArchiveDir)
        if nsDatabaseType:
            entry.setValues('nsDatabaseType', nsDatabaseType)
        if nsForceToReindex:
            entry.setValues('nsForceToReindex', 'True')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add upgradedb task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: upgradedb task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("Upgradedb task (%s) completed successfully" % (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #23
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def fixupTombstones(self, bename=None, args=None):
        '''
            Trigger a tombstone fixup task on the specified backend

            @param bename - 'commonname'/'cn' of the backend (e.g. 'userRoot').
                            Optional.
            @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return

            @return exit code

            @raise ValueError: if bename name does not exist
        '''

        if not bename:
            bename = DEFAULT_BENAME

        # Verify the backend name
        if bename:
            ents = self.conn.mappingtree.list(bename=bename)
            if len(ents) != 1:
                raise ValueError("invalid backend name: %s" % bename)

        cn = "fixupTombstone_" + time.strftime("%m%d%Y_%H%M%S",
                                               time.localtime())
        dn = "cn=%s,%s" % (cn, DN_TOMB_FIXUP_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('backend', bename)
        if args and args.get(TASK_TOMB_STRIP, False):
            entry.setValues('stripcsn', 'yes')

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the fixup tombstone task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: tombstone fixup task %s for backend %s exited with %d"
                % (cn, bename, exitCode))
        else:
            self.log.info(
                "tombstone fixup task %s for backend %s completed successfully"
                % (cn, bename))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #24
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def cleanAllRUV(self, suffix=None, replicaid=None, force=None, args=None):
        '''
        @param replicaid - The replica ID to remove/clean
        @param force - True/False - Clean all the replicas, even if one is down
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return tuple (task dn, and the exit code)
        @raise ValueError: If missing replicaid
        '''

        if not replicaid:
            raise ValueError("Missing required paramter: replicaid")

        if not suffix:
            raise ValueError("Missing required paramter: suffix")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=cleanallruv,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('replica-base-dn', suffix)
        entry.setValues('replica-id', replicaid)
        if force:
            entry.setValues('replica-force-cleaning', 'yes')
        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add cleanAllRUV task")
            return (dn, -1)

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: cleanAllRUV task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("cleanAllRUV task (%s) completed successfully" %
                          (cn))

        self.dn = dn
        self.entry = entry

        return (dn, exitCode)
예제 #25
0
def test_ticket47676_skip_oc_at(topology_m2):
    '''
        This test ADD an entry on SUPPLIER1 where 47676 is fixed. Then it checks that entry is replicated
        on SUPPLIER2 (even if on SUPPLIER2 47676 is NOT fixed). Then update on SUPPLIER2.
        If the schema has successfully been pushed, updating Supplier2 should succeed
    '''
    topology_m2.ms["supplier1"].log.info("\n\n######################### ADD ######################\n")

    # bind as 'cn=Directory manager'
    topology_m2.ms["supplier1"].log.info("Bind as %s and add the add the entry with specific oc" % DN_DM)
    topology_m2.ms["supplier1"].simple_bind_s(DN_DM, PASSWORD)

    # Prepare the entry with multivalued members
    entry = Entry(ENTRY_DN)
    entry.setValues('objectclass', 'top', 'person', 'OCticket47676')
    entry.setValues('sn', ENTRY_NAME)
    entry.setValues('cn', ENTRY_NAME)
    entry.setValues('postalAddress', 'here')
    entry.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry.setValues('member', members)

    topology_m2.ms["supplier1"].log.info("Try to add Add  %s should be successful" % ENTRY_DN)
    topology_m2.ms["supplier1"].add_s(entry)

    #
    # Now check the entry as been replicated
    #
    topology_m2.ms["supplier2"].simple_bind_s(DN_DM, PASSWORD)
    topology_m2.ms["supplier1"].log.info("Try to retrieve %s from Supplier2" % ENTRY_DN)
    replication_check(topology_m2)
    ent = topology_m2.ms["supplier2"].getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
    assert ent
    # Now update the entry on Supplier2 (as DM because 47676 is possibly not fixed on M2)
    topology_m2.ms["supplier1"].log.info("Update  %s on M2" % ENTRY_DN)
    mod = [(ldap.MOD_REPLACE, 'description', b'test_add')]
    topology_m2.ms["supplier2"].modify_s(ENTRY_DN, mod)

    topology_m2.ms["supplier1"].simple_bind_s(DN_DM, PASSWORD)
    replication_check(topology_m2)
    ent = topology_m2.ms["supplier1"].getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
    assert ensure_str(ent.getValue('description')) == 'test_add'
예제 #26
0
파일: tasks.py 프로젝트: pombreda/lib389
    def automemberRebuild(self,
                          suffix=DEFAULT_SUFFIX,
                          scope='sub',
                          filterstr='objectclass=top',
                          args=None):
        '''
        @param suffix - The suffix the task should examine - defualt is "dc=example,dc=com"
        @param scope - The scope of the search to find entries
        @param fitlerstr - THe search filter to find entries
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=automember rebuild membership,cn=tasks,cn=config' % cn)

        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        entry.setValues('filter', filterstr)
        entry.setValues('scope', scope)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Automember Rebuild Membership task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Automember Rebuild Membership task (%s) exited with %d"
                % (cn, exitCode))
        else:
            self.log.info(
                "Automember Rebuild Membership task (%s) completed successfully"
                % (cn))
        return exitCode
예제 #27
0
파일: index.py 프로젝트: Firstyear/lib389
    def addIndex(self, suffix, be_name, attr, indexTypes, matchingRules,
                 postReadCtrl=None):
        """Specify the suffix (should contain 1 local database backend),
            the name of the attribute to index, and the types of indexes
            to create e.g. "pres", "eq", "sub"
        """
        msg_id = None
        if be_name:
            dn = ('cn=%s,cn=index,cn=%s,cn=ldbm database,cn=plugins,cn=config'
                  % (attr, be_name))
        else:
            entries_backend = self.conn.backend.list(suffix=suffix)
            # assume 1 local backend
            dn = "cn=%s,cn=index,%s" % (attr, entries_backend[0].dn)

        if postReadCtrl:
            add_record = [('nsSystemIndex', ['false']),
                          ('cn', [attr]),
                          ('objectclass', ['top', 'nsindex']),
                          ('nsIndexType', indexTypes)]
            if matchingRules:
                add_record.append(('nsMatchingRule', matchingRules))

        else:
            entry = Entry(dn)
            entry.setValues('objectclass', 'top', 'nsIndex')
            entry.setValues('cn', attr)
            entry.setValues('nsSystemIndex', "false")
            entry.setValues('nsIndexType', indexTypes)
            if matchingRules:
                entry.setValues('nsMatchingRule', matchingRules)

        if MAJOR >= 3 or (MAJOR == 2 and MINOR >= 7):
            try:
                if postReadCtrl:
                    pr = PostReadControl(criticality=True, attrList=['*'])
                    msg_id = self.conn.add_ext(dn, add_record, serverctrls=[pr])
                else:
                    self.conn.add_s(entry)
            except ldap.LDAPError as e:
                raise e

        return msg_id
예제 #28
0
파일: index.py 프로젝트: ioggstream/lib389
 def addIndex(self, suffix, attr, indexTypes, matchingRules):
     """Specify the suffix (should contain 1 local database backend),
         the name of the attribute to index, and the types of indexes
         to create e.g. "pres", "eq", "sub"
     """
     entries_backend = self.conn.backend.list(suffix=suffix)
     # assume 1 local backend
     dn = "cn=%s,cn=index,%s" % (attr, entries_backend[0].dn)
     entry = Entry(dn)
     entry.setValues('objectclass', 'top', 'nsIndex')
     entry.setValues('cn', attr)
     entry.setValues('nsSystemIndex', "false")
     entry.setValues('nsIndexType', indexTypes)
     if matchingRules:
         entry.setValues('nsMatchingRule', matchingRules)
     try:
         self.conn.add_s(entry)
     except ldap.ALREADY_EXISTS:
         print "Index for attr %s for backend %s already exists" % (
             attr, dn)
예제 #29
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def schemaReload(self, schemadir=None, args=None):
        '''
        @param schemadir - The directory to look for schema files(optional)
        @param args - Is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=schema reload task,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if schemadir:
            entry.setValues('schemadir', schemadir)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Schema Reload task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Schema Reload task (%s) exited with %d" % (cn, exitCode))
        else:
            self.log.info("Schema Reload task (%s) completed successfully" % (cn))
        return exitCode
예제 #30
0
파일: tasks.py 프로젝트: pombreda/lib389
    def schemaReload(self, schemadir=None, args=None):
        '''
        @param schemadir - The directory to look for schema files(optional)
        @param args - Is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=schema reload task,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if schemadir:
            entry.setValues('schemadir', schemadir)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Schema Reload task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Schema Reload task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("Schema Reload task (%s) completed successfully" %
                          (cn))
        return exitCode
예제 #31
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def fixupLinkedAttrs(self, linkdn=None, args=None):
        '''
        @param linkdn - The DN of linked attr config entry (if None all possible configurations are checked)
        @param args - Is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=fixup linked attributes,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if linkdn:
            entry.setValues('linkdn', linkdn)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Fixup Linked Attributes task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Fixup Linked Attributes task (%s) exited with %d" % (cn, exitCode))
        else:
            self.log.info("Fixup Linked Attributes task (%s) completed successfully" % (cn))
        return exitCode
예제 #32
0
def group(topology):
    """Create a group entry"""

    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
    gentry.setValues('objectclass', 'top', 'extensibleobject')
    gentry.setValues('cn', 'testgroup')
    for i in range(0, 2):
        gentry.setValues('uniqueMember', 'uid=test%s,%s' % (i, DEFAULT_SUFFIX))
    topology.standalone.add_s(gentry)
예제 #33
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def automemberMap(self, ldif_in=None, ldif_out=None, args=None):
        '''
        @param ldif_in - Entries to pass into the task for processing
        @param ldif_out - The resulting LDIF of changes from ldif_in
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion
                                     of the task before to return
        @return exit code
        @raise ValueError: if ldif_out/ldif_in is not provided
        '''

        if not ldif_out or not ldif_in:
            raise ValueError("Missing ldif_out and/or ldif_in")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=automember map updates,cn=tasks,cn=config' % cn)

        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('ldif_in', ldif_in)
        entry.setValues('ldif_out', ldif_out)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Automember Map Updates task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Automember Map Updates task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "Automember Map Updates task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #34
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def automemberMap(self, ldif_in=None, ldif_out=None, args=None):
        '''
        @param ldif_in - Entries to pass into the task for processing
        @param ldif_out - The resulting LDIF of changes from ldif_in
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion
                                     of the task before to return
        @return exit code
        @raise ValueError: if ldif_out/ldif_in is not provided
        '''

        if not ldif_out or not ldif_in:
            raise ValueError("Missing ldif_out and/or ldif_in")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=automember map updates,cn=tasks,cn=config' % cn)

        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('ldif_in', ldif_in)
        entry.setValues('ldif_out', ldif_out)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Automember Map Updates task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Automember Map Updates task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "Automember Map Updates task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #35
0
def group(topology):
    """Create a group entry"""

    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
    gentry.setValues('objectclass', 'top', 'extensibleobject')
    gentry.setValues('cn', 'testgroup')
    for i in range(0, 2):
        gentry.setValues('uniqueMember', 'uid=test%s,%s' % (i, DEFAULT_SUFFIX))
    topology.standalone.add_s(gentry)
예제 #36
0
파일: tasks.py 프로젝트: Firstyear/lib389
    def sysconfigReload(self, configfile=None, logchanges=None, args=None):
        '''
        @param configfile - The sysconfig file:
                            /etc/sysconfig/dirsrv-localhost
        @param logchanges - True/False - Tell the server to log the changes
                                         made by the task
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return exit code
        @raise ValueError: If sysconfig file not provided
        '''

        if not configfile:
            raise ValueError("Missing required paramter: configfile")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=cn=sysconfig reload,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('sysconfigfile', configfile)
        if logchanges:
            entry.setValues('logchanges', logchanges)
        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Sysconfig Reload task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Sysconfig Reload task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("Sysconfig Reload task (%s) completed successfully" %
                          (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #37
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def sysconfigReload(self, configfile=None, logchanges=None, args=None):
        '''
        @param configfile - The sysconfig file:
                            /etc/sysconfig/dirsrv-localhost
        @param logchanges - True/False - Tell the server to log the changes
                                         made by the task
        @param args - is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion of the
                                     task before to return
        @return exit code
        @raise ValueError: If sysconfig file not provided
        '''

        if not configfile:
            raise ValueError("Missing required paramter: configfile")

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=cn=sysconfig reload,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('sysconfigfile', configfile)
        if logchanges:
            entry.setValues('logchanges', logchanges)
        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Sysconfig Reload task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: Sysconfig Reload task (%s) exited with %d" %
                           (cn, exitCode))
        else:
            self.log.info("Sysconfig Reload task (%s) completed successfully" %
                          (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #38
0
파일: tasks.py 프로젝트: nextoa/389-ds-base
    def fixupLinkedAttrs(self, linkdn=None, args=None):
        '''
        @param linkdn - The DN of linked attr config entry (if None all
                         possible configurations are checked)
        @param args - Is a dictionary that contains modifier of the task
                wait: True/[False] - If True,  waits for the completion
                                     of the task before to return
        @return exit code
        '''

        cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = ('cn=%s,cn=fixup linked attributes,cn=tasks,cn=config' % cn)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        if linkdn:
            entry.setValues('linkdn', linkdn)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add Fixup Linked Attributes task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: Fixup Linked Attributes task (%s) exited with %d" %
                (cn, exitCode))
        else:
            self.log.info(
                "Fixup Linked Attributes task (%s) completed successfully" %
                (cn))

        self.dn = dn
        self.entry = entry

        return exitCode
예제 #39
0
def complex_aci(topology):
    ACI_TARGET = ('(targetfilter ="(ou=groups)")(targetattr ="uniqueMember '
                  '|| member")')
    ACI_ALLOW = ('(version 3.0; acl "Allow test aci";allow (read, search, '
                 'write)')
    ACI_SUBJECT = ('(userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" '
                   'and userdn="ldap:///dc=example,dc=com??sub?(manager=uid='
                   'wbrown,ou=managers,dc=example,dc=com) || ldap:///dc=examp'
                   'le,dc=com??sub?(manager=uid=tbrown,ou=managers,dc=exampl'
                   'e,dc=com)" );)')
    ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT

    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
    gentry.setValues('objectclass', 'top', 'extensibleobject')
    gentry.setValues('cn', 'testgroup')
    gentry.setValues('aci', ACI_BODY)

    topology.standalone.add_s(gentry)

    return ensure_str(ACI_BODY)
예제 #40
0
    def create(self, suffix=None, bename=None, parent=None):
        '''
            Create a mapping tree entry (under "cn=mapping tree,cn=config"), for the 'suffix' 
            and that is stored in 'bename' backend. 
            'bename' backend must exists before creating the mapping tree entry. 
            
            If a 'parent' is provided that means that we are creating a sub-suffix mapping tree.

            @param suffix - suffix mapped by this mapping tree entry. It will be the common name ('cn') of the entry
            @param benamebase - backend common name (e.g. 'userRoot')
            @param parent - if provided is a parent suffix of 'suffix'
            
            @return DN of the mapping tree entry
            
            @raise ldap.NO_SUCH_OBJECT - if the backend entry or parent mapping tree does not exist

        '''
        # Check suffix is provided
        if not suffix:
            raise ValueError("suffix is mandatory")
        else:
            nsuffix = normalizeDN(suffix)
        
        # Check backend name is provided
        if not bename:
            raise ValueError("backend name is mandatory")
        
        # Check that if the parent suffix is provided then
        # it exists a mapping tree for it
        if parent:
            nparent = normalizeDN(parent)
            filt = suffixfilt(parent)
            try:
                entry = self.conn.getEntry(DN_MAPPING_TREE, ldap.SCOPE_SUBTREE, filt)
                pass
            except NoSuchEntryError:
                raise ValueError("parent suffix has no mapping tree")
        else:
            nparent = ""
            
        # Check if suffix exists, return
        filt = suffixfilt(suffix)
        try:
            entry = self.conn.getEntry(DN_MAPPING_TREE, ldap.SCOPE_SUBTREE, filt)
            return entry
        except NoSuchEntryError:
            entry = None

        # 
        # Now start the real work
        #
        
        # fix me when we can actually used escaped DNs
        dn = ','.join(('cn="%s"' % nsuffix, DN_MAPPING_TREE))
        entry = Entry(dn)
        entry.update({
            'objectclass': ['top', 'extensibleObject', MT_OBJECTCLASS_VALUE],
            'nsslapd-state': 'backend',
            # the value in the dn has to be DN escaped
            # internal code will add the quoted value - unquoted value is useful for searching
            MT_PROPNAME_TO_ATTRNAME[MT_SUFFIX]: nsuffix,
            MT_PROPNAME_TO_ATTRNAME[MT_BACKEND]: bename
        })
        
        # possibly add the parent
        if parent:
            entry.setValues(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX], nparent)
            
        try:
            self.log.debug("Creating entry: %s" % entry.dn)
            self.log.info("Entry %r" % entry)
            self.conn.add_s(entry)
        except ldap.LDAPError, e:
            raise ldap.LDAPError("Error adding suffix entry " + dn, e)
예제 #41
0
    def test_update_complex(self):
        # compare two entries created with different methods
        nsuffix, replid, replicatype = ("dc=example,dc=com", 5,
                                        lib389.REPLICA_RDWR_TYPE)
        binddnlist, legacy = ['uid=pippo, cn=config'], 'off'
        dn = "dc=example,dc=com"
        entry = Entry(dn)
        entry.setValues('objectclass', "top", "nsds5replica",
                        "extensibleobject")
        entry.setValues('cn', "replica")
        entry.setValues('nsds5replicaroot', nsuffix)
        entry.setValues('nsds5replicaid', str(replid))
        entry.setValues('nsds5replicatype', str(replicatype))
        entry.setValues('nsds5flags', "1")
        entry.setValues('nsds5replicabinddn', binddnlist)
        entry.setValues('nsds5replicalegacyconsumer', legacy)

        uentry = Entry((dn, {
            'objectclass': ["top", "nsds5replica", "extensibleobject"],
            'cn': ["replica"]
        }))
        log.debug("Entry created with dict:", uentry)
        # Entry.update *replaces*, so be careful with multi-valued attrs
        uentry.update({
            'nsds5replicaroot': nsuffix,
            'nsds5replicaid': str(replid),
            'nsds5replicatype': str(replicatype),
            'nsds5flags': '1',
            'nsds5replicabinddn': binddnlist,
            'nsds5replicalegacyconsumer': legacy
        })
        uentry_s, entry_s = list(map(str, (uentry, entry)))
        assert uentry_s == entry_s, "Mismatching entries [%r] vs [%r]" % (
            uentry, entry)
예제 #42
0
def test_ticket47653_add(topology_m2):
    '''
        This test ADD an entry on MASTER1 where 47653 is fixed. Then it checks that entry is replicated
        on MASTER2 (even if on MASTER2 47653 is NOT fixed). Then update on MASTER2 and check the update on MASTER1

        It checks that, bound as bind_entry,
            - we can not ADD an entry without the proper SELFDN aci.
            - with the proper ACI we can not ADD with 'member' attribute
            - with the proper ACI and 'member' it succeeds to ADD
    '''
    topology_m2.ms["master1"].log.info("\n\n######################### ADD ######################\n")

    # bind as bind_entry
    topology_m2.ms["master1"].log.info("Bind as %s" % BIND_DN)
    topology_m2.ms["master1"].simple_bind_s(BIND_DN, BIND_PW)

    # Prepare the entry with multivalued members
    entry_with_members = Entry(ENTRY_DN)
    entry_with_members.setValues('objectclass', 'top', 'person', 'OCticket47653')
    entry_with_members.setValues('sn', ENTRY_NAME)
    entry_with_members.setValues('cn', ENTRY_NAME)
    entry_with_members.setValues('postalAddress', 'here')
    entry_with_members.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry_with_members.setValues('member', members)

    # Prepare the entry with only one member value
    entry_with_member = Entry(ENTRY_DN)
    entry_with_member.setValues('objectclass', 'top', 'person', 'OCticket47653')
    entry_with_member.setValues('sn', ENTRY_NAME)
    entry_with_member.setValues('cn', ENTRY_NAME)
    entry_with_member.setValues('postalAddress', 'here')
    entry_with_member.setValues('postalCode', '1234')
    member = []
    member.append(BIND_DN)
    entry_with_member.setValues('member', member)

    # entry to add WITH member being BIND_DN but WITHOUT the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_m2.ms["master1"].log.info("Try to add Add  %s (aci is missing): %r" % (ENTRY_DN, entry_with_member))

        topology_m2.ms["master1"].add_s(entry_with_member)
    except Exception as e:
        topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # Ok Now add the proper ACI
    topology_m2.ms["master1"].log.info("Bind as %s and add the ADD SELFDN aci" % DN_DM)
    topology_m2.ms["master1"].simple_bind_s(DN_DM, PASSWORD)

    ACI_TARGET = "(target = \"ldap:///cn=*,%s\")" % SUFFIX
    ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME
    ACI_ALLOW = "(version 3.0; acl \"SelfDN add\"; allow (add)"
    ACI_SUBJECT = " userattr = \"member#selfDN\";)"
    ACI_BODY = ACI_TARGET + ACI_TARGETFILTER + ACI_ALLOW + ACI_SUBJECT
    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
    topology_m2.ms["master1"].modify_s(SUFFIX, mod)
    time.sleep(1)

    # bind as bind_entry
    topology_m2.ms["master1"].log.info("Bind as %s" % BIND_DN)
    topology_m2.ms["master1"].simple_bind_s(BIND_DN, BIND_PW)

    # entry to add WITHOUT member and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_m2.ms["master1"].log.info("Try to add Add  %s (member is missing)" % ENTRY_DN)
        topology_m2.ms["master1"].add_s(Entry((ENTRY_DN, {
            'objectclass': ENTRY_OC.split(),
            'sn': ENTRY_NAME,
            'cn': ENTRY_NAME,
            'postalAddress': 'here',
            'postalCode': '1234'})))
    except Exception as e:
        topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
    time.sleep(1)

    # entry to add WITH memberS and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    # member should contain only one value
    try:
        topology_m2.ms["master1"].log.info("Try to add Add  %s (with several member values)" % ENTRY_DN)
        topology_m2.ms["master1"].add_s(entry_with_members)
    except Exception as e:
        topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
    time.sleep(2)

    topology_m2.ms["master1"].log.info("Try to add Add  %s should be successful" % ENTRY_DN)
    try:
        topology_m2.ms["master1"].add_s(entry_with_member)
    except ldap.LDAPError as e:
        topology_m2.ms["master1"].log.info("Failed to add entry,  error: " + e.message['desc'])
        assert False

    #
    # Now check the entry as been replicated
    #
    topology_m2.ms["master2"].simple_bind_s(DN_DM, PASSWORD)
    topology_m2.ms["master1"].log.info("Try to retrieve %s from Master2" % ENTRY_DN)
    loop = 0
    while loop <= 10:
        try:
            ent = topology_m2.ms["master2"].getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
            break
        except ldap.NO_SUCH_OBJECT:
            time.sleep(1)
            loop += 1
    assert loop <= 10

    # Now update the entry on Master2 (as DM because 47653 is possibly not fixed on M2)
    topology_m2.ms["master1"].log.info("Update  %s on M2" % ENTRY_DN)
    mod = [(ldap.MOD_REPLACE, 'description', 'test_add')]
    topology_m2.ms["master2"].modify_s(ENTRY_DN, mod)
    time.sleep(1)

    topology_m2.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
    loop = 0
    while loop <= 10:
        try:
            ent = topology_m2.ms["master1"].getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
            if ent.hasAttr('description') and (ent.getValue('description') == 'test_add'):
                break
        except ldap.NO_SUCH_OBJECT:
            time.sleep(1)
            loop += 1

    assert ent.getValue('description') == 'test_add'
예제 #43
0
    'normal, regular AD account disabled, do not expire password',
    'userAccountControl': 512 + 2 + 65536
}]

userids_disabled = {}
if useds:
    print "Create sub-ou's on the AD side and add users . . ."
    ii = 0
    dns = [
        'ou=people,' + suffix, 'ou=1,ou=people,' + suffix,
        'ou=2,ou=people,' + suffix, 'ou=11,ou=1,ou=people,' + suffix,
        'ou=12,ou=1,ou=people,' + suffix
    ]
    for dn in dns:
        ent = Entry(dn)
        ent.setValues('objectclass', 'organizationalUnit')
        try:
            ad.add_s(ent)
        except ldap.ALREADY_EXISTS:
            pass
        print "Add users to", dn
        for jj in range(0, 5):
            strii = str(ii)
            userdn = 'cn=Test User' + strii + ',' + dn
            ent = Entry(userdn)
            userid = 'userid' + strii
            ent.setValues('objectclass', ['person', 'adPerson'])
            ent.setValues('sn', 'User' + strii)
            ent.setValues('samAccountName', userid)
            ent.setValues('objectGUID', struct.pack('B', ii))
            ent.setValues('name', 'Test User' + strii)  # same as cn
예제 #44
0
파일: tasks.py 프로젝트: pombreda/lib389
    def importLDIF(self,
                   suffix=None,
                   benamebase=None,
                   input_file=None,
                   args=None):
        '''
        Import from a LDIF format a given 'suffix' (or 'benamebase' that stores that suffix).
        It uses an internal task to acheive this request.

        If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
        If both 'suffix' and 'benamebase' are missing it raise ValueError

        'input_file' is the ldif input file

        @param suffix - suffix of the backend
        @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
        @param ldif_input - file that will contain the entries in LDIF format, to import
        @param args - is a dictionary that contains modifier of the import task
                wait: True/[False] - If True, 'export' waits for the completion of the task before to return

        @return None

        @raise ValueError

        '''
        # Checking the parameters
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        if not input_file:
            raise ValueError("input_file is mandatory")

        if not os.path.exists(input_file):
            raise ValueError("Import file (%s) does not exist" % input_file)

        # Prepare the task entry
        cn = "import_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = "cn=%s,%s" % (cn, DN_IMPORT_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('nsFilename', input_file)
        if benamebase:
            entry.setValues('nsInstance', benamebase)
        else:
            entry.setValues('nsIncludeSuffix', suffix)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the import task of %s" % input_file)
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: import task %s for file %s exited with %d" %
                           (cn, input_file, exitCode))
        else:
            self.log.info("Import task %s for file %s completed successfully" %
                          (cn, input_file))
        return exitCode
예제 #45
0
#del os.environ['USE_DBX']
m2.replicaSetupAll(m2replargs)

print "create agreements and init consumers"
agmtm1tom2 = m1.agreement.create(basedn, m2.host, m2.port, agmtargs)
m1.replica.start_and_wait(agmtm1tom2)
agmtm2tom1 = m2.agreement.create(basedn, m1.host, m1.port, agmtargs)

nents = 5
m1ents = range(nents)
m2ents = range(len(m1ents), len(m1ents)+nents+1)
print "Add %d entries to m2" % len(m2ents)
for ii in m2ents:
    dn = "cn=%d, %s" % (ii, basedn)
    ent = Entry(dn)
    ent.setValues('objectclass', 'person')
    ent.setValues('sn', 'testuser')
    m2.add_s(ent)
    print "Added m2 entry", dn

print "Add %d entries to m1" % len(m1ents)
for ii in m1ents:
    dn = "cn=%d, %s" % (ii, basedn)
    ent = Entry(dn)
    ent.setValues('objectclass', 'person')
    ent.setValues('sn', 'testuser')
    m1.add_s(ent)
    print "Added m1 entry", dn

print "Sleep for 5 seconds to let changes propagate . . ."
time.sleep(5)
예제 #46
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def importLDIF(self, suffix=None, benamebase=None, input_file=None, args=None):
        '''
        Import from a LDIF format a given 'suffix' (or 'benamebase' that stores that suffix).
        It uses an internal task to acheive this request.

        If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
        If both 'suffix' and 'benamebase' are missing it raise ValueError

        'input_file' is the ldif input file

        @param suffix - suffix of the backend
        @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
        @param ldif_input - file that will contain the entries in LDIF format, to import
        @param args - is a dictionary that contains modifier of the import task
                wait: True/[False] - If True, 'export' waits for the completion of the task before to return

        @return None

        @raise ValueError

        '''
        # Checking the parameters
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        if not input_file:
            raise ValueError("input_file is mandatory")

        if not os.path.exists(input_file):
            raise ValueError("Import file (%s) does not exist" % input_file)

        # Prepare the task entry
        cn = "import_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = "cn=%s,%s" % (cn, DN_IMPORT_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('nsFilename', input_file)
        if benamebase:
            entry.setValues('nsInstance', benamebase)
        else:
            entry.setValues('nsIncludeSuffix', suffix)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the import task of %s" % input_file)
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: import task %s for file %s exited with %d" % (
                    cn, input_file, exitCode))
        else:
            self.log.info("Import task %s for file %s completed successfully" % (
                    cn, input_file))
        return exitCode
예제 #47
0
def test_ticket47808_run(topology):
    """
        It enables attribute uniqueness plugin with sn as a unique attribute
        Add an entry 1 with sn = ENTRY_NAME
        Add an entry 2 with sn = ENTRY_NAME
        If the second add does not crash the server and the following search found none,
        the bug is fixed.
    """

    # bind as directory manager
    topology.standalone.log.info("Bind as %s" % DN_DM)
    topology.standalone.simple_bind_s(DN_DM, PASSWORD)

    topology.standalone.log.info("\n\n######################### SETUP ATTR UNIQ PLUGIN ######################\n")

    # enable attribute uniqueness plugin
    mod = [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', 'on'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'sn'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg1', SUFFIX)]
    topology.standalone.modify_s(ATTRIBUTE_UNIQUENESS_PLUGIN, mod)

    topology.standalone.log.info("\n\n######################### ADD USER 1 ######################\n")

    # Prepare entry 1
    entry_name = '%s 1' % (ENTRY_NAME)
    entry_dn_1 = 'cn=%s, %s' % (entry_name, SUFFIX)
    entry_1 = Entry(entry_dn_1)
    entry_1.setValues('objectclass', 'top', 'person')
    entry_1.setValues('sn', ENTRY_NAME)
    entry_1.setValues('cn', entry_name)
    topology.standalone.log.info("Try to add Add %s: %r" % (entry_1, entry_1))
    topology.standalone.add_s(entry_1)

    topology.standalone.log.info("\n\n######################### Restart Server ######################\n")
    topology.standalone.stop(timeout=10)
    topology.standalone.start(timeout=10)

    topology.standalone.log.info("\n\n######################### ADD USER 2 ######################\n")

    # Prepare entry 2 having the same sn, which crashes the server
    entry_name = '%s 2' % (ENTRY_NAME)
    entry_dn_2 = 'cn=%s, %s' % (entry_name, SUFFIX)
    entry_2 = Entry(entry_dn_2)
    entry_2.setValues('objectclass', 'top', 'person')
    entry_2.setValues('sn', ENTRY_NAME)
    entry_2.setValues('cn', entry_name)
    topology.standalone.log.info("Try to add Add %s: %r" % (entry_2, entry_2))
    try:
        topology.standalone.add_s(entry_2)
    except:
        topology.standalone.log.warn("Adding %s failed" % entry_dn_2)
        pass

    topology.standalone.log.info("\n\n######################### IS SERVER UP? ######################\n")
    ents = topology.standalone.search_s(entry_dn_1, ldap.SCOPE_BASE, '(objectclass=*)')
    assert len(ents) == 1
    topology.standalone.log.info("Yes, it's up.")

    topology.standalone.log.info("\n\n######################### CHECK USER 2 NOT ADDED ######################\n")
    topology.standalone.log.info("Try to search %s" % entry_dn_2)
    try:
        ents = topology.standalone.search_s(entry_dn_2, ldap.SCOPE_BASE, '(objectclass=*)')
    except ldap.NO_SUCH_OBJECT:
        topology.standalone.log.info("Found none")

    topology.standalone.log.info("\n\n######################### DELETE USER 1 ######################\n")

    topology.standalone.log.info("Try to delete  %s " % entry_dn_1)
    topology.standalone.delete_s(entry_dn_1)
    log.info('Testcase PASSED')
예제 #48
0
    def create(self, suffix=None, bename=None, parent=None):
        '''
            Create a mapping tree entry (under "cn=mapping tree,cn=config"),
            for the 'suffix' and that is stored in 'bename' backend.
            'bename' backend must exist before creating the mapping tree entry.

            If a 'parent' is provided that means that we are creating a
            sub-suffix mapping tree.

            @param suffix - suffix mapped by this mapping tree entry. It will
                            be the common name ('cn') of the entry
            @param benamebase - backend common name (e.g. 'userRoot')
            @param parent - if provided is a parent suffix of 'suffix'

            @return DN of the mapping tree entry

            @raise ldap.NO_SUCH_OBJECT - if the backend entry or parent mapping
                                         tree does not exist
                   ValueError - if missing a parameter,

        '''
        # Check suffix is provided
        if not suffix:
            raise ValueError("suffix is mandatory")
        else:
            nsuffix = normalizeDN(suffix)

        # Check backend name is provided
        if not bename:
            raise ValueError("backend name is mandatory")

        # Check that if the parent suffix is provided then
        # it exists a mapping tree for it
        if parent:
            nparent = normalizeDN(parent)
            filt = suffixfilt(parent)
            try:
                entry = self.conn.getEntry(DN_MAPPING_TREE, ldap.SCOPE_SUBTREE,
                                           filt)
                pass
            except NoSuchEntryError:
                raise ValueError("parent suffix has no mapping tree")
        else:
            nparent = ""

        # Check if suffix exists, return
        filt = suffixfilt(suffix)
        try:
            entry = self.conn.getEntry(DN_MAPPING_TREE, ldap.SCOPE_SUBTREE,
                                       filt)
            return entry
        except ldap.NO_SUCH_OBJECT:
            entry = None

        #
        # Now start the real work
        #

        # fix me when we can actually used escaped DNs
        dn = ','.join(('cn="%s"' % nsuffix, DN_MAPPING_TREE))
        entry = Entry(dn)
        entry.update({
            'objectclass': ['top', 'extensibleObject', MT_OBJECTCLASS_VALUE],
            'nsslapd-state':
            'backend',
            # the value in the dn has to be DN escaped
            # internal code will add the quoted value - unquoted value is
            # useful for searching.
            MT_PROPNAME_TO_ATTRNAME[MT_SUFFIX]:
            nsuffix,
            MT_PROPNAME_TO_ATTRNAME[MT_BACKEND]:
            bename
        })

        # possibly add the parent
        if parent:
            entry.setValues(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX], nparent)

        try:
            self.log.debug("Creating entry: %s", entry.dn)
            self.log.info("Entry %r", entry)
            self.conn.add_s(entry)
        except ldap.LDAPError as e:
            raise ldap.LDAPError("Error adding suffix entry " + dn, e)

        ret = self.conn._test_entry(dn, ldap.SCOPE_BASE)
        return ret
예제 #49
0
def test_ticket47653_add(topology_st):
    '''
        It checks that, bound as bind_entry,
            - we can not ADD an entry without the proper SELFDN aci.
            - with the proper ACI we can not ADD with 'member' attribute
            - with the proper ACI and 'member' it succeeds to ADD
    '''
    topology_st.standalone.log.info(
        "\n\n######################### ADD ######################\n")

    # bind as bind_entry
    topology_st.standalone.log.info("Bind as %s" % BIND_DN)
    topology_st.standalone.simple_bind_s(BIND_DN, BIND_PW)

    # Prepare the entry with multivalued members
    entry_with_members = Entry(ENTRY_DN)
    entry_with_members.setValues('objectclass', 'top', 'person',
                                 'OCticket47653')
    entry_with_members.setValues('sn', ENTRY_NAME)
    entry_with_members.setValues('cn', ENTRY_NAME)
    entry_with_members.setValues('postalAddress', 'here')
    entry_with_members.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry_with_members.setValues('member', members)

    # Prepare the entry with one member
    entry_with_member = Entry(ENTRY_DN)
    entry_with_member.setValues('objectclass', 'top', 'person',
                                'OCticket47653')
    entry_with_member.setValues('sn', ENTRY_NAME)
    entry_with_member.setValues('cn', ENTRY_NAME)
    entry_with_member.setValues('postalAddress', 'here')
    entry_with_member.setValues('postalCode', '1234')
    member = []
    member.append(BIND_DN)
    entry_with_member.setValues('member', member)

    # entry to add WITH member being BIND_DN but WITHOUT the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (aci is missing): %r" %
            (ENTRY_DN, entry_with_member))

        topology_st.standalone.add_s(entry_with_member)
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # Ok Now add the proper ACI
    topology_st.standalone.log.info("Bind as %s and add the ADD SELFDN aci" %
                                    DN_DM)
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)

    ACI_TARGET = "(target = \"ldap:///cn=*,%s\")" % SUFFIX
    ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME
    ACI_ALLOW = "(version 3.0; acl \"SelfDN add\"; allow (add)"
    ACI_SUBJECT = " userattr = \"member#selfDN\";)"
    ACI_BODY = ACI_TARGET + ACI_TARGETFILTER + ACI_ALLOW + ACI_SUBJECT
    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
    topology_st.standalone.modify_s(SUFFIX, mod)

    # bind as bind_entry
    topology_st.standalone.log.info("Bind as %s" % BIND_DN)
    topology_st.standalone.simple_bind_s(BIND_DN, BIND_PW)

    # entry to add WITHOUT member and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (member is missing)" % ENTRY_DN)
        topology_st.standalone.add_s(
            Entry((ENTRY_DN, {
                'objectclass': ENTRY_OC.split(),
                'sn': ENTRY_NAME,
                'cn': ENTRY_NAME,
                'postalAddress': 'here',
                'postalCode': '1234'
            })))
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # entry to add WITH memberS and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    # member should contain only one value
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (with several member values)" % ENTRY_DN)
        topology_st.standalone.add_s(entry_with_members)
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    topology_st.standalone.log.info("Try to add Add  %s should be successful" %
                                    ENTRY_DN)
    topology_st.standalone.add_s(entry_with_member)
예제 #50
0
def test_ticket47313_run(topology):
    """
        It adds 2 test entries
        Search with filters including subtype and !
            It deletes the added entries
    """

    # bind as directory manager
    topology.standalone.log.info("Bind as %s" % DN_DM)
    topology.standalone.simple_bind_s(DN_DM, PASSWORD)

    # enable filter error logging
    #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '32')]
    #topology.standalone.modify_s(DN_CONFIG, mod)

    topology.standalone.log.info("\n\n######################### ADD ######################\n")

    # Prepare the entry with cn;fr & cn;en
    entry_name_fr = '%s fr' % (ENTRY_NAME)
    entry_name_en = '%s en' % (ENTRY_NAME)
    entry_name_both = '%s both' % (ENTRY_NAME)
    entry_dn_both = 'cn=%s, %s' % (entry_name_both, SUFFIX)
    entry_both = Entry(entry_dn_both)
    entry_both.setValues('objectclass', 'top', 'person')
    entry_both.setValues('sn', entry_name_both)
    entry_both.setValues('cn', entry_name_both)
    entry_both.setValues('cn;fr', entry_name_fr)
    entry_both.setValues('cn;en', entry_name_en)

    # Prepare the entry with one member
    entry_name_en_only = '%s en only' % (ENTRY_NAME)
    entry_dn_en_only = 'cn=%s, %s' % (entry_name_en_only, SUFFIX)
    entry_en_only = Entry(entry_dn_en_only)
    entry_en_only.setValues('objectclass', 'top', 'person')
    entry_en_only.setValues('sn', entry_name_en_only)
    entry_en_only.setValues('cn', entry_name_en_only)
    entry_en_only.setValues('cn;en', entry_name_en)

    topology.standalone.log.info("Try to add Add %s: %r" % (entry_dn_both, entry_both))
    topology.standalone.add_s(entry_both)

    topology.standalone.log.info("Try to add Add %s: %r" % (entry_dn_en_only, entry_en_only))
    topology.standalone.add_s(entry_en_only)

    topology.standalone.log.info("\n\n######################### SEARCH ######################\n")

    # filter: (&(cn=test_entry en only)(!(cn=test_entry fr)))
    myfilter = '(&(sn=%s)(!(cn=%s)))' % (entry_name_en_only, entry_name_fr)
    topology.standalone.log.info("Try to search with filter %s" % myfilter)
    ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter)
    assert len(ents) == 1
    assert ents[0].sn == entry_name_en_only
    topology.standalone.log.info("Found %s" % ents[0].dn)

    # filter: (&(cn=test_entry en only)(!(cn;fr=test_entry fr)))
    myfilter = '(&(sn=%s)(!(cn;fr=%s)))' % (entry_name_en_only, entry_name_fr)
    topology.standalone.log.info("Try to search with filter %s" % myfilter)
    ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter)
    assert len(ents) == 1
    assert ents[0].sn == entry_name_en_only
    topology.standalone.log.info("Found %s" % ents[0].dn)

    # filter: (&(cn=test_entry en only)(!(cn;en=test_entry en)))
    myfilter = '(&(sn=%s)(!(cn;en=%s)))' % (entry_name_en_only, entry_name_en)
    topology.standalone.log.info("Try to search with filter %s" % myfilter)
    ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, myfilter)
    assert len(ents) == 0
    topology.standalone.log.info("Found none")

    topology.standalone.log.info("\n\n######################### DELETE ######################\n")

    topology.standalone.log.info("Try to delete  %s " % entry_dn_both)
    topology.standalone.delete_s(entry_dn_both)

    topology.standalone.log.info("Try to delete  %s " % entry_dn_en_only)
    topology.standalone.delete_s(entry_dn_en_only)

    log.info('Testcase PASSED')
예제 #51
0
def test_ticket47653_add(topology):
    '''
        This test ADD an entry on MASTER1 where 47653 is fixed. Then it checks that entry is replicated
        on MASTER2 (even if on MASTER2 47653 is NOT fixed). Then update on MASTER2 and check the update on MASTER1

        It checks that, bound as bind_entry,
            - we can not ADD an entry without the proper SELFDN aci.
            - with the proper ACI we can not ADD with 'member' attribute
            - with the proper ACI and 'member' it succeeds to ADD
    '''
    topology.master1.log.info("\n\n######################### ADD ######################\n")

    # bind as bind_entry
    topology.master1.log.info("Bind as %s" % BIND_DN)
    topology.master1.simple_bind_s(BIND_DN, BIND_PW)

    # Prepare the entry with multivalued members
    entry_with_members = Entry(ENTRY_DN)
    entry_with_members.setValues('objectclass', 'top', 'person', 'OCticket47653')
    entry_with_members.setValues('sn', ENTRY_NAME)
    entry_with_members.setValues('cn', ENTRY_NAME)
    entry_with_members.setValues('postalAddress', 'here')
    entry_with_members.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry_with_members.setValues('member', members)

    # Prepare the entry with only one member value
    entry_with_member = Entry(ENTRY_DN)
    entry_with_member.setValues('objectclass', 'top', 'person', 'OCticket47653')
    entry_with_member.setValues('sn', ENTRY_NAME)
    entry_with_member.setValues('cn', ENTRY_NAME)
    entry_with_member.setValues('postalAddress', 'here')
    entry_with_member.setValues('postalCode', '1234')
    member = []
    member.append(BIND_DN)
    entry_with_member.setValues('member', member)

    # entry to add WITH member being BIND_DN but WITHOUT the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology.master1.log.info("Try to add Add  %s (aci is missing): %r" % (ENTRY_DN, entry_with_member))

        topology.master1.add_s(entry_with_member)
    except Exception as e:
        topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # Ok Now add the proper ACI
    topology.master1.log.info("Bind as %s and add the ADD SELFDN aci" % DN_DM)
    topology.master1.simple_bind_s(DN_DM, PASSWORD)

    ACI_TARGET       = "(target = \"ldap:///cn=*,%s\")" % SUFFIX
    ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME
    ACI_ALLOW        = "(version 3.0; acl \"SelfDN add\"; allow (add)"
    ACI_SUBJECT      = " userattr = \"member#selfDN\";)"
    ACI_BODY         = ACI_TARGET + ACI_TARGETFILTER + ACI_ALLOW + ACI_SUBJECT
    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
    topology.master1.modify_s(SUFFIX, mod)
    time.sleep(1)

    # bind as bind_entry
    topology.master1.log.info("Bind as %s" % BIND_DN)
    topology.master1.simple_bind_s(BIND_DN, BIND_PW)

    # entry to add WITHOUT member and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology.master1.log.info("Try to add Add  %s (member is missing)" % ENTRY_DN)
        topology.master1.add_s(Entry((ENTRY_DN, {
                                            'objectclass':      ENTRY_OC.split(),
                                            'sn':               ENTRY_NAME,
                                            'cn':               ENTRY_NAME,
                                            'postalAddress':    'here',
                                            'postalCode':       '1234'})))
    except Exception as e:
        topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # entry to add WITH memberS and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    # member should contain only one value
    try:
        topology.master1.log.info("Try to add Add  %s (with several member values)" % ENTRY_DN)
        topology.master1.add_s(entry_with_members)
    except Exception as e:
        topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    topology.master1.log.info("Try to add Add  %s should be successful" % ENTRY_DN)
    try:
        topology.master1.add_s(entry_with_member)
    except ldap.LDAPError as e:
        topology.master1.log.info("Failed to add entry,  error: " + e.message['desc'])
        assert False

    #
    # Now check the entry as been replicated
    #
    topology.master2.simple_bind_s(DN_DM, PASSWORD)
    topology.master1.log.info("Try to retrieve %s from Master2" % ENTRY_DN)
    loop = 0
    while loop <= 10:
        try:
            ent = topology.master2.getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
            break
        except ldap.NO_SUCH_OBJECT:
            time.sleep(1)
            loop += 1
    assert loop <= 10

    # Now update the entry on Master2 (as DM because 47653 is possibly not fixed on M2)
    topology.master1.log.info("Update  %s on M2" % ENTRY_DN)
    mod = [(ldap.MOD_REPLACE, 'description', 'test_add')]
    topology.master2.modify_s(ENTRY_DN, mod)

    topology.master1.simple_bind_s(DN_DM, PASSWORD)
    loop = 0
    while loop <= 10:
        try:
            ent = topology.master1.getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)")
            if ent.hasAttr('description') and (ent.getValue('description') == 'test_add'):
                break
        except ldap.NO_SUCH_OBJECT:
            time.sleep(1)
            loop += 1

    assert ent.getValue('description') == 'test_add'
예제 #52
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def exportLDIF(self, suffix=None, benamebase=None, output_file=None, args=None):
        '''
        Export in a LDIF format a given 'suffix' (or 'benamebase' that stores that suffix).
        It uses an internal task to acheive this request.

        If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
        If both 'suffix' and 'benamebase' are missing it raises ValueError

        'output_file' is the output file of the export

        @param suffix - suffix of the backend
        @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
        @param output_file - file that will contain the exported suffix in LDIF format
        @param args - is a dictionary that contains modifier of the export task
                wait: True/[False] - If True, 'export' waits for the completion of the task before to return
                repl-info: True/[False] - If True, it adds the replication meta data (state information,
                                          tombstones and RUV) in the exported file

        @return None

        @raise ValueError

        '''

        # Checking the parameters
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        if not output_file:
            raise ValueError("output_file is mandatory")

        # Prepare the task entry
        cn = "export_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = "cn=%s,%s" % (cn, DN_EXPORT_TASK)
        entry = Entry(dn)
        entry.update({
            'objectclass': ['top', 'extensibleObject'],
            'cn': cn,
            'nsFilename': output_file
        })
        if benamebase:
            entry.setValues('nsInstance', benamebase)
        else:
            entry.setValues('nsIncludeSuffix', suffix)

        if args.get(EXPORT_REPL_INFO, False):
            entry.setValues('nsExportReplica', 'true')

        # start the task and possibly wait for task completion
        self.conn.add_s(entry)
        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: export task %s for file %s exited with %d" % (
                    cn, output_file, exitCode))
        else:
            self.log.info("Export task %s for file %s completed successfully" % (
                    cn, output_file))
        return exitCode
예제 #53
0
def test_pwdAdmin_init(topology):
    '''
    Create our future Password Admin entry, set the password policy, and test
    that its working
    '''

    log.info('test_pwdAdmin_init: Creating Password Administator entries...')

    # Add Password Admin 1
    try:
        topology.standalone.add_s(Entry((ADMIN_DN, {'objectclass': "top extensibleObject".split(),
                                 'cn': ADMIN_NAME,
                                 'userpassword': ADMIN_PWD})))
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init: Failed to add test user' + ADMIN_DN + ': error ' + e.message['desc'])
        assert False

    # Add Password Admin 2
    try:
        topology.standalone.add_s(Entry((ADMIN2_DN, {'objectclass': "top extensibleObject".split(),
                                      'cn': ADMIN2_NAME,
                                      'userpassword': ADMIN_PWD})))
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init: Failed to add test user ' + ADMIN2_DN + ': error ' + e.message['desc'])
        assert False

    # Add Password Admin Group
    try:
        topology.standalone.add_s(Entry((ADMIN_GROUP_DN, {'objectclass': "top groupOfUNiqueNames".split(),
                                      'cn': 'password admin group',
                                      'uniquemember': ADMIN_DN,
                                      'uniquemember': ADMIN2_DN})))
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init:  Failed to add group' + ADMIN_GROUP_DN + ': error ' + e.message['desc'])
        assert False

    # Configure password policy
    log.info('test_pwdAdmin_init: Configuring password policy...')
    try:
        topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on'),
                                                 (ldap.MOD_REPLACE, 'passwordCheckSyntax', 'on'),
                                                 (ldap.MOD_REPLACE, 'passwordMinCategories', '1'),
                                                 (ldap.MOD_REPLACE, 'passwordMinTokenLength', '1'),
                                                 (ldap.MOD_REPLACE, 'passwordExp', 'on'),
                                                 (ldap.MOD_REPLACE, 'passwordMinDigits', '1'),
                                                 (ldap.MOD_REPLACE, 'passwordMinSpecials', '1')])
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init: Failed configure password policy: ' +
                  e.message['desc'])
        assert False

    #
    # Add an aci to allow everyone all access (just makes things easier)
    #
    log.info('Add aci to allow password admin to add/update entries...')

    ACI_TARGET       = "(target = \"ldap:///%s\")" % SUFFIX
    ACI_TARGETATTR   = "(targetattr = *)"
    ACI_ALLOW        = "(version 3.0; acl \"Password Admin Access\"; allow (all) "
    ACI_SUBJECT      = "(userdn = \"ldap:///anyone\");)"
    ACI_BODY         = ACI_TARGET + ACI_TARGETATTR + ACI_ALLOW + ACI_SUBJECT
    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
    try:
        topology.standalone.modify_s(SUFFIX, mod)
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init: Failed to add aci for password admin: ' +
                  e.message['desc'])
        assert False

    #
    # Bind as the future Password Admin
    #
    log.info('test_pwdAdmin_init: Bind as the Password Administator (before activating)...')
    try:
        topology.standalone.simple_bind_s(ADMIN_DN, ADMIN_PWD)
    except ldap.LDAPError as e:
        log.fatal('test_pwdAdmin_init: Failed to bind as the Password Admin: ' +
                                      e.message['desc'])
        assert False

    #
    # Setup our test entry, and test password policy is working
    #
    entry = Entry(ENTRY_DN)
    entry.setValues('objectclass', 'top', 'person')
    entry.setValues('sn', ENTRY_NAME)
    entry.setValues('cn', ENTRY_NAME)

    #
    # Start by attempting to add an entry with an invalid password
    #
    log.info('test_pwdAdmin_init: Attempt to add entries with invalid passwords, these adds should fail...')
    for passwd in INVALID_PWDS:
        failed_as_expected = False
        entry.setValues('userpassword', passwd)
        log.info('test_pwdAdmin_init: Create a regular user entry %s with password (%s)...' %
                 (ENTRY_DN, passwd))
        try:
            topology.standalone.add_s(entry)
        except ldap.LDAPError as e:
            # We failed as expected
            failed_as_expected = True
            log.info('test_pwdAdmin_init: Add failed as expected: password (%s) result (%s)'
                    % (passwd, e.message['desc']))

        if not failed_as_expected:
            log.fatal('test_pwdAdmin_init: We were incorrectly able to add an entry ' +
                      'with an invalid password (%s)' % (passwd))
            assert False
예제 #54
0
파일: tasks.py 프로젝트: ioggstream/lib389
    def fixupMemberOf(self, suffix=None, benamebase=None, filt=None, args=None):
        '''
            Trigger a fixup task on 'suffix' (or 'benamebase' that stores that suffix) related to the
            entries 'memberof' of groups. It uses an internal task to acheive this request.

            If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
            If both 'suffix' and 'benamebase' are missing it raise ValueError

            'filt' is a filter that will select all the entries (under 'suffix') that we need to evaluate/fix.
            If missing, the default value is "(|(objectclass=inetuser)(objectclass=inetadmin))"

            @param suffix - suffix of the backend
            @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
            @param args - is a dictionary that contains modifier of the fixupMemberOf task
                wait: True/[False] - If True,  waits for the completion of the task before to return

            @return exit code

            @raise ValueError: if benamebase and suffix are specified, or can not retrieve the suffix from the
                            mapping tree entry
        '''
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        # If backend name was provided, retrieve the suffix
        if benamebase:
            ents = self.conn.mappingtree.list(bename=benamebase)
            if len(ents) != 1:
                raise ValueError("invalid backend name: %s" % benamebase)

            attr = MT_PROPNAME_TO_ATTRNAME[MT_SUFFIX]
            if not ents[0].hasAttr(attr):
                raise ValueError("invalid backend name: %s, or entry without %s" % (benamebase, attr))

            suffix = ents[0].getValue(attr)

        cn = "fixupmemberof_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = "cn=%s,%s" % (cn, DN_MBO_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        if filt:
            entry.setValues('filter', filt)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the memberOf fixup task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: fixupMemberOf task %s for basedn %s exited with %d" % (cn, suffix, exitCode))
        else:
            self.log.info("fixupMemberOf task %s for basedn %s completed successfully" % (cn, suffix))
        return exitCode
예제 #55
0
def makeDSUserEnt(idnum):
    id = str(idnum)
    userid = 'testuser' + id
    dn = 'uid=%s,%s,%s' % (userid, usersubtree, suffix)
    ent = Entry(dn)
    ent.setValues('objectclass', userObjClasses)
    ent.setValues('cn', 'Test User' + id)
    ent.setValues('sn', 'User' + id)
    ent.setValues('uid', userid)
    ent.setValues('userPassword', 'Password' + id)
    ent.setValues('ntUserDomainId', userid)
    ent.setValues('userPassword', 'Ornette1')
    if ipawinsync:
        ent.setValues('krbPrincipalName', '%s@%s' % (userid, realm))
        ent.setValues('uidNumber', str(500 + idnum))
        ent.setValues('gidNumber', '1002')
        ent.setValues('homeDirectory', '/home/' + userid)
        if idnum % 2:
            ent.setValues('description', 'User added disabled to DS')
            ent.setValues('nsAccountLock', 'TRUE')
        else:
            ent.setValues('description', 'User added enabled to DS')
    else:
        ent.setValues('description', 'User added to DS')
        ent.setValues('ntUserCreateNewAccount', 'TRUE')
        ent.setValues('ntUserDeleteAccount', 'TRUE')
    return ent
예제 #56
0
def test_selfdn_permission_add(topology_st, allow_user_init):
    """Check add entry operation with and without SelfDN aci

    :id: e837a9ef-be92-48da-ad8b-ebf42b0fede1
    :setup: Standalone instance, add a entry which is used to bind,
    enable acl error logging by setting 'nsslapd-errorlog-level' to '128',
    remove aci's to start with a clean slate, and add dummy entries
    :steps:
        1. Check we can not ADD an entry without the proper SELFDN aci
        2. Check with the proper ACI we can not ADD with 'member' attribute
        3. Check entry to add with memberS and with the ACI
        4. Check with the proper ACI and 'member' it succeeds to ADD
    :expectedresults:
        1. Operation should be successful
        2. Operation should be successful
        3. Operation should fail with Insufficient Access
        4. Operation should be successful
     """
    topology_st.standalone.log.info(
        "\n\n######################### ADD ######################\n")

    # bind as bind_entry
    topology_st.standalone.log.info("Bind as %s" % BIND_DN)
    topology_st.standalone.simple_bind_s(BIND_DN, BIND_PW)

    # Prepare the entry with multivalued members
    entry_with_members = Entry(ENTRY_DN)
    entry_with_members.setValues('objectclass', 'top', 'person',
                                 'OCticket47653')
    entry_with_members.setValues('sn', ENTRY_NAME)
    entry_with_members.setValues('cn', ENTRY_NAME)
    entry_with_members.setValues('postalAddress', 'here')
    entry_with_members.setValues('postalCode', '1234')
    members = []
    for cpt in range(MAX_OTHERS):
        name = "%s%d" % (OTHER_NAME, cpt)
        members.append("cn=%s,%s" % (name, SUFFIX))
    members.append(BIND_DN)
    entry_with_members.setValues('member', members)

    # Prepare the entry with one member
    entry_with_member = Entry(ENTRY_DN)
    entry_with_member.setValues('objectclass', 'top', 'person',
                                'OCticket47653')
    entry_with_member.setValues('sn', ENTRY_NAME)
    entry_with_member.setValues('cn', ENTRY_NAME)
    entry_with_member.setValues('postalAddress', 'here')
    entry_with_member.setValues('postalCode', '1234')
    member = []
    member.append(BIND_DN)
    entry_with_member.setValues('member', member)

    # entry to add WITH member being BIND_DN but WITHOUT the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (aci is missing): %r" %
            (ENTRY_DN, entry_with_member))

        topology_st.standalone.add_s(entry_with_member)
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # Ok Now add the proper ACI
    topology_st.standalone.log.info("Bind as %s and add the ADD SELFDN aci" %
                                    DN_DM)
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)

    ACI_TARGET = "(target = \"ldap:///cn=*,%s\")" % SUFFIX
    ACI_TARGETFILTER = "(targetfilter =\"(objectClass=%s)\")" % OC_NAME
    ACI_ALLOW = "(version 3.0; acl \"SelfDN add\"; allow (add)"
    ACI_SUBJECT = " userattr = \"member#selfDN\";)"
    ACI_BODY = ACI_TARGET + ACI_TARGETFILTER + ACI_ALLOW + ACI_SUBJECT
    mod = [(ldap.MOD_ADD, 'aci', ensure_bytes(ACI_BODY))]
    topology_st.standalone.modify_s(SUFFIX, mod)

    # bind as bind_entry
    topology_st.standalone.log.info("Bind as %s" % BIND_DN)
    topology_st.standalone.simple_bind_s(BIND_DN, BIND_PW)

    # entry to add WITHOUT member and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (member is missing)" % ENTRY_DN)
        topology_st.standalone.add_s(
            Entry((ENTRY_DN, {
                'objectclass': ENTRY_OC.split(),
                'sn': ENTRY_NAME,
                'cn': ENTRY_NAME,
                'postalAddress': 'here',
                'postalCode': '1234'
            })))
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    # entry to add WITH memberS and WITH the ACI -> ldap.INSUFFICIENT_ACCESS
    # member should contain only one value
    try:
        topology_st.standalone.log.info(
            "Try to add Add  %s (with several member values)" % ENTRY_DN)
        topology_st.standalone.add_s(entry_with_members)
    except Exception as e:
        topology_st.standalone.log.info("Exception (expected): %s" %
                                        type(e).__name__)
        assert isinstance(e, ldap.INSUFFICIENT_ACCESS)

    topology_st.standalone.log.info("Try to add Add  %s should be successful" %
                                    ENTRY_DN)
    topology_st.standalone.add_s(entry_with_member)
예제 #57
0
    def test_update_complex(self):
        # compare two entries created with different methods
        nsuffix, replid, replicatype = ("dc=example,dc=com", 5,
                                        lib389.REPLICA_RDWR_TYPE)
        binddnlist, legacy = ['uid=pippo, cn=config'], 'off'
        dn = "dc=example,dc=com"
        entry = Entry(dn)
        entry.setValues(
            'objectclass', "top", "nsds5replica", "extensibleobject")
        entry.setValues('cn', "replica")
        entry.setValues('nsds5replicaroot', nsuffix)
        entry.setValues('nsds5replicaid', str(replid))
        entry.setValues('nsds5replicatype', str(replicatype))
        entry.setValues('nsds5flags', "1")
        entry.setValues('nsds5replicabinddn', binddnlist)
        entry.setValues('nsds5replicalegacyconsumer', legacy)

        uentry = Entry((
            dn, {'objectclass': ["top", "nsds5replica", "extensibleobject"],
                 'cn': ["replica"]})
        )
        log.debug("Entry created with dict:", uentry)
        # Entry.update *replaces*, so be careful with multi-valued attrs
        uentry.update({
            'nsds5replicaroot': nsuffix,
            'nsds5replicaid': str(replid),
            'nsds5replicatype': str(replicatype),
            'nsds5flags': '1',
            'nsds5replicabinddn': binddnlist,
            'nsds5replicalegacyconsumer': legacy
        })
        uentry_s, entry_s = list(map(str, (uentry, entry)))
        assert uentry_s == entry_s, "Mismatching entries [%r] vs [%r]" % (
            uentry, entry)
예제 #58
0
파일: tasks.py 프로젝트: pombreda/lib389
    def exportLDIF(self,
                   suffix=None,
                   benamebase=None,
                   output_file=None,
                   args=None):
        '''
        Export in a LDIF format a given 'suffix' (or 'benamebase' that stores that suffix).
        It uses an internal task to acheive this request.

        If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
        If both 'suffix' and 'benamebase' are missing it raises ValueError

        'output_file' is the output file of the export

        @param suffix - suffix of the backend
        @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
        @param output_file - file that will contain the exported suffix in LDIF format
        @param args - is a dictionary that contains modifier of the export task
                wait: True/[False] - If True, 'export' waits for the completion of the task before to return
                repl-info: True/[False] - If True, it adds the replication meta data (state information,
                                          tombstones and RUV) in the exported file

        @return None

        @raise ValueError

        '''

        # Checking the parameters
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        if not output_file:
            raise ValueError("output_file is mandatory")

        # Prepare the task entry
        cn = "export_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
        dn = "cn=%s,%s" % (cn, DN_EXPORT_TASK)
        entry = Entry(dn)
        entry.update({
            'objectclass': ['top', 'extensibleObject'],
            'cn': cn,
            'nsFilename': output_file
        })
        if benamebase:
            entry.setValues('nsInstance', benamebase)
        else:
            entry.setValues('nsIncludeSuffix', suffix)

        if args.get(EXPORT_REPL_INFO, False):
            entry.setValues('nsExportReplica', 'true')

        # start the task and possibly wait for task completion
        self.conn.add_s(entry)
        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error("Error: export task %s for file %s exited with %d" %
                           (cn, output_file, exitCode))
        else:
            self.log.info("Export task %s for file %s completed successfully" %
                          (cn, output_file))
        return exitCode
예제 #59
0
파일: tasks.py 프로젝트: pombreda/lib389
    def fixupMemberOf(self,
                      suffix=None,
                      benamebase=None,
                      filt=None,
                      args=None):
        '''
            Trigger a fixup task on 'suffix' (or 'benamebase' that stores that suffix) related to the
            entries 'memberof' of groups. It uses an internal task to acheive this request.

            If 'suffix' and 'benamebase' are specified, it uses 'benamebase' first else 'suffix'.
            If both 'suffix' and 'benamebase' are missing it raise ValueError

            'filt' is a filter that will select all the entries (under 'suffix') that we need to evaluate/fix.
            If missing, the default value is "(|(objectclass=inetuser)(objectclass=inetadmin))"

            @param suffix - suffix of the backend
            @param benamebase - 'commonname'/'cn' of the backend (e.g. 'userRoot')
            @param args - is a dictionary that contains modifier of the fixupMemberOf task
                wait: True/[False] - If True,  waits for the completion of the task before to return

            @return exit code

            @raise ValueError: if benamebase and suffix are specified, or can not retrieve the suffix from the
                            mapping tree entry
        '''
        if not benamebase and not suffix:
            raise ValueError("Specify either bename or suffix")

        # If backend name was provided, retrieve the suffix
        if benamebase:
            ents = self.conn.mappingtree.list(bename=benamebase)
            if len(ents) != 1:
                raise ValueError("invalid backend name: %s" % benamebase)

            attr = MT_PROPNAME_TO_ATTRNAME[MT_SUFFIX]
            if not ents[0].hasAttr(attr):
                raise ValueError(
                    "invalid backend name: %s, or entry without %s" %
                    (benamebase, attr))

            suffix = ents[0].getValue(attr)

        cn = "fixupmemberof_" + time.strftime("%m%d%Y_%H%M%S",
                                              time.localtime())
        dn = "cn=%s,%s" % (cn, DN_MBO_TASK)
        entry = Entry(dn)
        entry.setValues('objectclass', 'top', 'extensibleObject')
        entry.setValues('cn', cn)
        entry.setValues('basedn', suffix)
        if filt:
            entry.setValues('filter', filt)

        # start the task and possibly wait for task completion
        try:
            self.conn.add_s(entry)
        except ldap.ALREADY_EXISTS:
            self.log.error("Fail to add the memberOf fixup task")
            return -1

        exitCode = 0
        if args and args.get(TASK_WAIT, False):
            (done, exitCode) = self.conn.tasks.checkTask(entry, True)

        if exitCode:
            self.log.error(
                "Error: fixupMemberOf task %s for basedn %s exited with %d" %
                (cn, suffix, exitCode))
        else:
            self.log.info(
                "fixupMemberOf task %s for basedn %s completed successfully" %
                (cn, suffix))
        return exitCode