예제 #1
0
파일: dhcp.py 프로젝트: neoclust/pulse
 def getFailoverConfig(self):
     """
     Return failover configuration of server
     """
     serviceData = self.getService()[1]
     primaryDN = False
     if 'dhcpPrimaryDN' in serviceData:
         primaryDN = serviceData['dhcpPrimaryDN'][0]
         primaryName = str2dn(primaryDN)[0][0][1]
     secondaryDN = False
     if 'dhcpSecondaryDN' in serviceData:
         secondaryDN = serviceData['dhcpSecondaryDN'][0]
         secondaryName = str2dn(secondaryDN)[0][0][1]
     if primaryDN and secondaryDN:
         pattern = 'failover.*address (?P<primaryIp>[0-9.]+); port (?P<primaryPort>[0-9]+); peer address (?P<secondaryIp>[0-9.]+); peer port (?P<secondaryPort>[0-9]+); max-response-delay (?P<delay>[0-9]+); max-unacked-updates (?P<update>[0-9]+); load balance max seconds (?P<balance>[0-9]+); mclt (?P<mclt>[0-9]+); split (?P<split>[0-9]+);'
         for statement in self.getObjectStatements(primaryDN):
             m = re.match(pattern, statement)
             if m:
                 return { 'primary': [primaryName], 'secondary': [secondaryName],
                          'primaryIp': [m.group("primaryIp")], 'secondaryIp': [m.group("secondaryIp")],
                          'primaryPort': [m.group("primaryPort")], 'secondaryPort': [m.group("secondaryPort")],
                          'delay': [m.group("delay")], 'update': [m.group("update")], "balance": [m.group("balance")],
                          'mclt': [m.group("mclt")], "split": [m.group("split")] }
         return dict({ 'primary': [primaryName], 'secondary': [secondaryName] }.items() + self.getFailoverDefaultValues().items())
     elif primaryDN:
         return dict({ 'primary': [primaryName] }.items() + self.getFailoverDefaultValues().items())
     else:
         return self.getFailoverDefaultValues()
예제 #2
0
 def setFailoverConfig(self,
                       masterIp,
                       slaveIp,
                       serverPort=647,
                       peerPort=647,
                       delay=30,
                       update=10,
                       balance=3,
                       mclt=1800,
                       split=128):
     """
     Setup the failover configuration on servers
     """
     serviceData = self.getService()[1]
     if 'dhcpPrimaryDN' in serviceData and 'dhcpSecondaryDN' in serviceData:
         primaryDN = serviceData['dhcpPrimaryDN'][0]
         secondaryDN = serviceData['dhcpSecondaryDN'][0]
         primaryName = str2dn(primaryDN)[0][0][1]
         secondaryName = str2dn(secondaryDN)[0][0][1]
         self.setServerFailover(primaryDN, primaryName, "primary", masterIp,
                                slaveIp, int(serverPort), int(peerPort),
                                int(delay), int(update), int(balance),
                                int(mclt), int(split))
         self.setServerFailover(secondaryDN, secondaryName, "secondary",
                                slaveIp, masterIp, int(peerPort),
                                int(serverPort), int(delay), int(update),
                                int(balance), int(mclt), int(split))
     else:
         return False
예제 #3
0
파일: proxy.py 프로젝트: gonicus/clacks
    def get_adjusted_parent_dn(self, dn=None):
        index = PluginRegistry.getInstance("ObjectIndex")
        tdn = []
        pdn = self.get_parent_dn(dn)

        # Skip base
        if len(pdn) < len(self.__env.base):
            return pdn

        while True:
            if pdn == self.__env.base or len(pdn) < len(self.__env.base):
                break

            # Fetch object type for pdn
            ptype = index.search({"dn": pdn}, {'_type': 1})[0]['_type']
            schema = self.__factory.getXMLSchema(ptype)
            if not ("StructuralInvisible" in schema.__dict__ and schema.StructuralInvisible == True):
                #tdn.insert(0, str2dn(pdn.encode('utf-8'))[0])
                tdn.append(str2dn(pdn.encode('utf-8'))[0])

            pdn = self.get_parent_dn(pdn)

        tdn = str2dn(self.__env.base.encode('utf-8'))[::-1] + tdn[::-1]

        return dn2str(tdn[::-1]).decode('utf-8')
예제 #4
0
    def handle(self, dn, entry):
        if (dn != 'o=gluu') and (dn != 'ou=appliances,o=gluu'):
            self.DNs.append(dn)
            self.entries[dn] = entry
            
            if not self.inumOrg and 'gluuOrganization' in entry['objectClass']:
                self.inumOrg_dn  = dn
                dne = str2dn(dn)
                self.inumOrg = dne[0][0][1]

            if not self.inumApllience and 'gluuAppliance' in entry['objectClass']:
                self.inumApllience_dn = dn
                dne = str2dn(dn)
                self.inumApllience = dne[0][0][1]
예제 #5
0
	def _register_host(self, app, args):
		if not app.docker:
			self.debug('App is not docker. Skip registering host')
			return None, None
		hostdn = ucr_get(app.ucr_hostdn_key)
		lo, pos = self._get_ldap_connection(args)
		if hostdn:
			if lo.get(hostdn):
				self.log('Already found %s as a host for %s. Better do nothing...' % (hostdn, app.id))
				return hostdn, None
			else:
				self.warn('%s should be the host for %s. But it was not found in LDAP. Creating a new one' % (hostdn, app.id))
		# quasi unique hostname; make sure it does not exceed 14 chars
		# 5 chars of appid + '-' + 8 digits of Epoch
		hostname = '%s-%s' % (app.id[:5], str(int((time.time() * 1000000)))[-10:-2])
		password = generate_password()
		self.log('Registering the container host %s for %s' % (hostname, app.id))
		if app.docker_server_role == 'memberserver':
			base = 'cn=memberserver,cn=computers,%s' % ucr_get('ldap/base')
		else:
			base = 'cn=dc,cn=computers,%s' % ucr_get('ldap/base')
		while base and not lo.get(base):
			base = dn2str(str2dn(base)[1:])
		pos.setDn(base)
		domain = ucr_get('domainname')
		description = '%s (%s)' % (app.name, app.version)
		policies = ['cn=app-release-update,cn=policies,%s' % ucr_get('ldap/base'), 'cn=app-update-schedule,cn=policies,%s' % ucr_get('ldap/base')]
		obj = create_object_if_not_exists('computers/%s' % app.docker_server_role, lo, pos, name=hostname, description=description, domain=domain, password=password, objectFlag='docker', policies=policies)
		ucr_save({app.ucr_hostdn_key: obj.dn})
		return obj.dn, password
