# 0.9.6

Release Date: 2001-09-29

Bug fixes and work arounds
  - Added a workaround for misbehaving LDAP servers (e.g. Lotus Domino) which return a single null-byte character in namingContexts attribute of RootDSE.
  - Another workaround for some weird effects if python-ldap is linked against OpenLDAP 2 libs.
  - Fixed race condition in LDAPSession.getRootDSE() which ended with namingContexts attribute having the value None instead of [] under some strange error conditions.

# 0.9.5

Release Date: 2001-09-23

Installation changes
  - Use separately distributed module PyWebLib for web session handling, form processing, some HTTP header handling and SSL-related environment. Modules cgiforms, cgisession, cgihelper and httphelper are no longer shipped with web2ldap package.
  - Use module ldapthreadlock contributed to python-ldap instead shipping own module ldapthreading.
  - Module ldif is no longer shipped since it was contributed to python-ldap ages ago.
  - Module DNS is no longer distributed within the package. Install PyDNS instead.
  - Format of host-specific parameter addform_oc_list has changed. The tuple now contains the attribute type for forming the RDN. This is pretty convenient. Use it!
  - On Posix platforms a local configuration module (etc/web2ldap in start directory) now has precedence over a system-wide configuration module (/etc/web2ldap). Also getting the configuration module from Windows-specific system directories is not possible anymore.
New features
  - Implemented very basic group management. Make sure to check out button [Groups] in context menu of single entry display (read).
  - Added handling of binary attribute values stored as hex-byte encoding with prefix {ASN}.
User Interface
  - The bind DN (var who) is reused as default in login form if ldap.INVALID_CREDENTIALS was raised after login try.
  - New quick button in ConnInfo for accessing subschemaSubentry.
  - The old password is not requested anymore in the password input form. Instead a relogin window is provided if ldap.INSUFFICIENT_ACCESS is raised.
  - If the user has to do a new login after changing his/her password there is no menu shown anymore.
  - Added search option "exists" to advanced search form. The search string is ignored if this option is chosen.
Code cleaning and performance tuning
  - Removed unused module msshelve.
  - Removed some unnecessary module imports.
  - Separate module ldaputil.passwd is used to set the userPassword attribute instead of doing all the stuff in application module w2lpasswd.
  - Moved application modules pylib/w2l*.py to separate module package directory pylib/w2lapp/.
  - Code-cleaning concerning w2lapp.core.CleanUpThread
  - Some code-cleaning with catching referral exceptions when python-ldap is built with OpenLDAP 2.0.x.
  - Implemented new class ldaputil.ldapurlLDAPUrl which does the whole LDAP URL handling.
  - Lots of small code clean-ups, e.g. substituted lots of lambda, map(), filter function calls with list comprehensions.
  - The dumpasn1 config file is only parsed once at startup and the parsed content is held persistent => tremendous speed-up when displaying certificates and CRLs.
  - Moved creation of modlist's for modify() calls from ldapbase into new sub-module ldaputil.modlist. Functions were renamed.
Bug fixes and work arounds
  - Hopefully fixed bugs with mixed-case handling of LDIF and other input data by rewriting ldapbase.modify_modifylist().
  - Proper handling of lower-cased attribute type names of special root DSE attributes.
  - Catch all exceptions which might occur when calling DNS.ParseResolvConf() in module ldapdns and set ldapdns.dns_module_avail=0 in this case which switches off looking up SRV RRs in DNS. This is a rather crude approach which should be refined in the near future.
  - A bunch of small fixes and clean-ups for nasty things detected by PyChecker.
  - utctime.strftimeiso8601() does not rely on time.strftime() to display timestamps anymore. This makes displaying of all year values possible (not only 0..99,1900.. like enforced by time.strftime()).
  - When retrieving the root DSE "+" (ASCII 43) is used as requested attribute type for OpenLDAP 2.0.x as described in RFC 3673 if the objectClass attribute of root DSE contains "OpenLDAProotDSE".
  - Fixed wrong definition of Mozilla-specific MIME type for attribute certificateRevocationList.

# 0.9.4

Release Date: 2001-06-23

- Fixed displaying of iPAddress attribute in certificates.
- Abandoned global configuration parameter web2ldapcnf.misc.script_method.
- Slightly improved exception handling especially of logging/ignoring user-aborted connections, etc.
- Determining appropriate charset used with browser was improved: mainly proper parsing of capability values.
- A lookup of SRV RRs is automatically done if a LDAP URL does not contain a host name but a "dc-style" DN (a DN formed by domainComponent attributes).
- New configuration sub-module fastcgi.
- Some really significant performance optimizations in ldapthreading module. Former approach in method LDAPObject.result() was brain-dead and slow.
- Web session ID is now passed around in PATH_INFO instead as a hidden form field. This means less HTML bloat and it decoupled session retrieving from form processing.
- If ldap.NAMING_VIOLATION occurs during add the user can reedit his input.
- Fixed smart login search with user names containing NON-ASCII chars. (sigh!)
- Fixed wrong passing of parameters when calling function ldapbase.SmartLogin().
- Use timeout search for smart login.

