Author: Nitin More

# Change Log for the ldaputil library

Author: Nitin More
E-mail: nitin@netscape.com
Phone: (415) 937-4240

Changes since Apr 17, 1997

Last Update: Aug 25, 1997

All the new changes have been checked into the server3_tier_branch. The server3_branch is frozen & contains the version of 'ldaputil' for the SuiteSpot 3.0 release.

## Changed:

Several bug fixes went in since I last modified this file. The important ones are:

- 79373: Attributes listed multiple times in certmap.conf were turining that attribute off and enabling some other attribute. (For example, if you have "E" as well as "MAIL" in FilterComps, they cancelled each other).
- 58474: If nested group checks goes on for 30 recursions, a circular groups error is returned.
- 80004: after thoroughly testing the certmap utility, several (mostly minor) oddities were found & fixed.

## Added:

- 79370: Group membership check is optimized now through the new function ldapu_auth_userdn_groupids. Use this new function to get the optimization. This function's algorithm is as follows:
The first search uses the following filter (w/o the group names!):

`(| (& (objectclass=groupofuniquenames)`
`(uniquemember=<userDN>))`
`(& (objectclass=groupofnames)(member=<userDN>)))`

This gives us all the groups the user is member of. We ask for only the "CN" attributes of the returned groups. We check if "CN" of any of the returned groups is one of the groups we have. If yes, we have succeeded. If there are no groups returned then we have failed. Otherwise, we continue with the nested group check. To perform that check, we need DNs of all the groups the user is member of, which we already have from the previous search. Now we repeat the search as follows:

`(| (& (objectclass=groupofuniquenames)`
`(| (uniquemember=<grp1DN>)... (uniquemember=<grpNDN>))`
`(& (objectclass=groupofnames)`
`(| (member=<grp1DN>)... (member=<grpNDN>))`

We check the list of groups returned by this search with the groups in the ACL and recursively continue until we succeed or no more groups are returned from the searches.

Advantages of this new function is it checks multiple groups at the same time. Previously we were performing 2 ldap lookups per group. Now we achieve this in a single ldap lookup!

Caution: this function allows multiple groups with the same "CN".

To use this function, you need to provide a list of group names in any form (e.g comma separated string, a hash table, array of strings, etc.) and a function to compare the name returned by the ldap lookup with your group names.

Changes since Mar 22, 1997

Last Update: Apr 17, 1997

Now that all beta releases are out for servers using this library, I could do some incompatible changes to make this library more flexible. No more incompatible changes are planned (except for possibly one: see http://scopus/bugsplat/show_bug.cgi?id=58482). All 3.0 SuiteSpot servers supporting client auth need to upgrade to this version.

## Changed:

- Exchanged certmap.h & ldaputil.h: ldaputil.h had public API but when the file was installed on the server root, it was called certmap.h. Since we already had a certmap.h, this was causing lot of confusion. If you were including "certmap.h", now include "ldaputil.h" and vice versa.
- Renamed 'SearchComps' to 'FilterComps': Shouldn't affect your code but may affect tests and documentation.
- 'VerifyCert' must be either "on" or "off": VerifyCert didn't have a value. Now it must have a value. If it has a value of "on" then the "verification" step is on, otherwise it is off.
- Important bug fixes: One bug was causing stack corruption & weird unpredictable results. The other important bug was to map 'E' in cert to 'MAIL' in LDAP.

## Added:

- Settable 'search function': User defined search function can be set for cert to ldap mapping.
- ldapu_get_cert_ava_val & ldapu_free_cert_ava_val: API functions to get & free an attribute's value(s) from either the subject DN or the issuer DN from a cert.

## Open Bugs:

Following bugs may not get fixed by RTM.

- 51279: 'uniquemember' bug
- 58474: 'circular groups' results in infinite loop
- 58478: Don't allow a space as a valid delimeter for DNComps & FilterComps.
- 58482: Make the 'search function' configurable.

### Changes since Mar 18, 1997

Last Update: Mar 22, 1997
A query on how to map a verisign certificate prompted these changes. I was hoping I don't have to do any major changes when I wrote this document on Mar 18. These are incompatible changes -- please review them before you upgrade. I have checked in this file in CVS under "ns/netsite/lib/ldaputil/ldapu-changes.html". I have added all the "XYZ_branch" and "XYZ_point" tags to this file so that you can easily see this file in your tree. When I make significant changes to this file/library, I will retag this file for your branch to make it same as the server3_branch. [Let me know if I shouldn't do it for your branch].

## Changed:

- ldapu_cert_to_ldap_entry: The major change was to allow for the mapped DN to be NULL and in that case, start the search from the basedn of the LDAP server. This required API change so that the basedn can be passed to the ldapu_cert_to_ldap_entry function. This change was required for correctly mapping certs from verisign w/o writing plugins. The Verisign certs can be mapped correctly using the following setting in the <ServerRoot>/userdb/certmap.conf file:

`certmap verisign <verisign's DN>`
`verisign:dncomps`
`verisign:searchcomps cn, e`

