Skip to content

Commit 69832b5

Browse files
committed
Attach msgid/controls/... to exceptions (Closes #177, #208)
Closes: #177 (msgid) #208 (controls)
1 parent 624e332 commit 69832b5

File tree

6 files changed

+108
-52
lines changed

6 files changed

+108
-52
lines changed

Modules/LDAPObject.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ l_ldap_unbind_ext(LDAPObject *self, PyObject *args)
415415
LDAPControl_List_DEL(client_ldcs);
416416

417417
if (ldaperror != LDAP_SUCCESS)
418-
return LDAPerror(self->ldap, "ldap_unbind_ext");
418+
return LDAPerror(self->ldap, "ldap_unbind_ext", NULL);
419419

420420
self->valid = 0;
421421
Py_INCREF(Py_None);
@@ -461,7 +461,7 @@ l_ldap_abandon_ext(LDAPObject *self, PyObject *args)
461461
LDAPControl_List_DEL(client_ldcs);
462462

463463
if (ldaperror != LDAP_SUCCESS)
464-
return LDAPerror(self->ldap, "ldap_abandon_ext");
464+
return LDAPerror(self->ldap, "ldap_abandon_ext", NULL);
465465

466466
Py_INCREF(Py_None);
467467
return Py_None;
@@ -517,7 +517,7 @@ l_ldap_add_ext(LDAPObject *self, PyObject *args)
517517
LDAPControl_List_DEL(client_ldcs);
518518

519519
if (ldaperror != LDAP_SUCCESS)
520-
return LDAPerror(self->ldap, "ldap_add_ext");
520+
return LDAPerror(self->ldap, "ldap_add_ext", NULL);
521521

522522
return PyInt_FromLong(msgid);
523523
}
@@ -568,7 +568,7 @@ l_ldap_simple_bind(LDAPObject *self, PyObject *args)
568568
LDAPControl_List_DEL(client_ldcs);
569569

570570
if (ldaperror != LDAP_SUCCESS)
571-
return LDAPerror(self->ldap, "ldap_simple_bind");
571+
return LDAPerror(self->ldap, "ldap_simple_bind", NULL);
572572

573573
return PyInt_FromLong(msgid);
574574
}
@@ -727,7 +727,7 @@ l_ldap_sasl_bind_s(LDAPObject *self, PyObject *args)
727727
servercred->bv_len);
728728
}
729729
else if (ldaperror != LDAP_SUCCESS)
730-
return LDAPerror(self->ldap, "l_ldap_sasl_bind_s");
730+
return LDAPerror(self->ldap, "l_ldap_sasl_bind_s", NULL);
731731
return PyInt_FromLong(ldaperror);
732732
}
733733

@@ -806,7 +806,7 @@ l_ldap_sasl_interactive_bind_s(LDAPObject *self, PyObject *args)
806806
LDAPControl_List_DEL(client_ldcs);
807807

808808
if (msgid != LDAP_SUCCESS)
809-
return LDAPerror(self->ldap, "ldap_sasl_interactive_bind_s");
809+
return LDAPerror(self->ldap, "ldap_sasl_interactive_bind_s", NULL);
810810
return PyInt_FromLong(msgid);
811811
}
812812
#endif
@@ -854,7 +854,7 @@ l_ldap_cancel(LDAPObject *self, PyObject *args)
854854
LDAPControl_List_DEL(client_ldcs);
855855

856856
if (ldaperror != LDAP_SUCCESS)
857-
return LDAPerror(self->ldap, "ldap_cancel");
857+
return LDAPerror(self->ldap, "ldap_cancel", NULL);
858858

859859
return PyInt_FromLong(msgid);
860860
}
@@ -908,7 +908,7 @@ l_ldap_compare_ext(LDAPObject *self, PyObject *args)
908908
LDAPControl_List_DEL(client_ldcs);
909909

910910
if (ldaperror != LDAP_SUCCESS)
911-
return LDAPerror(self->ldap, "ldap_compare_ext");
911+
return LDAPerror(self->ldap, "ldap_compare_ext", NULL);
912912

913913
return PyInt_FromLong(msgid);
914914
}
@@ -954,7 +954,7 @@ l_ldap_delete_ext(LDAPObject *self, PyObject *args)
954954
LDAPControl_List_DEL(client_ldcs);
955955

