def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False): """ Convert DNs in member attributes to work in IPA. """ new_members = [] entry_attrs.setdefault(member_attr, []) for m in entry_attrs[member_attr]: try: m = DN(m) except ValueError, e: # This should be impossible unless the remote server # doesn't enforce syntax checking. api.log.error('Malformed DN %s: %s' % (m, e)) continue try: rdnval = m[0].value except IndexError: api.log.error('Malformed DN %s has no RDN?' % m) continue if m.endswith(search_bases['user']): api.log.debug('migrating %s user %s', member_attr, m) m = DN((api.Object.user.primary_key.name, rdnval), api.env.container_user, api.env.basedn) elif m.endswith(search_bases['group']): api.log.debug('migrating %s group %s', member_attr, m) m = DN((api.Object.group.primary_key.name, rdnval), api.env.container_group, api.env.basedn) else: api.log.error('entry %s does not belong into any known container' % m) continue new_members.append(m)
def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False): """ Convert DNs in member attributes to work in IPA. """ new_members = [] entry_attrs.setdefault(member_attr, []) for m in entry_attrs[member_attr]: try: m = DN(m) except ValueError, e: # This should be impossible unless the remote server # doesn't enforce syntax checking. api.log.error('Malformed DN %s: %s' % (m, e)) continue try: rdnval = m[0].value except IndexError: api.log.error('Malformed DN %s has no RDN?' % m) continue if m.endswith(search_bases['user']): api.log.info('migrating %s user %s' % (member_attr, m)) m = DN((api.Object.user.primary_key.name, rdnval), api.env.container_user) elif m.endswith(search_bases['group']): api.log.info('migrating %s group %s' % (member_attr, m)) m = DN((api.Object.group.primary_key.name, rdnval), api.env.container_group) else: api.log.error( 'entry %s does not belong into any known container' % m) continue m = ldap.normalize_dn(m) new_members.append(m)
def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False): """ Convert DNs in member attributes to work in IPA. """ new_members = [] entry_attrs.setdefault(member_attr, []) for m in entry_attrs[member_attr]: try: m = DN(m) except ValueError as e: # This should be impossible unless the remote server # doesn't enforce syntax checking. logger.error('Malformed DN %s: %s', m, e) continue try: rdnval = m[0].value except IndexError: logger.error('Malformed DN %s has no RDN?', m) continue if m.endswith(search_bases['user']): logger.debug('migrating %s user %s', member_attr, m) m = DN((api.Object.user.primary_key.name, rdnval), api.env.container_user, api.env.basedn) elif m.endswith(search_bases['group']): logger.debug('migrating %s group %s', member_attr, m) m = DN((api.Object.group.primary_key.name, rdnval), api.env.container_group, api.env.basedn) else: logger.error( 'entry %s does not belong into any known ' 'container', m) continue new_members.append(m) del entry_attrs[member_attr] if overwrite: entry_attrs['member'] = [] entry_attrs['member'] += new_members
def suppress_netgroup_memberof(self, ldap, entry_attrs): """ We don't want to show managed netgroups so remove them from the memberofindirect list. """ ng_container = DN(api.env.container_netgroup, api.env.basedn) for member in list(entry_attrs.get('memberofindirect', [])): memberdn = DN(member) if not memberdn.endswith(ng_container): continue filter = ldap.make_filter({'objectclass': 'mepmanagedentry'}) try: ldap.get_entries(memberdn, ldap.SCOPE_BASE, filter, ['']) except errors.NotFound: pass else: entry_attrs['memberofindirect'].remove(member)
def execute(self, term=None, **kw): ldap = self.api.Backend.ldap2 entry = ldap.get_entry(self.api.env.basedn, ['aci']) acis = _convert_strings_to_acis(entry.get('aci', [])) results = [] if term: term = term.lower() for a in acis: if a.name.lower().find(term) != -1 and a not in results: results.append(a) acis = list(results) else: results = list(acis) if kw.get('aciname'): for a in acis: prefix, name = _parse_aci_name(a.name) if name != kw['aciname']: results.remove(a) acis = list(results) if kw.get('aciprefix'): for a in acis: prefix, name = _parse_aci_name(a.name) if prefix != kw['aciprefix']: results.remove(a) acis = list(results) if kw.get('attrs'): for a in acis: if not 'targetattr' in a.target: results.remove(a) continue alist1 = sorted( [t.lower() for t in a.target['targetattr']['expression']] ) alist2 = sorted([t.lower() for t in kw['attrs']]) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get('permission'): try: self.api.Command['permission_show']( kw['permission'] ) except errors.NotFound: pass else: for a in acis: uri = 'ldap:///%s' % entry.dn if a.bindrule['expression'] != uri: results.remove(a) acis = list(results) if kw.get('permissions'): for a in acis: alist1 = sorted(a.permissions) alist2 = sorted(kw['permissions']) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get('memberof'): try: dn = _group_from_memberof(kw['memberof']) except errors.NotFound: pass else: memberof_filter = '(memberOf=%s)' % dn for a in acis: if 'targetfilter' in a.target: targetfilter = a.target['targetfilter']['expression'] if targetfilter != memberof_filter: results.remove(a) else: results.remove(a) if kw.get('type'): for a in acis: if 'target' in a.target: target = a.target['target']['expression'] else: results.remove(a) continue found = False for k in _type_map.keys(): if _type_map[k] == target and kw['type'] == k: found = True break if not found: try: results.remove(a) except ValueError: pass if kw.get('selfaci', False) is True: for a in acis: if a.bindrule['expression'] != u'ldap:///self': try: results.remove(a) except ValueError: pass if kw.get('group'): for a in acis: groupdn = a.bindrule['expression'] groupdn = DN(groupdn.replace('ldap:///','')) try: cn = groupdn[0]['cn'] except (IndexError, KeyError): cn = None if cn is None or cn != kw['group']: try: results.remove(a) except ValueError: pass if kw.get('targetgroup'): for a in acis: found = False if 'target' in a.target: target = a.target['target']['expression'] targetdn = DN(target.replace('ldap:///','')) group_container_dn = DN(api.env.container_group, api.env.basedn) if targetdn.endswith(group_container_dn): try: cn = targetdn[0]['cn'] except (IndexError, KeyError): cn = None if cn == kw['targetgroup']: found = True if not found: try: results.remove(a) except ValueError: pass if kw.get('filter'): if not kw['filter'].startswith('('): kw['filter'] = unicode('('+kw['filter']+')') for a in acis: if 'targetfilter' not in a.target or\ not a.target['targetfilter']['expression'] or\ a.target['targetfilter']['expression'] != kw['filter']: results.remove(a) if kw.get('subtree'): for a in acis: if 'target' in a.target: target = a.target['target']['expression'] else: results.remove(a) continue if kw['subtree'].lower() != target.lower(): try: results.remove(a) except ValueError: pass acis = [] for result in results: if kw.get('raw', False): aci = dict(aci=unicode(result)) else: aci = _aci_to_kw(ldap, result, pkey_only=kw.get('pkey_only', False)) acis.append(aci) return dict( result=acis, count=len(acis), truncated=False, )
def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs): assert isinstance(dn, DN) attr_blacklist = ['krbprincipalkey','memberofindirect','memberindirect'] attr_blacklist.extend(kwargs.get('attr_blacklist', [])) ds_ldap = ctx['ds_ldap'] search_bases = kwargs.get('search_bases', None) valid_gids = kwargs['valid_gids'] invalid_gids = kwargs['invalid_gids'] if 'gidnumber' not in entry_attrs: raise errors.NotFound(reason=_('%(user)s is not a POSIX user') % dict(user=pkey)) else: # See if the gidNumber at least points to a valid group on the remote # server. if entry_attrs['gidnumber'][0] in invalid_gids: api.log.warning('GID number %s of migrated user %s does not point to a known group.' \ % (entry_attrs['gidnumber'][0], pkey)) elif entry_attrs['gidnumber'][0] not in valid_gids: try: remote_entry = ds_ldap.find_entry_by_attr( 'gidnumber', entry_attrs['gidnumber'][0], 'posixgroup', [''], search_bases['group'] ) valid_gids.add(entry_attrs['gidnumber'][0]) except errors.NotFound: api.log.warning('GID number %s of migrated user %s does not point to a known group.' \ % (entry_attrs['gidnumber'][0], pkey)) invalid_gids.add(entry_attrs['gidnumber'][0]) except errors.SingleMatchExpected as e: # GID number matched more groups, this should not happen api.log.warning('GID number %s of migrated user %s should match 1 group, but it matched %d groups' \ % (entry_attrs['gidnumber'][0], pkey, e.found)) except errors.LimitsExceeded as e: api.log.warning('Search limit exceeded searching for GID %s' % entry_attrs['gidnumber'][0]) # We don't want to create a UPG so set the magic value in description # to let the DS plugin know. entry_attrs.setdefault('description', []) entry_attrs['description'].append(NO_UPG_MAGIC) # fill in required attributes by IPA entry_attrs['ipauniqueid'] = 'autogenerate' if 'homedirectory' not in entry_attrs: homes_root = config.get('ipahomesrootdir', (paths.HOME_DIR, ))[0] home_dir = '%s/%s' % (homes_root, pkey) home_dir = home_dir.replace('//', '/').rstrip('/') entry_attrs['homedirectory'] = home_dir if 'loginshell' not in entry_attrs: default_shell = config.get('ipadefaultloginshell', [paths.SH])[0] entry_attrs.setdefault('loginshell', default_shell) # do not migrate all attributes for attr in attr_blacklist: entry_attrs.pop(attr, None) # do not migrate all object classes if 'objectclass' in entry_attrs: for object_class in kwargs.get('oc_blacklist', []): try: entry_attrs['objectclass'].remove(object_class) except ValueError: # object class not present pass _create_kerberos_principals(ldap, pkey, entry_attrs, failed) # Fix any attributes with DN syntax that point to entries in the old # tree for attr in entry_attrs.keys(): if ldap.has_dn_syntax(attr): for ind, value in enumerate(entry_attrs[attr]): if not isinstance(value, DN): # value is not DN instance, the automatic encoding may have # failed due to missing schema or the remote attribute type OID was # not detected as DN type. Try to work this around api.log.debug('%s: value %s of type %s in attribute %s is not a DN' ', convert it', pkey, value, type(value), attr) try: value = DN(value) except ValueError as e: api.log.warning('%s: skipping normalization of value %s of type %s ' 'in attribute %s which could not be converted to DN: %s', pkey, value, type(value), attr, e) continue try: remote_entry = ds_ldap.get_entry(value, [api.Object.user.primary_key.name, api.Object.group.primary_key.name]) except errors.NotFound: api.log.warning('%s: attribute %s refers to non-existent entry %s' % (pkey, attr, value)) continue if value.endswith(search_bases['user']): primary_key = api.Object.user.primary_key.name container = api.env.container_user elif value.endswith(search_bases['group']): primary_key = api.Object.group.primary_key.name container = api.env.container_group else: api.log.warning('%s: value %s in attribute %s does not belong into any known container' % (pkey, value, attr)) continue if not remote_entry.get(primary_key): api.log.warning('%s: there is no primary key %s to migrate for %s' % (pkey, primary_key, attr)) continue api.log.debug('converting DN value %s for %s in %s' % (value, attr, dn)) rdnval = remote_entry[primary_key][0].lower() entry_attrs[attr][ind] = DN((primary_key, rdnval), container, api.env.basedn) return dn
def _aci_to_kw(ldap, a, test=False, pkey_only=False): """Convert an ACI into its equivalent keywords. This is used for the modify operation so we can merge the incoming kw and existing ACI and pass the result to _make_aci(). """ kw = {} kw['aciprefix'], kw['aciname'] = _parse_aci_name(a.name) if pkey_only: return kw kw['permissions'] = tuple(a.permissions) if 'targetattr' in a.target: kw['attrs'] = tuple(unicode(e) for e in a.target['targetattr']['expression']) if 'targetfilter' in a.target: target = a.target['targetfilter']['expression'] if target.startswith('(memberOf=') or target.startswith('memberOf='): (junk, memberof) = target.split('memberOf=', 1) memberof = DN(memberof) kw['memberof'] = memberof['cn'] else: kw['filter'] = unicode(target) if 'target' in a.target: target = a.target['target']['expression'] found = False for k in _type_map.keys(): if _type_map[k] == target: kw['type'] = unicode(k) found = True break if not found: if target.startswith('('): kw['filter'] = unicode(target) else: # See if the target is a group. If so we set the # targetgroup attr, otherwise we consider it a subtree try: targetdn = DN(target.replace('ldap:///','')) except ValueError as e: raise errors.ValidationError(name='subtree', error=_("invalid DN (%s)") % e.message) if targetdn.endswith(DN(api.env.container_group, api.env.basedn)): kw['targetgroup'] = targetdn[0]['cn'] else: kw['subtree'] = unicode(target) groupdn = a.bindrule['expression'] groupdn = groupdn.replace('ldap:///','') if groupdn == 'self': kw['selfaci'] = True elif groupdn == 'anyone': pass else: groupdn = DN(groupdn) if len(groupdn) and groupdn[0].attr == 'cn': dn = DN() entry = ldap.make_entry(dn) try: entry = ldap.get_entry(groupdn, ['cn']) except errors.NotFound as e: # FIXME, use real name here if test: dn = DN(('cn', 'test'), api.env.container_permission, api.env.basedn) entry = ldap.make_entry(dn, {'cn': [u'test']}) if api.env.container_permission in entry.dn: kw['permission'] = entry['cn'][0] else: if 'cn' in entry: kw['group'] = entry['cn'][0] return kw
# not detected as DN type. Try to work this around api.log.debug('%s: value %s of type %s in attribute %s is not a DN' ', convert it', pkey, value, type(value), attr) try: value = DN(value) except ValueError, e: api.log.warn('%s: skipping normalization of value %s of type %s ' 'in attribute %s which could not be converted to DN: %s', pkey, value, type(value), attr, e) continue try: remote_entry = ds_ldap.get_entry(value, [api.Object.user.primary_key.name, api.Object.group.primary_key.name]) except errors.NotFound: api.log.warn('%s: attribute %s refers to non-existent entry %s' % (pkey, attr, value)) continue if value.endswith(search_bases['user']): primary_key = api.Object.user.primary_key.name container = api.env.container_user elif value.endswith(search_bases['group']): primary_key = api.Object.group.primary_key.name container = api.env.container_group else: api.log.warn('%s: value %s in attribute %s does not belong into any known container' % (pkey, value, attr)) continue if not remote_entry.get(primary_key): api.log.warn('%s: there is no primary key %s to migrate for %s' % (pkey, primary_key, attr)) continue api.log.debug('converting DN value %s for %s in %s' % (value, attr, dn)) rdnval = remote_entry[primary_key][0].lower()
def _aci_to_kw(ldap, a, test=False, pkey_only=False): """Convert an ACI into its equivalent keywords. This is used for the modify operation so we can merge the incoming kw and existing ACI and pass the result to _make_aci(). """ kw = {} kw["aciprefix"], kw["aciname"] = _parse_aci_name(a.name) if pkey_only: return kw kw["permissions"] = tuple(a.permissions) if "targetattr" in a.target: kw["attrs"] = tuple(unicode(e) for e in a.target["targetattr"]["expression"]) if "targetfilter" in a.target: target = a.target["targetfilter"]["expression"] if target.startswith("(memberOf=") or target.startswith("memberOf="): (junk, memberof) = target.split("memberOf=", 1) memberof = DN(memberof) kw["memberof"] = memberof["cn"] else: kw["filter"] = unicode(target) if "target" in a.target: target = a.target["target"]["expression"] found = False for k in _type_map.keys(): if _type_map[k] == target: kw["type"] = unicode(k) found = True break if not found: if target.startswith("("): kw["filter"] = unicode(target) else: # See if the target is a group. If so we set the # targetgroup attr, otherwise we consider it a subtree try: targetdn = DN(target.replace("ldap:///", "")) except ValueError as e: raise errors.ValidationError(name="subtree", error=_("invalid DN (%s)") % e.message) if targetdn.endswith(DN(api.env.container_group, api.env.basedn)): kw["targetgroup"] = targetdn[0]["cn"] else: kw["subtree"] = unicode(target) groupdn = a.bindrule["expression"] groupdn = groupdn.replace("ldap:///", "") if groupdn == "self": kw["selfaci"] = True elif groupdn == "anyone": pass else: groupdn = DN(groupdn) if len(groupdn) and groupdn[0].attr == "cn": dn = DN() entry = ldap.make_entry(dn) try: entry = ldap.get_entry(groupdn, ["cn"]) except errors.NotFound as e: # FIXME, use real name here if test: dn = DN(("cn", "test"), api.env.container_permission, api.env.basedn) entry = ldap.make_entry(dn, {"cn": [u"test"]}) if api.env.container_permission in entry.dn: kw["permission"] = entry["cn"][0] else: if "cn" in entry: kw["group"] = entry["cn"][0] return kw
def test_cmp(self): # Equality dn1 = DN((self.attr1, self.value1)) self.assertTrue(dn1 == self.dn1) self.assertFalse(dn1 != self.dn1) self.assertTrue(dn1 == self.str_dn1) self.assertFalse(dn1 != self.str_dn1) result = cmp(dn1, self.dn1) self.assertEqual(result, 0) # Make dn1's attr greater with self.assertRaises(AttributeError): dn1[0].attr = self.attr1 + "1" dn1 = DN((self.attr1 + "1", self.value1)) self.assertFalse(dn1 == self.dn1) self.assertTrue(dn1 != self.dn1) result = cmp(dn1, self.dn1) self.assertEqual(result, 1) result = cmp(self.dn1, dn1) self.assertEqual(result, -1) # Reset dn1's attr, should be equal again with self.assertRaises(AttributeError): dn1[0].attr = self.attr1 dn1 = DN((self.attr1, self.value1)) result = cmp(dn1, self.dn1) self.assertEqual(result, 0) # Make dn1's value greater # attr will be equal, this tests secondary comparision component with self.assertRaises(AttributeError): dn1[0].value = self.value1 + "1" dn1 = DN((self.attr1, self.value1 + "1")) result = cmp(dn1, self.dn1) self.assertEqual(result, 1) result = cmp(self.dn1, dn1) self.assertEqual(result, -1) # Make sure dn's with more rdn's are greater result = cmp(self.dn1, self.dn3) self.assertEqual(result, -1) result = cmp(self.dn3, self.dn1) self.assertEqual(result, 1) # Test startswith, endswith container_dn = DN(self.container_dn) base_container_dn = DN(self.base_container_dn) self.assertTrue(base_container_dn.startswith(self.rdn1)) self.assertTrue(base_container_dn.startswith(self.dn1)) self.assertTrue(base_container_dn.startswith(self.dn1 + container_dn)) self.assertFalse(base_container_dn.startswith(self.dn2)) self.assertFalse(base_container_dn.startswith(self.rdn2)) self.assertTrue(base_container_dn.startswith((self.dn1))) self.assertTrue(base_container_dn.startswith((self.rdn1))) self.assertFalse(base_container_dn.startswith((self.rdn2))) self.assertTrue(base_container_dn.startswith((self.rdn2, self.rdn1))) self.assertTrue(base_container_dn.startswith((self.dn1, self.dn2))) self.assertTrue(base_container_dn.endswith(self.base_dn)) self.assertTrue(base_container_dn.endswith(container_dn + self.base_dn)) self.assertFalse(base_container_dn.endswith(DN(self.base_rdn1))) self.assertTrue(base_container_dn.endswith(DN(self.base_rdn2))) self.assertTrue(base_container_dn.endswith((DN(self.base_rdn1), DN(self.base_rdn2)))) # Test "in" membership self.assertTrue(self.container_rdn1 in container_dn) self.assertTrue(container_dn in container_dn) self.assertFalse(self.base_rdn1 in container_dn) self.assertTrue(self.container_rdn1 in base_container_dn) self.assertTrue(container_dn in base_container_dn) self.assertTrue(container_dn + self.base_dn in base_container_dn) self.assertTrue(self.dn1 + container_dn + self.base_dn in base_container_dn) self.assertTrue(self.dn1 + container_dn + self.base_dn == base_container_dn) self.assertFalse(self.container_rdn1 in self.base_dn)
"in attribute %s which could not be converted to DN: %s", pkey, value, type(value), attr, e, ) continue try: remote_entry = ds_ldap.get_entry( value, [api.Object.user.primary_key.name, api.Object.group.primary_key.name] ) except errors.NotFound: api.log.warn("%s: attribute %s refers to non-existent entry %s" % (pkey, attr, value)) continue if value.endswith(search_bases["user"]): primary_key = api.Object.user.primary_key.name container = api.env.container_user elif value.endswith(search_bases["group"]): primary_key = api.Object.group.primary_key.name container = api.env.container_group else: api.log.warn( "%s: value %s in attribute %s does not belong into any known container" % (pkey, value, attr) ) continue if not remote_entry.get(primary_key): api.log.warn("%s: there is no primary key %s to migrate for %s" % (pkey, primary_key, attr)) continue
def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs): assert isinstance(dn, DN) attr_blocklist = ['krbprincipalkey', 'memberofindirect', 'memberindirect'] attr_blocklist.extend(kwargs.get('attr_blocklist', [])) ds_ldap = ctx['ds_ldap'] search_bases = kwargs.get('search_bases', None) valid_gids = kwargs['valid_gids'] invalid_gids = kwargs['invalid_gids'] if 'gidnumber' not in entry_attrs: raise errors.NotFound(reason=_('%(user)s is not a POSIX user') % dict(user=pkey)) else: # See if the gidNumber at least points to a valid group on the remote # server. if entry_attrs['gidnumber'][0] in invalid_gids: logger.warning( 'GID number %s of migrated user %s does not point ' 'to a known group.', entry_attrs['gidnumber'][0], pkey) elif entry_attrs['gidnumber'][0] not in valid_gids: try: remote_entry = ds_ldap.find_entry_by_attr( 'gidnumber', entry_attrs['gidnumber'][0], 'posixgroup', [''], search_bases['group']) valid_gids.add(entry_attrs['gidnumber'][0]) except errors.NotFound: logger.warning( 'GID number %s of migrated user %s does not ' 'point to a known group.', entry_attrs['gidnumber'][0], pkey) invalid_gids.add(entry_attrs['gidnumber'][0]) except errors.SingleMatchExpected as e: # GID number matched more groups, this should not happen logger.warning( 'GID number %s of migrated user %s should ' 'match 1 group, but it matched %d groups', entry_attrs['gidnumber'][0], pkey, e.found) except errors.LimitsExceeded as e: logger.warning('Search limit exceeded searching for GID %s', entry_attrs['gidnumber'][0]) # We don't want to create a UPG so set the magic value in description # to let the DS plugin know. entry_attrs.setdefault('description', []) entry_attrs['description'].append(NO_UPG_MAGIC) # fill in required attributes by IPA entry_attrs['ipauniqueid'] = 'autogenerate' if 'homedirectory' not in entry_attrs: homes_root = config.get('ipahomesrootdir', (paths.HOME_DIR, ))[0] home_dir = '%s/%s' % (homes_root, pkey) home_dir = home_dir.replace('//', '/').rstrip('/') entry_attrs['homedirectory'] = home_dir if 'loginshell' not in entry_attrs: default_shell = config.get('ipadefaultloginshell', [platformconstants.DEFAULT_SHELL])[0] entry_attrs.setdefault('loginshell', default_shell) # do not migrate all attributes for attr in attr_blocklist: entry_attrs.pop(attr, None) # do not migrate all object classes if 'objectclass' in entry_attrs: for object_class in kwargs.get('oc_blocklist', []): try: entry_attrs['objectclass'].remove(object_class) except ValueError: # object class not present pass _create_kerberos_principals(ldap, pkey, entry_attrs, failed) # Fix any attributes with DN syntax that point to entries in the old # tree for attr in entry_attrs.keys(): if ldap.has_dn_syntax(attr): for ind, value in enumerate(entry_attrs[attr]): if not isinstance(value, DN): # value is not DN instance, the automatic encoding may have # failed due to missing schema or the remote attribute type OID was # not detected as DN type. Try to work this around logger.debug( '%s: value %s of type %s in attribute %s is ' 'not a DN, convert it', pkey, value, type(value), attr) try: value = DN(value) except ValueError as e: logger.warning( '%s: skipping normalization of value ' '%s of type %s in attribute %s which ' 'could not be converted to DN: %s', pkey, value, type(value), attr, e) continue try: remote_entry = ds_ldap.get_entry(value, [ api.Object.user.primary_key.name, api.Object.group.primary_key.name ]) except errors.NotFound: logger.warning( '%s: attribute %s refers to non-existent ' 'entry %s', pkey, attr, value) continue if value.endswith(search_bases['user']): primary_key = api.Object.user.primary_key.name container = api.env.container_user elif value.endswith(search_bases['group']): primary_key = api.Object.group.primary_key.name container = api.env.container_group else: logger.warning( '%s: value %s in attribute %s does not ' 'belong into any known container', pkey, value, attr) continue if not remote_entry.get(primary_key): logger.warning( '%s: there is no primary key %s to migrate ' 'for %s', pkey, primary_key, attr) continue logger.debug('converting DN value %s for %s in %s', value, attr, dn) rdnval = remote_entry[primary_key][0].lower() entry_attrs[attr][ind] = DN((primary_key, rdnval), container, api.env.basedn) return dn
def execute(self, term, **kw): ldap = self.api.Backend.ldap2 entry = ldap.get_entry(self.api.env.basedn, ["aci"]) acis = _convert_strings_to_acis(entry.get("aci", [])) results = [] if term: term = term.lower() for a in acis: if a.name.lower().find(term) != -1 and a not in results: results.append(a) acis = list(results) else: results = list(acis) if kw.get("aciname"): for a in acis: prefix, name = _parse_aci_name(a.name) if name != kw["aciname"]: results.remove(a) acis = list(results) if kw.get("aciprefix"): for a in acis: prefix, name = _parse_aci_name(a.name) if prefix != kw["aciprefix"]: results.remove(a) acis = list(results) if kw.get("attrs"): for a in acis: if not "targetattr" in a.target: results.remove(a) continue alist1 = sorted([t.lower() for t in a.target["targetattr"]["expression"]]) alist2 = sorted([t.lower() for t in kw["attrs"]]) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get("permission"): try: self.api.Command["permission_show"](kw["permission"]) except errors.NotFound: pass else: for a in acis: uri = "ldap:///%s" % entry.dn if a.bindrule["expression"] != uri: results.remove(a) acis = list(results) if kw.get("permissions"): for a in acis: alist1 = sorted(a.permissions) alist2 = sorted(kw["permissions"]) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get("memberof"): try: dn = _group_from_memberof(kw["memberof"]) except errors.NotFound: pass else: memberof_filter = "(memberOf=%s)" % dn for a in acis: if "targetfilter" in a.target: targetfilter = a.target["targetfilter"]["expression"] if targetfilter != memberof_filter: results.remove(a) else: results.remove(a) if kw.get("type"): for a in acis: if "target" in a.target: target = a.target["target"]["expression"] else: results.remove(a) continue found = False for k in _type_map.keys(): if _type_map[k] == target and kw["type"] == k: found = True break if not found: try: results.remove(a) except ValueError: pass if kw.get("selfaci", False) is True: for a in acis: if a.bindrule["expression"] != u"ldap:///self": try: results.remove(a) except ValueError: pass if kw.get("group"): for a in acis: groupdn = a.bindrule["expression"] groupdn = DN(groupdn.replace("ldap:///", "")) try: cn = groupdn[0]["cn"] except (IndexError, KeyError): cn = None if cn is None or cn != kw["group"]: try: results.remove(a) except ValueError: pass if kw.get("targetgroup"): for a in acis: found = False if "target" in a.target: target = a.target["target"]["expression"] targetdn = DN(target.replace("ldap:///", "")) group_container_dn = DN(api.env.container_group, api.env.basedn) if targetdn.endswith(group_container_dn): try: cn = targetdn[0]["cn"] except (IndexError, KeyError): cn = None if cn == kw["targetgroup"]: found = True if not found: try: results.remove(a) except ValueError: pass if kw.get("filter"): if not kw["filter"].startswith("("): kw["filter"] = unicode("(" + kw["filter"] + ")") for a in acis: if ( "targetfilter" not in a.target or not a.target["targetfilter"]["expression"] or a.target["targetfilter"]["expression"] != kw["filter"] ): results.remove(a) if kw.get("subtree"): for a in acis: if "target" in a.target: target = a.target["target"]["expression"] else: results.remove(a) continue if kw["subtree"].lower() != target.lower(): try: results.remove(a) except ValueError: pass acis = [] for result in results: if kw.get("raw", False): aci = dict(aci=unicode(result)) else: aci = _aci_to_kw(ldap, result, pkey_only=kw.get("pkey_only", False)) acis.append(aci) return dict(result=acis, count=len(acis), truncated=False)
def test_cmp(self): # Equality dn1 = DN((self.attr1, self.value1)) self.assertTrue(dn1 == self.dn1) self.assertFalse(dn1 != self.dn1) self.assertTrue(dn1 == self.str_dn1) self.assertFalse(dn1 != self.str_dn1) result = cmp(dn1, self.dn1) self.assertEqual(result, 0) # Make dn1's attr greater with self.assertRaises(AttributeError): dn1[0].attr = self.attr1 + "1" dn1 = DN((self.attr1 + "1", self.value1)) self.assertFalse(dn1 == self.dn1) self.assertTrue(dn1 != self.dn1) result = cmp(dn1, self.dn1) self.assertEqual(result, 1) result = cmp(self.dn1, dn1) self.assertEqual(result, -1) # Reset dn1's attr, should be equal again with self.assertRaises(AttributeError): dn1[0].attr = self.attr1 dn1 = DN((self.attr1, self.value1)) result = cmp(dn1, self.dn1) self.assertEqual(result, 0) # Make dn1's value greater # attr will be equal, this tests secondary comparision component with self.assertRaises(AttributeError): dn1[0].value = self.value1 + "1" dn1 = DN((self.attr1, self.value1 + "1")) result = cmp(dn1, self.dn1) self.assertEqual(result, 1) result = cmp(self.dn1, dn1) self.assertEqual(result, -1) # Make sure dn's with more rdn's are greater result = cmp(self.dn1, self.dn3) self.assertEqual(result, -1) result = cmp(self.dn3, self.dn1) self.assertEqual(result, 1) # Test startswith, endswith container_dn = DN(self.container_dn) base_container_dn = DN(self.base_container_dn) self.assertTrue(base_container_dn.startswith(self.rdn1)) self.assertTrue(base_container_dn.startswith(self.dn1)) self.assertTrue(base_container_dn.startswith(self.dn1 + container_dn)) self.assertFalse(base_container_dn.startswith(self.dn2)) self.assertFalse(base_container_dn.startswith(self.rdn2)) self.assertTrue(base_container_dn.startswith((self.dn1))) self.assertTrue(base_container_dn.startswith((self.rdn1))) self.assertFalse(base_container_dn.startswith((self.rdn2))) self.assertTrue(base_container_dn.startswith((self.rdn2, self.rdn1))) self.assertTrue(base_container_dn.startswith((self.dn1, self.dn2))) self.assertTrue(base_container_dn.endswith(self.base_dn)) self.assertTrue(base_container_dn.endswith(container_dn + self.base_dn)) self.assertFalse(base_container_dn.endswith(DN(self.base_rdn1))) self.assertTrue(base_container_dn.endswith(DN(self.base_rdn2))) self.assertTrue( base_container_dn.endswith( (DN(self.base_rdn1), DN(self.base_rdn2)))) # Test "in" membership self.assertTrue(self.container_rdn1 in container_dn) self.assertTrue(container_dn in container_dn) self.assertFalse(self.base_rdn1 in container_dn) self.assertTrue(self.container_rdn1 in base_container_dn) self.assertTrue(container_dn in base_container_dn) self.assertTrue(container_dn + self.base_dn in base_container_dn) self.assertTrue(self.dn1 + container_dn + self.base_dn in base_container_dn) self.assertTrue(self.dn1 + container_dn + self.base_dn == base_container_dn) self.assertFalse(self.container_rdn1 in self.base_dn)
'%s: skipping normalization of value %s of type %s ' 'in attribute %s which could not be converted to DN: %s', pkey, value, type(value), attr, e) continue try: (remote_dn, remote_entry) = ds_ldap.get_entry(value, [ api.Object.user.primary_key.name, api.Object.group.primary_key.name ]) except errors.NotFound: api.log.warn( '%s: attribute %s refers to non-existent entry %s' % (pkey, attr, value)) continue if value.endswith(search_bases['user']): primary_key = api.Object.user.primary_key.name container = api.env.container_user elif value.endswith(search_bases['group']): primary_key = api.Object.group.primary_key.name container = api.env.container_group else: api.log.warn( '%s: value %s in attribute %s does not belong into any known container' % (pkey, value, attr)) continue if not remote_entry.get(primary_key): api.log.warn( '%s: there is no primary key %s to migrate for %s' % (pkey, primary_key, attr))
def test_cmp(self): # Equality dn1 = DN((self.attr1, self.value1)) assert dn1 == self.dn1 assert dn1 == self.dn1 assert dn1 == self.str_dn1 assert dn1 == self.str_dn1 result = cmp(dn1, self.dn1) assert result == 0 # Make dn1's attr greater with pytest.raises(AttributeError): dn1[0].attr = self.attr1 + "1" dn1 = DN((self.attr1 + "1", self.value1)) assert dn1 != self.dn1 assert dn1 != self.dn1 result = cmp(dn1, self.dn1) assert result == 1 result = cmp(self.dn1, dn1) assert result == -1 # Reset dn1's attr, should be equal again with pytest.raises(AttributeError): dn1[0].attr = self.attr1 dn1 = DN((self.attr1, self.value1)) result = cmp(dn1, self.dn1) assert result == 0 # Make dn1's value greater # attr will be equal, this tests secondary comparision component with pytest.raises(AttributeError): dn1[0].value = self.value1 + "1" dn1 = DN((self.attr1, self.value1 + "1")) result = cmp(dn1, self.dn1) assert result == 1 result = cmp(self.dn1, dn1) assert result == -1 # Make sure dn's with more rdn's are greater result = cmp(self.dn1, self.dn3) assert result == -1 result = cmp(self.dn3, self.dn1) assert result == 1 # Test startswith, endswith container_dn = DN(self.container_dn) base_container_dn = DN(self.base_container_dn) assert base_container_dn.startswith(self.rdn1) assert base_container_dn.startswith(self.dn1) assert base_container_dn.startswith(self.dn1 + container_dn) assert not base_container_dn.startswith(self.dn2) assert not base_container_dn.startswith(self.rdn2) assert base_container_dn.startswith((self.dn1)) assert base_container_dn.startswith((self.rdn1)) assert not base_container_dn.startswith((self.rdn2)) assert base_container_dn.startswith((self.rdn2, self.rdn1)) assert base_container_dn.startswith((self.dn1, self.dn2)) assert base_container_dn.endswith(self.base_dn) assert base_container_dn.endswith(container_dn + self.base_dn) assert not base_container_dn.endswith(DN(self.base_rdn1)) assert base_container_dn.endswith(DN(self.base_rdn2)) assert base_container_dn.endswith( (DN(self.base_rdn1), DN(self.base_rdn2))) # Test "in" membership assert self.container_rdn1 in container_dn # pylint: disable=comparison-with-itself assert container_dn in container_dn assert self.base_rdn1 not in container_dn assert self.container_rdn1 in base_container_dn assert container_dn in base_container_dn assert container_dn + self.base_dn in base_container_dn assert self.dn1 + container_dn + self.base_dn in base_container_dn assert self.dn1 + container_dn + self.base_dn == base_container_dn assert self.container_rdn1 not in self.base_dn
def execute(self, term=None, **kw): ldap = self.api.Backend.ldap2 entry = ldap.get_entry(self.api.env.basedn, ['aci']) acis = _convert_strings_to_acis(entry.get('aci', [])) results = [] if term: term = term.lower() for a in acis: if a.name.lower().find(term) != -1 and a not in results: results.append(a) acis = list(results) else: results = list(acis) if kw.get('aciname'): for a in acis: prefix, name = _parse_aci_name(a.name) if name != kw['aciname']: results.remove(a) acis = list(results) if kw.get('aciprefix'): for a in acis: prefix, name = _parse_aci_name(a.name) if prefix != kw['aciprefix']: results.remove(a) acis = list(results) if kw.get('attrs'): for a in acis: if not 'targetattr' in a.target: results.remove(a) continue alist1 = sorted( [t.lower() for t in a.target['targetattr']['expression']]) alist2 = sorted([t.lower() for t in kw['attrs']]) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get('permission'): try: self.api.Command['permission_show'](kw['permission']) except errors.NotFound: pass else: for a in acis: uri = 'ldap:///%s' % entry.dn if a.bindrule['expression'] != uri: results.remove(a) acis = list(results) if kw.get('permissions'): for a in acis: alist1 = sorted(a.permissions) alist2 = sorted(kw['permissions']) if len(set(alist1) & set(alist2)) != len(alist2): results.remove(a) acis = list(results) if kw.get('memberof'): try: dn = _group_from_memberof(kw['memberof']) except errors.NotFound: pass else: memberof_filter = '(memberOf=%s)' % dn for a in acis: if 'targetfilter' in a.target: targetfilter = a.target['targetfilter']['expression'] if targetfilter != memberof_filter: results.remove(a) else: results.remove(a) if kw.get('type'): for a in acis: if 'target' in a.target: target = a.target['target']['expression'] else: results.remove(a) continue found = False for k, value in _type_map.items(): if value == target and kw['type'] == k: found = True break if not found: try: results.remove(a) except ValueError: pass if kw.get('selfaci', False) is True: for a in acis: if a.bindrule['expression'] != u'ldap:///self': try: results.remove(a) except ValueError: pass if kw.get('group'): for a in acis: groupdn = a.bindrule['expression'] groupdn = DN(groupdn.replace('ldap:///', '')) try: cn = groupdn[0]['cn'] except (IndexError, KeyError): cn = None if cn is None or cn != kw['group']: try: results.remove(a) except ValueError: pass if kw.get('targetgroup'): for a in acis: found = False if 'target' in a.target: target = a.target['target']['expression'] targetdn = DN(target.replace('ldap:///', '')) group_container_dn = DN(api.env.container_group, api.env.basedn) if targetdn.endswith(group_container_dn): try: cn = targetdn[0]['cn'] except (IndexError, KeyError): cn = None if cn == kw['targetgroup']: found = True if not found: try: results.remove(a) except ValueError: pass if kw.get('filter'): if not kw['filter'].startswith('('): kw['filter'] = unicode('(' + kw['filter'] + ')') for a in acis: if 'targetfilter' not in a.target or\ not a.target['targetfilter']['expression'] or\ a.target['targetfilter']['expression'] != kw['filter']: results.remove(a) if kw.get('subtree'): for a in acis: if 'target' in a.target: target = a.target['target']['expression'] else: results.remove(a) continue if kw['subtree'].lower() != target.lower(): try: results.remove(a) except ValueError: pass acis = [] for result in results: if kw.get('raw', False): aci = dict(aci=unicode(result)) else: aci = _aci_to_kw(ldap, result, pkey_only=kw.get('pkey_only', False)) acis.append(aci) return dict( result=acis, count=len(acis), truncated=False, )
def _aci_to_kw(ldap, a, test=False, pkey_only=False): """Convert an ACI into its equivalent keywords. This is used for the modify operation so we can merge the incoming kw and existing ACI and pass the result to _make_aci(). """ kw = {} kw['aciprefix'], kw['aciname'] = _parse_aci_name(a.name) if pkey_only: return kw kw['permissions'] = tuple(a.permissions) if 'targetattr' in a.target: kw['attrs'] = tuple( unicode(e) for e in a.target['targetattr']['expression']) if 'targetfilter' in a.target: target = a.target['targetfilter']['expression'] if target.startswith('(memberOf=') or target.startswith('memberOf='): _junk, memberof = target.split('memberOf=', 1) memberof = DN(memberof) kw['memberof'] = memberof['cn'] else: kw['filter'] = unicode(target) if 'target' in a.target: target = a.target['target']['expression'] found = False for k, value in _type_map.items(): if value == target: kw['type'] = unicode(k) found = True break if not found: if target.startswith('('): kw['filter'] = unicode(target) else: # See if the target is a group. If so we set the # targetgroup attr, otherwise we consider it a subtree try: targetdn = DN(target.replace('ldap:///', '')) except ValueError as e: raise errors.ValidationError(name='subtree', error=_("invalid DN (%s)") % e) if targetdn.endswith( DN(api.env.container_group, api.env.basedn)): kw['targetgroup'] = targetdn[0]['cn'] else: kw['subtree'] = unicode(target) groupdn = a.bindrule['expression'] groupdn = groupdn.replace('ldap:///', '') if groupdn == 'self': kw['selfaci'] = True elif groupdn == 'anyone': pass else: groupdn = DN(groupdn) if len(groupdn) and groupdn[0].attr == 'cn': dn = DN() entry = ldap.make_entry(dn) try: entry = ldap.get_entry(groupdn, ['cn']) except errors.NotFound as e: # FIXME, use real name here if test: dn = DN(('cn', 'test'), api.env.container_permission, api.env.basedn) entry = ldap.make_entry(dn, {'cn': [u'test']}) if api.env.container_permission in entry.dn: kw['permission'] = entry['cn'][0] else: if 'cn' in entry: kw['group'] = entry['cn'][0] return kw