I have an upcoming project that will require a custom LDAP server backed by an existing inventory/asset management application, which runs on Oracle. Of course, I plan to tackle this in OCaml. I’m confident enough with Oracaml now, and I’m delighted to find that OCaml’s LDAP module includes a server API. So to construct a new LDAP server, the process seems to be very straightforward:
- Implement a function
(Ldap_funserver.connection_id → Ldap_types.ldap_message → unit → Ldap_types.ldap_message)to actually do the lookup and return the result. This is the only functionality I require at this stage – the underlying data will be managed by the existing application, so no need for add, modify, delete and so on. I don’t even need authentication since it will run on trusted network. This function wll get the request in an
ldap_messageand construct an
ldap_messagewith the reply.
- Create a record of type
bi_op_searchwith my new function. All fields of this type are optional.
- Pass this record to
init, and get back a record of type
- Pass that to
runand we’re ready to start accepting clients. Perhaps I’ll put in a signal handler for a clean
Here’s where it gets more fiddly. I can also implement
bi_init (unit → unit) which is called as the server starts up (and there is a corresponding
bi_close called when shutting down). These are the logical places to place
occi_disconnect respectively, and
occi_create_statement in the function in step (1) with the
lda created therein. What I don’t understand is how to get that from there and into my handler function, without using global mutable state.
I am starting to think that as and when I start implementing my own APIs I will always include an arbitary type in the method signature, that the developer can just set to () if they don’t care, a sort of poor man’s Reader monad…