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