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 39int 40ldap_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 85done:; 86 if ( ber != NULL ) { 87 ber_free( ber, 1 ); 88 } 89 90 return ld->ld_errno; 91} 92 93int 94ldap_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 121int 122ldap_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 175int 176ldap_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 193int 194ldap_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 234done:; 235 if ( ber != NULL ) { 236 ber_free( ber, 1 ); 237 } 238 239 return ld->ld_errno; 240} 241 242int 243ldap_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 271int 272ldap_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