1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #ifndef	_LIBADUTILS_H
26 #define	_LIBADUTILS_H
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <rpc/rpc.h>
32 #include <ldap.h>
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 #define	ADUTILS_DEF_NUM_RETRIES	2
39 
40 /*
41  * Symbolic constants for different sets of debug messages.
42  */
43 enum ad_debug {
44 	AD_DEBUG_ALL = 0,
45 	AD_DEBUG_DNS = 1,
46 	AD_DEBUG_LDAP = 2,
47 	AD_DEBUG_DISC = 3,
48 	AD_DEBUG_MAX = 3
49 };
50 
51 #define	ADUTILS_SID_MAX_SUB_AUTHORITIES	15
52 #define	ADUTILS_MAXBINSID\
53 	(1 + 1 + 6 + (ADUTILS_SID_MAX_SUB_AUTHORITIES * 4))
54 #define	ADUTILS_MAXHEXBINSID	(ADUTILS_MAXBINSID * 3)
55 
56 typedef struct adutils_ad adutils_ad_t;
57 typedef struct adutils_entry adutils_entry_t;
58 typedef struct adutils_result adutils_result_t;
59 typedef struct adutils_ctx adutils_ctx_t;
60 typedef struct adutils_query_state adutils_query_state_t;
61 
62 /*
63  * Typedef for callback routine for adutils_lookup_batch_start.
64  * This callback routine is used to process the result of
65  * ldap_result(3LDAP).
66  *	ld   - LDAP handle used by ldap_result(3LDAP)
67  *	res  - Entry returned by ldap_result(3LDAP)
68  *	rc   - Return value of ldap_result(3LDAP)
69  *	qid  - Query ID that corresponds to the result.
70  *	argp - Argument passed by the caller at the time
71  *	       of adutils_lookup_batch_start.
72  */
73 typedef void (*adutils_ldap_res_search_cb)(LDAP *ld, LDAPMessage **res,
74 	int rc, int qid, void *argp);
75 
76 typedef enum {
77 	ADUTILS_SUCCESS = 0,
78 	ADUTILS_ERR_INTERNAL = -10000,
79 	ADUTILS_ERR_OTHER,
80 	ADUTILS_ERR_NOTFOUND,
81 	ADUTILS_ERR_RETRIABLE_NET_ERR,
82 	ADUTILS_ERR_MEMORY,
83 	ADUTILS_ERR_DOMAIN
84 } adutils_rc;
85 
86 /*
87  * We use the port numbers for normal LDAP and global catalog LDAP as
88  * the enum values for this enumeration.  Clever?  Silly?  You decide.
89  * Although we never actually use these enum values as port numbers and
90  * never will, so this is just cute.
91  */
92 typedef enum adutils_ad_partition {
93 	ADUTILS_AD_DATA = 389,
94 	ADUTILS_AD_GLOBAL_CATALOG = 3268
95 } adutils_ad_partition_t;
96 
97 
98 /*
99  * adutils interfaces:
100  *
101  *  - an adutils_ad_t represents an AD partition
102  *  - a DS (hostname + port, if port != 0) can be added/removed from an
103  *  adutils_ad_t
104  *  - an adutils_ad_t can be allocated, ref'ed and released; last release
105  *  releases resources
106  *
107  *
108  * adutils_lookup_batch_xxx interfaces:
109  *
110  * These interfaces allow the caller to batch AD lookup requests. The
111  * batched requests are processed asynchronously. The actual lookup
112  * is currently implement using libldap's ldap_search_ext(3LDAP) and
113  * ldap_result(3LDAP) APIs.
114  *
115  *	Example:
116  *      	adutils_query_state_t	*qs;
117  *      	adutils_lookup_batch_start(..., &qs);
118  *		for each request {
119  *			rc = adutils_lookup_batch_add(qs, ...);
120  *			if (rc != success)
121  *				break;
122  *		}
123  *		if (rc == success)
124  *			adutils_lookup_batch_end(&qs);
125  *		else
126  *			adutils_lookup_batch_release(&qs);
127  *
128  *	The adutils_lookup_batch_start interface allows the caller to pass
129  *	in a callback function that's invoked when ldap_result() returns
130  *	LDAP_RES_SEARCH_RESULT and LDAP_RES_SEARCH_ENTRY for each request.
131  *
132  *	If no callback is provided then adutils batch API falls back to its
133  *	default behaviour which is:
134  *		For LDAP_RES_SEARCH_ENTRY, add the entry to the entry set.
135  *		For LDAP_RES_SEARCH_RESULT, set return code to
136  *			ADUTILS_ERR_NOTFOUND if the entry set is empty.
137  *
138  *	See $SRC/cmd/idmap/idmapd/adutils.c for an example of
139  *      non-default callback routine.
140  *
141  */
142 
143 typedef void (*adutils_logger)(int, const char *, ...);
144 
145 extern void		adutils_set_debug(enum ad_debug item, int val);
146 
147 extern adutils_rc	adutils_ad_alloc(adutils_ad_t **new_ad,
148 				const char *domain_name,
149 				adutils_ad_partition_t part);
150 extern void		adutils_ad_free(adutils_ad_t **ad);
151 extern adutils_rc	adutils_add_ds(adutils_ad_t *ad,
152 				const char *host, int port);
153 extern adutils_rc	adutils_add_domain(adutils_ad_t *ad,
154 				const char *domain_name,
155 				const char *domain_sid);
156 extern void		adutils_freeresult(adutils_result_t **result);
157 extern adutils_rc	adutils_lookup(adutils_ad_t *ad,
158 				const char *searchfilter,
159 				const char **attrs, const char *domain,
160 				adutils_result_t **result);
161 extern char		**adutils_getattr(const adutils_entry_t *entry,
162 				const char *attrname);
163 extern const adutils_entry_t	*adutils_getfirstentry(
164 					adutils_result_t *result);
165 extern int		adutils_txtsid2hexbinsid(const char *txt,
166 				const uint32_t *rid,
167 				char *hexbinsid, int hexbinsidlen);
168 extern char		*adutils_bv_str(BerValue *bval);
169 extern boolean_t	adutils_bv_uint(BerValue *bval, unsigned int *result);
170 extern char		*adutils_bv_objsid2sidstr(BerValue *bval,
171 				uint32_t *rid);
172 extern void		adutils_reap_idle_connections(void);
173 extern char		*adutils_dn2dns(const char *dn);
174 extern adutils_rc	adutils_lookup_batch_start(adutils_ad_t *ad,
175 				int nqueries,
176 				adutils_ldap_res_search_cb ldap_res_search_cb,
177 				void *ldap_res_search_argp,
178 				adutils_query_state_t **state);
179 extern adutils_rc	adutils_lookup_batch_add(adutils_query_state_t *state,
180 				const char *filter, const char * const *attrs,
181 				const char *edomain, adutils_result_t **result,
182 				adutils_rc *rc);
183 extern adutils_rc	adutils_lookup_batch_end(
184 				adutils_query_state_t **state);
185 extern void		adutils_lookup_batch_release(
186 				adutils_query_state_t **state);
187 extern int		adutils_lookup_check_domain(
188 				adutils_query_state_t *state,
189 				const char *domain);
190 extern int		adutils_lookup_check_sid_prefix(
191 				adutils_query_state_t *state,
192 				const char *sid);
193 extern void		adutils_set_logger(adutils_logger logger);
194 
195 extern boolean_t	domain_eq(const char *a, const char *b);
196 
197 #ifdef	__cplusplus
198 }
199 #endif
200 
201 #endif	/* _LIBADUTILS_H */
202