Add support for unsolicited notifications.

This commit is contained in:
Kurt Zeilenga 1999-07-07 18:51:39 +00:00
parent b8edef2b2c
commit e9c2895472
31 changed files with 372 additions and 181 deletions

View file

@ -9,7 +9,7 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \
dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
repl.c lock.c controls.c \
repl.c lock.c controls.c extended.c \
suffixalias.c schema.c schemaparse.c monitor.c configinfo.c \
root_dse.c module.c
OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
@ -17,7 +17,7 @@ OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
repl.o lock.o controls.o \
repl.o lock.o controls.o extended.o \
suffixalias.o schema.o schemaparse.o monitor.o configinfo.o \
root_dse.o module.o

View file

@ -40,7 +40,9 @@ do_abandon(
if ( ber_scanf( op->o_ber, "i", &id ) == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "do_abandon: ber_scanf failed\n", 0, 0 ,0 );
return LDAP_PROTOCOL_ERROR;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
if( (rc = get_ctrls( conn, op, 0 )) != LDAP_SUCCESS ) {

View file

@ -55,7 +55,7 @@ access_allowed(
e->e_dn, attr, 0 );
/* the lastmod attributes are ignored by ACL checking */
if ( oc_check_operational( attr ) ) {
if ( oc_check_no_usermod_attr( attr ) ) {
Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
attr, 0, 0 );
return(1);
@ -212,7 +212,6 @@ acl_access_allowed(
)
{
int i;
char *odn;
struct access *b;
Attribute *at;
struct berval bv;
@ -244,11 +243,9 @@ acl_access_allowed(
return( default_access >= access );
}
odn = op->o_ndn;
if ( odn != NULL ) {
bv.bv_val = odn;
bv.bv_len = strlen( odn );
if ( op->o_ndn != NULL ) {
bv.bv_val = op->o_ndn;
bv.bv_len = strlen( bv.bv_val );
}
for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
@ -282,7 +279,7 @@ acl_access_allowed(
return ACL_GRANT(b->a_access, access );
}
} else {
if ( regex_matches( b->a_dnpat, odn, edn, matches ) ) {
if ( regex_matches( b->a_dnpat, op->o_ndn, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
@ -365,7 +362,7 @@ acl_access_allowed(
string_expand(buf, sizeof(buf), b->a_group, edn, matches);
(void) dn_normalize_case(buf);
if (backend_group(be, e, buf, odn,
if (backend_group(be, e, buf, op->o_ndn,
b->a_group_oc, b->a_group_at) == 0)
{
Debug( LDAP_DEBUG_ACL,
@ -408,7 +405,7 @@ acl_check_modlist(
regmatch_t matches[MAXREMATCHES];
/* the lastmod attributes are ignored by ACL checking */
if ( oc_check_operational( mlist->ml_type ) ) {
if ( oc_check_no_usermod_attr( mlist->ml_type ) ) {
Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
mlist->ml_type, 0, 0 );
continue;

View file

@ -57,9 +57,9 @@ do_add( Connection *conn, Operation *op )
/* get the name */
if ( ber_scanf( ber, "{a", /*}*/ &dn ) == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
"decoding error" );
return LDAP_PROTOCOL_ERROR;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
@ -80,17 +80,17 @@ do_add( Connection *conn, Operation *op )
struct berval **vals;
if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "decoding error" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
entry_free( e );
return LDAP_PROTOCOL_ERROR;
return -1;
}
if ( vals == NULL ) {
Debug( LDAP_DEBUG_ANY, "no values for type %s\n", type,
0, 0 );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
NULL );
send_ldap_result( conn, op,
LDAP_PROTOCOL_ERROR, NULL, "no values for type" );
free( type );
entry_free( e );
return LDAP_PROTOCOL_ERROR;
@ -105,9 +105,9 @@ do_add( Connection *conn, Operation *op )
if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
entry_free( e );
Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
"decoding error" );
return LDAP_PROTOCOL_ERROR;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
@ -186,7 +186,7 @@ add_created_attrs( Operation *op, Entry *e )
/* remove any attempts by the user to add these attrs */
for ( a = &e->e_attrs; *a != NULL; a = next ) {
if ( oc_check_operational( (*a)->a_type ) ) {
if ( oc_check_no_usermod_attr( (*a)->a_type ) ) {
tmp = *a;
*a = (*a)->a_next;
attr_free( tmp );
@ -197,7 +197,7 @@ add_created_attrs( Operation *op, Entry *e )
}
if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
bv.bv_val = "NULLDN";
bv.bv_val = "<anonymous>";
bv.bv_len = strlen( bv.bv_val );
} else {
bv.bv_val = op->o_dn;

View file

@ -18,12 +18,12 @@ get_ava(
if ( ber_scanf( ber, "{ao}", &ava->ava_type, &ava->ava_value )
== LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, " get_ava ber_scanf\n", 0, 0, 0 );
return( LDAP_PROTOCOL_ERROR );
return( -1 );
}
attr_normalize( ava->ava_type );
value_normalize( ava->ava_value.bv_val, attr_syntax( ava->ava_type ) );
return( 0 );
return( LDAP_SUCCESS );
}
void

View file

@ -33,9 +33,9 @@ add_lastmods( Operation *op, LDAPModList **modlist )
/* remove any attempts by the user to modify these attrs */
for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) {
if ( oc_check_operational( (*m)->ml_type ) ) {
if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) {
Debug( LDAP_DEBUG_TRACE,
"add_lastmods: found operational attr: %s\n",
"add_lastmods: found no user mod attr: %s\n",
(*m)->ml_type, 0, 0 );
tmp = *m;
*m = (*m)->ml_next;

View file

@ -265,7 +265,7 @@ bdb2i_back_search_internal(
if (e) {
switch ( send_search_entry( be, conn, op, e,
attrs, attrsonly ) ) {
attrs, attrsonly, 0 ) ) {
case 0: /* entry sent ok */
nentries++;
break;

View file

@ -158,7 +158,7 @@ ldap_send_entry(
if (!attr->a_vals)
attr->a_vals = &dummy;
}
send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly );
send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly, 0 );
for (;ent.e_attrs;) {
attr=ent.e_attrs;
ent.e_attrs = attr->a_next;

View file

@ -33,9 +33,9 @@ add_lastmods( Operation *op, LDAPModList **modlist )
/* remove any attempts by the user to modify these attrs */
for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) {
if ( oc_check_operational( (*m)->ml_type ) ) {
if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) {
Debug( LDAP_DEBUG_TRACE,
"add_lastmods: found operational attr: %s\n",
"add_lastmods: found no user mod attr: %s\n",
(*m)->ml_type, 0, 0 );
tmp = *m;
*m = (*m)->ml_next;

View file

@ -264,7 +264,7 @@ ldbm_back_search(
}
if (e) {
switch ( send_search_entry( be, conn, op, e,
attrs, attrsonly ) ) {
attrs, attrsonly, 0 ) ) {
case 0: /* entry sent ok */
nentries++;
break;

View file

@ -139,7 +139,7 @@ passwd_back_search(
return( 0 );
}
send_search_entry( be, conn, op, e, attrs, attrsonly );
send_search_entry( be, conn, op, e, attrs, attrsonly, 0 );
sent++;
}
@ -176,7 +176,7 @@ passwd_back_search(
e = pw2entry( be, pw, rdn );
if ( test_filter( be, conn, op, e, filter ) == 0 ) {
send_search_entry( be, conn, op, e, attrs, attrsonly );
send_search_entry( be, conn, op, e, attrs, attrsonly, 0 );
sent++;
}

View file

@ -91,7 +91,8 @@ perl_back_search(
op,
e,
attrs,
attrsonly );
attrsonly,
0 );
entry_free( e );
}

View file

@ -59,7 +59,7 @@ read_and_send_results(
buf, 0, 0 );
} else {
send_search_entry( be, conn, op, e, attrs,
attrsonly );
attrsonly, 0 );
entry_free( e );
}

View file

@ -1,6 +1,6 @@
/* result.c - tcl backend utility functions
*
* $Id: tcl_util.c,v 1.4 1999/02/19 06:55:20 bcollins Exp $
* $Id: tcl_util.c,v 1.5 1999/02/28 04:55:49 bcollins Exp $
*
* Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
*
@ -80,7 +80,7 @@ interp_send_results (
buf, 0, 0);
} else {
send_search_entry (be, conn, op, e, attrs,
attrsonly);
attrsonly, 0 );
entry_free (e);
}

View file

@ -22,7 +22,6 @@
#include "slap.h"
char *supportedSASLMechanisms[] = {
"X-CRAM-MD5",
"X-DIGEST-MD5",
NULL
};
@ -103,8 +102,9 @@ do_bind(
if ( tag == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"decoding error" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
rc = -1;
goto cleanup;
}
@ -131,8 +131,10 @@ do_bind(
}
if ( tag == LBER_ERROR ) {
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR,
"decoding error" );
rc = -1;
goto cleanup;
}
@ -156,8 +158,8 @@ do_bind(
if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
Debug( LDAP_DEBUG_ANY, "unknown version %d\n", version, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"version not supported" );
send_ldap_result( conn, op,
rc = LDAP_PROTOCOL_ERROR, NULL, "version not supported" );
goto cleanup;
}
@ -165,8 +167,9 @@ do_bind(
if ( version < LDAP_VERSION3 ) {
Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%d\n",
version, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"sasl bind requires LDAPv3" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "sasl bind requires LDAPv3" );
rc = -1;
goto cleanup;
}

View file

@ -54,8 +54,9 @@ do_compare(
if ( ber_scanf( op->o_ber, "{a{ao}}", &ndn, &ava.ava_type,
&ava.ava_value ) == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
if( ( rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {

View file

@ -63,7 +63,7 @@ config_info( Connection *conn, Operation *op )
attr_merge( e, "database", vals );
}
send_search_entry( &backends[0], conn, op, e, NULL, 0 );
send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
entry_free( e );

View file

@ -681,18 +681,22 @@ connection_operation( void *arg_v )
rc = do_abandon( conn, arg->co_op );
break;
#if 0
case LDAP_REQ_EXTENDED:
rc = do_extended( conn, arg->co_op );
break;
#endif
default:
Debug( LDAP_DEBUG_ANY, "unknown request 0x%lx\n",
arg->co_op->o_tag, 0, 0 );
Debug( LDAP_DEBUG_ANY, "unknown LDAP request 0x%lx\n",
tag, 0, 0 );
arg->co_op->o_tag = LBER_ERROR;
send_ldap_disconnect( conn, arg->co_op,
LDAP_PROTOCOL_ERROR, "unknown LDAP request" );
rc = -1;
break;
}
if( rc == -1 ) tag = LBER_ERROR;
ldap_pvt_thread_mutex_lock( &num_ops_mutex );
num_ops_completed++;
ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
@ -710,6 +714,7 @@ connection_operation( void *arg_v )
arg = NULL;
switch( tag ) {
case LBER_ERROR:
case LDAP_REQ_UNBIND:
/* c_mutex is locked */
connection_closing( conn );

View file

@ -32,6 +32,7 @@ int get_ctrls(
BerElement *ber = op->o_ber;
LDAPControl ***ctrls = &op->o_ctrls;
int rc = LDAP_SUCCESS;
char *errmsg = NULL;
len = ber_pvt_ber_remaining(ber);
@ -43,14 +44,16 @@ int get_ctrls(
if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
if( tag == LBER_ERROR ) {
rc = LDAP_PROTOCOL_ERROR;
rc = -1;
errmsg = "unexpected data in PDU";
}
goto return_results;
}
if( op->o_protocol < LDAP_VERSION3 ) {
rc = LDAP_PROTOCOL_ERROR;
rc = -1;
errmsg = "controls require LDAPv3";
goto return_results;
}
@ -61,6 +64,7 @@ int get_ctrls(
#if 0
if( *ctrls == NULL ) {
rc = LDAP_NO_MEMORY;
errmsg = "no memory";
goto return_results;
}
#endif
@ -94,6 +98,7 @@ int get_ctrls(
*ctrls = NULL;
rc = LDAP_NO_MEMORY;
errmsg = "no memory";
goto return_results;
}
#endif
@ -128,7 +133,8 @@ int get_ctrls(
if( tag == LBER_ERROR ) {
*ctrls = NULL;
ldap_controls_free( tctrls );
rc = LDAP_DECODING_ERROR;
rc = -1;
errmsg = "decoding controls error";
goto return_results;
}
@ -136,6 +142,7 @@ int get_ctrls(
!charray_inlist( supportedControls, tctrl->ldctl_oid ) )
{
rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
errmsg = "critical extension is unavailable ";
goto return_results;
}
@ -144,7 +151,11 @@ int get_ctrls(
return_results:
if( sendres && rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc, NULL, NULL );
if( rc == -1 ) {
send_ldap_disconnect( conn, op, rc, errmsg );
} else {
send_ldap_result( conn, op, rc, NULL, errmsg );
}
}
return rc;

View file

@ -47,8 +47,9 @@ do_delete(
if ( ber_scanf( op->o_ber, "a", &ndn ) == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) {

View file

@ -34,6 +34,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,,
* approxMatch [8] AttributeValueAssertion
* extensibleMatch [9] MatchingRuleAssertion
* }
*
* SubstringFilter ::= SEQUENCE {
@ -44,19 +45,27 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
* final [2] IA5String
* }
* }
*
* MatchingRuleAssertion ::= SEQUENCE {
* matchingRule [1] MatchingRuleId OPTIONAL,
* type [2] AttributeDescription OPTIONAL,
* matchValue [3] AssertionValue,
* dnAttributes [4] BOOLEAN DEFAULT FALSE
* }
*
*/
f = (Filter *) ch_malloc( sizeof(Filter) );
f->f_next = NULL;
err = 0;
err = LDAP_SUCCESS;
*fstr = NULL;
f->f_choice = ber_peek_tag( ber, &len );
switch ( f->f_choice ) {
case LDAP_FILTER_EQUALITY:
Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
*fstr = ch_malloc(4 + strlen( f->f_avtype ) +
f->f_avvalue.bv_len);
sprintf( *fstr, "(%s=%s)", f->f_avtype,
@ -71,7 +80,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_GE:
Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
*fstr = ch_malloc(5 + strlen( f->f_avtype ) +
f->f_avvalue.bv_len);
sprintf( *fstr, "(%s>=%s)", f->f_avtype,
@ -81,7 +90,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_LE:
Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
*fstr = ch_malloc(5 + strlen( f->f_avtype ) +
f->f_avvalue.bv_len);
sprintf( *fstr, "(%s<=%s)", f->f_avtype,
@ -92,7 +101,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_PRESENT:
Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
err = LDAP_PROTOCOL_ERROR;
err = -1;
} else {
err = LDAP_SUCCESS;
attr_normalize( f->f_type );
@ -103,7 +112,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_APPROX:
Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
*fstr = ch_malloc(5 + strlen( f->f_avtype ) +
f->f_avvalue.bv_len);
sprintf( *fstr, "(%s~=%s)", f->f_avtype,
@ -114,7 +123,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_AND:
Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
== 0 ) {
== LDAP_SUCCESS ) {
if (ftmp == NULL) ftmp = ch_strdup("");
*fstr = ch_malloc( 4 + strlen( ftmp ) );
sprintf( *fstr, "(&%s)", ftmp );
@ -125,7 +134,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_OR:
Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
== 0 ) {
== LDAP_SUCCESS ) {
if (ftmp == NULL) ftmp = ch_strdup("");
*fstr = ch_malloc( 4 + strlen( ftmp ) );
sprintf( *fstr, "(|%s)", ftmp );
@ -136,7 +145,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
case LDAP_FILTER_NOT:
Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
(void) ber_skip_tag( ber, &len );
if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) {
if (ftmp == NULL) ftmp = ch_strdup("");
*fstr = ch_malloc( 4 + strlen( ftmp ) );
sprintf( *fstr, "(!%s)", ftmp );
@ -144,6 +153,12 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
}
break;
case LBER_DEFAULT:
Debug( LDAP_DEBUG_ANY, "decoding filter error\n",
0, 0, 0 );
err = -1;
break;
default:
Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
f->f_choice, 0, 0 );
@ -151,7 +166,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
break;
}
if ( err != 0 ) {
if ( err != LDAP_SUCCESS ) {
free( (char *) f );
if ( *fstr != NULL ) {
free( *fstr );
@ -178,8 +193,9 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
*fstr = NULL;
new = f;
for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) {
if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
tag = ber_next_element( ber, &len, last ) )
{
if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS )
return( err );
if ( *fstr == NULL ) {
*fstr = ftmp;
@ -194,7 +210,7 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
*new = NULL;
Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
return( 0 );
return( LDAP_SUCCESS );
}
static int
@ -214,7 +230,7 @@ get_substring_filter(
Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
return( LDAP_PROTOCOL_ERROR );
return( -1 );
}
attr_normalize( f->f_sub_type );
syntax = attr_syntax( f->f_sub_type );
@ -225,10 +241,11 @@ get_substring_filter(
*fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
sprintf( *fstr, "(%s=", f->f_sub_type );
for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) {
rc = ber_scanf( ber, "a", &val );
tag = ber_next_element( ber, &len, last ) )
{
rc = ber_scanf( ber, "a", &val );
if ( rc == LBER_ERROR ) {
return( LDAP_PROTOCOL_ERROR );
return( -1 );
}
if ( val == NULL || *val == '\0' ) {
if ( val != NULL ) {
@ -284,7 +301,7 @@ get_substring_filter(
strcat( *fstr, ")" );
Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
return( 0 );
return( LDAP_SUCCESS );
}
void

View file

@ -200,6 +200,10 @@ SOURCE=.\entry.c
# End Source File
# Begin Source File
SOURCE=.\extended.c
# End Source File
# Begin Source File
SOURCE=.\filter.c
# End Source File
# Begin Source File

View file

@ -71,8 +71,9 @@ do_modify(
if ( ber_scanf( op->o_ber, "{a" /*}*/, &ndn ) == LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", ndn, 0, 0 );
@ -95,13 +96,13 @@ do_modify(
&(*modtail)->ml_type, &(*modtail)->ml_bvalues )
== LBER_ERROR )
{
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"decoding error" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding modlist error" );
free( ndn );
free( *modtail );
*modtail = NULL;
modlist_free( modlist );
return rc;
return -1;
}
(*modtail)->ml_op = mop;
@ -110,21 +111,21 @@ do_modify(
(*modtail)->ml_op != LDAP_MOD_DELETE &&
(*modtail)->ml_op != LDAP_MOD_REPLACE )
{
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"unrecognized modify operation" );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "unrecognized modify operation" );
free( ndn );
modlist_free( modlist );
return rc;
return LDAP_PROTOCOL_ERROR;
}
if ( (*modtail)->ml_bvalues == NULL
&& (*modtail)->ml_op != LDAP_MOD_DELETE )
{
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"no values given" );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "unrecognized modify operation" );
free( ndn );
modlist_free( modlist );
return rc;
return LDAP_PROTOCOL_ERROR;
}
attr_normalize( (*modtail)->ml_type );

View file

@ -72,8 +72,9 @@ do_modrdn(
if ( ber_scanf( op->o_ber, "{aab", &ndn, &newrdn, &deloldrdn )
== LBER_ERROR ) {
Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
/* Check for newSuperior parameter, if present scan it */
@ -96,9 +97,9 @@ do_modrdn(
Debug( LDAP_DEBUG_ANY,
"modrdn(v2): invalid field newSuperior!\n",
0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "newSuperior requires LDAPv3" );
return -1;
}
if ( ber_scanf( op->o_ber, "a", &newSuperior )
@ -106,9 +107,9 @@ do_modrdn(
Debug( LDAP_DEBUG_ANY, "ber_scanf(\"a\"}) failed\n",
0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
@ -124,12 +125,11 @@ do_modrdn(
free( newrdn );
free( newSuperior );
Debug( LDAP_DEBUG_ANY, "do_modrdn: ber_scanf failed\n", 0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"decoding error" );
return rc;
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
return -1;
}
#ifdef GET_CTRLS
if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
free( ndn );
free( newrdn );
@ -137,7 +137,6 @@ do_modrdn(
Debug( LDAP_DEBUG_ANY, "do_modrdn: get_ctrls failed\n", 0, 0, 0 );
return rc;
}
#endif
if( newSuperior != NULL ) {
/* GET BACKEND FOR NEW SUPERIOR */

View file

@ -21,10 +21,6 @@
#include "ldap_defaults.h"
#include "slap.h"
char *supportedExtensions[] = {
NULL
};
#if defined( SLAPD_MONITOR_DN )
void
@ -232,7 +228,7 @@ monitor_info( Connection *conn, Operation *op )
attr_merge( e, "concurrency", vals );
#endif
send_search_entry( &backends[0], conn, op, e, NULL, 0 );
send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
entry_free( e );

View file

@ -257,17 +257,26 @@ void replog LDAP_P(( Backend *be, int optype, char *dn, void *change, int flag )
* result.c
*/
void send_ldap_result LDAP_P(( Connection *conn, Operation *op, int err, char *matched,
char *text ));
void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err,
char *matched, char *text, int nentries ));
void send_ldap_result LDAP_P((
Connection *conn, Operation *op,
int err, char *matched, char *text ));
void send_ldap_disconnect LDAP_P((
Connection *conn, Operation *op,
int err, char *text ));
void send_ldap_search_result LDAP_P((
Connection *conn, Operation *op,
int err, char *matched, char *text, int nentries ));
/*
* schema.c
*/
int oc_schema_check LDAP_P(( Entry *e ));
int oc_check_operational LDAP_P(( char *type ));
int oc_check_operational_attr LDAP_P(( char *type ));
int oc_check_usermod_attr LDAP_P(( char *type ));
int oc_check_no_usermod_attr LDAP_P(( char *type ));
ObjectClass *oc_find LDAP_P((const char *ocname));
int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err));
Syntax *syn_find LDAP_P((const char *synname));
@ -401,9 +410,12 @@ extern int do_modify LDAP_P((Connection *conn, Operation *op));
extern int do_modrdn LDAP_P((Connection *conn, Operation *op));
extern int do_search LDAP_P((Connection *conn, Operation *op));
extern int do_unbind LDAP_P((Connection *conn, Operation *op));
extern int do_exop LDAP_P((Connection *conn, Operation *op));
extern int do_extended LDAP_P((Connection *conn, Operation *op));
extern int send_search_entry LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e, char **attrs, int attrsonly, int opattrs ));
extern int send_search_entry LDAP_P((Backend *be, Connection *conn, Operation *op, Entry *e, char **attrs, int attrsonly));
extern int str2result LDAP_P(( char *s, int *code, char **matched, char **info ));
extern ber_socket_t dtblsize;

View file

@ -20,6 +20,7 @@ static void
send_ldap_result2(
Connection *conn,
Operation *op,
int disconnect,
ber_int_t err,
char *matched,
char *text,
@ -30,32 +31,50 @@ send_ldap_result2(
int rc;
ber_tag_t tag;
ber_len_t bytes;
int msgid;
assert( !LDAP_API_ERROR( err ) );
if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') )
err = LDAP_NO_SUCH_OBJECT;
Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n", err,
matched ? matched : "",
text ? text : "" );
if( disconnect ) {
msgid = 0; /* unsolicited */
if ( op->o_protocol > LDAP_VERSION3 ) {
tag = LDAP_RES_EXTENDED;
}
switch ( op->o_tag ) {
case LBER_DEFAULT:
tag = LBER_SEQUENCE;
break;
#define LDAP_UNSOLICITED_ERROR(e) \
( (e) == LDAP_PROTOCOL_ERROR \
|| (e) == LDAP_STRONG_AUTH_REQUIRED \
|| (e) == LDAP_UNAVAILABLE )
case LDAP_REQ_SEARCH:
tag = LDAP_RES_SEARCH_RESULT;
break;
assert( LDAP_UNSOLICITED_ERROR( err ) );
case LDAP_REQ_DELETE:
tag = LDAP_RES_DELETE;
break;
} else {
msgid = op->o_msgid;
default:
tag = op->o_tag + 1;
break;
switch ( op->o_tag ) {
case LDAP_REQ_ABANDON:
case LDAP_REQ_UNBIND:
case LBER_ERROR:
tag = LBER_SEQUENCE;
msgid = 0;
assert( LDAP_UNSOLICITED_ERROR( err ) );
break;
case LDAP_REQ_SEARCH:
tag = LDAP_RES_SEARCH_RESULT;
break;
case LDAP_REQ_DELETE:
tag = LDAP_RES_DELETE;
break;
default:
tag = op->o_tag + 1;
break;
}
}
@ -68,13 +87,20 @@ send_ldap_result2(
#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
rc = ber_printf( ber, "{is{t{ess}}}", op->o_msgid, "", tag,
rc = ber_printf( ber, "{is{t{ess}}}", msgid, "", tag,
err, matched ? matched : "", text ? text : "" );
} else
#endif
{
rc = ber_printf( ber, "{it{ess}}", op->o_msgid, tag, err,
matched ? matched : "", text ? text : "" );
if( tag == LDAP_RES_EXTENDED ) {
rc = ber_printf( ber, "{it{esss}}",
msgid, tag, err,
"", text ? text : "",
LDAP_NOTICE_DISCONNECT );
} else {
rc = ber_printf( ber, "{it{ess}}",
msgid, tag, err,
matched ? matched : "", text ? text : "" );
}
if ( rc == -1 ) {
@ -158,6 +184,9 @@ send_ldap_result(
{
assert( !LDAP_API_ERROR( err ) );
Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n",
err, matched ? matched : "", text ? text : "" );
#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
ber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
@ -168,7 +197,34 @@ send_ldap_result(
0 );
}
#endif
send_ldap_result2( conn, op, err, matched, text, 0 );
send_ldap_result2( conn, op, 0, err, matched, text, 0 );
}
void
send_ldap_disconnect(
Connection *conn,
Operation *op,
ber_int_t err,
char *text
)
{
assert( !LDAP_API_ERROR( err ) );
Debug( LDAP_DEBUG_TRACE,
"send_ldap_disconnect %d:%s\n",
err, text ? text : "", NULL );
#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
ber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n",
inet_ntoa(((struct sockaddr_in *)
&op->o_clientaddr)->sin_addr ),
((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
0 );
}
#endif
send_ldap_result2( conn, op, 0, err, NULL, text, 0 );
}
void
@ -181,7 +237,10 @@ send_ldap_search_result(
int nentries
)
{
send_ldap_result2( conn, op, err, matched, text, nentries );
Debug( LDAP_DEBUG_TRACE, "send_ldap_search_result %d:%s:%s\n",
err, matched ? matched : "", text ? text : "" );
send_ldap_result2( conn, op, 0, err, matched, text, nentries );
}
int
@ -191,7 +250,8 @@ send_search_entry(
Operation *op,
Entry *e,
char **attrs,
int attrsonly
int attrsonly,
int opattrs
)
{
BerElement *ber;
@ -202,6 +262,17 @@ send_search_entry(
Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
#if defined( SLAPD_SCHEMA_DN )
{
/* this could be backend specific */
struct berval val;
val.bv_val = SLAPD_SCHEMA_DN;
val.bv_len = strlen( val.bv_val );
attr_merge( e, "subschemaSubentry", vals );
ldap_memfree( val.bv_val );
}
#endif
if ( ! access_allowed( be, conn, op, e,
"entry", NULL, ACL_READ ) )
{
@ -237,12 +308,15 @@ send_search_entry(
if ( attrs == NULL ) {
/* all addrs request, skip operational attributes */
if( oc_check_operational( a->a_type )) {
if( !opattrs && oc_check_operational_attr( a->a_type )) {
continue;
}
} else {
/* specific addrs requested */
if ( !charray_inlist( attrs, a->a_type )) {
if ( !charray_inlist( attrs, a->a_type )
&& !charray_inlist( attrs, LDAP_ALL_USER_ATTRIBUTES ) )
{
continue;
}
}

View file

@ -19,8 +19,8 @@
void
root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
{
char buf[BUFSIZ];
Entry *e;
char buf[BUFSIZ];
struct berval val;
struct berval *vals[2];
int i, j;
@ -37,51 +37,44 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
for ( i = 0; i < nbackends; i++ ) {
for ( j = 0; backends[i].be_suffix[j] != NULL; j++ ) {
strcpy( buf, backends[i].be_suffix[j] );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = backends[i].be_suffix[j];
val.bv_len = strlen( val.bv_val );
attr_merge( e, "namingContexts", vals );
}
}
#if defined( SLAPD_MONITOR_DN )
strcpy( buf, SLAPD_MONITOR_DN );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = SLAPD_MONITOR_DN;
val.bv_len = strlen( val.bv_val );
attr_merge( e, "namingContexts", vals );
/* subschemasubentry is added by send_search_entry() */
#endif
#if defined( SLAPD_CONFIG_DN )
strcpy( buf, SLAPD_CONFIG_DN );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = SLAPD_CONFIG_DN;
val.bv_len = strlen( val.bv_val );
attr_merge( e, "namingContexts", vals );
#endif
#if defined( SLAPD_SCHEMA_DN )
strcpy( buf, SLAPD_SCHEMA_DN );
val.bv_val = buf;
val.bv_val = SLAPD_SCHEMA_DN;
val.bv_len = strlen( val.bv_val );
attr_merge( e, "namingContexts", vals );
attr_merge( e, "subschemaSubentry", vals );
ldap_memfree( val.bv_val );
#endif
/* altServer unsupported */
/* supportedControl */
for ( i=0; supportedControls[i] != NULL; i++ ) {
strcpy( buf, supportedControls[i] );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = supportedControls[i];
val.bv_len = strlen( val.bv_val );
attr_merge( e, "supportedControl", vals );
}
/* supportedExtension */
for ( i=0; supportedExtensions[i] != NULL; i++ ) {
strcpy( buf, supportedExtensions[i] );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = supportedExtensions[i];
val.bv_len = strlen( val.bv_val );
attr_merge( e, "supportedExtension", vals );
}
@ -89,20 +82,19 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
for ( i=LDAP_VERSION_MIN; i<=LDAP_VERSION_MAX; i++ ) {
sprintf(buf,"%d",i);
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_len = strlen( val.bv_val );
attr_merge( e, "supportedLDAPVersion", vals );
}
/* supportedSASLMechanism */
for ( i=0; supportedSASLMechanisms[i] != NULL; i++ ) {
strcpy( buf, supportedSASLMechanisms[i] );
val.bv_val = buf;
val.bv_len = strlen( buf );
val.bv_val = supportedSASLMechanisms[i];
val.bv_len = strlen( val.bv_val );
attr_merge( e, "supportedSASLMechanism", vals );
}
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly );
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 1 );
send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
entry_free( e );

View file

@ -123,20 +123,78 @@ oc_check_required( Entry *e, char *ocname )
return( NULL );
}
static char *oc_usermod_attrs[] = {
/*
* OpenLDAP doesn't support any user modification of
* operational attributes.
*/
NULL
};
static char *oc_operational_attrs[] = {
/*
* these are operational attributes that *could* be
* modified by users if we supported such.
*/
"objectClasses",
"attributeTypes",
"matchingRules",
"matchingRuleUse",
"dITStructureRules",
"dITContentRules",
"nameForms",
"ldapSyntaxes",
NULL
};
/* this list should be extensible */
static char *oc_no_usermod_attrs[] = {
/*
* Operational and 'no user modification' attributes
*/
/* RFC2252, 3.2.1 */
"creatorsName",
"createTimestamp",
"modifiersName",
"modifyTimestamp",
"subschemaSubentry",
NULL
};
/*
* check to see if attribute is 'operational' or not.
* this list should be extensible...
*/
int
oc_check_operational( char *type )
oc_check_operational_attr( char *type )
{
return ( strcasecmp( type, "modifiersname" ) == 0 ||
strcasecmp( type, "modifytimestamp" ) == 0 ||
strcasecmp( type, "creatorsname" ) == 0 ||
strcasecmp( type, "createtimestamp" ) == 0 )
? 1 : 0;
return charray_inlist( oc_operational_attrs, type )
|| charray_inlist( oc_usermod_attrs, type )
|| charray_inlist( oc_no_usermod_attrs, type );
}
/*
* check to see if attribute can be user modified or not.
*/
int
oc_check_usermod_attr( char *type )
{
return charray_inlist( oc_usermod_attrs, type );
}
/*
* check to see if attribute is 'no user modification' or not.
*/
int
oc_check_no_usermod_attr( char *type )
{
return charray_inlist( oc_no_usermod_attrs, type );
}
static int
oc_check_allowed( char *type, struct berval **ocl )
{
@ -153,7 +211,12 @@ oc_check_allowed( char *type, struct berval **ocl )
return( 0 );
}
if ( oc_check_operational( type ) ) {
/*
* All operational attributions are allowed by schema rules.
* However, we only check attributions which are stored in the
* the directory regardless if they are user or non-user modified.
*/
if ( oc_check_usermod_attr( type ) || oc_check_no_usermod_attr( type ) ) {
return( 0 );
}
@ -1080,7 +1143,7 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
return;
}
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly );
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 0 );
send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
entry_free( e );

View file

@ -74,14 +74,17 @@ do_search(
if ( ber_scanf( op->o_ber, "{aiiiib",
&base, &scope, &deref, &sizelimit,
&timelimit, &attrsonly ) == LBER_ERROR ) {
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
rc = -1;
goto return_results;
}
if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
&& scope != LDAP_SCOPE_SUBTREE ) {
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
"Unknown search scope" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
rc = -1;
goto return_results;
}
@ -93,14 +96,22 @@ do_search(
/* filter - returns a "normalized" version */
if ( (err = get_filter( conn, op->o_ber, &filter, &fstr )) != 0 ) {
send_ldap_result( conn, op, err, NULL, "Bad search filter" );
if( err == -1 ) {
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decode error" );
} else {
send_ldap_result( conn, op, err, NULL, "Bad search filter" );
}
goto return_results;
}
Debug( LDAP_DEBUG_ARGS, " filter: %s\n", fstr, 0, 0 );
/* attributes */
if ( ber_scanf( op->o_ber, /*{*/ "{v}}", &attrs ) == LBER_ERROR ) {
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
rc = -1;
goto return_results;
}

View file

@ -55,7 +55,8 @@ send_search_entry(
Operation *op,
Entry *e,
char **attrs,
int attrsonly
int attrsonly,
int opattrs
)
{
assert(0);