956956
if (ldaperror != LDAP_SUCCESS)
957-
return LDAPerror(self->ldap, "ldap_delete_ext");
957+
return LDAPerror(self->ldap, "ldap_delete_ext", NULL);
958958

959959
return PyInt_FromLong(msgid);
960960
}
@@ -1011,7 +1011,7 @@ l_ldap_modify_ext(LDAPObject *self, PyObject *args)
10111011
LDAPControl_List_DEL(client_ldcs);
10121012

10131013
if (ldaperror != LDAP_SUCCESS)
1014-
return LDAPerror(self->ldap, "ldap_modify_ext");
1014+
return LDAPerror(self->ldap, "ldap_modify_ext", NULL);
10151015

10161016
return PyInt_FromLong(msgid);
10171017
}
@@ -1061,7 +1061,7 @@ l_ldap_rename(LDAPObject *self, PyObject *args)
10611061
LDAPControl_List_DEL(client_ldcs);
10621062

10631063
if (ldaperror != LDAP_SUCCESS)
1064-
return LDAPerror(self->ldap, "ldap_rename");
1064+
return LDAPerror(self->ldap, "ldap_rename", NULL);
10651065

10661066
return PyInt_FromLong(msgid);
10671067
}
@@ -1109,7 +1109,7 @@ l_ldap_result4(LDAPObject *self, PyObject *args)
11091109
LDAP_END_ALLOW_THREADS(self);
11101110

11111111
if (res_type < 0) /* LDAP or system error */
1112-
return LDAPerror(self->ldap, "ldap_result4");
1112+
return LDAPerror(self->ldap, "ldap_result4", msg);
11131113

11141114
if (res_type == 0) {
11151115
/* Polls return (None, None, None, None); timeouts raise an exception */
@@ -1172,9 +1172,8 @@ l_ldap_result4(LDAPObject *self, PyObject *args)
11721172
else
11731173
e = "ldap_parse_result";
11741174
ldap_controls_free(serverctrls);
1175-
ldap_msgfree(msg);
11761175
Py_XDECREF(valuestr);
1177-
return LDAPerror(self->ldap, e);
1176+
return LDAPerror(self->ldap, e, msg);
11781177
}
11791178

11801179
if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
@@ -1186,7 +1185,7 @@ l_ldap_result4(LDAPObject *self, PyObject *args)
11861185
ldap_controls_free(serverctrls);
11871186
ldap_msgfree(msg);
11881187
Py_XDECREF(valuestr);
1189-
return LDAPerror(self->ldap, "LDAPControls_to_List");
1188+
return LDAPerror(self->ldap, "LDAPControls_to_List", NULL);
11901189
}
11911190
ldap_controls_free(serverctrls);
11921191

@@ -1287,7 +1286,7 @@ l_ldap_search_ext(LDAPObject *self, PyObject *args)
12871286
LDAPControl_List_DEL(client_ldcs);
12881287

12891288
if (ldaperror != LDAP_SUCCESS)
1290-
return LDAPerror(self->ldap, "ldap_search_ext");
1289+
return LDAPerror(self->ldap, "ldap_search_ext", NULL);
12911290

12921291
return PyInt_FromLong(msgid);
12931292
}
@@ -1334,7 +1333,7 @@ l_ldap_whoami_s(LDAPObject *self, PyObject *args)
13341333

13351334
if (ldaperror != LDAP_SUCCESS) {
13361335
ber_bvfree(bvalue);
1337-
return LDAPerror(self->ldap, "ldap_whoami_s");
1336+
return LDAPerror(self->ldap, "ldap_whoami_s", NULL);
13381337
}
13391338

13401339
result = LDAPberval_to_unicode_object(bvalue);
@@ -1361,7 +1360,7 @@ l_ldap_start_tls_s(LDAPObject *self, PyObject *args)
13611360
LDAP_END_ALLOW_THREADS(self);
13621361
if (ldaperror != LDAP_SUCCESS) {
13631362
ldap_set_option(self->ldap, LDAP_OPT_ERROR_NUMBER, &ldaperror);
1364-
return LDAPerror(self->ldap, "ldap_start_tls_s");
1363+
return LDAPerror(self->ldap, "ldap_start_tls_s", NULL);
13651364
}
13661365

