xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/msctrl.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: msctrl.c,v 1.2 2021/08/14 16:14:56 christos Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2021 The OpenLDAP Foundation.
7  * Portions Copyright 2018 Howard Chu.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 /* ACKNOWLEDGEMENTS:
19  * This work was developed by Howard Chu for inclusion in
20  * OpenLDAP Software.
21  */
22 
23 #include <sys/cdefs.h>
24 __RCSID("$NetBSD: msctrl.c,v 1.2 2021/08/14 16:14:56 christos Exp $");
25 
26 #include "portable.h"
27 
28 #include <stdio.h>
29 #include <ac/stdlib.h>
30 #include <ac/string.h>
31 #include <ac/time.h>
32 
33 #include "ldap-int.h"
34 
35 /* MS Active Directory controls - not implemented in slapd(8) */
36 
37 #ifdef LDAP_CONTROL_X_DIRSYNC
38 
39 int
ldap_create_dirsync_value(LDAP * ld,int flags,int maxAttrCount,struct berval * cookie,struct berval * value)40 ldap_create_dirsync_value(
41 	LDAP		*ld,
42 	int		flags,
43 	int		maxAttrCount,
44 	struct berval	*cookie,
45 	struct berval	*value )
46 {
47 	BerElement	*ber = NULL;
48 	ber_tag_t	tag;
49 
50 	if ( ld == NULL || cookie == NULL ||
51 		value == NULL )
52 	{
53 		if ( ld ) {
54 			ld->ld_errno = LDAP_PARAM_ERROR;
55 		}
56 
57 		return LDAP_PARAM_ERROR;
58 	}
59 
60 	assert( LDAP_VALID( ld ) );
61 	ld->ld_errno = LDAP_SUCCESS;
62 
63 	/* maxAttrCount less than 0x100000 is treated as 0x100000 by server */
64 
65 	/* prepare value */
66 	value->bv_val = NULL;
67 	value->bv_len = 0;
68 
69 	ber = ldap_alloc_ber_with_options( ld );
70 	if ( ber == NULL ) {
71 		ld->ld_errno = LDAP_NO_MEMORY;
72 		return ld->ld_errno;
73 	}
74 
75 	tag = ber_printf( ber, "{iiO}", flags, maxAttrCount, cookie );
76 	if ( tag == LBER_ERROR ) {
77 		ld->ld_errno = LDAP_ENCODING_ERROR;
78 		goto done;
79 	}
80 
81 	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
82 		ld->ld_errno = LDAP_NO_MEMORY;
83 	}
84 
85 done:;
86 	if ( ber != NULL ) {
87 		ber_free( ber, 1 );
88 	}
89 
90 	return ld->ld_errno;
91 }
92 
93 int
ldap_create_dirsync_control(LDAP * ld,int flags,int maxAttrCount,struct berval * cookie,LDAPControl ** ctrlp)94 ldap_create_dirsync_control(
95 	LDAP		*ld,
96 	int			flags,
97 	int			maxAttrCount,
98 	struct berval	*cookie,
99 	LDAPControl	**ctrlp )
100 {
101 	struct berval	value;
102 
103 	if ( ctrlp == NULL ) {
104 		ld->ld_errno = LDAP_PARAM_ERROR;
105 		return ld->ld_errno;
106 	}
107 
108 	ld->ld_errno = ldap_create_dirsync_value( ld,
109 		flags, maxAttrCount, cookie, &value );
110 	if ( ld->ld_errno == LDAP_SUCCESS ) {
111 		ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_DIRSYNC,
112 			1, &value, 0, ctrlp );
113 		if ( ld->ld_errno != LDAP_SUCCESS ) {
114 			LDAP_FREE( value.bv_val );
115 		}
116 	}
117 
118 	return ld->ld_errno;
119 }
120 
121 int
ldap_parse_dirsync_control(LDAP * ld,LDAPControl * ctrl,int * continueFlag,struct berval * cookie)122 ldap_parse_dirsync_control(
123 	LDAP *ld,
124 	LDAPControl *ctrl,
125 	int *continueFlag,
126 	struct berval *cookie )
127 {
128 	BerElement	*ber;
129 	ber_tag_t	tag;
130 	ber_len_t	len;
131 	int unused;
132 
133 	if ( ld == NULL ||
134 		ctrl == NULL ||
135 		continueFlag == NULL ||
136 		cookie == NULL )
137 	{
138 		if ( ld ) {
139 			ld->ld_errno = LDAP_PARAM_ERROR;
140 		}
141 
142 		/* NOTE: we want the caller to get all or nothing;
143 		 * we could allow some of the pointers to be NULL,
144 		 * if one does not want part of the data */
145 		return LDAP_PARAM_ERROR;
146 	}
147 
148 	*continueFlag = 0;
149 	BER_BVZERO( cookie );
150 
151 	ber = ber_init( &ctrl->ldctl_value );
152 
153 	if ( ber == NULL ) {
154 		ld->ld_errno = LDAP_NO_MEMORY;
155 		return ld->ld_errno;
156 	}
157 
158 	tag = ber_scanf( ber, "{iio}", continueFlag, &unused, cookie );
159 	if ( tag == LBER_DEFAULT )
160 		tag = LBER_ERROR;
161 
162 	(void)ber_free( ber, 1 );
163 
164 	if ( tag == LBER_ERROR ) {
165 		return LDAP_DECODING_ERROR;
166 	}
167 
168 	return ld->ld_errno;
169 }
170 
171 #endif /* LDAP_CONTROL_X_DIRSYNC */
172 
173 #ifdef LDAP_CONTROL_X_SHOW_DELETED
174 
175 int
ldap_create_show_deleted_control(LDAP * ld,LDAPControl ** ctrlp)176 ldap_create_show_deleted_control( LDAP *ld,
177                                     LDAPControl **ctrlp )
178 {
179 	assert( ld != NULL );
180 	assert( LDAP_VALID( ld ) );
181 	assert( ctrlp != NULL );
182 
183 	ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SHOW_DELETED,
184 		0, NULL, 0, ctrlp );
185 
186 	return ld->ld_errno;
187 }
188 
189 #endif /* LDAP_CONTROL_X_SHOW_DELETED */
190 
191 #ifdef LDAP_CONTROL_X_EXTENDED_DN
192 
193 int
ldap_create_extended_dn_value(LDAP * ld,int flag,struct berval * value)194 ldap_create_extended_dn_value(
195 	LDAP		*ld,
196 	int			flag,
197 	struct berval	*value )
198 {
199 	BerElement	*ber = NULL;
200 	ber_tag_t	tag;
201 
202 	if ( ld == NULL ||
203 		value == NULL )
204 	{
205 		if ( ld ) {
206 			ld->ld_errno = LDAP_PARAM_ERROR;
207 		}
208 
209 		return LDAP_PARAM_ERROR;
210 	}
211 
212 	assert( LDAP_VALID( ld ) );
213 	ld->ld_errno = LDAP_SUCCESS;
214 
215 	/* prepare value */
216 	value->bv_val = NULL;
217 	value->bv_len = 0;
218 
219 	ber = ldap_alloc_ber_with_options( ld );
220 	if ( ber == NULL ) {
221 		ld->ld_errno = LDAP_NO_MEMORY;
222 		return ld->ld_errno;
223 	}
224 	tag = ber_printf( ber, "{i}", flag );
225 	if ( tag == LBER_ERROR ) {
226 		ld->ld_errno = LDAP_ENCODING_ERROR;
227 		goto done;
228 	}
229 
230 	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
231 		ld->ld_errno = LDAP_NO_MEMORY;
232 	}
233 
234 done:;
235 	if ( ber != NULL ) {
236 		ber_free( ber, 1 );
237 	}
238 
239 	return ld->ld_errno;
240 }
241 
242 int
ldap_create_extended_dn_control(LDAP * ld,int flag,LDAPControl ** ctrlp)243 ldap_create_extended_dn_control(
244 	LDAP		*ld,
245 	int			flag,
246 	LDAPControl	**ctrlp )
247 {
248 	struct berval	value;
249 
250 	if ( ctrlp == NULL ) {
251 		ld->ld_errno = LDAP_PARAM_ERROR;
252 		return ld->ld_errno;
253 	}
254 
255 	ld->ld_errno = ldap_create_extended_dn_value( ld, flag, &value );
256 	if ( ld->ld_errno == LDAP_SUCCESS ) {
257 		ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_EXTENDED_DN,
258 			0, &value, 0, ctrlp );
259 		if ( ld->ld_errno != LDAP_SUCCESS ) {
260 			LDAP_FREE( value.bv_val );
261 		}
262 	}
263 
264 	return ld->ld_errno;
265 }
266 
267 #endif /* LDAP_CONTROL_X_EXTENDED_DN */
268 
269 #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
270 
271 int
ldap_create_server_notification_control(LDAP * ld,LDAPControl ** ctrlp)272 ldap_create_server_notification_control( LDAP *ld,
273                                     LDAPControl **ctrlp )
274 {
275 	assert( ld != NULL );
276 	assert( LDAP_VALID( ld ) );
277 	assert( ctrlp != NULL );
278 
279 	ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SERVER_NOTIFICATION,
280 		0, NULL, 0, ctrlp );
281 
282 	return ld->ld_errno;
283 }
284 
285 #endif /* LDAP_CONTROL_X_SERVER_NOTIFICATION */
286