Example #1
0
class BaseLDAPEntry(WireStrAlias):
    dn = None
    _object_class_keys = set(get_strings('objectClass'))
    _object_class_lower_keys = set(get_strings('objectclass'))
    _user_password_keys = set(get_strings('userPassword'))

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes = InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k, vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k, vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        raise KeyError(key)

    def get(self, key, default=None):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        return default

    def has_key(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return True
        return False

    def __contains__(self, key):
        return self.has_key(key)

    def __iter__(self):
        for key in self._attributes.iterkeys():
            yield key

    def keys(self):
        a = []
        for key in self._object_class_keys:
            if key in self._attributes:
                a.append(key)
        l = list(self._attributes.keys())
        l.sort(key=to_bytes)
        for key in l:
            if key.lower() not in self._object_class_lower_keys:
                a.append(key)
        return a

    def items(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            if objectClasses:
                a.append((key, objectClasses))

        l = list(self._attributes.items())
        l.sort(key=lambda x: to_bytes(x[0]))
        for key, values in l:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))

        return a

    def toWire(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            a.append((key, objectClasses))

        items_gen = ((key, self[key]) for key in self)
        items = sorted(items_gen, key=lambda x: to_bytes(x[0]))
        for key, values in items:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn.getText(), a)

    def getLDIF(self):
        return self.toWire().decode('utf-8')

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return NotImplemented
        if self.dn != other.dn:
            return 0

        my = sorted((key for key in self), key=to_bytes)
        its = sorted((key for key in other), key=to_bytes)
        if my != its:
            return 0
        for key in my:
            myAttr = self[key]
            itsAttr = other[key]
            if myAttr != itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self == other

    def __len__(self):
        return len(self.keys())

    def __bool__(self):
        return True

    def __nonzero__(self):
        return self.__bool__()

    def __repr__(self):
        keys = sorted((key for key in self), key=to_bytes)
        a = []
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes = ', '.join(a)
        dn = to_bytes(self.dn.getText()) if six.PY2 else self.dn.getText()
        return '%s(%s, {%s})' % (self.__class__.__name__, repr(dn), attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = set(key for key in self)
        otherKeys = set(key for key in other)

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort(key=to_bytes)  # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort(key=to_bytes)  # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort(key=to_bytes)  # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        password = to_bytes(password)
        for key in self._user_password_keys:
            for digest in self.get(key, ()):
                digest = to_bytes(digest)
                if digest.startswith(b'{SSHA}'):
                    raw = base64.decodestring(digest[len(b'{SSHA}'):])
                    salt = raw[20:]
                    got = sshaDigest(password, salt)
                    if got == digest:
                        return self
                else:
                    # Plaintext
                    if digest == password:
                        return self
        raise ldaperrors.LDAPInvalidCredentials()

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        # FIXME:https://github.com/twisted/ldaptor/issues/101
        # The hash should take into consideration any attribute used to
        # decide the equality.
        return hash(self.dn)
Example #2
0
class BaseLDAPEntry(object):
    implements(interfaces.ILDAPEntry)
    dn = None

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes=InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k,vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k,vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        return self._attributes[key]

    def get(self, key, default=None):
        return self._attributes.get(key, default)

    def has_key(self, key):
        return key in self._attributes

    def __contains__(self, key):
        return self.has_key(key)

    def keys(self):
        a = []
        if self.get('objectClass'):
            a.append('objectClass')
        l=list(self._attributes.keys())
        l.sort()
        for key in l:
            if key.lower() != 'objectclass':
                a.append(key)
        return a

    def items(self):
        a=[]
        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        if objectClasses:
            a.append(('objectClass', objectClasses))

        l=list(self._attributes.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))

        return a

    def __str__(self):
        a=[]

        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        a.append(('objectClass', objectClasses))

        l=list(self.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn, a)

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return 0
        if self.dn != other.dn:
            return 0

        my=self.keys()
        my.sort()
        its=other.keys()
        its.sort()
        if my!=its:
            return 0
        for key in my:
            myAttr=self[key]
            itsAttr=other[key]
            if myAttr!=itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self==other

    def __len__(self):
        return len(self.keys())

    def __nonzero__(self):
        return True

    def __repr__(self):
        x={}
        for key in self.keys():
            x[key]=self[key]
        keys=self.keys()
        keys.sort()
        a=[]
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes=', '.join(a)
        return '%s(%s, {%s})' % (
            self.__class__.__name__,
            repr(str(self.dn)),
            attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = set(self.keys())
        otherKeys = set(other.keys())

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort() # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort() # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort() # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort() # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort() # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        for digest in self.get('userPassword', ()):
            if digest.startswith('{SSHA}'):
                raw = base64.decodestring(digest[len('{SSHA}'):])
                salt = raw[20:]
                got = sshaDigest(password, salt)
                if got == digest:
                    return self
        raise ldaperrors.LDAPInvalidCredentials

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        return hash(self.dn)
Example #3
0
class BaseLDAPEntry(object):
    implements(interfaces.ILDAPEntry)
    dn = None

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes=InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k,vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k,vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        return self._attributes[key]

    def get(self, key, default=None):
        return self._attributes.get(key, default)

    def has_key(self, key):
        return key in self._attributes

    def __contains__(self, key):
        return self.has_key(key)

    def keys(self):
        return self._attributes.keys()

    def items(self):
        return self._attributes.items()

    def __str__(self):
        a=[]

        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        a.append(('objectClass', objectClasses))

        l=list(self.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn, a)

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return 0
        if self.dn != other.dn:
            return 0

        my=self.keys()
        my.sort()
        its=other.keys()
        its.sort()
        if my!=its:
            return 0
        for key in my:
            myAttr=self[key]
            itsAttr=other[key]
            if myAttr!=itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self==other

    def __len__(self):
        return len(self.keys())

    def __nonzero__(self):
        return True

    def __repr__(self):
        x={}
        for key in self.keys():
            x[key]=self[key]
        keys=self.keys()
        keys.sort()
        a=[]
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes=', '.join(a)
        return '%s(%s, {%s})' % (
            self.__class__.__name__,
            repr(str(self.dn)),
            attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = sets.Set(self.keys())
        otherKeys = sets.Set(other.keys())

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort() # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort() # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort() # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort() # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort() # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        for digest in self.get('userPassword', ()):
            if digest.startswith('{SSHA}'):
                raw = base64.decodestring(digest[len('{SSHA}'):])
                salt = raw[20:]
                got = sshaDigest(password, salt)
                if got == digest:
                    return self
        raise ldaperrors.LDAPInvalidCredentials

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        return hash(self.dn)
Example #4
0
class BaseLDAPEntry(WireStrAlias):
    dn = None
    _object_class_keys = set(get_strings('objectClass'))
    _object_class_lower_keys = set(get_strings('objectclass'))
    _user_password_keys = set(get_strings('userPassword'))

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes = InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k, vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k, vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        raise KeyError(key)

    def get(self, key, default=None):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        return default

    def has_key(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return True
        return False

    def __contains__(self, key):
        return self.has_key(key)

    def __iter__(self):
        for key in self._attributes.iterkeys():
            yield key

    def keys(self):
        a = []
        for key in self._object_class_keys:
            if key in self._attributes:
                a.append(key)
        l = list(self._attributes.keys())
        l.sort(key=to_bytes)
        for key in l:
            if key.lower() not in self._object_class_lower_keys:
                a.append(key)
        return a

    def items(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            if objectClasses:
                a.append((key, objectClasses))

        l = list(self._attributes.items())
        l.sort(key=lambda x: to_bytes(x[0]))
        for key, values in l:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))

        return a

    def toWire(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            a.append((key, objectClasses))

        items_gen = ((key, self[key]) for key in self)
        items = sorted(items_gen, key=lambda x: to_bytes(x[0]))
        for key, values in items:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn.getText(), a)

    def getLDIF(self):
        return self.toWire().decode('utf-8')

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return NotImplemented
        if self.dn != other.dn:
            return 0

        my = sorted((key for key in self), key=to_bytes)
        its = sorted((key for key in other), key=to_bytes)
        if my != its:
            return 0
        for key in my:
            myAttr = self[key]
            itsAttr = other[key]
            if myAttr != itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self == other

    def __len__(self):
        return len(self.keys())

    def __bool__(self):
        return True

    def __nonzero__(self):
        return self.__bool__()

    def __repr__(self):
        keys = sorted((key for key in self), key=to_bytes)
        a = []
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes = ', '.join(a)
        dn = to_bytes(self.dn.getText()) if six.PY2 else self.dn.getText()
        return '%s(%s, {%s})' % (
            self.__class__.__name__,
            repr(dn),
            attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = set(key for key in self)
        otherKeys = set(key for key in other)

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort(key=to_bytes)  # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort(key=to_bytes)  # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort(key=to_bytes)  # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        password = to_bytes(password)
        for key in self._user_password_keys:
            for digest in self.get(key, ()):
                digest = to_bytes(digest)
                if digest.startswith(b'{SSHA}'):
                    raw = base64.decodestring(digest[len(b'{SSHA}'):])
                    salt = raw[20:]
                    got = sshaDigest(password, salt)
                    if got == digest:
                        return self
                else:
                    # Plaintext
                    if digest == password:
                        return self
        raise ldaperrors.LDAPInvalidCredentials()

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        # FIXME:https://github.com/twisted/ldaptor/issues/101
        # The hash should take into consideration any attribute used to
        # decide the equality.
        return hash(self.dn)