searchrequest scope handling (fixed by Thomas Walpuski)

add (primitive) auth support
This commit is contained in:
leitner
2002-05-14 20:11:36 +00:00
parent 6c7c32c1d1
commit 1d03b1e60f
9 changed files with 129 additions and 14 deletions

View File

@@ -12,3 +12,8 @@ data
dumpidx
parse
tinyldap_debug
attic
doit
idx2ldif
ldap-capture
server

View File

@@ -23,6 +23,8 @@ ldif.a: ldif_parse.o ldap_match.o ldap_match_mapped.o
storage.a: strstorage.o strduptab.o mstorage_add.o mduptab_add.o
auth.a: auth.o
DIET=/opt/diet/bin/diet -Os
CC=gcc
CFLAGS=-pipe -I. -Wall -W
@@ -43,7 +45,7 @@ endif
t1 parse: ldif.a storage.a
t2: ldap.a asn1.a
t3 t4 t5 addindex: storage.a
tinyldap tinyldap_standalone tinyldap_debug: ldif.a storage.a
tinyldap tinyldap_standalone tinyldap_debug: ldif.a storage.a auth.a
bindrequest tinyldap tinyldap_standalone tinyldap_debug ldapclient ldapclient_str: ldap.a asn1.a
tinyldap_standalone: tinyldap.c

2
THANKS
View File

@@ -3,3 +3,5 @@ Trevor Harrison found a bug in fmt_asn1tag for the multibyte encoding.
David Lichteblau found lots of problems in the ASN.1 code.
Özgür Kesim helped fix the substring search.
Thomas Walpuski has found lots of problems with the LDAP code.

View File

