Menu

Disabling anonymous binds

2021-10-13
2021-10-14
  • Jesse Van Hill

    Jesse Van Hill - 2021-10-13

    We use the InMemoryDirectoryServer for testing. It is fantastic btw.

    I would like to disable anonymous binds to an InMemoryDirectoryServer for a specific set of tests. It is not obvious from the configuration on whether this is possible (and I read some documentation that seems to indicate it is not). I thought perhaps even a request or response interceptor for a simple bind op might work, but didn't see any examples.

    Is it possible to disable anonymous binds via configuration or via some sort of plug point?

    Thanks in advance.

     
  • Neil Wilson

    Neil Wilson - 2021-10-14

    The in-memory directory server doesn't have the ability to reject anonymous binds by default, but you are correct that it's something that can be easily done with an interceptor. I've attached an example that demonstrates this.

     
    • Jesse Van Hill

      Jesse Van Hill - 2021-10-14

      Thanks for the quick response. The next question I have is I want to return a 50 when using an anonmyous bind for a search request. My understanding is that the InMemoryDirectoryServer does not have fine-grained authorization roles.

      I was hoping I could leverage the interceptor to do this as well. It would save off the state of the anonymous bind in the processSimpleBindRequest(..) method and reject the search in the processSearchRequest(...) method if we were in an anonymous bind. However; as you probably know that didn't work. Is there another way I can check to see if we are using an anonymous bind for the current search request?

      Thanks.

       
  • Neil Wilson

    Neil Wilson - 2021-10-14

    You are correct that the in-memory directory server doesn't provide support for fine-grained authorization. However, it does allow you to define a set of operation types that will only be allowed for authenticated connections. You can do that through the InMemoryDirectoryServerConfig.setAuthenticationRequiredOperationTypes method. If you do that and a client tries to process one of those types of operations on an unauthenticated connection, then the server will return an INSUFFICIENT_ACCESS_RIGHTS result, so that sounds like what you want.

     
    • Jesse Van Hill

      Jesse Van Hill - 2021-10-14

      Thanks. This is exactly what I was looking for.

      Another unrelated question. We have occassionally hit a native OutOfMemoryError when running this for long durations. When we look at that stack dump, we see a ton of these:

      3XMTHREADINFO "LDAP Listener Thread (listening on port 35705)" J9VMThread:0x000000000104B800, omrthread_t:0x00007F3F1C37E130, java/lang/Thread:0x00000000C07D67D8, state:R, prio=5
      3XMJAVALTHREAD (java/lang/Thread getId:0x14, isDaemon:false)
      3XMTHREADINFO1 (native thread ID:0x54D9, native priority:0x5, native policy:UNKNOWN, vmstate:R, vm thread flags:0x00001020)
      3XMTHREADINFO2 (native stack address range from:0x00007F3EEEC46000, to:0x00007F3EEEC87000, size:0x41000)
      3XMCPUTIME CPU usage total: 0.504557072 secs, current category="Application"
      3XMHEAPALLOC Heap bytes allocated since last GC cycle=0 (0x0)
      3XMTHREADINFO3 Java callstack:
      4XESTACKTRACE at java/lang/Thread.startImpl(Native Method)
      4XESTACKTRACE at java/lang/Thread.start(Thread.java:1002)
      5XESTACKTRACE (entered lock: java/lang/Thread$ThreadLock@0x00000000FFBF64B0, entry count: 1)
      5XESTACKTRACE (entered lock: com/unboundid/ldap/listener/LDAPListenerClientConnection@0x00000000FFBF6398, entry count: 1)
      4XESTACKTRACE at com/unboundid/ldap/listener/LDAPListener.run(LDAPListener.java:261)

      We aren't certain this is causing the issue, but we see ~200 of these threads. Should we expect so many of these threads waiting?

      If you want me to open a defect, I can do that as well (let me know where to open it). I will need to check with the developer who encountered this and see if they are still hitting this and if so if they can recreate (it has happened occasionally over the years).

       
  • Neil Wilson

    Neil Wilson - 2021-10-14

    Those are threads that the LDAP SDK uses to read responses from the directory server. The LDAP SDK uses them if you're not running in synchronous mode (and it doesn't use synchronous mode by default), and it allows the SDK to handle asynchronous operations (where there may be multiple operations in progress on the same connection at the same time) and more quickly react to intermediate responses and connection closures.

    It's pretty unlikely that these threads are accumulating as a result of a bug in the LDAP SDK. When a connection is properly closed, the listener thread should also be shut down. We have a lot of very heavy users of the LDAP SDK, including our own LDAP client and server products, and we're not aware of any cases in which a connection may be properly closed but will leave the listener thread running.

    It's more likely to be a case in which you have an application that is inadvertently leaking connections. A couple of the most common ways in which this might happen include:

    • An application establishes a connection but doesn't properly close it (for example, because an unexpected condition arose after establishing the connection that caused the application to throw an exception or return from the method that created it without ensuring that the connection got properly closed. The best way to deal with this is to use either try-with-resources or a try/finally block to ensure that whenever you establish a connection, you make sure that it gets closed even under exceptional circumstances.
    • An application uses a connection pool and checks out a connection but doesn't properly release it back to the pool (either as a valid connection or as a defunct connection). The best way to avoid this is to not actually check out and release connections yourself, but instead to let the connection pool do all that work for you. For example, if you want to use a pooled connection to perform a search, it's much better to use LDAPConnectionPool.search (which will automatically check out the connection, perform the search, release the connection, and return the search result, making sure to handle all error conditions properly) than it is to check out the connection, do the search yourself, and release the connection. As an added benefit, using the connection pool to process operations directly rather than doing the connection management yourself can be more robust because it offers the ability to automatically re-connect and re-try an operation if an attempt fails in a way that suggests the connection might not be valid.
     

Log in to post a comment.