예제 #6
0
    def get_root_suffix_by_entry(self, entry_dn):
        """Get the root suffix to which the entry belongs

        :param entry_dn: An entry DN
        :type entry_dn: str
        :returns: str
        """

        mapping_tree_list = sorted(self.list(),
                                   key=lambda b: len(b.dn),
                                   reverse=True)

        entry_dn_parts = str2dn(entry_dn)
        processing = True
        while processing:
            compare_dn = dn2str(entry_dn_parts)
            for mapping_tree in mapping_tree_list:
                if str.lower(compare_dn) == str.lower(mapping_tree.rdn):
                    processing = False
                    return mapping_tree.rdn
            if entry_dn_parts:
                entry_dn_parts.pop(0)
            else:
                processing = False
        raise ldap.NO_SUCH_OBJECT(f"{entry_dn} doesn't belong to any suffix")
예제 #7
0
 def _rdns_from_value(self, value):
     if isinstance(value, six.string_types):
         try:
             if isinstance(value, six.text_type):
                 value = val_encode(value)
             rdns = str2dn(value)
         except DECODING_ERROR:
             raise ValueError("malformed RDN string = \"%s\"" % value)
         for rdn in rdns:
             sort_avas(rdn)
     elif isinstance(value, DN):
         rdns = value._copy_rdns()
     elif isinstance(value, (tuple, list, AVA)):
         ava = get_ava(value)
         rdns = [[ava]]
     elif isinstance(value, RDN):
         rdns = [value.to_openldap()]
     elif isinstance(value, cryptography.x509.name.Name):
         rdns = list(
             reversed([[
                 get_ava(
                     _ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
                     ava.value)
             ] for ava in value]))
     else:
         raise TypeError(
             "must be str, unicode, tuple, Name, RDN or DN, got %s instead"
             % type(value))
     return rdns
예제 #8
0
파일: dn.py 프로젝트: LiptonB/freeipa
 def _rdns_from_value(self, value):
     if isinstance(value, six.string_types):
         try:
             if isinstance(value, six.text_type):
                 value = val_encode(value)
             rdns = str2dn(value)
         except DECODING_ERROR:
             raise ValueError("malformed RDN string = \"%s\"" % value)
         for rdn in rdns:
             sort_avas(rdn)
     elif isinstance(value, DN):
         rdns = value._copy_rdns()
     elif isinstance(value, (tuple, list, AVA)):
         ava = get_ava(value)
         rdns = [[ava]]
     elif isinstance(value, RDN):
         rdns = [value.to_openldap()]
     elif isinstance(value, cryptography.x509.name.Name):
         rdns = list(reversed([
             [get_ava(
                 _ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
                 ava.value)]
             for ava in value
         ]))
     else:
         raise TypeError(
             "must be str, unicode, tuple, Name, RDN or DN, got %s instead"
             % type(value))
     return rdns
예제 #9
0
파일: dn.py 프로젝트: LiptonB/freeipa
def str2rdn(value):
    try:
        rdns = str2dn(value.encode('utf-8'))
    except DECODING_ERROR:
        raise ValueError("malformed AVA string = \"%s\"" % value)
    if len(rdns) != 1:
        raise ValueError("multiple RDN's specified by \"%s\"" % (value))
    return rdns[0]
예제 #10
0
def str2rdn(value):
    try:
        rdns = str2dn(value.encode('utf-8'))
    except DECODING_ERROR:
        raise ValueError("malformed AVA string = \"%s\"" % value)
    if len(rdns) != 1:
        raise ValueError("multiple RDN's specified by \"%s\"" % (value))
    return rdns[0]
예제 #11
0
파일: dhcp.py 프로젝트: neoclust/pulse
 def setFailoverConfig(self, masterIp, slaveIp, serverPort = 647, peerPort = 647,
     delay = 30, update = 10, balance = 3, mclt = 1800, split = 128):
     """
     Setup the failover configuration on servers
     """
     serviceData = self.getService()[1]
     if 'dhcpPrimaryDN' in serviceData and 'dhcpSecondaryDN' in serviceData:
         primaryDN = serviceData['dhcpPrimaryDN'][0]
         secondaryDN = serviceData['dhcpSecondaryDN'][0]
         primaryName = str2dn(primaryDN)[0][0][1]
         secondaryName = str2dn(secondaryDN)[0][0][1]
         self.setServerFailover(primaryDN, primaryName, "primary", masterIp, slaveIp,
             int(serverPort), int(peerPort), int(delay), int(update), int(balance), int(mclt), int(split))
         self.setServerFailover(secondaryDN, secondaryName, "secondary", slaveIp, masterIp,
             int(peerPort), int(serverPort), int(delay), int(update), int(balance), int(mclt), int(split))
     else:
         return False
예제 #12
0
def extract_cn(user_dn):
    """ Get cn from a user dn """
    try:
        for rdn in dn.str2dn(user_dn):
            rdn = rdn[0]
            if rdn[0] == 'cn':
                return rdn[1]
    except Exception:
        return user_dn
예제 #13
0
파일: updateldap.py 프로젝트: bhoflack/spdc
def domainroot(d):
  """ get the domain ldap root for the given dn 

      >>> dn = "sambaDomainName=IEPER-TEST,dc=Ieper,dc=elex"
      >>> domainroot(dn)
      'dc=Ieper,dc=elex'
  """
  dn = str2dn(d)
  dn.pop(0)
  return dn2str(dn)
예제 #14
0
	def __init__(self, dn):
		logging.debug('Plugin.__init__(dn=' + repr(dn) + ')')
		self.core = OgpCore.getInstance()
		self.dn = dn
		# Dirty but it pleases Michel :-P
		# Loads RW XML conf from LDAP
		self.cancel()
		# Parent DN (to find parent conf)
		self.parentDn = str2dn(dn)
		del self.parentDn[0]
		self.parentDn = dn2str(self.parentDn)
예제 #15
0
 def get_servers(self, lo):
     old_name = self.name
     old_position = self.position
     old_dn = str2dn(self.old_dn or self.dn)
     self.position = dn2str(old_dn[1:])
     self.name = old_dn[0][0][1]
     try:
         return super(AnyDHCPService, self).get_servers(lo)
     finally:
         self.position = old_position
         self.name = old_name
예제 #16
0
 def __init__(self, dn):
     logging.debug('Plugin.__init__(dn=' + repr(dn) + ')')
     self.core = OgpCore.getInstance()
     self.dn = dn
     # Dirty but it pleases Michel :-P
     # Loads RW XML conf from LDAP
     self.cancel()
     # Parent DN (to find parent conf)
     self.parentDn = str2dn(dn)
     del self.parentDn[0]
     self.parentDn = dn2str(self.parentDn)
