Hi,
I am looking to patch the LDAP Service Name feature and would like some
feedback prior to doing so. In general, while I personally view this as a bug
fix, it could also easily be considered to simply be an enhancement to current
functionality and therefore the below is written as a proposed enhancement.
Note: This will also potentially serve as my first patch submission, so this
will be a "smoke test" of my direct interaction with the mailing list as a
Goldman Sachs Employee for proposal/feedback as well as following up with a
potential patch/participation in commit processes, etc. As such my replies and
related code submissions may be delayed for processes to happen on my end, with
my associated apologies in advance. I hope to have this process completed for
contribution to the 9.5 release.
################## Currently:
* Service names are provided as an available abstraction mechanism for a
host:port (and user, dbname, ssl requirements, etc.) information for connection
parameters via libpq.
* If service names are used, they must each individually have an entry in
pg_service.conf.
* In a service name entry, host:port entries, hosts can either be directly
provided or their values may be referenced via an LDAP location that provides
equivalent name/value pairs for connection information.
The service name feature facilitates the use of dynamic/managed host entries or
allows for active connection configuration management with the goal in either
case of separating such overhead from application or other process
configuration.
Therefore:
* Dynamic DNS entries require a fixed port or active management of the file
(DNS resolution can happen elsewhere)
* Non-Dynamic DNS entries require active management of pg_service.conf, but may
still be desirable for configuration management reasons - version control?
* LDAP entries are largely static, but do require active management of
pg_service.conf if new data servers are to be added (or old ones decommissioned)
In all cases described above, a newly provisioned data server requires a new
service name entry, which requires the file to be actively managed. This
mitigates the value of using LDAP or Dynamic DNS entries (with fixed ports in
the DNS case) since an active distribution mechanism must still be in place,
especially for deployments of many servers and perhaps this useful mechanism is
used less often as a result.
################## Proposal:
* Have a wildcard entry that allows string substitution of the service name
into either the host field or an LDAP record.
I do not want to over complicate the existing configuration file or parsing
logic as it is pretty lightweight currently. As such, I am looking for feedback
related to if it would be acceptable to have a "wildcard" entry for service
names as well as what that wildcard should be. I do *not* propose that complex
string substitution, including regular expressions, etc. be utilized for
service name matching at this time.
Per 31.16 in the 9.4 Documentation, a valid service entry is of the following
format:
# comment
[mydb]
host=somehost.domain.com
port=5433
user=admin
Would specifying a special value for the service name, perhaps [%], be an
acceptable implementation of this enhancement/fix to my above concerns?
Example:
# comment
[%]
host=%.domain.com
port=5433
user=admin
...or more interestingly, per 31.17:
# comment
[%]
ldap=ldap://ldap.mycompany.com/dc=mycompany,dc=com?uniqueMember?one?(cn=%)
The location of [%] and therefore order of the service names would still be
honored. I believe this allows for useful functionality:
* LDAP wildcard listed first - libpq can always try an LDAP lookup and proceed
with further service names if one is not found in LDAP location
* LDAP wildcard listed last - only look up LDAP entries if a service name
doesn't match prior service names
* LDAP wildcard in the middle - combination of first 2 behaviors
* DNS wildcard listed last - try connecting with service name in well-formed
dns-based host entry (this likely can't be first as it would always match)
* Combination of the LDAP/keyword = value entries per 31.17:
>From the existing documentation: "Processing of pg_service.conf is terminated
>after a successful LDAP lookup, but is continued if the LDAP server cannot be
>contacted. This is to provide a fallback with further LDAP URL lines that
>point to different LDAP servers, classical keyword = value pairs, or default
>connection options. If you would rather get an error message in this case, add
>a syntactically incorrect line after the LDAP URL."
The "%" in the ldap, host entry would replace with the service name in use -
also possible to make it less likely to match a future valid "%" by providing
it as [%] in the string, though I don't know why a % would reasonably show up
in an ldap or host record.
I have not made the patch yet, but it looks like this change is isolated to the
parseServiceFile subroutine, currently starting on line 3867 in
https://github.com/postgres/postgres/blob/master/src/interfaces/libpq/fe-connect.c
(and associated documentation).
################## Scope:
Note that this discussion is scoped only for LDAP directory services and not
for LDAP authentication/authorization. Again, I do *not* propose that complex
string substitution, including regular expressions, etc. be utilized for
service name matching at this time. Just looking for a simple [%] entry, which
could be extended for flexibility in a consistent way, if people find this
general case useful.
I am looking forward to feedback and our first interaction on the distribution
list.
Thanks,
Bryan