From bc1cd9514938a3deb121c0b8afe5ee2c4dab5113 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 9 Jan 2002 06:29:54 +0000 Subject: [PATCH] Rework control infrastructure a bit. Add subentries visibility control. --- servers/slapd/controls.c | 197 +++++++++++++++++++++++++++++-------- servers/slapd/dn.c | 8 +- servers/slapd/proto-slap.h | 11 +-- servers/slapd/root_dse.c | 3 +- servers/slapd/search.c | 13 +-- servers/slapd/slap.h | 10 ++ 6 files changed, 180 insertions(+), 62 deletions(-) diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 9782433128..3683e23bb5 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -19,12 +19,64 @@ #include "../../libraries/liblber/lber-int.h" -char *supportedControls[] = { - LDAP_CONTROL_MANAGEDSAIT, - LDAP_CONTROL_SUBENTRIES, - NULL +#define SLAP_CTRL_ABANDON 0x0001 +#define SLAP_CTRL_ADD 0x2002 +#define SLAP_CTRL_BIND 0x0004 +#define SLAP_CTRL_COMPARE 0x1008 +#define SLAP_CTRL_DELETE 0x2010 +#define SLAP_CTRL_MODIFY 0x2020 +#define SLAP_CTRL_RENAME 0x2040 +#define SLAP_CTRL_SEARCH 0x1080 +#define SLAP_CTRL_UNBIND 0x0100 + +#define SLAP_CTRL_INTROGATE (SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH) +#define SLAP_CTRL_UPDATE \ + (SLAP_CTRL_ADD|SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME) +#define SLAP_CTRL_ACCESS (SLAP_CTRL_INTROGATE|SLAP_CTRL_UPDATE) + +typedef int (SLAP_CTRL_PARSE_FN) LDAP_P(( + Connection *conn, + Operation *op, + LDAPControl *ctrl, + const char **text )); + +static SLAP_CTRL_PARSE_FN parseManageDSAit; +static SLAP_CTRL_PARSE_FN parseSubentries; + +static struct slap_control { + char *sc_oid; + int sc_ops_mask; + char **sc_extendedops; + SLAP_CTRL_PARSE_FN *sc_parse; + +} supportedControls[] = { + { LDAP_CONTROL_MANAGEDSAIT, + SLAP_CTRL_ACCESS, NULL, + parseManageDSAit }, + { LDAP_CONTROL_SUBENTRIES, + SLAP_CTRL_SEARCH, NULL, + parseSubentries }, + { NULL } }; +char * +get_supported_ctrl(int index) +{ + return supportedControls[index].sc_oid; +} + +static struct slap_control * +find_ctrl( const char *oid ) +{ + int i; + for( i=0; supportedControls[i].sc_oid; i++ ) { + if( strcmp( oid, supportedControls[i].sc_oid ) == 0 ) { + return &supportedControls[i]; + } + } + return NULL; +} + int get_ctrls( Connection *conn, Operation *op, @@ -36,6 +88,7 @@ int get_ctrls( char *opaque; BerElement *ber = op->o_ber; LDAPControl ***ctrls = &op->o_ctrls; + struct slap_control *c; int rc = LDAP_SUCCESS; char *errmsg = NULL; @@ -192,11 +245,69 @@ int get_ctrls( } } - if( tctrl->ldctl_iscritical && - !charray_inlist( supportedControls, tctrl->ldctl_oid ) ) - { + c = find_ctrl( tctrl->ldctl_oid ); + if( c != NULL ) { + /* recongized control */ + int tagmask = -1; + switch( op->o_tag ) { + case LDAP_REQ_ADD: + tagmask = SLAP_CTRL_ADD; + break; + case LDAP_REQ_BIND: + tagmask = SLAP_CTRL_BIND; + break; + case LDAP_REQ_COMPARE: + tagmask = SLAP_CTRL_COMPARE; + break; + case LDAP_REQ_DELETE: + tagmask = SLAP_CTRL_DELETE; + break; + case LDAP_REQ_MODIFY: + tagmask = SLAP_CTRL_MODIFY; + break; + case LDAP_REQ_RENAME: + tagmask = SLAP_CTRL_RENAME; + break; + case LDAP_REQ_SEARCH: + tagmask = SLAP_CTRL_SEARCH; + break; + case LDAP_REQ_UNBIND: + tagmask = SLAP_CTRL_UNBIND; + break; + case LDAP_REQ_EXTENDED: + /* FIXME: check list of extended operations */ + tagmask = -1; + break; + default: + rc = LDAP_OTHER; + errmsg = "controls internal error"; + goto return_results; + } + + if (( c->sc_ops_mask & tagmask ) == tagmask ) { + /* available extension */ + + if( !c->sc_parse ) { + rc = LDAP_OTHER; + errmsg = "not yet implemented"; + goto return_results; + } + + rc = c->sc_parse( conn, op, tctrl, &errmsg ); + + if( rc != LDAP_SUCCESS ) goto return_results; + + } else if( tctrl->ldctl_iscritical ) { + /* unavailable CRITICAL control */ + rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; + errmsg = "critical extension is unavailable"; + goto return_results; + } + + } else if( tctrl->ldctl_iscritical ) { + /* unrecongized CRITICAL control */ rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; - errmsg = "critical extension is unavailable "; + errmsg = "critical extension is not recongized"; goto return_results; } @@ -225,46 +336,54 @@ return_results: return rc; } - -int get_manageDSAit( Operation *op ) +static int parseManageDSAit ( + Connection *conn, + Operation *op, + LDAPControl *ctrl, + const char **text ) { - int i; - if( op == NULL || op->o_ctrls == NULL ) { - return SLAP_NO_CONTROL; + if ( op->o_managedsait != SLAP_NO_CONTROL ) { + *text = "manageDSAit control specified multiple times"; + return LDAP_PROTOCOL_ERROR; } - for( i=0; op->o_ctrls[i] != NULL; i++ ) { - if( strcmp( LDAP_CONTROL_MANAGEDSAIT, - op->o_ctrls[i]->ldctl_oid ) == 0 ) - { - return op->o_ctrls[i]->ldctl_iscritical - ? SLAP_CRITICAL_CONTROL - : SLAP_NONCRITICAL_CONTROL; - } + if ( ctrl->ldctl_value.bv_len ) { + *text = "manageDSAit control value not empty"; + return LDAP_PROTOCOL_ERROR; } - return SLAP_NO_CONTROL; + op->o_managedsait = ctrl->ldctl_iscritical + ? SLAP_CRITICAL_CONTROL + : SLAP_NONCRITICAL_CONTROL; + + return LDAP_SUCCESS; } -int get_subentries( Operation *op, int *visibility ) +static int parseSubentries ( + Connection *conn, + Operation *op, + LDAPControl *ctrl, + const char **text ) { - int i; - if( op == NULL || op->o_ctrls == NULL ) { - return SLAP_NO_CONTROL; + if ( op->o_subentries != SLAP_NO_CONTROL ) { + *text = "subentries control specified multiple times"; + return LDAP_PROTOCOL_ERROR; } - for( i=0; op->o_ctrls[i] != NULL; i++ ) { - if( strcmp( LDAP_CONTROL_SUBENTRIES, - op->o_ctrls[i]->ldctl_oid ) == 0 ) - { - /* need to parse the value */ - *visibility = 0; - - return op->o_ctrls[i]->ldctl_iscritical - ? SLAP_CRITICAL_CONTROL - : SLAP_NONCRITICAL_CONTROL; - } + /* FIXME: should use BER library */ + if( ( ctrl->ldctl_value.bv_len != 3 ) + && ( ctrl->ldctl_value.bv_val[0] != 0x01 ) + && ( ctrl->ldctl_value.bv_val[1] != 0x01 )) + { + *text = "subentries control value encoding is bogus"; + return LDAP_PROTOCOL_ERROR; } - return SLAP_NO_CONTROL; -} + op->o_subentries = ctrl->ldctl_iscritical + ? SLAP_CRITICAL_CONTROL + : SLAP_NONCRITICAL_CONTROL; + + op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00); + + return LDAP_SUCCESS; +} \ No newline at end of file diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index 0f359d4a5f..52cbb6e8be 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -646,7 +646,7 @@ dnParent( const char *p; int rc; - rc = ldap_str2rdn( dn, NULL, &p, LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP ); + rc = ldap_str2rdn( dn, NULL, & (char *) p, LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP ); if ( rc != LDAP_SUCCESS ) { return rc; } @@ -719,7 +719,7 @@ dnExtractRdn( return LDAP_OTHER; } - rc = ldap_str2rdn( dn->bv_val, &tmpRDN, &p, LDAP_DN_FORMAT_LDAP ); + rc = ldap_str2rdn( dn->bv_val, &tmpRDN, &(char *)p, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return rc; } @@ -758,7 +758,7 @@ dn_rdnlen( return 0; } - rc = ldap_str2rdn( dn_in->bv_val, NULL, &p, + rc = ldap_str2rdn( dn_in->bv_val, NULL, &(char *)p, LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP ); if ( rc != LDAP_SUCCESS ) { return 0; @@ -904,7 +904,7 @@ rdn_attrs( const char * rdn, char ***types, char ***values) assert( *values == NULL ); assert( types == NULL || *types == NULL ); - rc = ldap_str2rdn( rdn, &tmpRDN, &p, LDAP_DN_FORMAT_LDAP ); + rc = ldap_str2rdn( rdn, &tmpRDN, &(char *)p, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return rc; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 998d5f1383..0bf1aa33d2 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -287,15 +287,13 @@ LDAP_SLAPD_F (char *) slap_strcopy LDAP_P(( /* * controls.c */ -#define SLAP_NO_CONTROL 0 -#define SLAP_NONCRITICAL_CONTROL 1 -#define SLAP_CRITICAL_CONTROL 2 - LDAP_SLAPD_F (int) get_ctrls LDAP_P(( Connection *co, Operation *op, int senderrors )); +LDAP_SLAPD_F (char *) get_supported_ctrl LDAP_P((int index)); + LDAP_SLAPD_F (int) get_manageDSAit LDAP_P(( Operation *op )); LDAP_SLAPD_F (int) get_subentries LDAP_P(( Operation *op, int *visibility )); @@ -565,11 +563,6 @@ LDAP_SLAPD_F (void) *module_resolve LDAP_P(( #endif /* SLAPD_MODULES */ -/* - * controls.c - */ -LDAP_SLAPD_V (char *) supportedControls[]; - /* * mra.c */ diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index ff72b78fdf..4edcebbb80 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -98,8 +98,7 @@ root_dse_info( /* altServer unsupported */ /* supportedControl */ - for ( i=0; supportedControls[i] != NULL; i++ ) { - vals[0].bv_val = supportedControls[i]; + for ( i=0; (vals[0].bv_val = get_supported_ctrl(i)) != NULL; i++ ) { vals[0].bv_len = strlen( vals[0].bv_val ); attr_merge( e, ad_supportedControl, vals ); } diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 75795eaabf..6213d10d8b 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -155,7 +155,6 @@ do_search( Debug( LDAP_DEBUG_ARGS, " filter: %s\n", fstr.bv_val, 0, 0 ); #endif - /* attributes */ siz = sizeof(AttributeName); off = 0; @@ -180,9 +179,7 @@ do_search( #endif goto return_results; - } - - rc = LDAP_SUCCESS; + } #ifdef NEW_LOGGING LDAP_LOG(( "operation", LDAP_LEVEL_ARGS, @@ -191,7 +188,6 @@ do_search( Debug( LDAP_DEBUG_ARGS, " attrs:", 0, 0, 0 ); #endif - if ( siz != 0 ) { for ( i = 0; io_protocol==LDAP_VERSION2 && conn->c_is_udp) { goto return_results; } @@ -320,7 +316,8 @@ do_search( timelimit, filter, &fstr, an, attrsonly ); } else { send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, - NULL, "operation not supported within namingContext", NULL, NULL ); + NULL, "operation not supported within namingContext", + NULL, NULL ); } return_results:; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 32f1541e49..8fc0fc5b20 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1315,8 +1315,18 @@ typedef struct slap_op { LDAP_STAILQ_ENTRY(slap_op) o_next; /* next operation in list */ void *o_private; /* anything the backend needs */ void *o_glue; /* for the glue backend */ + +#define SLAP_NO_CONTROL 0 +#define SLAP_NONCRITICAL_CONTROL 1 +#define SLAP_CRITICAL_CONTROL 2 + + char o_managedsait; + char o_subentries; + char o_subentries_visibility; } Operation; +#define get_manageDSAit(op) ((int)(op)->o_managedsait) + /* * Caches the result of a backend_group check for ACL evaluation */ -- 2.39.5