1N/A/*
1N/A * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
1N/A */
1N/A
1N/A#ifndef _LDAP_PRIVATE_H
1N/A#define _LDAP_PRIVATE_H
1N/A
1N/A#include <signal.h>
1N/A#include <pthread.h> /* rri */
1N/A
1N/A#define pthread_self thr_self
1N/A#define thr_self thr_self
1N/A#define pthread_kill thr_kill
1N/A#define thr_kill thr_kill
1N/A
1N/A#ifdef _REENTRANT
1N/A#ifndef MAX_THREAD_ID
1N/A#define MAX_THREAD_ID 500
1N/A#endif /* MAX_THREAD_ID */
1N/A#else /* _REENTRANT */
1N/A#ifndef MAX_THREAD_ID
1N/A#define MAX_THREAD_ID 1
1N/A#endif /* MAX_THREAD_ID */
1N/A#endif /* _REENTRANT */
1N/A
1N/A#define COMPAT20
1N/A#define COMPAT30
1N/A#if defined(COMPAT20) || defined(COMPAT30)
1N/A#define COMPAT
1N/A#endif
1N/A
1N/A#ifdef LDAP_DNS
1N/A#define LDAP_OPT_DNS 0x00000001 /* use DN & DNS */
1N/A#endif /* LDAP_DNS */
1N/A
1N/A/*
1N/A#define DBG_LOCK1(st) printf("%d> %s %d:%s\n", thr_self(), st, __LINE__, __FILE__);
1N/A#define DBG_LOCK2(ld,st) printf("%d> %s ld_lockcount=%d %d:%s\n", thr_self(), st, (ld)->ld_lockcount, __LINE__, __FILE__);
1N/A*/
1N/A#define DBG_LOCK1(st)
1N/A#define DBG_LOCK2(ld,st)
1N/A
1N/Aextern pthread_t thr_self();
1N/A#define LOCK_RESPONSE(ld) \
1N/A if ((ld)->ld_response_lockthread != thr_self()) { \
1N/A DBG_LOCK1("waiting for response lock") \
1N/A pthread_mutex_lock( &((ld)->ld_response_mutex) ); \
1N/A DBG_LOCK1("got response lock") \
1N/A (ld)->ld_response_lockthread = thr_self(); \
1N/A } else { \
1N/A (ld)->ld_response_lockcount++; \
1N/A DBG_LOCK2(ld, "fake ldap lock") \
1N/A }
1N/A
1N/A#define UNLOCK_RESPONSE(ld) \
1N/A if ((ld)->ld_response_lockcount==0) { \
1N/A (ld)->ld_response_lockthread = 0; \
1N/A pthread_mutex_unlock( &((ld)->ld_response_mutex) ); \
1N/A DBG_LOCK1("freed response lock") \
1N/A } else { \
1N/A (ld)->ld_response_lockcount--; \
1N/A DBG_LOCK2(ld, "fake ldap unlock") \
1N/A }
1N/A
1N/A#define LOCK_LDAP(ld) \
1N/A if ((ld)->ld_lockthread != thr_self()) { \
1N/A DBG_LOCK1("waiting for ldap lock") \
1N/A pthread_mutex_lock( &((ld)->ld_ldap_mutex) ); \
1N/A DBG_LOCK1("got ldap lock") \
1N/A (ld)->ld_lockthread = thr_self(); \
1N/A } else { \
1N/A (ld)->ld_lockcount++; \
1N/A DBG_LOCK2(ld, "fake ldap lock") \
1N/A }
1N/A
1N/A#define UNLOCK_LDAP(ld) \
1N/A if ((ld)->ld_lockcount==0) { \
1N/A (ld)->ld_lockthread = 0; \
1N/A pthread_mutex_unlock( &((ld)->ld_ldap_mutex) ); \
1N/A DBG_LOCK1("freed ldap lock") \
1N/A } else { \
1N/A (ld)->ld_lockcount--; \
1N/A DBG_LOCK2(ld, "fake ldap unlock") \
1N/A }
1N/A
1N/A#define LOCK_POLL(ld) pthread_mutex_lock( &ld->ld_poll_mutex )
1N/A#define UNLOCK_POLL(ld) pthread_mutex_unlock( &ld->ld_poll_mutex )
1N/A
1N/A
1N/A/*
1N/A * structure representing a Ber Element
1N/A */
1N/Atypedef struct berelement {
1N/A char *ber_buf;
1N/A char *ber_ptr;
1N/A char *ber_end;
1N/A struct seqorset *ber_sos;
1N/A unsigned int ber_tag;
1N/A unsigned int ber_len;
1N/A int ber_usertag;
1N/A char ber_options;
1N/A#define LBER_USE_DER 0x01
1N/A#define LBER_USE_INDEFINITE_LEN 0x02
1N/A#define LBER_TRANSLATE_STRINGS 0x04
1N/A char *ber_rwptr;
1N/A BERTranslateProc ber_encode_translate_proc;
1N/A BERTranslateProc ber_decode_translate_proc;
1N/A} _struct_BerElement;
1N/A
1N/A
1N/A/*
1N/A * This structure represents both ldap messages and ldap responses.
1N/A * These are really the same, except in the case of search responses,
1N/A * where a response has multiple messages.
1N/A */
1N/Atypedef struct ldapmsg {
1N/A int lm_msgid; /* the message id */
1N/A int lm_msgtype; /* the message type */
1N/A BerElement *lm_ber; /* the ber encoded message contents */
1N/A struct ldapmsg *lm_chain; /* for search - next msg in the resp */
1N/A struct ldapmsg *lm_next; /* next response */
1N/A unsigned long lm_time; /* used to maintain cache */
1N/A} _struct_LDAPMessage;
1N/A
1N/Atypedef struct ldap_filt_list {
1N/A char *lfl_tag;
1N/A char *lfl_pattern;
1N/A char *lfl_delims;
1N/A LDAPFiltInfo *lfl_ilist;
1N/A struct ldap_filt_list *lfl_next;
1N/A} _struct_FiltList;
1N/A
1N/Atypedef struct ldap_filt_desc {
1N/A LDAPFiltList *lfd_filtlist;
1N/A LDAPFiltInfo *lfd_curfip;
1N/A LDAPFiltInfo lfd_retfi;
1N/A char lfd_filter[ LDAP_FILT_MAXSIZ ];
1N/A char *lfd_curval;
1N/A char *lfd_curvalcopy;
1N/A char **lfd_curvalwords;
1N/A char *lfd_filtprefix;
1N/A char *lfd_filtsuffix;
1N/A} _struct_FiltDesc;
1N/A
1N/A/*
1N/A * structure for tracking LDAP server host, ports, DNs, etc.
1N/A */
1N/Atypedef struct ldap_server {
1N/A char *lsrv_host;
1N/A char *lsrv_dn; /* if NULL, use default */
1N/A int lsrv_port;
1N/A struct ldap_server *lsrv_next;
1N/A} LDAPServer;
1N/A
1N/A
1N/A/*
1N/A * structure representing a Socket buffer
1N/A */
1N/Atypedef struct sockbuf {
1N/A#ifndef MACOS
1N/A int sb_sd;
1N/A#else /* MACOS */
1N/A void *sb_sd;
1N/A#endif /* MACOS */
1N/A BerElement sb_ber;
1N/A
1N/A int sb_naddr; /* > 0 implies using CLDAP (UDP) */
1N/A void *sb_useaddr; /* pointer to sockaddr to use next */
1N/A void *sb_fromaddr; /* pointer to message source sockaddr */
1N/A void **sb_addrs; /* actually an array of pointers to */
1N/A /* sockaddrs */
1N/A
1N/A int sb_options; /* to support copying ber elements */
1N/A#define LBER_TO_FILE 0x01 /* to a file referenced by sb_fd */
1N/A#define LBER_TO_FILE_ONLY 0x02 /* only write to file, not network */
1N/A#define LBER_MAX_INCOMING_SIZE 0x04 /* impose limit on incoming stuff */
1N/A#define LBER_NO_READ_AHEAD 0x08 /* read only as much as requested */
1N/A int sb_fd;
1N/A int sb_max_incoming;
1N/A#ifdef LDAP_SSL
1N/A int sb_ssl_tls;
1N/A SSL *sb_ssl; /* to support ldap over ssl */
1N/A#endif /* LDAP_SSL */
1N/A} Sockbuf;
1N/A#define READBUFSIZ 8192
1N/A
1N/A
1N/A/*
1N/A * structure for representing an LDAP server connection
1N/A */
1N/Atypedef struct ldap_conn {
1N/A Sockbuf *lconn_sb;
1N/A int lconn_refcnt;
1N/A unsigned long lconn_lastused; /* time */
1N/A int lconn_status;
1N/A#define LDAP_CONNST_NEEDSOCKET 1
1N/A#define LDAP_CONNST_CONNECTING 2
1N/A#define LDAP_CONNST_CONNECTED 3
1N/A#define LDAP_CONNST_DEAD 4
1N/A LDAPServer *lconn_server;
1N/A char *lconn_krbinstance;
1N/A struct ldap_conn *lconn_next;
1N/A} LDAPConn;
1N/A
1N/A/*
1N/A * Structure used to keep track of search references
1N/A */
1N/Atypedef struct ldap_reference {
1N/A char ** lref_refs;
1N/A struct ldap_reference *lref_next;
1N/A} LDAPRef;
1N/A
1N/A
1N/A
1N/A/*
1N/A * structure used to track outstanding requests
1N/A */
1N/Atypedef struct ldapreq {
1N/A int lr_msgid; /* the message id */
1N/A int lr_status; /* status of request */
1N/A#define LDAP_REQST_INPROGRESS 1
1N/A#define LDAP_REQST_CHASINGREFS 2
1N/A#define LDAP_REQST_NOTCONNECTED 3
1N/A#define LDAP_REQST_WRITING 4
1N/A#define LDAP_REQST_CONNDEAD 5
1N/A int lr_outrefcnt; /* count of outstanding referrals */
1N/A int lr_origid; /* original request's message id */
1N/A int lr_parentcnt; /* count of parent requests */
1N/A int lr_res_msgtype; /* result message type */
1N/A int lr_res_errno; /* result LDAP errno */
1N/A char *lr_res_error; /* result error string */
1N/A char *lr_res_matched;/* result matched DN string */
1N/A BerElement *lr_ber; /* ber encoded request contents */
1N/A LDAPConn *lr_conn; /* connection used to send request */
1N/A LDAPRef *lr_references;
1N/A char **lr_ref_followed; /* referral being followed */
1N/A char **lr_ref_unfollowed; /* Not being followed */
1N/A char **lr_ref_tofollow; /* referral to follow if the one being
1N/A followed fails. */
1N/A struct ldapreq *lr_parent; /* request that spawned this referral */
1N/A struct ldapreq *lr_refnext; /* next referral spawned */
1N/A struct ldapreq *lr_prev; /* previous request */
1N/A struct ldapreq *lr_next; /* next request */
1N/A} LDAPRequest;
1N/A
1N/A/*
1N/A * structure for client cache
1N/A */
1N/A#define LDAP_CACHE_BUCKETS 31 /* cache hash table size */
1N/Atypedef struct ldapcache {
1N/A LDAPMessage *lc_buckets[LDAP_CACHE_BUCKETS];/* hash table */
1N/A LDAPMessage *lc_requests; /* unfulfilled reqs */
1N/A time_t lc_timeout; /* request timeout */
1N/A ssize_t lc_maxmem; /* memory to use */
1N/A ssize_t lc_memused; /* memory in use */
1N/A int lc_enabled; /* enabled? */
1N/A unsigned int lc_options; /* options */
1N/A#define LDAP_CACHE_OPT_CACHENOERRS 0x00000001
1N/A#define LDAP_CACHE_OPT_CACHEALLERRS 0x00000002
1N/A} LDAPCache;
1N/A#define NULLLDCACHE ((LDAPCache *)NULL)
1N/A
1N/A/*
1N/A * structure representing an ldap connection
1N/A */
1N/Atypedef struct ldap {
1N/A Sockbuf ld_sb; /* socket descriptor & buffer */
1N/A char *ld_host;
1N/A int ld_version;
1N/A char ld_lberoptions;
1N/A int ld_deref;
1N/A
1N/A int ld_timelimit;
1N/A int ld_sizelimit;
1N/A
1N/A LDAPFiltDesc *ld_filtd; /* from getfilter for ufn searches */
1N/A char *ld_ufnprefix; /* for incomplete ufn's */
1N/A
1N/A int ld_errno[MAX_THREAD_ID]; /* thread-specific */
1N/A#define ld_errno ld_errno[ldap_thr_index()]
1N/A char *ld_error[MAX_THREAD_ID]; /* thread-specific */
1N/A#define ld_error ld_error[ldap_thr_index()]
1N/A char *ld_matched[MAX_THREAD_ID]; /* thread-specific */
1N/A#define ld_matched ld_matched[ldap_thr_index()]
1N/A char **ld_referrals[MAX_THREAD_ID]; /* thread-specific */
1N/A#define ld_referrals ld_referrals[ldap_thr_index()]
1N/A LDAPControl **ld_ret_ctrls[MAX_THREAD_ID]; /* thread-specific */
1N/A#define ld_ret_ctrls ld_ret_ctrls[ldap_thr_index()]
1N/A int ld_msgid;
1N/A
1N/A int ld_follow_referral; /* flag set to true if lib follow referrals */
1N/A LDAPRequest *ld_requests; /* list of outstanding requests -- referrals*/
1N/A
1N/A LDAPMessage *ld_responses; /* list of outstanding responses */
1N/A int *ld_abandoned; /* array of abandoned requests */
1N/A
1N/A pthread_mutex_t ld_response_mutex; /* mutex for responses part of structure */
1N/A pthread_t ld_response_lockthread; /* thread which currently holds the response lock */
1N/A int ld_response_lockcount; /* response lock depth */
1N/A
1N/A char *ld_attrbuffer[MAX_THREAD_ID];
1N/A#define ld_attrbuffer ld_attrbuffer[ldap_thr_index()]
1N/A LDAPCache *ld_cache; /* non-null if cache is initialized */
1N/A char *ld_cldapdn; /* DN used in connectionless search */
1N/A
1N/A /* it is OK to change these next four values directly */
1N/A int ld_cldaptries; /* connectionless search retry count */
1N/A int ld_cldaptimeout;/* time between retries */
1N/A int ld_refhoplimit; /* limit on referral nesting */
1N/A/* LP TO CHANGE */
1N/A char ld_restart;
1N/A#ifdef LDAP_SSL
1N/A int ld_use_ssl;
1N/A char *ld_ssl_key;
1N/A#endif
1N/A unsigned int ld_options; /* boolean options */
1N/A
1N/A /* do not mess with the rest though */
1N/A char *ld_defhost; /* full name of default server */
1N/A int ld_defport; /* port of default server */
1N/A BERTranslateProc ld_lber_encode_translate_proc;
1N/A BERTranslateProc ld_lber_decode_translate_proc;
1N/A
1N/A LDAPConn *ld_defconn; /* default connection */
1N/A LDAPConn *ld_conns; /* list of server connections */
1N/A void *ld_selectinfo; /* platform specifics for select */
1N/A
1N/A LDAP_REBIND_FUNCTION *ld_rebindproc;
1N/A void *ld_rebind_extra_arg;
1N/A/* int (*ld_rebindproc)( struct ldap *ld, char **dnp, */
1N/A/* char **passwdp, int *authmethodp, int freeit ); */
1N/A /* routine to get info needed for re-bind */
1N/A
1N/A pthread_mutex_t ld_ldap_mutex; /* mutex for thread dependent part of struct */
1N/A pthread_t ld_lockthread; /* thread which currently holds the lock */
1N/A int ld_lockcount; /* lock depth */
1N/A pthread_mutex_t ld_poll_mutex; /* a separate lock for polling */
1N/A
1N/A LDAPControl **ld_srvctrls; /* Controls used by ldap and server */
1N/A LDAPControl **ld_cltctrls; /* Client side controls */
1N/A
1N/A/* KE: Lists of unsolicited notifications */
1N/A LDAPMessage *ld_notifs[MAX_THREAD_ID];
1N/A
1N/A /* How long to wait for while connecting to a server */
1N/A int ld_connect_timeout;
1N/A#define ld_notifs ld_notifs[ldap_thr_index()]
1N/A} _struct_LDAP;
1N/A
1N/A
1N/A/*
1N/A * handy macro to check whether LDAP struct is set up for CLDAP or not
1N/A */
1N/A#define LDAP_IS_CLDAP( ld ) ( ld->ld_sb.sb_naddr > 0 )
1N/A
1N/A
1N/A#endif /* _LDAP_PRIVATE_H */