[Raw Msg Headers][Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: router db API
Hi all,
Finally, I wrote my LDAP router db module. It tested with 2.99.48 and I
think it shouldn't have any problem with latest version if no API is changed.
With the module compiled, you can define your LDAP search query in a config
file. Here's one that I am currently testing.
---- $MAILSHARE/db/fullnames.ldap ------------------------------------------
#
# You must at least define "base", "ldaphost", "filter" & "attr".
#
base o=HKUST,c=HK
ldaphost ldap.ust.hk
ldapport 389
binddn cn=Directory Manager,o=HKUST,c=HK
passwd secret
filter (&(objectclass=person)(mailAlternateAddress=%s))
attr uid
scope sub
----------------------------------------------------------------------------
And then defined your relation DB in .cf file.
relation -mt ldap -f $MAILSHARE/db/fullnames.ldap fullnamemap
It supports the -m flag such that it will re-read the configuration if the
config file changed. Also, the search filter is a "sprintf" style
string that defines how the key is. It MUST be of the form "(attribute=%s)".
It should define a search that return AT MOST one entry & single attribute
value. If not, the map will only use the first entry and first attribute it
received.
In case of server or network error that the map failed to lookup, the mail
message will be deferred and hold with DEFER_IO_ERROR.
Mea, I haven't integrated this module into autoconfig as I don't know
enough how to do it :( Can you or anyone help to put it altogether? It
should compile well either with UM ldap 3.3 or Netscape Directory SDK 1.0.
=======================================================================
Lai Yiu Fai | Tel.: (852) 2358-6202
Centre of Computing Services | Fax.: (852) 2358-0967
& Telecommunications | E-mail: ccyflai@ust.hk
|
The Hong Kong University of | Clear Water Bay,
Science & Technology | Kowloon, Hong Kong.
/*
* Copyright 1997 by Lai Yiu Fai (ccyflai@ust.hk), all rights reserved.
*/
/* LINTLIBRARY */
#include "mailer.h"
#include "search.h"
#include "io.h"
#ifdef HAVE_LDAP
#include "lber.h"
#include "ldap.h"
typedef struct ldapmap_struct {
char *ldaphost;
int ldapport;
char *base;
char *binddn;
char *passwd;
int scope;
char *filter;
char *attr;
} LDAPMAP;
extern int deferit;
extern void v_set();
static LDAPMAP *
open_ldap(sip, caller)
struct search_info *sip;
char *caller;
{
LDAPMAP *lmap;
spkey_t symid;
struct spblk *spl;
FILE *fp;
char buf[256];
if (sip->file == NULL)
return NULL;
symid = symbol((u_char *)sip->file);
spl = sp_lookup(symid, spt_files);
if (spl == NULL || (lmap = (LDAPMAP *)spl->data) == NULL) {
if ((fp = fopen(sip->file, "r")) == NULL) {
++deferit;
v_set(DEFER, DEFER_IO_ERROR);
fprintf(stderr, "%s: cannot open %s!\n",
caller, sip->file);
return NULL;
}
lmap = (LDAPMAP *) malloc(sizeof(LDAPMAP));
if (spl == NULL)
sp_install(symid, (u_char *)lmap, 0, spt_files);
else
spl->data = (u_char *)lmap;
lmap->ldaphost = NULL;
lmap->ldapport = LDAP_PORT;
lmap->base = NULL;
lmap->binddn = NULL;
lmap->passwd = NULL;
lmap->scope = LDAP_SCOPE_SUBTREE;
lmap->filter = NULL;
lmap->attr = NULL;
while (fgets(buf, 256, fp) != NULL) {
register char *p = buf;
buf[strlen(buf)-1] = '\0'; /* chop() */
while (isascii(*p) && isspace(*p))
p++;
if (*p == '#') /* skip comment */
continue;
if (strncasecmp(p, "base", 4) == 0) {
p += 4;
while (isascii(*++p) && isspace(*p))
continue;
lmap->base = strdup(p);
}
else if (strncasecmp(p, "ldaphost", 8) == 0) {
p += 8;
while (isascii(*++p) && isspace(*p))
continue;
lmap->ldaphost = strdup(p);
}
else if (strncasecmp(p, "ldapport", 8) == 0) {
p += 8;
while (isascii(*++p) && isspace(*p))
continue;
lmap->ldapport = atoi(p);
}
else if (strncasecmp(p, "binddn", 6) == 0) {
p += 6;
while (isascii(*++p) && isspace(*p))
continue;
lmap->binddn = strdup(p);
}
else if (strncasecmp(p, "passwd", 6) == 0) {
p += 6;
while (isascii(*++p) && isspace(*p))
continue;
lmap->passwd = strdup(p);
}
else if (strncasecmp(p, "attr", 4) == 0) {
p += 4;
while (isascii(*++p) && isspace(*p))
continue;
lmap->attr = strdup(p);
}
else if (strncasecmp(p, "filter", 6) == 0) {
p += 6;
while (isascii(*++p) && isspace(*p))
continue;
lmap->filter = strdup(p);
}
else if (strncasecmp(p, "scope", 5) == 0) {
p += 5;
while (isascii(*++p) && isspace(*p))
continue;
if (strncasecmp(p, "base", 4) == 0)
lmap->scope = LDAP_SCOPE_BASE;
else if (strncasecmp(p, "one", 3) == 0)
lmap->scope = LDAP_SCOPE_ONELEVEL;
else if (strncasecmp(p, "sub", 3) == 0)
lmap->scope = LDAP_SCOPE_SUBTREE;
}
}
fclose(fp);
}
return lmap;
}
/*
* Search LDAP for a key attribute.
*/
struct conscell *
search_ldap(sip)
struct search_info *sip;
{
LDAPMAP *lmap;
LDAP *ld = NULL;
LDAPMessage *msg = NULL, *entry;
char filter[LDAP_FILT_MAXSIZ + 1];
char **vals = NULL;
char *attrs[] = {NULL, NULL};
struct conscell *tmp;
u_char *us = NULL;
if ((lmap = open_ldap(sip, "search_ldap")) == NULL)
return NULL;
if ((ld = ldap_open(lmap->ldaphost, lmap->ldapport)) == NULL ||
ldap_simple_bind_s(ld, lmap->binddn, lmap->passwd) != LDAP_SUCCESS) {
++deferit;
v_set(DEFER, DEFER_IO_ERROR);
fprintf(stderr, "search_ldap: cannot connect %s!\n",
lmap->ldaphost);
goto ldap_exit;
}
sprintf(filter, lmap->filter, (char *)sip->key);
attrs[0] = lmap->attr;
if (ldap_search_s(ld, lmap->base, lmap->scope, filter,
attrs, 0, &msg) != LDAP_SUCCESS) {
++deferit;
v_set(DEFER, DEFER_IO_ERROR);
fprintf(stderr, "search_ldap: ldap_search_s error!\n");
goto ldap_exit;
}
if ((entry = ldap_first_entry(ld, msg)) == NULL)
goto ldap_exit;
/* only get the first attribute, ignore others if defined */
if ((vals = ldap_get_values(ld, entry, lmap->attr)) != NULL)
/* if there is more that one use the first */
us = (u_char *)strsave(vals[0]);
ldap_exit:
if (vals != NULL)
ldap_value_free(vals);
if (msg != NULL)
ldap_msgfree(msg);
if (ld != NULL)
ldap_unbind_s(ld);
return (us) ? newstring(us) : NULL;
}
void
close_ldap(sip)
struct search_info *sip;
{
LDAPMAP *lmap;
struct spblk *spl;
spkey_t symid;
if (sip->file == NULL)
return;
symid = symbol((u_char *)sip->file);
spl = sp_lookup(symid, spt_modcheck);
if (spl != NULL)
sp_delete(spl, spt_modcheck);
spl = sp_lookup(symid, spt_files);
if (spl == NULL || (lmap = (LDAPMAP *)spl->data) == NULL)
return;
sp_install(symid, (u_char *)NULL, 0, spt_files);
if (lmap->base != NULL)
free(lmap->base);
if (lmap->ldaphost != NULL)
free(lmap->ldaphost);
if (lmap->binddn != NULL)
free(lmap->binddn);
if (lmap->passwd != NULL)
free(lmap->passwd);
if (lmap->filter != NULL)
free(lmap->filter);
if (lmap->attr != NULL)
free(lmap->attr);
free(lmap);
return;
}
int
modp_ldap(sip)
struct search_info *sip;
{
LDAPMAP *lmap;
struct stat stbuf;
struct spblk *spl;
spkey_t symid;
int rval;
if (sip->file == NULL
|| (lmap = open_ldap(sip, "modp_ldap")) == NULL)
return 0;
if (lstat(sip->file, &stbuf) < 0) {
fprintf(stderr, "modp_ldap: cannot fstat(\"%s\")!\n",
sip->file);
return 0;
}
if (stbuf.st_nlink == 0)
return 1; /* Unlinked underneath of us! */
symid = symbol((u_char *)sip->file);
spl = sp_lookup(symid, spt_modcheck);
if (spl != NULL) {
rval = ((long)stbuf.st_mtime != (long)spl->data
|| (long)stbuf.st_nlink != (long)spl->mark);
} else
rval = 0;
sp_install(symid, (u_char *)((long)stbuf.st_mtime),
stbuf.st_nlink, spt_modcheck);
return rval;
}
#endif /* HAVE_LDAP */
- Follow-Ups:
- Re: router db API
- From: Matti Aarnio <mea@nic.funet.fi> (Sat, 2 Aug 1997 15:17:19 +0300)