3
3
4
4
#include "common.h"
5
5
#include "constants.h"
6
+ #include "ldapcontrol.h"
6
7
#include "lber.h"
7
8
#include "ldap.h"
8
9
@@ -48,38 +49,81 @@ LDAPerr(int errnum)
48
49
49
50
/* Convert an LDAP error into an informative python exception */
50
51
PyObject *
51
- LDAPerror (LDAP * l , char * msg )
52
+ LDAPraise_for_message (LDAP * l , char * msg , LDAPMessage * m )
52
53
{
53
54
if (l == NULL ) {
54
55
PyErr_SetFromErrno (LDAPexception_class );
56
+ ldap_msgfree (m );
55
57
return NULL ;
56
58
}
57
59
else {
58
- int myerrno , errnum , opt_errnum ;
60
+ int myerrno , errnum , opt_errnum , msgid = -1 , msgtype = 0 ;
59
61
PyObject * errobj ;
60
62
PyObject * info ;
61
63
PyObject * str ;
62
64
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 ;
64
71
65
72
/* at first save errno for later use before it gets overwritten by another call */
66
73
myerrno = errno ;
67
74
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
+ }
71
81
72
- if (errnum == LDAP_NO_MEMORY )
73
- return PyErr_NoMemory ();
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
+ }
74
94
75
95
if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX )
76
96
errobj = errobjects [errnum + LDAP_ERROR_OFFSET ];
77
97
else
78
98
errobj = LDAPexception_class ;
79
99
80
100
info = PyDict_New ();
81
- if (info == NULL )
101
+ if (info == NULL ) {
102
+ ldap_memfree (matched );
103
+ ldap_memfree (error );
104
+ ldap_memvfree ((void * * )refs );
105
+ ldap_controls_free (serverctrls );
82
106
return NULL ;
107
+ }
108
+
109
+ if (msgtype > 0 ) {
110
+ pyresult = PyInt_FromLong (msgtype );
111
+ if (pyresult )
112
+ PyDict_SetItemString (info , "msgtype" , pyresult );
113
+ Py_XDECREF (pyresult );
114
+ }
115
+
116
+ if (msgid >= 0 ) {
117
+ pyresult = PyInt_FromLong (msgid );
118
+ if (pyresult )
119
+ PyDict_SetItemString (info , "msgid" , pyresult );
120
+ Py_XDECREF (pyresult );
121
+ }
122
+
123
+ pyresult = PyInt_FromLong (errnum );
124
+ if (pyresult )
125
+ PyDict_SetItemString (info , "result" , pyresult );
126
+ Py_XDECREF (pyresult );
83
127
84
128
str = PyUnicode_FromString (ldap_err2string (errnum ));
85
129
if (str )
@@ -93,8 +137,21 @@ LDAPerror(LDAP *l, char *msg)
93
137
Py_XDECREF (pyerrno );
94
138
}
95
139
96
- if (ldap_get_option (l , LDAP_OPT_MATCHED_DN , & matched ) >= 0
97
- && matched != NULL ) {
140
+ if (!(pyctrls = LDAPControls_to_List (serverctrls ))) {
141
+ int err = LDAP_NO_MEMORY ;
142
+
143
+ ldap_set_option (l , LDAP_OPT_ERROR_NUMBER , & err );
144
+ ldap_memfree (matched );
145
+ ldap_memfree (error );
146
+ ldap_memvfree ((void * * )refs );
147
+ ldap_controls_free (serverctrls );
148
+ return PyErr_NoMemory ();
149
+ }
150
+ ldap_controls_free (serverctrls );
151
+ PyDict_SetItemString (info , "ctrls" , pyctrls );
152
+ Py_XDECREF (pyctrls );
153
+
154
+ if (matched != NULL ) {
98
155
if (* matched != '\0' ) {
99
156
str = PyUnicode_FromString (matched );
100
157
if (str )
@@ -104,27 +161,38 @@ LDAPerror(LDAP *l, char *msg)
104
161
ldap_memfree (matched );
105
162
}
106
163
107
- if (errnum == LDAP_REFERRAL ) {
164
+ if (errnum == LDAP_REFERRAL && refs != NULL && refs [0 ] != NULL ) {
165
+ /* Keep old behaviour, overshadow error message */
166
+ char err [1024 ];
167
+
168
+ snprintf (err , sizeof (err ), "Referral:\n%s" , refs [0 ]);
169
+ str = PyUnicode_FromString (err );
170
+ PyDict_SetItemString (info , "info" , str );
171
+ Py_XDECREF (str );
172
+ }
173
+ else if (msg != NULL || (error != NULL && * error != '\0' )) {
174
+ msg = msg ? msg : error ;
175
+
108
176
str = PyUnicode_FromString (msg );
109
177
if (str )
110
178
PyDict_SetItemString (info , "info" , str );
111
179
Py_XDECREF (str );
112
180
}
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
- }
181
+
122
182
PyErr_SetObject (errobj , info );
123
183
Py_DECREF (info );
184
+ ldap_memvfree ((void * * )refs );
185
+ ldap_memfree (error );
124
186
return NULL ;
125
187
}
126
188
}
127
189
190
+ PyObject *
191
+ LDAPerror (LDAP * l , char * msg )
192
+ {
193
+ return LDAPraise_for_message (l , msg , NULL );
194
+ }
195
+
128
196
/* initialise the module constants */
129
197
130
198
int
0 commit comments