# 0.9.3

Release Date: 2001-06-08

- Started writing a FAQ document.
- Cleaned up determining the default RDN for adding new entry.
- If an exception instance of type ldap.PARTIAL_RESULTS contains more than one referral LDAP URL only the first one is extracted and used. This is a workaround for the problem that multiple referral URLs were not parsed properly.
- New method LDAPSession.isLeafEntry() is used to prevent user from submitting modrdn request on non-leaf entry.
- If a single binary attribute is requested by command read an error message is generated if the entry does not contain this attribute (probably affects only cases where the user manually edits the URL).
- Some modifications to nicely display attributes found in Active Directory (e.g. objectGUID, whenChanged).
- Incompatible change to configuration dictionary web2ldapcnf.misc.ldap_browsermimetypes to make it more flexible. The format is now:

      ldap_browsermimetypes = {
        ('browsername','browserversion'):{
          'attrtype':'mime_type'
        },
        'browsername':{
          'attrtype':'mime_type'
        },
      }

- Default MIME-types of certificates and CRLs were changed to application/pkix-cert and application/pkix-crl to be compliant to RFC 2585.
- Extra try-except block in w2lhandler.py sends all unhandled exceptions (including exceptions raised in except statements of inner try-except block) to logging function w2lcore.log_exception().
- Work around buggy browsers (e.g. StarOffice) which does not honour the accept-charset attribute of <form> tag and try to decode input as ISO-8859-1 if e.g. UTF-8 fails.

# 0.9.2

Release Date: 2001-05-19

- Security fix:
  When calling ldapsession.LDAPSession.bind() the LDAPSession instance (associated with the web session) flushes all cached data, forgets all old RootDSE attributes and calls ldapsession.LDAPSession.getRootDSE() again.
- Security fix:
  Fixed determining SSL security level and displaying certificates from SSL-related environment vars in conninfo. (works only through FastCGI)
- Security feature:
  Reimplemented rudimental SSL-based authorization scheme for gateway use. (works only through FastCGI)
- Fixed handling of search scope select field when a search form is displayed after the user entered an invalid search filter.
- Send HTTP error 405 in msHTTPHandler if running stand-alone and web application is accessed with HTTP-method HEAD.
- Adjusted some more HTTP error responses in msHTTPHandler for running stand-alone to be hopefully more compliant to RFC 2616.
- If the user enters an incomplete RDN for a new entry containing only the attribute type (e.g. 'cn=') and the corresponding attribute value is present in the entry the new RDN is automatically formed.
- Removed input form for command locate from entry page because too many people did not know what it means. Instead directly invoke web2ldap with URL `http://[host:port]/web2ldap/locate` to get the input form.

# 0.9.1

Release Date: 2001-05-15

- Fixed a compatibility issue in method ldapthreading.LDAPObject.result() with versions of python-ldap based on sources prior 2000-10-19. (see the incompatible change made to python-ldap)
- Catch an AttributeError exception when using python-ldap built with LDAP libs without caching option.
- Running multi-threaded is also the default on non-Posix platforms (e.g. Win32) now.

# 0.9.0

Release Date: 2001-05-10

- Most important change:
  Dropped support for running as stateless CGI-BIN or stateless mod_python handler. Instead the possible modes are running as a multi-threaded stand-alone server or as a multi-threaded FastCGI server.
  The main benefit is that LDAPObject instances are kept persistent in memory => there is no need rebind for each hit anymore. This greatly improves performance and reduces security risks since the credentials do not have to be stored at all. Other benefits are faster session database clean-ups and avoiding problems with file locking, file permissions etc.
- Web session management. Each LDAP connection object is tied to a session ID stored in a hidden input field.
- Method HTTP-POST is used wherever the state of the LDAP repository is changed or a login is done (to be compliant with section 9.1 of RFC 2616).
- Slightly improved debug log by suppressing traceback if IOError.errno==32 (user aborted connection) and printing date/time and client IP address.
- Important security fix: Internal URL redirector.
  URLs are not displayed directly anymore. The URL points to the new urlredirect command which creates a HTML page with <meta http-equiv="refresh" content="0;..>". This avoids that the browser sends the currently viewed URL as Referer-URL which could reveal session ID and credentials to an attacker.