13671366
Py_INCREF(Py_None);
@@ -1453,7 +1452,7 @@ l_ldap_passwd(LDAPObject *self, PyObject *args)
14531452
LDAPControl_List_DEL(client_ldcs);
14541453

14551454
if (ldaperror != LDAP_SUCCESS)
1456-
return LDAPerror(self->ldap, "ldap_passwd");
1455+
return LDAPerror(self->ldap, "ldap_passwd", NULL);
14571456

14581457
return PyInt_FromLong(msgid);
14591458
}
@@ -1504,7 +1503,7 @@ l_ldap_extended_operation(LDAPObject *self, PyObject *args)
15041503
LDAPControl_List_DEL(client_ldcs);
15051504

15061505
if (ldaperror != LDAP_SUCCESS)
1507-
return LDAPerror(self->ldap, "ldap_extended_operation");
1506+
return LDAPerror(self->ldap, "ldap_extended_operation", NULL);
15081507

15091508
return PyInt_FromLong(msgid);
15101509
}

Modules/constants.c

Lines changed: 78 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "common.h"
55
#include "constants.h"
6+
#include "ldapcontrol.h"
67
#include "lber.h"
78
#include "ldap.h"
89

@@ -48,38 +49,92 @@ LDAPerr(int errnum)
4849

4950
/* Convert an LDAP error into an informative python exception */
5051
PyObject *
51-
LDAPerror(LDAP *l, char *msg)
52+
LDAPerror(LDAP *l, char *msg, LDAPMessage *m)
5253
{
5354
if (l == NULL) {
5455
PyErr_SetFromErrno(LDAPexception_class);
56+
ldap_msgfree(m);
5557
return NULL;
5658
}
5759
else {
58-
int myerrno, errnum, opt_errnum;
60+
int myerrno, errnum, opt_errnum, msgid = -1, msgtype = 0;
5961
PyObject *errobj;
6062
PyObject *info;
6163
PyObject *str;
6264
PyObject *pyerrno;
63-
char *matched, *error;
65+
PyObject *pyresult;
66+
PyObject *pyctrls = NULL;
67+
char *matched = NULL,
68+
*error = NULL,
69+
**refs = NULL;
70+
LDAPControl **serverctrls = NULL;
6471

6572
/* at first save errno for later use before it gets overwritten by another call */
6673
myerrno = errno;
6774

68-
opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum);
69-
if (opt_errnum != LDAP_OPT_SUCCESS)
70-
errnum = opt_errnum;
75+
if (m != NULL) {
76+
msgid = ldap_msgid(m);
77+
msgtype = ldap_msgtype(m);
78+
ldap_parse_result(l, m, &errnum, &matched, &error, &refs,
79+
&serverctrls, 1);
80+
}
81+
82+
if (msgtype <= 0) {
83+
opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum);
84+
if (opt_errnum != LDAP_OPT_SUCCESS)
85+
errnum = opt_errnum;
86+
87+
if (errnum == LDAP_NO_MEMORY) {
88+
return PyErr_NoMemory();
89+
}
90+
91+
ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched);
92+
ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error);
93+
}
94+
95+
if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
96+
int err = LDAP_NO_MEMORY;
7197

72-
if (errnum == LDAP_NO_MEMORY)
98+
ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err);
99+
ldap_memfree(matched);
100+
ldap_memfree(error);
101+
ldap_memvfree((void **)refs);
102+
ldap_controls_free(serverctrls);
73103
return PyErr_NoMemory();
104+
}
105+
ldap_controls_free(serverctrls);
74106

75107
if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX)
76108
errobj = errobjects[errnum + LDAP_ERROR_OFFSET];
77109
else
78110
errobj = LDAPexception_class;
79111

80112
info = PyDict_New();
81-
if (info == NULL)
113+
if (info == NULL) {
114+
ldap_memfree(matched);
115+
ldap_memfree(error);
116+
ldap_memvfree((void **)refs);
82117
return NULL;
118+
}
119+
120+
if (msgtype > 0) {
121+
pyresult = PyInt_FromLong(msgtype);
122+
if (pyresult)
123+
PyDict_SetItemString(info, "msgtype", pyresult);
124+
Py_XDECREF(pyresult);
125+
}
126+
127+
if (msgid >= 0) {
128+
pyresult = PyInt_FromLong(msgid);
129+
if (pyresult)
130+
PyDict_SetItemString(info, "msgid", pyresult);
131+
Py_XDECREF(pyresult);
132+
}
133+
134+
pyresult = PyInt_FromLong(errnum);
135+
if (pyresult)
136+
PyDict_SetItemString(info, "result", pyresult);
137+
Py_XDECREF(pyresult);
83138

