summaryrefslogtreecommitdiffstats
path: root/scan_ldapaddrequest.c
blob: d311324d6f3dbc3e8540d80867854ece46a815e8 (plain) (blame)
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
90
91
92
93
94
95
#include <stdlib.h>
#include "ldap.h"
#include <buffer.h>
#include <byte.h>

#if 0
        AddRequest ::= [APPLICATION 8] SEQUENCE {
                entry           LDAPDN,
                attributes      SEQUENCE OF SEQUENCE {
                        type            AttributeDescription,
                        vals            SET OF AttributeValue } }

        AttributeList ::= SEQUENCE OF SEQUENCE {
                type    AttributeDescription,
                vals    SET OF AttributeValue }
#endif

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;
  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;
    if (last) {
      struct Addition* cur;
      if (!(cur=malloc(sizeof(struct Addition))))
        goto error;
      last->next=cur;
      last=cur;
    } else {
      last=&a->a;
    }
    last->next=0;
    if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen)))
      goto error;
    res+=tmp;
    /* scan AttributeDescription: */
    if (!(tmp=scan_ldapstring(src+res,max,&last->AttributeDescription)))
      goto error;
    res+=tmp;

    /* scan set of AttributeValue: */
    {
      size_t set_len;
      const char* set_max;
      struct AttributeDescriptionList* ilast=0;
      if (!(tmp=scan_asn1SET(src+res,max,&set_len))) {
        goto error;
      }
      res+=tmp;
      set_max=src+res+set_len;
      if (src+res+set_len!=set_max) {
        goto error;
      }
      while (src+res<set_max) {
        if (ilast) {
          struct AttributeDescriptionList* x;
          if (!(x=malloc(sizeof(struct AttributeDescriptionList)))) goto error;
          ilast->next=x;
          ilast = ilast->next;
        } else {
          ilast=&last->vals;
        }
	ilast->next=0;
        if (!(tmp=scan_ldapstring(src+res,max,&ilast->a)))
          goto error;
        res+=tmp;
      }
    }
  } while (src+res<max);
//  buffer_putsflush(buffer_2,"done with scan_ldapaddrequest!\n");
  return res;
error:
  free_ldapaddrequest(a);
  return 0;
}

static void free_add(struct Addition * a) {
  while (a) {
    struct Addition * tmp = a->next;
    free(a);
    a = tmp;
  }
}

void free_ldapaddrequest(struct AddRequest * a) {
  free_ldapadl(a->a.vals.next);
  free_add(a->a.next);
}