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
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)
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
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
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
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)
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
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
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