1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 #ifndef _LDAP_PRIVATE_H 9 #define _LDAP_PRIVATE_H 10 11 #include <signal.h> 12 #include <pthread.h> /* rri */ 13 14 #define pthread_self thr_self 15 #define thr_self thr_self 16 #define pthread_kill thr_kill 17 #define thr_kill thr_kill 18 19 #ifdef _REENTRANT 20 #ifndef MAX_THREAD_ID 21 #define MAX_THREAD_ID 500 22 #endif /* MAX_THREAD_ID */ 23 #else /* _REENTRANT */ 24 #ifndef MAX_THREAD_ID 25 #define MAX_THREAD_ID 1 26 #endif /* MAX_THREAD_ID */ 27 #endif /* _REENTRANT */ 28 29 #define COMPAT20 30 #define COMPAT30 31 #if defined(COMPAT20) || defined(COMPAT30) 32 #define COMPAT 33 #endif 34 35 #ifdef LDAP_DNS 36 #define LDAP_OPT_DNS 0x00000001 /* use DN & DNS */ 37 #endif /* LDAP_DNS */ 38 39 /* 40 #define DBG_LOCK1(st) printf("%d> %s %d:%s\n", thr_self(), st, __LINE__, __FILE__); 41 #define DBG_LOCK2(ld,st) printf("%d> %s ld_lockcount=%d %d:%s\n", thr_self(), st, (ld)->ld_lockcount, __LINE__, __FILE__); 42 */ 43 #define DBG_LOCK1(st) 44 #define DBG_LOCK2(ld,st) 45 46 extern pthread_t thr_self(); 47 #define LOCK_RESPONSE(ld) \ 48 if ((ld)->ld_response_lockthread != thr_self()) { \ 49 DBG_LOCK1("waiting for response lock") \ 50 pthread_mutex_lock( &((ld)->ld_response_mutex) ); \ 51 DBG_LOCK1("got response lock") \ 52 (ld)->ld_response_lockthread = thr_self(); \ 53 } else { \ 54 (ld)->ld_response_lockcount++; \ 55 DBG_LOCK2(ld, "fake ldap lock") \ 56 } 57 58 #define UNLOCK_RESPONSE(ld) \ 59 if ((ld)->ld_response_lockcount==0) { \ 60 (ld)->ld_response_lockthread = 0; \ 61 pthread_mutex_unlock( &((ld)->ld_response_mutex) ); \ 62 DBG_LOCK1("freed response lock") \ 63 } else { \ 64 (ld)->ld_response_lockcount--; \ 65 DBG_LOCK2(ld, "fake ldap unlock") \ 66 } 67 68 #define LOCK_LDAP(ld) \ 69 if ((ld)->ld_lockthread != thr_self()) { \ 70 DBG_LOCK1("waiting for ldap lock") \ 71 pthread_mutex_lock( &((ld)->ld_ldap_mutex) ); \ 72 DBG_LOCK1("got ldap lock") \ 73 (ld)->ld_lockthread = thr_self(); \ 74 } else { \ 75 (ld)->ld_lockcount++; \ 76 DBG_LOCK2(ld, "fake ldap lock") \ 77 } 78 79 #define UNLOCK_LDAP(ld) \ 80 if ((ld)->ld_lockcount==0) { \ 81 (ld)->ld_lockthread = 0; \ 82 pthread_mutex_unlock( &((ld)->ld_ldap_mutex) ); \ 83 DBG_LOCK1("freed ldap lock") \ 84 } else { \ 85 (ld)->ld_lockcount--; \ 86 DBG_LOCK2(ld, "fake ldap unlock") \ 87 } 88 89 #define LOCK_POLL(ld) pthread_mutex_lock( &ld->ld_poll_mutex ) 90 #define UNLOCK_POLL(ld) pthread_mutex_unlock( &ld->ld_poll_mutex ) 91 92 93 /* 94 * structure representing a Ber Element 95 */ 96 typedef struct berelement { 97 char *ber_buf; 98 char *ber_ptr; 99 char *ber_end; 100 struct seqorset *ber_sos; 101 unsigned int ber_tag; 102 unsigned int ber_len; 103 int ber_usertag; 104 char ber_options; 105 #define LBER_USE_DER 0x01 106 #define LBER_USE_INDEFINITE_LEN 0x02 107 #define LBER_TRANSLATE_STRINGS 0x04 108 char *ber_rwptr; 109 BERTranslateProc ber_encode_translate_proc; 110 BERTranslateProc ber_decode_translate_proc; 111 } _struct_BerElement; 112 113 114 /* 115 * This structure represents both ldap messages and ldap responses. 116 * These are really the same, except in the case of search responses, 117 * where a response has multiple messages. 118 */ 119 typedef struct ldapmsg { 120 int lm_msgid; /* the message id */ 121 int lm_msgtype; /* the message type */ 122 BerElement *lm_ber; /* the ber encoded message contents */ 123 struct ldapmsg *lm_chain; /* for search - next msg in the resp */ 124 struct ldapmsg *lm_next; /* next response */ 125 unsigned long lm_time; /* used to maintain cache */ 126 } _struct_LDAPMessage; 127 128 typedef struct ldap_filt_list { 129 char *lfl_tag; 130 char *lfl_pattern; 131 char *lfl_delims; 132 LDAPFiltInfo *lfl_ilist; 133 struct ldap_filt_list *lfl_next; 134 } _struct_FiltList; 135 136 typedef struct ldap_filt_desc { 137 LDAPFiltList *lfd_filtlist; 138 LDAPFiltInfo *lfd_curfip; 139 LDAPFiltInfo lfd_retfi; 140 char lfd_filter[ LDAP_FILT_MAXSIZ ]; 141 char *lfd_curval; 142 char *lfd_curvalcopy; 143 char **lfd_curvalwords; 144 char *lfd_filtprefix; 145 char *lfd_filtsuffix; 146 } _struct_FiltDesc; 147 148 /* 149 * structure for tracking LDAP server host, ports, DNs, etc. 150 */ 151 typedef struct ldap_server { 152 char *lsrv_host; 153 char *lsrv_dn; /* if NULL, use default */ 154 int lsrv_port; 155 struct ldap_server *lsrv_next; 156 } LDAPServer; 157 158 159 /* 160 * structure representing a Socket buffer 161 */ 162 typedef struct sockbuf { 163 #ifndef MACOS 164 int sb_sd; 165 #else /* MACOS */ 166 void *sb_sd; 167 #endif /* MACOS */ 168 BerElement sb_ber; 169 170 int sb_naddr; /* > 0 implies using CLDAP (UDP) */ 171 void *sb_useaddr; /* pointer to sockaddr to use next */ 172 void *sb_fromaddr; /* pointer to message source sockaddr */ 173 void **sb_addrs; /* actually an array of pointers to */ 174 /* sockaddrs */ 175 176 int sb_options; /* to support copying ber elements */ 177 #define LBER_TO_FILE 0x01 /* to a file referenced by sb_fd */ 178 #define LBER_TO_FILE_ONLY 0x02 /* only write to file, not network */ 179 #define LBER_MAX_INCOMING_SIZE 0x04 /* impose limit on incoming stuff */ 180 #define LBER_NO_READ_AHEAD 0x08 /* read only as much as requested */ 181 int sb_fd; 182 int sb_max_incoming; 183 #ifdef LDAP_SSL 184 int sb_ssl_tls; 185 SSL *sb_ssl; /* to support ldap over ssl */ 186 #endif /* LDAP_SSL */ 187 } Sockbuf; 188 #define READBUFSIZ 8192 189 190 191 /* 192 * structure for representing an LDAP server connection 193 */ 194 typedef struct ldap_conn { 195 Sockbuf *lconn_sb; 196 int lconn_refcnt; 197 unsigned long lconn_lastused; /* time */ 198 int lconn_status; 199 #define LDAP_CONNST_NEEDSOCKET 1 200 #define LDAP_CONNST_CONNECTING 2 201 #define LDAP_CONNST_CONNECTED 3 202 #define LDAP_CONNST_DEAD 4 203 LDAPServer *lconn_server; 204 char *lconn_krbinstance; 205 struct ldap_conn *lconn_next; 206 } LDAPConn; 207 208 /* 209 * Structure used to keep track of search references 210 */ 211 typedef struct ldap_reference { 212 char ** lref_refs; 213 struct ldap_reference *lref_next; 214 } LDAPRef; 215 216 217 218 /* 219 * structure used to track outstanding requests 220 */ 221 typedef struct ldapreq { 222 int lr_msgid; /* the message id */ 223 int lr_status; /* status of request */ 224 #define LDAP_REQST_INPROGRESS 1 225 #define LDAP_REQST_CHASINGREFS 2 226 #define LDAP_REQST_NOTCONNECTED 3 227 #define LDAP_REQST_WRITING 4 228 #define LDAP_REQST_CONNDEAD 5 229 int lr_outrefcnt; /* count of outstanding referrals */ 230 int lr_origid; /* original request's message id */ 231 int lr_parentcnt; /* count of parent requests */ 232 int lr_res_msgtype; /* result message type */ 233 int lr_res_errno; /* result LDAP errno */ 234 char *lr_res_error; /* result error string */ 235 char *lr_res_matched;/* result matched DN string */ 236 BerElement *lr_ber; /* ber encoded request contents */ 237 LDAPConn *lr_conn; /* connection used to send request */ 238 LDAPRef *lr_references; 239 char **lr_ref_followed; /* referral being followed */ 240 char **lr_ref_unfollowed; /* Not being followed */ 241 char **lr_ref_tofollow; /* referral to follow if the one being 242 followed fails. */ 243 struct ldapreq *lr_parent; /* request that spawned this referral */ 244 struct ldapreq *lr_refnext; /* next referral spawned */ 245 struct ldapreq *lr_prev; /* previous request */ 246 struct ldapreq *lr_next; /* next request */ 247 } LDAPRequest; 248 249 /* 250 * structure for client cache 251 */ 252 #define LDAP_CACHE_BUCKETS 31 /* cache hash table size */ 253 typedef struct ldapcache { 254 LDAPMessage *lc_buckets[LDAP_CACHE_BUCKETS];/* hash table */ 255 LDAPMessage *lc_requests; /* unfulfilled reqs */ 256 time_t lc_timeout; /* request timeout */ 257 ssize_t lc_maxmem; /* memory to use */ 258 ssize_t lc_memused; /* memory in use */ 259 int lc_enabled; /* enabled? */ 260 unsigned int lc_options; /* options */ 261 #define LDAP_CACHE_OPT_CACHENOERRS 0x00000001 262 #define LDAP_CACHE_OPT_CACHEALLERRS 0x00000002 263 } LDAPCache; 264 #define NULLLDCACHE ((LDAPCache *)NULL) 265 266 /* 267 * structure representing an ldap connection 268 */ 269 typedef struct ldap { 270 Sockbuf ld_sb; /* socket descriptor & buffer */ 271 char *ld_host; 272 int ld_version; 273 char ld_lberoptions; 274 int ld_deref; 275 276 int ld_timelimit; 277 int ld_sizelimit; 278 279 LDAPFiltDesc *ld_filtd; /* from getfilter for ufn searches */ 280 char *ld_ufnprefix; /* for incomplete ufn's */ 281 282 int ld_errno[MAX_THREAD_ID]; /* thread-specific */ 283 #define ld_errno ld_errno[ldap_thr_index()] 284 char *ld_error[MAX_THREAD_ID]; /* thread-specific */ 285 #define ld_error ld_error[ldap_thr_index()] 286 char *ld_matched[MAX_THREAD_ID]; /* thread-specific */ 287 #define ld_matched ld_matched[ldap_thr_index()] 288 char **ld_referrals[MAX_THREAD_ID]; /* thread-specific */ 289 #define ld_referrals ld_referrals[ldap_thr_index()] 290 LDAPControl **ld_ret_ctrls[MAX_THREAD_ID]; /* thread-specific */ 291 #define ld_ret_ctrls ld_ret_ctrls[ldap_thr_index()] 292 int ld_msgid; 293 294 int ld_follow_referral; /* flag set to true if lib follow referrals */ 295 LDAPRequest *ld_requests; /* list of outstanding requests -- referrals*/ 296 297 LDAPMessage *ld_responses; /* list of outstanding responses */ 298 int *ld_abandoned; /* array of abandoned requests */ 299 300 pthread_mutex_t ld_response_mutex; /* mutex for responses part of structure */ 301 pthread_t ld_response_lockthread; /* thread which currently holds the response lock */ 302 int ld_response_lockcount; /* response lock depth */ 303 304 char *ld_attrbuffer[MAX_THREAD_ID]; 305 #define ld_attrbuffer ld_attrbuffer[ldap_thr_index()] 306 LDAPCache *ld_cache; /* non-null if cache is initialized */ 307 char *ld_cldapdn; /* DN used in connectionless search */ 308 309 /* it is OK to change these next four values directly */ 310 int ld_cldaptries; /* connectionless search retry count */ 311 int ld_cldaptimeout;/* time between retries */ 312 int ld_refhoplimit; /* limit on referral nesting */ 313 /* LP TO CHANGE */ 314 char ld_restart; 315 #ifdef LDAP_SSL 316 int ld_use_ssl; 317 char *ld_ssl_key; 318 #endif 319 unsigned int ld_options; /* boolean options */ 320 321 /* do not mess with the rest though */ 322 char *ld_defhost; /* full name of default server */ 323 int ld_defport; /* port of default server */ 324 BERTranslateProc ld_lber_encode_translate_proc; 325 BERTranslateProc ld_lber_decode_translate_proc; 326 327 LDAPConn *ld_defconn; /* default connection */ 328 LDAPConn *ld_conns; /* list of server connections */ 329 void *ld_selectinfo; /* platform specifics for select */ 330 331 LDAP_REBIND_FUNCTION *ld_rebindproc; 332 void *ld_rebind_extra_arg; 333 /* int (*ld_rebindproc)( struct ldap *ld, char **dnp, */ 334 /* char **passwdp, int *authmethodp, int freeit ); */ 335 /* routine to get info needed for re-bind */ 336 337 pthread_mutex_t ld_ldap_mutex; /* mutex for thread dependent part of struct */ 338 pthread_t ld_lockthread; /* thread which currently holds the lock */ 339 int ld_lockcount; /* lock depth */ 340 pthread_mutex_t ld_poll_mutex; /* a seperate lock for polling */ 341 342 LDAPControl **ld_srvctrls; /* Controls used by ldap and server */ 343 LDAPControl **ld_cltctrls; /* Client side controls */ 344 345 /* KE: Lists of unsolicited notifications */ 346 LDAPMessage *ld_notifs[MAX_THREAD_ID]; 347 348 /* How long to wait for while connecting to a server */ 349 int ld_connect_timeout; 350 #define ld_notifs ld_notifs[ldap_thr_index()] 351 } _struct_LDAP; 352 353 354 /* 355 * handy macro to check whether LDAP struct is set up for CLDAP or not 356 */ 357 #define LDAP_IS_CLDAP( ld ) ( ld->ld_sb.sb_naddr > 0 ) 358 359 360 #endif /* _LDAP_PRIVATE_H */ 361