The mapped DN will be NULL so basedn will be used. The filter will be
(& (cn="<user's CN>") (mail="<user's mail>")). The new signature of ldapu_cert_to_ldap_entry is as follows:
int ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res);
- verify cert functions: A major change in how verify cert functions work. This is function is now called even when multiple potential matches are found for the cert. The mapping is successful if the verify function can reduce the number of matches to exactly one. For example, if there are multiple "Joe Smith" entries, at most one of those will have the cert in it's "userCertificate" attr. The verify function will select that entry. The verify function is called with "LDAPMessage *res" containing all the potential matches. It should return a pointer to the matched entry in the new "LDAPMessage **entry" parameter. The new signature for CertVerifyFn_t is as follows:
typedef int (*CertVerifyFn_t)(void *cert, LDAP *ld, LDAPMessage *res,

LDAPMessage **entry);

- typedef int (*CertMapInitiFn_t): Renamed from CertmapInitFn_t. Now this has two extra parameters to make it easy to use it in a plugin. Other API functions require "issuerDN" but this function was called with "LDAPUCertMapInfo_t *certinfo". There was no public API function to get the issuerDN from "certinfo". The new signature for CertMapInitFn_t is as follows:
typedef int (*CertMapInitFn_t)(void *certmap_info, const char *issuerName,
const char *issuerDN);
- (ldapauth.h) ldapu_auth_* functions: For multiple matches, these functions now return LDAPU_ERR_MULTIPLE_MATCHES instead of LDAPU_FAILED. This change was required to make nested group membership work efficiently and enable the new functionality of verify cert function.

### Changes since Feb 1, 1997

Last Update: Mar 18, 1997
There have been several changes to the netsite/lib/ldaputil recently. If you use this library, please start using the latest version of ldaputil on the server3_branch so that all the servers go out with the same API and behavior. Review the changes before you upgrade. If you don't plan to upgrade, please let me know.

## Renamed:

Following structures and functions are renamed. But this shouldn't affect you unless you have written a certmap plugin.
  `struct CertMappingFunction_t ---> CertMapFn_t`
  `struct CertVerifyFunction_t ---> CertVerifyFn_t`
  `ldapu_set_cert_mapping_function ---> ldapu_set_cert_mapfn`
  `ldapu_get_cert_mapping_function ---> ldapu_get_cert_mapfn`
  `ldapu_set_cert_verify_function ---> ldapu_set_cert_verifyfn`
  `ldapu_get_cert_verify_function ---> ldapu_get_cert_verifyfn`

## Removed: (from .h)

Removed the following functions from .h files. They are still in the .c file as static functions. I don't think these should be public. If you think otherwise, let me know.
  `ldapu_cert_mapping_function_default`
  `ldapu_cert_verify_function_default`
  `ldapu_search_cert_dn`
  `ldapu_subject_dn_to_ldap_dn`

## Changed:

The following changes may affect you. Please review them carefully before you upgrade to the latest version of ldaputil.

- `ldapu_auth_userdn_groupdn` -- added `const char *base` argument for group within group membership check
- ldap_init and bind calls using `LDAPDatabase_t *ldb` retry once if the LDAP server is/went down.
- `typedef CertVerifyFn_t` has different arguments.
- DNs from cert with escaped/quoted characters are correctly handled now.
- cert to ldap entry mapping is optimized by not using string comparisons during thruntime. A bitmask is created when the config file is read, cert data is mapped to bits and compared against the bitmask.
- Only the required attrs are retrieved in most `ldap_search_s` calls from ldaputil. Some new functions were added to keep older functions the same.
- Fixed a core dump in ldapu_free_LDAPDatabase_t when using the local db.
- ldaputil functions for initializing connection to the LDAP server and binding to the server are thread-safe now. This requires linking to netsite/lib/base. If you don't use libbase, you can turn off the thread-safe code using a compile time option.

## Added:

- Documentation to functions in ldaputil.h (customer API) - ldaputil.h is the external public API for customers to write there plugins.
- `ldapu_get_cert_der` - returns raw DER encoded cert data
- `ldapu_cert_to_user` - Similar to ldapu_cert_to_ldap_entry but only retrieves the 'uid' and 'userCertificate' attributes from LDAP and also extracts the user id.
- `ldapu_find_uid_attrs` and `ldapu_find_group_attrs` - Similar to ldapu_find_uid and ldapu_find_group resp., but only retrieves the specified attributes. Internally used during password verification and group membership checks.
- `ldapu_certinfo_delete, ldapu_certinfo_modify and ldapu_certinfo_save` - API for the certmap config file GUI tool which is not yet developed. Any volunteers?

## TODO/Bugs:

- uniquemember attribute is not handled correctly in the group membership check. If the user's entry has 'x500UniqueIdentifier' attribute populated, the group could refer to the user entry by the user's dn followed by '#' and an unique identifier. For example, the group entry could have:
  uniquemember: cn=Joe Smith,o=Netscape,c=US#jsmith
where, 'jsmith' is one of the values of the 'x500UniqueIdentifier' attribute for the Joe Smith entry.