Gentoo Archives: gentoo-commits

From: "Eray Aslan (eras)" <eras@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in app-crypt/mit-krb5/files: mit-krb5-CVE-2014-5354.patch 2015-001-patch-r113.patch mit-krb5-CVE-2014-5353.patch
Date: Thu, 05 Feb 2015 16:24:45
Message-Id: 20150205162440.AE1F6111E5@oystercatcher.gentoo.org
1 eras 15/02/05 16:24:40
2
3 Added: mit-krb5-CVE-2014-5354.patch
4 2015-001-patch-r113.patch
5 mit-krb5-CVE-2014-5353.patch
6 Log:
7 Security bump - bugs #533734 #538842
8
9 (Portage version: 2.2.15/cvs/Linux x86_64, signed Manifest commit with key 0x77F1F175586A3B1F)
10
11 Revision Changes Path
12 1.1 app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch
13
14 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch?rev=1.1&view=markup
15 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch?rev=1.1&content-type=text/plain
16
17 Index: mit-krb5-CVE-2014-5354.patch
18 ===================================================================
19 diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
20 index 3e560d9..10b5982 100644
21 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
22 +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
23 @@ -406,14 +406,14 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data,
24 int num_versions = 1;
25 int i, j, last;
26 krb5_error_code err = 0;
27 - krb5_key_data *key_data;
28 + krb5_key_data *key_data = NULL;
29
30 - if (n_key_data <= 0)
31 + if (n_key_data < 0)
32 return NULL;
33
34 /* Make a shallow copy of the key data so we can alter it. */
35 key_data = k5calloc(n_key_data, sizeof(*key_data), &err);
36 - if (key_data_in == NULL)
37 + if (key_data == NULL)
38 goto cleanup;
39 memcpy(key_data, key_data_in, n_key_data * sizeof(*key_data));
40
41 @@ -467,9 +467,8 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data,
42 free(key_data);
43 if (err != 0) {
44 if (ret != NULL) {
45 - for (i = 0; i <= num_versions; i++)
46 - if (ret[i] != NULL)
47 - free (ret[i]);
48 + for (i = 0; ret[i] != NULL; i++)
49 + free (ret[i]);
50 free (ret);
51 ret = NULL;
52 }
53 @@ -1036,9 +1035,19 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
54 bersecretkey = krb5_encode_krbsecretkey (entry->key_data,
55 entry->n_key_data, mkvno);
56
57 - if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
58 - LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0)
59 + if (bersecretkey == NULL) {
60 + st = ENOMEM;
61 goto cleanup;
62 + }
63 + /* An empty list of bervals is only accepted for modify operations,
64 + * not add operations. */
65 + if (bersecretkey[0] != NULL || !create_standalone_prinicipal) {
66 + st = krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
67 + LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
68 + bersecretkey);
69 + if (st != 0)
70 + goto cleanup;
71 + }
72
73 if (!(entry->mask & KADM5_PRINCIPAL)) {
74 memset(strval, 0, sizeof(strval));
75
76
77
78 1.1 app-crypt/mit-krb5/files/2015-001-patch-r113.patch
79
80 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/2015-001-patch-r113.patch?rev=1.1&view=markup
81 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/2015-001-patch-r113.patch?rev=1.1&content-type=text/plain
82
83 Index: 2015-001-patch-r113.patch
84 ===================================================================
85 diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
86 index 3837931..f4d2a7c 100644
87 --- a/src/kadmin/server/kadm_rpc_svc.c
88 +++ b/src/kadmin/server/kadm_rpc_svc.c
89 @@ -4,7 +4,7 @@
90 *
91 */
92
93 -#include <k5-platform.h>
94 +#include <k5-int.h>
95 #include <gssrpc/rpc.h>
96 #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
97 #include <syslog.h>
98 @@ -296,14 +296,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
99 c1 = krb5_princ_component(kctx, princ, 0);
100 c2 = krb5_princ_component(kctx, princ, 1);
101 realm = krb5_princ_realm(kctx, princ);
102 - if (strncmp(handle->params.realm, realm->data, realm->length) == 0
103 - && strncmp("kadmin", c1->data, c1->length) == 0) {
104 -
105 - if (strncmp("history", c2->data, c2->length) == 0)
106 - goto fail_princ;
107 - else
108 - success = 1;
109 - }
110 + success = data_eq_string(*realm, handle->params.realm) &&
111 + data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history");
112
113 fail_princ:
114 if (!success) {
115 diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
116 index b3d1db0..a18cfb0 100644
117 --- a/src/lib/gssapi/krb5/context_time.c
118 +++ b/src/lib/gssapi/krb5/context_time.c
119 @@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
120
121 ctx = (krb5_gss_ctx_id_rec *) context_handle;
122
123 - if (! ctx->established) {
124 + if (ctx->terminated || !ctx->established) {
125 *minor_status = KG_CTX_INCOMPLETE;
126 return(GSS_S_NO_CONTEXT);
127 }
128 diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c
129 index 18a3a34..1b3de68 100644
130 --- a/src/lib/gssapi/krb5/export_sec_context.c
131 +++ b/src/lib/gssapi/krb5/export_sec_context.c
132 @@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
133 *minor_status = 0;
134
135 ctx = (krb5_gss_ctx_id_t) *context_handle;
136 + if (ctx->terminated) {
137 + *minor_status = KG_CTX_INCOMPLETE;
138 + return (GSS_S_NO_CONTEXT);
139 + }
140 +
141 context = ctx->k5_context;
142 kret = krb5_gss_ser_init(context);
143 if (kret)
144 diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
145 index 7e807cc..a0e8625 100644
146 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h
147 +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
148 @@ -206,6 +206,7 @@ typedef struct _krb5_gss_ctx_id_rec {
149 unsigned int established : 1;
150 unsigned int have_acceptor_subkey : 1;
151 unsigned int seed_init : 1; /* XXX tested but never actually set */
152 + unsigned int terminated : 1;
153 OM_uint32 gss_flags;
154 unsigned char seed[16];
155 krb5_gss_name_t here;
156 diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
157 index 6456b23..77b7fff 100644
158 --- a/src/lib/gssapi/krb5/gssapi_krb5.c
159 +++ b/src/lib/gssapi/krb5/gssapi_krb5.c
160 @@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
161
162 ctx = (krb5_gss_ctx_id_rec *) context_handle;
163
164 - if (!ctx->established)
165 + if (ctx->terminated || !ctx->established)
166 return GSS_S_NO_CONTEXT;
167
168 for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/
169 diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
170 index eacb0fd..096df2a 100644
171 --- a/src/lib/gssapi/krb5/inq_context.c
172 +++ b/src/lib/gssapi/krb5/inq_context.c
173 @@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
174
175 ctx = (krb5_gss_ctx_id_rec *) context_handle;
176
177 - if (! ctx->established) {
178 + if (ctx->terminated || !ctx->established) {
179 *minor_status = KG_CTX_INCOMPLETE;
180 return(GSS_S_NO_CONTEXT);
181 }
182 diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
183 index 7665cba..f1c74dd 100644
184 --- a/src/lib/gssapi/krb5/k5seal.c
185 +++ b/src/lib/gssapi/krb5/k5seal.c
186 @@ -342,7 +342,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
187
188 ctx = (krb5_gss_ctx_id_rec *) context_handle;
189
190 - if (! ctx->established) {
191 + if (ctx->terminated || !ctx->established) {
192 *minor_status = KG_CTX_INCOMPLETE;
193 return(GSS_S_NO_CONTEXT);
194 }
195 diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c
196 index a129670..b53e348 100644
197 --- a/src/lib/gssapi/krb5/k5sealiov.c
198 +++ b/src/lib/gssapi/krb5/k5sealiov.c
199 @@ -281,7 +281,7 @@ kg_seal_iov(OM_uint32 *minor_status,
200 }
201
202 ctx = (krb5_gss_ctx_id_rec *)context_handle;
203 - if (!ctx->established) {
204 + if (ctx->terminated || !ctx->established) {
205 *minor_status = KG_CTX_INCOMPLETE;
206 return GSS_S_NO_CONTEXT;
207 }
208 diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
209 index 0573958..673c883 100644
210 --- a/src/lib/gssapi/krb5/k5unseal.c
211 +++ b/src/lib/gssapi/krb5/k5unseal.c
212 @@ -492,7 +492,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
213
214 ctx = (krb5_gss_ctx_id_rec *) context_handle;
215
216 - if (! ctx->established) {
217 + if (ctx->terminated || !ctx->established) {
218 *minor_status = KG_CTX_INCOMPLETE;
219 return(GSS_S_NO_CONTEXT);
220 }
221 diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
222 index f34d802..8b67042 100644
223 --- a/src/lib/gssapi/krb5/k5unsealiov.c
224 +++ b/src/lib/gssapi/krb5/k5unsealiov.c
225 @@ -625,7 +625,7 @@ kg_unseal_iov(OM_uint32 *minor_status,
226 OM_uint32 code;
227
228 ctx = (krb5_gss_ctx_id_rec *)context_handle;
229 - if (!ctx->established) {
230 + if (ctx->terminated || !ctx->established) {
231 *minor_status = KG_CTX_INCOMPLETE;
232 return GSS_S_NO_CONTEXT;
233 }
234 diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c
235 index 85df7fd..449e71f 100644
236 --- a/src/lib/gssapi/krb5/lucid_context.c
237 +++ b/src/lib/gssapi/krb5/lucid_context.c
238 @@ -75,6 +75,11 @@ gss_krb5int_export_lucid_sec_context(
239 *minor_status = 0;
240 *data_set = GSS_C_NO_BUFFER_SET;
241
242 + if (ctx->terminated || !ctx->established) {
243 + *minor_status = KG_CTX_INCOMPLETE;
244 + return GSS_S_NO_CONTEXT;
245 + }
246 +
247 retval = generic_gss_oid_decompose(minor_status,
248 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID,
249 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH,
250 diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
251 index e19291f..e897074 100644
252 --- a/src/lib/gssapi/krb5/prf.c
253 +++ b/src/lib/gssapi/krb5/prf.c
254 @@ -58,6 +58,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status,
255 ns.data = NULL;
256
257 ctx = (krb5_gss_ctx_id_t)context;
258 + if (ctx->terminated || !ctx->established) {
259 + *minor_status = KG_CTX_INCOMPLETE;
260 + return GSS_S_NO_CONTEXT;
261 + }
262
263 switch (prf_key) {
264 case GSS_C_PRF_KEY_FULL:
265 diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c
266 index ae33180..a672f48 100644
267 --- a/src/lib/gssapi/krb5/process_context_token.c
268 +++ b/src/lib/gssapi/krb5/process_context_token.c
269 @@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_status, context_handle,
270
271 ctx = (krb5_gss_ctx_id_t) context_handle;
272
273 - if (! ctx->established) {
274 + if (ctx->terminated || !ctx->established) {
275 *minor_status = KG_CTX_INCOMPLETE;
276 return(GSS_S_NO_CONTEXT);
277 }
278
279 + /* We only support context deletion tokens for now, and RFC 4121 does not
280 + * define a context deletion token. */
281 + if (ctx->proto) {
282 + *minor_status = 0;
283 + return(GSS_S_DEFECTIVE_TOKEN);
284 + }
285 +
286 /* "unseal" the token */
287
288 if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle,
289 @@ -52,8 +59,8 @@ krb5_gss_process_context_token(minor_status, context_handle,
290 KG_TOK_DEL_CTX)))
291 return(majerr);
292
293 - /* that's it. delete the context */
294 -
295 - return(krb5_gss_delete_sec_context(minor_status, &context_handle,
296 - GSS_C_NO_BUFFER));
297 + /* Mark the context as terminated, but do not delete it (as that would
298 + * leave the caller with a dangling context handle). */
299 + ctx->terminated = 1;
300 + return(GSS_S_COMPLETE);
301 }
302 diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
303 index 7bc4221..ed5c599 100644
304 --- a/src/lib/gssapi/krb5/wrap_size_limit.c
305 +++ b/src/lib/gssapi/krb5/wrap_size_limit.c
306 @@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
307 }
308
309 ctx = (krb5_gss_ctx_id_rec *) context_handle;
310 - if (! ctx->established) {
311 + if (ctx->terminated || !ctx->established) {
312 *minor_status = KG_CTX_INCOMPLETE;
313 return(GSS_S_NO_CONTEXT);
314 }
315 diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
316 index e56b9c1..2b5145e 100644
317 --- a/src/lib/gssapi/mechglue/mglueP.h
318 +++ b/src/lib/gssapi/mechglue/mglueP.h
319 @@ -25,7 +25,6 @@ do { \
320 */
321 typedef struct gss_union_ctx_id_struct {
322 struct gss_union_ctx_id_struct *loopback;
323 - struct gss_union_ctx_id_struct *interposer;
324 gss_OID mech_type;
325 gss_ctx_id_t internal_ctx_id;
326 } gss_union_ctx_id_desc, *gss_union_ctx_id_t;
327 diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
328 index 42ac783..975f94c 100644
329 --- a/src/lib/kadm5/kadm_rpc_xdr.c
330 +++ b/src/lib/kadm5/kadm_rpc_xdr.c
331 @@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
332 free(tl);
333 tl = tl2;
334 }
335 + *tl_data_head = NULL;
336 break;
337
338 case XDR_ENCODE:
339 @@ -1096,6 +1097,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
340 case XDR_FREE:
341 if(*objp != NULL)
342 krb5_free_principal(context, *objp);
343 + *objp = NULL;
344 break;
345 }
346 return TRUE;
347 diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
348 index 53bdb98..a05ea19 100644
349 --- a/src/lib/rpc/auth_gssapi_misc.c
350 +++ b/src/lib/rpc/auth_gssapi_misc.c
351 @@ -322,7 +322,6 @@ bool_t auth_gssapi_unwrap_data(
352 if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {
353 PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));
354 gss_release_buffer(minor, &out_buf);
355 - xdr_free(xdr_func, xdr_ptr);
356 XDR_DESTROY(&temp_xdrs);
357 return FALSE;
358 }
359 diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
360 index 09a3534..b81c4a3 100644
361 --- a/src/lib/rpc/svc_auth_gss.c
362 +++ b/src/lib/rpc/svc_auth_gss.c
363 @@ -65,16 +65,6 @@ extern const gss_OID_desc * const gss_mech_spkm3;
364
365 extern SVCAUTH svc_auth_none;
366
367 -/*
368 - * from mit-krb5-1.2.1 mechglue/mglueP.h:
369 - * Array of context IDs typed by mechanism OID
370 - */
371 -typedef struct gss_union_ctx_id_t {
372 - gss_OID mech_type;
373 - gss_ctx_id_t internal_ctx_id;
374 -} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
375 -
376 -
377 static auth_gssapi_log_badauth_func log_badauth = NULL;
378 static caddr_t log_badauth_data = NULL;
379 static auth_gssapi_log_badauth2_func log_badauth2 = NULL;
380 @@ -239,16 +229,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
381 gd->ctx = GSS_C_NO_CONTEXT;
382 goto errout;
383 }
384 - /*
385 - * ANDROS: krb5 mechglue returns ctx of size 8 - two pointers,
386 - * one to the mechanism oid, one to the internal_ctx_id
387 - */
388 - if ((gr->gr_ctx.value = mem_alloc(sizeof(gss_union_ctx_id_desc))) == NULL) {
389 - fprintf(stderr, "svcauth_gss_accept_context: out of memory\n");
390 - goto errout;
391 - }
392 - memcpy(gr->gr_ctx.value, gd->ctx, sizeof(gss_union_ctx_id_desc));
393 - gr->gr_ctx.length = sizeof(gss_union_ctx_id_desc);
394 + gr->gr_ctx.value = "xxxx";
395 + gr->gr_ctx.length = 4;
396
397 /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version... */
398 gr->gr_win = sizeof(gd->seqmask) * 8;
399 @@ -520,8 +502,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
400
401 if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
402 gss_release_buffer(&min_stat, &gr.gr_token);
403 - mem_free(gr.gr_ctx.value,
404 - sizeof(gss_union_ctx_id_desc));
405 ret_freegc (AUTH_FAILED);
406 }
407 *no_dispatch = TRUE;
408 @@ -531,7 +511,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
409
410 gss_release_buffer(&min_stat, &gr.gr_token);
411 gss_release_buffer(&min_stat, &gd->checksum);
412 - mem_free(gr.gr_ctx.value, sizeof(gss_union_ctx_id_desc));
413 if (!call_stat)
414 ret_freegc (AUTH_FAILED);
415
416 diff --git a/src/tests/gssapi/t_prf.c b/src/tests/gssapi/t_prf.c
417 index 254f8fb..7f04899 100644
418 --- a/src/tests/gssapi/t_prf.c
419 +++ b/src/tests/gssapi/t_prf.c
420 @@ -127,6 +127,7 @@ main(int argc, char *argv[])
421 uctx.mech_type = &mech_krb5;
422 uctx.internal_ctx_id = (gss_ctx_id_t)&kgctx;
423 kgctx.k5_context = NULL;
424 + kgctx.established = 1;
425 kgctx.have_acceptor_subkey = 1;
426 kb1.contents = k1buf;
427 kb2.contents = k2buf;
428
429
430
431 1.1 app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch
432
433 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch?rev=1.1&view=markup
434 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch?rev=1.1&content-type=text/plain
435
436 Index: mit-krb5-CVE-2014-5353.patch
437 ===================================================================
438 diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
439 index 522773e..6779f51 100644
440 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
441 +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
442 @@ -314,10 +314,11 @@ krb5_ldap_get_password_policy_from_dn(krb5_context context, char *pol_name,
443 LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes);
444
445 ent=ldap_first_entry(ld, result);
446 - if (ent != NULL) {
447 - if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0)
448 - goto cleanup;
449 + if (ent == NULL) {
450 + st = KRB5_KDB_NOENTRY;
451 + goto cleanup;
452 }
453 + st = populate_policy(context, ld, ent, pol_name, *policy);
454
455 cleanup:
456 ldap_msgfree(result);