From xemacs-m  Wed May 21 05:48:51 1997
Received: from ALPHA8.CC.MONASH.EDU.AU (alpha8.cc.monash.edu.au [130.194.1.8])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id FAA24704
	for <xemacs-beta@xemacs.org>; Wed, 21 May 1997 05:48:48 -0500 (CDT)
Received: from goaway.cc.monash.edu.au ("port 2605"@goaway.cc.monash.edu.au)
 by vaxh.cc.monash.edu.au (PMDF V5.1-7 #20655)
 with ESMTP id <01IJ587ER2GA8ZEDG4@vaxh.cc.monash.edu.au> for
 xemacs-beta@xemacs.org; Wed, 21 May 1997 20:48:43 +1000
Received: (ajc@localhost) by goaway.cc.monash.edu.au (8.8.5/8.6.4)
 id UAA20362; Wed, 21 May 1997 20:48:43 +1000 (EST)
Date: Wed, 21 May 1997 20:48:43 +1000
From: Andrew J Cosgriff <Andrew.Cosgriff@cc.monash.edu.au>
Subject: LDAP for (X)Emacs
To: xemacs-beta@xemacs.org
Message-id: <ruivi4dayno.fsf@goaway.cc.monash.edu.au>
MIME-version: 1.0 (generated by tm-edit 7.106)
X-Mailer: Gnus v5.4.53/XEmacs 20.2
Content-type: multipart/mixed; boundary="Multipart_Wed_May_21_20:48:42_1997-1"
Content-transfer-encoding: 7bit
X-Attribution: ajc
X-URI: <URL:http://www-personal.monash.edu.au/~ajc>
X-PGP-Key-ID: C7BD53F5
X-Face: 
 PBPJ+.AE`FBN4$}H<dIo+^`A-G%mJTXXP$^4bBox##5=oF{G\[:0|sNlr%~H1,>rwwEh<qq.dHRpu8ftJ\'14l]<x(nRD>J)x?-5$MQ%Z)svNR@Q\WG6[GDr,}a@8ULwGWBsk,Pqxm!Z<lnD(Skwwe$j+<0g6N6z}>-
Lines: 215

--Multipart_Wed_May_21_20:48:42_1997-1
Content-Type: text/plain; charset=US-ASCII


Since i'm playing around with an LDAP server (among other things) as
part of my work, I thought "Wouldn't it be nice if emacs could do LDAP
searches for me so I can find people's email addresses ?"  - since i'm
unaware of any other LDAP interfaces for (X)Emacs, I figured i'd give
it a whirl.  It requires that you have the command line "ldapsearch"
program sitting around (I cheated a bit :)

Currently it just returns the first hit out of the list it gets given,
which is of questionable value if you're using one of those public
servers like Four11 (eg. the first hit on "Andrew Cosgriff" returns my
(now defunct) email address from my previous job...).  But it does
leave the output sitting around in a buffer called "*ldap-search*" so
you can go and see the rest.

Obviously, this needs a lot of work (patches most welcome :).  It's
also the first vaguely useful piece of elisp i've ever written, so i'd
appreciate any advice/feedback.

I even remembered to use "checkdoc" to help me out a bit :)

I'll post it to gnu.emacs.sources when/if it becomes a bit more
useful.

Of course, if there's anything in existence that does it all better,
i'd love to know about it.

Enjoy,
  Andrew

--Multipart_Wed_May_21_20:48:42_1997-1
Content-Type: text/plain; type=emacs-lisp; charset=US-ASCII
Content-Disposition: attachment; filename="ldap.el"
Content-Transfer-Encoding: 7bit

;;; ldap --- LDAP searching routines
;;
;; Copyright (c) 1997 Andrew J. Cosgriff
;;
;; Author: Andrew J Cosgriff <ajc@bing.wattle.id.au>
;; Version: 0.02
;; Keywords: ldap, search
;; X-RCS: $Id: ldap.el,v 1.4 1997/05/21 10:31:47 ajc Exp ajc $
;; Creation Date : Wed May 21 13:54:57 1997
;;
;; Free for use as long as you don't claim you wrote it or charge money for it.
;; I'm not responsible for your inability to use this program for its intended
;; purpose.  Use at your own risk.
;;
;; This is not part of GNU Emacs.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; Since I'm currently working on testing an LDAP server, I needed
;; (well wanted) some routines to look up people on the server and
;; return me their email addresses.
;;
;; It currently relies on having the "ldapsearch" executable in your
;; path.
;;
;;; TO DO:
;;
;; - Allow choosing of LDAP server at search time or search one after
;;   another.
;; - Allow searching on more than just CN, and look for more than just
;;   mail addresses (partly done, although we still only search for
;;   people and one of their attributes)
;; - Maybe write our own ldap connection routines ?
;; - Better error handling :P
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; History:
;;
;; 0.01 - Initial version
;; 0.02 - Use ldap-host-info to allow use of more than one LDAP
;;        service.
;;      - Make ldap-do-search a bit more generic (you can now specify
;;        the attribute you're after, as well as the attribute name of
;;        the search key).
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Variables:
;;
(defvar ldap-host-info
  '((four11
     (comment . "Four11 public LDAP service")
     (host . "ldap.four11.com")
     (maxhits . "100"))
    (bigfoot
     (comment . "BigFoot public LDAP service")
     (host . "ldap.bigfoot.com")
     (maxhits . "100"))
    (infospace
     (comment . "InfoSpace public LDAP service")
     (host . "ldap.infospace.com")
     (maxhits . "100")
     (base-dn . "c=US"))
    (whowhere
     (comment . "WhoWhere public LDAP service")
     (host . "ldap.whowhere.com")
     (maxhits . "100")))
  "List of ldap hosts and their properties.