예제 #17
0
 def getFailoverConfig(self):
     """
     Return failover configuration of server
     """
     serviceData = self.getService()[1]
     primaryDN = False
     if 'dhcpPrimaryDN' in serviceData:
         primaryDN = serviceData['dhcpPrimaryDN'][0]
         primaryName = str2dn(primaryDN)[0][0][1]
     secondaryDN = False
     if 'dhcpSecondaryDN' in serviceData:
         secondaryDN = serviceData['dhcpSecondaryDN'][0]
         secondaryName = str2dn(secondaryDN)[0][0][1]
     if primaryDN and secondaryDN:
         pattern = 'failover.*address (?P<primaryIp>[0-9.]+); port (?P<primaryPort>[0-9]+); peer address (?P<secondaryIp>[0-9.]+); peer port (?P<secondaryPort>[0-9]+); max-response-delay (?P<delay>[0-9]+); max-unacked-updates (?P<update>[0-9]+); load balance max seconds (?P<balance>[0-9]+); mclt (?P<mclt>[0-9]+); split (?P<split>[0-9]+);'
         for statement in self.getObjectStatements(primaryDN):
             m = re.match(pattern, statement)
             if m:
                 return {
                     'primary': [primaryName],
                     'secondary': [secondaryName],
                     'primaryIp': [m.group("primaryIp")],
                     'secondaryIp': [m.group("secondaryIp")],
                     'primaryPort': [m.group("primaryPort")],
                     'secondaryPort': [m.group("secondaryPort")],
                     'delay': [m.group("delay")],
                     'update': [m.group("update")],
                     "balance": [m.group("balance")],
                     'mclt': [m.group("mclt")],
                     "split": [m.group("split")]
                 }
         return dict({
             'primary': [primaryName],
             'secondary': [secondaryName]
         }.items() + self.getFailoverDefaultValues().items())
     elif primaryDN:
         return dict({'primary': [primaryName]}.items() +
                     self.getFailoverDefaultValues().items())
     else:
         return self.getFailoverDefaultValues()
예제 #18
0
 def build_dn_and_filter(self, ressource, ldap_attributes):
     '''Build the target record dn'''
     base_dn = ressource['base_dn']
     rdn_attributes = ressource['rdn_attributes']
     dn = str2dn(base_dn)
     rdn = []
     for ldap_attribute in rdn_attributes:
         values = ldap_attributes.get(ldap_attribute, [])
         assert len(values) == 1, 'RDN attribute must have exactly one value %r %r' % \
             (rdn_attributes, ldap_attributes)
         rdn.append((ldap_attribute, values[0], 1))
     dn = [rdn] + dn
     return dn2str(dn), ('&', [(a,b) for a, b, c in rdn])
예제 #19
0
 def build_dn_and_filter(self, ressource, ldap_attributes):
     '''Build the target record dn'''
     base_dn = ressource['base_dn']
     rdn_attributes = ressource['rdn_attributes']
     dn = str2dn(base_dn)
     rdn = []
     for ldap_attribute in rdn_attributes:
         values = ldap_attributes.get(ldap_attribute, [])
         assert len(values) == 1, 'RDN attribute must have exactly one value %r %r' % \
             (rdn_attributes, ldap_attributes)
         rdn.append((ldap_attribute, values[0], 1))
     dn = [rdn] + dn
     return dn2str(dn), ('&', [(a, b) for a, b, c in rdn])
예제 #20
0
def create_base_c(instance, basedn):
    """Create the base country object"""

    c = Country(instance, dn=basedn)
    # Explode the dn to get the first bit.
    avas = dn.str2dn(basedn)
    c_ava = avas[0][0][1]

    c.create(properties={
        'c': c_ava,
    })

    return c
예제 #21
0
    def getDestinationIndicator(self, client_id, uid, cn_query, rotate=True):
        """

        :param client_id: UUID of the client used to find the closest destinationIndicators
        :param uid: uid of the user
        :param cn_query: filter for destinationIndicator-cns (e.g. 'lts-% for wildcards)
        :param rotate: rotate the destinationIndicators (do not use the last one twice in a row)
        :return: FQDN of the server marked as destinationIndicator
        """
        index = PluginRegistry.getInstance('ObjectIndex')
        res = index.search({'_type': 'User', 'uid': uid}, {'dn': 1})
        if len(res) == 0:
            raise ValueError(C.make_error("USER_NOT_FOUND", user=uid, status_code=404))

        user = ObjectProxy(res[0]['dn'])

        if rotate is False and user.destinationIndicator is not None:
            # nothing to rotate, take the stored one
            return user.destinationIndicator

        client = self.__open_device(client_id, read_only=True)
        parent_dn = client.get_adjusted_parent_dn()
        res = index.search({'_type': 'Device', 'extension': 'GoServer', 'cn': cn_query, '_adjusted_parent_dn': parent_dn}, {'dn': 1})

        while len(res) == 0 and len(parent_dn) > len(self.env.base):
            parent_dn = dn2str(str2dn(parent_dn, flags=ldap.DN_FORMAT_LDAPV3)[1:])
            res = index.search({'_type': 'Device', 'cn': cn_query, '_adjusted_parent_dn': parent_dn}, {'dn': 1})

        if len(res) > 0:
            di_pool = sorted([x['dn'] for x in res])
            if user.destinationIndicator is None:
                # nothing to rotate, take the first one
                user.destinationIndicator = di_pool[0]
                user.commit()

            elif rotate is True:
                if user.destinationIndicator in di_pool:
                    # take the next one from list
                    position = di_pool.index(user.destinationIndicator)+1
                    if position >= len(di_pool):
                        position = 0
                    user.destinationIndicator = di_pool[position]
                    user.commit()
                else:
                    # nothing to rotate, take the first one
                    user.destinationIndicator = di_pool[0]
                    user.commit()

            return user.destinationIndicator
        return None
예제 #22
0
def create_base_cn(instance, basedn):
    """Create the base nsContainer object"""

    cn = nsContainer(instance, dn=basedn)
    # Explode the dn to get the first bit.
    avas = dn.str2dn(basedn)
    cn_ava = avas[0][0][1]

    cn.create(properties={
        # I think in python 2 this forces unicode return ...
        'cn': cn_ava,
    })

    return cn
