diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/libldap/msctrl.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/libraries/libldap/msctrl.c b/libraries/libldap/msctrl.c new file mode 100644 index 0000000..0f9264e --- /dev/null +++ b/libraries/libldap/msctrl.c @@ -0,0 +1,280 @@ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 1998-2022 The OpenLDAP Foundation. + * Portions Copyright 2018 Howard Chu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * <http://www.OpenLDAP.org/license.html>. + */ +/* ACKNOWLEDGEMENTS: + * This work was developed by Howard Chu for inclusion in + * OpenLDAP Software. + */ + +#include "portable.h" + +#include <stdio.h> +#include <ac/stdlib.h> +#include <ac/string.h> +#include <ac/time.h> + +#include "ldap-int.h" + +/* MS Active Directory controls - not implemented in slapd(8) */ + +#ifdef LDAP_CONTROL_X_DIRSYNC + +int +ldap_create_dirsync_value( + LDAP *ld, + int flags, + int maxAttrCount, + struct berval *cookie, + struct berval *value ) +{ + BerElement *ber = NULL; + ber_tag_t tag; + + if ( ld == NULL || cookie == NULL || + value == NULL ) + { + if ( ld ) { + ld->ld_errno = LDAP_PARAM_ERROR; + } + + return LDAP_PARAM_ERROR; + } + + assert( LDAP_VALID( ld ) ); + ld->ld_errno = LDAP_SUCCESS; + + /* maxAttrCount less than 0x100000 is treated as 0x100000 by server */ + + /* prepare value */ + value->bv_val = NULL; + value->bv_len = 0; + + ber = ldap_alloc_ber_with_options( ld ); + if ( ber == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; + } + + tag = ber_printf( ber, "{iiO}", flags, maxAttrCount, cookie ); + if ( tag == LBER_ERROR ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + goto done; + } + + if ( ber_flatten2( ber, value, 1 ) == -1 ) { + ld->ld_errno = LDAP_NO_MEMORY; + } + +done:; + if ( ber != NULL ) { + ber_free( ber, 1 ); + } + + return ld->ld_errno; +} + +int +ldap_create_dirsync_control( + LDAP *ld, + int flags, + int maxAttrCount, + struct berval *cookie, + LDAPControl **ctrlp ) +{ + struct berval value; + + if ( ctrlp == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + ld->ld_errno = ldap_create_dirsync_value( ld, + flags, maxAttrCount, cookie, &value ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_DIRSYNC, + 1, &value, 0, ctrlp ); + if ( ld->ld_errno != LDAP_SUCCESS ) { + LDAP_FREE( value.bv_val ); + } + } + + return ld->ld_errno; +} + +int +ldap_parse_dirsync_control( + LDAP *ld, + LDAPControl *ctrl, + int *continueFlag, + struct berval *cookie ) +{ + BerElement *ber; + ber_tag_t tag; + ber_len_t len; + int unused; + + if ( ld == NULL || + ctrl == NULL || + continueFlag == NULL || + cookie == NULL ) + { + if ( ld ) { + ld->ld_errno = LDAP_PARAM_ERROR; + } + + /* NOTE: we want the caller to get all or nothing; + * we could allow some of the pointers to be NULL, + * if one does not want part of the data */ + return LDAP_PARAM_ERROR; + } + + *continueFlag = 0; + BER_BVZERO( cookie ); + + ber = ber_init( &ctrl->ldctl_value ); + + if ( ber == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; + } + + tag = ber_scanf( ber, "{iio}", continueFlag, &unused, cookie ); + if ( tag == LBER_DEFAULT ) + tag = LBER_ERROR; + + (void)ber_free( ber, 1 ); + + if ( tag == LBER_ERROR ) { + return LDAP_DECODING_ERROR; + } + + return ld->ld_errno; +} + +#endif /* LDAP_CONTROL_X_DIRSYNC */ + +#ifdef LDAP_CONTROL_X_SHOW_DELETED + +int +ldap_create_show_deleted_control( LDAP *ld, + LDAPControl **ctrlp ) +{ + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( ctrlp != NULL ); + + ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SHOW_DELETED, + 0, NULL, 0, ctrlp ); + + return ld->ld_errno; +} + +#endif /* LDAP_CONTROL_X_SHOW_DELETED */ + +#ifdef LDAP_CONTROL_X_EXTENDED_DN + +int +ldap_create_extended_dn_value( + LDAP *ld, + int flag, + struct berval *value ) +{ + BerElement *ber = NULL; + ber_tag_t tag; + + if ( ld == NULL || + value == NULL ) + { + if ( ld ) { + ld->ld_errno = LDAP_PARAM_ERROR; + } + + return LDAP_PARAM_ERROR; + } + + assert( LDAP_VALID( ld ) ); + ld->ld_errno = LDAP_SUCCESS; + + /* prepare value */ + value->bv_val = NULL; + value->bv_len = 0; + + ber = ldap_alloc_ber_with_options( ld ); + if ( ber == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; + } + tag = ber_printf( ber, "{i}", flag ); + if ( tag == LBER_ERROR ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + goto done; + } + + if ( ber_flatten2( ber, value, 1 ) == -1 ) { + ld->ld_errno = LDAP_NO_MEMORY; + } + +done:; + if ( ber != NULL ) { + ber_free( ber, 1 ); + } + + return ld->ld_errno; +} + +int +ldap_create_extended_dn_control( + LDAP *ld, + int flag, + LDAPControl **ctrlp ) +{ + struct berval value; + + if ( ctrlp == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + return ld->ld_errno; + } + + ld->ld_errno = ldap_create_extended_dn_value( ld, flag, &value ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_EXTENDED_DN, + 0, &value, 0, ctrlp ); + if ( ld->ld_errno != LDAP_SUCCESS ) { + LDAP_FREE( value.bv_val ); + } + } + + return ld->ld_errno; +} + +#endif /* LDAP_CONTROL_X_EXTENDED_DN */ + +#ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION + +int +ldap_create_server_notification_control( LDAP *ld, + LDAPControl **ctrlp ) +{ + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( ctrlp != NULL ); + + ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SERVER_NOTIFICATION, + 0, NULL, 0, ctrlp ); + + return ld->ld_errno; +} + +#endif /* LDAP_CONTROL_X_SERVER_NOTIFICATION */ |