Beispiel #1
0
 def create_container(self):
     dn = decode_dn(self.request.params.get('dn', ''))
     localizer = get_localizer(self.request)
     if not dn:
         message = localizer.translate(
             _('no_container_dn_defined', 'No container DN defined.'))
         raise Exception(message)
     if not dn.startswith('ou='):
         message = localizer.translate(
             _('expected_ou_as_rdn', "Expected 'ou' as RDN Attribute."))
         raise Exception(message)
     props = self.model.parent['ugm_server'].ldap_props
     try:
         parent_dn = ','.join(explode_dn(dn)[1:])
     except Exception:
         message = localizer.translate(_('invalid_dn', 'Invalid DN.'))
         raise Exception(message)
     rdn = explode_dn(dn)[0]
     node = LDAPNode(parent_dn, props)
     if node is None:
         message = localizer.translate(
             _('parent_not_found', "Parent not found. Can't continue."))
         raise Exception(message)
     node[rdn] = LDAPNode()
     node[rdn].attrs['objectClass'] = ['organizationalUnit']
     node()
     self.model.invalidate()
     message = localizer.translate(
             _('created_principal_container',
               default="Created ${rdn}",
               mapping={'rdn': rdn}))
     return message
Beispiel #2
0
def queryNode(props, dn):
    """Query an ldap entry and return as LDAPNode.
    
    ``props``
        ``LDAPProps`` instance
    ``dn``
        DN of the node to query

    The difference to just LDAPNode(props=props, name=dn) is, that the node
    generated here will have only the rdn as its name, whereas LDAPNode() would
    generate a root node, with the full dn as its name.
    """
    containerdn = ','.join(explode_dn(dn)[1:])
    nodedn = explode_dn(dn)[0]
    container = LDAPNode(name=containerdn, props=props)
    return container.get(nodedn, None)
Beispiel #3
0
 def __iter__(self):
     if self.name is None:
         return
     cookie = ''
     while True:
         try:
             res = self.ldap_session.search(
                 scope=ONELEVEL,
                 baseDN=self.DN,
                 attrlist=[''],
                 page_size=self._page_size,
                 cookie=cookie
             )
         except NO_SUCH_OBJECT:
             # happens if not persisted yet
             res = list()
         if isinstance(res, tuple):
             res, cookie = res
         for dn, _ in res:
             key = ensure_text(explode_dn(dn)[0])
             # do not yield if node is supposed to be deleted
             if key not in self._deleted_children:
                 yield key
         if not cookie:
             break
     # also yield keys of children not persisted yet.
     for key in self._added_children:
         yield key
 def put(self, dn, entry):
     status = None
     try:
         stored_object = self.conn.search_s(dn, ldap.SCOPE_BASE)[0]
         mods = ldap.modlist.modifyModlist(stored_object[1], entry, self.ignore_attr_types)
         if mods:
             if self.debug:
                 logging.info("update: %s" % (dn))
                 logging.info(mods)
             if not self.dryrun:
                 self.conn.modify_s(dn, mods)
             status = 'update'
         #else:
         #    #if self.debug:
         #    #    print "no-change: %s" % (dn)    
         #    status = 'nochange'
     except ldap.NO_SUCH_OBJECT:
         mods = ldap.modlist.addModlist(entry)
         if self.debug:
             logging.info("add: %s" % (dn))
         if not self.dryrun:
             self.conn.add_s(dn, mods)
         status = 'add'
     self.seen[str(explode_dn(dn))] = True
     return status
 def __init__(self, conn, base, scope=ldap.SCOPE_ONELEVEL, dryrun=False, debug=False, ignore_attr_types=[]):
     self.conn   = conn
     self.base   = base
     self.scope  = scope
     self.dryrun = dryrun
     self.debug  = debug
     self.ignore_attr_types = ignore_attr_types
     self.seen = {}
     self.seen[str(explode_dn(base))] = True
Beispiel #6
0
 def create_container(self):
     dn = decode_dn(self.request.params.get('dn', ''))
     if not dn:
         raise Exception(u"No container DN defined.")
     if not dn.startswith('ou='):
         raise Exception(u"Expected 'ou' as RDN Attribute.")
     props = self.model.parent['ugm_server'].ldap_props
     try:
         parent_dn = ','.join(explode_dn(dn)[1:])
     except Exception:
         raise Exception(u"Invalid DN.")
     rdn = explode_dn(dn)[0]
     node = LDAPNode(parent_dn, props)
     if node is None:
         raise Exception(u"Parent not found. Can't continue.")
     node[rdn] = LDAPNode()
     node[rdn].attrs['objectClass'] = ['organizationalUnit']
     node()
     return u"Created '%s'" % rdn
 def purge(self):
     delete = []
     for dn, entry in self.conn.search_s(self.base, self.scope, attrlist=[]):
         if not self.seen.has_key(str(explode_dn(dn))):
             delete.append(dn)
     delete.sort(lambda a, b: cmp(''.join(list(reversed(list(a)))), ''.join(list(reversed(list(b))))), reverse=True)
     for dn in delete:
         if self.debug:
             logging.info("delete: %s" % (dn))
         if not self.dryrun:
             self.conn.delete_s(dn)
     return delete
Beispiel #8
0
 def _calculate_key(self, dn, attrs):
     if self._key_attr == 'rdn':
         # explode_dn is ldap world
         key = decode(explode_dn(encode(dn))[0])
     else:
         key = attrs[self._key_attr]
         if isinstance(key, list):
             if len(key) != 1:
                 raise KeyError(u"Expected one value for '%s' "+
                         u"not %s: '%s'." % \
                                 (self._key_attr, len(key), key))
             key = key[0]
     return key