예제 #23
0
 def _refresh(self):
     try:
         with open(self._password_file) as fd:
             password = fd.read().rstrip("\n")
     except EnvironmentError:
         get_logger("cache").warning("Unable to read {}".format(
             self._password_file))
         return None
     con = ldap.initialize(self._ldap_uri)
     con.simple_bind_s(self._bind_dn, password)
     ldap_content = {}
     users = {}
     groups = con.search_s(self._ldap_base, ldap.SCOPE_SUBTREE,
                           u"(objectClass=posixGroup)")
     for dn, attrs in groups:
         usernames = []
         groups = []
         member_uids = [
             member.decode("utf-8").lower()
             for member in attrs.get("memberUid", [])
         ]
         unique_members = [
             member.decode("utf-8").lower()
             for member in attrs.get("uniqueMember", [])
         ]
         for member in member_uids:
             if not member.endswith("$"):
                 usernames.append(member.lower())
         for member in unique_members:
             if member.startswith("cn="):
                 member_uid = str2dn(member)[0][0][1]
                 if "{}$".format(member_uid) not in member_uids:
                     groups.append(member)
         ldap_content[dn.lower()] = {
             "usernames": usernames,
             "groups": groups
         }
     groups_with_nested_groups = {}
     for group_dn in ldap_content:
         self._nested_groups(group_dn, ldap_content,
                             groups_with_nested_groups)
     for group_dn, attrs in ldap_content.items():
         for user in attrs["usernames"]:
             groups = users.setdefault(user, set())
             groups.update(groups_with_nested_groups[group_dn])
     users = dict((user, list(groups)) for user, groups in users.items())
     with tempfile.NamedTemporaryFile(mode="w", delete=False) as fd:
         json.dump(users, fd, sort_keys=True, indent=4)
     return fd
예제 #24
0
    def changed_cases(members):
        def mixed_case(attr):
            return attr[0].lower() + attr[1:].upper()

        variants = []
        for transform in (str.lower, str.upper, mixed_case):
            result = {}
            for key, dn in members.items():
                dn = str2dn(dn)
                rdn = dn.pop(0)
                rdn = [tuple([transform(str(rdn[0][0]))] + list(rdn[0][1:]))]
                dn.insert(0, rdn)
                result[key] = [dn2str(dn)]
            variants.append(result)
        return variants
def get_key_from(dn):
    dns = []
    for d in str2dn(dn):
        for rd in d:
            if rd[0] == 'o' and rd[1] == 'gluu':
                continue
            dns.append(rd[1])

    dns.reverse(),
    key = '_'.join(dns)

    if not key:
        key = '_'

    return key
예제 #26
0
 def create_without_hooks(self, lo, validate):
     # prepare LDAP: create containers where this basic group lives if necessary
     container_dn = self.get_own_container()[:-len(ucr.get('ldap/base')) -
                                             1]
     containers = str2dn(container_dn)
     super_container_dn = ucr.get('ldap/base')
     for container_info in reversed(containers):
         dn_part, cn = container_info[0][0:2]
         if dn_part.lower() == 'ou':
             container = OU(name=cn)
         else:
             container = Container(name=cn, school='', group_path='1')
         container.position = super_container_dn
         super_container_dn = container.create(lo, False)
     return super(BasicGroup, self).create_without_hooks(lo, validate)
예제 #27
0
def create_base_orgunit(instance, basedn):
    """Create the base org unit object for a org unit"""

    orgunit = OrganizationalUnit(instance, dn=basedn)
    # Explode the dn to get the first bit.
    avas = dn.str2dn(basedn)
    ou_ava = avas[0][0][1]

    orgunit.create(
        properties={
            # I think in python 2 this forces unicode return ...
            'ou': ou_ava,
            'description': basedn,
        })

    return orgunit
예제 #28
0
    def get(self, selector=[], dn=None, json=False):
        """Create a test user with uid=test_user_UID rdn

        :param uid: User id
        :type uid: int
        :param gid: Group id
        :type gid: int

        :returns: DSLdapObject of the created entry
        """

        # Normalise escaped characters
        if is_dn(selector):
            selector = dn2str(str2dn(selector))

        return super(MappingTrees, self).get(selector, dn, json)
예제 #29
0
def create_base_domain(instance, basedn):
    """Create the base domain object"""

    domain = Domain(instance, dn=basedn)
    # Explode the dn to get the first bit.
    avas = dn.str2dn(basedn)
    dc_ava = avas[0][0][1]

    domain.create(properties={
        # I think in python 2 this forces unicode return ...
        'dc': dc_ava,
        'description': basedn,
    })
    # ACI can be added later according to your needs

    return domain
예제 #30
0
파일: __init__.py 프로젝트: AnatomicJC/mmc
    def getVAliasUsers(self, alias):
        """
        Get the user list of a virtual alias entry

        @param alias: virtual alias name
        @type alias: str
        """

        dn = "mailalias=" + alias + ", " + self.conf.vAliasesDN
        s = self.l.search_s(dn, ldap.SCOPE_BASE)
        c, attrs = s[0]
        users = []
        if "mailaliasmember" in attrs:
            for user in attrs["mailaliasmember"]:
                # get the user uid
                users.append(str2dn(user)[0][0][1])
        return users
예제 #31
0
    def getVAliasUsers(self, alias):
        """
        Get the user list of a virtual alias entry

        @param alias: virtual alias name
        @type alias: str
        """

        dn = "mailalias=" + alias + ", " + self.conf.vAliasesDN
        s = self.l.search_s(dn, ldap.SCOPE_BASE)
        c, attrs = s[0]
        users = []
        if "mailaliasmember" in attrs:
            for user in attrs["mailaliasmember"]:
                # get the user uid
                users.append(str2dn(user)[0][0][1])
        return users
예제 #32
0
파일: dn.py 프로젝트: andygabby/freeipa
 def _rdns_from_value(self, value):
     if isinstance(value, six.string_types):
         try:
             if isinstance(value, unicode):
                 value = value.encode('utf-8')
             rdns = str2dn(value)
         except DECODING_ERROR:
             raise ValueError("malformed RDN string = \"%s\"" % value)
         for rdn in rdns:
             sort_avas(rdn)
     elif isinstance(value, DN):
         rdns = value._copy_rdns()
     elif isinstance(value, (tuple, list, AVA)):
         ava = get_ava(value)
         rdns = [[ava]]
     elif isinstance(value, RDN):
         rdns = [value.to_openldap()]
     else:
         raise TypeError("must be str, unicode, tuple, or RDN or DN, got %s instead" %
                         type(value))
     return rdns
예제 #33
0
 def _rdns_from_value(self, value):
     if isinstance(value, six.string_types):
         try:
             if isinstance(value, six.text_type):
                 value = val_encode(value)
             rdns = str2dn(value)
         except DECODING_ERROR:
             raise ValueError("malformed RDN string = \"%s\"" % value)
         for rdn in rdns:
             sort_avas(rdn)
     elif isinstance(value, DN):
         rdns = value._copy_rdns()
     elif isinstance(value, (tuple, list, AVA)):
         ava = get_ava(value)
         rdns = [[ava]]
     elif isinstance(value, RDN):
         rdns = [value.to_openldap()]
     else:
         raise TypeError(
             "must be str, unicode, tuple, or RDN or DN, got %s instead" %
             type(value))
     return rdns
