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 \
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
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 ) {
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);
)
{
int i;
- char *odn;
struct access *b;
Attribute *at;
struct berval bv;
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++ ) {
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)
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,
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;
/* 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) );
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;
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 ) {
/* 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 );
}
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;
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
/* 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;
if (e) {
switch ( send_search_entry( be, conn, op, e,
- attrs, attrsonly ) ) {
+ attrs, attrsonly, 0 ) ) {
case 0: /* entry sent ok */
nentries++;
break;
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;
/* 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;
}
if (e) {
switch ( send_search_entry( be, conn, op, e,
- attrs, attrsonly ) ) {
+ attrs, attrsonly, 0 ) ) {
case 0: /* entry sent ok */
nentries++;
break;
return( 0 );
}
- send_search_entry( be, conn, op, e, attrs, attrsonly );
+ send_search_entry( be, conn, op, e, attrs, attrsonly, 0 );
sent++;
}
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++;
}
op,
e,
attrs,
- attrsonly );
+ attrsonly,
+ 0 );
entry_free( e );
}
buf, 0, 0 );
} else {
send_search_entry( be, conn, op, e, attrs,
- attrsonly );
+ attrsonly, 0 );
entry_free( e );
}
/* 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.
*
buf, 0, 0);
} else {
send_search_entry (be, conn, op, e, attrs,
- attrsonly);
+ attrsonly, 0 );
entry_free (e);
}
#include "slap.h"
char *supportedSASLMechanisms[] = {
- "X-CRAM-MD5",
"X-DIGEST-MD5",
NULL
};
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;
}
}
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;
}
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;
}
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;
}
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 ) {
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 );
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 );
arg = NULL;
switch( tag ) {
+ case LBER_ERROR:
case LDAP_REQ_UNBIND:
/* c_mutex is locked */
connection_closing( conn );
BerElement *ber = op->o_ber;
LDAPControl ***ctrls = &op->o_ctrls;
int rc = LDAP_SUCCESS;
+ char *errmsg = NULL;
len = ber_pvt_ber_remaining(ber);
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;
}
#if 0
if( *ctrls == NULL ) {
rc = LDAP_NO_MEMORY;
+ errmsg = "no memory";
goto return_results;
}
#endif
*ctrls = NULL;
rc = LDAP_NO_MEMORY;
+ errmsg = "no memory";
goto return_results;
}
#endif
if( tag == LBER_ERROR ) {
*ctrls = NULL;
ldap_controls_free( tctrls );
- rc = LDAP_DECODING_ERROR;
+ rc = -1;
+ errmsg = "decoding controls error";
goto return_results;
}
!charray_inlist( supportedControls, tctrl->ldctl_oid ) )
{
rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+ errmsg = "critical extension is unavailable ";
goto return_results;
}
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;
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 ) {
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,,
* approxMatch [8] AttributeValueAssertion
+ * extensibleMatch [9] MatchingRuleAssertion
* }
*
* SubstringFilter ::= SEQUENCE {
* 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,
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,
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,
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 );
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,
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 );
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 );
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 );
}
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 );
break;
}
- if ( err != 0 ) {
+ if ( err != LDAP_SUCCESS ) {
free( (char *) f );
if ( *fstr != NULL ) {
free( *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;
*new = NULL;
Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
- return( 0 );
+ return( LDAP_SUCCESS );
}
static int
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 );
*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 ) {
strcat( *fstr, ")" );
Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
- return( 0 );
+ return( LDAP_SUCCESS );
}
void
# End Source File
# Begin Source File
+SOURCE=.\extended.c
+# End Source File
+# Begin Source File
+
SOURCE=.\filter.c
# End Source File
# Begin Source File
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 );
&(*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;
(*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 );
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 */
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 )
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;
}
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 );
Debug( LDAP_DEBUG_ANY, "do_modrdn: get_ctrls failed\n", 0, 0, 0 );
return rc;
}
-#endif
if( newSuperior != NULL ) {
/* GET BACKEND FOR NEW SUPERIOR */
#include "ldap_defaults.h"
#include "slap.h"
-char *supportedExtensions[] = {
- NULL
-};
-
#if defined( SLAPD_MONITOR_DN )
void
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 );
* 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));
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;
send_ldap_result2(
Connection *conn,
Operation *op,
+ int disconnect,
ber_int_t err,
char *matched,
char *text,
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;
+ }
+
+#define LDAP_UNSOLICITED_ERROR(e) \
+ ( (e) == LDAP_PROTOCOL_ERROR \
+ || (e) == LDAP_STRONG_AUTH_REQUIRED \
+ || (e) == LDAP_UNAVAILABLE )
+
+ assert( LDAP_UNSOLICITED_ERROR( err ) );
- switch ( op->o_tag ) {
- case LBER_DEFAULT:
- tag = LBER_SEQUENCE;
- break;
+ } else {
+ msgid = op->o_msgid;
+
+ 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_SEARCH:
+ tag = LDAP_RES_SEARCH_RESULT;
+ break;
- case LDAP_REQ_DELETE:
- tag = LDAP_RES_DELETE;
- break;
+ case LDAP_REQ_DELETE:
+ tag = LDAP_RES_DELETE;
+ break;
- default:
- tag = op->o_tag + 1;
- break;
+ default:
+ tag = op->o_tag + 1;
+ break;
+ }
}
#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 ) {
{
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 );
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
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
Operation *op,
Entry *e,
char **attrs,
- int attrsonly
+ int attrsonly,
+ int opattrs
)
{
BerElement *ber;
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 ) )
{
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;
}
}
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;
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 );
}
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 );
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 )
{
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 );
}
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 );
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;
}
/* 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;
}
Operation *op,
Entry *e,
char **attrs,
- int attrsonly
+ int attrsonly,
+ int opattrs
)
{
assert(0);