Beispiel #9
0
 def _calculate_key(self, dn, attrs):
     if self._key_attr == 'rdn':
         # explode_dn is ldap world
         key = explode_dn(encode(dn))[0]
     else:
         key = attrs[self._key_attr]
         if isinstance(key, list):
             if len(key) != 1:
                 msg = u"Expected one value for '%s' " % (self._key_attr,)
                 msg += u"not %s: '%s'." % (len(key), key)
                 raise KeyError(msg)
             key = key[0]
     return decode(key)
Beispiel #10
0
    def create_container(self):
        """Create LDAP container by dn.

        Currently this only supports ou container type.

        XXX: Do we need to support c and dc?
        XXX: Should we create parents as well if missing?
        """
        dn = self.container_dn
        if not dn:
            raise LDAPContainerError(
                _('no_container_dn_defined',
                  default='No container DN defined.'))
        if not dn.startswith('ou='):
            raise LDAPContainerError(
                _('expected_ou_as_rdn',
                  default="Expected 'ou' as RDN Attribute."))
        props = self.server_settings.ldap_props
        try:
            parent_dn = ','.join(explode_dn(dn)[1:])
        except Exception:
            raise LDAPContainerError(_('invalid_dn', default='Invalid DN.'))
        rdn = explode_dn(dn)[0]
        parent = LDAPNode(parent_dn, props)
        if not parent.exists:
            raise LDAPContainerError(
                _('parent_not_found',
                  default="Parent not found. Can't continue."))
        parent[rdn] = LDAPNode()
        parent[rdn].attrs['objectClass'] = ['organizationalUnit']
        parent()
        self.invalidate()
        message = _('created_principal_container',
                    default="Created ${rdn}",
                    mapping={'rdn': rdn})
        return message
Beispiel #11
0
 def node_by_dn(self, dn, strict=False):
     """Return node from tree by DN.
     """
     root = node = self.root
     base_dn = root.name
     if not dn.endswith(base_dn):
         raise ValueError(u'Invalid base DN')
     dn = dn[:len(dn) - len(base_dn)].strip(',')
     for rdn in reversed(explode_dn(encode(dn))):
         try:
             node = node[rdn]
         except KeyError:
             if strict:
                 raise ValueError(u'Tree contains no node by given DN. '
                                  u'Failed at RDN {}'.format(rdn))
             return None
     return node
Beispiel #12
0
 def node_by_dn(self, dn, strict=False):
     """Return node from tree by DN.
     """
     root = node = self.root
     base_dn = root.name
     if not dn.endswith(base_dn):
         raise ValueError(u'Invalid base DN')
     dn = dn[:len(dn) - len(base_dn)].strip(',')
     for rdn in reversed(explode_dn(encode(dn))):
         try:
             node = node[rdn]
         except KeyError:
             if strict:
                 raise ValueError(u'Tree contains no node by given DN. '
                                  u'Failed at RDN {}'.format(rdn))
             return None
     return node
Beispiel #13
0
 def search(self, queryFilter=None, criteria=None, attrlist=None,
            relation=None, relation_node=None, exact_match=False,
            or_search=False, or_keys=None, or_values=None,
            page_size=None, cookie=None, get_nodes=False):
     attrset = set(attrlist or [])
     attrset.discard('dn')
     attrset.discard('rdn')
     # Create queryFilter from all filter definitions
     # filter for this search ANDed with the default filters defined on self
     search_filter = LDAPFilter(queryFilter)
     search_filter &= LDAPDictFilter(
         criteria,
         or_search=or_search,
         or_keys=or_keys,
         or_values=or_values
     )
     _filter = LDAPFilter(self.search_filter)
     _filter &= LDAPDictFilter(self.search_criteria)
     _filter &= search_filter
     # relation filters
     if relation_node is None:
         relation_node = self
     relations = [relation, self.search_relation]
     for relation in relations:
         if not relation:
             continue
         if isinstance(relation, LDAPRelationFilter):
             _filter &= relation
         else:
             _filter &= LDAPRelationFilter(relation_node, relation)
     # perform the backend search
     logger.debug("LDAP search with filter: \n{0}".format(_filter))
     matches = self.ldap_session.search(
         str(_filter),
         self.search_scope,
         baseDN=self.DN,
         force_reload=self._reload,
         attrlist=list(attrset),
         page_size=page_size,
         cookie=cookie
     )
     if type(matches) is tuple:
         matches, cookie = matches
     # check exact match
     if exact_match and len(matches) > 1:
         raise ValueError(u"Exact match asked but result not unique")
     if exact_match and len(matches) == 0:
         raise ValueError(u"Exact match asked but result length is zero")
     # extract key and desired attributes
     res = []
     for dn, attrs in matches:
         dn = decode(dn)
         if attrlist is not None:
             resattr = dict()
             for k, v in six.iteritems(attrs):
                 if k in attrlist:
                     # Check binary binary attribute directly from root
                     # data to avoid initing attrs for a simple search.
                     if k in self.root._binary_attributes:
                         resattr[decode(k)] = v
                     else:
                         resattr[decode(k)] = decode(v)
             if 'dn' in attrlist:
                 resattr[u'dn'] = dn
             if 'rdn' in attrlist:
                 rdn = explode_dn(dn)[0]
                 resattr[u'rdn'] = decode(rdn)
             if get_nodes:
                 res.append((self.node_by_dn(dn, strict=True), resattr))
             else:
                 res.append((dn, resattr))
         else:
             if get_nodes:
                 res.append(self.node_by_dn(dn, strict=True))
             else:
                 res.append(dn)
     if cookie is not None:
         return (res, cookie)
     return res