def check_correct_domain_admin():
    """Check domain administrator saved for ucs-test and
	correct if needed"""

    print('=== Checking / Correcting ucs-test domain administrator ===')

    ucr.load()
    ucr_domain_admin = ucr['tests/domainadmin/account']
    if ucr_domain_admin:
        ucr_domain_admin_parts = str2dn(ucr_domain_admin)
        if ucr_domain_admin_parts[0][0][1] != options.domain_admin:
            ucr_domain_admin_parts[0][0] = ('uid', options.domain_admin,
                                            ucr_domain_admin_parts[0][0][2])
            ucr['tests/domainadmin/account'] = dn2str(ucr_domain_admin_parts)
    else:
        print(
            "=== tests/domainadmin/account is not set, trying to create it ==="
        )
        ucr['tests/domainadmin/account'] = 'uid=%s,cn=users,%s' % (
            escape_dn_chars(options.domain_admin), ucr['ldap/base'])

    ucr.save()
예제 #35
0
    def _get_single_entry(self, *args, **kwargs):
        dn = kwargs.pop('dn', None)
        if dn:
            normalized_dn = lambda x: dn2str(str2dn(x))
            assert normalized_dn(dn).lower().endswith(
                normalized_dn(self.model.base).lower())
            self.search.scope = ldap.SCOPE_BASE
            self.search.base = dn
            if not args and not kwargs:
                self.search.filter = filterbuilder(objectclass__ne=None)
            else:
                self.search.filter = filterbuilder(*args, **kwargs)
        else:
            self.search.filter = filterbuilder(*args, **kwargs)

        self._evaluate()
        if not self.results:
            return None
        if len(self.results) > 1:
            raise ValueError("Multiple Results Found")
        else:
            dn, entry = self.results.pop()
            return self._map_to_model(dn, entry)
예제 #36
0
파일: proxy.py 프로젝트: peuter/gosa
 def get_parent_dn(self, dn=None):
     if not dn:
         dn = self.__base.dn
     return dn2str(str2dn(dn)[1:])
예제 #37
0
파일: proxy.py 프로젝트: lhm-limux/clacks
 def get_parent_dn(self):
     return dn2str(str2dn(self.__base.dn.encode('utf-8'))[1:]).decode('utf-8')
예제 #38
0
파일: proxy.py 프로젝트: lhm-limux/clacks
    def move(self, new_base, recursive=False):
        """
        Moves the currently proxied object to another base
        """

        # Check ACLs
        # to move an object we need the 'w' (write) right on the virtual attribute base,
        # the d (delete) right for the complete source object and at least the c (create)
        # right on the target base.
        if self.__current_user is not None:

            # Prepare ACL results
            topic_user = "******" % (self.__env.domain, self.__base_type)
            topic_base = "%s.objects.%s.attributes.base" % (self.__env.domain, self.__base_type)
            allowed_base_mod = self.__acl_resolver.check(self.__current_user, topic_base, "w", base=self.dn)
            allowed_delete = self.__acl_resolver.check(self.__current_user, topic_user, "d", base=self.dn)
            allowed_create = self.__acl_resolver.check(self.__current_user, topic_user, "c", base=new_base)

            # Check for 'w' access to attribute base
            if not allowed_base_mod:
                self.__log.debug("user '%s' has insufficient permissions to move %s, required is %s:%s on %s" % (
                    self.__current_user, self.__base.dn, topic_base, "w", self.__base.dn))
                raise ACLException(C.make_error('PERMISSION_MOVE', source=self.__base.dn, target=new_base))

            # Check for 'd' permission on the source object
            if not allowed_delete:
                self.__log.debug("user '%s' has insufficient permissions to move %s, required is %s:%s on %s" % (
                    self.__current_user, self.__base.dn, topic_user, "d", self.__base.dn))
                raise ACLException(C.make_error('PERMISSION_MOVE', source=self.__base.dn, target=new_base))

            # Check for 'c' permission on the source object
            if not allowed_create:
                self.__log.debug("user '%s' has insufficient permissions to move %s, required is %s:%s on %s" % (
                    self.__current_user, self.__base.dn, topic_user, "c", new_base))
                raise ACLException(C.make_error('PERMISSION_MOVE', source=self.__base.dn, target=new_base))

        zope.event.notify(ObjectChanged("pre object move", self.__base))

        if recursive:
            old_base = self.__base.dn

            try:
                child_new_base = dn2str([str2dn(self.__base.dn.encode('utf-8'))[0]]).decode('utf-8') + "," + new_base

                # Get primary backend of the object to be moved
                p_backend = getattr(self.__base, '_backend')

                # Traverse tree and find different backends
                foreign_backends = {}
                index = PluginRegistry.getInstance("ObjectIndex")
                children = index.search({"dn": re.compile("^(.*,)?" + re.escape(self.__base.dn) + "$")},
                    {'dn': 1, '_type': 1})

                # Note all elements with different backends
                for v in children:
                    cdn = v['dn']
                    ctype = v['_type']
                    cback = self.__factory.getObjectTypes()[ctype]['backend']
                    if cback != p_backend:
                        if not cback in foreign_backends:
                            foreign_backends = []
                        foreign_backends[cback].append(cdn.decode('utf-8'))

                # Only keep the first per backend that is close to the root
                root_elements = {}
                for fbe, fdns in foreign_backends.items():
                    fdns.sort(key=len)
                    root_elements[fbe] = fdns[0]

                # Move base object
                self.__base.move(new_base)

                # Move additional backends if needed
                for fbe, fdn in root_elements.items():

                    # Get new base of child
                    new_child_dn = fdn[:len(fdn) - len(old_base)] + child_new_base
                    new_child_base = dn2str(str2dn(new_child_dn.encode('utf-8'))[1:]).decode('utf-8')

                    # Select objects with different base and trigger a move, the
                    # primary backend move will be triggered and do a recursive
                    # move for that backend.
                    obj = self.__factory.getObject(children[fdn], fdn)
                    obj.move(new_child_base)

                # Update all DN references
                # Emit 'post move' events
                for cdn, ctype in children.items():

                    # Don't handle objects that already have been moved
                    if cdn in root_elements.values():
                        continue

                    # These objects have been moved automatically. Open
                    # them and let them do a simulated move to update
                    # their refs.
                    new_cdn = cdn[:len(cdn) - len(old_base)] + child_new_base
                    obj = self.__factory.getObject(ctype, new_cdn)
                    obj.simulate_move(cdn)

                zope.event.notify(ObjectChanged("post object move", self.__base))
                return True

            except Exception as e:
                from traceback import print_exc
                print_exc()
                self.__log.error("moving object '%s' from '%s' to '%s' failed: %s" % (self.__base.uuid, old_base, new_base, str(e)))
                return False

        else:
            # Test if we've children
            if len(self.__factory.getObjectChildren(self.__base.dn)):
                raise ProxyException(C.make_error('OBJECT_HAS_CHILDREN', target=self.__base.dn))

        res = self.__base.move(new_base)
        if res:
            zope.event.notify(ObjectChanged("post object move", self.__base))

        return res
	def _write_json(self):
		self.logger.info('Gathering AppAttributes...')
		locales = [locale.split('.')[0] for locale in self.ucr.get('locale', 'en_US.UTF-8:UTF-8').split() if '.' in locale]
		if 'en_US' not in locales:
			locales.append('en_US')
		cache = {}
		custom_attributes_base = 'cn=custom attributes,cn=univention,%s' % self.ucr.get('ldap/base')
		for current_locale in locales:
			locale_cache = cache[current_locale] = {}
			app_objs = search_objects('appcenter/app', self.lo, self.po)
			apps = {}
			for app_obj in app_objs:
				app_version = app_obj['version']
				app_id = app_obj['id'][:-len(app_version) - 1]
				app = AllApps().find(app_id, app_version=app_version)
				if app:
					if app.id in apps:
						if apps[app.id] > app:
							continue
					apps[app.id] = app
			for app in apps.itervalues():
				for attribute in app.umc_options_attributes:
					attribute, option_name = (attribute.split(':', 1) * 2)[:2]
					objs = search_objects('settings/extended_attribute', self.lo, self.po, custom_attributes_base, CLIName=attribute)
					for obj in objs:
						for module in obj['module']:
							if search_objects('settings/extended_options', self.lo, self.po, custom_attributes_base, objectClass=obj['objectClass'], module=module):
								# a newer version of the App is installed that uses the
								# superior settings/extended_option
								continue
							if module not in locale_cache:
								locale_cache[module] = {}
							option_def = locale_cache[module]
							group_name = obj['groupName']
							for loc, desc in obj['translationGroupName']:
								if loc == current_locale:
									group_name = desc
									break
							tab_name = obj['tabName']
							for loc, desc in obj['translationTabName']:
								if loc == current_locale:
									tab_name = desc
									break
							short_description = obj['shortDescription']
							for loc, desc in obj['translationShortDescription']:
								if loc == current_locale:
									short_description = desc
									break
							if obj['syntax'] == 'boolean':
								boolean_values = ['1', '0']
							elif obj['syntax'] in ['TrueFalseUp', 'TrueFalseUpper']:
								boolean_values = ['TRUE', 'FALSE']
							elif obj['syntax'] == 'TrueFalse':
								boolean_values = ['true', 'false']
							elif obj['syntax'] == 'OkOrNot':
								boolean_values = ['OK', 'Not']
							else:
								continue
							default = int(obj['default'] == boolean_values[0])
							attributes = []
							layout = []
							option_def[option_name] = {
								'label': group_name or tab_name,
								'description': short_description,
								'default': default,
								'boolean_values': boolean_values,
								'attributes': attributes,
								'layout': layout,
								'attribute_name': obj['CLIName'],
							}
							base = dn2str(str2dn(obj.dn)[1:])
							for _obj in search_objects('settings/extended_attribute', self.lo, self.po, base, univentionUDMPropertyModule=module):
								if obj.dn == _obj.dn:
									continue
								if _obj['disableUDMWeb'] == '1':
									continue
								attributes.append(_obj['CLIName'])
								if _obj['tabAdvanced']:
									group_name = _obj['tabName']
									for loc, desc in _obj['translationTabName']:
										if loc == current_locale:
											group_name = desc
											break
									group_position = _obj['tabPosition']
								else:
									group_name = _obj['groupName']
									for loc, desc in _obj['translationGroupName']:
										if loc == current_locale:
											group_name = desc
											break
									group_position = _obj['groupPosition']
								for group in layout:
									if group['label'] == group_name:
										break
								else:
									group = {
										'label': group_name,
										'description': '',
										'advanced': False,
										'is_app_tab': False,
										'layout': [],
										'unsorted': [],
									}
									layout.append(group)
								group_layout = group['layout']
								if group_position:
									group_position = int(group_position)
									while len(group_layout) < group_position:
										group_layout.append([])
									group_layout[group_position - 1].append(_obj['CLIName'])
								else:
									group['unsorted'].append(_obj['CLIName'])
							for group in layout:
								unsorted = group.pop('unsorted')
								if unsorted:
									group['layout'].append(unsorted)
		self.logger.info('Finished')
		tmp_fname = FNAME + '.tmp'
		with open(tmp_fname, 'w') as fd:
			json.dump(cache, fd)
		shutil.move(tmp_fname, FNAME)
