1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include <stdlib.h>
#include "ldap.h"
#if 0
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
object LDAPDN,
modification SEQUENCE OF SEQUENCE {
operation ENUMERATED {
add (0),
delete (1),
replace (2) },
modification AttributeTypeAndValues } }
AttributeTypeAndValues ::= SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
#endif
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;
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&oslen))) goto error;
res+=tmp;
if (src+res+oslen>max) goto error;
max=src+res+oslen;
if (src+res>=max) goto error; /* need at least one record */
do {
size_t islen;
unsigned long etmp;
if (last) {
struct Modification* cur;
if (!(cur=malloc(sizeof(struct Modification)))) goto error;
last->next=cur; last=cur;
} else
last=&m->m;
last->next=0;
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen))) goto error;
res+=tmp;
if (!(tmp=scan_asn1ENUMERATED(src+res,max,&etmp))) goto error;
if (etmp>2) goto error; last->operation=etmp; res+=tmp;
{
size_t iislen; /* urgh, _three_ levels of indirection */
const char* imax;
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&iislen))) goto error;
res+=tmp;
imax=src+res+iislen;
if (imax>max) goto error;
if (!(tmp=scan_ldapstring(src+res,imax,&last->AttributeDescription))) goto error;
res+=tmp;
{
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;
res+=tmp;
iimax=src+res+iiislen;
if (src+res+iiislen!=imax) goto error;
ilast=&last->vals;
while (src+res<iimax) {
if (!(*ilast=malloc(sizeof(struct AttributeDescriptionList)))) goto error;
if (!(tmp=scan_ldapstring(src+res,imax,&(*ilast)->a))) goto error;
(*ilast)->next=0;
ilast=&(*ilast)->next;
res+=tmp;
}
}
}
break;
} while (src+res<max);
return res;
error:
free_ldapmodifyrequest(m);
return 0;
}
static void free_mod(struct Modification* m) {
while (m) {
struct Modification* tmp=m->next;
free(m);
m=tmp;
}
}
void free_ldapmodifyrequest(struct ModifyRequest* m) {
free_ldapadl(m->m.vals);
free_mod(m->m.next);
}
|