int monitor_subsys_thread_update( struct monitorinfo *mi, Entry *e ) { Attribute *a; struct berval bv[2], *b = NULL; char buf[1024]; bv[1].bv_val = NULL; snprintf( buf, sizeof( buf ), "backload=%d", ldap_pvt_thread_pool_backload( &connection_pool ) ); if ( ( a = attr_find( e->e_attrs, monitor_ad_desc ) ) != NULL ) { for ( b = a->a_vals; b[0].bv_val != NULL; b++ ) { if ( strncmp( b[0].bv_val, "backload=", sizeof( "backload=" ) - 1 ) == 0 ) { free( b[0].bv_val ); ber_str2bv( buf, 0, 1, &b[0] ); break; } } } if ( b == NULL || b[0].bv_val == NULL ) { bv[0].bv_val = buf; bv[0].bv_len = strlen( buf ); attr_merge( e, monitor_ad_desc, bv ); } return( 0 ); }
static int collect_response( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; collect_info *ci = on->on_bi.bi_private; /* If we've been configured and the current response is * a search entry */ if ( ci && rs->sr_type == REP_SEARCH ) { int rc; op->o_bd->bd_info = (BackendInfo *)on->on_info; for (; ci; ci=ci->ci_next ) { int idx=0; /* Is this entry an ancestor of this collectinfo ? */ if (!dnIsSuffix(&rs->sr_entry->e_nname, &ci->ci_dn)) { /* collectinfo does not match */ continue; } /* Is this entry the same as the template DN ? */ if ( dn_match(&rs->sr_entry->e_nname, &ci->ci_dn)) { /* dont apply change to parent */ continue; } /* The current entry may live in a cache, so * don't modify it directly. Make a copy and * work with that instead. */ rs_entry2modifiable( op, rs, on ); /* Loop for each attribute in this collectinfo */ for(idx=0; idx<ci->ci_ad_num; idx++) { BerVarray vals = NULL; /* Extract the values of the desired attribute from * the ancestor entry */ rc = backend_attribute( op, NULL, &ci->ci_dn, ci->ci_ad[idx], &vals, ACL_READ ); /* If there are any values, merge them into the * current search result */ if ( vals ) { attr_merge( rs->sr_entry, ci->ci_ad[idx], vals, NULL ); ber_bvarray_free_x( vals, op->o_tmpmemctx ); } } } } /* Default is to just fall through to the normal processing */ return SLAP_CB_CONTINUE; }
/* adds dynamicSubtrees to root DSE */ static int dds_entry_info( void *arg, Entry *e ) { dds_info_t *di = (dds_info_t *)arg; attr_merge( e, slap_schema.si_ad_dynamicSubtrees, di->di_suffix, di->di_nsuffix ); return 0; }
static int usn_func( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; usn_info_t *ui = on->on_bi.bi_private; int my_usn; char intbuf[64]; struct berval bv[2]; ldap_pvt_thread_mutex_lock( &ui->ui_mutex ); ui->ui_current++; my_usn = ui->ui_current; ldap_pvt_thread_mutex_unlock( &ui->ui_mutex ); BER_BVZERO(&bv[1]); bv[0].bv_val = intbuf; bv[0].bv_len = snprintf( intbuf, sizeof(intbuf), "%d", my_usn ); switch(op->o_tag) { case LDAP_REQ_ADD: attr_merge( op->ora_e, ad_usnCreated, bv, NULL ); attr_merge( op->ora_e, ad_usnChanged, bv, NULL ); break; case LDAP_REQ_DELETE: /* Probably need to update root usnLastObjRem */ break; default: { /* Modify, ModDN */ Modifications *ml, *mod = ch_calloc( sizeof( Modifications ), 1 ); for ( ml = op->orm_modlist; ml && ml->sml_next; ml = ml->sml_next ); ml->sml_next = mod; mod->sml_desc = ad_usnChanged; mod->sml_numvals = 1; value_add_one( &mod->sml_values, &bv[0] ); mod->sml_nvalues = NULL; mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = 0; mod->sml_next = NULL; break; } } return SLAP_CB_CONTINUE; }
/* * * initializes log subentry * */ int monitor_subsys_thread_init( BackendDB *be ) { struct monitorinfo *mi; Entry *e; struct berval bv[2]; static char buf[1024]; mi = ( struct monitorinfo * )be->be_private; if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn, &e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_thread_init: unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_thread_init: unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn.bv_val, 0, 0 ); #endif return( -1 ); } /* initialize the thread number */ snprintf( buf, sizeof( buf ), "max=%d", connection_pool_max ); bv[1].bv_val = NULL; bv[0].bv_val = buf; bv[0].bv_len = strlen( bv[0].bv_val ); attr_merge( e, monitor_ad_desc, bv ); monitor_cache_release( mi, e ); return( 0 ); }
int exop_root_dse_info( Entry *e ) { AttributeDescription *ad_supportedExtension = slap_schema.si_ad_supportedExtension; struct berval vals[2]; struct extop_list *ext; vals[1].bv_val = NULL; vals[1].bv_len = 0; for (ext = supp_ext_list; ext != NULL; ext = ext->next) { if( ext->flags & SLAP_EXOP_HIDE ) continue; vals[0] = ext->oid; if( attr_merge( e, ad_supportedExtension, vals, NULL ) ) { return LDAP_OTHER; } } return LDAP_SUCCESS; }
/* * Read the entries specified in fname and merge the attributes * to the user defined baseObject entry. Note that if we find any errors * what so ever, we will discard the entire entries, print an * error message and return. */ static int read_baseObject( BackendDB *be, const char *fname ) { backsql_info *bi = (backsql_info *)be->be_private; LDIFFP *fp; int rc = 0, lmax = 0, ldifrc; unsigned long lineno = 0; char *buf = NULL; assert( fname != NULL ); fp = ldif_open( fname, "r" ); if ( fp == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open back-sql baseObject " "attr file \"%s\" - absolute path?\n", fname, 0, 0 ); perror( fname ); return LDAP_OTHER; } bi->sql_baseObject = entry_alloc(); if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_ANY, "read_baseObject_file: entry_alloc failed", 0, 0, 0 ); ldif_close( fp ); return LDAP_NO_MEMORY; } bi->sql_baseObject->e_name = be->be_suffix[0]; bi->sql_baseObject->e_nname = be->be_nsuffix[0]; bi->sql_baseObject->e_attrs = NULL; while (( ldifrc = ldif_read_record( fp, &lineno, &buf, &lmax )) > 0 ) { Entry *e = str2entry( buf ); Attribute *a; if( e == NULL ) { fprintf( stderr, "back-sql baseObject: " "could not parse entry (line=%lu)\n", lineno ); rc = LDAP_OTHER; break; } /* make sure the DN is the database's suffix */ if ( !be_issuffix( be, &e->e_nname ) ) { fprintf( stderr, "back-sql: invalid baseObject - " "dn=\"%s\" (line=%lu)\n", e->e_name.bv_val, lineno ); entry_free( e ); rc = LDAP_OTHER; break; } /* * we found a valid entry, so walk thru all the attributes in the * entry, and add each attribute type and description to baseObject */ for ( a = e->e_attrs; a != NULL; a = a->a_next ) { if ( attr_merge( bi->sql_baseObject, a->a_desc, a->a_vals, ( a->a_nvals == a->a_vals ) ? NULL : a->a_nvals ) ) { rc = LDAP_OTHER; break; } } entry_free( e ); if ( rc ) { break; } } if ( ldifrc < 0 ) rc = LDAP_OTHER; if ( rc ) { entry_free( bi->sql_baseObject ); bi->sql_baseObject = NULL; } ch_free( buf ); ldif_close( fp ); Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 ); return rc; }
static int retcode_db_open( BackendDB *be, ConfigReply *cr) { slap_overinst *on = (slap_overinst *)be->bd_info; retcode_t *rd = (retcode_t *)on->on_bi.bi_private; retcode_item_t *rdi; for ( rdi = rd->rd_item; rdi; rdi = rdi->rdi_next ) { LDAPRDN rdn = NULL; int rc, j; char* p; struct berval val[ 3 ]; char buf[ SLAP_TEXT_BUFLEN ]; /* DN */ rdi->rdi_e.e_name = rdi->rdi_dn; rdi->rdi_e.e_nname = rdi->rdi_ndn; /* objectClass */ val[ 0 ] = oc_errObject->soc_cname; val[ 1 ] = slap_schema.si_oc_extensibleObject->soc_cname; BER_BVZERO( &val[ 2 ] ); attr_merge( &rdi->rdi_e, slap_schema.si_ad_objectClass, val, NULL ); /* RDN avas */ rc = ldap_bv2rdn( &rdi->rdi_dn, &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP ); assert( rc == LDAP_SUCCESS ); for ( j = 0; rdn[ j ]; j++ ) { LDAPAVA *ava = rdn[ j ]; AttributeDescription *ad = NULL; const char *text; rc = slap_bv2ad( &ava->la_attr, &ad, &text ); assert( rc == LDAP_SUCCESS ); attr_merge_normalize_one( &rdi->rdi_e, ad, &ava->la_value, NULL ); } ldap_rdnfree( rdn ); /* error code */ snprintf( buf, sizeof( buf ), "%d", rdi->rdi_err ); ber_str2bv( buf, 0, 0, &val[ 0 ] ); attr_merge_one( &rdi->rdi_e, ad_errCode, &val[ 0 ], NULL ); if ( rdi->rdi_ref != NULL ) { attr_merge_normalize( &rdi->rdi_e, slap_schema.si_ad_ref, rdi->rdi_ref, NULL ); } /* text */ if ( !BER_BVISNULL( &rdi->rdi_text ) ) { val[ 0 ] = rdi->rdi_text; attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL ); } /* matched */ if ( !BER_BVISNULL( &rdi->rdi_matched ) ) { val[ 0 ] = rdi->rdi_matched; attr_merge_normalize_one( &rdi->rdi_e, ad_errMatchedDN, &val[ 0 ], NULL ); } /* sleep time */ if ( rdi->rdi_sleeptime ) { snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime ); ber_str2bv( buf, 0, 0, &val[ 0 ] ); attr_merge_one( &rdi->rdi_e, ad_errSleepTime, &val[ 0 ], NULL ); } /* operations */ if ( rdi->rdi_mask & SN_DG_OP_ADD ) { BER_BVSTR( &val[ 0 ], "add" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_BIND ) { BER_BVSTR( &val[ 0 ], "bind" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_COMPARE ) { BER_BVSTR( &val[ 0 ], "compare" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_DELETE ) { BER_BVSTR( &val[ 0 ], "delete" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_EXTENDED ) { BER_BVSTR( &val[ 0 ], "extended" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_MODIFY ) { BER_BVSTR( &val[ 0 ], "modify" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_RENAME ) { BER_BVSTR( &val[ 0 ], "rename" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } if ( rdi->rdi_mask & SN_DG_OP_SEARCH ) { BER_BVSTR( &val[ 0 ], "search" ); attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL ); } } return 0; }
int modify_add_values( Entry *e, Modification *mod, int permissive, const char **text, char *textbuf, size_t textlen ) { int rc; const char *op; Attribute *a; Modification pmod = *mod; switch ( mod->sm_op ) { case LDAP_MOD_ADD: op = "add"; break; case LDAP_MOD_REPLACE: op = "replace"; break; default: op = "?"; assert( 0 ); } /* FIXME: Catch old code that doesn't set sm_numvals. */ if ( !BER_BVISNULL( &mod->sm_values[mod->sm_numvals] )) { unsigned i; for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ); assert( mod->sm_numvals == i ); } /* check if values to add exist in attribute */ a = attr_find( e->e_attrs, mod->sm_desc ); if ( a != NULL ) { MatchingRule *mr; struct berval *cvals; int rc; unsigned i, p, flags; mr = mod->sm_desc->ad_type->sat_equality; if( mr == NULL || !mr->smr_match ) { /* do not allow add of additional attribute if no equality rule exists */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: no equality matching rule", op, mod->sm_desc->ad_cname.bv_val ); return LDAP_INAPPROPRIATE_MATCHING; } if ( permissive ) { i = mod->sm_numvals; pmod.sm_values = (BerVarray)ch_malloc( (i + 1) * sizeof( struct berval )); if ( pmod.sm_nvalues != NULL ) { pmod.sm_nvalues = (BerVarray)ch_malloc( (i + 1) * sizeof( struct berval )); } } /* no normalization is done in this routine nor * in the matching routines called by this routine. * values are now normalized once on input to the * server (whether from LDAP or from the underlying * database). */ if ( a->a_desc == slap_schema.si_ad_objectClass ) { /* Needed by ITS#5517 */ flags = SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX; } else { flags = SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX; } if ( mod->sm_nvalues ) { flags |= SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH; cvals = mod->sm_nvalues; } else { cvals = mod->sm_values; } for ( p = i = 0; i < mod->sm_numvals; i++ ) { unsigned slot; rc = attr_valfind( a, flags, &cvals[i], &slot, NULL ); if ( rc == LDAP_SUCCESS ) { if ( !permissive ) { /* value already exists */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: value #%u already exists", op, mod->sm_desc->ad_cname.bv_val, i ); return LDAP_TYPE_OR_VALUE_EXISTS; } } else if ( rc != LDAP_NO_SUCH_ATTRIBUTE ) { return rc; } if ( permissive && rc ) { if ( pmod.sm_nvalues ) { pmod.sm_nvalues[p] = mod->sm_nvalues[i]; } pmod.sm_values[p++] = mod->sm_values[i]; } } if ( permissive ) { if ( p == 0 ) { /* all new values match exist */ ch_free( pmod.sm_values ); if ( pmod.sm_nvalues ) ch_free( pmod.sm_nvalues ); return LDAP_SUCCESS; } BER_BVZERO( &pmod.sm_values[p] ); if ( pmod.sm_nvalues ) { BER_BVZERO( &pmod.sm_nvalues[p] ); } } } /* no - add them */ if ( mod->sm_desc->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) { rc = ordered_value_add( e, mod->sm_desc, a, pmod.sm_values, pmod.sm_nvalues ); } else { rc = attr_merge( e, mod->sm_desc, pmod.sm_values, pmod.sm_nvalues ); } if ( a != NULL && permissive ) { ch_free( pmod.sm_values ); if ( pmod.sm_nvalues ) ch_free( pmod.sm_nvalues ); } if ( rc != 0 ) { /* this should return result of attr_merge */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: merge error (%d)", op, mod->sm_desc->ad_cname.bv_val, rc ); return LDAP_OTHER; } return LDAP_SUCCESS; }
int schema_info( Entry **entry, const char **text ) { AttributeDescription *ad_structuralObjectClass = slap_schema.si_ad_structuralObjectClass; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; AttributeDescription *ad_createTimestamp = slap_schema.si_ad_createTimestamp; AttributeDescription *ad_modifyTimestamp = slap_schema.si_ad_modifyTimestamp; Entry *e; struct berval vals[5]; struct berval nvals[5]; e = entry_alloc(); if( e == NULL ) { /* Out of memory, do something about it */ Debug( LDAP_DEBUG_ANY, "schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 ); *text = "out of memory"; return LDAP_OTHER; } e->e_attrs = NULL; /* backend-specific schema info should be created by the * backend itself */ ber_dupbv( &e->e_name, &frontendDB->be_schemadn ); ber_dupbv( &e->e_nname, &frontendDB->be_schemandn ); e->e_private = NULL; BER_BVSTR( &vals[0], "subentry" ); if( attr_merge_one( e, ad_structuralObjectClass, vals, NULL ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } BER_BVSTR( &vals[0], "top" ); BER_BVSTR( &vals[1], "subentry" ); BER_BVSTR( &vals[2], "subschema" ); BER_BVSTR( &vals[3], "extensibleObject" ); BER_BVZERO( &vals[4] ); if ( attr_merge( e, ad_objectClass, vals, NULL ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } { int rc; AttributeDescription *desc = NULL; struct berval rdn = frontendDB->be_schemadn; vals[0].bv_val = ber_bvchr( &rdn, '=' ); if( vals[0].bv_val == NULL ) { *text = "improperly configured subschema subentry"; return LDAP_OTHER; } vals[0].bv_val++; vals[0].bv_len = rdn.bv_len - (vals[0].bv_val - rdn.bv_val); rdn.bv_len -= vals[0].bv_len + 1; rc = slap_bv2ad( &rdn, &desc, text ); if( rc != LDAP_SUCCESS ) { entry_free( e ); *text = "improperly configured subschema subentry"; return LDAP_OTHER; } nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' ); assert( nvals[0].bv_val != NULL ); nvals[0].bv_val++; nvals[0].bv_len = frontendDB->be_schemandn.bv_len - (nvals[0].bv_val - frontendDB->be_schemandn.bv_val); if ( attr_merge_one( e, desc, vals, nvals ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } } { char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; /* * According to RFC 4512: Servers SHOULD maintain the 'creatorsName', 'createTimestamp', 'modifiersName', and 'modifyTimestamp' attributes for all entries of the DIT. * to be conservative, we declare schema created * AND modified at server startup time ... */ vals[0].bv_val = timebuf; vals[0].bv_len = sizeof( timebuf ); slap_timestamp( &starttime, vals ); if( attr_merge_one( e, ad_createTimestamp, vals, NULL ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } if( attr_merge_one( e, ad_modifyTimestamp, vals, NULL ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } } if ( syn_schema_info( e ) || mr_schema_info( e ) || mru_schema_info( e ) || at_schema_info( e ) || oc_schema_info( e ) || cr_schema_info( e ) ) { /* Out of memory, do something about it */ entry_free( e ); *text = "out of memory"; return LDAP_OTHER; } *entry = e; return LDAP_SUCCESS; }
static int monitor_subsys_readw_update_internal( struct monitorinfo *mi, Entry *e, int rw ) { Connection *c; int connindex; int nconns, nwritewaiters, nreadwaiters; Attribute *a; struct berval bv[2], *b = NULL; char buf[1024]; char *str = NULL; int num = 0; assert( mi != NULL ); assert( e != NULL ); bv[1].bv_val = NULL; nconns = nwritewaiters = nreadwaiters = 0; for ( c = connection_first( &connindex ); c != NULL; c = connection_next( c, &connindex ), nconns++ ) { if ( c->c_writewaiter ) { nwritewaiters++; } if ( c->c_currentber != NULL ) { nreadwaiters++; } } connection_done(c); switch ( rw ) { case 0: str = "read waiters"; num = nreadwaiters; break; case 1: str = "write waiters"; num = nwritewaiters; break; } snprintf( buf, sizeof( buf ), "%s=%d", str, num ); if ( ( a = attr_find( e->e_attrs, monitor_ad_desc ) ) != NULL ) { for ( b = a->a_vals; b[0].bv_val != NULL; b++ ) { if ( strncmp( b[0].bv_val, str, strlen( str ) ) == 0 ) { free( b[0].bv_val ); ber_str2bv( buf, 0, 1, b ); break; } } } if ( b == NULL || b[0].bv_val == NULL ) { bv[0].bv_val = buf; bv[0].bv_len = strlen( buf ); attr_merge( e, monitor_ad_desc, bv ); } return( 0 ); }
int modify_add_values( Entry *e, Modification *mod, int permissive, const char **text, char *textbuf, size_t textlen ) { int i, j; int matched; Attribute *a; MatchingRule *mr = mod->sm_desc->ad_type->sat_equality; const char *op; switch( mod->sm_op ) { case LDAP_MOD_ADD: op = "add"; break; case LDAP_MOD_REPLACE: op = "replace"; break; default: op = "?"; assert( 0 ); } a = attr_find( e->e_attrs, mod->sm_desc ); /* * With permissive set, as long as the attribute being added * has the same value(s?) as the existing attribute, then the * modify will succeed. */ /* check if the values we're adding already exist */ if( mr == NULL || !mr->smr_match ) { if ( a != NULL ) { /* do not allow add of additional attribute if no equality rule exists */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: no equality matching rule", op, mod->sm_desc->ad_cname.bv_val ); return LDAP_INAPPROPRIATE_MATCHING; } for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) { /* test asserted values against existing values */ if( a ) { for( matched = 0, j = 0; a->a_vals[j].bv_val != NULL; j++ ) { if ( bvmatch( &mod->sm_bvalues[i], &a->a_vals[j] ) ) { if ( permissive ) { matched++; continue; } /* value exists already */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: value #%i already exists", op, mod->sm_desc->ad_cname.bv_val, j ); return LDAP_TYPE_OR_VALUE_EXISTS; } } if ( permissive && matched == j ) { /* values already exist; do nothing */ return LDAP_SUCCESS; } } /* test asserted values against themselves */ for( j = 0; j < i; j++ ) { if ( bvmatch( &mod->sm_bvalues[i], &mod->sm_bvalues[j] ) ) { /* value exists already */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: value #%i already exists", op, mod->sm_desc->ad_cname.bv_val, j ); return LDAP_TYPE_OR_VALUE_EXISTS; } } } } else { /* * The original code performs ( n ) normalizations * and ( n * ( n - 1 ) / 2 ) matches, which hide * the same number of normalizations. The new code * performs the same number of normalizations ( n ) * and ( n * ( n - 1 ) / 2 ) mem compares, far less * expensive than an entire match, if a match is * equivalent to a normalization and a mem compare ... * * This is far more memory expensive than the previous, * but it can heavily improve performances when big * chunks of data are added (typical example is a group * with thousands of DN-syntax members; on my system: * for members of 5-RDN DNs, members orig bvmatch (dirty) new 1000 0m38.456s 0m0.553s 0m0.608s 2000 2m33.341s 0m0.851s 0m1.003s * Moreover, 100 groups with 10000 members each were * added in 37m27.933s (an analogous LDIF file was * loaded into Active Directory in 38m28.682s, BTW). * * Maybe we could switch to the new algorithm when * the number of values overcomes a given threshold? */ int rc; if ( mod->sm_bvalues[ 1 ].bv_val == 0 ) { if ( a != NULL ) { struct berval asserted; int i; rc = value_normalize( mod->sm_desc, SLAP_MR_EQUALITY, &mod->sm_bvalues[ 0 ], &asserted, text ); if ( rc != LDAP_SUCCESS ) { return rc; } for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) { int match; rc = value_match( &match, mod->sm_desc, mr, SLAP_MR_VALUE_SYNTAX_MATCH, &a->a_vals[ i ], &asserted, text ); if( rc == LDAP_SUCCESS && match == 0 ) { if ( permissive ) { matched++; continue; } free( asserted.bv_val ); *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: value #0 already exists", op, mod->sm_desc->ad_cname.bv_val, 0 ); return LDAP_TYPE_OR_VALUE_EXISTS; } } free( asserted.bv_val ); if ( permissive && matched == i ) { /* values already exist; do nothing */ return LDAP_SUCCESS; } } } else { rc = modify_check_duplicates( mod->sm_desc, mr, a ? a->a_vals : NULL, mod->sm_bvalues, permissive, text, textbuf, textlen ); if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) { return LDAP_SUCCESS; } if ( rc != LDAP_SUCCESS ) { return rc; } } } /* no - add them */ if( attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) { /* this should return result of attr_merge */ *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: merge error", op, mod->sm_desc->ad_cname.bv_val ); return LDAP_OTHER; } return LDAP_SUCCESS; }
int monitor_subsys_listener_init( BackendDB *be ) { struct monitorinfo *mi; Entry *e, *e_listener, *e_tmp; int i; struct monitorentrypriv *mp; Listener **l; assert( be != NULL ); assert( monitor_ad_desc != NULL ); mi = ( struct monitorinfo * )be->be_private; if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn, &e_listener ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_listener_init: " "unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_listener_init: " "unable to get entry '%s'\n%s%s", monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, "", "" ); #endif return( -1 ); } if ( ( l = slapd_get_listeners() ) == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_listener_init: " "unable to get listeners\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_listener_init: " "unable to get listeners\n", 0, 0, 0 ); #endif return( -1 ); } e_tmp = NULL; for ( i = 0; l[i]; i++ ); for ( ; i--; ) { char buf[1024]; snprintf( buf, sizeof( buf ), "dn: cn=Listener %d,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: Listener %d\n" "description: %s\n" "labeledURI: %s", i, monitor_subsys[SLAPD_MONITOR_LISTENER].mss_dn.bv_val, i, l[i]->sl_name.bv_val, l[i]->sl_url.bv_val ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_listener_init: " "unable to create entry 'cn=Listener, %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_listener_init: " "unable to create entry 'cn=Listener %d,%s'\n%s", i, monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, "" ); #endif return( -1 ); } #ifdef HAVE_TLS if ( l[i]->sl_is_tls ) { struct berval bv[2]; bv[1].bv_val = NULL; bv[0].bv_val = "TLS"; bv[0].bv_len = sizeof("TLS")-1; attr_merge( e, monitor_ad_desc, bv ); } #endif /* HAVE_TLS */ #ifdef LDAP_CONNECTIONLESS if ( l[i]->sl_is_udp ) { struct berval bv[2]; bv[1].bv_val = NULL; bv[0].bv_val = "UDP"; bv[0].bv_len = sizeof("UDP")-1; attr_merge( e, monitor_ad_desc, bv ); } #endif /* HAVE_TLS */ mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_tmp; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_LISTENER]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_LISTENER].mss_flags | MONITOR_F_SUB; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_listener_init: " "unable to add entry 'cn=Listener %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_listener_init: " "unable to add entry 'cn=Listener %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_LISTENER].mss_ndn.bv_val, 0 ); #endif return( -1 ); } e_tmp = e; } mp = ( struct monitorentrypriv * )e_listener->e_private; mp->mp_children = e_tmp; monitor_cache_release( mi, e_listener ); return( 0 ); }
int monitor_subsys_ops_init( BackendDB *be ) { struct monitorinfo *mi; Entry *e, *e_tmp, *e_op, *e_children; struct monitorentrypriv *mp; char buf[1024]; struct berval bv[2]; int i; assert( be != NULL ); mi = ( struct monitorinfo * )be->be_private; if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn, &e_op ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to get entry '%s'\n%s%s", monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, "", "" ); #endif return( -1 ); } e_tmp = NULL; /* * Initiated ops */ snprintf( buf, sizeof( buf ), "dn: cn=%s,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: %s\n", bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_dn.bv_val, bv_initiated.bv_val ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,%s'\n", bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,%s'\n%s", bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, "" ); #endif return( -1 ); } bv[1].bv_val = NULL; bv[0].bv_val = "0"; bv[0].bv_len = 1; attr_merge( e, monitor_ad_desc, bv ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_tmp; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_OPS]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_OPS].mss_flags \ | MONITOR_F_SUB | MONITOR_F_PERSISTENT; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,%s'\n", bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,%s'\n%s", bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, "" ); #endif return( -1 ); } e_tmp = e; e_children = NULL; for ( i = SLAP_OP_LAST; i-- > 0; ) { /* * Initiated ops */ snprintf( buf, sizeof( buf ), "dn: cn=%s,cn=%s,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: %s\n", bv_op[ i ].bv_val, bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_dn.bv_val, bv_op[ i ].bv_val ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #endif return( -1 ); } bv[1].bv_val = NULL; bv[0].bv_val = "0"; bv[0].bv_len = 1; attr_merge( e, monitor_ad_desc, bv ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_children; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_OPS]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_OPS].mss_flags \ | MONITOR_F_SUB | MONITOR_F_PERSISTENT; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_initiated.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #endif return( -1 ); } e_children = e; } mp = ( struct monitorentrypriv * )e_tmp->e_private; mp->mp_children = e_children; /* * Completed ops */ snprintf( buf, sizeof( buf ), "dn: cn=%s,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: %s\n", bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_dn.bv_val, bv_completed.bv_val ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,%s'\n", bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,%s'\n%s", bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, "" ); #endif return( -1 ); } bv[0].bv_val = "0"; bv[0].bv_len = 1; attr_merge( e, monitor_ad_desc, bv ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_tmp; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_OPS]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_OPS].mss_flags \ | MONITOR_F_SUB | MONITOR_F_PERSISTENT; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,%s'\n", bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,%s'\n%s", bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val, "" ); #endif return( -1 ); } e_tmp = e; e_children = NULL; for ( i = SLAP_OP_LAST; i-- > 0; ) { /* * Completed ops */ snprintf( buf, sizeof( buf ), "dn: cn=%s,cn=%s,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: %s\n", bv_op[ i ].bv_val, bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_dn.bv_val, bv_op[ i ].bv_val ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to create entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #endif return( -1 ); } bv[0].bv_val = "0"; bv[0].bv_len = 1; attr_merge( e, monitor_ad_desc, bv ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_children; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_OPS]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_OPS].mss_flags \ | MONITOR_F_SUB | MONITOR_F_PERSISTENT; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_ops_init: " "unable to add entry 'cn=%s,cn=%s,%s'\n", bv_op[ i ].bv_val, bv_completed.bv_val, monitor_subsys[SLAPD_MONITOR_OPS].mss_ndn.bv_val ); #endif return( -1 ); } e_children = e; } mp = ( struct monitorentrypriv * )e_tmp->e_private; mp->mp_children = e_children; mp = ( struct monitorentrypriv * )e_op->e_private; mp->mp_children = e_tmp; monitor_cache_release( mi, e_op ); return( 0 ); }
static int monitor_subsys_log_modify( Operation *op, SlapReply *rs, Entry *e ) { monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private; int rc = LDAP_OTHER; int newlevel = ldap_syslog; Attribute *save_attrs; Modifications *modlist = op->orm_modlist; Modifications *ml; ldap_pvt_thread_mutex_lock( &monitor_log_mutex ); save_attrs = e->e_attrs; e->e_attrs = attrs_dup( e->e_attrs ); for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { Modification *mod = &ml->sml_mod; /* * accept all operational attributes; * this includes modifersName and modifyTimestamp * if lastmod is "on" */ if ( is_at_operational( mod->sm_desc->ad_type ) ) { ( void ) attr_delete( &e->e_attrs, mod->sm_desc ); rc = rs->sr_err = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues ); if ( rc != LDAP_SUCCESS ) { break; } continue; /* * only the "managedInfo" attribute can be modified */ } else if ( mod->sm_desc != mi->mi_ad_managedInfo ) { rc = rs->sr_err = LDAP_UNWILLING_TO_PERFORM; break; } switch ( mod->sm_op ) { case LDAP_MOD_ADD: rc = add_values( op, e, mod, &newlevel ); break; case LDAP_MOD_DELETE: rc = delete_values( op, e, mod, &newlevel ); break; case LDAP_MOD_REPLACE: rc = replace_values( op, e, mod, &newlevel ); break; default: rc = LDAP_OTHER; break; } if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; break; } } /* set the new debug level */ if ( rc == LDAP_SUCCESS ) { const char *text; static char textbuf[ BACKMONITOR_BUFSIZE ]; /* check for abandon */ if ( op->o_abandon ) { rc = rs->sr_err = SLAPD_ABANDON; goto cleanup; } /* check that the entry still obeys the schema */ rc = entry_schema_check( op, e, save_attrs, 0, 0, NULL, &text, textbuf, sizeof( textbuf ) ); if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; goto cleanup; } /* * Do we need to protect this with a mutex? */ ldap_syslog = newlevel; #if 0 /* debug rather than log */ slap_debug = newlevel; lutil_set_debug_level( "slapd", slap_debug ); ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug); ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug); ldif_debug = slap_debug; #endif } cleanup:; if ( rc == LDAP_SUCCESS ) { attrs_free( save_attrs ); } else { attrs_free( e->e_attrs ); e->e_attrs = save_attrs; } ldap_pvt_thread_mutex_unlock( &monitor_log_mutex ); if ( rc == LDAP_SUCCESS ) { rc = SLAP_CB_CONTINUE; } return rc; }
int slapadd( int argc, char **argv ) { char *buf = NULL; const char *text; char textbuf[SLAP_TEXT_BUFLEN] = { '\0' }; size_t textlen = sizeof textbuf; const char *progname = "slapadd"; struct berval csn; struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ]; unsigned long sid; struct berval bvtext; Attribute *attr; Entry *ctxcsn_e; ID ctxcsn_id, id; OperationBuffer opbuf; Operation *op; int match; int checkvals; int lineno, nextline; int lmax; int rc = EXIT_SUCCESS; int manage = 0; /* default "000" */ csnsid = 0; slap_tool_init( progname, SLAPADD, argc, argv ); memset( &opbuf, 0, sizeof(opbuf) ); op = &opbuf.ob_op; op->o_hdr = &opbuf.ob_hdr; if( !be->be_entry_open || !be->be_entry_close || !be->be_entry_put || (update_ctxcsn && (!be->be_dn2id_get || !be->be_entry_get || !be->be_entry_modify)) ) { fprintf( stderr, "%s: database doesn't support necessary operations.\n", progname ); if ( dryrun ) { fprintf( stderr, "\t(dry) continuing...\n" ); } else { exit( EXIT_FAILURE ); } } checkvals = (slapMode & SLAP_TOOL_QUICK) ? 0 : 1; lmax = 0; nextline = 0; /* enforce schema checking unless not disabled */ if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) { SLAP_DBFLAGS(be) &= ~(SLAP_DBFLAG_NO_SCHEMA_CHECK); } if( !dryrun && be->be_entry_open( be, 1 ) != 0 ) { fprintf( stderr, "%s: could not open database.\n", progname ); exit( EXIT_FAILURE ); } if ( update_ctxcsn ) { maxcsn[ 0 ].bv_val = maxcsnbuf; for ( sid = 1; sid <= SLAP_SYNC_SID_MAX; sid++ ) { maxcsn[ sid ].bv_val = maxcsn[ sid - 1 ].bv_val + LDAP_LUTIL_CSNSTR_BUFSIZE; maxcsn[ sid ].bv_len = 0; } } /* nextline is the line number of the end of the current entry */ for( lineno=1; ldif_read_record( ldiffp, &nextline, &buf, &lmax ); lineno=nextline+1 ) { Entry *e; if ( lineno < jumpline ) continue; e = str2entry2( buf, checkvals ); /* * Initialize text buffer */ bvtext.bv_len = textlen; bvtext.bv_val = textbuf; bvtext.bv_val[0] = '\0'; if( e == NULL ) { fprintf( stderr, "%s: could not parse entry (line=%d)\n", progname, lineno ); rc = EXIT_FAILURE; if( continuemode ) continue; break; } /* make sure the DN is not empty */ if( BER_BVISEMPTY( &e->e_nname ) && !BER_BVISEMPTY( be->be_nsuffix )) { fprintf( stderr, "%s: empty dn=\"%s\" (line=%d)\n", progname, e->e_dn, lineno ); rc = EXIT_FAILURE; entry_free( e ); if( continuemode ) continue; break; } /* check backend */ if( select_backend( &e->e_nname, nosubordinates ) != be ) { fprintf( stderr, "%s: line %d: " "database (%s) not configured to hold \"%s\"\n", progname, lineno, be ? be->be_suffix[0].bv_val : "<none>", e->e_dn ); fprintf( stderr, "%s: line %d: " "database (%s) not configured to hold \"%s\"\n", progname, lineno, be ? be->be_nsuffix[0].bv_val : "<none>", e->e_ndn ); rc = EXIT_FAILURE; entry_free( e ); if( continuemode ) continue; break; } { Attribute *oc = attr_find( e->e_attrs, slap_schema.si_ad_objectClass ); if( oc == NULL ) { fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n", progname, e->e_dn, lineno, "no objectClass attribute"); rc = EXIT_FAILURE; entry_free( e ); if( continuemode ) continue; break; } /* check schema */ op->o_bd = be; if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) { rc = entry_schema_check( op, e, NULL, manage, 1, &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n", progname, e->e_dn, lineno, rc, text ); rc = EXIT_FAILURE; entry_free( e ); if( continuemode ) continue; break; } textbuf[ 0 ] = '\0'; } } if ( SLAP_LASTMOD(be) ) { time_t now = slap_get_time(); char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; struct berval vals[ 2 ]; struct berval name, timestamp; struct berval nvals[ 2 ]; struct berval nname; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; vals[1].bv_len = 0; vals[1].bv_val = NULL; nvals[1].bv_len = 0; nvals[1].bv_val = NULL; csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), csnsid, 0 ); csn.bv_val = csnbuf; timestamp.bv_val = timebuf; timestamp.bv_len = sizeof(timebuf); slap_timestamp( &now, ×tamp ); if ( BER_BVISEMPTY( &be->be_rootndn ) ) { BER_BVSTR( &name, SLAPD_ANONYMOUS ); nname = name; } else { name = be->be_rootdn; nname = be->be_rootndn; } if( attr_find( e->e_attrs, slap_schema.si_ad_entryUUID ) == NULL ) { vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) ); vals[0].bv_val = uuidbuf; attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, vals, NULL ); } if( attr_find( e->e_attrs, slap_schema.si_ad_creatorsName ) == NULL ) { vals[0] = name; nvals[0] = nname; attr_merge( e, slap_schema.si_ad_creatorsName, vals, nvals ); } if( attr_find( e->e_attrs, slap_schema.si_ad_createTimestamp ) == NULL ) { vals[0] = timestamp; attr_merge( e, slap_schema.si_ad_createTimestamp, vals, NULL ); } if( attr_find( e->e_attrs, slap_schema.si_ad_entryCSN ) == NULL ) { vals[0] = csn; attr_merge( e, slap_schema.si_ad_entryCSN, vals, NULL ); } if( attr_find( e->e_attrs, slap_schema.si_ad_modifiersName ) == NULL ) { vals[0] = name; nvals[0] = nname; attr_merge( e, slap_schema.si_ad_modifiersName, vals, nvals ); } if( attr_find( e->e_attrs, slap_schema.si_ad_modifyTimestamp ) == NULL ) { vals[0] = timestamp; attr_merge( e, slap_schema.si_ad_modifyTimestamp, vals, NULL ); } if ( update_ctxcsn ) { int rc_sid; attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN ); assert( attr != NULL ); rc_sid = slap_parse_csn_sid( &attr->a_nvals[ 0 ] ); if ( rc_sid < 0 ) { Debug( LDAP_DEBUG_ANY, "%s: could not " "extract SID from entryCSN=%s\n", progname, attr->a_nvals[ 0 ].bv_val, 0 ); } else { assert( rc_sid <= SLAP_SYNC_SID_MAX ); sid = (unsigned)rc_sid; if ( maxcsn[ sid ].bv_len != 0 ) { match = 0; value_match( &match, slap_schema.si_ad_entryCSN, slap_schema.si_ad_entryCSN->ad_type->sat_ordering, SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, &maxcsn[ sid ], &attr->a_nvals[0], &text ); } else { match = -1; } if ( match < 0 ) { strcpy( maxcsn[ sid ].bv_val, attr->a_nvals[0].bv_val ); maxcsn[ sid ].bv_len = attr->a_nvals[0].bv_len; } } } } if ( !dryrun ) { id = be->be_entry_put( be, e, &bvtext ); if( id == NOID ) { fprintf( stderr, "%s: could not add entry dn=\"%s\" " "(line=%d): %s\n", progname, e->e_dn, lineno, bvtext.bv_val ); rc = EXIT_FAILURE; entry_free( e ); if( continuemode ) continue; break; } if ( verbose ) fprintf( stderr, "added: \"%s\" (%08lx)\n", e->e_dn, (long) id ); } else { if ( verbose ) fprintf( stderr, "added: \"%s\"\n", e->e_dn ); } entry_free( e ); } bvtext.bv_len = textlen; bvtext.bv_val = textbuf; bvtext.bv_val[0] = '\0'; if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1 ) { ctxcsn_id = be->be_dn2id_get( be, be->be_nsuffix ); if ( ctxcsn_id == NOID ) { fprintf( stderr, "%s: context entry is missing\n", progname ); rc = EXIT_FAILURE; } else { ctxcsn_e = be->be_entry_get( be, ctxcsn_id ); if ( ctxcsn_e != NULL ) { Entry *e = entry_dup( ctxcsn_e ); int change; attr = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN ); if ( attr ) { int i; change = 0; for ( i = 0; !BER_BVISNULL( &attr->a_nvals[ i ] ); i++ ) { int rc_sid; rc_sid = slap_parse_csn_sid( &attr->a_nvals[ i ] ); if ( rc_sid < 0 ) { Debug( LDAP_DEBUG_ANY, "%s: unable to extract SID " "from #%d contextCSN=%s\n", progname, i, attr->a_nvals[ i ].bv_val ); continue; } assert( rc_sid <= SLAP_SYNC_SID_MAX ); sid = (unsigned)rc_sid; if ( maxcsn[ sid ].bv_len == 0 ) { match = -1; } else { value_match( &match, slap_schema.si_ad_entryCSN, slap_schema.si_ad_entryCSN->ad_type->sat_ordering, SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, &maxcsn[ sid ], &attr->a_nvals[i], &text ); } if ( match > 0 ) { change = 1; } else { AC_MEMCPY( maxcsn[ sid ].bv_val, attr->a_nvals[ i ].bv_val, attr->a_nvals[ i ].bv_len ); maxcsn[ sid ].bv_val[ attr->a_nvals[ i ].bv_len ] = '\0'; maxcsn[ sid ].bv_len = attr->a_nvals[ i ].bv_len; } } if ( change ) { if ( attr->a_nvals != attr->a_vals ) { ber_bvarray_free( attr->a_nvals ); } attr->a_nvals = NULL; ber_bvarray_free( attr->a_vals ); attr->a_vals = NULL; attr->a_numvals = 0; } } else { change = 1; } if ( change ) { for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) { if ( maxcsn[ sid ].bv_len ) { attr_merge_one( e, slap_schema.si_ad_contextCSN, &maxcsn[ sid], NULL ); } } ctxcsn_id = be->be_entry_modify( be, e, &bvtext ); if( ctxcsn_id == NOID ) { fprintf( stderr, "%s: could not modify ctxcsn\n", progname); rc = EXIT_FAILURE; } else if ( verbose ) { fprintf( stderr, "modified: \"%s\" (%08lx)\n", e->e_dn, (long) ctxcsn_id ); } } entry_free( e ); } } } ch_free( buf ); if ( !dryrun ) { if( be->be_entry_close( be ) ) { rc = EXIT_FAILURE; } if( be->be_sync ) { be->be_sync( be ); } } slap_tool_destroy(); return rc; }
int monitor_subsys_database_init( BackendDB *be ) { struct monitorinfo *mi; Entry *e, *e_database, *e_tmp; int i; struct monitorentrypriv *mp; AttributeDescription *ad_nc = slap_schema.si_ad_namingContexts; AttributeDescription *ad_mc = slap_schema.si_ad_monitorContext; AttributeDescription *ad_seeAlso = NULL; const char *text = NULL; assert( be != NULL ); assert( monitor_ad_desc != NULL ); mi = ( struct monitorinfo * )be->be_private; if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn, &e_database ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to get entry '%s'\n%s%s", monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, "", "" ); #endif return( -1 ); } if ( slap_str2ad( "seeAlso", &ad_seeAlso, &text ) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to find 'seeAlso' attribute description\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to find 'seeAlso' attribute description\n", 0, 0, 0 ); #endif return( -1 ); } e_tmp = NULL; for ( i = nBackendDB; i--; ) { char buf[1024]; int j; be = &backendDB[i]; /* Subordinates are not exposed as their own naming context */ if ( SLAP_GLUE_SUBORDINATE( be ) ) { continue; } snprintf( buf, sizeof( buf ), "dn: cn=Database %d,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: Database %d\n" "description: %s", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_dn.bv_val, i, be->bd_info->bi_type ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to create entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to create entry 'cn=Database %d,%s'\n%s", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, "" ); #endif return( -1 ); } if ( be->be_flags & SLAP_BFLAG_MONITOR ) { attr_merge( e, ad_mc, be->be_suffix ); attr_merge( e_database, ad_mc, be->be_suffix ); } else { attr_merge( e, ad_nc, be->be_suffix ); attr_merge( e_database, ad_nc, be->be_suffix ); } for ( j = nBackendInfo; j--; ) { if ( backendInfo[ j ].bi_type == be->bd_info->bi_type ) { struct berval bv; snprintf( buf, sizeof( buf ), "cn=Backend %d,%s", j, monitor_subsys[SLAPD_MONITOR_BACKEND].mss_dn.bv_val ); bv.bv_val = buf; bv.bv_len = strlen( buf ); attr_merge_one( e, ad_seeAlso, &bv ); break; } } /* we must find it! */ assert( j >= 0 ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_tmp; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_DATABASE]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_DATABASE].mss_flags | MONITOR_F_SUB; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to add entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to add entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #endif return( -1 ); } #if defined(LDAP_SLAPI) monitor_back_add_plugin( be, e ); #endif /* defined(LDAP_SLAPI) */ e_tmp = e; } mp = ( struct monitorentrypriv * )e_database->e_private; mp->mp_children = e_tmp; monitor_cache_release( mi, e_database ); return( 0 ); }