예제 #40
0
파일: proxy.py 프로젝트: lhm-limux/clacks
    def commit(self):

        # Check create permissions
        if self.__base_mode == "create":
            topic = "%s.objects.%s" % (self.__env.domain, self.__base_type)
            if self.__current_user is not None and not self.__acl_resolver.check(self.__current_user, topic, "c", base=self.dn):
                self.__log.debug("user '%s' has insufficient permissions to create %s, required is %s:%s" % (
                    self.__current_user, self.__base.dn, topic, 'c'))
                raise ACLException(C.make_error('PERMISSION_CREATE', target=self.__base.dn))

        zope.event.notify(ObjectChanged("pre object %s" % self.__base_mode, self.__base))

        # Gather information about children
        old_base = self.__base.dn

        # Get primary backend of the object to be moved
        p_backend = getattr(self.__base, '_backend')

        # Traverse tree and find different backends
        foreign_backends = {}
        index = PluginRegistry.getInstance("ObjectIndex")
        children = index.search({"dn": re.compile("^(.*,)?" + re.escape(self.__base.dn) + "$")},
            {'dn': 1, '_type': 1})

        # Note all elements with different backends
        for v in children:
            cdn = v['dn']
            ctype = v['_type']

            cback = self.__factory.getObjectTypes()[ctype]['backend']
            if cback != p_backend:
                if not cback in foreign_backends:
                    foreign_backends[cback] = []
                foreign_backends[cback].append(cdn)

        # Only keep the first per backend that is close to the root
        root_elements = {}
        for fbe, fdns in foreign_backends.items():
            fdns.sort(key=len)
            root_elements[fbe] = fdns[0]

        # Handle retracts
        for idx in self.__retractions.keys():
            if self.__initial_extension_state[idx]:
                self.__retractions[idx].retract()
            del self.__retractions[idx]

        # Check each extension before trying to save them
        check_props = self.__base.check()
        for extension in [ext for ext in self.__extensions.values() if ext]:
            check_props.update(extension.check(check_props))

        # Handle commits
        save_props = self.__base.commit()
        for extension in [ext for ext in self.__extensions.values() if ext]:

            # Populate the base uuid to the extensions
            if extension.uuid and extension.uuid != self.__base.uuid:
                raise ProxyException(C.make_error('OBJECT_UUID_MISMATCH', b_uuid=self.__base.uuid, e_uuid=extension.uuid))
            if not extension.uuid:
                extension.uuid = self.__base.uuid
            extension.dn = self.__base.dn
            save_props.update(extension.commit(save_props))

        # Skip further actions if we're in create mode
        if self.__base_mode == "create":
            pass

        # Did the commit result in a move?
        elif self.dn != self.__base.dn:

            if children:
                # Move additional backends if needed
                for fbe, fdn in root_elements.items():

                    # Get new base of child
                    new_child_dn = fdn[:len(fdn) - len(old_base)] + self.__base.dn
                    new_child_base = dn2str(str2dn(new_child_dn.encode('utf-8'))[1:]).decode('utf-8')

                    # Select objects with different base and trigger a move, the
                    # primary backend move will be triggered and do a recursive
                    # move for that backend.
                    obj = self.__factory.getObject(children[fdn], fdn)
                    obj.move(new_child_base)

                # Update all DN references
                # Emit 'post move' events
                for entry in children:
                    cdn = entry['dn']
                    ctype = entry['_type']

                    # Don't handle objects that already have been moved
                    if cdn in root_elements.values():
                        continue

                    # These objects have been moved automatically. Open
                    # them and let them do a simulated move to update
                    # their refs.
                    new_cdn = cdn[:len(cdn) - len(old_base)] + self.__base.dn
                    obj = self.__factory.getObject(ctype, new_cdn)
                    obj.simulate_move(cdn)

            self.dn = self.__base.dn

            zope.event.notify(ObjectChanged("post object move", self.__base))

        zope.event.notify(ObjectChanged("post object %s" % self.__base_mode, self.__base))
    def _apply(self):
        # Create the base domain object
        domain = Domain(self._instance, dn=self._basedn)
        # Explode the dn to get the first bit.
        avas = dn.str2dn(self._basedn)
        dc_ava = avas[0][0][1]

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

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

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

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

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

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

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

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

        # Create the permission groups required for the acis
        permissions = Groups(self._instance, self._basedn, rdn='ou=permissions')
        permissions.create(properties={
            'cn': 'group_admin',
        })
        permissions.create(properties={
            'cn': 'group_modify',
        })
        permissions.create(properties={
            'cn': 'user_admin',
        })
        permissions.create(properties={
            'cn': 'user_modify',
        })
        permissions.create(properties={
            'cn': 'user_passwd_reset',
        })
        permissions.create(properties={
            'cn': 'user_private_read',
        })
