+(defun ldap-password-read (host)
+ "Read LDAP password for HOST.
+If the password is cached, it is read from the cache, otherwise the user
+is prompted for the password. If `password-cache' is non-nil the password
+is verified and cached. The `password-cache-expiry' variable
+controls for how long the password is cached.
+
+This function can be specified for the `passwd' property in
+`ldap-host-parameters-alist' when interactive password prompting
+is desired for HOST."
+ ;; Add ldap: namespace to allow empty string for default host.
+ (let* ((host-key (concat "ldap:" host))
+ (password (password-read
+ (format "Enter LDAP Password%s: "
+ (if (equal host "")
+ ""
+ (format " for %s" host)))
+ host-key)))
+ (when (and password-cache
+ (not (password-in-cache-p host-key))
+ ;; Confirm the password is valid before adding it to
+ ;; the password cache. ldap-search-internal will throw
+ ;; an error if the password is invalid.
+ (not (ldap-search-internal
+ `(host ,host
+ ;; Specify an arbitrary filter that should
+ ;; produce no results, since only
+ ;; authentication success is of interest.
+ filter "emacs-test-password="
+ attributes nil
+ attrsonly nil
+ withdn nil
+ ;; Preempt passwd ldap-password-read
+ ;; setting in ldap-host-parameters-alist.
+ passwd ,password
+ ,@(cdr
+ (assoc
+ host
+ ldap-host-parameters-alist))))))
+ (password-cache-add host-key password))
+ password))