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