예제 #42
0
    def modify(self,
               dn,
               mod_type=None,
               attrs=None,
               bind_dn=None,
               bind_pwd=None):
        """ Modify a record
        """
        self._complainIfReadOnly()

        unescaped_dn = self._encode_incoming(dn)
        dn = escape_dn(unescaped_dn, self.ldap_encoding)
        res = self.search(base=unescaped_dn,
                          scope=ldap.SCOPE_BASE,
                          bind_dn=bind_dn,
                          bind_pwd=bind_pwd,
                          raw=True)
        attrs = attrs and attrs or {}
        cur_rec = res['results'][0]
        mod_list = []

        for key, values in list(attrs.items()):

            if key.endswith(';binary'):
                key = key[:-7]
                is_binary = True
            else:
                is_binary = False

            if not isinstance(key, six.binary_type):
                key = self._encode_incoming(key)

            if not is_binary:
                if isinstance(values, six.string_types):
                    values = [
                        self._encode_incoming(x) for x in values.split(';')
                    ]
                else:
                    values = [self._encode_incoming(x) for x in values]

            if isinstance(key, six.text_type):
                key = self._encode_incoming(key)

            if mod_type is None:
                if key not in cur_rec and values != [b'']:
                    mod_list.append((ldap.MOD_ADD, key, values))
                elif cur_rec.get(key, [b'']) != values and \
                        values not in ([b''], []):
                    mod_list.append((ldap.MOD_REPLACE, key, values))
                elif key in cur_rec and values in ([b''], []):
                    mod_list.append((ldap.MOD_DELETE, key, None))
            elif mod_type in (ldap.MOD_ADD, ldap.MOD_DELETE) and \
                    values == [b'']:
                continue
            elif mod_type == ldap.MOD_DELETE and \
                    set(values).difference(set(cur_rec.get(key, []))):
                continue
            else:
                mod_list.append((mod_type, key, values))

            attrs[key] = values

        try:
            connection = self.connect(bind_dn=bind_dn, bind_pwd=bind_pwd)

            dn_parts = str2dn(dn)
            clean_dn_parts = []
            for dn_part in dn_parts:
                for (attr_name, attr_val, flag) in dn_part:
                    if isinstance(attr_name, six.text_type):
                        attr_name = self._encode_incoming(attr_name)
                    if isinstance(attr_val, six.text_type):
                        attr_val = self._encode_incoming(attr_val)
                    clean_dn_parts.append([(attr_name, attr_val, flag)])

            rdn_attr = clean_dn_parts[0][0][0]
            raw_rdn = attrs.get(rdn_attr, '')
            if isinstance(raw_rdn, six.string_types):
                raw_rdn = [raw_rdn]
            new_rdn = raw_rdn[0]

            if new_rdn:
                rdn_value = self._encode_incoming(new_rdn)
                if rdn_value != cur_rec.get(rdn_attr)[0]:
                    clean_dn_parts[0] = [(rdn_attr, rdn_value, 1)]
                    dn_parts[0] = [(rdn_attr, raw_rdn[0], 1)]
                    raw_utf8_rdn = rdn_attr + b'=' + rdn_value
                    new_rdn = escape_dn(raw_utf8_rdn, self.ldap_encoding)
                    connection.modrdn_s(dn, new_rdn)
                    dn = dn2str(clean_dn_parts)

            if mod_list:
                connection.modify_s(dn, mod_list)
            else:
                debug_msg = 'Nothing to modify: %s' % dn
                self.logger().debug(debug_msg)

        except ldap.REFERRAL as e:
            connection = self._handle_referral(e)
            connection.modify_s(dn, mod_list)
예제 #43
0
파일: utils.py 프로젝트: counsyl/baya
def group_names(group_dn_list):
    return {str2dn(group)[0][0][1].lower() for group in group_dn_list}
예제 #44
0
def canonical_dn(dn):
    return dn2str(str2dn(dn))
예제 #45
0
파일: ldap.py 프로젝트: doyousoft/pyvac
 def _extract_country(self, user_dn):
     """ Get country from a user dn """
     for rdn in dn.str2dn(user_dn):
         rdn = rdn[0]
         if rdn[0] == self.country_attr:
             return rdn[1]
