1/*	$OpenBSD: aldap.h,v 1.15 2022/10/13 04:55:33 jmatthew Exp $ */
2
3/*
4 * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
5 * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <stdio.h>
21
22#include <ber.h>
23#include <tls.h>
24
25#define LDAP_URL 		"ldap://"
26#define LDAPS_URL 		"ldaps://"
27#define LDAPTLS_URL 		"ldap+tls://"
28#define LDAPI_URL 		"ldapi://"
29
30#define LDAP_PORT 		389
31#define LDAPS_PORT 		636
32#define LDAP_PAGED_OID		"1.2.840.113556.1.4.319"
33#define LDAP_STARTTLS_OID	"1.3.6.1.4.1.1466.20037"
34
35#define LDAP_SASL_MECH_EXTERNAL	"EXTERNAL"
36
37struct aldap {
38#define ALDAP_ERR_SUCCESS		0
39#define ALDAP_ERR_PARSER_ERROR		1
40#define ALDAP_ERR_INVALID_FILTER	2
41#define ALDAP_ERR_OPERATION_FAILED	3
42#define ALDAP_ERR_TLS_ERROR		4
43	u_int8_t	err;
44	int		msgid;
45	struct ber	ber;
46
47	int		fd;
48	struct tls	*tls;
49
50	struct evbuffer *buf;
51};
52
53struct aldap_page_control {
54	int size;
55	char *cookie;
56	unsigned int cookie_len;
57};
58
59struct aldap_message {
60	int msgid;
61	int message_type;
62
63	struct ber_element	*msg;
64
65	struct ber_element	*header;
66	struct ber_element	*protocol_op;
67
68	struct ber_element	*dn;
69
70	union {
71		struct {
72			long long		 rescode;
73			struct ber_element	*diagmsg;
74		}			 res;
75		struct {
76			struct ber_element	*iter;
77			struct ber_element	*attrs;
78		}			 search;
79	} body;
80	struct ber_element	*references;
81	struct aldap_page_control *page;
82};
83
84enum aldap_protocol {
85	LDAP,
86	LDAPS,
87	LDAPTLS,
88	LDAPI
89};
90
91struct aldap_stringset {
92	size_t			 len;
93	struct ber_octetstring	*str;
94};
95
96struct aldap_url {
97	int		 protocol;
98	char		*host;
99	in_port_t	 port;
100	char		*dn;
101#define MAXATTR 1024
102	char		*attributes[MAXATTR];
103	int		 scope;
104	char		*filter;
105	char		*buffer;
106};
107
108enum protocol_op {
109	LDAP_REQ_BIND		= 0,
110	LDAP_RES_BIND		= 1,
111	LDAP_REQ_UNBIND_30	= 2,
112	LDAP_REQ_SEARCH		= 3,
113	LDAP_RES_SEARCH_ENTRY	= 4,
114	LDAP_RES_SEARCH_RESULT	= 5,
115	LDAP_REQ_MODIFY		= 6,
116	LDAP_RES_MODIFY		= 7,
117	LDAP_REQ_ADD		= 8,
118	LDAP_RES_ADD		= 9,
119	LDAP_REQ_DELETE_30	= 10,
120	LDAP_RES_DELETE		= 11,
121	LDAP_REQ_MODRDN		= 12,
122	LDAP_RES_MODRDN		= 13,
123	LDAP_REQ_COMPARE	= 14,
124	LDAP_RES_COMPARE	= 15,
125	LDAP_REQ_ABANDON_30	= 16,
126
127	LDAP_RES_SEARCH_REFERENCE = 19,
128
129	LDAP_REQ_EXTENDED	= 23,
130	LDAP_RES_EXTENDED	= 24
131};
132
133enum deref_aliases {
134	LDAP_DEREF_NEVER	= 0,
135	LDAP_DEREF_SEARCHING	= 1,
136	LDAP_DEREF_FINDING	= 2,
137	LDAP_DEREF_ALWAYS	= 3,
138};
139
140enum authentication_choice {
141	LDAP_AUTH_SIMPLE	= 0,
142	LDAP_AUTH_SASL		= 3,
143};
144
145enum scope {
146	LDAP_SCOPE_BASE		= 0,
147	LDAP_SCOPE_ONELEVEL	= 1,
148	LDAP_SCOPE_SUBTREE	= 2,
149};
150
151enum result_code {
152	LDAP_SUCCESS				= 0,
153	LDAP_OPERATIONS_ERROR			= 1,
154	LDAP_PROTOCOL_ERROR			= 2,
155	LDAP_TIMELIMIT_EXCEEDED			= 3,
156	LDAP_SIZELIMIT_EXCEEDED			= 4,
157	LDAP_COMPARE_FALSE			= 5,
158	LDAP_COMPARE_TRUE			= 6,
159	LDAP_STRONG_AUTH_NOT_SUPPORTED		= 7,
160	LDAP_STRONG_AUTH_REQUIRED		= 8,
161
162	LDAP_REFERRAL				= 10,
163	LDAP_ADMINLIMIT_EXCEEDED		= 11,
164	LDAP_UNAVAILABLE_CRITICAL_EXTENSION	= 12,
165	LDAP_CONFIDENTIALITY_REQUIRED		= 13,
166	LDAP_SASL_BIND_IN_PROGRESS		= 14,
167	LDAP_NO_SUCH_ATTRIBUTE			= 16,
168	LDAP_UNDEFINED_TYPE			= 17,
169	LDAP_INAPPROPRIATE_MATCHING		= 18,
170	LDAP_CONSTRAINT_VIOLATION		= 19,
171	LDAP_TYPE_OR_VALUE_EXISTS		= 20,
172	LDAP_INVALID_SYNTAX			= 21,
173
174	LDAP_NO_SUCH_OBJECT			= 32,
175	LDAP_ALIAS_PROBLEM			= 33,
176	LDAP_INVALID_DN_SYNTAX			= 34,
177
178	LDAP_ALIAS_DEREF_PROBLEM		= 36,
179
180	LDAP_INAPPROPRIATE_AUTH			= 48,
181	LDAP_INVALID_CREDENTIALS		= 49,
182	LDAP_INSUFFICIENT_ACCESS		= 50,
183	LDAP_BUSY				= 51,
184	LDAP_UNAVAILABLE			= 52,
185	LDAP_UNWILLING_TO_PERFORM		= 53,
186	LDAP_LOOP_DETECT			= 54,
187
188	LDAP_NAMING_VIOLATION			= 64,
189	LDAP_OBJECT_CLASS_VIOLATION		= 65,
190	LDAP_NOT_ALLOWED_ON_NONLEAF		= 66,
191	LDAP_NOT_ALLOWED_ON_RDN			= 67,
192	LDAP_ALREADY_EXISTS			= 68,
193	LDAP_NO_OBJECT_CLASS_MODS		= 69,
194
195	LDAP_AFFECTS_MULTIPLE_DSAS		= 71,
196
197	LDAP_OTHER				= 80,
198};
199
200enum filter {
201	LDAP_FILT_AND		= 0,
202	LDAP_FILT_OR		= 1,
203	LDAP_FILT_NOT		= 2,
204	LDAP_FILT_EQ		= 3,
205	LDAP_FILT_SUBS		= 4,
206	LDAP_FILT_GE		= 5,
207	LDAP_FILT_LE		= 6,
208	LDAP_FILT_PRES		= 7,
209	LDAP_FILT_APPR		= 8,
210};
211
212enum subfilter {
213	LDAP_FILT_SUBS_INIT	= 0,
214	LDAP_FILT_SUBS_ANY	= 1,
215	LDAP_FILT_SUBS_FIN	= 2,
216};
217
218struct aldap		*aldap_init(int);
219int			 aldap_tls(struct aldap *, struct tls_config *,
220			    const char *);
221int			 aldap_close(struct aldap *);
222struct aldap_message	*aldap_parse(struct aldap *);
223void			 aldap_freemsg(struct aldap_message *);
224
225int	 		 aldap_req_starttls(struct aldap *);
226
227int	 aldap_bind(struct aldap *, char *, char *);
228int	 aldap_bind_sasl_external(struct aldap *, char *);
229int	 aldap_unbind(struct aldap *);
230int	 aldap_search(struct aldap *, char *, enum scope, char *, char **, int, int, int, struct aldap_page_control *);
231int	 aldap_get_errno(struct aldap *, const char **);
232
233int	 aldap_get_resultcode(struct aldap_message *);
234char	*aldap_get_dn(struct aldap_message *);
235char	*aldap_get_diagmsg(struct aldap_message *);
236struct aldap_stringset	*aldap_get_references(struct aldap_message *);
237void	 aldap_free_references(char **values);
238int	 aldap_parse_url(const char *, struct aldap_url *);
239void	 aldap_free_url(struct aldap_url *);
240int	 aldap_search_url(struct aldap *, char *, int, int, int,
241	    struct aldap_page_control *);
242
243int	 aldap_count_attrs(struct aldap_message *);
244int	 aldap_match_attr(struct aldap_message *, char *,
245	    struct aldap_stringset **);
246int	 aldap_first_attr(struct aldap_message *, char **, struct
247	    aldap_stringset **);
248int	 aldap_next_attr(struct aldap_message *, char **,
249	    struct aldap_stringset **);
250int	 aldap_free_attr(struct aldap_stringset *);
251
252struct aldap_page_control *aldap_parse_page_control(struct ber_element *, size_t len);
253void	 aldap_freepage(struct aldap_page_control *);
254