1 #include "common.h"
2 #include "message.h"
3 #include "errors.h"
4 #include "ldapcontrol.h"
5 #include "constants.h"
6
7 /*
8 * Converts an LDAP message into a Python structure.
9 *
10 * On success, returns a list of dictionaries.
11 * On failure, returns NULL, and sets an error.
12 *
13 * The message m is always freed, regardless of return value.
14 *
15 * If add_ctrls is non-zero, per-entry/referral/partial/intermediate
16 * controls will be added as a third item to each entry tuple
17 *
18 * If add_intermediates is non-zero, intermediate/partial results will
19 * be returned
20 */
21 PyObject *
LDAPmessage_to_python(LDAP * ld,LDAPMessage * m,int add_ctrls,int add_intermediates)22 LDAPmessage_to_python(LDAP *ld, LDAPMessage *m, int add_ctrls, int add_intermediates)
23 {
24 /* we convert an LDAP message into a python structure.
25 * It is always a list of dictionaries.
26 * We always free m.
27 */
28
29 PyObject *result, *pyctrls = 0;
30 LDAPMessage* entry;
31 LDAPControl **req_ctrls = 0;
32 int rc;
33
34 result = PyList_New(0);
35 if (result == NULL) {
36 ldap_msgfree(m);
37 return NULL;
38 }
39
40 for(
41 entry = ldap_first_entry(ld, m);
42 entry != NULL;
43 entry = ldap_next_entry(ld, entry)
44 ) {
45 char *dn;
46 char *attr;
47 BerElement *ber = NULL;
48 PyObject* entrytuple;
49 PyObject* attrdict;
50
51 dn = ldap_get_dn(ld, entry);
52 if (dn == NULL) {
53 Py_DECREF(result);
54 ldap_msgfree(m);
55 return LDAPerror(ld);
56 }
57
58 attrdict = PyDict_New();
59 if (attrdict == NULL) {
60 Py_DECREF(result);
61 ldap_msgfree(m);
62 ldap_memfree(dn);
63 return NULL;
64 }
65
66 rc = ldap_get_entry_controls( ld, entry, &req_ctrls );
67 if (rc) {
68 Py_DECREF(result);
69 ldap_msgfree(m);
70 ldap_memfree(dn);
71 return LDAPerror(ld);
72 }
73
74 /* convert req_ctrls to list of tuples */
75 if ( ! ( pyctrls = LDAPControls_to_List( req_ctrls ) ) ) {
76 int err = LDAP_NO_MEMORY;
77 ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
78 Py_DECREF(result);
79 ldap_msgfree(m);
80 ldap_memfree(dn);
81 ldap_controls_free(req_ctrls);
82 return LDAPerror(ld);
83 }
84 ldap_controls_free(req_ctrls);
85
86 /* Fill attrdict with lists */
87 for (
88 attr = ldap_first_attribute(ld, entry, &ber);
89 attr != NULL;
90 attr = ldap_next_attribute(ld, entry, ber)
91 ) {
92 PyObject* valuelist;
93 PyObject *attr_key;
94 struct berval **bvals;
95
96 attr_key = PyBytes_FromString(attr);
97 bvals = ldap_get_values_len(ld, entry, attr);
98
99 /* Find which list to append to */
100 if ( PyDict_Contains(attrdict, attr_key) ) {
101 valuelist = PyDict_GetItem(attrdict, attr_key);
102 if (valuelist != NULL)
103 /* own the ref from here */
104 Py_INCREF(valuelist);
105 } else {
106 valuelist = PyList_New(0);
107 if (
108 valuelist != NULL &&
109 PyDict_SetItem(attrdict, attr_key, valuelist) == -1
110 ) {
111 Py_DECREF(valuelist);
112 valuelist = NULL; /* catch error later */
113 }
114 }
115
116 if (valuelist == NULL) {
117 Py_DECREF(attrdict);
118 Py_DECREF(result);
119 if (ber != NULL)
120 ber_free(ber, 0);
121 ldap_msgfree(m);
122 ldap_memfree(attr);
123 ldap_memfree(dn);
124 Py_XDECREF(pyctrls);
125 return NULL;
126 }
127
128 if (bvals != NULL) {
129 Py_ssize_t i;
130
131 for (i=0; bvals[i]; i++) {
132 PyObject *valuestr;
133 valuestr = LDAPberval_to_object(bvals[i]);
134 if (PyList_Append( valuelist, valuestr ) == -1) {
135 Py_DECREF(attrdict);
136 Py_DECREF(result);
137 Py_DECREF(valuestr);
138 Py_DECREF(valuelist);
139 if (ber != NULL)
140 ber_free(ber, 0);
141 ldap_msgfree(m);
142 ldap_memfree(attr);
143 ldap_memfree(dn);
144 Py_XDECREF(pyctrls);
145 return NULL;
146 }
147 Py_DECREF(valuestr);
148 }
149
150 ldap_value_free_len(bvals);
151 }
152
153 Py_DECREF(valuelist);
154 ldap_memfree(attr);
155 }
156
157 if (add_ctrls) {
158 entrytuple = Py_BuildValue("(yOO)", dn, attrdict, pyctrls);
159 } else {
160 entrytuple = Py_BuildValue("(yO)", dn, attrdict);
161 }
162 ldap_memfree(dn);
163 Py_DECREF(attrdict);
164 Py_XDECREF(pyctrls);
165 PyList_Append(result, entrytuple);
166 Py_DECREF(entrytuple);
167 if (ber != NULL)
168 ber_free(ber, 0);
169
170 }
171
172 for(
173 entry = ldap_first_reference(ld,m);
174 entry != NULL;
175 entry = ldap_next_reference(ld,entry)
176 ) {
177 char **refs = NULL;
178 PyObject* entrytuple;
179 PyObject* reflist = PyList_New(0);
180
181 if (reflist == NULL) {
182 Py_DECREF(result);
183 ldap_msgfree(m);
184 return NULL;
185 }
186
187 if (ldap_parse_reference(ld, entry, &refs, &req_ctrls, 0) != LDAP_SUCCESS) {
188 Py_DECREF(reflist);
189 Py_DECREF(result);
190 ldap_msgfree(m);
191 return LDAPerror(ld);
192 }
193
194 /* convert req_ctrls to list of tuples */
195 if ( ! ( pyctrls = LDAPControls_to_List( req_ctrls ) ) ) {
196 int err = LDAP_NO_MEMORY;
197 ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
198 Py_DECREF(reflist);
199 Py_DECREF(result);
200 ldap_msgfree(m);
201 ldap_controls_free(req_ctrls);
202 return LDAPerror(ld);
203 }
204 ldap_controls_free(req_ctrls);
205 if (refs) {
206 Py_ssize_t i;
207 for (i=0; refs[i] != NULL; i++) {
208 PyObject *refstr = PyBytes_FromString(refs[i]);
209 PyList_Append(reflist, refstr);
210 Py_DECREF(refstr);
211 }
212 ber_memvfree( (void **) refs );
213 }
214 if (add_ctrls) {
215 entrytuple = Py_BuildValue("(yOO)", NULL, reflist, pyctrls);
216 } else {
217 entrytuple = Py_BuildValue("(yO)", NULL, reflist);
218 }
219 Py_DECREF(reflist);
220 Py_XDECREF(pyctrls);
221 PyList_Append(result, entrytuple);
222 Py_DECREF(entrytuple);
223 }
224
225 if (add_intermediates) {
226 for(
227 entry = ldap_first_message(ld,m);
228 entry != NULL;
229 entry = ldap_next_message(ld,entry)
230 ) {
231 /* list of tuples */
232 /* each tuple is OID, Berval, controllist */
233 if ( LDAP_RES_INTERMEDIATE == ldap_msgtype( entry ) ) {
234 PyObject* valtuple;
235 PyObject *valuestr;
236 char *retoid = 0;
237 struct berval *retdata = 0;
238
239 if (ldap_parse_intermediate( ld, entry, &retoid, &retdata, &req_ctrls, 0 ) != LDAP_SUCCESS) {
240 Py_DECREF(result);
241 ldap_msgfree(m);
242 return LDAPerror(ld);
243 }
244
245 /* convert req_ctrls to list of tuples */
246 if ( ! ( pyctrls = LDAPControls_to_List( req_ctrls ) ) ) {
247 int err = LDAP_NO_MEMORY;
248 ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
249 Py_DECREF(result);
250 ldap_msgfree(m);
251 ldap_controls_free(req_ctrls);
252 ldap_memfree(retoid);
253 ber_bvfree(retdata);
254 return LDAPerror(ld);
255 }
256 ldap_controls_free(req_ctrls);
257
258 valuestr = LDAPberval_to_object(retdata);
259 ber_bvfree( retdata );
260 valtuple = Py_BuildValue("(yOO)", retoid, valuestr ? valuestr : Py_None, pyctrls);
261 ldap_memfree( retoid );
262 Py_DECREF(valuestr);
263 Py_XDECREF(pyctrls);
264 PyList_Append(result, valtuple);
265 Py_DECREF(valtuple);
266 }
267 }
268 }
269
270 ldap_msgfree(m);
271 return result;
272
273 }
274