spring-projects / spring-projects/spring-ldap

EqualsFilter does not support binary strings

Open
#634 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
375
Forks
501
Avg merge
6h 4m
Merged PRs (30d)
63

Description

Suppose the following classes:

@Entry(objectClasses = ["top", "person", "user"], base = "ou=users")
class LdapUser {

    @Id
    lateinit var id: Name

    @Attribute(name = "objectGUID", type = Attribute.Type.BINARY, readonly = true)
    lateinit var guid: UUID
}


@Repository
class LdapUserRepository(
    private val ldapTemplate: LdapTemplate,
) {
    fun findById(guid: UUID): LdapUser {
        val byteBuffer = ByteBuffer.wrap(ByteArray(16))
        byteBuffer.putLong(guid.mostSignificantBits)
        byteBuffer.putLong(guid.leastSignificantBits)
        val bytes = byteBuffer.array()

        val guidByteString = bytes.joinToString("\\", "\\") { "%02x".format(it) }
        val guidFilter = HardcodedFilter("(objectGUID=$guidByteString)")

        return ldapTemplate.find(
            query().where("objectGUID").`is`(guidByteString),
            LdapUser::class.java
        ).firstOrNull() ?: error("Could not find user")
    }

When you search the user with guid 90d1c68e-01be-4485-aafd-b3ffb9ddb026. The following log will be generated but nothing would be found:

DEBUG LdapTemplate.java[find]:1843 - Searching - base=ou=users, finalFilter=(&(&(objectclass=top)(objectclass=person)(objectclass=user))(objectGUID=\90\d1\c6\8e\01\be\44\85\aa\fd\b3\ff\b9\dd\b0\26)), scope=javax.naming.directory.SearchControls@54e07139

The query is correct, but it will not be executed. The following query will be executed instead:

base=ou=users, finalFilter=(&(&(objectclass=top)(objectclass=person)(objectclass=user))(objectGUID=\5c90\5cd1\5cc6\5c8e\5c01\5cbe\5c44\5c85\5caa\5cfd\5cb3\5cff\5cb9\5cdd\5cb0\5c26))

This happens because org.springframework.ldap.filter.EqualsFilter will be encoded and the backslashes will be escaped. This encoding is incorrect for the binary strings.

Please,

  1. provide a way to pass a value to the query builder without the encoding
  2. provide a way to pass binary values to the query builder
  3. fix the log at LdapTemplate.java[find]:1843 to show the propper encoded finalFilter

P.S. There is a workaround to fix the encoding issue but it finalizes the query builder

@Repository
class LdapUserRepository(
    private val ldapTemplate: LdapTemplate,
) {
    fun findById(guid: UUID): LdapUser {
        val byteBuffer = ByteBuffer.wrap(ByteArray(16))
        byteBuffer.putLong(guid.mostSignificantBits)
        byteBuffer.putLong(guid.leastSignificantBits)
        val bytes = byteBuffer.array()

        val guidByteString = bytes.joinToString("\\", "\\") { "%02x".format(it) }
        val guidFilter = HardcodedFilter("(objectGUID=$guidByteString)")

        return ldapTemplate.find(
            query().filter(guidFilter),
            LdapUser::class.java
        ).firstOrNull() ?: error("Could not find user")
    }

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with org.springframework.ldap.filter.EqualsFilter and the query builder behavior described in the issue, then inspect LdapTemplate.java at the find log location. Reproduce the binary objectGUID filter behavior and determine how raw or binary values should be represented; done means the filter is executed without incorrect backslash escaping and the finalFilter log shows the actual encoded filter.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.