summaryrefslogtreecommitdiffstats
path: root/scan_ldapmodifyrequest.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-03-15 01:49:50 +0100
committerSimon Rettberg2014-03-15 01:49:50 +0100
commitbedd2e7ccb1595c23e159eaa952ae1b0b5a3d2ad (patch)
treec7d1995a09f6ed0c4e6873252e957d72f5d07d07 /scan_ldapmodifyrequest.c
downloadldadp-bedd2e7ccb1595c23e159eaa952ae1b0b5a3d2ad.tar.gz
ldadp-bedd2e7ccb1595c23e159eaa952ae1b0b5a3d2ad.tar.xz
ldadp-bedd2e7ccb1595c23e159eaa952ae1b0b5a3d2ad.zip
Lean and mean initial commit
Not much functionality yet
Diffstat (limited to 'scan_ldapmodifyrequest.c')
-rw-r--r--scan_ldapmodifyrequest.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/scan_ldapmodifyrequest.c b/scan_ldapmodifyrequest.c
new file mode 100644
index 0000000..ba42e4f
--- /dev/null
+++ b/scan_ldapmodifyrequest.c
@@ -0,0 +1,88 @@
+#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, 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);
+}