X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=3048dd41bb26e3f411aa4fda2d3676fb0f1b91f7;hb=ed471a4d53b9bcd2cc89410743ffb4bd58b5fc05;hp=07be37e36e0a4673ba2fc7029bdbd374362b0150;hpb=bad62d2167c3db55203d71d904d84e4a11d13a62;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 07be37e36e..3048dd41bb 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -7,6 +7,7 @@ #include "portable.h" +#include "slapi_common.h" #include @@ -16,7 +17,9 @@ #include #include "slap.h" +#include "slapi.h" #include "lutil.h" +#include "lber_pvt.h" /* * If a module is configured as dynamic, its header should not @@ -44,6 +47,9 @@ #if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC) #include "back-monitor/external.h" #endif +#if defined(SLAPD_NULL) && !defined(SLAPD_NULL_DYNAMIC) +#include "back-null/external.h" +#endif #if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC) #include "back-passwd/external.h" #endif @@ -82,6 +88,9 @@ static BackendInfo binfo[] = { #if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC) {"monitor", monitor_back_initialize}, #endif +#if defined(SLAPD_NULL) && !defined(SLAPD_NULL_DYNAMIC) + {"null", null_back_initialize}, +#endif #if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC) {"passwd", passwd_back_initialize}, #endif @@ -117,8 +126,8 @@ int backend_init(void) if((nBackendInfo != 0) || (backendInfo != NULL)) { /* already initialized */ #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_ERR, - "backend_init: backend already initialized\n" )); + LDAP_LOG( BACKEND, ERR, + "backend_init: backend already initialized\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_init: already initialized.\n", 0, 0, 0 ); @@ -134,9 +143,9 @@ int backend_init(void) if(rc != 0) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_INFO, + LDAP_LOG( BACKEND, INFO, "backend_init: initialized for type \"%s\"\n", - binfo[nBackendInfo].bi_type )); + binfo[nBackendInfo].bi_type, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_init: initialized for type \"%s\"\n", @@ -166,8 +175,7 @@ int backend_init(void) #else #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_ERR, - "backend_init: failed\n" )); + LDAP_LOG( BACKEND, ERR, "backend_init: failed\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_init: failed\n", @@ -184,9 +192,9 @@ int backend_add(BackendInfo *aBackendInfo) if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_ERR, + LDAP_LOG( BACKEND, ERR, "backend_add: initialization for type \"%s\" failed\n", - aBackendInfo->bi_type )); + aBackendInfo->bi_type, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_add: initialization for type \"%s\" failed\n", @@ -225,9 +233,8 @@ int backend_startup(Backend *be) if( ! ( nBackendDB > 0 ) ) { /* no databases */ #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_INFO, - "backend_startup: %d databases to startup. \n", - nBackendDB )); + LDAP_LOG( BACKEND, INFO, + "backend_startup: %d databases to startup. \n", nBackendDB, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_startup: %d databases to startup.\n", @@ -239,46 +246,42 @@ int backend_startup(Backend *be) if(be != NULL) { /* startup a specific backend database */ #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1, - "backend_startup: starting \"%s\"\n", - be->be_suffix[0]->bv_val )); + LDAP_LOG( BACKEND, DETAIL1, "backend_startup: starting \"%s\"\n", + be->be_suffix[0].bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "backend_startup: starting \"%s\"\n", - be->be_suffix[0]->bv_val, 0, 0 ); + be->be_suffix[0].bv_val, 0, 0 ); #endif if ( be->bd_info->bi_open ) { rc = be->bd_info->bi_open( be->bd_info ); - } - - if(rc != 0) { + if ( rc != 0 ) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_CRIT, - "backend_startup: bi_open failed!\n" )); + LDAP_LOG( BACKEND, CRIT, "backend_startup: bi_open failed!\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "backend_startup: bi_open failed!\n", - 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "backend_startup: bi_open failed!\n", + 0, 0, 0 ); #endif - return rc; + return rc; + } } if ( be->bd_info->bi_db_open ) { rc = be->bd_info->bi_db_open( be ); - } - - if(rc != 0) { + if ( rc != 0 ) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_CRIT, - "backend_startup: bi_db_open failed! (%d)\n", rc )); + LDAP_LOG( BACKEND, CRIT, + "backend_startup: bi_db_open failed! (%d)\n", rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "backend_startup: bi_db_open failed! (%d)\n", - rc, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "backend_startup: bi_db_open failed! (%d)\n", + rc, 0, 0 ); #endif - return rc; + return rc; + } } return rc; @@ -294,18 +297,17 @@ int backend_startup(Backend *be) if( backendInfo[i].bi_open ) { rc = backendInfo[i].bi_open( &backendInfo[i] ); - } - - if(rc != 0) { + if ( rc != 0 ) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_CRIT, - "backend_startup: bi_open %d failed!\n", i )); + LDAP_LOG( BACKEND, CRIT, + "backend_startup: bi_open %d failed!\n", i, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "backend_startup: bi_open %d failed!\n", - i, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "backend_startup: bi_open %d failed!\n", + i, 0, 0 ); #endif - return rc; + return rc; + } } } @@ -317,19 +319,17 @@ int backend_startup(Backend *be) if ( backendDB[i].bd_info->bi_db_open ) { rc = backendDB[i].bd_info->bi_db_open( &backendDB[i] ); - } - - if(rc != 0) { + if ( rc != 0 ) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_CRIT, - "backend_startup: bi_db_open(%d) failed! (%d)\n", - i, rc )); + LDAP_LOG( BACKEND, CRIT, + "backend_startup: bi_db_open(%d) failed! (%d)\n", i, rc, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "backend_startup: bi_db_open(%d) failed! (%d)\n", - i, rc, 0 ); + Debug( LDAP_DEBUG_ANY, + "backend_startup: bi_db_open(%d) failed! (%d)\n", + i, rc, 0 ); #endif - return rc; + return rc; + } } } @@ -381,9 +381,9 @@ int backend_shutdown( Backend *be ) if(rc != 0) { #ifdef NEW_LOGGING - LDAP_LOG(( "backend", LDAP_LEVEL_NOTICE, - "backend_shutdown: bi_close %s failed!\n", - backendDB[i].be_type )); + LDAP_LOG( BACKEND, NOTICE, + "backend_shutdown: bi_close %s failed!\n", + backendDB[i].be_type, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "backend_close: bi_close %s failed!\n", @@ -418,8 +418,8 @@ int backend_destroy(void) if ( bd->bd_info->bi_db_destroy ) { bd->bd_info->bi_db_destroy( bd ); } - ber_bvecfree( bd->be_suffix ); - ber_bvecfree( bd->be_nsuffix ); + ber_bvarray_free( bd->be_suffix ); + ber_bvarray_free( bd->be_nsuffix ); if ( bd->be_rootdn.bv_val ) free( bd->be_rootdn.bv_val ); if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val ); if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val ); @@ -533,7 +533,7 @@ select_backend( for ( i = 0; i < nbackends; i++ ) { for ( j = 0; backends[i].be_nsuffix != NULL && - backends[i].be_nsuffix[j] != NULL; j++ ) + backends[i].be_nsuffix[j].bv_val != NULL; j++ ) { if (( backends[i].be_flags & SLAP_BFLAG_GLUE_SUBORDINATE ) && noSubs ) @@ -541,7 +541,7 @@ select_backend( continue; } - len = backends[i].be_nsuffix[j]->bv_len; + len = backends[i].be_nsuffix[j].bv_len; if ( len > dnlen ) { /* suffix is longer than DN */ @@ -558,7 +558,7 @@ select_backend( continue; } - if ( strcmp( backends[i].be_nsuffix[j]->bv_val, + if ( strcmp( backends[i].be_nsuffix[j].bv_val, &dn->bv_val[dnlen-len] ) == 0 ) { if( be == NULL ) { @@ -586,8 +586,8 @@ be_issuffix( { int i; - for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i] != NULL; i++ ) { - if ( ber_bvcmp( be->be_nsuffix[i], bvsuffix ) == 0 ) { + for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i].bv_val != NULL; i++ ) { + if ( bvmatch( &be->be_nsuffix[i], bvsuffix ) ) { return( 1 ); } } @@ -688,12 +688,60 @@ backend_unbind( Operation *op ) { - int i; + int i; + int rc; + Slapi_PBlock *pb = op->o_pb; + +#if defined( LDAP_SLAPI ) + slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn ); + slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op ); +#endif /* defined( LDAP_SLAPI ) */ for ( i = 0; i < nbackends; i++ ) { +#if defined( LDAP_SLAPI ) + slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] ); + rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, + (Slapi_PBlock *)pb ); + if ( rc != 0 && rc != LDAP_OTHER ) { + /* + * either there is no preOp (unbind) plugins + * or a plugin failed. Just log it. + * + * FIXME: is this correct? + */ +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preOps " + "failed\n", 0, 0, 0); +#else + Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preOps " + "failed.\n", 0, 0, 0); +#endif + } +#endif /* defined( LDAP_SLAPI ) */ + if ( backends[i].be_unbind ) { (*backends[i].be_unbind)( &backends[i], conn, op ); } + +#if defined( LDAP_SLAPI ) + rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, + (Slapi_PBlock *)pb ); + if ( rc != 0 && rc != LDAP_OTHER ) { + /* + * either there is no postOp (unbind) plugins + * or a plugin failed. Just log it. + * + * FIXME: is this correct? + */ +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postOps " + "failed\n", 0, 0, 0); +#else + Debug(LDAP_DEBUG_TRACE, "do_unbind: Unbind postOps " + "failed.\n", 0, 0, 0); +#endif + } +#endif /* defined( LDAP_SLAPI ) */ } return 0; @@ -738,15 +786,13 @@ backend_check_controls( Operation *op, const char **text ) { - LDAPControl **ctrls; - ctrls = op->o_ctrls; - if( ctrls == NULL ) { - return LDAP_SUCCESS; - } + LDAPControl **ctrls = op->o_ctrls; + + if( ctrls == NULL ) return LDAP_SUCCESS; for( ; *ctrls != NULL ; ctrls++ ) { if( (*ctrls)->ldctl_iscritical && - !charray_inlist( be->be_controls, (*ctrls)->ldctl_oid ) ) + !ldap_charray_inlist( be->be_controls, (*ctrls)->ldctl_oid ) ) { *text = "control unavailable in context"; return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; @@ -761,7 +807,7 @@ backend_check_restrictions( Backend *be, Connection *conn, Operation *op, - const void *opdata, + struct berval *opdata, const char **text ) { int rc; @@ -770,6 +816,8 @@ backend_check_restrictions( slap_mask_t opflag; slap_ssf_set_t *ssf; int updateop = 0; + int starttls = 0; + int session = 0; if( be ) { rc = backend_check_controls( be, conn, op, text ); @@ -795,6 +843,7 @@ backend_check_restrictions( break; case LDAP_REQ_BIND: opflag = SLAP_RESTRICT_OP_BIND; + session++; break; case LDAP_REQ_COMPARE: opflag = SLAP_RESTRICT_OP_COMPARE; @@ -805,7 +854,35 @@ backend_check_restrictions( break; case LDAP_REQ_EXTENDED: opflag = SLAP_RESTRICT_OP_EXTENDED; + + if( !opdata ) { + /* treat unspecified as a modify */ + opflag = SLAP_RESTRICT_OP_MODIFY; + updateop++; + break; + } + + { + struct berval bv = BER_BVC( LDAP_EXOP_START_TLS ); + if( bvmatch( opdata, &bv ) ) { + session++; + starttls++; + break; + } + } + + { + struct berval bv = BER_BVC( LDAP_EXOP_X_WHO_AM_I ); + if( bvmatch( opdata, &bv ) ) { + break; + } + } + + /* treat everything else as a modify */ + opflag = SLAP_RESTRICT_OP_MODIFY; + updateop++; break; + case LDAP_REQ_MODIFY: updateop++; opflag = SLAP_RESTRICT_OP_MODIFY; @@ -818,6 +895,7 @@ backend_check_restrictions( opflag = SLAP_RESTRICT_OP_SEARCH; break; case LDAP_REQ_UNBIND: + session++; opflag = 0; break; default: @@ -825,16 +903,9 @@ backend_check_restrictions( return LDAP_OTHER; } - if ( op->o_tag != LDAP_REQ_EXTENDED - || strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) ) - { + if ( !starttls ) { /* these checks don't apply to StartTLS */ - if( op->o_tag == LDAP_REQ_EXTENDED ) { - /* threat other extended operations as update ops */ - updateop++; - } - if( op->o_transport_ssf < ssf->sss_transport ) { *text = "transport confidentiality required"; return LDAP_CONFIDENTIALITY_REQUIRED; @@ -845,6 +916,15 @@ backend_check_restrictions( return LDAP_CONFIDENTIALITY_REQUIRED; } + + if( op->o_tag == LDAP_REQ_BIND && opdata == NULL ) { + /* simple bind specific check */ + if( op->o_ssf < ssf->sss_simple_bind ) { + *text = "confidentiality required"; + return LDAP_CONFIDENTIALITY_REQUIRED; + } + } + if( op->o_tag != LDAP_REQ_BIND || opdata == NULL ) { /* these checks don't apply to SASL bind */ @@ -880,21 +960,30 @@ backend_check_restrictions( return LDAP_CONFIDENTIALITY_REQUIRED; } - if( op->o_ndn.bv_len == 0 ) { + if( !( global_allows & SLAP_ALLOW_UPDATE_ANON ) && + op->o_ndn.bv_len == 0 ) + { *text = "modifications require authentication"; - return LDAP_OPERATIONS_ERROR; + return LDAP_STRONG_AUTH_REQUIRED; + } + +#ifdef SLAP_X_LISTENER_MOD + if ( ! ( conn->c_listener->sl_perms & S_IWUSR ) ) { + /* no "w" mode means readonly */ + *text = "modifications not allowed on this listener"; + return LDAP_UNWILLING_TO_PERFORM; } +#endif /* SLAP_X_LISTENER_MOD */ } } - if ( op->o_tag != LDAP_REQ_BIND && ( op->o_tag != LDAP_REQ_EXTENDED || - strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) ) ) - { - /* these checks don't apply to Bind or StartTLS */ + if ( !session ) { + /* these checks don't apply to Bind, StartTLS, or Unbind */ if( requires & SLAP_REQUIRE_STRONG ) { /* should check mechanism */ - if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 ) + if( ( op->o_transport_ssf < ssf->sss_transport + && op->o_authmech.bv_len == 0 ) || op->o_dn.bv_len == 0 ) { *text = "strong authentication required"; return LDAP_STRONG_AUTH_REQUIRED; @@ -902,8 +991,7 @@ backend_check_restrictions( } if( requires & SLAP_REQUIRE_SASL ) { - if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 ) - { + if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 ) { *text = "SASL authentication required"; return LDAP_STRONG_AUTH_REQUIRED; } @@ -936,6 +1024,25 @@ backend_check_restrictions( return LDAP_OPERATIONS_ERROR; } } + +#ifdef SLAP_X_LISTENER_MOD + if ( !starttls && op->o_dn.bv_len == 0 ) { + if ( ! ( conn->c_listener->sl_perms & S_IXUSR ) ) { + /* no "x" mode means bind required */ + *text = "bind required on this listener"; + return LDAP_STRONG_AUTH_REQUIRED; + } + } + + if ( !starttls && !updateop ) { + if ( ! ( conn->c_listener->sl_perms & S_IRUSR ) ) { + /* no "r" mode means no read */ + *text = "read not allowed on this listener"; + return LDAP_UNWILLING_TO_PERFORM; + } + } +#endif /* SLAP_X_LISTENER_MOD */ + } if( restrictops & opflag ) { @@ -987,12 +1094,8 @@ backend_group( ) { GroupAssertion *g; - int i; - ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); - i = op->o_abandon; - ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); - if (i) return SLAPD_ABANDON; + if ( op->o_abandon ) return SLAPD_ABANDON; if ( !dn_match( &target->e_nname, gr_ndn ) ) { /* we won't attempt to send it to a different backend */ @@ -1005,6 +1108,7 @@ backend_group( } ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + for (g = conn->c_groups; g; g=g->ga_next) { if (g->ga_be != be || g->ga_oc != group_oc || g->ga_at != group_at || g->ga_len != gr_ndn->bv_len) @@ -1012,7 +1116,9 @@ backend_group( if (strcmp( g->ga_ndn, gr_ndn->bv_val ) == 0) break; } + ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); + if (g) { return g->ga_res; } @@ -1022,7 +1128,7 @@ backend_group( target, gr_ndn, op_ndn, group_oc, group_at ); - if (op->o_tag != LDAP_REQ_BIND) { + if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) { g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len); g->ga_be = be; g->ga_oc = group_oc; @@ -1081,16 +1187,17 @@ Attribute *backend_operational( { Attribute *a = NULL, **ap = &a; -#ifdef SLAPD_SCHEMA_DN - *ap = slap_operational_subschemaSubentry(); - ap = &(*ap)->a_next; -#endif - /* * If operational attributes (allegedly) are required, * and the backend supports specific operational attributes, * add them to the attribute list */ + if ( opattrs || ( attrs && + ad_inlist( slap_schema.si_ad_subschemaSubentry, attrs )) ) { + *ap = slap_operational_subschemaSubentry( be ); + ap = &(*ap)->a_next; + } + if ( ( opattrs || attrs ) && be && be->be_operational != NULL ) { ( void )be->be_operational( be, conn, op, e, attrs, opattrs, ap ); }