Mercurial > hg > xemacs-beta
comparison src/eldap.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* LDAP client interface for XEmacs. | |
2 Copyright (C) 1998 Free Software Foundation, Inc. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. */ | |
20 | |
21 /* Synched up with: Not in FSF. */ | |
22 | |
23 /* Author: Oscar Figueiredo with lots of support from Hrvoje Niksic */ | |
24 | |
25 /* This file provides lisp primitives for access to an LDAP library | |
26 conforming to the API defined in RFC 1823. | |
27 It has been tested with: | |
28 - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) | |
29 - OpenLDAP 1.2 (http://www.openldap.org/) | |
30 - Netscape's LDAP SDK (http://developer.netscape.com/) */ | |
31 | |
32 | |
33 #include <config.h> | |
34 #include "lisp.h" | |
35 #include "opaque.h" | |
36 #include "sysdep.h" | |
37 #include "buffer.h" | |
38 | |
39 #include <errno.h> | |
40 | |
41 #include "eldap.h" | |
42 | |
43 static int ldap_default_port; | |
44 static Lisp_Object Vldap_default_base; | |
45 | |
46 /* Needed by the lrecord definition */ | |
47 Lisp_Object Qldapp; | |
48 | |
49 /* ldap-open plist keywords */ | |
50 static Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit, Qsizelimit; | |
51 /* Search scope limits */ | |
52 static Lisp_Object Qbase, Qonelevel, Qsubtree; | |
53 /* Authentication methods */ | |
54 static Lisp_Object Qkrbv41, Qkrbv42; | |
55 /* Deref policy */ | |
56 static Lisp_Object Qnever, Qalways, Qfind; | |
57 | |
58 /************************************************************************/ | |
59 /* Utility Functions */ | |
60 /************************************************************************/ | |
61 | |
62 static void | |
63 signal_ldap_error (LDAP *ld, LDAPMessage *res, int ldap_err) | |
64 { | |
65 if (ldap_err <= 0) | |
66 { | |
67 #if defined HAVE_LDAP_PARSE_RESULT | |
68 int err; | |
69 ldap_err = ldap_parse_result (ld, res, | |
70 &err, | |
71 NULL, NULL, NULL, NULL, 0); | |
72 if (ldap_err == LDAP_SUCCESS) | |
73 ldap_err = err; | |
74 #elif defined HAVE_LDAP_GET_LDERRNO | |
75 ldap_err = ldap_get_lderrno (ld, NULL, NULL); | |
76 #elif defined HAVE_LDAP_RESULT2ERROR | |
77 ldap_err = ldap_result2error (ld, res, 0); | |
78 #else | |
79 ldap_err = ld->ld_errno; | |
80 #endif | |
81 } | |
82 signal_simple_error ("LDAP error", | |
83 build_string (ldap_err2string (ldap_err))); | |
84 } | |
85 | |
86 | |
87 /************************************************************************/ | |
88 /* ldap lrecord basic functions */ | |
89 /************************************************************************/ | |
90 | |
91 static Lisp_Object | |
92 make_ldap (struct Lisp_LDAP *ldap) | |
93 { | |
94 Lisp_Object lisp_ldap; | |
95 XSETLDAP (lisp_ldap, ldap); | |
96 return lisp_ldap; | |
97 } | |
98 | |
99 static Lisp_Object | |
100 mark_ldap (Lisp_Object obj) | |
101 { | |
102 return XLDAP (obj)->host; | |
103 } | |
104 | |
105 static void | |
106 print_ldap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
107 { | |
108 char buf[32]; | |
109 | |
110 struct Lisp_LDAP *ldap = XLDAP (obj); | |
111 | |
112 if (print_readably) | |
113 error ("printing unreadable object #<ldap %s>", | |
114 XSTRING_DATA (ldap->host)); | |
115 | |
116 write_c_string ("#<ldap ", printcharfun); | |
117 print_internal (ldap->host, printcharfun, 1); | |
118 if (!ldap->ld) | |
119 write_c_string ("(dead) ",printcharfun); | |
120 sprintf (buf, " 0x%x>", (unsigned int)ldap); | |
121 write_c_string (buf, printcharfun); | |
122 } | |
123 | |
124 static struct Lisp_LDAP * | |
125 allocate_ldap (void) | |
126 { | |
127 struct Lisp_LDAP *ldap = | |
128 alloc_lcrecord_type (struct Lisp_LDAP, &lrecord_ldap); | |
129 | |
130 ldap->ld = NULL; | |
131 ldap->host = Qnil; | |
132 return ldap; | |
133 } | |
134 | |
135 static void | |
136 finalize_ldap (void *header, int for_disksave) | |
137 { | |
138 struct Lisp_LDAP *ldap = (struct Lisp_LDAP *) header; | |
139 | |
140 if (for_disksave) | |
141 signal_simple_error ("Can't dump an emacs containing LDAP objects", | |
142 make_ldap (ldap)); | |
143 | |
144 if (ldap->ld) | |
145 ldap_unbind (ldap->ld); | |
146 ldap->ld = NULL; | |
147 } | |
148 | |
149 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, | |
150 mark_ldap, print_ldap, finalize_ldap, | |
151 NULL, NULL, 0, struct Lisp_LDAP); | |
152 | |
153 | |
154 | |
155 | |
156 /************************************************************************/ | |
157 /* Basic ldap accessors */ | |
158 /************************************************************************/ | |
159 | |
160 DEFUN ("ldapp", Fldapp, 1, 1, 0, /* | |
161 Return t if OBJECT is a LDAP connection. | |
162 */ | |
163 (object)) | |
164 { | |
165 return LDAPP (object) ? Qt : Qnil; | |
166 } | |
167 | |
168 DEFUN ("ldap-host", Fldap_host, 1, 1, 0, /* | |
169 Return the server host of the connection LDAP, as a string. | |
170 */ | |
171 (ldap)) | |
172 { | |
173 CHECK_LDAP (ldap); | |
174 return (XLDAP (ldap))->host; | |
175 } | |
176 | |
177 DEFUN ("ldap-live-p", Fldap_status, 1, 1, 0, /* | |
178 Return t if LDAP is an active LDAP connection. | |
179 */ | |
180 (ldap)) | |
181 { | |
182 CHECK_LDAP (ldap); | |
183 return (XLDAP (ldap))->ld ? Qt : Qnil; | |
184 } | |
185 | |
186 /************************************************************************/ | |
187 /* Opening/Closing a LDAP connection */ | |
188 /************************************************************************/ | |
189 | |
190 | |
191 DEFUN ("ldap-open", Fldap_open, 1, 2, 0, /* | |
192 Open a LDAP connection to HOST. | |
193 PLIST is a plist containing additional parameters for the connection. | |
194 Valid keys in that list are: | |
195 `port' the TCP port to use for the connection if different from | |
196 `ldap-default-port'. | |
197 `auth' is the authentication method to use, possible values depend on | |
198 the LDAP library XEmacs was compiled with: `simple', `krbv41' and `krbv42'. | |
199 `binddn' is the distinguished name of the user to bind as (in RFC 1779 syntax). | |
200 `passwd' is the password to use for simple authentication. | |
201 `deref' is one of the symbols `never', `always', `search' or `find'. | |
202 `timelimit' is the timeout limit for the connection in seconds. | |
203 `sizelimit' is the maximum number of matches to return. | |
204 */ | |
205 (host, plist)) | |
206 { | |
207 /* This function can GC */ | |
208 struct Lisp_LDAP *ldap; | |
209 LDAP *ld; | |
210 int ldap_port = 0; | |
211 int ldap_auth = LDAP_AUTH_SIMPLE; | |
212 char *ldap_binddn = NULL; | |
213 char *ldap_passwd = NULL; | |
214 int ldap_deref = LDAP_DEREF_NEVER; | |
215 int ldap_timelimit = 0; | |
216 int ldap_sizelimit = 0; | |
217 int err; | |
218 | |
219 Lisp_Object list, keyword, value; | |
220 | |
221 CHECK_STRING (host); | |
222 | |
223 EXTERNAL_PROPERTY_LIST_LOOP (list, keyword, value, plist) | |
224 { | |
225 /* TCP Port */ | |
226 if (EQ (keyword, Qport)) | |
227 { | |
228 CHECK_INT (value); | |
229 ldap_port = XINT (value); | |
230 } | |
231 /* Authentication method */ | |
232 if (EQ (keyword, Qauth)) | |
233 { | |
234 if (EQ (value, Qsimple)) | |
235 ldap_auth = LDAP_AUTH_SIMPLE; | |
236 #ifdef LDAP_AUTH_KRBV41 | |
237 else if (EQ (value, Qkrbv41)) | |
238 ldap_auth = LDAP_AUTH_KRBV41; | |
239 #endif | |
240 #ifdef LDAP_AUTH_KRBV42 | |
241 else if (EQ (value, Qkrbv42)) | |
242 ldap_auth = LDAP_AUTH_KRBV42; | |
243 #endif | |
244 else | |
245 signal_simple_error ("Invalid authentication method", value); | |
246 } | |
247 /* Bind DN */ | |
248 else if (EQ (keyword, Qbinddn)) | |
249 { | |
250 CHECK_STRING (value); | |
251 GET_C_STRING_OS_DATA_ALLOCA (value, ldap_binddn); | |
252 } | |
253 /* Password */ | |
254 else if (EQ (keyword, Qpasswd)) | |
255 { | |
256 CHECK_STRING (value); | |
257 GET_C_STRING_OS_DATA_ALLOCA (value, ldap_passwd); | |
258 } | |
259 /* Deref */ | |
260 else if (EQ (keyword, Qderef)) | |
261 { | |
262 if (EQ (value, Qnever)) | |
263 ldap_deref = LDAP_DEREF_NEVER; | |
264 else if (EQ (value, Qsearch)) | |
265 ldap_deref = LDAP_DEREF_SEARCHING; | |
266 else if (EQ (value, Qfind)) | |
267 ldap_deref = LDAP_DEREF_FINDING; | |
268 else if (EQ (value, Qalways)) | |
269 ldap_deref = LDAP_DEREF_ALWAYS; | |
270 else | |
271 signal_simple_error ("Invalid deref value", value); | |
272 } | |
273 /* Timelimit */ | |
274 else if (EQ (keyword, Qtimelimit)) | |
275 { | |
276 CHECK_INT (value); | |
277 ldap_timelimit = XINT (value); | |
278 } | |
279 /* Sizelimit */ | |
280 else if (EQ (keyword, Qsizelimit)) | |
281 { | |
282 CHECK_INT (value); | |
283 ldap_sizelimit = XINT (value); | |
284 } | |
285 } | |
286 | |
287 if (ldap_port == 0) | |
288 { | |
289 ldap_port = ldap_default_port; | |
290 } | |
291 | |
292 /* Connect to the server and bind */ | |
293 slow_down_interrupts (); | |
294 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); | |
295 speed_up_interrupts (); | |
296 | |
297 if (ld == NULL ) | |
298 signal_simple_error_2 ("Failed connecting to host", | |
299 host, | |
300 lisp_strerror (errno)); | |
301 | |
302 | |
303 #ifdef HAVE_LDAP_SET_OPTION | |
304 if ((err = ldap_set_option (ld, LDAP_OPT_DEREF, | |
305 (void *)&ldap_deref)) != LDAP_SUCCESS) | |
306 signal_ldap_error (ld, NULL, err); | |
307 if ((err = ldap_set_option (ld, LDAP_OPT_TIMELIMIT, | |
308 (void *)&ldap_timelimit)) != LDAP_SUCCESS) | |
309 signal_ldap_error (ld, NULL, err); | |
310 if ((err = ldap_set_option (ld, LDAP_OPT_SIZELIMIT, | |
311 (void *)&ldap_sizelimit)) != LDAP_SUCCESS) | |
312 signal_ldap_error (ld, NULL, err); | |
313 if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, | |
314 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
315 signal_ldap_error (ld, NULL, err); | |
316 #else /* not HAVE_LDAP_SET_OPTION */ | |
317 ld->ld_deref = ldap_deref; | |
318 ld->ld_timelimit = ldap_timelimit; | |
319 ld->ld_sizelimit = ldap_sizelimit; | |
320 #ifdef LDAP_REFERRALS | |
321 ld->ld_options = LDAP_OPT_REFERRALS; | |
322 #else /* not LDAP_REFERRALS */ | |
323 ld->ld_options = 0; | |
324 #endif /* not LDAP_REFERRALS */ | |
325 #endif /* not HAVE_LDAP_SET_OPTION */ | |
326 | |
327 /* ldap_bind_s calls select and may be wedged by SIGIO. */ | |
328 slow_down_interrupts (); | |
329 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); | |
330 speed_up_interrupts (); | |
331 if (err != LDAP_SUCCESS) | |
332 signal_simple_error ("Failed binding to the server", | |
333 build_string (ldap_err2string (err))); | |
334 | |
335 ldap = allocate_ldap (); | |
336 ldap->ld = ld; | |
337 ldap->host = host; | |
338 | |
339 return make_ldap (ldap); | |
340 } | |
341 | |
342 | |
343 | |
344 DEFUN ("ldap-close", Fldap_close, 1, 1, 0, /* | |
345 Close an LDAP connection. | |
346 */ | |
347 (ldap)) | |
348 { | |
349 struct Lisp_LDAP *lldap; | |
350 CHECK_LIVE_LDAP (ldap); | |
351 lldap = XLDAP (ldap); | |
352 ldap_unbind (lldap->ld); | |
353 lldap->ld = NULL; | |
354 return Qnil; | |
355 } | |
356 | |
357 | |
358 | |
359 /************************************************************************/ | |
360 /* Working on a LDAP connection */ | |
361 /************************************************************************/ | |
362 struct ldap_unwind_struct | |
363 { | |
364 LDAPMessage *res; | |
365 struct berval **vals; | |
366 }; | |
367 | |
368 | |
369 static Lisp_Object | |
370 ldap_search_unwind (Lisp_Object unwind_obj) | |
371 { | |
372 struct ldap_unwind_struct *unwind = | |
373 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); | |
374 if (unwind->res) | |
375 ldap_msgfree (unwind->res); | |
376 if (unwind->vals) | |
377 ldap_value_free_len (unwind->vals); | |
378 return Qnil; | |
379 } | |
380 | |
381 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 7, 0, /* | |
382 Perform a search on an open LDAP connection. | |
383 LDAP is an LDAP connection object created with `ldap-open'. | |
384 FILTER is a filter string for the search as described in RFC 1558. | |
385 BASE is the distinguished name at which to start the search. | |
386 SCOPE is one of the symbols `base', `onelevel' or `subtree' indicating | |
387 the scope of the search. | |
388 ATTRS is a list of strings indicating which attributes to retrieve | |
389 for each matching entry. If nil return all available attributes. | |
390 If ATTRSONLY is non-nil then only the attributes are retrieved, not | |
391 the associated values. | |
392 If WITHDN is non-nil each entry in the result will be prepennded with | |
393 its distinguished name DN. | |
394 The function returns a list of matching entries. Each entry is itself | |
395 an alist of attribute/value pairs optionally preceded by the DN of the | |
396 entry according to the value of WITHDN. | |
397 */ | |
398 (ldap, filter, base, scope, attrs, attrsonly, withdn)) | |
399 { | |
400 /* This function can GC */ | |
401 | |
402 /* Vars for query */ | |
403 LDAP *ld; | |
404 LDAPMessage *e; | |
405 BerElement *ptr; | |
406 char *a, *dn; | |
407 int i, rc, rc2; | |
408 int matches; | |
409 struct ldap_unwind_struct unwind; | |
410 | |
411 int ldap_scope = LDAP_SCOPE_SUBTREE; | |
412 char **ldap_attributes = NULL; | |
413 | |
414 int speccount = specpdl_depth (); | |
415 | |
416 Lisp_Object list, entry, result; | |
417 struct gcpro gcpro1, gcpro2, gcpro3; | |
418 | |
419 list = entry = result = Qnil; | |
420 GCPRO3 (list, entry, result); | |
421 | |
422 unwind.res = NULL; | |
423 unwind.vals = NULL; | |
424 | |
425 /* Do all the parameter checking */ | |
426 CHECK_LIVE_LDAP (ldap); | |
427 ld = XLDAP (ldap)->ld; | |
428 | |
429 /* Filter */ | |
430 CHECK_STRING (filter); | |
431 | |
432 /* Search base */ | |
433 if (NILP (base)) | |
434 { | |
435 base = Vldap_default_base; | |
436 } | |
437 if (!NILP (base)) | |
438 { | |
439 CHECK_STRING (base); | |
440 } | |
441 | |
442 /* Search scope */ | |
443 if (!NILP (scope)) | |
444 { | |
445 if (EQ (scope, Qbase)) | |
446 ldap_scope = LDAP_SCOPE_BASE; | |
447 else if (EQ (scope, Qonelevel)) | |
448 ldap_scope = LDAP_SCOPE_ONELEVEL; | |
449 else if (EQ (scope, Qsubtree)) | |
450 ldap_scope = LDAP_SCOPE_SUBTREE; | |
451 else | |
452 signal_simple_error ("Invalid scope", scope); | |
453 } | |
454 | |
455 /* Attributes to search */ | |
456 if (!NILP (attrs)) | |
457 { | |
458 CHECK_CONS (attrs); | |
459 ldap_attributes = alloca_array (char *, 1 + XINT (Flength (attrs))); | |
460 | |
461 i = 0; | |
462 EXTERNAL_LIST_LOOP (attrs, attrs) | |
463 { | |
464 Lisp_Object current = XCAR (attrs); | |
465 CHECK_STRING (current); | |
466 GET_C_STRING_OS_DATA_ALLOCA (current, ldap_attributes[i]); | |
467 ++i; | |
468 } | |
469 ldap_attributes[i] = NULL; | |
470 } | |
471 | |
472 /* Attributes only ? */ | |
473 CHECK_SYMBOL (attrsonly); | |
474 | |
475 /* Perform the search */ | |
476 if (ldap_search (ld, | |
477 NILP (base) ? "" : (char *) XSTRING_DATA (base), | |
478 ldap_scope, | |
479 NILP (filter) ? "" : (char *) XSTRING_DATA (filter), | |
480 ldap_attributes, | |
481 NILP (attrsonly) ? 0 : 1) | |
482 == -1) | |
483 { | |
484 signal_ldap_error (ld, NULL, 0); | |
485 } | |
486 | |
487 /* Ensure we don't exit without cleaning up */ | |
488 record_unwind_protect (ldap_search_unwind, | |
489 make_opaque_ptr (&unwind)); | |
490 | |
491 /* Build the results list */ | |
492 matches = 0; | |
493 | |
494 /* ldap_result calls select() and can get wedged by EINTR signals */ | |
495 slow_down_interrupts (); | |
496 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); | |
497 speed_up_interrupts (); | |
498 while (rc == LDAP_RES_SEARCH_ENTRY) | |
499 { | |
500 QUIT; | |
501 matches ++; | |
502 e = ldap_first_entry (ld, unwind.res); | |
503 /* #### This call to message() is pretty fascist, because it | |
504 destroys the current echo area contents, even when invoked | |
505 from Lisp. It should use echo_area_message() instead, and | |
506 restore the old echo area contents later. */ | |
507 message ("Parsing ldap results... %d", matches); | |
508 entry = Qnil; | |
509 /* Get the DN if required */ | |
510 if (! NILP (withdn)) | |
511 { | |
512 dn = ldap_get_dn (ld, e); | |
513 if (dn == NULL) | |
514 signal_ldap_error (ld, e, 0); | |
515 entry = Fcons (build_ext_string (dn, FORMAT_OS), Qnil); | |
516 } | |
517 for (a= ldap_first_attribute (ld, e, &ptr); | |
518 a != NULL; | |
519 a = ldap_next_attribute (ld, e, ptr) ) | |
520 { | |
521 list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); | |
522 unwind.vals = ldap_get_values_len (ld, e, a); | |
523 if (unwind.vals != NULL) | |
524 { | |
525 for (i = 0; unwind.vals[i] != NULL; i++) | |
526 { | |
527 list = Fcons (make_ext_string (unwind.vals[i]->bv_val, | |
528 unwind.vals[i]->bv_len, | |
529 FORMAT_OS), | |
530 list); | |
531 } | |
532 } | |
533 entry = Fcons (Fnreverse (list), | |
534 entry); | |
535 ldap_value_free_len (unwind.vals); | |
536 unwind.vals = NULL; | |
537 } | |
538 result = Fcons (Fnreverse (entry), | |
539 result); | |
540 ldap_msgfree (unwind.res); | |
541 unwind.res = NULL; | |
542 | |
543 slow_down_interrupts (); | |
544 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); | |
545 speed_up_interrupts (); | |
546 } | |
547 | |
548 if (rc == -1) | |
549 signal_ldap_error (ld, unwind.res, 0); | |
550 | |
551 if (rc == 0) | |
552 signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); | |
553 | |
554 #if defined HAVE_LDAP_PARSE_RESULT | |
555 rc2 = ldap_parse_result (ld, unwind.res, | |
556 &rc, | |
557 NULL, NULL, NULL, NULL, 0); | |
558 if (rc2 != LDAP_SUCCESS) | |
559 rc = rc2; | |
560 #elif defined HAVE_LDAP_RESULT2ERROR | |
561 rc = ldap_result2error (ld, unwind.res, 0); | |
562 #endif | |
563 if ((rc != LDAP_SUCCESS) && (rc != LDAP_SIZELIMIT_EXCEEDED)) | |
564 signal_ldap_error (ld, NULL, rc); | |
565 | |
566 ldap_msgfree (unwind.res); | |
567 unwind.res = (LDAPMessage *)NULL; | |
568 /* #### See above for calling message(). */ | |
569 message ("Parsing ldap results... done"); | |
570 | |
571 unbind_to (speccount, Qnil); | |
572 UNGCPRO; | |
573 return Fnreverse (result); | |
574 } | |
575 | |
576 | |
577 void | |
578 syms_of_eldap (void) | |
579 { | |
580 defsymbol (&Qldapp, "ldapp"); | |
581 defsymbol (&Qport, "port"); | |
582 defsymbol (&Qauth, "auth"); | |
583 defsymbol (&Qbinddn, "binddn"); | |
584 defsymbol (&Qpasswd, "passwd"); | |
585 defsymbol (&Qderef, "deref"); | |
586 defsymbol (&Qtimelimit, "timelimit"); | |
587 defsymbol (&Qsizelimit, "sizelimit"); | |
588 defsymbol (&Qbase, "base"); | |
589 defsymbol (&Qonelevel, "onelevel"); | |
590 defsymbol (&Qsubtree, "subtree"); | |
591 defsymbol (&Qkrbv41, "krbv41"); | |
592 defsymbol (&Qkrbv42, "krbv42"); | |
593 defsymbol (&Qnever, "never"); | |
594 defsymbol (&Qalways, "always"); | |
595 defsymbol (&Qfind, "find"); | |
596 | |
597 DEFSUBR (Fldapp); | |
598 DEFSUBR (Fldap_host); | |
599 DEFSUBR (Fldap_status); | |
600 DEFSUBR (Fldap_open); | |
601 DEFSUBR (Fldap_close); | |
602 DEFSUBR (Fldap_search_internal); | |
603 } | |
604 | |
605 void | |
606 vars_of_eldap (void) | |
607 { | |
608 | |
609 ldap_default_port = LDAP_PORT; | |
610 Vldap_default_base = Qnil; | |
611 | |
612 DEFVAR_INT ("ldap-default-port", &ldap_default_port /* | |
613 Default TCP port for LDAP connections. | |
614 Initialized from the LDAP library. Default value is 389. | |
615 */ ); | |
616 | |
617 DEFVAR_LISP ("ldap-default-base", &Vldap_default_base /* | |
618 Default base for LDAP searches. | |
619 This is a string using the syntax of RFC 1779. | |
620 For instance, "o=ACME, c=US" limits the search to the | |
621 Acme organization in the United States. | |
622 */ ); | |
623 | |
624 } | |
625 | |
626 |