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