integrate LDIF parsing and write a matching routine.

Make tinyldap call the matching routine.
This commit is contained in:
leitner
2002-01-15 01:58:28 +00:00
parent 0fe1e3e9eb
commit dae713be6b
5 changed files with 134 additions and 14 deletions

View File

@@ -14,7 +14,7 @@ scan_ldapstring.o scan_ldapsearchfilter.o scan_ldapsearchrequest.o \
freefilter.o freeava.o scan_ldapava.o fmt_ldapsearchresultentry.o \
fmt_ldapstring.o freepal.o scan_ldapsearchresultentry.o \
ldif.a: ldif_parse.o
ldif.a: ldif_parse.o ldap_match.o strduptab.o strstorage.o
DIET=diet -Os
CC=gcc
@@ -33,7 +33,7 @@ endif
%: %.c
$(DIET) $(CC) $(CFLAGS) -o $@ $^ -lowfat
t1: strduptab.o strstorage.o
t1:
t2: ldap.a asn1.a
bindrequest tinyldap ldapclient: ldap.a asn1.a

13
README
View File

@@ -1,14 +1,17 @@
Please read ldap.h and asn1.h for an overview of the API.
Example code using the high level API is in tinyldap and ldapclient.
This will be encapsulated some more eventually. The next steps are:
This will be encapsulated some more eventually.
Tinyldap now not only parses incoming search requests, it also performs
a search on the data structure we parsed from the flat LDIF file! When
I plug in fmt_ldapsearchresultentry and fmt_ldapsearchresultdone, we
have a minimal LDAP server!
The next steps are:
- integrate the LDIF parser from t1.c
- write fmt_ldapsearchresponse
- write fmt_ldapsearchrequest and scan_ldapsearchresponse
Then we will have a minimal LDAP server!
ldapclient is the client test application. It connects to localhost,
makes a BindRequest and dumps the BindResponse in human readable form.

92
ldap_match.c Normal file
View File

@@ -0,0 +1,92 @@
#include "ldap.h"
#include "ldif.h"
#include "byte.h"
#include "str.h"
#include <unistd.h>
#include <stdio.h>
/* behave like strcmp */
static int matchstring(struct string* s,const char* c) {
int l,l1,i;
if (!c) return -1;
l1=l=strlen(c);
if (s->l<l1) l1=s->l;
i=byte_diff(s->s,l1,c);
if (i) return i;
/* one is a prefix of the other */
if (l==s->l) return 0;
if (c[l1]) /* is c the longer string? */
return c[l1];
return -(int)(s->s[l1]);
}
/* look up value of an attribute for an LDIF record.
* Return NULL if not found */
static const char* findattr(struct ldaprec* f,struct string* name) {
int i;
if (!matchstring(name,"dn")) return f->dn;
if (!matchstring(name,"mail")) return f->mail;
if (!matchstring(name,"sn")) return f->sn;
if (!matchstring(name,"cn")) return f->cn;
for (i=0; i<ATTRIBS; ++i)
if (!matchstring(name,f->a[i].name))
return f->a[i].value;
return 0;
}
/* return non-zero if the record matches the search filter */
int ldap_matchfilter(struct ldaprec* s,struct Filter* f) {
struct Filter* y=f->x;
if (!f) return 1;
switch (f->type) {
case AND:
while (y) {
if (!ldap_matchfilter(s,y)) return 0;
y=y->next;
}
return 1;
case OR:
while (y) {
if (ldap_matchfilter(s,y)) return 1;
y=y->next;
}
return 0;
case NOT:
return !ldap_matchfilter(s,f->x);
case EQUAL:
// printf(" -> \"%s\" vs. \"%.*s\"\n",findattr(s,&f->ava.desc),f->ava.value.l,f->ava.value.s);
if (matchstring(&f->ava.value,findattr(s,&f->ava.desc))) return 0;
// puts("yes!!!");
break;
default:
write(2,"foo\n",4);
return 0;
}
return 1;
}
/* return non-zero if the record matches the search request */
int ldap_match(struct ldaprec* r,struct SearchRequest* sr) {
int l=strlen(r->dn);
int i;
// printf("comparing \"%s\" and \"%.*s\"\n",r->dn,(int)sr->baseObject.l,sr->baseObject.s);
/* first see if baseObject is a suffix of dn */
if (sr->baseObject.l>l) {
// puts("fail: baseObject longer than dn");
return 0;
}
if (!byte_equal(sr->baseObject.s,sr->baseObject.l,r->dn+l-sr->baseObject.l)) {
// puts("fail: not suffix");
return 0;
}
/* it is. If scope==wholeSubtree, the scope check is also done */
switch (sr->scope) {
case wholeSubtree: break;
case baseObject: if (l==sr->baseObject.l) break; return 0;
default:
i=str_chr(r->dn,',');
if (i+2>=sr->baseObject.l-l) break;
return 0;
}
return ldap_matchfilter(r,sr->filter);
}

2
ldif.h
View File

@@ -17,7 +17,7 @@ struct ldaprec {
extern const char* dn,* mail,* sn,* cn,* objectClass;
extern struct ldaprec *first;
int parse_ldif(const char* filename);
int ldif_parse(const char* filename);
/* return non-zero if the record matches the search request */
int ldap_match(struct ldaprec* r,struct SearchRequest* sr);

View File

@@ -9,12 +9,14 @@
int main() {
char buf[BUFSIZE];
int len=0;
ldif_parse("exp.ldif");
for (;;) {
int tmp=read(0,buf+len,BUFSIZE-len);
int res;
long messageid,op,Len;
if (tmp==0) { write(2,"eof!\n",5); return 0; }
if (tmp<1) { write(2,"error!\n",7); return 1; }
if (tmp==0)
if (!len) { write(2,"eof!\n",5); return 0; }
if (tmp<0) { write(2,"error!\n",7); return 1; }
len+=tmp;
res=scan_ldapmessage(buf,buf+len,&messageid,&op,&Len);
if (res>0) {
@@ -30,8 +32,9 @@ int main() {
{
long version,method;
struct string name;
res=scan_ldapbindrequest(buf+res,buf+res+len,&version,&name,&method);
if (res>=0) {
int tmp;
tmp=scan_ldapbindrequest(buf+res,buf+res+len,&version,&name,&method);
if (tmp>=0) {
buffer_puts(buffer_2,"bind request: version ");
buffer_putulong(buffer_2,version);
buffer_puts(buffer_2," for name \"");
@@ -49,11 +52,33 @@ int main() {
}
}
}
break;
case SearchRequest:
{
struct SearchRequest br;
int tmp;
if ((tmp=scan_ldapsearchrequest(buf+res,buf+res+len,&br))) {
struct ldaprec* r=first;
while (r) {
if (ldap_match(r,&br)) {
buffer_puts(buffer_2,"found: ");
buffer_puts(buffer_2,r->dn);
buffer_putsflush(buffer_2,"\n");
}
r=r->next;
}
}
}
break;
default:
exit(1);
}
Len+=res;
if (Len<len) {
byte_copyr(buf,len-Len,buf+len);
byte_copy(buf,len-Len,buf+Len);
len-=Len;
}
}
} else
exit(2);
}
}