X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbconfig.c;h=6d4153cb6e750ac35fc10a70733be30e05c4a749;hb=ca7f697e14087234e44c96fb7edd81cfb14183dc;hp=1275e1d5274132d3002215ac20ef17bf3fd9469b;hpb=a773a0cc14be2d35c266fb6a470a70138f983035;p=openldap diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 1275e1d527..6d4153cb6e 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2005-2014 The OpenLDAP Foundation. + * Copyright 2005-2017 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -200,6 +200,9 @@ enum { CFG_DISABLED, CFG_THREADQS, CFG_TLS_ECNAME, + CFG_TLS_CACERT, + CFG_TLS_CERT, + CFG_TLS_KEY, CFG_LAST }; @@ -695,7 +698,16 @@ static ConfigTable config_back_cf_table[] = { "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, { "timelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC, &config_timelimit, "( OLcfgGlAt:67 NAME 'olcTimeLimit' " - "SYNTAX OMsDirectoryString )", NULL, NULL }, + "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + { "TLSCACertificate", NULL, 2, 2, 0, +#ifdef HAVE_TLS + CFG_TLS_CACERT|ARG_BINARY|ARG_MAGIC, &config_tls_option, +#else + ARG_IGNORED, NULL, +#endif + "( OLcfgGlAt:97 NAME 'olcTLSCACertificate' " + "DESC 'X.509 certificate, must use ;binary' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 SINGLE-VALUE )", NULL, NULL }, { "TLSCACertificateFile", NULL, 2, 2, 0, #ifdef HAVE_TLS CFG_TLS_CA_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option, @@ -712,6 +724,15 @@ static ConfigTable config_back_cf_table[] = { #endif "( OLcfgGlAt:69 NAME 'olcTLSCACertificatePath' " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + { "TLSCertificate", NULL, 2, 2, 0, +#ifdef HAVE_TLS + CFG_TLS_CERT|ARG_BINARY|ARG_MAGIC, &config_tls_option, +#else + ARG_IGNORED, NULL, +#endif + "( OLcfgGlAt:98 NAME 'olcTLSCertificate' " + "DESC 'X.509 certificate, must use ;binary' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 SINGLE-VALUE )", NULL, NULL }, { "TLSCertificateFile", NULL, 2, 2, 0, #ifdef HAVE_TLS CFG_TLS_CERT_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option, @@ -720,6 +741,15 @@ static ConfigTable config_back_cf_table[] = { #endif "( OLcfgGlAt:70 NAME 'olcTLSCertificateFile' " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + { "TLSCertificateKey", NULL, 2, 2, 0, +#ifdef HAVE_TLS + CFG_TLS_KEY|ARG_BINARY|ARG_MAGIC, &config_tls_option, +#else + ARG_IGNORED, NULL, +#endif + "( OLcfgGlAt:99 NAME 'olcTLSCertificateKey' " + "DESC 'X.509 privateKey, must use ;binary' " + "SYNTAX 1.3.6.1.4.1.4203.666.2.13 SINGLE-VALUE )", NULL, NULL }, { "TLSCertificateKeyFile", NULL, 2, 2, 0, #ifdef HAVE_TLS CFG_TLS_CERT_KEY|ARG_STRING|ARG_MAGIC, &config_tls_option, @@ -868,6 +898,7 @@ static ConfigOCs cf_ocs[] = { "olcTimeLimit $ olcTLSCACertificateFile $ " "olcTLSCACertificatePath $ olcTLSCertificateFile $ " "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ " + "olcTLSCACertificate $ olcTLSCertificate $ olcTLSCertificateKey $ " "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSECName $ " "olcTLSCRLFile $ olcTLSProtocolMin $ olcToolThreads $ olcWriteTimeout $ " "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ " @@ -3203,9 +3234,9 @@ config_suffix(ConfigArgs *c) if(tbe == c->be) { Debug( LDAP_DEBUG_ANY, "%s: suffix already served by this backend!.\n", c->log, 0, 0); - return 1; free(pdn.bv_val); free(ndn.bv_val); + return 1; } else if(tbe) { BackendDB *b2 = tbe; @@ -3285,7 +3316,7 @@ config_rootpw(ConfigArgs *c) { } tbe = select_backend(&c->be->be_rootndn, 0); - if(tbe != c->be) { + if(tbe != c->be && !SLAP_DBHIDDEN( c->be )) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> can only be set when rootdn is under suffix", c->argv[0] ); Debug(LDAP_DEBUG_ANY, "%s: %s\n", @@ -4060,7 +4091,8 @@ config_tls_cleanup(ConfigArgs *c) { static int config_tls_option(ConfigArgs *c) { - int flag; + int flag, rc; + int berval = 0; LDAP *ld = slap_tls_ld; switch(c->type) { case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; ld = NULL; break; @@ -4074,20 +4106,25 @@ config_tls_option(ConfigArgs *c) { #ifdef HAVE_GNUTLS case CFG_TLS_CRL_FILE: flag = LDAP_OPT_X_TLS_CRLFILE; break; #endif + case CFG_TLS_CACERT: flag = LDAP_OPT_X_TLS_CACERT; berval = 1; break; + case CFG_TLS_CERT: flag = LDAP_OPT_X_TLS_CERT; berval = 1; break; + case CFG_TLS_KEY: flag = LDAP_OPT_X_TLS_KEY; berval = 1; break; default: Debug(LDAP_DEBUG_ANY, "%s: " "unknown tls_option <0x%x>\n", c->log, c->type, 0); return 1; } if (c->op == SLAP_CONFIG_EMIT) { - return ldap_pvt_tls_get_option( ld, flag, &c->value_string ); + return ldap_pvt_tls_get_option( ld, flag, berval ? (void *)&c->value_bv : (void *)&c->value_string ); } else if ( c->op == LDAP_MOD_DELETE ) { c->cleanup = config_tls_cleanup; return ldap_pvt_tls_set_option( ld, flag, NULL ); } - ch_free(c->value_string); + if ( !berval ) ch_free(c->value_string); c->cleanup = config_tls_cleanup; - return(ldap_pvt_tls_set_option(ld, flag, c->argv[1])); + rc = ldap_pvt_tls_set_option(ld, flag, berval ? (void *)&c->value_bv : (void *)c->argv[1]); + if ( berval ) ch_free(c->value_bv.bv_val); + return rc; } /* FIXME: this ought to be provided by libldap */ @@ -4560,6 +4597,8 @@ config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad, ConfigArgs *ca ) { int i, j; + if (ad->ad_flags & SLAP_DESC_BINARY) + ad = ad->ad_type->sat_ad; for (j=0; jco_table[i].name; i++) @@ -4658,10 +4697,14 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr ) } for ( i=0; vals[i].bv_val; i++ ) { ca->line = vals[i].bv_val; + ca->linelen = vals[i].bv_len; if (( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) && ca->line[0] == '{' ) { char *idx = strchr( ca->line, '}' ); - if ( idx ) ca->line = idx+1; + if ( idx ) { + ca->linelen -= (idx+1) - ca->line; + ca->line = idx+1; + } } rc = config_parse_vals( ct, ca, i ); if ( rc ) { @@ -4720,8 +4763,10 @@ config_rename_one( Operation *op, SlapReply *rs, Entry *e, struct berval *nnewrdn, int use_ldif ) { char *ptr1; - int rc = 0; + int cnt, rc = 0; struct berval odn, ondn; + const char *text = ""; + LDAPRDN rDN; odn = e->e_name; ondn = e->e_nname; @@ -4729,19 +4774,41 @@ config_rename_one( Operation *op, SlapReply *rs, Entry *e, build_new_dn( &e->e_nname, &parent->ce_entry->e_nname, nnewrdn, NULL ); /* Replace attr */ - free( a->a_vals[0].bv_val ); - ptr1 = strchr( newrdn->bv_val, '=' ) + 1; - a->a_vals[0].bv_len = newrdn->bv_len - (ptr1 - newrdn->bv_val); - a->a_vals[0].bv_val = ch_malloc( a->a_vals[0].bv_len + 1 ); - strcpy( a->a_vals[0].bv_val, ptr1 ); - - if ( a->a_nvals != a->a_vals ) { - free( a->a_nvals[0].bv_val ); - ptr1 = strchr( nnewrdn->bv_val, '=' ) + 1; - a->a_nvals[0].bv_len = nnewrdn->bv_len - (ptr1 - nnewrdn->bv_val); - a->a_nvals[0].bv_val = ch_malloc( a->a_nvals[0].bv_len + 1 ); - strcpy( a->a_nvals[0].bv_val, ptr1 ); + rc = ldap_bv2rdn( &e->e_name, &rDN, (char **)&text, LDAP_DN_FORMAT_LDAP ); + if ( rc ) { + return rc; } + for ( cnt = 0; rDN[cnt]; cnt++ ) { + AttributeDescription *ad = NULL; + LDAPAVA *ava = rDN[cnt]; + + rc = slap_bv2ad( &ava->la_attr, &ad, &text ); + if ( rc ) { + break; + } + + if ( ad != a->a_desc ) continue; + + free( a->a_vals[0].bv_val ); + ber_dupbv( &a->a_vals[0], &ava->la_value ); + if ( a->a_nvals != a->a_vals ) { + free( a->a_nvals[0].bv_val ); + rc = attr_normalize_one( ad, &ava->la_value, &a->a_nvals[0], NULL ); + if ( rc ) { + break; + } + } + + /* attributes with X-ORDERED 'SIBLINGS' are single-valued, we're done */ + break; + } + /* the attribute must be present in rDN */ + assert( rDN[cnt] ); + ldap_rdnfree( rDN ); + if ( rc ) { + return rc; + } + if ( use_ldif ) { CfBackInfo *cfb = (CfBackInfo *)op->o_bd->be_private; BackendDB *be = op->o_bd; @@ -4926,7 +4993,7 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e, if ( ce_type == Cft_Database ) nsibs--; - if ( index != nsibs ) { + if ( index != nsibs || isfrontend ) { if ( gotindex ) { if ( index < nsibs ) { if ( tailindex ) return LDAP_NAMING_VIOLATION; @@ -5423,10 +5490,12 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, char *iptr = NULL; ca->valx = -1; ca->line = a->a_vals[i].bv_val; + ca->linelen = a->a_vals[i].bv_len; if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED ) { ptr = strchr( ca->line, '}' ); if ( ptr ) { iptr = strchr( ca->line, '{' ); + ca->linelen -= (ptr+1) - ca->line; ca->line = ptr+1; } } @@ -5614,7 +5683,7 @@ static int config_back_add( Operation *op, SlapReply *rs ) { CfBackInfo *cfb; - int renumber; + int renumber, dopause = 1; ConfigArgs ca; if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry, @@ -5655,7 +5724,8 @@ config_back_add( Operation *op, SlapReply *rs ) rs->sr_err = SLAPD_ABANDON; goto out; } - ldap_pvt_thread_pool_pause( &connection_pool ); + if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 ) + dopause = 0; /* Strategy: * 1) check for existence of entry @@ -5705,7 +5775,8 @@ config_back_add( Operation *op, SlapReply *rs ) } out2:; - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) + ldap_pvt_thread_pool_resume( &connection_pool ); out:; { int repl = op->o_dont_replicate; @@ -5745,6 +5816,7 @@ config_modify_add( ConfigTable *ct, ConfigArgs *ca, AttributeDescription *ad, if ( next == ca->line + 1 || next[ 0 ] != '}' ) { return LDAP_OTHER; } + ca->linelen -= (ptr+1) - ca->line; ca->line = ptr+1; } } @@ -5966,6 +6038,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs, bv.bv_val = ptr; } ca->line = bv.bv_val; + ca->linelen = bv.bv_len; ca->valx = d->idx[i]; config_parse_vals(ct, ca, d->idx[i] ); rc = config_del_vals( ct, ca ); @@ -6004,6 +6077,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs, break; for (i=0; ml->sml_values[i].bv_val; i++) { ca->line = ml->sml_values[i].bv_val; + ca->linelen = ml->sml_values[i].bv_len; ca->valx = -1; rc = config_modify_add( ct, ca, ml->sml_desc, i ); if ( rc ) @@ -6033,6 +6107,7 @@ out: } for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) { ca->line = s->a_vals[i].bv_val; + ca->linelen = s->a_vals[i].bv_len; ca->valx = -1; config_modify_add( ct, ca, s->a_desc, i ); } @@ -6050,6 +6125,7 @@ out: s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD); for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) { ca->line = s->a_vals[i].bv_val; + ca->linelen = s->a_vals[i].bv_len; ca->valx = -1; config_modify_add( ct, ca, s->a_desc, i ); } @@ -6141,7 +6217,8 @@ config_back_modify( Operation *op, SlapReply *rs ) rs->sr_err = SLAPD_ABANDON; goto out; } - ldap_pvt_thread_pool_pause( &connection_pool ); + if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 ) + do_pause = 0; } /* Strategy: @@ -6188,7 +6265,7 @@ config_back_modrdn( Operation *op, SlapReply *rs ) CfBackInfo *cfb; CfEntryInfo *ce, *last; struct berval rdn; - int ixold, ixnew; + int ixold, ixnew, dopause = 1; cfb = (CfBackInfo *)op->o_bd->be_private; @@ -6310,7 +6387,8 @@ config_back_modrdn( Operation *op, SlapReply *rs ) rs->sr_err = SLAPD_ABANDON; goto out; } - ldap_pvt_thread_pool_pause( &connection_pool ); + if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 ) + dopause = 0; if ( ce->ce_type == Cft_Schema ) { req_modrdn_s modr = op->oq_modrdn; @@ -6377,7 +6455,8 @@ config_back_modrdn( Operation *op, SlapReply *rs ) op->oq_modrdn = modr; } - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) + ldap_pvt_thread_pool_resume( &connection_pool ); out: send_ldap_result( op, rs ); return rs->sr_err; @@ -6389,6 +6468,7 @@ config_back_delete( Operation *op, SlapReply *rs ) #ifdef SLAP_CONFIG_DELETE CfBackInfo *cfb; CfEntryInfo *ce, *last, *ce2; + int dopause = 1; cfb = (CfBackInfo *)op->o_bd->be_private; @@ -6407,7 +6487,8 @@ config_back_delete( Operation *op, SlapReply *rs ) char *iptr; int count, ixold; - ldap_pvt_thread_pool_pause( &connection_pool ); + if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 ) + dopause = 0; if ( ce->ce_type == Cft_Overlay ){ overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi, op ); @@ -6427,7 +6508,7 @@ config_back_delete( Operation *op, SlapReply *rs ) if ( !oc_at ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "objectclass not found"; - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool ); goto out; } for ( i=0; !BER_BVISNULL(&oc_at->a_nvals[i]); i++ ) { @@ -6445,7 +6526,7 @@ config_back_delete( Operation *op, SlapReply *rs ) /* FIXME: We should return a helpful error message * here */ } - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool ); goto out; } break; @@ -6454,7 +6535,7 @@ config_back_delete( Operation *op, SlapReply *rs ) if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){ rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "Cannot delete config or frontend database"; - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool ); goto out; } if ( ce->ce_be->bd_info->bi_db_close ) { @@ -6516,7 +6597,7 @@ config_back_delete( Operation *op, SlapReply *rs ) ce->ce_entry->e_private=NULL; entry_free(ce->ce_entry); ch_free(ce); - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool ); } else { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; } @@ -6696,13 +6777,14 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent, struct berval val; struct berval ad_name; AttributeDescription *ad = NULL; - int rc; + int cnt, rc; char *ptr; const char *text = ""; Attribute *oc_at; struct berval pdn; ObjectClass *oc; CfEntryInfo *ceprev = NULL; + LDAPRDN rDN; Debug( LDAP_DEBUG_TRACE, "config_build_entry: \"%s\"\n", rdn->bv_val, 0, 0); e->e_private = ce; @@ -6731,16 +6813,35 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent, if ( extra ) attr_merge_normalize_one(e, slap_schema.si_ad_objectClass, extra->co_name, NULL ); - ptr = strchr(rdn->bv_val, '='); - ad_name.bv_val = rdn->bv_val; - ad_name.bv_len = ptr - rdn->bv_val; - rc = slap_bv2ad( &ad_name, &ad, &text ); + + rc = ldap_bv2rdn( rdn, &rDN, (char **)&text, LDAP_DN_FORMAT_LDAP ); + if ( rc ) { + goto fail; + } + for ( cnt = 0; rDN[cnt]; cnt++ ) { + LDAPAVA *ava = rDN[cnt]; + + ad = NULL; + rc = slap_bv2ad( &ava->la_attr, &ad, &text ); + if ( rc ) { + break; + } + if ( !ad->ad_type->sat_equality ) { + rc = LDAP_CONSTRAINT_VIOLATION; + text = "attribute has no equality matching rule"; + break; + } + if ( !ad->ad_type->sat_equality->smr_match ) { + rc = LDAP_CONSTRAINT_VIOLATION; + text = "attribute has unsupported equality matching rule"; + break; + } + attr_merge_normalize_one(e, ad, &ava->la_value, NULL ); + } + ldap_rdnfree( rDN ); if ( rc ) { goto fail; } - val.bv_val = ptr+1; - val.bv_len = rdn->bv_len - (val.bv_val - rdn->bv_val); - attr_merge_normalize_one(e, ad, &val, NULL ); oc = main->co_oc; c->table = main->co_type; @@ -6838,7 +6939,12 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent, bv.bv_len ); c->value_dn.bv_len += bv.bv_len; c->value_dn.bv_val[c->value_dn.bv_len] ='\0'; - rdnNormalize( 0, NULL, NULL, &c->value_dn, &rdn, NULL ); + if ( rdnNormalize( 0, NULL, NULL, &c->value_dn, &rdn, NULL )) { + Debug( LDAP_DEBUG_ANY, + "config_build_schema_inc: invalid schema name \"%s\"\n", + bv.bv_val, 0, 0 ); + return -1; + } c->ca_private = cf; e = config_build_entry( op, rs, ceparent, c, &rdn, @@ -7486,22 +7592,6 @@ config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text ) return NOID; } } else { - if ( !strncmp( e->e_nname.bv_val + - STRLENOF( "olcDatabase" ), "=frontend", - STRLENOF( "=frontend" ) ) ) - { - struct berval rdn, pdn, ndn; - dnParent( &e->e_nname, &pdn ); - rdn.bv_val = ca.log; - rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ), - "%s=" SLAP_X_ORDERED_FMT "%s", - cfAd_database->ad_cname.bv_val, -1, - frontendDB->bd_info->bi_type ); - build_new_dn( &ndn, &pdn, &rdn, NULL ); - ber_memfree( e->e_name.bv_val ); - e->e_name = ndn; - ber_bvreplace( &e->e_nname, &e->e_name ); - } entry_put_got_frontend++; isFrontend = 1; } @@ -7607,6 +7697,22 @@ config_tool_entry_modify( BackendDB *be, Entry *e, struct berval *text ) return NOID; } +static int +config_tool_entry_delete( BackendDB *be, struct berval *ndn, struct berval *text ) +{ + CfBackInfo *cfb = be->be_private; + BackendInfo *bi = cfb->cb_db.bd_info; + CfEntryInfo *ce, *last; + ConfigArgs ca = {0}; + + ce = config_find_base( cfb->cb_root, ndn, &last ); + + if ( ce && bi && bi->bi_tool_entry_delete ) + return bi->bi_tool_entry_delete( &cfb->cb_db, ndn, text ); + + return LDAP_OTHER; +} + static struct { char *name; AttributeDescription **desc; @@ -7706,6 +7812,7 @@ config_back_initialize( BackendInfo *bi ) bi->bi_tool_entry_get = config_tool_entry_get; bi->bi_tool_entry_put = config_tool_entry_put; bi->bi_tool_entry_modify = config_tool_entry_modify; + bi->bi_tool_entry_delete = config_tool_entry_delete; ca.argv = argv; argv[ 0 ] = "slapd";