Mercurial > hg > xemacs-beta
comparison src/eldap.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | 7347b34c275b |
children | bbff43aa5eb7 |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
24 | 24 |
25 /* This file provides lisp primitives for access to an LDAP library | 25 /* This file provides lisp primitives for access to an LDAP library |
26 conforming to the API defined in RFC 1823. | 26 conforming to the API defined in RFC 1823. |
27 It has been tested with: | 27 It has been tested with: |
28 - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) | 28 - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) |
29 - OpenLDAP 1.2 (http://www.openldap.org/) | 29 - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */ |
30 - Netscape's LDAP SDK (http://developer.netscape.com/) */ | |
31 | 30 |
32 | 31 |
33 #include <config.h> | 32 #include <config.h> |
34 #include "lisp.h" | 33 #include "lisp.h" |
35 #include "opaque.h" | 34 #include "opaque.h" |
36 #include "sysdep.h" | 35 #include "sysdep.h" |
37 #include "buffer.h" | |
38 | 36 |
39 #include <errno.h> | 37 #include <errno.h> |
40 | 38 |
41 #include "eldap.h" | 39 #include "eldap.h" |
40 | |
41 #ifdef HAVE_NS_LDAP | |
42 # define HAVE_LDAP_SET_OPTION 1 | |
43 # define HAVE_LDAP_GET_ERRNO 1 | |
44 #else | |
45 # undef HAVE_LDAP_SET_OPTION | |
46 # undef HAVE_LDAP_GET_ERRNO | |
47 #endif | |
42 | 48 |
43 static int ldap_default_port; | 49 static int ldap_default_port; |
44 static Lisp_Object Vldap_default_base; | 50 static Lisp_Object Vldap_default_base; |
45 | 51 |
46 /* Needed by the lrecord definition */ | 52 /* Needed by the lrecord definition */ |
59 /************************************************************************/ | 65 /************************************************************************/ |
60 /* Utility Functions */ | 66 /* Utility Functions */ |
61 /************************************************************************/ | 67 /************************************************************************/ |
62 | 68 |
63 static void | 69 static void |
64 signal_ldap_error (LDAP *ld, LDAPMessage *res, int ldap_err) | 70 signal_ldap_error (LDAP *ld) |
65 { | 71 { |
66 if (ldap_err <= 0) | 72 #ifdef HAVE_LDAP_GET_ERRNO |
67 { | 73 signal_simple_error |
68 #if defined HAVE_LDAP_PARSE_RESULT | 74 ("LDAP error", |
69 int err; | 75 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL)))); |
70 ldap_err = ldap_parse_result (ld, res, | |
71 &err, | |
72 NULL, NULL, NULL, NULL, 0); | |
73 if (ldap_err == LDAP_SUCCESS) | |
74 ldap_err = err; | |
75 #elif defined HAVE_LDAP_GET_LDERRNO | |
76 ldap_err = ldap_get_lderrno (ld, NULL, NULL); | |
77 #elif defined HAVE_LDAP_RESULT2ERROR | |
78 ldap_err = ldap_result2error (ld, res, 0); | |
79 #else | 76 #else |
80 ldap_err = ld->ld_errno; | 77 signal_simple_error ("LDAP error", |
78 build_string (ldap_err2string (ld->ld_errno))); | |
81 #endif | 79 #endif |
82 } | |
83 signal_simple_error ("LDAP error", | |
84 build_string (ldap_err2string (ldap_err))); | |
85 } | 80 } |
86 | 81 |
87 | 82 |
88 /************************************************************************/ | 83 /************************************************************************/ |
89 /* ldap lrecord basic functions */ | 84 /* ldap lrecord basic functions */ |
114 error ("printing unreadable object #<ldap %s>", | 109 error ("printing unreadable object #<ldap %s>", |
115 XSTRING_DATA (ldap->host)); | 110 XSTRING_DATA (ldap->host)); |
116 | 111 |
117 write_c_string ("#<ldap ", printcharfun); | 112 write_c_string ("#<ldap ", printcharfun); |
118 print_internal (ldap->host, printcharfun, 1); | 113 print_internal (ldap->host, printcharfun, 1); |
119 if (!ldap->ld) | 114 if (!ldap->livep) |
120 write_c_string ("(dead) ",printcharfun); | 115 write_c_string ("(dead) ",printcharfun); |
121 sprintf (buf, " 0x%x>", (unsigned int)ldap); | 116 sprintf (buf, " 0x%x>", (unsigned int)ldap); |
122 write_c_string (buf, printcharfun); | 117 write_c_string (buf, printcharfun); |
123 } | 118 } |
124 | 119 |
128 struct Lisp_LDAP *ldap = | 123 struct Lisp_LDAP *ldap = |
129 alloc_lcrecord_type (struct Lisp_LDAP, lrecord_ldap); | 124 alloc_lcrecord_type (struct Lisp_LDAP, lrecord_ldap); |
130 | 125 |
131 ldap->ld = NULL; | 126 ldap->ld = NULL; |
132 ldap->host = Qnil; | 127 ldap->host = Qnil; |
128 ldap->livep = 0; | |
133 return ldap; | 129 return ldap; |
134 } | 130 } |
135 | 131 |
136 static void | 132 static void |
137 finalize_ldap (void *header, int for_disksave) | 133 finalize_ldap (void *header, int for_disksave) |
140 | 136 |
141 if (for_disksave) | 137 if (for_disksave) |
142 signal_simple_error ("Can't dump an emacs containing LDAP objects", | 138 signal_simple_error ("Can't dump an emacs containing LDAP objects", |
143 make_ldap (ldap)); | 139 make_ldap (ldap)); |
144 | 140 |
145 if (ldap->ld) | 141 if (ldap->livep) |
146 ldap_unbind (ldap->ld); | 142 ldap_unbind (ldap->ld); |
147 ldap->ld = NULL; | |
148 } | 143 } |
149 | 144 |
150 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, | 145 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, |
151 mark_ldap, print_ldap, finalize_ldap, | 146 mark_ldap, print_ldap, finalize_ldap, |
152 NULL, NULL, struct Lisp_LDAP); | 147 NULL, NULL, struct Lisp_LDAP); |
179 Return t if LDAP is an active LDAP connection. | 174 Return t if LDAP is an active LDAP connection. |
180 */ | 175 */ |
181 (ldap)) | 176 (ldap)) |
182 { | 177 { |
183 CHECK_LDAP (ldap); | 178 CHECK_LDAP (ldap); |
184 return (XLDAP (ldap))->ld ? Qt : Qnil; | 179 return (XLDAP (ldap))->livep ? Qt : Qnil; |
185 } | 180 } |
186 | 181 |
187 /************************************************************************/ | 182 /************************************************************************/ |
188 /* Opening/Closing a LDAP connection */ | 183 /* Opening/Closing a LDAP connection */ |
189 /************************************************************************/ | 184 /************************************************************************/ |
247 } | 242 } |
248 /* Bind DN */ | 243 /* Bind DN */ |
249 else if (EQ (keyword, Qbinddn)) | 244 else if (EQ (keyword, Qbinddn)) |
250 { | 245 { |
251 CHECK_STRING (value); | 246 CHECK_STRING (value); |
252 GET_C_STRING_OS_DATA_ALLOCA (value, ldap_binddn); | 247 ldap_binddn = alloca (XSTRING_LENGTH (value) + 1); |
248 strcpy (ldap_binddn, (char *)XSTRING_DATA (value)); | |
253 } | 249 } |
254 /* Password */ | 250 /* Password */ |
255 else if (EQ (keyword, Qpasswd)) | 251 else if (EQ (keyword, Qpasswd)) |
256 { | 252 { |
257 CHECK_STRING (value); | 253 CHECK_STRING (value); |
258 GET_C_STRING_OS_DATA_ALLOCA (value, ldap_passwd); | 254 ldap_passwd = alloca (XSTRING_LENGTH (value) + 1); |
255 strcpy (ldap_passwd, (char *)XSTRING_DATA (value)); | |
259 } | 256 } |
260 /* Deref */ | 257 /* Deref */ |
261 else if (EQ (keyword, Qderef)) | 258 else if (EQ (keyword, Qderef)) |
262 { | 259 { |
263 if (EQ (value, Qnever)) | 260 if (EQ (value, Qnever)) |
289 { | 286 { |
290 ldap_port = ldap_default_port; | 287 ldap_port = ldap_default_port; |
291 } | 288 } |
292 | 289 |
293 /* Connect to the server and bind */ | 290 /* Connect to the server and bind */ |
294 slow_down_interrupts (); | |
295 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); | 291 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); |
296 speed_up_interrupts (); | |
297 | |
298 if (ld == NULL ) | 292 if (ld == NULL ) |
299 signal_simple_error_2 ("Failed connecting to host", | 293 signal_simple_error_2 ("Failed connecting to host", |
300 host, | 294 host, |
301 lisp_strerror (errno)); | 295 lisp_strerror (errno)); |
302 | 296 |
303 | 297 |
304 #ifdef HAVE_LDAP_SET_OPTION | 298 #ifdef HAVE_LDAP_SET_OPTION |
305 if ((err = ldap_set_option (ld, LDAP_OPT_DEREF, | 299 if (ldap_set_option (ld, LDAP_OPT_DEREF, (void *)&ldap_deref) != LDAP_SUCCESS) |
306 (void *)&ldap_deref)) != LDAP_SUCCESS) | 300 signal_ldap_error (ld); |
307 signal_ldap_error (ld, NULL, err); | 301 if (ldap_set_option (ld, LDAP_OPT_TIMELIMIT, |
308 if ((err = ldap_set_option (ld, LDAP_OPT_TIMELIMIT, | 302 (void *)&ldap_timelimit) != LDAP_SUCCESS) |
309 (void *)&ldap_timelimit)) != LDAP_SUCCESS) | 303 signal_ldap_error (ld); |
310 signal_ldap_error (ld, NULL, err); | 304 if (ldap_set_option (ld, LDAP_OPT_SIZELIMIT, |
311 if ((err = ldap_set_option (ld, LDAP_OPT_SIZELIMIT, | 305 (void *)&ldap_sizelimit) != LDAP_SUCCESS) |
312 (void *)&ldap_sizelimit)) != LDAP_SUCCESS) | 306 signal_ldap_error (ld); |
313 signal_ldap_error (ld, NULL, err); | 307 if (ldap_set_option (ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS) |
314 if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, | 308 signal_ldap_error (ld); |
315 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
316 signal_ldap_error (ld, NULL, err); | |
317 if ((err = ldap_set_option (ld, LDAP_OPT_RESTART, | |
318 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
319 signal_ldap_error (ld, NULL, err); | |
320 #else /* not HAVE_LDAP_SET_OPTION */ | 309 #else /* not HAVE_LDAP_SET_OPTION */ |
321 ld->ld_deref = ldap_deref; | 310 ld->ld_deref = ldap_deref; |
322 ld->ld_timelimit = ldap_timelimit; | 311 ld->ld_timelimit = ldap_timelimit; |
323 ld->ld_sizelimit = ldap_sizelimit; | 312 ld->ld_sizelimit = ldap_sizelimit; |
324 #ifdef LDAP_REFERRALS | 313 #ifdef LDAP_REFERRALS |
325 ld->ld_options = LDAP_OPT_REFERRALS; | 314 ld->ld_options = LDAP_OPT_REFERRALS; |
326 #else /* not LDAP_REFERRALS */ | 315 #else /* not LDAP_REFERRALS */ |
327 ld->ld_options = 0; | 316 ld->ld_options = 0; |
328 #endif /* not LDAP_REFERRALS */ | 317 #endif /* not LDAP_REFERRALS */ |
329 /* XEmacs uses interrupts (SIGIO,SIGALRM), LDAP calls need to ignore them */ | |
330 ld->ld_options |= LDAP_OPT_RESTART; | |
331 #endif /* not HAVE_LDAP_SET_OPTION */ | 318 #endif /* not HAVE_LDAP_SET_OPTION */ |
332 | 319 |
320 /* ldap_bind_s calls select and may be wedged by SIGIO. */ | |
321 slow_down_interrupts (); | |
333 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); | 322 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); |
323 speed_up_interrupts (); | |
334 if (err != LDAP_SUCCESS) | 324 if (err != LDAP_SUCCESS) |
335 signal_simple_error ("Failed binding to the server", | 325 signal_simple_error ("Failed binding to the server", |
336 build_string (ldap_err2string (err))); | 326 build_string (ldap_err2string (err))); |
337 | 327 |
338 ldap = allocate_ldap (); | 328 ldap = allocate_ldap (); |
339 ldap->ld = ld; | 329 ldap->ld = ld; |
340 ldap->host = host; | 330 ldap->host = host; |
331 ldap->livep = 1; | |
341 | 332 |
342 return make_ldap (ldap); | 333 return make_ldap (ldap); |
343 } | 334 } |
344 | 335 |
345 | 336 |
351 { | 342 { |
352 struct Lisp_LDAP *lldap; | 343 struct Lisp_LDAP *lldap; |
353 CHECK_LIVE_LDAP (ldap); | 344 CHECK_LIVE_LDAP (ldap); |
354 lldap = XLDAP (ldap); | 345 lldap = XLDAP (ldap); |
355 ldap_unbind (lldap->ld); | 346 ldap_unbind (lldap->ld); |
356 lldap->ld = NULL; | 347 lldap->livep = 0; |
357 return Qnil; | 348 return Qnil; |
358 } | 349 } |
359 | 350 |
360 | 351 |
361 | 352 |
363 /* Working on a LDAP connection */ | 354 /* Working on a LDAP connection */ |
364 /************************************************************************/ | 355 /************************************************************************/ |
365 struct ldap_unwind_struct | 356 struct ldap_unwind_struct |
366 { | 357 { |
367 LDAPMessage *res; | 358 LDAPMessage *res; |
368 struct berval **vals; | 359 char **vals; |
369 }; | 360 }; |
361 | |
370 | 362 |
371 static Lisp_Object | 363 static Lisp_Object |
372 ldap_search_unwind (Lisp_Object unwind_obj) | 364 ldap_search_unwind (Lisp_Object unwind_obj) |
373 { | 365 { |
374 struct ldap_unwind_struct *unwind = | 366 struct ldap_unwind_struct *unwind = |
375 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); | 367 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); |
376 if (unwind->res) | 368 if (unwind->res) |
377 ldap_msgfree (unwind->res); | 369 ldap_msgfree (unwind->res); |
378 if (unwind->vals) | 370 if (unwind->vals) |
379 ldap_value_free_len (unwind->vals); | 371 ldap_value_free (unwind->vals); |
380 return Qnil; | 372 return Qnil; |
381 } | 373 } |
382 | 374 |
383 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* | 375 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* |
384 Perform a search on an open LDAP connection. | 376 Perform a search on an open LDAP connection. |
401 /* Vars for query */ | 393 /* Vars for query */ |
402 LDAP *ld; | 394 LDAP *ld; |
403 LDAPMessage *e; | 395 LDAPMessage *e; |
404 BerElement *ptr; | 396 BerElement *ptr; |
405 char *a; | 397 char *a; |
406 int i, rc, rc2; | 398 int i, rc; |
407 int matches; | 399 int matches; |
408 struct ldap_unwind_struct unwind; | 400 struct ldap_unwind_struct unwind; |
409 | 401 |
410 int ldap_scope = LDAP_SCOPE_SUBTREE; | 402 int ldap_scope = LDAP_SCOPE_SUBTREE; |
411 char **ldap_attributes = NULL; | 403 char **ldap_attributes = NULL; |
460 i = 0; | 452 i = 0; |
461 EXTERNAL_LIST_LOOP (attrs, attrs) | 453 EXTERNAL_LIST_LOOP (attrs, attrs) |
462 { | 454 { |
463 Lisp_Object current = XCAR (attrs); | 455 Lisp_Object current = XCAR (attrs); |
464 CHECK_STRING (current); | 456 CHECK_STRING (current); |
465 GET_C_STRING_OS_DATA_ALLOCA (current, ldap_attributes[i]); | 457 ldap_attributes[i] = |
458 alloca_array (char, 1 + XSTRING_LENGTH (current)); | |
459 /* XSTRING_LENGTH is increased by one in order to copy the final 0 */ | |
460 memcpy (ldap_attributes[i], | |
461 XSTRING_DATA (current), 1 + XSTRING_LENGTH (current)); | |
466 ++i; | 462 ++i; |
467 } | 463 } |
468 ldap_attributes[i] = NULL; | 464 ldap_attributes[i] = NULL; |
469 } | 465 } |
470 | 466 |
476 NILP (base) ? "" : (char *) XSTRING_DATA (base), | 472 NILP (base) ? "" : (char *) XSTRING_DATA (base), |
477 ldap_scope, | 473 ldap_scope, |
478 NILP (filter) ? "" : (char *) XSTRING_DATA (filter), | 474 NILP (filter) ? "" : (char *) XSTRING_DATA (filter), |
479 ldap_attributes, | 475 ldap_attributes, |
480 NILP (attrsonly) ? 0 : 1) | 476 NILP (attrsonly) ? 0 : 1) |
481 == -1) | 477 == -1) |
482 { | 478 { |
483 signal_ldap_error (ld, NULL, 0); | 479 signal_ldap_error (ld); |
484 } | 480 } |
485 | 481 |
486 /* Ensure we don't exit without cleaning up */ | 482 /* Ensure we don't exit without cleaning up */ |
487 record_unwind_protect (ldap_search_unwind, | 483 record_unwind_protect (ldap_search_unwind, |
488 make_opaque_ptr (&unwind)); | 484 make_opaque_ptr (&unwind)); |
489 | 485 |
490 /* Build the results list */ | 486 /* Build the results list */ |
491 matches = 0; | 487 matches = 0; |
492 | 488 |
489 /* ldap_result calls select() and can get wedged by EINTR signals */ | |
490 slow_down_interrupts (); | |
493 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); | 491 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); |
494 | 492 speed_up_interrupts (); |
495 while (rc == LDAP_RES_SEARCH_ENTRY) | 493 while (rc == LDAP_RES_SEARCH_ENTRY) |
496 { | 494 { |
497 QUIT; | 495 QUIT; |
498 matches ++; | 496 matches ++; |
499 e = ldap_first_entry (ld, unwind.res); | 497 e = ldap_first_entry (ld, unwind.res); |
503 restore the old echo area contents later. */ | 501 restore the old echo area contents later. */ |
504 message ("Parsing ldap results... %d", matches); | 502 message ("Parsing ldap results... %d", matches); |
505 entry = Qnil; | 503 entry = Qnil; |
506 for (a= ldap_first_attribute (ld, e, &ptr); | 504 for (a= ldap_first_attribute (ld, e, &ptr); |
507 a != NULL; | 505 a != NULL; |
508 a = ldap_next_attribute (ld, e, ptr) ) | 506 a= ldap_next_attribute (ld, e, ptr) ) |
509 { | 507 { |
510 list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); | 508 list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); |
511 unwind.vals = ldap_get_values_len (ld, e, a); | 509 unwind.vals = ldap_get_values (ld, e, a); |
512 if (unwind.vals != NULL) | 510 if (unwind.vals != NULL) |
513 { | 511 { |
514 for (i = 0; unwind.vals[i] != NULL; i++) | 512 for (i = 0; unwind.vals[i] != NULL; i++) |
515 { | 513 { |
516 list = Fcons (make_ext_string (unwind.vals[i]->bv_val, | 514 list = Fcons (build_ext_string (unwind.vals[i], FORMAT_OS), |
517 unwind.vals[i]->bv_len, | |
518 FORMAT_OS), | |
519 list); | 515 list); |
520 } | 516 } |
521 } | 517 } |
522 entry = Fcons (Fnreverse (list), | 518 entry = Fcons (Fnreverse (list), |
523 entry); | 519 entry); |
524 ldap_value_free_len (unwind.vals); | 520 ldap_value_free (unwind.vals); |
525 unwind.vals = NULL; | 521 unwind.vals = NULL; |
526 } | 522 } |
527 result = Fcons (Fnreverse (entry), | 523 result = Fcons (Fnreverse (entry), |
528 result); | 524 result); |
529 ldap_msgfree (unwind.res); | 525 ldap_msgfree (unwind.res); |
530 unwind.res = NULL; | 526 unwind.res = NULL; |
531 | 527 |
528 slow_down_interrupts (); | |
532 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); | 529 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); |
533 } | 530 speed_up_interrupts (); |
534 | 531 } |
535 #if defined HAVE_LDAP_PARSE_RESULT | |
536 rc2 = ldap_parse_result (ld, unwind.res, | |
537 &rc, | |
538 NULL, NULL, NULL, NULL, 0); | |
539 if (rc2 != LDAP_SUCCESS) | |
540 rc = rc2; | |
541 #else | |
542 if (rc == 0) | |
543 signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); | |
544 | 532 |
545 if (rc == -1) | 533 if (rc == -1) |
546 signal_ldap_error (ld, unwind.res, (unwind.res==NULL) ? ld->ld_errno : 0); | 534 { |
547 | 535 signal_ldap_error (ld); |
548 #if defined HAVE_LDAP_RESULT2ERROR | 536 } |
549 rc = ldap_result2error (ld, unwind.res, 0); | 537 rc = ldap_result2error (ld, unwind.res, 0); |
550 #endif | 538 if ((rc != LDAP_SUCCESS) && |
551 #endif | 539 (rc != LDAP_SIZELIMIT_EXCEEDED)) |
552 | 540 { |
553 if (rc != LDAP_SUCCESS) | 541 signal_ldap_error (ld); |
554 signal_ldap_error (ld, NULL, rc); | 542 } |
555 | 543 |
556 ldap_msgfree (unwind.res); | 544 ldap_msgfree (unwind.res); |
557 unwind.res = (LDAPMessage *)NULL; | 545 unwind.res = (LDAPMessage *)NULL; |
558 | |
559 /* #### See above for calling message(). */ | 546 /* #### See above for calling message(). */ |
560 message ("Parsing ldap results... done"); | 547 message ("Parsing ldap results... done"); |
561 | 548 |
562 unbind_to (speccount, Qnil); | 549 unbind_to (speccount, Qnil); |
563 UNGCPRO; | 550 UNGCPRO; |
578 } | 565 } |
579 | 566 |
580 void | 567 void |
581 vars_of_eldap (void) | 568 vars_of_eldap (void) |
582 { | 569 { |
570 Fprovide (intern ("ldap")); | |
583 | 571 |
584 ldap_default_port = LDAP_PORT; | 572 ldap_default_port = LDAP_PORT; |
585 Vldap_default_base = Qnil; | 573 Vldap_default_base = Qnil; |
586 | 574 |
587 DEFVAR_INT ("ldap-default-port", &ldap_default_port /* | 575 DEFVAR_INT ("ldap-default-port", &ldap_default_port /* |