first shot at "addrequest" support
This commit is contained in:
2
Makefile
2
Makefile
@@ -65,7 +65,7 @@ t1 parse: ldif.a storage.a
|
||||
t2: ldap.a asn1.a
|
||||
t3 t4 t5 addindex: storage.a
|
||||
t6: storage.a
|
||||
tinyldap tinyldap_standalone tinyldap_debug: ldif.a auth.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
|
||||
idx2ldif: ldap.a
|
||||
dumpacls: ldap.a asn1.a
|
||||
|
||||
16
TODO
16
TODO
@@ -1,4 +1,20 @@
|
||||
|
||||
1. let tinyldap check for and incorporate updates from the journal in
|
||||
the hash table
|
||||
|
||||
2. support modify and delete requests (should be easy)
|
||||
|
||||
9. test whether the acls for add actually work
|
||||
|
||||
10. think about how to incorporate the journal into the database while
|
||||
still allowing new writes. Second journal? Switch to one-process
|
||||
model?
|
||||
|
||||
11. think about compressed database (maybe add first n chars of each
|
||||
string to index to avoid decompressing too much)
|
||||
|
||||
[old and obsolete]
|
||||
|
||||
- add auth method (openldap md5: base64, 4 bytes salt, direct hash)
|
||||
- add write support with an external journal
|
||||
We can also implement clustering through this journal.
|
||||
|
||||
@@ -58,7 +58,7 @@ uint32 hashmapped(uint32 ofs,int ignorecase) {
|
||||
unsigned char* c=(unsigned char*)map+ofs;
|
||||
uint32 len;
|
||||
if (*c) return ignorecase?hash_tolower(c,strlen((char*)c)):hash(c,strlen((char*)c));
|
||||
uint32_unpack(c+1,&len);
|
||||
uint32_unpack((char*)c+1,&len);
|
||||
return ignorecase?hash_tolower(c+5,len):hash(c+5,len);
|
||||
}
|
||||
|
||||
|
||||
53
asn1.h
53
asn1.h
@@ -1,6 +1,8 @@
|
||||
/* parser and formatter for ASN.1 DER encoding.
|
||||
* The parser can read BER encoding, too. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
enum asn1_tagclass {
|
||||
UNIVERSAL=(0<<6),
|
||||
APPLICATION=(1<<6),
|
||||
@@ -24,29 +26,32 @@ enum asn1_tag {
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 tag */
|
||||
unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long tag);
|
||||
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
unsigned long tag);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 length */
|
||||
unsigned int fmt_asn1length(char* dest,unsigned long l);
|
||||
size_t fmt_asn1length(char* dest,size_t l);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER. This only does the payload, not the tag
|
||||
* and length headers! */
|
||||
unsigned int fmt_asn1intpayload(char* dest,unsigned long l);
|
||||
size_t fmt_asn1intpayload(char* dest,unsigned long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER. This only does the payload, not the tag
|
||||
* and length headers! */
|
||||
unsigned int fmt_asn1sintpayload(char* dest,signed long l);
|
||||
size_t fmt_asn1sintpayload(char* dest,signed long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
unsigned int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l);
|
||||
size_t fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,unsigned long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l);
|
||||
size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,signed long val);
|
||||
|
||||
/* write any data type that does not require transformation in the least
|
||||
* amount of bytes, return number of bytes */
|
||||
@@ -54,11 +59,13 @@ unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
/* does not wrote the payload itself, just the header! First construct
|
||||
* the sequence/octet string so you know the length, then use
|
||||
* fmt_asn1transparent to write the header before it */
|
||||
unsigned int fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l);
|
||||
size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc,
|
||||
enum asn1_tagtype tt,enum asn1_tag tag,size_t len);
|
||||
|
||||
/* write string in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 OCTET STRING. */
|
||||
unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,unsigned long l);
|
||||
size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,const char* c,size_t l);
|
||||
|
||||
/* write ASN.1 OCTET STRING */
|
||||
#define fmt_asn1OCTETSTRING(dest,c,l) fmt_asn1string(dest,UNIVERSAL,PRIMITIVE,OCTET_STRING,c,l)
|
||||
@@ -85,32 +92,32 @@ unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype t
|
||||
* the return value is the number of bytes parsed or 0 for parse error */
|
||||
|
||||
/* parse ASN.1 tag into a tag class, tag type and tag number */
|
||||
unsigned int scan_asn1tag(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
||||
size_t scan_asn1tag(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
||||
|
||||
/* parse ASN.1 length */
|
||||
unsigned int scan_asn1length(const char* src,const char* max,unsigned long* length);
|
||||
size_t scan_asn1length(const char* src,const char* max,size_t* length);
|
||||
|
||||
/* parse ASN.1 integer with tag and length */
|
||||
unsigned int scan_asn1int(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag,
|
||||
long* l);
|
||||
size_t scan_asn1int(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag,
|
||||
long* val);
|
||||
|
||||
/* parse raw integer (payload after tag and length); internal helper */
|
||||
unsigned int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* i);
|
||||
size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* val);
|
||||
|
||||
/* parse string with tag and length.
|
||||
* Points s to the first byte in the string, and writes the length of
|
||||
* the string to l. */
|
||||
unsigned int scan_asn1string(const char* src,const char* max,
|
||||
size_t scan_asn1string(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,
|
||||
const char** s,unsigned long* l);
|
||||
const char** s,size_t* l);
|
||||
|
||||
/* the following expect a specific universal type and return a parse
|
||||
* error if the tag does not match that type */
|
||||
unsigned int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l);
|
||||
unsigned int scan_asn1INTEGER(const char* src,const char* max,signed long* l);
|
||||
unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
|
||||
unsigned int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l);
|
||||
unsigned int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len);
|
||||
unsigned int scan_asn1SET(const char* src,const char* max,unsigned long* len);
|
||||
size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l);
|
||||
size_t scan_asn1INTEGER(const char* src,const char* max,signed long* l);
|
||||
size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
|
||||
size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l);
|
||||
size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len);
|
||||
size_t scan_asn1SET(const char* src,const char* max,size_t* len);
|
||||
|
||||
7
bstr.h
7
bstr.h
@@ -1,11 +1,12 @@
|
||||
#include <stddef.h>
|
||||
|
||||
int bstr_diff(const char* a,const char* b);
|
||||
#define bstr_equal(s,t) (!bstr_diff((s),(t)))
|
||||
|
||||
int bstr_diff2(const char* a,const char* b,unsigned int blen);
|
||||
int bstr_diff2(const char* a,const char* b,size_t blen);
|
||||
#define bstr_equal2(s,t,l) (!bstr_diff2((s),(t),(l)))
|
||||
|
||||
int bstrlen(const char* a);
|
||||
int bstrstart(const char* a); /* offset of first byte of bstring */
|
||||
size_t bstrlen(const char* a);
|
||||
size_t bstrstart(const char* a); /* offset of first byte of bstring */
|
||||
|
||||
const char* bstrfirst(const char* a); /* pointer to first byte of bstring */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "uint32.h"
|
||||
#include "bstr.h"
|
||||
|
||||
int bstr_diff2(const char* a,const char* b,unsigned int blen) {
|
||||
int bstr_diff2(const char* a,const char* b,size_t blen) {
|
||||
const char* A,* B;
|
||||
int j;
|
||||
/* like str_diff, just for bstrs */
|
||||
@@ -23,7 +23,7 @@ int bstr_diff2(const char* a,const char* b,unsigned int blen) {
|
||||
} else
|
||||
if (b==B)
|
||||
return 1;
|
||||
if ((j=(*a-*b))) break;
|
||||
if ((j=((unsigned char)*a-(unsigned char)*b))) break;
|
||||
++a; ++b;
|
||||
}
|
||||
return j;
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
#include "uint32.h"
|
||||
#include "str.h"
|
||||
|
||||
int bstrlen(const char* a) {
|
||||
size_t bstrlen(const char* a) {
|
||||
if (*a) return str_len(a); else return uint32_read(a+1);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "bstr.h"
|
||||
#include "uint32.h"
|
||||
|
||||
int bstrstart(const char* a) {
|
||||
size_t bstrstart(const char* a) {
|
||||
if (*a) return 0; else return 5;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <asn1.h>
|
||||
|
||||
unsigned int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) {
|
||||
unsigned int len,tmp;
|
||||
size_t fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) {
|
||||
size_t len,tmp;
|
||||
/* first the tag */
|
||||
if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l);
|
||||
len=fmt_asn1tag(dest,tc,tt,tag);
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
#include <asn1.h>
|
||||
|
||||
unsigned int fmt_asn1intpayload(char* dest,unsigned long l) {
|
||||
unsigned int needed=sizeof l;
|
||||
unsigned int i;
|
||||
unsigned int fixup;
|
||||
size_t fmt_asn1intpayload(char* dest,unsigned long l) {
|
||||
size_t needed=sizeof l,i,fixup;
|
||||
for (i=1; i<needed; ++i) {
|
||||
if (!(l>>(i*8)))
|
||||
break;
|
||||
}
|
||||
fixup=(l>>((i-1)*8))&0x80 ? 1 : 0;
|
||||
if (dest) {
|
||||
unsigned int j=i;
|
||||
size_t j=i;
|
||||
if (fixup) *dest++=0;
|
||||
while (j) {
|
||||
--j;
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 length */
|
||||
unsigned int fmt_asn1length(char* dest,unsigned long l) {
|
||||
size_t fmt_asn1length(char* dest,size_t l) {
|
||||
/* encoding is either l%128 or (0x80+number of bytes,bytes) */
|
||||
int needed=(sizeof l);
|
||||
int i;
|
||||
size_t needed=(sizeof l),i;
|
||||
if (l<128) {
|
||||
if (dest) *dest=l&0x7f;
|
||||
return 1;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <asn1.h>
|
||||
|
||||
unsigned int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) {
|
||||
unsigned int len,tmp;
|
||||
size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) {
|
||||
size_t len,tmp;
|
||||
/* first the tag */
|
||||
if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l);
|
||||
len=fmt_asn1tag(dest,tc,tt,tag);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include <asn1.h>
|
||||
|
||||
unsigned int fmt_asn1sintpayload(char* dest,signed long l) {
|
||||
unsigned int needed=sizeof l;
|
||||
unsigned int i;
|
||||
size_t fmt_asn1sintpayload(char* dest,signed long l) {
|
||||
size_t needed=sizeof l,i;
|
||||
signed long tmp=0x7f;
|
||||
if (l>=0) return fmt_asn1intpayload(dest,l);
|
||||
for (i=1; i<needed; ++i) {
|
||||
@@ -12,7 +11,7 @@ unsigned int fmt_asn1sintpayload(char* dest,signed long l) {
|
||||
tmp=(tmp<<8)|0xff;
|
||||
}
|
||||
if (dest) {
|
||||
int j=i;
|
||||
size_t j=i;
|
||||
while (j) {
|
||||
--j;
|
||||
*dest=(l>>(j*8))&0xff;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "asn1.h"
|
||||
#include "byte.h"
|
||||
|
||||
unsigned int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,unsigned long l) {
|
||||
int len;
|
||||
size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,size_t l) {
|
||||
size_t len;
|
||||
if (l>(size_t)-100) return (size_t)-1;
|
||||
len=fmt_asn1transparent(dest,tc,tt,tag,l);
|
||||
if (dest) byte_copy(dest+len,l,c);
|
||||
return len+l;
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 tags */
|
||||
unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) {
|
||||
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) {
|
||||
/* encoding is either l%128 or (0x1f,...) */
|
||||
int needed=(sizeof l)*7/8;
|
||||
int i;
|
||||
size_t needed=(sizeof l)*7/8,i;
|
||||
if (l<0x1f) {
|
||||
if (dest) *dest=(int)tc+(int)tt+(l&0x1f);
|
||||
return 1;
|
||||
@@ -14,7 +13,7 @@ unsigned int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,u
|
||||
if (!(l>>(i*7)))
|
||||
break;
|
||||
if (dest) {
|
||||
int j=i;
|
||||
size_t j=i;
|
||||
*dest=(int)tc+(int)tt+0x1f; ++dest;
|
||||
while (j) {
|
||||
--j;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "byte.h"
|
||||
|
||||
unsigned int fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) {
|
||||
unsigned int len,tmp;
|
||||
size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,size_t l) {
|
||||
size_t len,tmp;
|
||||
/* first the tag */
|
||||
len=fmt_asn1tag(dest,tc,tt,tag);
|
||||
tmp=fmt_asn1length(dest?dest+len:dest,l);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
static int doit(char* dest,struct AttributeDescriptionList* adl,int seq) {
|
||||
static size_t doit(char* dest,struct AttributeDescriptionList* adl,int seq) {
|
||||
struct AttributeDescriptionList* x=adl;
|
||||
long sum=0;
|
||||
int tmp;
|
||||
size_t sum=0,tmp;
|
||||
while (x) {
|
||||
sum+=fmt_asn1OCTETSTRING(0,0,x->a.l);
|
||||
x=x->next;
|
||||
@@ -25,10 +24,10 @@ static int doit(char* dest,struct AttributeDescriptionList* adl,int seq) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
unsigned int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
size_t fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
return doit(dest,adl,1);
|
||||
}
|
||||
|
||||
unsigned int fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
size_t fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl) {
|
||||
return doit(dest,adl,0);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapava(char* dest,struct AttributeValueAssertion* a) {
|
||||
long sum,l;
|
||||
size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a) {
|
||||
size_t sum,l;
|
||||
sum=fmt_ldapstring(dest,&a->desc);
|
||||
if (dest) dest+=sum;
|
||||
l=fmt_ldapstring(dest,&a->value);
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
#include "str.h"
|
||||
#include "rangecheck.h"
|
||||
|
||||
unsigned int fmt_ldapbindrequest(char* dest,long version,char* name,char* simple) {
|
||||
unsigned int l,sum;
|
||||
unsigned int nlen=str_len(name);
|
||||
size_t fmt_ldapbindrequest(char* dest,long version,char* name,char* simple) {
|
||||
size_t l,sum;
|
||||
size_t nlen=str_len(name);
|
||||
sum=l=fmt_asn1INTEGER(dest,version);
|
||||
if (dest) dest+=l;
|
||||
l=fmt_asn1OCTETSTRING(dest,name,nlen);
|
||||
sum+=l; if (dest) dest+=l;
|
||||
if (add_of(sum,sum,l)) return (size_t)-1; if (dest) dest+=l;
|
||||
// sum+=l; if (dest) dest+=l;
|
||||
nlen=str_len(simple);
|
||||
l=fmt_asn1string(dest,PRIVATE,PRIMITIVE,0,simple,nlen);
|
||||
if (dest) dest+=l;
|
||||
return sum+l;
|
||||
if (add_of(sum,sum,l)) return (size_t)-1; if (dest) dest+=l;
|
||||
return sum;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapmessage(char* dest,long messageid,long op,long len) {
|
||||
unsigned int l,l2,l3;
|
||||
size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len) {
|
||||
size_t l,l2,l3;
|
||||
l2=fmt_asn1INTEGER(0,messageid);
|
||||
l3=fmt_asn1transparent(0,APPLICATION,CONSTRUCTED,op,len);
|
||||
l=fmt_asn1SEQUENCE(dest,len+l2+l3);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
||||
size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
||||
// int l,l2,sum;
|
||||
long sum,l,l2;
|
||||
size_t sum,l,l2;
|
||||
if (!pal) return 0;
|
||||
sum=fmt_ldapstring(0,&pal->type);
|
||||
/* look how much space the adl needs */
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#include "ldap.h"
|
||||
#include "str.h"
|
||||
|
||||
unsigned int fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral) {
|
||||
unsigned int l,sum=0;
|
||||
unsigned int nlen;
|
||||
size_t fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral) {
|
||||
size_t l,sum=0,nlen;
|
||||
sum=l=fmt_asn1ENUMERATED(dest,result);
|
||||
if (dest) dest+=l;
|
||||
nlen=str_len(matcheddn);
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
extensibleMatch [9] MatchingRuleAssertion }
|
||||
*/
|
||||
|
||||
int fmt_ldapsubstring(char* dest,struct Substring* s) {
|
||||
long sum=0,tmp=0;
|
||||
size_t fmt_ldapsubstring(char* dest,struct Substring* s) {
|
||||
size_t sum=0,tmp=0;
|
||||
while (s) {
|
||||
tmp=fmt_asn1string(dest,PRIVATE,PRIMITIVE,s->substrtype,s->s.s,s->s.l);
|
||||
if (dest) dest+=tmp; sum+=tmp;
|
||||
@@ -27,9 +27,8 @@ int fmt_ldapsubstring(char* dest,struct Substring* s) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
||||
long sum=0,tmp;
|
||||
long savesum;
|
||||
size_t fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
||||
size_t sum=0,tmp,savesum;
|
||||
if (!f)
|
||||
return 0;
|
||||
switch (f->type) {
|
||||
@@ -40,7 +39,7 @@ unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
||||
case SUBSTRING:
|
||||
{
|
||||
char* nd=dest;
|
||||
long l=0,tmp=0;
|
||||
size_t l,tmp;
|
||||
|
||||
tmp=fmt_ldapsubstring(0,f->substrings);
|
||||
l=fmt_ldapstring(nd,&f->ava.desc);
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "str.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapsearchfilterstring(char* dest,struct Filter* f) {
|
||||
unsigned int len;
|
||||
size_t fmt_ldapsearchfilterstring(char* dest,struct Filter* f) {
|
||||
size_t len;
|
||||
len = fmt_str(dest,"(");
|
||||
switch (f->type) {
|
||||
case AND: case OR: case NOT:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) {
|
||||
int l,sum=0;
|
||||
size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) {
|
||||
size_t l,sum=0;
|
||||
sum=fmt_ldapstring(dest,&sr->baseObject);
|
||||
if (dest) dest+=sum;
|
||||
l=fmt_asn1ENUMERATED(dest,sr->scope);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) {
|
||||
unsigned int l,sum=0;
|
||||
size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) {
|
||||
size_t l,sum=0;
|
||||
sum=fmt_ldapstring(dest,&sre->objectName);
|
||||
if (dest) dest+=sum;
|
||||
l=fmt_asn1SEQUENCE(dest,fmt_ldappal(0,sre->attributes));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int fmt_ldapstring(char* dest,struct string* s) {
|
||||
size_t fmt_ldapstring(char* dest,struct string* s) {
|
||||
return fmt_asn1OCTETSTRING(dest,s->s,s->l);
|
||||
}
|
||||
|
||||
17
idx2ldif.c
17
idx2ldif.c
@@ -6,27 +6,32 @@
|
||||
#include "uint32.h"
|
||||
#include "bstr.h"
|
||||
#include "textcode.h"
|
||||
#include <assert.h>
|
||||
|
||||
static void dumpbstr(const char* c) {
|
||||
int printable=1;
|
||||
int i,l;
|
||||
size_t i,l,up;
|
||||
const char* d;
|
||||
l=bstrlen(c);
|
||||
d=bstrfirst(c);
|
||||
for (i=0; i<l; ++i)
|
||||
if (!isprint(d[i])) { printable=0; break; }
|
||||
if (printable) {
|
||||
up=fmt_ldapescape(0,d,l);
|
||||
assert(up>=l);
|
||||
if (up==l) {
|
||||
buffer_puts(buffer_1," ");
|
||||
if (*c)
|
||||
buffer_puts(buffer_1,c);
|
||||
else
|
||||
buffer_put(buffer_1,bstrfirst(c),bstrlen(c));
|
||||
} else {
|
||||
} else if (up > (l+2)/3*4) {
|
||||
char* e;
|
||||
i=fmt_base64(0,d,l);
|
||||
e=alloca(i+1);
|
||||
buffer_puts(buffer_1,": ");
|
||||
buffer_put(buffer_1,e,fmt_base64(e,d,l));
|
||||
} else {
|
||||
char* e;
|
||||
e=alloca(up);
|
||||
buffer_puts(buffer_1,": ");
|
||||
buffer_put(buffer_1,e,fmt_ldapescape(e,d,l));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
79
ldap.h
79
ldap.h
@@ -1,10 +1,11 @@
|
||||
#ifndef _LDAP_H
|
||||
#define _LDAP_H
|
||||
|
||||
#include "uint32.h"
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
struct string {
|
||||
unsigned long l;
|
||||
size_t l;
|
||||
const char* s;
|
||||
};
|
||||
|
||||
@@ -19,7 +20,7 @@ struct AttributeValueAssertion {
|
||||
|
||||
struct AttributeDescriptionList {
|
||||
struct string a;
|
||||
uint32 attrofs;
|
||||
uint32_t attrofs;
|
||||
struct AttributeDescriptionList *next;
|
||||
};
|
||||
|
||||
@@ -42,8 +43,8 @@ enum FilterType {
|
||||
struct Filter {
|
||||
enum FilterType type;
|
||||
struct AttributeValueAssertion ava;
|
||||
uint32 attrofs; /* offset of attribute name in index */
|
||||
uint32 attrflag; /* "case sensitivity" flag from index */
|
||||
uint32_t attrofs; /* offset of attribute name in index */
|
||||
uint32_t attrflag; /* "case sensitivity" flag from index */
|
||||
struct Substring* substrings;
|
||||
struct AttributeDescriptionList *a;
|
||||
struct Filter* x,*next;
|
||||
@@ -152,40 +153,40 @@ void freefilter(struct Filter* f);
|
||||
void freeava(struct AttributeDescriptionList* a);
|
||||
void freepal(struct PartialAttributeList* a);
|
||||
|
||||
unsigned int scan_ldapstring(const char* src,const char* max,struct string* s);
|
||||
unsigned int scan_ldapmessage(const char* src,const char* max,
|
||||
unsigned long* messageid,unsigned long* op,
|
||||
unsigned long* len);
|
||||
unsigned int scan_ldapbindrequest(const char* src,const char* max,
|
||||
unsigned long* version,struct string* name,
|
||||
unsigned long* method);
|
||||
unsigned int scan_ldapbindresponse(const char* src,const char* max,
|
||||
unsigned long* result,struct string* matcheddn,
|
||||
struct string* errormessage,struct string* referral);
|
||||
unsigned int scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* a);
|
||||
unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f);
|
||||
unsigned int scan_ldapsearchrequest(const char* src,const char* max,struct SearchRequest* s);
|
||||
unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre);
|
||||
unsigned int scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
||||
struct string* matcheddn,struct string* errormessage,
|
||||
struct string* referral);
|
||||
unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m);
|
||||
unsigned int scan_ldapaddrequest(const char * src, const char * max, struct AddRequest * a);
|
||||
unsigned int scan_ldapsearchfilterstring(const char* src,struct Filter** f);
|
||||
size_t scan_ldapstring(const char* src,const char* max,struct string* s);
|
||||
size_t scan_ldapmessage(const char* src,const char* max,
|
||||
unsigned long* messageid,unsigned long* op,
|
||||
size_t* len);
|
||||
size_t scan_ldapbindrequest(const char* src,const char* max,
|
||||
unsigned long* version,struct string* name,
|
||||
unsigned long* method);
|
||||
size_t scan_ldapbindresponse(const char* src,const char* max,
|
||||
unsigned long* result,struct string* matcheddn,
|
||||
struct string* errormessage,struct string* referral);
|
||||
size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* a);
|
||||
size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f);
|
||||
size_t scan_ldapsearchrequest(const char* src,const char* max,struct SearchRequest* s);
|
||||
size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre);
|
||||
size_t scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
||||
struct string* matcheddn,struct string* errormessage,
|
||||
struct string* referral);
|
||||
size_t scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m);
|
||||
size_t scan_ldapaddrequest(const char* src, const char * max, struct AddRequest * a);
|
||||
size_t scan_ldapsearchfilterstring(const char* src,struct Filter** f);
|
||||
|
||||
unsigned int fmt_ldapstring(char* dest,struct string* s);
|
||||
unsigned int fmt_ldapmessage(char* dest,long messageid,long op,long len);
|
||||
unsigned int fmt_ldapbindrequest(char* dest,long version,char* name,char* simple);
|
||||
unsigned int fmt_ldapsearchfilter(char* dest,struct Filter* f);
|
||||
unsigned int fmt_ldapsearchrequest(char* dest,struct SearchRequest* s);
|
||||
unsigned int fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre);
|
||||
unsigned int fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral);
|
||||
unsigned int fmt_ldappal(char* dest,struct PartialAttributeList* pal);
|
||||
unsigned int fmt_ldapava(char* dest,struct AttributeValueAssertion* a);
|
||||
unsigned int fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl);
|
||||
unsigned int fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl);
|
||||
unsigned int fmt_ldapmodifyrequest(char* dest,struct ModifyRequest* m);
|
||||
unsigned int fmt_ldapsearchfilterstring(char* dest,struct Filter* f);
|
||||
size_t fmt_ldapstring(char* dest,struct string* s);
|
||||
size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len);
|
||||
size_t fmt_ldapbindrequest(char* dest,long version,char* name,char* simple);
|
||||
size_t fmt_ldapsearchfilter(char* dest,struct Filter* f);
|
||||
size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* s);
|
||||
size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre);
|
||||
size_t fmt_ldapresult(char* dest,long result,char* matcheddn,char* errormessage,char* referral);
|
||||
size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal);
|
||||
size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a);
|
||||
size_t fmt_ldapadl(char* dest,struct AttributeDescriptionList* adl);
|
||||
size_t fmt_ldapavl(char* dest,struct AttributeDescriptionList* adl);
|
||||
size_t fmt_ldapmodifyrequest(char* dest,struct ModifyRequest* m);
|
||||
size_t fmt_ldapsearchfilterstring(char* dest,struct Filter* f);
|
||||
|
||||
#define fmt_ldapbindresponse(a,b,c,d,e) fmt_ldapresult(a,b,c,d,e)
|
||||
#define fmt_ldapsearchresultdone(a,b,c,d,e) fmt_ldapresult(a,b,c,d,e)
|
||||
@@ -204,5 +205,7 @@ void free_ldapsearchresultentry(struct SearchResultEntry* e);
|
||||
|
||||
int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f);
|
||||
|
||||
int matchint(struct Filter* f,const char* t);
|
||||
int substringmatch(struct Substring* x,const char* attr,int ignorecase);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ extern long filelen;
|
||||
extern uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table;
|
||||
extern uint32 dn_ofs,objectClass_ofs;
|
||||
|
||||
static int substringmatch(struct Substring* x,const char* attr,int ignorecase) {
|
||||
int substringmatch(struct Substring* x,const char* attr,int ignorecase) {
|
||||
int (*diff)(const void* a, unsigned long len, const void* b);
|
||||
if (ignorecase)
|
||||
diff=case_diffb;
|
||||
@@ -66,7 +66,7 @@ uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int matchint(struct Filter* f,const char* t) {
|
||||
int matchint(struct Filter* f,const char* t) {
|
||||
int r;
|
||||
|
||||
if (f->attrflag&1)
|
||||
|
||||
@@ -72,7 +72,7 @@ found:
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern uint32 dn_ofs;
|
||||
extern uint32_t dn_ofs;
|
||||
|
||||
int ldap_matchfilter_sre(struct SearchResultEntry* sre,struct Filter* f) {
|
||||
struct PartialAttributeList* p;
|
||||
|
||||
18
ldapclient.c
18
ldapclient.c
@@ -9,12 +9,20 @@
|
||||
#include "socket.h"
|
||||
#include "ip4.h"
|
||||
#include "str.h"
|
||||
#include "textcode.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define BUFSIZE 8192
|
||||
|
||||
static void buffer_putescaped(buffer* b,const char* x,size_t l) {
|
||||
size_t needed=fmt_ldapescape(0,x,l);
|
||||
char* buf=alloca(needed);
|
||||
fmt_ldapescape(buf,x,l);
|
||||
buffer_put(b,buf,needed);
|
||||
}
|
||||
|
||||
static unsigned long messageid=1;
|
||||
|
||||
static int ldapbind(int sock) {
|
||||
@@ -118,7 +126,7 @@ usage:
|
||||
}
|
||||
shutdown(sock,SHUT_WR);
|
||||
{
|
||||
char buf[8192]; /* arbitrary limit, bad! */
|
||||
char buf[32*1024]; /* arbitrary limit, bad! */
|
||||
int len=0,tmp,tmp2;
|
||||
char* max;
|
||||
struct SearchResultEntry sre;
|
||||
@@ -158,16 +166,16 @@ nextmessage:
|
||||
|
||||
if (durchlauf==0) {
|
||||
buffer_puts(buffer_1,"dn: ");
|
||||
buffer_put(buffer_1,sre.objectName.s,sre.objectName.l);
|
||||
buffer_putescaped(buffer_1,sre.objectName.s,sre.objectName.l);
|
||||
buffer_puts(buffer_1,"\n");
|
||||
while (pal) {
|
||||
struct AttributeDescriptionList* adl=pal->values;
|
||||
do {
|
||||
buffer_puts(buffer_1," ");
|
||||
buffer_put(buffer_1,pal->type.s,pal->type.l);
|
||||
// buffer_puts(buffer_1," ");
|
||||
buffer_putescaped(buffer_1,pal->type.s,pal->type.l);
|
||||
buffer_puts(buffer_1,": ");
|
||||
if (adl) {
|
||||
buffer_put(buffer_1,adl->a.s,adl->a.l);
|
||||
buffer_putescaped(buffer_1,adl->a.s,adl->a.l);
|
||||
buffer_puts(buffer_1,"\n");
|
||||
adl=adl->next;
|
||||
if (!adl) break;
|
||||
|
||||
18
ldif.h
18
ldif.h
@@ -1,21 +1,21 @@
|
||||
#include "uint32.h"
|
||||
#include <inttypes.h>
|
||||
#include <ldap.h>
|
||||
|
||||
/* how many attributes do we allow per record? */
|
||||
#define ATTRIBS 100
|
||||
|
||||
struct attribute {
|
||||
uint32 name, value;
|
||||
uint32_t name, value;
|
||||
};
|
||||
|
||||
struct ldaprec {
|
||||
uint32 dn;
|
||||
int n; /* number of attributes */
|
||||
uint32_t dn;
|
||||
unsigned int n; /* number of attributes */
|
||||
struct attribute a[ATTRIBS];
|
||||
struct ldaprec* next;
|
||||
};
|
||||
|
||||
extern uint32 dn, mail, sn, cn, objectClass;
|
||||
extern uint32_t dn, mail, sn, cn, objectClass;
|
||||
extern struct ldaprec *first;
|
||||
extern unsigned long ldifrecords;
|
||||
|
||||
@@ -23,7 +23,7 @@ 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);
|
||||
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);
|
||||
int ldap_matchfilter_mapped(uint32 ofs,struct Filter* f);
|
||||
int ldap_match_mapped(uint32_t ofs,struct SearchRequest* sr);
|
||||
int ldap_match_present(uint32_t ofs,uint32_t attrofs);
|
||||
uint32_t ldap_find_attr_value(uint32_t ofs,uint32_t attrofs);
|
||||
int ldap_matchfilter_mapped(uint32_t ofs,struct Filter* f);
|
||||
|
||||
53
ldif_parse.c
53
ldif_parse.c
@@ -12,10 +12,11 @@
|
||||
#include "byte.h"
|
||||
#include "textcode.h"
|
||||
#include "stralloc.h"
|
||||
#include "uint32.h"
|
||||
|
||||
mduptab_t attributes,classes;
|
||||
mstorage_t stringtable;
|
||||
uint32 dn, objectClass;
|
||||
uint32_t dn, objectClass;
|
||||
unsigned long lines;
|
||||
|
||||
/* this is called after each record.
|
||||
@@ -27,11 +28,11 @@ unsigned long lines;
|
||||
* If the callback is NULL, a callback that always returns 1 is assumed.
|
||||
* */
|
||||
int (*ldif_parse_callback)(struct ldaprec* l);
|
||||
uint32 (*ldif_addstring_callback)(const char* s,unsigned long len);
|
||||
uint32_t (*ldif_addstring_callback)(const char* s,unsigned long len);
|
||||
|
||||
unsigned long ldifrecords;
|
||||
|
||||
static void addattribute(struct ldaprec** l,uint32 name,uint32 val) {
|
||||
static void addattribute(struct ldaprec** l,uint32_t name,uint32_t val) {
|
||||
if (name==dn) (*l)->dn=val; else
|
||||
if ((*l)->n<ATTRIBS) {
|
||||
(*l)->a[(*l)->n].name=name;
|
||||
@@ -80,28 +81,28 @@ static int unbase64(char* buf) {
|
||||
return destlen;
|
||||
}
|
||||
|
||||
uint32 (*ldif_addstring_callback)(const char* s,unsigned long len);
|
||||
uint32_t (*ldif_addstring_callback)(const char* s,unsigned long len);
|
||||
|
||||
static uint32 addstring(const char* s,unsigned long len) {
|
||||
static uint32_t addstring(const char* s,unsigned long len) {
|
||||
return mstorage_add(&stringtable,s,len);
|
||||
}
|
||||
|
||||
static long commit_string_bin(const char* s,unsigned long n) {
|
||||
unsigned int i;
|
||||
static char zero;
|
||||
uint32 x;
|
||||
uint32_t x;
|
||||
char intbuf[4];
|
||||
if (n==0 || (n==1 && s[0]==0)) goto encodebinary;
|
||||
for (i=0; i<n-1; ++i)
|
||||
if (!s[i]) {
|
||||
encodebinary:
|
||||
uint32_pack(intbuf,n);
|
||||
if ((x=ldif_addstring_callback(&zero,1))==(uint32)-1 || ldif_addstring_callback(intbuf,4)==(uint32)-1 || ldif_addstring_callback(s,n)==(uint32)-1) return -1;
|
||||
if ((x=ldif_addstring_callback(&zero,1))==(uint32_t)-1 || ldif_addstring_callback(intbuf,4)==(uint32_t)-1 || ldif_addstring_callback(s,n)==(uint32_t)-1) return -1;
|
||||
return x;
|
||||
}
|
||||
x=ldif_addstring_callback(s,n);
|
||||
if (s[n-1])
|
||||
if (ldif_addstring_callback(&zero,1)==(uint32)-1) return -1;
|
||||
if (ldif_addstring_callback(&zero,1)==(uint32_t)-1) return -1;
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@ static int parserec(buffer* b, struct ldaprec** l) {
|
||||
char buf[8192];
|
||||
int n,i,eof=0,ofs=0;
|
||||
unsigned int i2;
|
||||
int len,base64,binary;
|
||||
size_t len,base64,binary;
|
||||
stralloc payload={0,0,0};
|
||||
|
||||
if (!(*l=malloc(sizeof(struct ldaprec)))) {
|
||||
@@ -129,7 +130,7 @@ nomem:
|
||||
(*l)->next=0; (*l)->n=0;
|
||||
ldifrecords=0;
|
||||
do {
|
||||
uint32 tmp, val;
|
||||
uint32_t tmp, val;
|
||||
base64=binary=0;
|
||||
n=ofs+buffer_get_token(b,buf+ofs,8192-ofs,":",1);
|
||||
if (n==0) break;
|
||||
@@ -139,7 +140,7 @@ nomem:
|
||||
buf[i2]=0;
|
||||
if (str_equal("binary",buf+i2+1)) binary=1;
|
||||
}
|
||||
if ((tmp=mduptab_adds(&attributes,buf+i))==(uint32)-1) goto nomem;
|
||||
if ((tmp=mduptab_adds(&attributes,buf+i))==(uint32_t)-1) goto nomem;
|
||||
if (!stralloc_copys(&payload,"")) goto nomem;
|
||||
{
|
||||
char dummy;
|
||||
@@ -178,8 +179,12 @@ lookagain:
|
||||
if (base64) {
|
||||
len=unbase64(payload.s);
|
||||
if (!binary) { payload.s[len]=0; ++len; }
|
||||
} else
|
||||
len=n+1;
|
||||
} else {
|
||||
len=n;
|
||||
scan_ldapescape(payload.s,payload.s,&len);
|
||||
payload.s[len]=0;
|
||||
++len;
|
||||
}
|
||||
} else
|
||||
len=0;
|
||||
|
||||
@@ -192,11 +197,11 @@ lookagain:
|
||||
#endif
|
||||
|
||||
if (tmp==objectClass) {
|
||||
if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32)-1) goto nomem;
|
||||
if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32_t)-1) goto nomem;
|
||||
} else if (tmp==dn) {
|
||||
if ((val=add_normalized(payload.s,len))==(uint32)-1) goto nomem;
|
||||
if ((val=add_normalized(payload.s,len))==(uint32_t)-1) goto nomem;
|
||||
} else
|
||||
if ((val=commit_string_bin(payload.s,len))==(uint32)-1) goto nomem;
|
||||
if ((val=commit_string_bin(payload.s,len))==(uint32_t)-1) goto nomem;
|
||||
addattribute(l,tmp,val);
|
||||
|
||||
m=0;
|
||||
@@ -236,8 +241,12 @@ lookagain:
|
||||
if (base64) {
|
||||
len=unbase64(payload.s);
|
||||
if (!binary) { payload.s[len]=0; ++len; }
|
||||
} else
|
||||
len=n+1;
|
||||
} else {
|
||||
len=n;
|
||||
scan_ldapescape(payload.s,payload.s,&len);
|
||||
payload.s[len]=0;
|
||||
++len;
|
||||
}
|
||||
} else
|
||||
len=0;
|
||||
|
||||
@@ -250,16 +259,16 @@ lookagain:
|
||||
#endif
|
||||
|
||||
if (tmp==objectClass) {
|
||||
if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32)-1) goto nomem;
|
||||
if ((val=mduptab_add(&classes,payload.s,len-1))==(uint32_t)-1) goto nomem;
|
||||
} else if (tmp==dn) {
|
||||
if ((val=add_normalized(payload.s,payload.len))==(uint32)-1) goto nomem;
|
||||
if ((val=add_normalized(payload.s,payload.len))==(uint32_t)-1) goto nomem;
|
||||
} else
|
||||
if ((val=commit_string_bin(payload.s,len))==(uint32)-1) goto nomem;
|
||||
if ((val=commit_string_bin(payload.s,len))==(uint32_t)-1) goto nomem;
|
||||
addattribute(l,tmp,val);
|
||||
#endif
|
||||
} while (!eof);
|
||||
if (ldif_parse_callback && ldif_parse_callback(*l)==-1) return -1;
|
||||
if ((*l)->dn==(uint32)-1 && ((*l)->next)) {
|
||||
if ((*l)->dn==(uint32_t)-1 && ((*l)->next)) {
|
||||
struct ldaprec* m=(*l)->next;
|
||||
free((*l));
|
||||
(*l)=m;
|
||||
|
||||
@@ -14,5 +14,5 @@ typedef struct mduptable {
|
||||
|
||||
void mduptab_init(mduptab_t* t);
|
||||
void mduptab_init_reuse(mduptab_t* t,mstorage_t* s);
|
||||
long mduptab_add(mduptab_t* t,const char* s,unsigned int len);
|
||||
long mduptab_add(mduptab_t* t,const char* s,size_t len);
|
||||
long mduptab_adds(mduptab_t* t,const char* s);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "mduptab.h"
|
||||
#include "uint32.h"
|
||||
|
||||
long mduptab_add(mduptab_t* t,const char* s,unsigned int len) {
|
||||
long mduptab_add(mduptab_t* t,const char* s,size_t len) {
|
||||
unsigned int i;
|
||||
unsigned long* l=(unsigned long*)t->table.root;
|
||||
long x,bak;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#ifndef _MSTORAGE_H
|
||||
#define _MSTORAGE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* (optionally persistent) mmapped storage. */
|
||||
|
||||
typedef struct mstorage {
|
||||
char* root;
|
||||
unsigned long mapped,used;
|
||||
size_t mapped,used;
|
||||
int fd;
|
||||
} mstorage_t;
|
||||
|
||||
@@ -16,7 +18,7 @@ int mstorage_init_persistent(mstorage_t* p,int fd);
|
||||
/* Works like strstorage_add, but will return an
|
||||
* offset to mstorage_root, which is mmapped and may thus change. */
|
||||
/* offset -1 ==> error */
|
||||
long mstorage_add(mstorage_t* p,const char* s,unsigned long n);
|
||||
long mstorage_add(mstorage_t* p,const char* s,size_t n);
|
||||
|
||||
/* undo mapping */
|
||||
void mstorage_unmap(mstorage_t* p);
|
||||
@@ -26,6 +28,6 @@ void mstorage_unmap(mstorage_t* p);
|
||||
* char 0;
|
||||
* uint32 len;
|
||||
* char data[len] */
|
||||
long mstorage_add_bin(mstorage_t* p,const char* s,unsigned long n);
|
||||
long mstorage_add_bin(mstorage_t* p,const char* s,size_t n);
|
||||
|
||||
#endif
|
||||
|
||||
4
parse.c
4
parse.c
@@ -85,7 +85,7 @@ uint32 my_addstring(const char* s,unsigned long len) {
|
||||
|
||||
int ldif_callback(struct ldaprec* l) {
|
||||
char x[8]; /* temp buf for endianness conversion */
|
||||
int i;
|
||||
unsigned int i;
|
||||
// uint32 ofs;
|
||||
uint32 oc=(uint32)-1; /* value of the first objectClass */
|
||||
|
||||
@@ -99,7 +99,7 @@ int ldif_callback(struct ldaprec* l) {
|
||||
}
|
||||
if (oc==(uint32)-1) {
|
||||
extern long lines;
|
||||
buffer_puts(buffer_1,"ignoring record without objectClass... (line");
|
||||
buffer_puts(buffer_1,"ignoring record without objectClass... (line ");
|
||||
buffer_putulong(buffer_1,lines);
|
||||
buffer_putsflush(buffer_1,")\n");
|
||||
return 0;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l) {
|
||||
unsigned int tmp;
|
||||
size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* val) {
|
||||
size_t tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
long ltmp;
|
||||
if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,<mp)))
|
||||
if (tc==UNIVERSAL && tt==PRIMITIVE && tag==BOOLEAN) {
|
||||
if (ltmp<0 || src+tmp+ltmp>max) return 0;
|
||||
*l=(unsigned long)ltmp;
|
||||
if (ltmp!=0 && ltmp!=1) return 0;
|
||||
*val=(unsigned long)ltmp;
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l) {
|
||||
unsigned int tmp;
|
||||
size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* val) {
|
||||
size_t tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
@@ -9,7 +9,7 @@ unsigned int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long*
|
||||
if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,<mp)))
|
||||
if (tc==UNIVERSAL && tt==PRIMITIVE && tag==ENUMERATED) {
|
||||
if (ltmp<0 || src+tmp+ltmp>max) return 0;
|
||||
*l=(unsigned long)ltmp;
|
||||
*val=(unsigned long)ltmp;
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1INTEGER(const char* src,const char* max,signed long* l) {
|
||||
unsigned int tmp;
|
||||
size_t scan_asn1INTEGER(const char* src,const char* max,signed long* val) {
|
||||
size_t tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,l)))
|
||||
if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,val)))
|
||||
if (tc==UNIVERSAL && tt==PRIMITIVE && tag==INTEGER)
|
||||
return tmp;
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len) {
|
||||
size_t res,tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1SET(const char* src,const char* max,unsigned long* len) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_asn1SET(const char* src,const char* max,size_t* len) {
|
||||
size_t res,tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l) {
|
||||
unsigned int tmp;
|
||||
size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l) {
|
||||
size_t tmp;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) {
|
||||
unsigned int len,tmp;
|
||||
unsigned long tlen;
|
||||
size_t scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) {
|
||||
size_t len,tmp,tlen;
|
||||
if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0;
|
||||
if (!(tmp=scan_asn1length(src+len,max,&tlen))) return 0;
|
||||
len+=tmp;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include <inttypes.h>
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1length(const char* src,const char* max,unsigned long* length) {
|
||||
size_t scan_asn1length(const char* src,const char* max,size_t* length) {
|
||||
const char* orig=src;
|
||||
if (src>max) return 0;
|
||||
/* If the highest bit of the first byte is clear, the byte is the length.
|
||||
* Otherwise the next n bytes are the length (n being the lower 7 bits) */
|
||||
if (*src&0x80) {
|
||||
int chars=*src&0x7f;
|
||||
unsigned long l=0;
|
||||
size_t l=0;
|
||||
while (chars>0) {
|
||||
if (++src>=max) return 0;
|
||||
if (l>(((unsigned long)-1)>>8)) return 0; /* catch integer overflow */
|
||||
@@ -20,6 +20,6 @@ unsigned int scan_asn1length(const char* src,const char* max,unsigned long* leng
|
||||
*length=*src&0x7f;
|
||||
src++;
|
||||
if (src+*length>max) return 0; /* catch integer overflow */
|
||||
if ((uintptr_t)src+*length<(uintptr_t)src) return 0; /* gcc 4 removes this check without the cast to uintptr_t */
|
||||
if ((uintptr_t)src+*length<(uintptr_t)src) return 0; /* gcc 4.1 removes this check without the cast to uintptr_t */
|
||||
return src-orig;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1oid(const char* src,const char* max) {
|
||||
unsigned int res,tmp;
|
||||
unsigned long tag,tlen;
|
||||
size_t scan_asn1oid(const char* src,const char* max) {
|
||||
size_t res,tmp,tlen;
|
||||
unsigned long tag;
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error;
|
||||
if (!(tmp=scan_asn1length(src+res,max,&tlen))) goto error;
|
||||
res+=tmp;
|
||||
{
|
||||
unsigned int i,x,y;
|
||||
size_t i,x,y;
|
||||
tmp=0;
|
||||
for(i=0;src[res+i]&128;++i)
|
||||
tmp=(tmp<<7)+((unsigned char)src[res+i]&(~128));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* l) {
|
||||
unsigned int i,j;
|
||||
size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) {
|
||||
size_t i,j;
|
||||
long m;
|
||||
if (*src<0) m=-1; else m=0;
|
||||
for (i=j=0; i<len; ++i,++j) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1string(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,
|
||||
const char** s,unsigned long* l) {
|
||||
unsigned int len,tmp;
|
||||
size_t scan_asn1string(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,
|
||||
const char** s,size_t* l) {
|
||||
size_t len,tmp;
|
||||
if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0;
|
||||
if (!(tmp=scan_asn1length(src+len,max,l))) return 0;
|
||||
len+=tmp;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "asn1.h"
|
||||
|
||||
unsigned int scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag) {
|
||||
size_t scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag) {
|
||||
const char* orig=src;
|
||||
*tc=(*src&0xC0);
|
||||
*tt=(*src&0x20);
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
vals SET OF AttributeValue }
|
||||
#endif
|
||||
|
||||
unsigned int scan_ldapaddrequest(const char* src,const char* max,struct AddRequest* a) {
|
||||
unsigned int res,tmp;
|
||||
unsigned long oslen; /* outer sequence length */
|
||||
size_t scan_ldapaddrequest(const char* src,const char* max,struct AddRequest* a) {
|
||||
size_t res,tmp,oslen;
|
||||
struct Addition* last=0;
|
||||
byte_zero(a,sizeof(*a));
|
||||
if (!(res=scan_ldapstring(src,max,&a->entry))) goto error;
|
||||
@@ -28,7 +27,7 @@ unsigned int scan_ldapaddrequest(const char* src,const char* max,struct AddReque
|
||||
max=src+res+oslen;
|
||||
if (src+res>=max) goto error; /* need at least one record */
|
||||
do {
|
||||
unsigned long islen;
|
||||
size_t islen;
|
||||
if (last) {
|
||||
struct Addition* cur;
|
||||
if (!(cur=malloc(sizeof(struct Addition))))
|
||||
@@ -49,7 +48,7 @@ unsigned int scan_ldapaddrequest(const char* src,const char* max,struct AddReque
|
||||
|
||||
/* scan set of AttributeValue: */
|
||||
{
|
||||
unsigned long set_len;
|
||||
size_t set_len;
|
||||
const char* set_max;
|
||||
struct AttributeDescriptionList* ilast=0;
|
||||
if (!(tmp=scan_asn1SET(src+res,max,&set_len))) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) {
|
||||
size_t res,tmp;
|
||||
if (!(res=scan_ldapstring(src,max,&ava->desc))) goto error;
|
||||
if (!(tmp=scan_ldapstring(src+res,max,&ava->value))) goto error;
|
||||
return res+tmp;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapbindrequest(const char* src,const char* max,
|
||||
unsigned long* version,struct string* name,
|
||||
unsigned long* method) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapbindrequest(const char* src,const char* max,
|
||||
unsigned long* version,struct string* name,
|
||||
unsigned long* method) {
|
||||
size_t res,tmp;
|
||||
if (!(res=scan_asn1INTEGER(src,max,(signed long*)version))) return 0;
|
||||
if (!(tmp=scan_ldapstring(src+res,max,name))) return 0;
|
||||
res+=tmp;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapbindresponse(const char* src,const char* max,
|
||||
unsigned long* result,struct string* matcheddn,
|
||||
struct string* errormessage,struct string* referral) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapbindresponse(const char* src,const char* max,
|
||||
unsigned long* result,struct string* matcheddn,
|
||||
struct string* errormessage,struct string* referral) {
|
||||
size_t res,tmp;
|
||||
if (!(res=scan_asn1ENUMERATED(src,max,result))) return 0;
|
||||
if (!(tmp=scan_ldapstring(src+res,max,matcheddn))) return 0;
|
||||
res+=tmp;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapmessage(const char* src,const char* max,
|
||||
unsigned long* messageid,unsigned long* op,unsigned long* len) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapmessage(const char* src,const char* max,
|
||||
unsigned long* messageid,unsigned long* op,size_t* len) {
|
||||
size_t res,tmp;
|
||||
if (!(res=scan_asn1SEQUENCE(src,max,len))) goto error;
|
||||
if (!(tmp=scan_asn1INTEGER(src+res,max,(long*)messageid))) goto error;
|
||||
res+=tmp;
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
vals SET OF AttributeValue }
|
||||
#endif
|
||||
|
||||
unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m) {
|
||||
unsigned int res,tmp;
|
||||
unsigned long oslen; /* outer sequence length */
|
||||
size_t scan_ldapmodifyrequest(const char* src,const char* max,struct ModifyRequest* m) {
|
||||
size_t res,tmp,oslen; /* outer sequence length */
|
||||
struct Modification* last=0;
|
||||
m->m.next=0;
|
||||
if (!(res=scan_ldapstring(src,max,&m->object))) goto error;
|
||||
@@ -29,7 +28,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif
|
||||
max=src+res+oslen;
|
||||
if (src+res>=max) goto error; /* need at least one record */
|
||||
do {
|
||||
unsigned long islen, etmp;
|
||||
size_t islen, etmp;
|
||||
if (last) {
|
||||
struct Modification* cur;
|
||||
if (!(cur=malloc(sizeof(struct Modification)))) goto error;
|
||||
@@ -42,7 +41,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif
|
||||
if (!(tmp=scan_asn1ENUMERATED(src+res,max,&etmp))) goto error;
|
||||
if (etmp>2) goto error; last->operation=etmp; res+=tmp;
|
||||
{
|
||||
unsigned long iislen; /* urgh, _three_ levels of indirection */
|
||||
size_t iislen; /* urgh, _three_ levels of indirection */
|
||||
const char* imax;
|
||||
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&iislen))) goto error;
|
||||
res+=tmp;
|
||||
@@ -51,7 +50,7 @@ unsigned int scan_ldapmodifyrequest(const char* src,const char* max,struct Modif
|
||||
if (!(tmp=scan_ldapstring(src+res,imax,&last->AttributeDescription))) goto error;
|
||||
res+=tmp;
|
||||
{
|
||||
unsigned long iiislen; /* waah, _four_ levels of indirection! It doesn't get more inefficient than this */
|
||||
size_t iiislen; /* waah, _four_ levels of indirection! It doesn't get more inefficient than this */
|
||||
const char* iimax;
|
||||
struct AttributeDescriptionList* ilast=0;
|
||||
if (!(tmp=scan_asn1SET(src+res,max,&iiislen))) goto error;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
||||
struct string* matcheddn,struct string* errormessage,
|
||||
struct string* referral) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
||||
struct string* matcheddn,struct string* errormessage,
|
||||
struct string* referral) {
|
||||
size_t res,tmp;
|
||||
if (!(res=scan_asn1ENUMERATED(src,max,result))) return 0;
|
||||
if (!(tmp=scan_ldapstring(src+res,max,matcheddn))) return 0;
|
||||
res+=tmp;
|
||||
|
||||
@@ -30,12 +30,10 @@
|
||||
dnAttributes [4] BOOLEAN DEFAULT FALSE }
|
||||
*/
|
||||
|
||||
unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) {
|
||||
size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) {
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
unsigned long tag,len;
|
||||
unsigned int res;
|
||||
unsigned int tmp;
|
||||
size_t tag,len,res,tmp;
|
||||
const char* nmax;
|
||||
*f=0;
|
||||
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error;
|
||||
@@ -80,7 +78,7 @@ unsigned int scan_ldapsearchfilter(const char* src,const char* max,struct Filter
|
||||
break;
|
||||
case 4: /* substrings [4] SubstringFilter, */
|
||||
{
|
||||
unsigned long len2;
|
||||
size_t len2;
|
||||
if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) goto error;
|
||||
res+=tmp;
|
||||
if (!(tmp=scan_asn1SEQUENCE(src+res,nmax,&len2))) goto error;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
#include "ldap.h"
|
||||
#include "str.h"
|
||||
|
||||
unsigned int scan_ldapsearchfilterstring(const char* src,struct Filter** f) {
|
||||
size_t scan_ldapsearchfilterstring(const char* src,struct Filter** f) {
|
||||
char* s=(char*)src;
|
||||
if (!(*f=calloc(sizeof(struct Filter),1))) goto error;
|
||||
if (s[0]=='*' && (s[1]==0 || s[1]=='(')) {
|
||||
int i=scan_ldapsearchfilterstring("(objectClass=*)",f);
|
||||
size_t i=scan_ldapsearchfilterstring("(objectClass=*)",f);
|
||||
if (i) return 1;
|
||||
}
|
||||
if (*s!='(') goto error;
|
||||
@@ -18,7 +18,7 @@ scan_filterlist:
|
||||
s+=scan_ldapsearchfilterstring(s,&(*f)->x);
|
||||
n=&(*f)->x->next;
|
||||
while (*s!=')') {
|
||||
unsigned long l=scan_ldapsearchfilterstring(s,n);
|
||||
size_t l=scan_ldapsearchfilterstring(s,n);
|
||||
if (!l) return 0;
|
||||
s+=l;
|
||||
n=&(*n)->next;
|
||||
@@ -51,7 +51,7 @@ scan_filterlist:
|
||||
(*f)->type=SUBSTRING;
|
||||
substring:
|
||||
while (*s!=')') {
|
||||
int i,j;
|
||||
size_t i,j;
|
||||
struct Substring* substring=malloc(sizeof(struct Substring));
|
||||
if (!substring) goto error;
|
||||
substring->s.s=s;
|
||||
@@ -70,7 +70,7 @@ substring:
|
||||
if (*s==0) goto error;
|
||||
}
|
||||
} else {
|
||||
int i,j;
|
||||
size_t i,j;
|
||||
i=str_chr(s,')');
|
||||
j=str_chr(s,'*');
|
||||
if (i>j) {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapsearchrequest(const char* src,const char* max,
|
||||
struct SearchRequest* s) {
|
||||
unsigned int res,tmp;
|
||||
size_t scan_ldapsearchrequest(const char* src,const char* max,
|
||||
struct SearchRequest* s) {
|
||||
size_t res,tmp;
|
||||
unsigned long etmp;
|
||||
signed long ltmp;
|
||||
s->attributes=0;
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#include "asn1.h"
|
||||
#include "ldap.h"
|
||||
|
||||
unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) {
|
||||
unsigned int res,tmp;
|
||||
unsigned long oslen; /* outer sequence length */
|
||||
size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) {
|
||||
size_t res,tmp,oslen; /* outer sequence length */
|
||||
struct PartialAttributeList** a=&sre->attributes;
|
||||
*a=0;
|
||||
if (!(res=scan_ldapstring(src,max,&sre->objectName))) goto error;
|
||||
@@ -15,7 +14,7 @@ unsigned int scan_ldapsearchresultentry(const char* src,const char* max,struct S
|
||||
while (src+res<max) {
|
||||
struct string s;
|
||||
struct AttributeDescriptionList* x;
|
||||
unsigned long islen;
|
||||
size_t islen;
|
||||
const char* nmax;
|
||||
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen))) goto error;
|
||||
res+=tmp; nmax=src+res+islen; if (nmax>max) goto error;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <asn1.h>
|
||||
#include <ldap.h>
|
||||
|
||||
unsigned int scan_ldapstring(const char* src,const char* max,struct string* s) {
|
||||
size_t scan_ldapstring(const char* src,const char* max,struct string* s) {
|
||||
return scan_asn1STRING(src,max,&s->s,&s->l);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#define PAGESIZE 4096
|
||||
|
||||
const char* strduptab_add(struct stringduptable* t,const char* s) {
|
||||
int i;
|
||||
size_t i;
|
||||
for (i=0; i<t->n; ++i)
|
||||
if (str_equal(t->s[i],s))
|
||||
return t->s[i];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* the new string. */
|
||||
|
||||
struct stringduptable {
|
||||
int n,a;
|
||||
size_t n,a;
|
||||
const char** s;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#define PAGESIZE 4096
|
||||
|
||||
const char* strstorage_add(const char* s,int n) {
|
||||
const char* strstorage_add(const char* s,size_t n) {
|
||||
static char* page=0;
|
||||
static int leftonpage=0;
|
||||
static size_t leftonpage=0;
|
||||
if (leftonpage>=n) {
|
||||
copyit:
|
||||
byte_copy(page,n,s);
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
* later. On the plus side, the allocation overhead is close to zero.
|
||||
* Will return a pointer to the stored copy of the string. */
|
||||
|
||||
const char* strstorage_add(const char* s,int n);
|
||||
const char* strstorage_add(const char* s,size_t n);
|
||||
|
||||
|
||||
4
t2.c
4
t2.c
@@ -120,7 +120,7 @@ int main(int argc,char* argv[]) {
|
||||
{
|
||||
unsigned long result;
|
||||
struct string matcheddn,errormessage,referral;
|
||||
printf("scan_ldapbindresponse: %d\n",
|
||||
printf("scan_ldapbindresponse: %zd\n",
|
||||
scan_ldapbindresponse(ldapsequence+done+res,ldapsequence+done+res+len,
|
||||
&result,&matcheddn,&errormessage,&referral));
|
||||
printf("result %lu, matcheddn \"%.*s\", errormessage \"%.*s\", referral \"%.*s\"\n",
|
||||
@@ -184,7 +184,7 @@ int main(int argc,char* argv[]) {
|
||||
{
|
||||
unsigned long result;
|
||||
struct string matcheddn,errormessage,referral;
|
||||
printf("scan_ldapresult: %d\n",
|
||||
printf("scan_ldapresult: %zd\n",
|
||||
scan_ldapresult(ldapsequence+done+res,ldapsequence+done+res+len,
|
||||
&result,&matcheddn,&errormessage,&referral));
|
||||
printf("result %lu, matcheddn \"%.*s\", errormessage \"%.*s\", referral \"%.*s\"\n",
|
||||
|
||||
666
tinyldap.c
666
tinyldap.c
@@ -1,10 +1,12 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "str.h"
|
||||
#include "case.h"
|
||||
#include "byte.h"
|
||||
#include "buffer.h"
|
||||
#include "ldap.h"
|
||||
#include "mduptab.h"
|
||||
#include "ldif.h"
|
||||
#include "open.h"
|
||||
#include "mmap.h"
|
||||
@@ -28,6 +30,9 @@
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include "errmsg.h"
|
||||
#include "textcode.h"
|
||||
#include "fmt.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <sys/poll.h>
|
||||
@@ -38,9 +43,11 @@
|
||||
#define debug 0
|
||||
#endif
|
||||
|
||||
#define HUGE_SIZE_FOR_SANITY_CHECKS 1024*1024
|
||||
|
||||
/* basic operation: the whole data file is mmapped read-only at the beginning and stays there. */
|
||||
char* map; /* where the file is mapped */
|
||||
unsigned long filelen; /* how many bytes are mapped (the whole file) */
|
||||
size_t filelen; /* how many bytes are mapped (the whole file) */
|
||||
uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table;
|
||||
/* these are the first values from the file, see the file "FORMAT"
|
||||
* basic counts and offsets needed to calculate the positions of
|
||||
@@ -58,6 +65,23 @@ uint32 dn_ofs,objectClass_ofs,userPassword_ofs,any_ofs;
|
||||
|
||||
|
||||
|
||||
|
||||
/* journal hash structures */
|
||||
struct attribute2 {
|
||||
unsigned char* a,* v;
|
||||
};
|
||||
|
||||
struct hashnode {
|
||||
struct hashnode* next;
|
||||
unsigned long hashval;
|
||||
unsigned char* dn;
|
||||
size_t n;
|
||||
struct attribute2 a[1];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* to avoid string compares, we don't work with char* but with uint32 (offsets within
|
||||
* the mmapped file) whenever it's about values that will be mentioned in the file, such
|
||||
* as attribute names. So, for each filter we get sent, we look up the attributes in the
|
||||
@@ -82,7 +106,7 @@ static void fixup(struct Filter* f) {
|
||||
case APPROX:
|
||||
{
|
||||
char* x=map+5*4+size_of_string_table;
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
f->attrofs=f->attrflag=0;
|
||||
for (i=0; i<attribute_count; ++i) {
|
||||
uint32 j=uint32_read(x);
|
||||
@@ -112,7 +136,7 @@ static void fixup(struct Filter* f) {
|
||||
static void fixupadl(struct AttributeDescriptionList* a) {
|
||||
while (a) {
|
||||
char* x=map+5*4+size_of_string_table;
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
a->attrofs=0;
|
||||
for (i=0; i<attribute_count; ++i) {
|
||||
uint32 j=uint32_read(x);
|
||||
@@ -138,14 +162,14 @@ static void fixupadl(struct AttributeDescriptionList* a) {
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
_ _
|
||||
__ _ ___| | ___ _ _ _ __ _ __ ___ _ __| |_
|
||||
/ _` |/ __| | / __| | | | '_ \| '_ \ / _ \| '__| __|
|
||||
| (_| | (__| | \__ \ |_| | |_) | |_) | (_) | | | |_
|
||||
\__,_|\___|_| |___/\__,_| .__/| .__/ \___/|_| \__|
|
||||
|_| |_|
|
||||
#endif
|
||||
*/
|
||||
|
||||
uint32 filters,acls; /* number of filters and acls in the ACL section of the data file */
|
||||
uint32 filtertab,acltab; /* offsets of the filter and acl table in the data file */
|
||||
@@ -204,7 +228,7 @@ kaputt:
|
||||
else if (scan_ldapsearchfilter(map+ofs,map+filelen,&f)!=0) {
|
||||
fixup(f);
|
||||
if (debug) {
|
||||
unsigned long l=fmt_ldapsearchfilterstring(0,f);
|
||||
size_t l=fmt_ldapsearchfilterstring(0,f);
|
||||
char* buf=malloc(l+23);
|
||||
if (!buf) goto kaputt;
|
||||
buf[fmt_ldapsearchfilterstring(buf,f)]=0;
|
||||
@@ -258,14 +282,14 @@ kaputt:
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
_ _ _
|
||||
__| | ___| |__ _ _ __ _ ___ ___ __| | ___
|
||||
/ _` |/ _ \ '_ \| | | |/ _` | / __/ _ \ / _` |/ _ \
|
||||
| (_| | __/ |_) | |_| | (_| | | (_| (_) | (_| | __/
|
||||
\__,_|\___|_.__/ \__,_|\__, | \___\___/ \__,_|\___|
|
||||
|___/
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define BUFSIZE 8192
|
||||
|
||||
@@ -354,13 +378,13 @@ mergesub:
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
_ _ _
|
||||
(_)_ __ __| | _____ __ ___ ___ __| | ___
|
||||
| | '_ \ / _` |/ _ \ \/ / / __/ _ \ / _` |/ _ \
|
||||
| | | | | (_| | __/> < | (_| (_) | (_| | __/
|
||||
|_|_| |_|\__,_|\___/_/\_\ \___\___/ \__,_|\___|
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* find out whether this filter can be accelerated with the indices */
|
||||
static int indexable(struct Filter* f) {
|
||||
@@ -463,14 +487,14 @@ static long findrec(uint32 dat) {
|
||||
struct bitfield {
|
||||
unsigned long* bits;
|
||||
#ifdef RANGECHECK
|
||||
unsigned long n;
|
||||
size_t n;
|
||||
#endif
|
||||
unsigned long first,last;
|
||||
size_t first,last;
|
||||
};
|
||||
|
||||
/* basic bit-set support: set all bits to 0 */
|
||||
static inline void emptyset(struct bitfield* b) {
|
||||
unsigned long i;
|
||||
size_t i;
|
||||
#ifdef RANGECHECK
|
||||
b->n=
|
||||
#endif
|
||||
@@ -481,7 +505,7 @@ static inline void emptyset(struct bitfield* b) {
|
||||
|
||||
/* basic bit-set support: set all bits to 1 */
|
||||
static inline void fillset(struct bitfield* b) {
|
||||
unsigned long i;
|
||||
size_t i;
|
||||
b->first=0;
|
||||
#ifdef RANGECHECK
|
||||
b->n=
|
||||
@@ -491,7 +515,7 @@ static inline void fillset(struct bitfield* b) {
|
||||
}
|
||||
|
||||
/* basic bit-set support: set one bit to 1 */
|
||||
static inline void setbit(struct bitfield* b,unsigned long bit) {
|
||||
static inline void setbit(struct bitfield* b,size_t bit) {
|
||||
#ifdef RANGECHECK
|
||||
if (bit<=b->n) {
|
||||
#endif
|
||||
@@ -504,7 +528,7 @@ static inline void setbit(struct bitfield* b,unsigned long bit) {
|
||||
}
|
||||
|
||||
/* basic bit-set support: see if given bit is set */
|
||||
static inline int isset(struct bitfield* b,unsigned long bit) {
|
||||
static inline int isset(struct bitfield* b,size_t bit) {
|
||||
#ifdef RANGECHECK
|
||||
if (bit>b->n) return 0;
|
||||
#endif
|
||||
@@ -514,7 +538,7 @@ static inline int isset(struct bitfield* b,unsigned long bit) {
|
||||
/* use index (sorted table of offsets to records) to do a binary search
|
||||
* for all records that match the value in s. Set the corresponding
|
||||
* bits to 1 in bitfield. */
|
||||
static void tagmatches(uint32* index,unsigned int elements,struct string* s,
|
||||
static void tagmatches(uint32* index,size_t elements,struct string* s,
|
||||
struct bitfield* b,int (*match)(struct string* s,const char* c),
|
||||
uint32 index_type,enum FilterType ft) {
|
||||
uint32 bottom=0;
|
||||
@@ -623,9 +647,8 @@ static void tagmatches(uint32* index,unsigned int elements,struct string* s,
|
||||
}
|
||||
}
|
||||
|
||||
uint32 hash(const unsigned char* c,unsigned long keylen) {
|
||||
unsigned long h=0;
|
||||
unsigned long i;
|
||||
uint32 hash(const unsigned char* c,size_t keylen) {
|
||||
size_t h=0,i;
|
||||
for (i=0; i<keylen; ++i) {
|
||||
/* from djb's cdb */
|
||||
h += (h<<5);
|
||||
@@ -634,9 +657,8 @@ uint32 hash(const unsigned char* c,unsigned long keylen) {
|
||||
return (uint32)h;
|
||||
}
|
||||
|
||||
uint32 hash_tolower(const unsigned char* c,unsigned long keylen) {
|
||||
unsigned long h=0;
|
||||
unsigned long i;
|
||||
uint32 hash_tolower(const unsigned char* c,size_t keylen) {
|
||||
size_t h=0,i;
|
||||
for (i=0; i<keylen; ++i) {
|
||||
/* from djb's cdb */
|
||||
h += (h<<5);
|
||||
@@ -701,7 +723,7 @@ static int useindex(struct Filter* f,struct bitfield* b) {
|
||||
fillset(b);
|
||||
while (y) {
|
||||
if (useindex(y,&tmp)) {
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
for (i=0; i<record_set_length; ++i)
|
||||
b->bits[i] &= tmp.bits[i];
|
||||
if (tmp.first>b->first) b->first=tmp.first;
|
||||
@@ -724,7 +746,7 @@ static int useindex(struct Filter* f,struct bitfield* b) {
|
||||
emptyset(b);
|
||||
while (y) {
|
||||
if (useindex(y,&tmp)) {
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
for (i=0; i<record_set_length; ++i)
|
||||
b->bits[i] |= tmp.bits[i];
|
||||
if (tmp.first<b->first) b->first=tmp.first;
|
||||
@@ -765,7 +787,7 @@ static int useindex(struct Filter* f,struct bitfield* b) {
|
||||
* through the record table, but since each check is very cheap,
|
||||
* we pretend it's indexed */
|
||||
char* x=map+5*4+size_of_string_table+attribute_count*8;
|
||||
unsigned long i;
|
||||
size_t i;
|
||||
emptyset(b);
|
||||
for (i=0; i<record_count; ++i) {
|
||||
if (ldap_match_present(x-map,f->attrofs))
|
||||
@@ -801,17 +823,17 @@ static int useindex(struct Filter* f,struct bitfield* b) {
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
_
|
||||
__ _ _ _ ___ _ __ _ _ __ _ _ __ _____ _____ _ __(_)_ __ __ _
|
||||
/ _` | | | |/ _ \ '__| | | | / _` | '_ \/ __\ \ /\ / / _ \ '__| | '_ \ / _` |
|
||||
| (_| | |_| | __/ | | |_| | | (_| | | | \__ \\ V V / __/ | | | | | | (_| |
|
||||
\__, |\__,_|\___|_| \__, | \__,_|_| |_|___/ \_/\_/ \___|_| |_|_| |_|\__, |
|
||||
|_| |___/ |___/
|
||||
#endif
|
||||
*/
|
||||
|
||||
static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct SearchResultEntry* sre) {
|
||||
uint32_t j;
|
||||
static int checkacl(uint32 recofs,uint32 attrofs,unsigned long operation,struct SearchResultEntry* sre) {
|
||||
uint32 j;
|
||||
for (j=0; j<acls; ++j) {
|
||||
/* does the ACL subject apply? */
|
||||
if (!acl_ec_subjects[Acls[j]->subject]) continue;
|
||||
@@ -824,9 +846,9 @@ static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct Sea
|
||||
if (Filters[Acls[j]->object]==(struct Filter*)Any)
|
||||
match=1;
|
||||
else if (Filters[Acls[j]->object]==(struct Filter*)Self)
|
||||
match=(ofs==authenticated_as);
|
||||
else if (ofs)
|
||||
match=ldap_matchfilter_mapped(ofs,Filters[Acls[j]->object]);
|
||||
match=(recofs==authenticated_as);
|
||||
else if (recofs)
|
||||
match=ldap_matchfilter_mapped(recofs,Filters[Acls[j]->object]);
|
||||
else if (sre)
|
||||
match=ldap_matchfilter_sre(sre,Filters[Acls[j]->object]);
|
||||
else
|
||||
@@ -853,12 +875,62 @@ static int checkacl(uint32 ofs,uint32 attrofs,unsigned long operation,struct Sea
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ldap_matchfilter_hn(struct hashnode* hn,struct Filter* f);
|
||||
|
||||
static int checkacl_hn(struct hashnode* hn,const unsigned char* attr,unsigned long operation) {
|
||||
uint32 j;
|
||||
for (j=0; j<acls; ++j) {
|
||||
/* does the ACL subject apply? */
|
||||
if (!acl_ec_subjects[Acls[j]->subject]) continue;
|
||||
/* does the ACL even apply to the wanted operation? */
|
||||
if ((Acls[j]->may | Acls[j]->maynot) & operation) {
|
||||
uint32 k;
|
||||
if (acl_ec_subjects[filters+Acls[j]->object]==-1) continue;
|
||||
if (acl_ec_subjects[filters+Acls[j]->object]==0) {
|
||||
int match=0;
|
||||
if (Filters[Acls[j]->object]==(struct Filter*)Any)
|
||||
match=1;
|
||||
else if (Filters[Acls[j]->object]==(struct Filter*)Self)
|
||||
match=dn && !strcmp((char*)hn->dn,map+authenticated_as);
|
||||
else if (dn)
|
||||
match=ldap_matchfilter_hn(hn,Filters[Acls[j]->object]);
|
||||
else
|
||||
match=-1;
|
||||
if (match)
|
||||
acl_ec_subjects[filters+Acls[j]->object]=1;
|
||||
else {
|
||||
acl_ec_subjects[filters+Acls[j]->object]=-1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (k=0; k<Acls[j]->attrs; ++k) {
|
||||
/* if (Acls[j]->Attrs[k]==any_ofs || !matchstring(&adl->a,map+Acls[j]->Attrs[k])) { */
|
||||
if (Acls[j]->Attrs[k]==any_ofs || bstr_equal((char*)attr,map+Acls[j]->Attrs[k])) {
|
||||
if (Acls[j]->may&operation)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct hashnode** dn_in_journal(unsigned char* dn);
|
||||
|
||||
/* this routine is called for each record matched the query. It basically puts together
|
||||
* an answer LDAP message from the record and the list of attributes the other side said
|
||||
* it wanted to have. */
|
||||
static void answerwith(uint32 ofs,struct SearchRequest* sr,long messageid,int out) {
|
||||
struct SearchResultEntry sre;
|
||||
struct PartialAttributeList** pal=&sre.attributes;
|
||||
struct hashnode** hn;
|
||||
|
||||
if ((hn=dn_in_journal((unsigned char*)map+uint32_read(map+ofs+8))) && *hn)
|
||||
return;
|
||||
|
||||
#if (debug != 0)
|
||||
if (debug) {
|
||||
@@ -897,20 +969,21 @@ static void answerwith(uint32 ofs,struct SearchRequest* sr,long messageid,int ou
|
||||
/* now go through list of requested attributes */
|
||||
{
|
||||
struct AttributeDescriptionList* adl=sr->attributes;
|
||||
if (!adl) {
|
||||
if (!adl && attribute_count>2) {
|
||||
/* did not ask for any attributes. send 'em all. */
|
||||
/* to do that, construct a list of all attributes */
|
||||
|
||||
/* FIXME! This adl appears to create a segfault later on */
|
||||
uint32 i;
|
||||
char* x=map+5*4+size_of_string_table+4;
|
||||
if (attribute_count>HUGE_SIZE_FOR_SANITY_CHECKS/sizeof(struct AttributeDescriptionList))
|
||||
return;
|
||||
adl=alloca((attribute_count)*sizeof(struct AttributeDescriptionList));
|
||||
for (i=0; i<attribute_count-1; ++i) {
|
||||
uint32 j;
|
||||
uint32_unpack(x,&j);
|
||||
x+=4;
|
||||
adl[i].a.s=map+j;
|
||||
adl[i].a.l=strlen(map+j);
|
||||
adl[i].a.l=str_len(map+j);
|
||||
adl[i].attrofs=j;
|
||||
adl[i].next=adl+i+1;
|
||||
}
|
||||
@@ -974,29 +1047,32 @@ add_attribute:
|
||||
}
|
||||
{
|
||||
long l=fmt_ldapsearchresultentry(0,&sre);
|
||||
char *buf=alloca(l+300); /* you never know ;) */
|
||||
char *buf;
|
||||
long tmp;
|
||||
if (verbose) {
|
||||
buffer_puts(buffer_2,"sre len ");
|
||||
buffer_putulong(buffer_2,l);
|
||||
buffer_putsflush(buffer_2,".\n");
|
||||
if (l<=HUGE_SIZE_FOR_SANITY_CHECKS) {
|
||||
buf=alloca(l+300); /* you never know ;) */
|
||||
if (verbose) {
|
||||
buffer_puts(buffer_2,"sre len ");
|
||||
buffer_putulong(buffer_2,l);
|
||||
buffer_putsflush(buffer_2,".\n");
|
||||
}
|
||||
tmp=fmt_ldapmessage(buf,messageid,SearchResultEntry,l);
|
||||
fmt_ldapsearchresultentry(buf+tmp,&sre);
|
||||
write(out,buf,l+tmp);
|
||||
}
|
||||
tmp=fmt_ldapmessage(buf,messageid,SearchResultEntry,l);
|
||||
fmt_ldapsearchresultentry(buf+tmp,&sre);
|
||||
write(out,buf,l+tmp);
|
||||
}
|
||||
free_ldappal(sre.attributes);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
_ _ _ _ _ _ _
|
||||
| |__ (_) __ _| |__ | | _____ _____| | | | __| | __ _ _ __
|
||||
| '_ \| |/ _` | '_ \ | |/ _ \ \ / / _ \ | | |/ _` |/ _` | '_ \
|
||||
| | | | | (_| | | | | | | __/\ V / __/ | | | (_| | (_| | |_) |
|
||||
|_| |_|_|\__, |_| |_| |_|\___| \_/ \___|_| |_|\__,_|\__,_| .__/
|
||||
|___/ |_|
|
||||
#endif
|
||||
*/
|
||||
|
||||
int copystring(struct string* dest,struct string* src) {
|
||||
dest->s=malloc(src->l+1);
|
||||
@@ -1037,6 +1113,7 @@ static int copypal(struct PartialAttributeList** dest,struct PartialAttributeLis
|
||||
}
|
||||
#endif
|
||||
|
||||
/* small helper for addreq2sre */
|
||||
static int ar2sreh1(struct PartialAttributeList** dest,struct Addition* src) {
|
||||
*dest=0;
|
||||
while (src) {
|
||||
@@ -1050,25 +1127,112 @@ static int ar2sreh1(struct PartialAttributeList** dest,struct Addition* src) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addreq2sre(struct SearchResultEntry* sre,struct AddRequest* ar) {
|
||||
/* convert an AddRequest to a SearchResultEntry */
|
||||
static int addreq2sre(struct SearchResultEntry* sre,struct AddRequest* ar) {
|
||||
byte_zero(sre,sizeof(*sre));
|
||||
if (copystring(&sre->objectName,&ar->entry)) goto allocfailed;
|
||||
if (!(sre->attributes=malloc(sizeof(*sre->attributes)))) goto allocfailed;
|
||||
if (ar2sreh1(&sre->attributes,&ar->a)) goto allocfailed;
|
||||
if (copystring(&sre->objectName,&ar->entry) ||
|
||||
!(sre->attributes=malloc(sizeof(*sre->attributes))) ||
|
||||
ar2sreh1(&sre->attributes,&ar->a)) {
|
||||
free_ldapsearchresultentry(sre);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
allocfailed:
|
||||
free_ldapsearchresultentry(sre);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write a search result entry to a file */
|
||||
static int writesretofd(int fd,struct SearchResultEntry* sre) {
|
||||
/* we have no locking, but we open using O_APPEND, so the OS synchronizes for us as long
|
||||
* as we write atomically. Therefore we have to buffer here. */
|
||||
size_t i,l,nl;
|
||||
char* c;
|
||||
struct PartialAttributeList* pal=sre->attributes;
|
||||
l=5+fmt_ldapescape(0,sre->objectName.s,sre->objectName.l); /* "\ndn: ...\n" */
|
||||
if (l<=5) return -1;
|
||||
while (pal) {
|
||||
struct AttributeDescriptionList* adl=pal->values;
|
||||
while (adl) {
|
||||
nl=fmt_ldapescape(0,pal->type.s,pal->type.l);
|
||||
if (nl>HUGE_SIZE_FOR_SANITY_CHECKS) return -1;
|
||||
l+=nl;
|
||||
nl=fmt_ldapescape(0,adl->a.s,adl->a.l);
|
||||
if (nl>HUGE_SIZE_FOR_SANITY_CHECKS) return -1;
|
||||
l+=nl;
|
||||
if (l+3>HUGE_SIZE_FOR_SANITY_CHECKS) return -1;
|
||||
l+=3;
|
||||
adl=adl->next;
|
||||
}
|
||||
pal=pal->next;
|
||||
}
|
||||
c=alloca(l+1);
|
||||
if (!c) return -1;
|
||||
i=fmt_str(c,"dn: ");
|
||||
i+=fmt_ldapescape(c+i,sre->objectName.s,sre->objectName.l);
|
||||
i+=fmt_str(c+i,"\n");
|
||||
pal=sre->attributes;
|
||||
while (pal) {
|
||||
struct AttributeDescriptionList* adl=pal->values;
|
||||
while (adl) {
|
||||
i+=fmt_ldapescape(c+i,pal->type.s,pal->type.l);
|
||||
i+=fmt_str(c+i,": ");
|
||||
i+=fmt_ldapescape(c+i,adl->a.s,adl->a.l);
|
||||
i+=fmt_str(c+i,"\n");
|
||||
adl=adl->next;
|
||||
}
|
||||
pal=pal->next;
|
||||
}
|
||||
i+=fmt_str(c+i,"\n");
|
||||
|
||||
return (write(fd,c,i)==(ssize_t)i)?0:-1;
|
||||
}
|
||||
|
||||
/* This is the high level LDAP handling code. It reads queries from the socket at in, and
|
||||
* then writes the answers to out. Normally in == out, but they are separate here so this
|
||||
* can also be called with in=stdin and out=stdout. */
|
||||
|
||||
int writesretofd(int fd,struct SearchResultEntry* sre) {
|
||||
unsigned long l=fmt_ldapsearchresultentry(0,sre);
|
||||
char* c=alloca(l+10); /* you never know */
|
||||
return (write(fd,c,l)==(ssize_t)l)?0:-1;
|
||||
static void answerwithjournal(struct SearchRequest* sr,long messageid,int out);
|
||||
static struct hashnode** dn_in_journal2(const char* dn,size_t dnlen);
|
||||
|
||||
static int lookupdn(struct string* dn,size_t* index, struct hashnode** hn) {
|
||||
struct Filter f;
|
||||
struct hashnode** tmphn;
|
||||
if ((tmphn=dn_in_journal2(dn->s,dn->l)) && *tmphn) {
|
||||
*hn=*tmphn;
|
||||
*index=-1;
|
||||
return (*hn)->n > 0;
|
||||
}
|
||||
*hn=0;
|
||||
f.type=EQUAL;
|
||||
f.ava.desc.l=2; f.ava.desc.s="dn";
|
||||
f.ava.value=*dn;
|
||||
f.next=0;
|
||||
fixup(&f);
|
||||
if (!indexable(&f)) {
|
||||
buffer_putsflush(buffer_2,"no index for dn, lookup failed!\n");
|
||||
return -1;
|
||||
} else {
|
||||
struct bitfield result;
|
||||
size_t i,done;
|
||||
result.bits=alloca(record_set_length*sizeof(unsigned long));
|
||||
useindex(&f,&result);
|
||||
done=0;
|
||||
if (result.first>result.last)
|
||||
return 0;
|
||||
done=0;
|
||||
assert(result.last<=record_count);
|
||||
for (i=result.first; i<=result.last; ) {
|
||||
if (!result.bits[i/(8*sizeof(long))]) {
|
||||
i+=8*sizeof(long);
|
||||
continue;
|
||||
}
|
||||
for (; i<=result.last; ++i) {
|
||||
if (isset(&result,i)) {
|
||||
*index=i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a standard LDAP session looks like this:
|
||||
@@ -1083,12 +1247,12 @@ int writesretofd(int fd,struct SearchResultEntry* sre) {
|
||||
* tinyldap does not complain if you don't unbind before hanging up.
|
||||
*/
|
||||
int handle(int in,int out) {
|
||||
unsigned int len;
|
||||
size_t len;
|
||||
char buf[BUFSIZE];
|
||||
for (len=0;;) {
|
||||
int tmp=read(in,buf+len,BUFSIZE-len);
|
||||
int res;
|
||||
unsigned long messageid,op,Len;
|
||||
size_t messageid,op,Len;
|
||||
if (tmp==0) {
|
||||
close(in);
|
||||
if (in!=out) close(out);
|
||||
@@ -1140,16 +1304,16 @@ int handle(int in,int out) {
|
||||
authfailure:
|
||||
{
|
||||
char outbuf[1024];
|
||||
int s=100;
|
||||
int len=fmt_ldapbindresponse(outbuf+s,inappropriateAuthentication,"","authentication failure","");
|
||||
int hlen=fmt_ldapmessage(0,messageid,BindResponse,len);
|
||||
size_t s=100;
|
||||
size_t len=fmt_ldapbindresponse(outbuf+s,inappropriateAuthentication,"","authentication failure","");
|
||||
size_t hlen=fmt_ldapmessage(0,messageid,BindResponse,len);
|
||||
fmt_ldapmessage(outbuf+s-hlen,messageid,BindResponse,len);
|
||||
write(out,outbuf+s-hlen,len+hlen);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
struct bitfield result;
|
||||
unsigned long i,done;
|
||||
size_t i,done;
|
||||
result.bits=alloca(record_set_length*sizeof(unsigned long));
|
||||
useindex(&f,&result);
|
||||
done=0;
|
||||
@@ -1220,7 +1384,7 @@ found:
|
||||
}
|
||||
#endif
|
||||
if ((tmp=scan_ldapsearchrequest(buf+res,buf+res+len,&sr))) {
|
||||
unsigned long returned=0;
|
||||
size_t returned=0;
|
||||
|
||||
#if (debug != 0)
|
||||
if (debug) {
|
||||
@@ -1247,7 +1411,7 @@ found:
|
||||
fixupadl(sr.attributes);
|
||||
if (indexable(sr.filter)) {
|
||||
struct bitfield result;
|
||||
unsigned long i;
|
||||
size_t i;
|
||||
#if (debug != 0)
|
||||
if (debug) buffer_putsflush(buffer_2,"query can be answered with index!\n");
|
||||
#endif
|
||||
@@ -1258,7 +1422,7 @@ found:
|
||||
useindex(sr.filter,&result);
|
||||
assert(result.last<=record_count);
|
||||
for (i=result.first; i<=result.last; ) {
|
||||
unsigned long ni=i+8*sizeof(long);
|
||||
size_t ni=i+8*sizeof(long);
|
||||
if (!result.bits[i/(8*sizeof(long))]) {
|
||||
i=ni;
|
||||
continue;
|
||||
@@ -1278,7 +1442,7 @@ found:
|
||||
}
|
||||
} else {
|
||||
char* x=map+5*4+size_of_string_table+attribute_count*8;
|
||||
unsigned long i;
|
||||
size_t i;
|
||||
#if (debug != 0)
|
||||
if (debug) buffer_putsflush(buffer_2,"query can NOT be answered with index!\n");
|
||||
#endif
|
||||
@@ -1293,6 +1457,9 @@ found:
|
||||
x+=j*8;
|
||||
}
|
||||
}
|
||||
|
||||
/* now answer with the results from the journal */
|
||||
answerwithjournal(&sr,messageid,out);
|
||||
free_ldapsearchrequest(&sr);
|
||||
} else {
|
||||
buffer_putsflush(buffer_2,"couldn't parse search request!\n");
|
||||
@@ -1353,15 +1520,23 @@ found:
|
||||
// buffer_putsflush(buffer_2,"AddRequest!\n");
|
||||
if ((tmp=scan_ldapaddrequest(buf+res,buf+res+len,&ar))) {
|
||||
struct SearchResultEntry sre;
|
||||
addreq2sre(&sre,&ar);
|
||||
/* convert addrequest to searchresultentry */
|
||||
addreq2sre(&sre,&ar);
|
||||
/* TODO: do something with the add request ;-) */
|
||||
/* 1. check ACLs */
|
||||
if (!acls || checkacl(0,0,acl_add,&sre)==1) {
|
||||
/* 2. check is there already is a record with this dn */
|
||||
/* 2. check if there already is a record with this dn */
|
||||
struct hashnode* hn;
|
||||
size_t idx;
|
||||
switch (lookupdn(&sre.objectName,&idx,&hn)) {
|
||||
case -1: err=operationsError; break;
|
||||
case 1: err=entryAlreadyExists; break;
|
||||
case 0: break;
|
||||
default: err=operationsError;
|
||||
}
|
||||
if (err==success) {
|
||||
/* 3. write record to "data.upd" */
|
||||
{
|
||||
int fd=open("data.upd",O_WRONLY|O_APPEND|O_CREAT,0600);
|
||||
int fd=open("journal",O_WRONLY|O_APPEND|O_CREAT,0600);
|
||||
if (fd==-1)
|
||||
err=operationsError;
|
||||
else {
|
||||
@@ -1426,19 +1601,360 @@ found:
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/* journal reading code */
|
||||
|
||||
extern int (*ldif_parse_callback)(struct ldaprec* l);
|
||||
|
||||
extern mstorage_t stringtable;
|
||||
extern mduptab_t attributes,classes;
|
||||
|
||||
unsigned long hash2(const unsigned char* c) {
|
||||
unsigned long h=0;
|
||||
if (*c==0) {
|
||||
uint32 len=uint32_read((char*)c+1);
|
||||
return hash(c+5,len);
|
||||
}
|
||||
while (*c) {
|
||||
/* from djb's cdb */
|
||||
h += (h<<5);
|
||||
h ^= *c;
|
||||
++c;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
#define HASHTABSIZE 8191
|
||||
|
||||
unsigned char* bstrdup(unsigned char* c) {
|
||||
size_t len;
|
||||
unsigned char* x;
|
||||
if (*c)
|
||||
len=str_len((char*)c);
|
||||
else {
|
||||
len=5+uint32_read((char*)c+1);
|
||||
if (len<5) return 0;
|
||||
}
|
||||
x=malloc(len);
|
||||
if (x) byte_copy(x,len,c);
|
||||
return x;
|
||||
}
|
||||
|
||||
unsigned char* bstrdup_attrib(unsigned char* c) {
|
||||
char* x=map+5*4+size_of_string_table;
|
||||
size_t i,l;
|
||||
if (*c)
|
||||
l=str_len((char*)c)+1;
|
||||
else {
|
||||
l=uint32_read((char*)c+1);
|
||||
c+=5;
|
||||
}
|
||||
for (i=0; i<attribute_count; ++i) {
|
||||
uint32 j=uint32_read(x);
|
||||
if (case_equalb(c,l,map+j))
|
||||
return (unsigned char*)map+j;
|
||||
x+=4;
|
||||
}
|
||||
return bstrdup(c);
|
||||
}
|
||||
|
||||
struct hashnode* hashtab[HASHTABSIZE];
|
||||
|
||||
static struct hashnode** dn_in_journal(unsigned char* dn) {
|
||||
unsigned long hashval;
|
||||
struct hashnode** hn;
|
||||
hashval=hash2(dn);
|
||||
hn=hashtab+(hashval%HASHTABSIZE);
|
||||
while (*hn) {
|
||||
if ((*hn)->hashval==hashval) {
|
||||
if (!bstr_diff((char*)(*hn)->dn,(char*)dn))
|
||||
break;
|
||||
}
|
||||
hn=&((*hn)->next);
|
||||
}
|
||||
return hn;
|
||||
}
|
||||
|
||||
static struct hashnode** dn_in_journal2(const char* dn,size_t dnlen) {
|
||||
unsigned long hashval;
|
||||
struct hashnode** hn;
|
||||
hashval=hash2((const unsigned char*)dn);
|
||||
hn=hashtab+(hashval%HASHTABSIZE);
|
||||
while (*hn) {
|
||||
if ((*hn)->hashval==hashval) {
|
||||
if (!bstr_diff2((char*)(*hn)->dn,dn,dnlen))
|
||||
break;
|
||||
}
|
||||
hn=&((*hn)->next);
|
||||
}
|
||||
return hn;
|
||||
}
|
||||
|
||||
|
||||
int parse_callback(struct ldaprec* l) {
|
||||
size_t i;
|
||||
unsigned long hashval;
|
||||
struct hashnode** hn;
|
||||
if (l->dn==(uint32)-1) return -1;
|
||||
hashval=hash2((unsigned char*)stringtable.root+l->dn);
|
||||
hn=hashtab+(hashval%HASHTABSIZE);
|
||||
while (*hn) {
|
||||
if ((*hn)->hashval==hashval) {
|
||||
if (!bstr_diff((char*)(*hn)->dn,stringtable.root+l->dn))
|
||||
break;
|
||||
}
|
||||
hn=&((*hn)->next);
|
||||
}
|
||||
if (*hn) {
|
||||
/* a record with this dn exists */
|
||||
/* adjust it to the new reality */
|
||||
for (i=0; i<(*hn)->n; ++i) {
|
||||
free((*hn)->a[i].a);
|
||||
free((*hn)->a[i].v);
|
||||
}
|
||||
*hn = realloc(*hn,sizeof(**hn)-sizeof(struct attribute2)+l->n*sizeof(struct attribute2));
|
||||
if (!*hn) nomem: die(1,"out of memory!");
|
||||
} else {
|
||||
*hn = malloc(sizeof(**hn)-sizeof(struct attribute2)+l->n*sizeof(struct attribute2));
|
||||
if (!*hn) goto nomem;
|
||||
if (!((*hn)->dn=bstrdup((unsigned char*)stringtable.root+l->dn))) goto nomem;
|
||||
(*hn)->hashval=hashval;
|
||||
(*hn)->next=0;
|
||||
}
|
||||
(*hn)->n=l->n;
|
||||
for (i=0; i<l->n; ++i) {
|
||||
if (!((*hn)->a[i].a=bstrdup_attrib((unsigned char*)attributes.strings.root+l->a[i].name)) ||
|
||||
!((*hn)->a[i].v=bstrdup((unsigned char*)((*hn)->a[i].a==(unsigned char*)map+objectClass_ofs?classes.strings.root:stringtable.root)+l->a[i].value))) goto nomem;
|
||||
}
|
||||
stringtable.used=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readjournal() {
|
||||
ldif_parse_callback=parse_callback;
|
||||
mduptab_init(&attributes);
|
||||
mduptab_init(&classes);
|
||||
return ldif_parse("journal");
|
||||
}
|
||||
|
||||
static int ldap_matchfilter_hn(struct hashnode* hn,struct Filter* f) {
|
||||
struct Filter* y=f->x;
|
||||
size_t i;
|
||||
if (!hn->n) return 0;
|
||||
if (!f) return 1;
|
||||
switch (f->type) {
|
||||
case AND:
|
||||
while (y) {
|
||||
if (!ldap_matchfilter_hn(hn,y)) return 0;
|
||||
y=y->next;
|
||||
}
|
||||
return 1;
|
||||
case OR:
|
||||
while (y) {
|
||||
if (ldap_matchfilter_hn(hn,y)) return 1;
|
||||
y=y->next;
|
||||
}
|
||||
return 0;
|
||||
case NOT:
|
||||
return !ldap_matchfilter_hn(hn,y);
|
||||
case PRESENT:
|
||||
if (f->attrofs==dn_ofs)
|
||||
return 1;
|
||||
for (i=0; i<hn->n; ++i)
|
||||
if (!matchstring(&f->ava.desc,(char*)hn->a[i].a))
|
||||
return 1;
|
||||
return 0;
|
||||
case EQUAL:
|
||||
case LESSEQUAL:
|
||||
case GREATEQUAL:
|
||||
if (f->attrofs==dn_ofs)
|
||||
return matchint(f,(char*)hn->dn);
|
||||
for (i=0; i<hn->n; ++i)
|
||||
if (!matchstring(&f->ava.desc,(char*)hn->a[i].a) &&
|
||||
matchint(f,(char*)hn->a[i].v)) return 1;
|
||||
return 0;
|
||||
case SUBSTRING:
|
||||
if (f->attrofs==dn_ofs)
|
||||
return substringmatch(f->substrings,(char*)hn->dn,f->attrflag&1);
|
||||
for (i=0; i<hn->n; ++i)
|
||||
if (!matchstring(&f->ava.desc,(char*)hn->a[i].a) &&
|
||||
substringmatch(f->substrings,(char*)hn->a[i].v,f->attrflag&1)) return 1;
|
||||
return 0;
|
||||
default:
|
||||
write(2,"unsupported query type\n",23);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return 0 if they didn't match, otherwise return length in b */
|
||||
static int match(const char* a,int len,const char* b) {
|
||||
const char* A=a+len;
|
||||
const char* B=b+str_len(b);
|
||||
while (len>0 && A>a && B>b) {
|
||||
--A; --B; --len;
|
||||
while (*A==' ' && A>a) { --A; --len; }
|
||||
while (*B==' ' && B>b) --B;
|
||||
if (tolower(*A) != tolower(*B))
|
||||
return 0;
|
||||
}
|
||||
return str_len(B);
|
||||
}
|
||||
|
||||
static int matchhashnode(struct hashnode* hn,struct SearchRequest* sr) {
|
||||
size_t i,len=bstrlen((char*)hn->dn);
|
||||
unsigned char* c;
|
||||
if (sr->baseObject.l>len)
|
||||
/* baseObject is longer than dn */
|
||||
return 0;
|
||||
if (sr->baseObject.l && !match(sr->baseObject.s,sr->baseObject.l,(char*)hn->dn))
|
||||
/* baseObject is not a suffix of dn */
|
||||
return 0;
|
||||
switch (sr->scope) {
|
||||
case wholeSubtree: break;
|
||||
case baseObject: if (len==sr->baseObject.l) break; return 0;
|
||||
default:
|
||||
c=hn->dn+bstrstart((char*)hn->dn);
|
||||
for (i=0; i<len; ++i)
|
||||
if (c[i]==',')
|
||||
break;
|
||||
if (i+2>=len-sr->baseObject.l) break;
|
||||
return 0;
|
||||
}
|
||||
return ldap_matchfilter_hn(hn,sr->filter);
|
||||
}
|
||||
|
||||
static void answerwith_hn(struct hashnode* hn,struct SearchRequest* sr,long messageid,int out) {
|
||||
struct SearchResultEntry sre;
|
||||
struct PartialAttributeList** pal=&sre.attributes;
|
||||
|
||||
if (acls)
|
||||
byte_zero(acl_ec_subjects+filters,filters);
|
||||
|
||||
if (acls && checkacl_hn(hn,(unsigned char*)map+dn_ofs,acl_read)!=1) return;
|
||||
|
||||
sre.objectName.l=bstrlen(sre.objectName.s=(char*)hn->dn);
|
||||
sre.attributes=0;
|
||||
|
||||
/* now go through list of requested attributes */
|
||||
{
|
||||
struct AttributeDescriptionList* adl=sr->attributes;
|
||||
if (!adl && hn->n && hn->n<HUGE_SIZE_FOR_SANITY_CHECKS/sizeof(*adl)) {
|
||||
/* did not ask for any attributes. send 'em all. */
|
||||
/* to do that, construct a list of all attributes */
|
||||
|
||||
uint32 i,j,k;
|
||||
adl=alloca(hn->n*sizeof(*adl));
|
||||
for (i=k=0; i<hn->n; ++i) {
|
||||
adl[k].a.s=(char*)hn->a[i].a;
|
||||
adl[k].a.l=str_len((char*)hn->a[i].a);
|
||||
adl[k].attrofs=0;
|
||||
adl[k].next=adl+k+1;
|
||||
for (j=0; j<i; ++j) {
|
||||
if (!strcmp((char*)hn->a[i].a,(char*)hn->a[j].a)) {
|
||||
--k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
}
|
||||
if (k) adl[k-1].next=0;
|
||||
}
|
||||
while (adl) {
|
||||
const unsigned char* val=0;
|
||||
uint32 i=0;
|
||||
|
||||
if (!acls || checkacl_hn(hn,(unsigned char*)adl->a.s,acl_read)==1) {
|
||||
if (!matchstring(&adl->a,"dn"))
|
||||
val=hn->dn;
|
||||
else {
|
||||
for (; i<hn->n; ++i)
|
||||
if (!matchstring(&adl->a,(char*)hn->a[i].a)) {
|
||||
val=hn->a[i].v;
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (val) {
|
||||
*pal=malloc(sizeof(struct PartialAttributeList));
|
||||
if (!*pal) {
|
||||
nomem:
|
||||
buffer_putsflush(buffer_2,"out of virtual memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
(*pal)->type=adl->a;
|
||||
{
|
||||
struct AttributeDescriptionList** a;
|
||||
a=&(*pal)->values;
|
||||
add_attribute:
|
||||
*a=malloc(sizeof(struct AttributeDescriptionList));
|
||||
if (!*a) goto nomem;
|
||||
(*a)->a.s=bstrfirst((char*)val);
|
||||
(*a)->a.l=bstrlen((char*)val);
|
||||
for (;i<hn->n; ++i)
|
||||
if (!matchstring(&adl->a,(char*)hn->a[i].a)) {
|
||||
val=hn->a[i].v;
|
||||
++i;
|
||||
a=&(*a)->next;
|
||||
goto add_attribute;
|
||||
}
|
||||
(*a)->next=0;
|
||||
}
|
||||
(*pal)->next=0;
|
||||
pal=&(*pal)->next;
|
||||
}
|
||||
}
|
||||
adl=adl->next;
|
||||
}
|
||||
}
|
||||
{
|
||||
long l=fmt_ldapsearchresultentry(0,&sre);
|
||||
char *buf;
|
||||
long tmp;
|
||||
if (l<HUGE_SIZE_FOR_SANITY_CHECKS) {
|
||||
buf=alloca(l+300); /* you never know ;) */
|
||||
if (verbose) {
|
||||
buffer_puts(buffer_2,"sre len ");
|
||||
buffer_putulong(buffer_2,l);
|
||||
buffer_putsflush(buffer_2,".\n");
|
||||
}
|
||||
tmp=fmt_ldapmessage(buf,messageid,SearchResultEntry,l);
|
||||
fmt_ldapsearchresultentry(buf+tmp,&sre);
|
||||
write(out,buf,l+tmp);
|
||||
}
|
||||
}
|
||||
free_ldappal(sre.attributes);
|
||||
}
|
||||
|
||||
static void answerwithjournal(struct SearchRequest* sr,long messageid,int out) {
|
||||
int i;
|
||||
for (i=0; i<HASHTABSIZE; ++i) { /* for all entries in hash table... */
|
||||
struct hashnode* hn=hashtab[i];
|
||||
while (hn) {
|
||||
if (matchhashnode(hn,sr)) {
|
||||
answerwith_hn(hn,sr,messageid,out);
|
||||
}
|
||||
hn=hn->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
_
|
||||
_ __ ___ __ _(_)_ __
|
||||
| '_ ` _ \ / _` | | '_ \
|
||||
| | | | | | (_| | | | | |
|
||||
|_| |_| |_|\__,_|_|_| |_|
|
||||
#endif
|
||||
*/
|
||||
|
||||
int main(int argc,char* argv[]) {
|
||||
#ifdef STANDALONE
|
||||
int sock;
|
||||
#endif
|
||||
|
||||
errmsg_iam("tinyldap");
|
||||
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
|
||||
map=mmap_read(argc>1?argv[1]:"data",&filelen);
|
||||
@@ -1456,7 +1972,7 @@ int main(int argc,char* argv[]) {
|
||||
/* look up "dn" and "objectClass" */
|
||||
{
|
||||
char* x=map+5*4+size_of_string_table;
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
dn_ofs=objectClass_ofs=userPassword_ofs=any_ofs=0;
|
||||
for (i=0; i<attribute_count; ++i) {
|
||||
uint32 j;
|
||||
@@ -1477,6 +1993,8 @@ int main(int argc,char* argv[]) {
|
||||
|
||||
load_acls();
|
||||
|
||||
readjournal();
|
||||
|
||||
#if 0
|
||||
ldif_parse("exp.ldif");
|
||||
if (!first) {
|
||||
|
||||
Reference in New Issue
Block a user