xref: /onnv-gate/usr/src/lib/libldap4/include/ldap-private.h (revision 6812:febeba71273d)
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