summaryrefslogtreecommitdiffstats
path: root/libraries/libldap/msctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/libldap/msctrl.c')
-rw-r--r--libraries/libldap/msctrl.c280
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 */