Python ldap3.MODIFY_ADD Examples

The following are 13 code examples of ldap3.MODIFY_ADD(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module ldap3 , or try the search function .
Example #1
Source File: LDAPIdResolver.py    From privacyidea with GNU Affero General Public License v3.0 6 votes vote down vote up
def _create_ldap_modify_changes(self, attributes, uid):
        """
        Identifies if an LDAP attribute already exists and if the value needs to be updated, deleted or added.

        :param attributes: Attributes to be updated
        :type attributes: dict
        :param uid: The uid of the user object in the resolver
        :type uid: basestring
        :return: dict with attribute name as keys and values
        """
        modify_changes = {}
        uinfo = self.getUserInfo(uid)

        for fieldname, value in attributes.items():
            if value:
                if fieldname in uinfo:
                    modify_changes[fieldname] = [MODIFY_REPLACE, [value]]
                else:
                    modify_changes[fieldname] = [MODIFY_ADD, [value]]
            else:
                modify_changes[fieldname] = [MODIFY_DELETE, [value]]

        return modify_changes 
Example #2
Source File: gmsa.py    From treadmill with Apache License 2.0 6 votes vote down vote up
def add_spn(self, proid, spn):
        """ Add spn to a GMSA
        """

        if not self._duplicate_spn(spn):
            gmsa_obj = self._get_gmsa_obj(proid)
            if gmsa_obj:
                self.conn.modify(
                    gmsa_obj['dn'],
                    {'servicePrincipalName': [(ldap3.MODIFY_ADD, [spn])]}
                )

                if not _check_ldap3_operation(self.conn):
                    raise RuntimeError(self.conn.result['description'])
            else:
                raise RuntimeError('Proid:{} not found'.format(proid))
        else:
            raise RuntimeError('Spn already added to another gmsa') 
Example #3
Source File: exploitation.py    From aclpwn.py with MIT License 5 votes vote down vote up
def add_user_to_group(ldapconnection, state, user_sam, group_bh_name):
    # For display only
    group_sam = get_sam_name(group_bh_name)
    group_dn = get_object_info(ldapconnection, group_sam)[0]
    user_dn = get_object_info(ldapconnection, user_sam)[0]

    # Dictionary for restore data
    restoredata = {}

    # Save DNs
    restoredata['group_dn'] = group_dn
    restoredata['user_dn'] = user_dn

    # Now add the user as a member to this group
    res = ldapconnection.modify(group_dn, {
        'member': [(ldap3.MODIFY_ADD, [user_dn])]
    })
    if res:
        restoredata['success'] = True
        state.push_history('add_user_to_group', restoredata)
        print_o('Added %s as member to %s' % (user_dn, group_dn))
        return True
    else:
        # This means the user is already a member
        if ldapconnection.result['result'] == 68:
            print_m('Could not add %s to group %s since they are already a member, your BloodHound data may be out of date, continuing anyway!' % (user_dn, group_dn))
            # Treat this as a success
            restoredata['success'] = True
            state.push_history('add_user_to_group', restoredata)
            return True
        restoredata['success'] = False
        state.push_history('add_user_to_group', restoredata)
        raise ExploitException('Failed to add %s to group %s: %s' % (user_dn, group_dn, str(ldapconnection.result))) 
Example #4
Source File: ldapattack.py    From Exchange2domain with MIT License 5 votes vote down vote up
def addUserToGroup(self, userDn, domainDumper, groupDn):
        global alreadyEscalated
        # For display only
        groupName = groupDn.split(',')[0][3:]
        userName = userDn.split(',')[0][3:]
        # Now add the user as a member to this group
        res = self.client.modify(groupDn, {
            'member': [(ldap3.MODIFY_ADD, [userDn])]})
        if res:
            LOG.info('Adding user: %s to group %s result: OK' % (userName, groupName))
            LOG.info('Privilege escalation succesful, shutting down...')
            alreadyEscalated = True
            thread.interrupt_main()
        else:
            LOG.error('Failed to add user to %s group: %s' % (groupName, str(self.client.result))) 
Example #5
Source File: ldapattack.py    From Slackor with GNU General Public License v3.0 5 votes vote down vote up
def addUserToGroup(self, userDn, domainDumper, groupDn):
        global alreadyEscalated
        # For display only
        groupName = groupDn.split(',')[0][3:]
        userName = userDn.split(',')[0][3:]
        # Now add the user as a member to this group
        res = self.client.modify(groupDn, {
            'member': [(ldap3.MODIFY_ADD, [userDn])]})
        if res:
            LOG.info('Adding user: %s to group %s result: OK' % (userName, groupName))
            LOG.info('Privilege escalation succesful, shutting down...')
            alreadyEscalated = True
            _thread.interrupt_main()
        else:
            LOG.error('Failed to add user to %s group: %s' % (groupName, str(self.client.result))) 
Example #6
Source File: gmsa.py    From treadmill with Apache License 2.0 5 votes vote down vote up
def _add_dn_to_proid_group(self, conn, server_dn, proid, force=False):
        """Adds a placement.

        :param conn:
            The `ldap3.Connection`
        :param server_dn:
            The server server_dn
        :param proid:
            The name of the proid
        """
        server_dn_set = self._get_server_dn_set(proid)
        group = self._config.get_group_dn(proid)

        if not self._synced:
            _LOGGER.debug('Server %r should be in group %r', server_dn, group)
            self._increment_dn(server_dn_set, server_dn)
            return

        if not force:
            if not self._increment_dn(server_dn_set, server_dn):
                return

        _LOGGER.debug('Adding %r to group %r', server_dn, group)
        conn.modify(group, {'member': [(ldap3.MODIFY_ADD, [server_dn])]})

        if not _check_ldap3_operation(conn) and not force:
            self._decrement_dn(server_dn_set, server_dn) 
Example #7
Source File: gmsa_test.py    From treadmill with Apache License 2.0 5 votes vote down vote up
def test_gmsa_add_spn(self):
        """Test Gmsa.query_spn
        """
        gmsa_ = gmsa.Gmsa('dc', 'search_base')

        # test SPN duplicate senario
        # pylint: disable=protected-access
        gmsa_._duplicate_spn = mock.MagicMock(return_value=True)
        with self.assertRaises(RuntimeError):
            gmsa_.add_spn('proid1', 'SPN1')

        # test gmsa not exist senario
        # pylint: disable=protected-access
        gmsa_._duplicate_spn = mock.MagicMock(return_value=False)
        # pylint: disable=protected-access
        gmsa_._get_gmsa_obj = mock.MagicMock(return_value=None)
        with self.assertRaises(RuntimeError):
            gmsa_.add_spn('proid1', 'SPN1')

        # test normal case
        # pylint: disable=protected-access
        gmsa._check_ldap3_operation = mock.MagicMock(return_value=True)
        # pylint: disable=protected-access
        gmsa_._duplicate_spn = mock.MagicMock(return_value=False)
        # pylint: disable=protected-access
        gmsa_._get_gmsa_obj = mock.MagicMock(return_value={'dn': 'gmsadn'})
        gmsa_.add_spn('proid1', 'SPN1')
        gmsa_.conn.modify.assert_called_with(
            'gmsadn',
            {'servicePrincipalName': [(ldap3.MODIFY_ADD, ['SPN1'])]}
        ) 
Example #8
Source File: ldapattack.py    From CVE-2019-1040 with MIT License 5 votes vote down vote up
def addUserToGroup(self, userDn, domainDumper, groupDn):
        global alreadyEscalated
        # For display only
        groupName = groupDn.split(',')[0][3:]
        userName = userDn.split(',')[0][3:]
        # Now add the user as a member to this group
        res = self.client.modify(groupDn, {
            'member': [(ldap3.MODIFY_ADD, [userDn])]})
        if res:
            LOG.info('Adding user: %s to group %s result: OK' % (userName, groupName))
            LOG.info('Privilege escalation succesful, shutting down...')
            alreadyEscalated = True
            _thread.interrupt_main()
        else:
            LOG.error('Failed to add user to %s group: %s' % (groupName, str(self.client.result))) 
Example #9
Source File: client_ldap3.py    From code with MIT License 5 votes vote down vote up
def increment_attr(self, dn, attr, incr=1, use_increment=True):
        import random
        import time

        if use_increment and \
           self.has_control(OID_LDAP_CONTROL_POSTREAD) and \
           self.has_feature(OID_LDAP_FEATURE_MODIFY_INCREMENT):
            # this is far uglier than the Perl version already
            postread_ctrl = ldap3.protocol.rfc4527.post_read_control([attr])
            self.conn.modify(dn,
                             {attr: [(ldap3.MODIFY_INCREMENT, incr)]},
                             controls=[postread_ctrl])
            res = self.conn.result["controls"][OID_LDAP_CONTROL_POSTREAD]["value"]["result"]
            res = CaseInsensitiveDict(res)
            return res[attr][0]

        wait = 0
        while True:
            old_val = self.read_attr(dn, attr)[0]
            new_val = str(int(old_val) + incr)
            try:
                self.conn.modify(dn,
                                 {attr: [(ldap3.MODIFY_DELETE, old_val),
                                         (ldap3.MODIFY_ADD, new_val)]})
            except ldap3.core.exceptions.LDAPNoSuchAttributeResult as e:
                Core.debug("swap (%r, %r) failed: %r", old_val, new_val, e)
                wait += 1
                time.sleep(0.05 * 2**random.randint(0, wait))
            else:
                break
        return int(new_val) 
Example #10
Source File: post-setup-add-components.py    From community-edition-setup with MIT License 4 votes vote down vote up
def add_client2script(script_inum, client_id):
    dn = 'inum={},ou=scripts,o=gluu'.format(script_inum)

    if persistence_type == 'ldap':
        ldap_conn.search(search_base=dn, search_filter='(objectClass=*)', search_scope=ldap3.BASE, attributes=['oxConfigurationProperty'])
        
        for e in ldap_conn.response[0]['attributes'].get('oxConfigurationProperty', []):
            try:
                oxConfigurationProperty = json.loads(e)
            except:
                continue
            if isinstance(oxConfigurationProperty, dict) and oxConfigurationProperty.get('value1') == 'allowed_clients':
                if not client_id in oxConfigurationProperty['value2']:
                    oxConfigurationProperty['value2'] = add2strlist(client_id, oxConfigurationProperty['value2'])
                    oxConfigurationProperty_js = json.dumps(oxConfigurationProperty)
                    ldap_conn.modify(
                        dn,
                        {'oxConfigurationProperty': [ldap3.MODIFY_DELETE, e]}
                        )
                    ldap_conn.modify(
                        dn,
                        {'oxConfigurationProperty': [ldap3.MODIFY_ADD, oxConfigurationProperty_js]}
                        )
                    break

    else:
        n1ql = 'SELECT oxConfigurationProperty FROM `gluu` USE KEYS "scripts_{}"'.format(script_inum)
        result = setupObj.cbm.exec_query(n1ql)
        js = result.json()

        oxConfigurationProperties = js['results'][0]['oxConfigurationProperty']
        for i, oxconfigprop_str in enumerate(oxConfigurationProperties):
            oxconfigprop = json.loads(oxconfigprop_str)
            if oxconfigprop.get('value1') == 'allowed_clients' and not client_id in oxconfigprop['value2']:
                oxconfigprop['value2'] = self.add2strlist(client_id, oxconfigprop['value2'])
                oxConfigurationProperties[i] = json.dumps(oxconfigprop)
                break
        else:
            return

        n1ql = 'UPDATE `gluu` USE KEYS "scripts_{}" SET `oxConfigurationProperty`={}'.format(script_inum, json.dumps(oxConfigurationProperties))
        setupObj.cbm.exec_query(n1ql) 
Example #11
Source File: _ldap.py    From treadmill with Apache License 2.0 4 votes vote down vote up
def _diff_entries(old_entry, new_entry):
    """Diff the entries and produce a diff dictionary suitable for update."""
    # Adapted from python-ldap (http://www.python-ldap.org/) modlist
    # https://github.com/pyldap/pyldap/blob/master/Lib/ldap/modlist.py#L51
    diff = {}
    attrtype_lower_map = {}
    for attr in old_entry.keys():
        attrtype_lower_map[attr.lower()] = attr
    for attrtype in new_entry.keys():
        attrtype_lower = attrtype.lower()
        # Filter away null-strings
        new_values = [
            value
            for value in new_entry[attrtype]
            if value is not None
        ]
        if attrtype_lower in attrtype_lower_map:
            old_values = old_entry.get(attrtype_lower_map[attrtype_lower], [])
            old_values = [
                value
                for value in old_values
                if value is not None
            ]
            del attrtype_lower_map[attrtype_lower]
        else:
            old_values = []

        if not old_values and new_values:
            # Add a new attribute to entry
            diff.setdefault(attrtype, []).append(
                (ldap3.MODIFY_ADD, new_values)
            )
        elif old_values and new_values:
            # Replace existing attribute
            if _diff_attribute_values(old_values, new_values):
                diff.setdefault(attrtype, []).append(
                    (ldap3.MODIFY_REPLACE, new_values))
        elif old_values and not new_values:
            # Completely delete an existing attribute
            diff.setdefault(attrtype, []).append(
                (ldap3.MODIFY_DELETE, []))

    # Remove all attributes of old_entry which are not present
    # in new_entry at all
    for attr in attrtype_lower_map:
        attrtype = attrtype_lower_map[attr]
        diff.setdefault(attrtype, []).append((ldap3.MODIFY_DELETE, []))

    return diff 
Example #12
Source File: _ldap.py    From treadmill with Apache License 2.0 4 votes vote down vote up
def update_schema(self, new_schema):
        """Safely update schema, preserving existing attribute types."""
        old_schema = self.schema() or self.init_schema()

        schema_dn = old_schema['dn']
        old_attr_types = old_schema['attributeTypes']
        new_attr_types = new_schema['attributeTypes']

        changes = collections.defaultdict(list)
        to_del, to_add = self._schema_attrtype_diff(old_attr_types,
                                                    new_attr_types)

        if to_del:
            values = [_attrtype_2_str(_abstract_2_attrtype(name, attr))
                      for name, attr in six.iteritems(to_del)]
            _LOGGER.debug('del: %s - olcAttributeTypes: %r', schema_dn, values)
            changes['olcAttributeTypes'].extend(
                [(ldap3.MODIFY_DELETE, values)])

        if to_add:
            values = [_attrtype_2_str(_abstract_2_attrtype(name, attr))
                      for name, attr in six.iteritems(to_add)]
            _LOGGER.debug('add: %s - olcAttributeTypes: %r', schema_dn, values)
            changes['olcAttributeTypes'].extend([(ldap3.MODIFY_ADD, values)])

        old_obj_classes = old_schema['objectClasses']
        new_obj_classes = new_schema['objectClasses']

        to_del, to_add = self._schema_objcls_diff(old_obj_classes,
                                                  new_obj_classes)
        if to_del:
            values = [_objcls_2_str(name, item)
                      for name, item in six.iteritems(to_del)]
            _LOGGER.debug('del: %s - olcObjectClasses: %r', schema_dn, values)
            changes['olcObjectClasses'].extend([(ldap3.MODIFY_DELETE, values)])
        if to_add:
            values = [_objcls_2_str(name, item)
                      for name, item in six.iteritems(to_add)]
            _LOGGER.debug('add: %s - olcObjectClasses: %r', schema_dn, values)
            changes['olcObjectClasses'].extend([(ldap3.MODIFY_ADD, values)])

        if changes:
            # TODO must be modified in a specific order to avoid exceptions
            self.modify(schema_dn, changes)
        else:
            _LOGGER.info('Schema is up to date.') 
Example #13
Source File: gmsa_test.py    From treadmill with Apache License 2.0 4 votes vote down vote up
def test_on_created_same_host(self, connection):
        """Test gmsa.HostGroupWatch._on_created_placement."""
        # Access protected module
        # pylint: disable=W0212
        server1_path = os.path.join(self.placement_dir, 'server1.ad.com')
        os.mkdir(server1_path)

        with io.open(os.path.join(self.servers_dir, 'server1.ad.com'),
                     'w') as f:
            yaml.dump({
                servers.DC_KEY: 'dc.ad.com',
                servers.DN_KEY: 'CN=server1,DC=AD,DC=COM',
                'partition': 'partition1'
            }, f)

        mock_connection = mock.MagicMock()
        connection.return_value = mock_connection
        type(mock_connection).result = mock.PropertyMock(side_effect={
            'result': 0
        })
        type(mock_connection).response = mock.PropertyMock(return_value=[
            {'attributes': {
                'samAccountName': 'proid1-gmsa-hosts',
                'member': []
            }}
        ])

        watch = gmsa.HostGroupWatch(self.root, 'partition1',
                                    'OU=test,DC=ad,DC=com', '{}-gmsa-hosts')
        watch._sync()

        self.assertEqual(watch._proids, {
            'proid1': {},
        })

        placement_path1 = os.path.join(server1_path,
                                       'proid1.app#0000000000001')
        utils.touch(placement_path1)
        watch._on_created_placement(placement_path1)

        self.assertEqual(watch._proids, {
            'proid1': {'CN=server1,DC=AD,DC=COM': 1},
        })

        placement_path2 = os.path.join(server1_path,
                                       'proid1.app#0000000000001')
        utils.touch(placement_path2)
        watch._on_created_placement(placement_path2)

        self.assertEqual(watch._proids, {
            'proid1': {'CN=server1,DC=AD,DC=COM': 2},
        })

        mock_connection.modify.assert_has_calls([
            mock.call('CN=proid1-gmsa-hosts,OU=test,DC=ad,DC=com',
                      {'member': [(ldap3.MODIFY_ADD,
                                   ['CN=server1,DC=AD,DC=COM'])]}),
        ])
        self.assertEqual(mock_connection.modify.call_count, 1)