Commit bb6b474b authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#5768

parent 358eb874
OpenLDAP 2.4 Change Log
OpenLDAP 2.4.13 Engineering
Added libldap dereference control support (ITS#5768)
Fixed liblutil hex conversion (ITS#5699)
Fixed liblutil returning undefined data (ITS#5748)
Fixed libldap error code return (ITS#5762)
......@@ -36,6 +37,7 @@ OpenLDAP 2.4.13 Engineering
Build Environment
Added ldapurl command
Added slapd GSSAPI refactoring (ITS#5369)
Added slapo-deref overlay (ITS#5768)
Documentation
admin24 added olcLimits to example (ITS#5746)
......
......@@ -135,6 +135,9 @@ static int print_paged_results( LDAP *ld, LDAPControl *ctrl );
static int print_ppolicy( LDAP *ld, LDAPControl *ctrl );
#endif
static int print_sss( LDAP *ld, LDAPControl *ctrl );
#ifdef LDAP_CONTROL_X_DEREF
static int print_deref( LDAP *ld, LDAPControl *ctrl );
#endif
static struct tool_ctrls_t {
const char *oid;
......@@ -148,6 +151,9 @@ static struct tool_ctrls_t {
{ LDAP_CONTROL_PASSWORDPOLICYRESPONSE, TOOL_ALL, print_ppolicy },
#endif
{ LDAP_CONTROL_SORTRESPONSE, TOOL_SEARCH, print_sss },
#ifdef LDAP_CONTROL_X_DEREF
{ LDAP_CONTROL_X_DEREF, TOOL_SEARCH, print_deref },
#endif
{ NULL, 0, NULL }
};
......@@ -1890,6 +1896,76 @@ print_sss( LDAP *ld, LDAPControl *ctrl )
return rc;
}
#ifdef LDAP_CONTROL_X_DEREF
static int
print_deref( LDAP *ld, LDAPControl *ctrl )
{
LDAPDerefRes *drhead = NULL, *dr;
int rc;
rc = ldap_parse_derefresponse_control( ld, ctrl, &drhead );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
for ( dr = drhead; dr != NULL; dr = dr->next ) {
LDAPDerefVal *dv;
ber_len_t len;
char *buf, *ptr;
len = strlen( dr->derefAttr ) + STRLENOF(": ");
for ( dv = dr->attrVals; dv != NULL; dv = dv->next ) {
if ( dv->vals != NULL ) {
int j;
ber_len_t tlen = strlen(dv->type);
for ( j = 0; dv->vals[ j ].bv_val != NULL; j++ ) {
len += STRLENOF("<=>;") + tlen + dv->vals[ j ].bv_len;
}
}
}
len += dr->derefVal.bv_len;
buf = ldap_memalloc( len + 1 );
if ( buf == NULL ) {
rc = LDAP_NO_MEMORY;
goto done;
}
ptr = buf;
ptr = lutil_strcopy( ptr, dr->derefAttr );
*ptr++ = ':';
*ptr++ = ' ';
for ( dv = dr->attrVals; dv != NULL; dv = dv->next ) {
if ( dv->vals != NULL ) {
int j;
for ( j = 0; dv->vals[ j ].bv_val != NULL; j++ ) {
*ptr++ = '<';
ptr = lutil_strcopy( ptr, dv->type );
*ptr++ = '=';
ptr = lutil_strncopy( ptr, dv->vals[ j ].bv_val, dv->vals[ j ].bv_len );
*ptr++ = '>';
*ptr++ = ';';
}
}
}
ptr = lutil_strncopy( ptr, dr->derefVal.bv_val, dr->derefVal.bv_len );
*ptr++ = '\0';
tool_write_ldif( LDIF_PUT_COMMENT, NULL, buf, len );
ldap_memfree( buf );
}
rc = LDAP_SUCCESS;
done:;
ldap_derefresponse_free( drhead );
return rc;
}
#endif
#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
static int
print_ppolicy( LDAP *ld, LDAPControl *ctrl )
......
......@@ -133,6 +133,9 @@ usage( void )
fprintf( stderr, _(" [!]subentries[=true|false] (RFC 3672 subentries)\n"));
fprintf( stderr, _(" [!]sync=ro[/<cookie>] (RFC 4533 LDAP Sync refreshOnly)\n"));
fprintf( stderr, _(" rp[/<cookie>][/<slimit>] (refreshAndPersist)\n"));
#ifdef LDAP_CONTROL_X_DEREF
fprintf( stderr, _(" [!]deref=derefAttr:attr[,...][;derefAttr:attr[,...][;...]]\n"));
#endif
fprintf( stderr, _(" [!]<oid>=:<value> (generic control; no response handling)\n"));
fprintf( stderr, _(" -F prefix URL prefix for files (default: %s)\n"), def_urlpre);
fprintf( stderr, _(" -l limit time limit (in seconds, or \"none\" or \"max\") for search\n"));
......@@ -223,6 +226,12 @@ static LDAPControl *c = NULL;
static int nctrls = 0;
static int save_nctrls = 0;
#ifdef LDAP_CONTROL_X_DEREF
static int derefcrit;
static LDAPDerefSpec *ds;
static struct berval derefval;
#endif
static int
ctrl_add( void )
{
......@@ -491,6 +500,43 @@ handle_private_option( int i )
}
if ( crit ) ldapsync *= -1;
#ifdef LDAP_CONTROL_X_DEREF
} else if ( strcasecmp( control, "deref" ) == 0 ) {
int ispecs;
char **specs;
/* cvalue is something like
*
* derefAttr:attr[,attr[...]][;derefAttr:attr[,attr[...]]]"
*/
specs = ldap_str2charray( cvalue, ";" );
for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ )
/* count'em */
ds = ldap_memcalloc( ispecs + 1, sizeof( LDAPDerefSpec ) );
if ( ds == NULL ) {
/* error */
}
for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ ) {
char *ptr;
ptr = strchr( specs[ ispecs ], ':' );
if ( ptr == NULL ) {
/* error */
}
ds[ ispecs ].derefAttr = specs[ ispecs ];
*ptr++ = '\0';
ds[ ispecs ].attributes = ldap_str2charray( ptr, "," );
}
derefcrit = 1 + crit;
ldap_memfree( specs );
#endif /* LDAP_CONTROL_X_DEREF */
} else if ( tool_is_oid( control ) ) {
if ( ctrl_add() ) {
exit( EXIT_FAILURE );
......@@ -780,6 +826,9 @@ getNextPage:
if ( nctrls > 0
#ifdef LDAP_CONTROL_DONTUSECOPY
|| dontUseCopy
#endif
#ifdef LDAP_CONTROL_X_DEREF
|| derefcrit
#endif
|| domainScope
|| pagedResults
......@@ -933,6 +982,32 @@ getNextPage:
c[i].ldctl_iscritical = sss > 1;
i++;
}
#ifdef LDAP_CONTROL_X_DEREF
if ( ds ) {
if ( derefval.bv_val == NULL ) {
int i;
if ( ldap_create_deref_control_value( ld, ds, &derefval ) != LDAP_SUCCESS ) {
return EXIT_FAILURE;
}
for ( i = 0; ds[ i ].derefAttr != NULL; i++ ) {
ldap_memfree( ds[ i ].derefAttr );
ldap_charray_free( ds[ i ].attributes );
}
ldap_memfree( ds );
}
if ( ctrl_add() ) {
exit( EXIT_FAILURE );
}
c[ i ].ldctl_iscritical = derefcrit > 1;
c[ i ].ldctl_oid = LDAP_CONTROL_X_DEREF;
c[ i ].ldctl_value = derefval;
i++;
}
#endif /* LDAP_CONTROL_X_DEREF */
}
tool_server_controls( ld, c, i );
......@@ -1019,6 +1094,12 @@ getNextPage:
printf(_("\n# with server side sorting %scontrol"),
sss > 1 ? _("critical ") : "" );
}
#ifdef LDAP_CONTROL_X_DEREF
if ( sss ) {
printf(_("\n# with dereference %scontrol"),
sss > 1 ? _("critical ") : "" );
}
#endif
printf( _("\n#\n\n") );
......
#! /bin/sh
# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.631.2.14 2008/09/17 22:54:33 quanah Exp .
# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.631.2.15 2008/11/08 00:14:44 quanah Exp .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
......@@ -1052,6 +1052,7 @@ SLAPD Overlay Options:
--enable-collect Collect overlay no|yes|mod [no]
--enable-constraint Attribute Constraint overlay no|yes|mod [no]
--enable-dds Dynamic Directory Services overlay no|yes|mod [no]
--enable-deref Dereference overlay no|yes|mod [no]
--enable-dyngroup Dynamic Group overlay no|yes|mod [no]
--enable-dynlist Dynamic List overlay no|yes|mod [no]
--enable-memberof Reverse Group Membership overlay no|yes|mod [no]
......@@ -3174,6 +3175,7 @@ Overlays="accesslog \
collect \
constraint \
dds \
deref \
dyngroup \
dynlist \
memberof \
......@@ -3335,6 +3337,30 @@ else
fi;
# end --enable-dds
 
# OpenLDAP --enable-deref
# Check whether --enable-deref or --disable-deref was given.
if test "${enable_deref+set}" = set; then
enableval="$enable_deref"
ol_arg=invalid
for ol_val in no yes mod ; do
if test "$enableval" = "$ol_val" ; then
ol_arg="$ol_val"
fi
done
if test "$ol_arg" = "invalid" ; then
{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-deref" >&5
echo "$as_me: error: bad value $enableval for --enable-deref" >&2;}
{ (exit 1); exit 1; }; }
fi
ol_enable_deref="$ol_arg"
else
ol_enable_deref=${ol_enable_overlays:-no}
fi;
# end --enable-deref
# OpenLDAP --enable-dyngroup
 
# Check whether --enable-dyngroup or --disable-dyngroup was given.
......@@ -5701,7 +5727,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5704 "configure"' > conftest.$ac_ext
echo '#line 5730 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -7681,11 +7707,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7684: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7710: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7688: \$? = $ac_status" >&5
echo "$as_me:7714: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -7943,11 +7969,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7946: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7972: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7950: \$? = $ac_status" >&5
echo "$as_me:7976: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
......@@ -8005,11 +8031,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:8008: $lt_compile\"" >&5)
(eval echo "\"\$as_me:8034: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:8012: \$? = $ac_status" >&5
echo "$as_me:8038: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -10253,7 +10279,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10256 "configure"
#line 10282 "configure"
#include "confdefs.h"
 
#if HAVE_DLFCN_H
......@@ -10351,7 +10377,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10354 "configure"
#line 10380 "configure"
#include "confdefs.h"
 
#if HAVE_DLFCN_H
......@@ -38686,6 +38712,22 @@ _ACEOF
 
fi
 
if test "$ol_enable_deref" != no ; then
BUILD_DDS=$ol_enable_deref
if test "$ol_enable_deref" = mod ; then
MFLAG=SLAPD_MOD_DYNAMIC
SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS deref.la"
else
MFLAG=SLAPD_MOD_STATIC
SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS deref.o"
fi
cat >>confdefs.h <<_ACEOF
#define SLAPD_OVER_DEREF $MFLAG
_ACEOF
fi
if test "$ol_enable_dyngroup" != no ; then
BUILD_DYNGROUP=$ol_enable_dyngroup
if test "$ol_enable_dyngroup" = mod ; then
......@@ -338,6 +338,7 @@ Overlays="accesslog \
collect \
constraint \
dds \
deref \
dyngroup \
dynlist \
memberof \
......@@ -367,6 +368,8 @@ OL_ARG_ENABLE(constraint,[ --enable-constraint Attribute Constraint overlay
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(dds,[ --enable-dds Dynamic Directory Services overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(deref,[ --enable-deref Dereference overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(dyngroup,[ --enable-dyngroup Dynamic Group overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(dynlist,[ --enable-dynlist Dynamic List overlay],
......@@ -2846,6 +2849,18 @@ if test "$ol_enable_dds" != no ; then
AC_DEFINE_UNQUOTED(SLAPD_OVER_DDS,$MFLAG,[define for Dynamic Directory Services overlay])
fi
if test "$ol_enable_deref" != no ; then
BUILD_DDS=$ol_enable_deref
if test "$ol_enable_deref" = mod ; then
MFLAG=SLAPD_MOD_DYNAMIC
SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS deref.la"
else
MFLAG=SLAPD_MOD_STATIC
SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS deref.o"
fi
AC_DEFINE_UNQUOTED(SLAPD_OVER_DEREF,$MFLAG,[define for Dynamic Directory Services overlay])
fi
if test "$ol_enable_dyngroup" != no ; then
BUILD_DYNGROUP=$ol_enable_dyngroup
if test "$ol_enable_dyngroup" = mod ; then
......
......@@ -321,6 +321,8 @@ typedef struct ldapcontrol {
LDAP_CONTROL_X_SESSION_TRACKING ".2"
#define LDAP_CONTROL_X_SESSION_TRACKING_USERNAME \
LDAP_CONTROL_X_SESSION_TRACKING ".3"
/* Dereference Control (work in progress) */
#define LDAP_CONTROL_X_DEREF "1.3.6.1.4.1.4203.666.5.16"
#endif /* LDAP_DEVEL */
/* various expired works */
......@@ -2400,5 +2402,56 @@ ldap_create_assertion_control LDAP_P((
int iscritical,
LDAPControl **ctrlp ));
/*
* in deref.c
*/
typedef struct LDAPDerefSpec {
char *derefAttr;
char **attributes;
} LDAPDerefSpec;
typedef struct LDAPDerefVal {
char *type;
BerVarray vals;
struct LDAPDerefVal *next;
} LDAPDerefVal;
typedef struct LDAPDerefRes {
char *derefAttr;
struct berval derefVal;
LDAPDerefVal *attrVals;
struct LDAPDerefRes *next;
} LDAPDerefRes;
LDAP_F( int )
ldap_create_deref_control_value LDAP_P((
LDAP *ld,
LDAPDerefSpec *ds,
struct berval *value ));
LDAP_F( int )
ldap_create_deref_control LDAP_P((
LDAP *ld,
LDAPDerefSpec *ds,
int iscritical,
LDAPControl **ctrlp ));
LDAP_F( void )
ldap_derefresponse_free LDAP_P((
LDAPDerefRes *dr ));
LDAP_F( int )
ldap_parse_derefresponse_control LDAP_P((
LDAP *ld,
LDAPControl *ctrl,
LDAPDerefRes **drp ));
LDAP_F( int )
ldap_parse_deref_control LDAP_P((
LDAP *ld,
LDAPControl **ctrls,
LDAPDerefRes **drp ));
LDAP_END_DECL
#endif /* _LDAP_H */
......@@ -978,6 +978,9 @@
/* define for Dynamic Directory Services overlay */
#undef SLAPD_OVER_DDS
/* define for Dynamic Directory Services overlay */
#undef SLAPD_OVER_DEREF
/* define for Dynamic Group overlay */
#undef SLAPD_OVER_DYNGROUP
......
......@@ -27,7 +27,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
init.c options.c print.c string.c util-int.c schema.c \
charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c \
assertion.c
assertion.c deref.c
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
controls.lo messages.lo references.lo extended.lo cyrus.lo \
......@@ -39,7 +39,7 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo \
assertion.lo
assertion.lo deref.lo
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
......
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 1998-2008 The OpenLDAP Foundation.
* Portions Copyright 2008 Pierangelo Masarati.
* 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 initially developed by Pierangelo Masarati
* 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"
int
ldap_create_deref_control_value(
LDAP *ld,
LDAPDerefSpec *ds,
struct berval *value )
{
BerElement *ber = NULL;
ber_tag_t tag;
int i;
if ( ld == NULL || value == NULL || ds == NULL )
{
if ( ld )
ld->ld_errno = LDAP_PARAM_ERROR;
return LDAP_PARAM_ERROR;
}
assert( LDAP_VALID( ld ) );
value->bv_val = NULL;
value->bv_len = 0;
ld->ld_errno = LDAP_SUCCESS;
ber = ldap_alloc_ber_with_options( ld );
if ( ber == NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
return ld->ld_errno;
}
tag = ber_printf( ber, "{" /*}*/ );
if ( tag == LBER_ERROR ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
goto done;
}
for ( i = 0; ds[i].derefAttr != NULL; i++ ) {
int j;
tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr );
if ( tag == LBER_ERROR ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
goto done;
}
for ( j = 0; ds[i].attributes[j] != NULL; j++ ) {
tag = ber_printf( ber, "s", ds[i].attributes[ j ] );
if ( tag == LBER_ERROR ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
goto done;
}
}
tag = ber_printf( ber, /*{{*/ "}N}" );
if ( tag == LBER_ERROR ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
goto done;
}
}
tag = ber_printf( ber, /*{*/ "}" );
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_deref_control(
LDAP *ld,
LDAPDerefSpec *ds,
int iscritical,
LDAPControl **ctrlp )
{
struct berval value;
if ( ctrlp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
return ld->ld_errno;
}
ld->ld_errno = ldap_create_deref_control_value( ld, ds, &value );
if ( ld->ld_errno == LDAP_SUCCESS ) {
ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
iscritical, &value, 0, ctrlp );
if ( ld->ld_errno != LDAP_SUCCESS ) {
LDAP_FREE( value.bv_val );
}
}
return ld->ld_errno;
}