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