@@ -56,7 +56,10 @@ int main(int argc,char* argv[]) {
for (i=0; i<attribute_count; ++i) {
uint32 j;
uint32_unpack(x,&j);
if (!strcmp(map+j,argv[2])) {
buffer_puts(buffer_1,map+j); buffer_putsflush(buffer_1,"\n");
if (!strcasecmp(map+j,"dn")) dn=j;
if (!strcasecmp(map+j,"objectClass")) objectClass=j;
if (!strcasecmp(map+j,argv[2])) {
buffer_putsflush(buffer_2,"found attribute!\n");
wanted=j; casesensitive=x+attribute_count*4-map;
uint32_unpack(map+casesensitive,&j);
@@ -64,10 +67,7 @@ int main(int argc,char* argv[]) {
buffer_putsflush(buffer_2,"case sensitivity flag is nonzero?!\n");
return 1;
}
} else if (!strcmp(map+j,"dn"))
dn=j;
else if (!strcmp(map+j,"objectClass"))
objectClass=j;
}
x+=4;
}
if (!wanted) {
@@ -90,10 +90,12 @@ int main(int argc,char* argv[]) {
uint32_unpack(x+8,&k);
mstorage_add(&idx,(char*)&k,4);
++counted;
x+=j*8;
} else if (wanted==objectClass) {
uint32_unpack(x+12,&k);
mstorage_add(&idx,(char*)&k,4);
++counted;
x+=j*8;
} else {
x+=16;
for (; j>2; --j) {

22
auth.c Normal file
View File

@@ -0,0 +1,22 @@
#include <md5.h>
#include "ldap.h"
#include "auth.h"
#include "str.h"
#include "textcode.h"
#include "byte.h"
int check_password(const char* fromdb,struct string* plaintext) {
if (str_start(fromdb,"{MD5}")) {
char digest[17];
char md5[40];
MD5_CTX c;
MD5Init(&c);
MD5Update(&c,plaintext->s,plaintext->l);
MD5Final(digest,&c);
digest[16]=0;
fmt_hexdump(md5,digest,16);
if (byte_equal(md5,32,fromdb+5))
return 1;
}
return 0;
}

7
auth.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _AUTH_H
#define _AUTH_H
/* return non-zero if the password matches */
int check_password(const char* fromdb,struct string* plaintext);
#endif

View File

@@ -50,6 +50,17 @@ int ldap_match_present(uint32 ofs,uint32 attrofs) {
return 0;
}
uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs) {
uint32 j,k;
if (attrofs==dn_ofs) return uint32_read(map+ofs+8);
if (attrofs==objectClass_ofs) return uint32_read(map+ofs+12);
uint32_unpack(map+ofs,&j);
for (k=2; k<j; ++k)
if (uint32_read(map+ofs+k*8)==attrofs)
return uint32_read(map+ofs+k*8+4);
return 0;
}
/* return non-zero if the record matches the search filter */
int ldap_matchfilter_mapped(uint32 ofs,struct Filter* f) {
struct Filter* y=f->x;
@@ -165,7 +176,7 @@ int ldap_match_mapped(uint32 ofs,struct SearchRequest* sr) {
return 0;
}
/* we want "o=foo, o=bar" and "o=FOO,o=baR" to be equal */
if (sr->baseObject.l && !(l=match(sr->baseObject.s,sr->baseObject.l,map+k))) {
if (sr->baseObject.l && !match(sr->baseObject.s,sr->baseObject.l,map+k)) {
// puts("fail: not suffix");
return 0;
}
@@ -175,7 +186,7 @@ int ldap_match_mapped(uint32 ofs,struct SearchRequest* sr) {
case baseObject: if (l==sr->baseObject.l) break; return 0;
default:
i=str_chr(map+k,',');
if (i+2>=sr->baseObject.l-l) break;
if (i+2>=l-sr->baseObject.l) break;
return 0;
}
return ldap_matchfilter_mapped(ofs,sr->filter);

1
ldif.h
View File

@@ -25,3 +25,4 @@ int ldif_parse(const char* filename);
int ldap_match(struct ldaprec* r,struct SearchRequest* sr);
int ldap_match_mapped(uint32 ofs,struct SearchRequest* sr);
int ldap_match_present(uint32 ofs,uint32 attrofs);
uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs);

View File

@@ -1,5 +1,6 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "byte.h"
#include "buffer.h"
#include "ldap.h"
@@ -7,13 +8,14 @@
#include "open.h"
#include "mmap.h"
#include "uint32.h"
#include "auth.h"
#ifdef STANDALONE
#include "socket.h"
#include "ip6.h"
#include <wait.h>
#endif
#define verbose 0
#define verbose 1
#define debug 1
char* map;
@@ -24,7 +26,7 @@ uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table;
uint32 record_set_length;
/* some pre-looked-up attribute offsets to speed up ldap_match_mapped */
uint32 dn_ofs,objectClass_ofs;
uint32 dn_ofs,objectClass_ofs,userPassword_ofs;
#define BUFSIZE 8192
@@ -215,8 +217,9 @@ static uint32 findrec(uint32 dat) {
while ((top>=bottom)) {
uint32 mid=(top+bottom)/2;
uint32 l;
l=uint32_read(map+uint32_read(&records[mid])+8);
if (l<dat) {
if (l<=dat) {
if (mid>=record_count-1)
l=uint32_read(map+uint32_read(&records[0])+12);
else
@@ -548,6 +551,64 @@ int handle(int in,int out) {
buffer_putulong(buffer_2,method);
buffer_putsflush(buffer_2,".\n");
}
if (name.l) {
struct Filter f;
struct string password;
f.type=EQUAL; f.attrofs=dn_ofs;
scan_ldapstring(buf+res+tmp,buf+res+len,&password);
f.ava.desc.l=2; f.ava.desc.s="dn";
f.ava.value=name;
f.next=0;
if (!indexable(&f)) {
authfailure:
{
char outbuf[1024];
int s=100;
int len=fmt_ldapbindresponse(outbuf+s,48,"","authentication failure","");
int hlen=fmt_ldapmessage(0,messageid,BindResponse,len);
fmt_ldapmessage(outbuf+s-hlen,messageid,BindResponse,len);
write(out,outbuf+s-hlen,len+hlen);
continue;
}
} else {
unsigned long* result;
unsigned long i,done;
result=alloca(record_set_length*sizeof(unsigned long));
useindex(&f,result);
done=0;
for (i=0; i<record_set_length; ++i)
if (result[i])
done=1;
done=0;
for (i=0; i<record_count; ) {
if (!result[i/(8*sizeof(long))]) {
i+=8*sizeof(long);
continue;
}
for (; i<record_count; ++i) {
if (isset(result,i)) {
uint32 j;
const char* c;
uint32_unpack(map+indices_offset+4*i,&j);
if (!(j=ldap_find_attr_value(j,userPassword_ofs)))
goto authfailure;
c=map+j;
#if 0
buffer_puts(buffer_2,"compare ");
buffer_puts(buffer_2,c);
buffer_puts(buffer_2," with ");
buffer_put(buffer_2,f.ava.value.s,f.ava.value.l);
buffer_putsflush(buffer_2,".\n");
#endif
if (check_password(c,&password))
done=1;
}
}
}
if (!done) goto authfailure;
}
}
{
char outbuf[1024];
int s=100;
@@ -600,7 +661,6 @@ int handle(int in,int out) {
#if (debug != 0)
if (debug) buffer_putsflush(buffer_2,"query can be answered with index!\n");
#endif
record_set_length=(record_count+sizeof(unsigned long)*8-1) / (sizeof(long)*8);
result=alloca(record_set_length*sizeof(unsigned long));
/* Use the index to find matching data. Put the offsets
* of the matches in a table. Use findrec to locate
@@ -719,19 +779,22 @@ int main() {
uint32_unpack(map+2*4,&record_count);
uint32_unpack(map+3*4,&indices_offset);
uint32_unpack(map+4*4,&size_of_string_table);
record_set_length=(record_count+sizeof(unsigned long)*8-1) / (sizeof(long)*8);
/* look up "dn" and "objectClass" */
{
char* x=map+5*4+size_of_string_table;
unsigned int i;
dn_ofs=objectClass_ofs=0;
dn_ofs=objectClass_ofs=userPassword_ofs=0;
for (i=0; i<attribute_count; ++i) {
uint32 j;
j=uint32_read(x);
if (!strcmp("dn",map+j))
dn_ofs=j;
else if (!strcmp("objectClass",map+j))
else if (!strcasecmp("objectClass",map+j))
objectClass_ofs=j;
else if (!strcasecmp("userPassword",map+j))
userPassword_ofs=j;
x+=4;
}
if (!dn_ofs || !objectClass_ofs) {