- If ldap.SIZELIMIT_EXCEEDED exception is raised during a search the and the output format is table the partially received search results are displayed.
- Default configuration module in distribution is now platform-independent and tries to set all path names relative to web2ldap directory. This makes quick-install for stand-alone mode easy on most platforms. Just extract archive and start the sbin/web2ldap.py script.
- Type of audio and image attributes is automatically determined with sndhdr and imghdr modules in Python's standard lib.
- Hopefully fixed template files for vCard. At least works with Netscape now (problem with empty attributes).
- Single entries are now retrieved with all binary attributes and placed in a short-time cache together with other LDAP session data. This makes it possible to correctly access all multi-valued binary attributes with separate buttons or display multi-valued image attributes in-line.
- Wrapper script for running as FastCGI server.
- Access log for stand-alone mode in combined log format (with Referrer and User-Agent header).
- Wrapper class ldapthreading.LDAPObject around ldap.LDAPObject (mainly for thread-locking) which transforms all synchronous calls into asynchronous python-ldap calls.
- Log unhandled exceptions in error log file with a lot of information about the aborted connection.
- Make use of LDAP cache of LDAP libs. Two new host-/backend-specific parameters cache_timeout and cache_maxmem in configuration module web2ldapcnf.hosts.
- User interface:
  - Inline displaying of images (attribute jpegPhoto etc.) when displaying an entry (Read).
  - <embed type=".." src=".."> for "displaying" audio attribute.
  - Nicer displaying of operational attributes when displaying a single entry by using a (language variant) HTML template file.
  - Slightly improved the HTML generation, e.g. more consequent use of <fieldset> sections, lower-cased HTML tags and attributes etc.
  - If ldap.OBJECT_CLASS_VIOLATION, ldap.OBJECT_CLASS_VIOLATION or problems with RDN occurs during add (or modify) it is now possible for the user to edit his input again.
  - If ldap.FILTER_ERROR exception is raised during a search the user can edit the search filter and re-submit it.
  - Currently viewed DN is not changed if a new entry was added. This hopefully makes it easier to repeatedly add entries below the same node.
  - A [Display All] button for immediate switching to unpaged displaying of search results.
  - OIDs in RootDSE attributes are displayed with name and description. Credits go to Norbert Klasen for contributing a comprehensive list.
  - More information in connection info (ConnInfo).
  - Buttons for quickly choosing default object classes of new entries. This list is configurable per host/backend.
  - Quick buttons for accessing RootDSE, CN=MONITOR and CN=CONFIG in context menu of connection info (ConnInfo).
  - New command monitor which displays general gateway statistics.
  - Improved documentation of configuration module package web2ldapcnf.
- Bug fixes:
  - Configuration did not work properly since 0.8.0 because I dropped ldap_basedn in hidden fields. Fixed.
  - Fixed parsing of LDAP URLs. Bug was related to usage of new string methods.
  - Fixed the screwed up passwd changing.
  - Check if RDN in input is empty or RDN has wrong format before adding entry.
  - Fixed Unicode handling in ldapbase.SearchTree() (used for recursive deleting of entries).
  - Fixed displaying of missing parent entry DNs when adding an entry.
  - Many small HTML generation fixes.
  - Many, many small fixes...and probably new bugs... ;-)
  - Fixed handling of LDIF input data (was case-sensitive regarding the attribute types).
- Code cleaning:
  - Dropped support for checking gateway use by looking at DN of the client certificates. It seems that nobody is using it and it was getting ugly (may appear again in later version).
  - A lot of connection stuff is done within ldapsession.LDAPSession objects now including storing and restoring sessions and getting RootDSE attributes like namingContexts etc.
  - LDAP sessions are wrapped in LDAPSession objects for pickling and to wrap specific details if a patched python-ldap built against OpenLDAP 2.0.x libs is in use.
  - Rewrote parts of module w2lhandler.
  - Call login form directly if password of currently used bind DN was changed.
  - The code for creating the input forms for adding and modifying entries was a complete mess. It's still not pretty...
  - The code for creating the search forms was also a complete mess.
  - w2lgui.DisplayDN now took over all weird things with displaying DNs.
  - Moved class HTTPHandler from module msHTTPServer into separate module msHTTPHandler.
  - Creating hidden fields along with buttons is simplified by new parameter hidden_fields (list of tuples) in function w2lgui.CommandButton().
  - Almost no direct calls of LDAPObject methods anymore. All necessary methods are wrapped in sort of higher level wrapper methods of LDAPSession class. This makes caching and locking feasible.
  - Handle more input field stuff with the fine cgiforms module and derived classes in module w2lgui.
  - Cleaned up function httphelper.SendHeader().