84139
str = PyUnicode_FromString(ldap_err2string(errnum));
85140
if (str)
@@ -93,8 +148,7 @@ LDAPerror(LDAP *l, char *msg)
93148
Py_XDECREF(pyerrno);
94149
}
95150

96-
if (ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched) >= 0
97-
&& matched != NULL) {
151+
if (matched != NULL) {
98152
if (*matched != '\0') {
99153
str = PyUnicode_FromString(matched);
100154
if (str)
@@ -104,23 +158,26 @@ LDAPerror(LDAP *l, char *msg)
104158
ldap_memfree(matched);
105159
}
106160

107-
if (errnum == LDAP_REFERRAL) {
108-
str = PyUnicode_FromString(msg);
161+
if (errnum == LDAP_REFERRAL && refs != NULL && refs[0] != NULL) {
162+
/* Keep old behaviour, overshadow error message */
163+
char err[1024];
164+
165+
snprintf(err, sizeof(err), "Referral:\n%s", refs[0]);
166+
str = PyUnicode_FromString(err);
167+
PyDict_SetItemString(info, "info", str);
168+
Py_XDECREF(str);
169+
}
170+
else if (error != NULL && *error != '\0') {
171+
str = PyUnicode_FromString(error);
109172
if (str)
110173
PyDict_SetItemString(info, "info", str);
111174
Py_XDECREF(str);
112175
}
113-
else if (ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error) >= 0) {
114-
if (error != NULL && *error != '\0') {
115-
str = PyUnicode_FromString(error);
116-
if (str)
117-
PyDict_SetItemString(info, "info", str);
118-
Py_XDECREF(str);
119-
}
120-
ldap_memfree(error);
121-
}
176+
122177
PyErr_SetObject(errobj, info);
123178
Py_DECREF(info);
179+
ldap_memvfree((void **)refs);
180+
ldap_memfree(error);
124181
return NULL;
125182
}
126183
}

Modules/constants.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern int LDAPinit_constants(PyObject *m);
1111
extern PyObject *LDAPconstant(int);
1212

1313
extern PyObject *LDAPexception_class;
14-
extern PyObject *LDAPerror(LDAP *, char *msg);
14+
extern PyObject *LDAPerror(LDAP *, char *msg, LDAPMessage *m);
1515
PyObject *LDAPerr(int errnum);
1616

1717
#ifndef LDAP_CONTROL_PAGE_OID

Modules/functions.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ l_ldap_initialize(PyObject *unused, PyObject *args)
2121

2222
Py_BEGIN_ALLOW_THREADS ret = ldap_initialize(&ld, uri);
2323
Py_END_ALLOW_THREADS if (ret != LDAP_SUCCESS)
24-
return LDAPerror(ld, "ldap_initialize");
24+
return LDAPerror(ld, "ldap_initialize", NULL);
2525
return (PyObject *)newLDAPObject(ld);
2626
}
2727

Modules/ldapcontrol.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,14 +350,14 @@ encode_assertion_control(PyObject *self, PyObject *args)
350350
*/
351351
Py_BEGIN_ALLOW_THREADS err = ldap_create(&ld);
352352
Py_END_ALLOW_THREADS if (err != LDAP_SUCCESS)
353-
return LDAPerror(ld, "ldap_create");
353+
return LDAPerror(ld, "ldap_create", NULL);
354354

355355
err =
356356
ldap_create_assertion_control_value(ld, assertion_filterstr,
357357
&ctrl_val);
358358

359359
if (err != LDAP_SUCCESS) {
360-
LDAPerror(ld, "ldap_create_assertion_control_value");
360+
LDAPerror(ld, "ldap_create_assertion_control_value", NULL);
361361
Py_BEGIN_ALLOW_THREADS ldap_unbind_ext(ld, NULL, NULL);
362362
Py_END_ALLOW_THREADS return NULL;
363363
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy