2018-11-18 10:33:41 +08:00
|
|
|
/* $OpenLDAP$ */
|
|
|
|
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
|
|
*
|
2019-01-15 02:46:16 +08:00
|
|
|
* Copyright 1998-2019 The OpenLDAP Foundation.
|
2018-11-18 10:33:41 +08:00
|
|
|
* 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,
|
2018-11-18 10:47:21 +08:00
|
|
|
1, &value, 0, ctrlp );
|
2018-11-18 10:33:41 +08:00
|
|
|
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 */
|
2018-12-13 21:44:46 +08:00
|
|
|
|
|
|
|
#ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
|
|
|
|
|
|
|
|
int
|
|
|
|
ldap_create_sever_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 */
|