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