예제 #46
0
파일: ldap.py 프로젝트: doyousoft/pyvac
 def _extract_cn(self, user_dn):
     """ Get cn from a user dn """
     for rdn in dn.str2dn(user_dn):
         rdn = rdn[0]
         if rdn[0] == self.login_attr:
             return rdn[1]
예제 #47
0
    def modify(self, dn, mod_type=None, attrs=None, bind_dn=None, bind_pwd=None):
        """ Modify a record 
        """
        self._complainIfReadOnly()

        unescaped_dn = self._encode_incoming(dn)
        dn = escape_dn(unescaped_dn)
        res = self.search( base=unescaped_dn
                         , scope=ldap.SCOPE_BASE
                         , bind_dn=bind_dn
                         , bind_pwd=bind_pwd
                         , raw=True
                         )
        attrs = attrs and attrs or {}
        cur_rec = res['results'][0]
        mod_list = []

        for key, values in attrs.items():

            if key.endswith(';binary'):
                key = key[:-7]
            elif isinstance(values, basestring):
                values = [self._encode_incoming(x) for x in values.split(';')]
            else:
                values = [self._encode_incoming(x) for x in values]

            if mod_type is None:
                if not cur_rec.has_key(key) and values != ['']:
                    mod_list.append((ldap.MOD_ADD, key, values))
                elif cur_rec.get(key,['']) != values and values not in ([''],[]):
                    mod_list.append((ldap.MOD_REPLACE, key, values))
                elif cur_rec.has_key(key) and values in ([''], []):
                    mod_list.append((ldap.MOD_DELETE, key, None))
            elif mod_type in (ldap.MOD_ADD, ldap.MOD_DELETE) and values == ['']:
                continue
            elif ( mod_type == ldap.MOD_DELETE and
                   set(values).difference(set(cur_rec.get(key, []))) ):
                continue
            else:
                mod_list.append((mod_type, key, values))

        try:
            connection = self.connect(bind_dn=bind_dn, bind_pwd=bind_pwd)

            dn_parts = str2dn(dn)
            rdn = dn_parts[0]
            rdn_attr = rdn[0][0]
            raw_rdn = attrs.get(rdn_attr, '')
            if isinstance(raw_rdn, basestring):
                raw_rdn = [raw_rdn]
            new_rdn = raw_rdn[0]

            if new_rdn:
                rdn_value = self._encode_incoming(new_rdn)
                if rdn_value != cur_rec.get(rdn_attr)[0]:
                    dn_parts[0] = [(rdn_attr, rdn_value, 1)]
                    raw_utf8_rdn = rdn_attr + '=' + rdn_value
                    new_rdn = escape_dn(raw_utf8_rdn)
                    connection.modrdn_s(dn, new_rdn)
                    dn = dn2str(dn_parts)

            if mod_list:
                connection.modify_s(dn, mod_list)
            else:
                debug_msg = 'Nothing to modify: %s' % dn
                self.logger().debug(debug_msg)

        except ldap.REFERRAL, e:
            connection = self._handle_referral(e)
            connection.modify_s(dn, mod_list)
예제 #48
0
	def save(self):
		"""
		Save object to LDAP.

		:return: self
		:rtype: GenericObject
		:raises univention.udm.exceptions.MoveError: when a move operation fails
		"""
		if self._deleted:
			raise DeletedError('{} has been deleted.'.format(self), dn=self.dn, module_name=self._udm_module.name)
		if not self._fresh:
			ud.warn('Saving stale UDM object instance')
		self._copy_to_udm_obj()
		if self.dn:
			if self._old_position and self._old_position != self.position:
				new_dn_li = [str2dn(self._orig_udm_object.dn)[0]]
				new_dn_li.extend(str2dn(self.position))
				new_dn = dn2str(new_dn_li)
				ud.process('Moving {!r} object {!r} to {!r}'.format(self._udm_module.name, self.dn, new_dn))
				try:
					self.dn = self._orig_udm_object.move(new_dn)
				except univention.admin.uexceptions.invalidOperation as exc:
					raise MoveError, MoveError(
						'Moving {!r} object is not supported ({}).'.format(self._udm_module.name, exc),
						dn=self.dn, module_name=self._udm_module.name
					), sys.exc_info()[2]
				except (univention.admin.uexceptions.base, ldap.error) as exc:
					raise MoveError, MoveError(
						'Error moving {!r} object from {!r} to {!r}: {}'.format(
							self._udm_module.name, self.dn, self.position, exc
						), dn=self.dn, module_name=self._udm_module.name
					), sys.exc_info()[2]
				assert self.dn == self._orig_udm_object.dn
				self.position = self._lo.parentDn(self.dn)
				self._old_position = self.position
				self._orig_udm_object.position.setDn(self.position)
			try:
				self.dn = self._orig_udm_object.modify()
			except univention.admin.uexceptions.base as exc:
				raise ModifyError, ModifyError(
					'Error saving {!r} object at {!r}: {} ({})'.format(
						self._udm_module.name, self.dn, exc.message, exc
					), dn=self.dn, module_name=self._udm_module.name
				), sys.exc_info()[2]
			ud.process('Modified {!r} object {!r}'.format(self._udm_module.name, self.dn))
		else:
			try:
				self.dn = self._orig_udm_object.create()
			except ldap.INVALID_DN_SYNTAX as exc:
				raise CreateError, CreateError(
					'Error creating {!r} object: {} ({})'.format(
						self._udm_module.name, exc.message, exc
					), module_name=self._udm_module.name
				), sys.exc_info()[2]
			except univention.admin.uexceptions.base as exc:
				raise CreateError, CreateError(
					'Error creating {!r} object: {} ({})'.format(
						self._udm_module.name, exc.message, exc
					), module_name=self._udm_module.name
				), sys.exc_info()[2]
			ud.process('Created {!r} object {!r}'.format(self._udm_module.name, self.dn))

		assert self.dn == self._orig_udm_object.dn
		assert self.position == self._lo.parentDn(self.dn)
		self._fresh = False
		if self._udm_module.meta.auto_reload:
			self.reload()
		return self
예제 #49
0
파일: utils.py 프로젝트: kreneskyp/baya
def group_names(group_dn_list):
    return {str2dn(group)[0][0][1].lower() for group in group_dn_list}
예제 #50
0
def is_immediate_subdn(subdn, dn):
    subdn_comps = str2dn(subdn)
    dn_comps = str2dn(dn)
    return len(subdn_comps) > 0 and subdn_comps[1:] == dn_comps
예제 #51
0
def _rdn(_dn):
    return str2dn(_dn)[0][0][1]
예제 #52
0
파일: proxy.py 프로젝트: gonicus/clacks
 def get_parent_dn(self, dn=None):
     if not dn:
         dn = self.__base.dn
     return dn2str(str2dn(dn.encode('utf-8'))[1:]).decode('utf-8')