Back to index

lightning-sunbird  0.9+nobinonly
ldap-int.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef _LDAPINT_H
00038 #define _LDAPINT_H
00039 
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdlib.h>
00043 #include <errno.h>
00044 #include <time.h>
00045 #include <fcntl.h>
00046 #ifdef hpux
00047 #include <strings.h>
00048 #endif /* hpux */
00049 
00050 #ifdef _WINDOWS
00051 #  define FD_SETSIZE        256    /* number of connections we support */
00052 #  define WIN32_LEAN_AND_MEAN
00053 # include <windows.h>
00054 #elif defined(macintosh)
00055 #include "ldap-macos.h"
00056 #else /* _WINDOWS */
00057 # include <sys/time.h>
00058 # include <sys/types.h>
00059 # include <sys/socket.h>
00060 # include <netinet/in.h>
00061 #if !defined(XP_OS2) && !defined(XP_BEOS)
00062 # include <arpa/inet.h>
00063 #endif
00064 # include <netdb.h>
00065 #if !defined(hpux) && !defined(SUNOS4) && !defined(XP_BEOS)
00066 # include <sys/select.h>
00067 #endif /* !defined(hpux) and others */
00068 #endif /* _WINDOWS */
00069 
00070 #if defined(IRIX)
00071 #include <bstring.h>
00072 #endif /* IRIX */
00073 
00074 #ifdef XP_BEOS
00075 #define NSLDAPI_AVOID_OS_SOCKETS
00076 #endif
00077 
00078 #define NSLBERI_LBER_INT_FRIEND
00079 #ifdef macintosh
00080 #include "lber-int.h"
00081 #else /* macintosh */
00082 #include "../liblber/lber-int.h"
00083 #endif /* macintosh */
00084 
00085 #include "ldap.h"
00086 #include "ldaprot.h"
00087 #include "ldaplog.h"
00088 #include "portable.h"
00089 
00090 #ifdef LDAP_ASYNC_IO
00091 #ifdef NEED_FILIO
00092 #include <sys/filio.h>             /* to get FIONBIO for ioctl() call */
00093 #else /* NEED_FILIO */
00094 #if !defined( _WINDOWS) && !defined (macintosh)
00095 #include <sys/ioctl.h>             /* to get FIONBIO for ioctl() call */
00096 #endif /* _WINDOWS && macintosh */
00097 #endif /* NEED_FILIO */
00098 #endif /* LDAP_ASYNC_IO */
00099 
00100 #ifdef USE_SYSCONF
00101 #  include <unistd.h>
00102 #endif /* USE_SYSCONF */
00103 
00104 #if !defined(_WINDOWS) && !defined(macintosh) && !defined(BSDI) && \
00105     !defined(XP_OS2) && !defined(XP_BEOS) && !defined(NTO) && \
00106     !defined(DARWIN)
00107 #define NSLDAPI_HAVE_POLL   1
00108 #endif
00109 
00110 /* SSL version, or 0 if not built with SSL */
00111 #if defined(NET_SSL)
00112 #  define SSL_VERSION 3
00113 #else
00114 #  define SSL_VERSION 0
00115 #endif
00116 
00117 
00118 #define LDAP_URL_URLCOLON   "URL:"
00119 #define LDAP_URL_URLCOLON_LEN      4
00120 
00121 #define LDAP_LDAP_REF_STR   LDAP_URL_PREFIX
00122 #define LDAP_LDAP_REF_STR_LEN      LDAP_URL_PREFIX_LEN
00123 #define LDAP_LDAPS_REF_STR  LDAPS_URL_PREFIX
00124 #define LDAP_LDAPS_REF_STR_LEN     LDAPS_URL_PREFIX_LEN
00125 
00126 /* default limit on nesting of referrals */
00127 #define LDAP_DEFAULT_REFHOPLIMIT   5
00128 #ifdef LDAP_DNS
00129 #define LDAP_DX_REF_STR            "dx://"
00130 #define LDAP_DX_REF_STR_LEN 5
00131 #endif /* LDAP_DNS */
00132 
00133 typedef enum { 
00134     LDAP_CACHE_LOCK, 
00135     LDAP_MEMCACHE_LOCK, 
00136     LDAP_MSGID_LOCK,
00137     LDAP_REQ_LOCK, 
00138     LDAP_RESP_LOCK, 
00139     LDAP_ABANDON_LOCK, 
00140     LDAP_CTRL_LOCK,
00141     LDAP_OPTION_LOCK, 
00142     LDAP_ERR_LOCK, 
00143     LDAP_CONN_LOCK, 
00144     LDAP_IOSTATUS_LOCK,            /* serializes access to ld->ld_iostatus */
00145     LDAP_RESULT_LOCK, 
00146     LDAP_PEND_LOCK, 
00147     LDAP_THREADID_LOCK, 
00148     LDAP_MAX_LOCK 
00149 } LDAPLock;
00150 
00151 /*
00152  * This structure represents both ldap messages and ldap responses.
00153  * These are really the same, except in the case of search responses,
00154  * where a response has multiple messages.
00155  */
00156 
00157 struct ldapmsg {
00158        int           lm_msgid;     /* the message id */
00159        int           lm_msgtype;   /* the message type */
00160        BerElement    *lm_ber;      /* the ber encoded message contents */
00161        struct ldapmsg       *lm_chain;    /* for search - next msg in the resp */
00162        struct ldapmsg       *lm_next;     /* next response */
00163        int           lm_fromcache; /* memcache: origin of message */
00164 };
00165 
00166 /*
00167  * structure for tracking LDAP server host, ports, DNs, etc.
00168  */
00169 typedef struct ldap_server {
00170        char                 *lsrv_host;
00171        char                 *lsrv_dn;     /* if NULL, use default */
00172        int                  lsrv_port;
00173        unsigned long        lsrv_options; /* boolean options */
00174 #define LDAP_SRV_OPT_SECURE 0x01
00175        struct ldap_server   *lsrv_next;
00176 } LDAPServer;
00177 
00178 /*
00179  * structure for representing an LDAP server connection
00180  */
00181 typedef struct ldap_conn {
00182        Sockbuf                     *lconn_sb;
00183        BerElement           *lconn_ber;  /* non-NULL if in midst of msg. */
00184        int                  lconn_version;       /* LDAP protocol version */
00185        int                  lconn_refcnt;
00186        unsigned long        lconn_lastused;      /* time */
00187        int                  lconn_status;
00188 #define LDAP_CONNST_NEEDSOCKET            1
00189 #define LDAP_CONNST_CONNECTING            2
00190 #define LDAP_CONNST_CONNECTED             3
00191 #define LDAP_CONNST_DEAD           4
00192        LDAPServer           *lconn_server;
00193        char                 *lconn_binddn;       /* DN of last successful bind */
00194        int                  lconn_bound;  /* has a bind been done? */
00195        char                 *lconn_krbinstance;
00196        struct ldap_conn     *lconn_next;
00197 } LDAPConn;
00198 
00199 
00200 /*
00201  * structure used to track outstanding requests
00202  */
00203 typedef struct ldapreq {
00204        int           lr_msgid;     /* the message id */
00205        int           lr_status;    /* status of request */
00206 #define LDAP_REQST_INPROGRESS      1
00207 #define LDAP_REQST_CHASINGREFS     2
00208 #define LDAP_REQST_NOTCONNECTED    3
00209 #define LDAP_REQST_WRITING  4
00210 #define LDAP_REQST_CONNDEAD 5      /* associated conn. has failed */
00211        int           lr_outrefcnt; /* count of outstanding referrals */
00212        int           lr_origid;    /* original request's message id */
00213        int           lr_parentcnt; /* count of parent requests */
00214        int           lr_res_msgtype;      /* result message type */
00215        int           lr_res_errno; /* result LDAP errno */
00216        char          *lr_res_error;       /* result error string */
00217        char          *lr_res_matched;/* result matched DN string */
00218        BerElement    *lr_ber;      /* ber encoded request contents */
00219        LDAPConn      *lr_conn;     /* connection used to send request */
00220        char          *lr_binddn;   /* request is a bind for this DN */
00221        struct ldapreq       *lr_parent;   /* request that spawned this referral */
00222        struct ldapreq       *lr_child;    /* list of requests we spawned */
00223        struct ldapreq       *lr_sibling;  /* next referral spawned */
00224        struct ldapreq       *lr_prev;     /* ld->ld_requests previous request */
00225        struct ldapreq       *lr_next;     /* ld->ld_requests next request */
00226 } LDAPRequest;
00227 
00228 typedef struct ldappend {
00229        void          *lp_sema;     /* semaphore to post */
00230        int           lp_msgid;     /* message id */
00231        LDAPMessage   *lp_result;   /* result storage */
00232        struct ldappend      *lp_prev;     /* previous pending */
00233        struct ldappend      *lp_next;     /* next pending */
00234 } LDAPPend;
00235 
00236 /*
00237  * forward declaration for I/O status structure (defined in os-ip.c)
00238  */
00239 typedef struct nsldapi_iostatus_info NSLDAPIIOStatus;
00240 
00241 /*
00242  * old extended IO structure (before writev callback was added)
00243  */
00244 struct ldap_x_ext_io_fns_rev0 {
00245         int                                     lextiof_size;
00246         LDAP_X_EXTIOF_CONNECT_CALLBACK          *lextiof_connect;
00247         LDAP_X_EXTIOF_CLOSE_CALLBACK            *lextiof_close;
00248         LDAP_X_EXTIOF_READ_CALLBACK             *lextiof_read;
00249         LDAP_X_EXTIOF_WRITE_CALLBACK            *lextiof_write;
00250         LDAP_X_EXTIOF_POLL_CALLBACK             *lextiof_poll;
00251         LDAP_X_EXTIOF_NEWHANDLE_CALLBACK        *lextiof_newhandle;
00252         LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK    *lextiof_disposehandle;
00253         void                                    *lextiof_session_arg;
00254 };
00255 #define LDAP_X_EXTIO_FNS_SIZE_REV0   sizeof(struct ldap_x_ext_io_fns_rev0)
00256 
00257 
00258 /*
00259  * structure representing an ldap connection
00260  */
00261 struct ldap {
00262        struct sockbuf       *ld_sbp;      /* pointer to socket desc. & buffer */
00263        char          *ld_host;
00264        int           ld_version;   /* LDAP protocol version */
00265        char          ld_lberoptions;
00266        int           ld_deref;
00267 
00268        int           ld_timelimit;
00269        int           ld_sizelimit;
00270 
00271        struct ldap_filt_desc       *ld_filtd;    /* from getfilter for ufn searches */
00272        char          *ld_ufnprefix;       /* for incomplete ufn's */
00273 
00274        int           ld_errno;
00275        char          *ld_error;
00276        char          *ld_matched;
00277        int           ld_msgid;
00278 
00279        /* do not mess with these */
00280        LDAPRequest   *ld_requests; /* list of outstanding requests */
00281        LDAPMessage   *ld_responses;       /* list of outstanding responses */
00282        int           *ld_abandoned;       /* array of abandoned requests */
00283        char          *ld_cldapdn;  /* DN used in connectionless search */
00284 
00285        /* it is OK to change these next four values directly */
00286        int           ld_cldaptries;       /* connectionless search retry count */
00287        int           ld_cldaptimeout;/* time between retries */
00288        int           ld_refhoplimit;      /* limit on referral nesting */
00289        unsigned long ld_options;   /* boolean options */
00290 
00291 #define LDAP_BITOPT_REFERRALS      0x80000000
00292 #define LDAP_BITOPT_SSL            0x40000000
00293 #define LDAP_BITOPT_DNS            0x20000000
00294 #define LDAP_BITOPT_RESTART 0x10000000
00295 #define LDAP_BITOPT_RECONNECT      0x08000000
00296 #define LDAP_BITOPT_ASYNC       0x04000000
00297 
00298        /* do not mess with the rest though */
00299        char          *ld_defhost;  /* full name of default server */
00300        int           ld_defport;   /* port of default server */
00301        BERTranslateProc ld_lber_encode_translate_proc;
00302        BERTranslateProc ld_lber_decode_translate_proc;
00303        LDAPConn      *ld_defconn;  /* default connection */
00304        LDAPConn      *ld_conns;    /* list of all server connections */
00305        NSLDAPIIOStatus      *ld_iostatus; /* status info. about network sockets */
00306        LDAP_REBINDPROC_CALLBACK *ld_rebind_fn;
00307        void          *ld_rebind_arg;
00308 
00309        /* function pointers, etc. for extended I/O */
00310        struct ldap_x_ext_io_fns ld_ext_io_fns;
00311 #define ld_extio_size              ld_ext_io_fns.lextiof_size
00312 #define ld_extclose_fn             ld_ext_io_fns.lextiof_close
00313 #define ld_extconnect_fn    ld_ext_io_fns.lextiof_connect
00314 #define ld_extread_fn              ld_ext_io_fns.lextiof_read
00315 #define ld_extwrite_fn             ld_ext_io_fns.lextiof_write
00316 #define ld_extwritev_fn         ld_ext_io_fns.lextiof_writev
00317 #define ld_extpoll_fn              ld_ext_io_fns.lextiof_poll
00318 #define ld_extnewhandle_fn  ld_ext_io_fns.lextiof_newhandle
00319 #define ld_extdisposehandle_fn     ld_ext_io_fns.lextiof_disposehandle
00320 #define ld_ext_session_arg  ld_ext_io_fns.lextiof_session_arg
00321 
00322        /* allocated pointer for older I/O functions */
00323        struct ldap_io_fns   *ld_io_fns_ptr;
00324 #define NSLDAPI_USING_CLASSIC_IO_FUNCTIONS( ld ) ((ld)->ld_io_fns_ptr != NULL)
00325 
00326        /* function pointers, etc. for DNS */
00327        struct ldap_dns_fns  ld_dnsfn;
00328 #define ld_dns_extradata    ld_dnsfn.lddnsfn_extradata
00329 #define ld_dns_bufsize             ld_dnsfn.lddnsfn_bufsize
00330 #define ld_dns_gethostbyname_fn    ld_dnsfn.lddnsfn_gethostbyname
00331 #define ld_dns_gethostbyaddr_fn    ld_dnsfn.lddnsfn_gethostbyaddr
00332 
00333        /* function pointers, etc. for threading */
00334        struct ldap_thread_fns      ld_thread;
00335 #define ld_mutex_alloc_fn   ld_thread.ltf_mutex_alloc
00336 #define ld_mutex_free_fn    ld_thread.ltf_mutex_free
00337 #define ld_mutex_lock_fn    ld_thread.ltf_mutex_lock
00338 #define ld_mutex_unlock_fn  ld_thread.ltf_mutex_unlock
00339 #define ld_get_errno_fn            ld_thread.ltf_get_errno
00340 #define ld_set_errno_fn            ld_thread.ltf_set_errno
00341 #define ld_get_lderrno_fn   ld_thread.ltf_get_lderrno
00342 #define ld_set_lderrno_fn   ld_thread.ltf_set_lderrno
00343 #define ld_lderrno_arg             ld_thread.ltf_lderrno_arg
00344        void                 **ld_mutex;
00345 
00346        /* function pointers, etc. for caching */
00347        int                  ld_cache_on;
00348        int                  ld_cache_strategy;
00349        struct ldap_cache_fns       ld_cache;
00350 #define ld_cache_config            ld_cache.lcf_config
00351 #define ld_cache_bind              ld_cache.lcf_bind
00352 #define ld_cache_unbind            ld_cache.lcf_unbind
00353 #define ld_cache_search            ld_cache.lcf_search
00354 #define ld_cache_compare    ld_cache.lcf_compare
00355 #define ld_cache_add        ld_cache.lcf_add
00356 #define ld_cache_delete            ld_cache.lcf_delete
00357 #if 0
00358 #define ld_cache_rename            ld_cache.lcf_rename
00359 #endif
00360 #define ld_cache_modify            ld_cache.lcf_modify
00361 #define ld_cache_modrdn            ld_cache.lcf_modrdn
00362 #define ld_cache_abandon    ld_cache.lcf_abandon
00363 #define ld_cache_result            ld_cache.lcf_result
00364 #define ld_cache_flush             ld_cache.lcf_flush
00365 #define ld_cache_arg        ld_cache.lcf_arg
00366 
00367        /* ldapv3 controls */
00368        LDAPControl          **ld_servercontrols;
00369        LDAPControl          **ld_clientcontrols;
00370 
00371        /* Preferred language */
00372        char            *ld_preferred_language;
00373 
00374        /* MemCache */
00375        LDAPMemCache  *ld_memcache;
00376 
00377        /* Pending results */
00378        LDAPPend      *ld_pend;     /* list of pending results */
00379 
00380        /* extra thread function pointers */
00381        struct ldap_extra_thread_fns       ld_thread2;
00382 
00383        /* With the 4.0 version of the LDAP SDK */
00384        /* the extra thread functions except for */
00385        /* the ld_threadid_fn has been disabled */
00386        /* Look at the release notes for the full */
00387        /* explanation */
00388 #define ld_mutex_trylock_fn        ld_thread2.ltf_mutex_trylock
00389 #define ld_sema_alloc_fn           ld_thread2.ltf_sema_alloc
00390 #define ld_sema_free_fn                   ld_thread2.ltf_sema_free
00391 #define ld_sema_wait_fn                   ld_thread2.ltf_sema_wait
00392 #define ld_sema_post_fn                   ld_thread2.ltf_sema_post
00393 #define ld_threadid_fn                    ld_thread2.ltf_threadid_fn
00394 
00395        /* extra data for mutex handling in referrals */
00396        void                 *ld_mutex_threadid[LDAP_MAX_LOCK];
00397        unsigned long        ld_mutex_refcnt[LDAP_MAX_LOCK];
00398 
00399        /* connect timeout value */
00400        int                         ld_connect_timeout;
00401 };
00402 
00403 /* allocate/free mutex */
00404 #define LDAP_MUTEX_ALLOC( ld ) \
00405        (((ld)->ld_mutex_alloc_fn != NULL) ? (ld)->ld_mutex_alloc_fn() : NULL)
00406 
00407 /* allocate/free mutex */
00408 #define LDAP_MUTEX_FREE( ld, m ) \
00409        if ( (ld)->ld_mutex_free_fn != NULL && m != NULL ) { \
00410               (ld)->ld_mutex_free_fn( m ); \
00411        }
00412 
00413 /* enter/exit critical sections */
00414 /*
00415  * The locks assume that the locks are thread safe.  XXXmcs: which means???
00416  *
00417  * Note that we test for both ld_mutex_lock_fn != NULL AND ld_mutex != NULL.
00418  * This is necessary because there is a window in ldap_init() between the
00419  * time we set the ld_mutex_lock_fn pointer and the time we allocate the
00420  * mutexes in which external code COULD be called which COULD make a call to
00421  * something like ldap_get_option(), which uses LDAP_MUTEX_LOCK().  The
00422  * libprldap code does this in its newhandle callback (prldap_newhandle).
00423  */
00424 
00425 #define LDAP_MUTEX_LOCK(ld, lock) \
00426     if ((ld)->ld_mutex_lock_fn != NULL && ld->ld_mutex != NULL) { \
00427         if ((ld)->ld_threadid_fn != NULL) { \
00428             if ((ld)->ld_mutex_threadid[lock] == (ld)->ld_threadid_fn()) { \
00429                 (ld)->ld_mutex_refcnt[lock]++; \
00430             } else { \
00431                 (ld)->ld_mutex_lock_fn(ld->ld_mutex[lock]); \
00432                 (ld)->ld_mutex_threadid[lock] = ld->ld_threadid_fn(); \
00433                 (ld)->ld_mutex_refcnt[lock] = 1; \
00434             } \
00435         } else { \
00436             (ld)->ld_mutex_lock_fn(ld->ld_mutex[lock]); \
00437         } \
00438     } 
00439 
00440 #define LDAP_MUTEX_UNLOCK(ld, lock) \
00441     if ((ld)->ld_mutex_lock_fn != NULL && ld->ld_mutex != NULL) { \
00442         if ((ld)->ld_threadid_fn != NULL) { \
00443             if ((ld)->ld_mutex_threadid[lock] == (ld)->ld_threadid_fn()) { \
00444                 (ld)->ld_mutex_refcnt[lock]--; \
00445                 if ((ld)->ld_mutex_refcnt[lock] <= 0) { \
00446                     (ld)->ld_mutex_threadid[lock] = (void *) -1; \
00447                     (ld)->ld_mutex_refcnt[lock] = 0; \
00448                     (ld)->ld_mutex_unlock_fn(ld->ld_mutex[lock]); \
00449                 } \
00450             } \
00451         } else { \
00452             ld->ld_mutex_unlock_fn(ld->ld_mutex[lock]); \
00453         } \
00454     }
00455 
00456 /* Backward compatibility locks */
00457 #define LDAP_MUTEX_BC_LOCK( ld, i ) \
00458        /* the ld_mutex_trylock_fn is always set to NULL */ \
00459        /* in setoption.c as the extra thread functions were */ \
00460        /* turned off in the 4.0 SDK.  This check will  */ \
00461        /* always be true */ \
00462        if( (ld)->ld_mutex_trylock_fn == NULL ) { \
00463               LDAP_MUTEX_LOCK( ld, i ) ; \
00464        }
00465 #define LDAP_MUTEX_BC_UNLOCK( ld, i ) \
00466        /* the ld_mutex_trylock_fn is always set to NULL */ \
00467        /* in setoption.c as the extra thread functions were */ \
00468        /* turned off in the 4.0 SDK.  This check will  */ \
00469        /* always be true */ \
00470        if( (ld)->ld_mutex_trylock_fn == NULL ) { \
00471               LDAP_MUTEX_UNLOCK( ld, i ) ; \
00472        }
00473 
00474 /* allocate/free semaphore */
00475 #define LDAP_SEMA_ALLOC( ld ) \
00476        (((ld)->ld_sema_alloc_fn != NULL) ? (ld)->ld_sema_alloc_fn() : NULL)
00477 #define LDAP_SEMA_FREE( ld, m ) \
00478        if ( (ld)->ld_sema_free_fn != NULL && m != NULL ) { \
00479               (ld)->ld_sema_free_fn( m ); \
00480        }
00481 
00482 /* wait/post binary semaphore */
00483 #define LDAP_SEMA_WAIT( ld, lp ) \
00484        if ( (ld)->ld_sema_wait_fn != NULL ) { \
00485               (ld)->ld_sema_wait_fn( lp->lp_sema ); \
00486        }
00487 #define LDAP_SEMA_POST( ld, lp ) \
00488        if ( (ld)->ld_sema_post_fn != NULL ) { \
00489               (ld)->ld_sema_post_fn( lp->lp_sema ); \
00490        }
00491 #define POST( ld, y, z ) \
00492        /* the ld_mutex_trylock_fn is always set to NULL */ \
00493        /* in setoption.c as the extra thread functions were */ \
00494        /* turned off in the 4.0 SDK.  This check will  */ \
00495        /* always be false */ \
00496        if( (ld)->ld_mutex_trylock_fn != NULL ) { \
00497               nsldapi_post_result( ld, y, z ); \
00498        }
00499 
00500 /* get/set errno */
00501 #ifndef macintosh
00502 #define LDAP_SET_ERRNO( ld, e ) \
00503        if ( (ld)->ld_set_errno_fn != NULL ) { \
00504               (ld)->ld_set_errno_fn( e ); \
00505        } else { \
00506               errno = e; \
00507        }
00508 #define LDAP_GET_ERRNO( ld ) \
00509        (((ld)->ld_get_errno_fn != NULL) ? \
00510               (ld)->ld_get_errno_fn() : errno)
00511 #else /* macintosh */
00512 #define LDAP_SET_ERRNO( ld, e ) \
00513        if ( (ld)->ld_set_errno_fn != NULL ) { \
00514               (ld)->ld_set_errno_fn( e ); \
00515        }
00516 #define LDAP_GET_ERRNO( ld ) \
00517        (((ld)->ld_get_errno_fn != NULL) ? \
00518               (ld)->ld_get_errno_fn() : 0)
00519 #endif
00520 
00521 
00522 /* get/set ldap-specific errno */
00523 #define LDAP_SET_LDERRNO( ld, e, m, s )   ldap_set_lderrno( ld, e, m, s )
00524 #define LDAP_GET_LDERRNO( ld, m, s ) ldap_get_lderrno( ld, m, s )
00525 
00526 /*
00527  * your standard "mimimum of two values" macro
00528  */
00529 #define NSLDAPI_MIN(a, b)   (((a) < (b)) ? (a) : (b))
00530 
00531 /*
00532  * handy macro to check whether LDAP struct is set up for CLDAP or not
00533  */
00534 #define LDAP_IS_CLDAP( ld ) ( ld->ld_sbp->sb_naddr > 0 )
00535 
00536 /*
00537  * Some Unix error defs. Under CW 7, we can't define OTUNIXERRORS because
00538  * it generates many conflicts with errno.h. Define what we need here.
00539  * These need to be in sync with OpenTransport.h
00540  */
00541  
00542 #if defined(macintosh)
00543 #define EWOULDBLOCK     35
00544 #define EHOSTUNREACH    65
00545 #endif
00546 
00547 /*
00548  * handy macro to check errno "e" for an "in progress" sort of error
00549  */
00550 #if defined(macintosh) || defined(_WINDOWS)
00551 #define NSLDAPI_ERRNO_IO_INPROGRESS( e )  ((e) == EWOULDBLOCK || (e) == EAGAIN)
00552 #else
00553 #ifdef EAGAIN
00554 #define NSLDAPI_ERRNO_IO_INPROGRESS( e )  ((e) == EWOULDBLOCK || (e) == EINPROGRESS || (e) == EAGAIN)
00555 #else /* EAGAIN */
00556 #define NSLDAPI_ERRNO_IO_INPROGRESS( e )  ((e) == EWOULDBLOCK || (e) == EINPROGRESS) 
00557 #endif /* EAGAIN */
00558 #endif /* macintosh || _WINDOWS*/
00559 
00560 /*
00561  * macro to return the LDAP protocol version we are using
00562  */
00563 #define NSLDAPI_LDAP_VERSION( ld ) ( (ld)->ld_defconn == NULL ? \
00564                                    (ld)->ld_version : \
00565                                    (ld)->ld_defconn->lconn_version )
00566 
00567 /*
00568  * Structures used for handling client filter lists.
00569  */
00570 #define LDAP_FILT_MAXSIZ    1024
00571 
00572 struct ldap_filt_list {
00573     char                    *lfl_tag;
00574     char                    *lfl_pattern;
00575     char                    *lfl_delims;
00576     struct ldap_filt_info   *lfl_ilist;
00577     struct ldap_filt_list   *lfl_next;
00578 };
00579 
00580 struct ldap_filt_desc {
00581        LDAPFiltList         *lfd_filtlist;
00582        LDAPFiltInfo         *lfd_curfip;
00583        LDAPFiltInfo         lfd_retfi;
00584        char                 lfd_filter[ LDAP_FILT_MAXSIZ ];
00585        char                 *lfd_curval;
00586        char                 *lfd_curvalcopy;
00587        char                 **lfd_curvalwords;
00588        char                 *lfd_filtprefix;
00589        char                 *lfd_filtsuffix;
00590 };
00591 
00592 /*
00593  * "internal" globals used to track defaults and memory allocation callbacks:
00594  *    (the actual definitions are in open.c)
00595  */
00596 extern struct ldap                 nsldapi_ld_defaults;
00597 extern struct ldap_memalloc_fns           nsldapi_memalloc_fns;
00598 extern int                         nsldapi_initialized;
00599 
00600 
00601 /*
00602  * Memory allocation done in liblber should all go through one of the
00603  * following macros. This is so we can plug-in alternative memory
00604  * allocators, etc. as the need arises.
00605  */
00606 #define NSLDAPI_MALLOC( size )            ldap_x_malloc( size )
00607 #define NSLDAPI_CALLOC( nelem, elsize )   ldap_x_calloc( nelem, elsize )
00608 #define NSLDAPI_REALLOC( ptr, size )      ldap_x_realloc( ptr, size )
00609 #define NSLDAPI_FREE( ptr )        ldap_x_free( ptr )
00610 
00611 
00612 /*
00613  * macros used to check validity of data structures and parameters
00614  */
00615 #define NSLDAPI_VALID_LDAP_POINTER( ld ) \
00616        ( (ld) != NULL )
00617 
00618 #define NSLDAPI_VALID_LDAPMESSAGE_POINTER( lm ) \
00619        ( (lm) != NULL )
00620 
00621 #define NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( lm ) \
00622        ( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_SEARCH_ENTRY )
00623 
00624 #define NSLDAPI_VALID_LDAPMESSAGE_REFERENCE_POINTER( lm ) \
00625        ( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_SEARCH_REFERENCE )
00626 
00627 #define NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( lm ) \
00628        ( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_BIND )
00629 
00630 #define NSLDAPI_VALID_LDAPMESSAGE_EXRESULT_POINTER( lm ) \
00631        ( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_EXTENDED )
00632 
00633 #define NSLDAPI_VALID_LDAPMOD_ARRAY( mods ) \
00634        ( (mods) != NULL )
00635 
00636 #define NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods ) \
00637        ( (mods) != NULL && (mods)[0] != NULL )
00638 
00639 #define NSLDAPI_IS_SEARCH_ENTRY( code ) \
00640        ((code) == LDAP_RES_SEARCH_ENTRY)
00641 
00642 #define NSLDAPI_IS_SEARCH_RESULT( code ) \
00643        ((code) == LDAP_RES_SEARCH_RESULT)
00644 
00645 #define NSLDAPI_SEARCH_RELATED_RESULT( code ) \
00646        (NSLDAPI_IS_SEARCH_RESULT( code ) || NSLDAPI_IS_SEARCH_ENTRY( code ))
00647 
00648 /*
00649  * in bind.c
00650  */
00651 char *nsldapi_get_binddn( LDAP *ld );
00652 
00653 /*
00654  * in cache.c
00655  */
00656 void nsldapi_add_result_to_cache( LDAP *ld, LDAPMessage *result );
00657 
00658 /*
00659  * in dsparse.c
00660  */
00661 int nsldapi_next_line_tokens( char **bufp, long *blenp, char ***toksp );
00662 void nsldapi_free_strarray( char **sap );
00663 
00664 /*
00665  * in error.c
00666  */
00667 int nsldapi_parse_result( LDAP *ld, int msgtype, BerElement *rber,
00668     int *errcodep, char **matchednp, char **errmsgp, char ***referralsp,
00669     LDAPControl ***serverctrlsp );
00670 
00671 /*
00672  * in open.c
00673  */
00674 void nsldapi_initialize_defaults( void );
00675 void nsldapi_mutex_alloc_all( LDAP *ld );
00676 void nsldapi_mutex_free_all( LDAP *ld );
00677 int nsldapi_open_ldap_defconn( LDAP *ld );
00678 char *nsldapi_strdup( const char *s );  /* if s is NULL, returns NULL */
00679 
00680 /*
00681  * in os-ip.c
00682  */
00683 int nsldapi_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host,
00684        int port, int secure, char **krbinstancep );
00685 void nsldapi_close_connection( LDAP *ld, Sockbuf *sb );
00686 
00687 int nsldapi_iostatus_poll( LDAP *ld, struct timeval *timeout );
00688 void nsldapi_iostatus_free( LDAP *ld );
00689 int nsldapi_iostatus_interest_write( LDAP *ld, Sockbuf *sb );
00690 int nsldapi_iostatus_interest_read( LDAP *ld, Sockbuf *sb );
00691 int nsldapi_iostatus_interest_clear( LDAP *ld, Sockbuf *sb );
00692 int nsldapi_iostatus_is_read_ready( LDAP *ld, Sockbuf *sb );
00693 int nsldapi_iostatus_is_write_ready( LDAP *ld, Sockbuf *sb );
00694 int nsldapi_install_lber_extiofns( LDAP *ld, Sockbuf *sb );
00695 int nsldapi_install_compat_io_fns( LDAP *ld, struct ldap_io_fns *iofns );
00696 
00697 /*
00698  * if referral.c
00699  */
00700 int nsldapi_parse_reference( LDAP *ld, BerElement *rber, char ***referralsp,
00701        LDAPControl ***serverctrlsp );
00702 
00703 
00704 /*
00705  * in result.c
00706  */
00707 int ldap_msgdelete( LDAP *ld, int msgid );
00708 int nsldapi_result_nolock( LDAP *ld, int msgid, int all, int unlock_permitted,
00709     struct timeval *timeout, LDAPMessage **result );
00710 int nsldapi_wait_result( LDAP *ld, int msgid, int all, struct timeval *timeout,
00711     LDAPMessage **result );
00712 int nsldapi_post_result( LDAP *ld, int msgid, LDAPMessage *result );
00713 
00714 /*
00715  * in request.c
00716  */
00717 int nsldapi_send_initial_request( LDAP *ld, int msgid, unsigned long msgtype,
00718        char *dn, BerElement *ber );
00719 int nsldapi_alloc_ber_with_options( LDAP *ld, BerElement **berp );
00720 void nsldapi_set_ber_options( LDAP *ld, BerElement *ber );
00721 int nsldapi_ber_flush( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit,
00722        int async );
00723 int nsldapi_send_server_request( LDAP *ld, BerElement *ber, int msgid,
00724        LDAPRequest *parentreq, LDAPServer *srvlist, LDAPConn *lc,
00725        char *bindreqdn, int bind );
00726 LDAPConn *nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
00727        int connect, int bind );
00728 LDAPRequest *nsldapi_find_request_by_msgid( LDAP *ld, int msgid );
00729 void nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn );
00730 void nsldapi_free_connection( LDAP *ld, LDAPConn *lc,
00731        LDAPControl **serverctrls, LDAPControl **clientctrls,
00732        int force, int unbind );
00733 void nsldapi_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
00734 void nsldapi_dump_requests_and_responses( LDAP *ld );
00735 int nsldapi_chase_v2_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp,
00736        int *totalcountp, int *chasingcountp );
00737 int nsldapi_chase_v3_refs( LDAP *ld, LDAPRequest *lr, char **refs,
00738        int is_reference, int *totalcountp, int *chasingcountp );
00739 int nsldapi_append_referral( LDAP *ld, char **referralsp, char *s );
00740 void nsldapi_connection_lost_nolock( LDAP *ld, Sockbuf *sb );
00741 
00742 /*
00743  * in search.c
00744  */
00745 int nsldapi_build_search_req( LDAP *ld, const char *base, int scope,
00746        const char *filter, char **attrs, int attrsonly,
00747        LDAPControl **serverctrls, LDAPControl **clientctrls,
00748        int timelimit, int sizelimit, int msgid, BerElement **berp );
00749 
00750 /*
00751  * in unbind.c
00752  */
00753 int ldap_ld_free( LDAP *ld, LDAPControl **serverctrls,
00754        LDAPControl **clientctrls, int close );
00755 int nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls,
00756        LDAPControl **clientctrls );
00757 
00758 #ifdef LDAP_DNS
00759 /*
00760  * in getdxbyname.c
00761  */
00762 char **nsldapi_getdxbyname( char *domain );
00763 
00764 #endif /* LDAP_DNS */
00765 
00766 /*
00767  * in unescape.c
00768  */
00769 void nsldapi_hex_unescape( char *s );
00770 
00771 /*
00772  * in reslist.c
00773  */
00774 LDAPMessage *ldap_delete_result_entry( LDAPMessage **list, LDAPMessage *e );
00775 void ldap_add_result_entry( LDAPMessage **list, LDAPMessage *e );
00776 
00777 /*
00778  * in compat.c
00779  */
00780 #ifdef hpux
00781 char *nsldapi_compat_ctime_r( const time_t *clock, char *buf, int buflen );
00782 struct hostent *nsldapi_compat_gethostbyname_r( const char *name,
00783        struct hostent *result, char *buffer, int buflen, int *h_errnop );
00784 #endif /* hpux */
00785 
00786 /*
00787  * in control.c
00788  */
00789 int nsldapi_put_controls( LDAP *ld, LDAPControl **ctrls, int closeseq,
00790        BerElement *ber );
00791 int nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp );
00792 int nsldapi_dup_controls( LDAP *ld, LDAPControl ***ldctrls,
00793        LDAPControl **newctrls );
00794 int nsldapi_build_control( char *oid, BerElement *ber, int freeber,
00795     char iscritical, LDAPControl **ctrlp );
00796 
00797 
00798 /*
00799  * in url.c
00800  */
00801 int nsldapi_url_parse( const char *inurl, LDAPURLDesc **ludpp,
00802        int dn_required );
00803 
00804 
00805 /*
00806  * in charset.c
00807  *
00808  * If we ever want to expose character set translation functionality to
00809  * users of libldap, all of these prototypes will need to be moved to ldap.h
00810  */
00811 #ifdef STR_TRANSLATION
00812 void ldap_set_string_translators( LDAP *ld,
00813         BERTranslateProc encode_proc, BERTranslateProc decode_proc );
00814 int ldap_translate_from_t61( LDAP *ld, char **bufp,
00815         unsigned long *lenp, int free_input );
00816 int ldap_translate_to_t61( LDAP *ld, char **bufp,
00817         unsigned long *lenp, int free_input );
00818 void ldap_enable_translation( LDAP *ld, LDAPMessage *entry,
00819         int enable );
00820 #ifdef LDAP_CHARSET_8859
00821 int ldap_t61_to_8859( char **bufp, unsigned long *buflenp,
00822         int free_input );
00823 int ldap_8859_to_t61( char **bufp, unsigned long *buflenp,
00824         int free_input );
00825 #endif /* LDAP_CHARSET_8859 */
00826 #endif /* STR_TRANSLATION */
00827 
00828 /*
00829  * in memcache.h
00830  */
00831 int ldap_memcache_createkey( LDAP *ld, const char *base, int scope,
00832        const char *filter, char **attrs, int attrsonly,
00833        LDAPControl **serverctrls, LDAPControl **clientctrls,
00834        unsigned long *keyp );
00835 int ldap_memcache_result( LDAP *ld, int msgid, unsigned long key );
00836 int ldap_memcache_new( LDAP *ld, int msgid, unsigned long key,
00837        const char *basedn );
00838 int ldap_memcache_append( LDAP *ld, int msgid, int bLast, LDAPMessage *result );
00839 int ldap_memcache_abandon( LDAP *ld, int msgid );
00840 
00841 #endif /* _LDAPINT_H */