Format is something like the following :

((mycompany
  (comment . \"MyCompany's LDAP service\")
  (host . \"ldap.company.com.au\")
  (port . \"389\")
  (maxhits . \"100\")
  (base-dn . \"o=My Company, c=AU\")))

the first line's \"mycompany\" is just a random identifier for use
with ldap-default-host.  Most of the others are optional (except of
course, the host ! :)")

(defvar ldap-default-host 'four11
  "Default ldap host to use")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
;;
(defun ldap-get-host-attr (attr &optional host)
  "Return attribute ATTR for HOST from the ldap info list"
  (cdr (assoc attr (assoc (if host host ldap-default-host) ldap-host-info)))
)

(defun ldap-do-search (attr-wanted searchkey &optional searchkeytype ldap-host)
  "Do an LDAP search.
ATTR-WANTED is the attribute we want returned, eg. \"mail\".
SEARCHKEY is pretty self-explanatory, eg. \"Andrew Cosgriff\".
Optional args -
 SEARCHKEYTYPE specifies the attribute type of the searchkey (if it isn't
the person's full name (which is normall called \"cn\")
 LDAP-HOST if you want a server other than the default."
  (let ((ldap-search-buffer (get-buffer-create "*ldap-search*"))
	(host (ldap-get-host-attr 'host ldap-host))
	(port (ldap-get-host-attr 'port ldap-host))
	(base-dn (ldap-get-host-attr 'base-dn ldap-host))
	(maxhits (ldap-get-host-attr 'maxhits ldap-host))
	(arglist) (ldap-result)
	)
    (save-excursion
      (set-buffer ldap-search-buffer)
      (delete-region (point-min) (point-max))
      (if (not (or (equal nil host) (equal "" host)))
	  (setq arglist (nconc arglist (list (format "-h%s" host)))))
      (if (not (or (equal nil port) (equal "" port)))
	  (setq arglist (nconc arglist (list (format "-p%s" port)))))
      (if (not (or (equal nil base-dn) (equal "" base-dn)))
	  (setq arglist (nconc arglist (list (format "-b%s" base-dn)))))
      (if (not (or (equal nil maxhits) (equal "" maxhits)))
	  (setq arglist (nconc arglist (list (format "-z%s" maxhits)))))
      (setq ldap-result
	     (eval `(call-process "ldapsearch" nil ldap-search-buffer nil
				  ,@arglist
				  (format
				   "(&(objectclass=person)(%s=%s))"
				   (if searchkeytype searchkeytype "cn")
				   searchkey)
				  ;;
				  ;; Note - if using Four11, and we're
				  ;; after a CN, telling ldapsearch
				  ;; that we only want it to return
				  ;; the CN results in no output.
				  ;; Hmm.
				  ;;
				  attr-wanted)))
      (if (equal 0 ldap-result)
	  (progn
	    (goto-char (point-min))
	    (forward-line)
	    (if (re-search-forward (concat "^" attr-wanted "=\\(.*\\)$") nil t)
		(match-string 1)
	      nil))
	nil))))

(defun ldap-mail-search (name)
  "Do an LDAP search for NAME's email address and display in echo area."
  (interactive "sName to search for : ")
  (message "Performing LDAP Search for mail address...")
  (let ((addr (ldap-do-search "mail" name)))
    (if (not (stringp addr))
	(message "User not found")
      (message addr))))

(defun insert-ldap-mail-search (name)
  "Do an LDAP search for NAME's email address and insert in buffer."
  (interactive "sName to search for : ")
  (message "Performing LDAP Search for mail address...")
  (let ((addr (ldap-do-search "mail" name)))
    (if (not (stringp addr))
	(message "User not found")
      (progn (insert addr) (message "")))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(provide 'ldap)
;;; ldap ends here

--Multipart_Wed_May_21_20:48:42_1997-1
Content-Type: text/plain; charset=US-ASCII

-- 
 - Andrew J. Cosgriff -                  ajc@bing.wattle.id.au    (PGP/MIME ok)
 +61 3 9905 1165 (bh) 9905 4746 (fax)    http://www-personal.monash.edu.au/~ajc
          Look!  A ladder!  Maybe it leads to heaven, or a sandwich!

--Multipart_Wed_May_21_20:48:42_1997-1--

