/* updates counter - installed on add/delete only if required */ static int dds_counter_cb( Operation *op, SlapReply *rs ) { assert( rs->sr_type == REP_RESULT ); if ( rs->sr_err == LDAP_SUCCESS ) { dds_info_t *di = op->o_callback->sc_private; ldap_pvt_thread_mutex_lock( &di->di_mutex ); switch ( op->o_tag ) { case LDAP_REQ_DELETE: assert( di->di_num_dynamicObjects > 0 ); di->di_num_dynamicObjects--; break; case LDAP_REQ_ADD: assert( di->di_num_dynamicObjects < di->di_max_dynamicObjects ); di->di_num_dynamicObjects++; break; default: LDAP_BUG(); } ldap_pvt_thread_mutex_unlock( &di->di_mutex ); } return dds_freeit_cb( op, rs ); }
static int dds_expire_cb( Operation *op, SlapReply *rs ) { dds_cb_t *dc = (dds_cb_t *)op->o_callback->sc_private; dds_expire_t *de; int rc; switch ( rs->sr_type ) { case REP_SEARCH: /* alloc list and buffer for berval all in one */ de = op->o_tmpalloc( sizeof( dds_expire_t ) + rs->sr_entry->e_nname.bv_len + 1, op->o_tmpmemctx ); de->de_next = dc->dc_ndnlist; dc->dc_ndnlist = de; de->de_ndn.bv_len = rs->sr_entry->e_nname.bv_len; de->de_ndn.bv_val = (char *)&de[ 1 ]; memcpy( de->de_ndn.bv_val, rs->sr_entry->e_nname.bv_val, rs->sr_entry->e_nname.bv_len + 1 ); rc = 0; break; case REP_SEARCHREF: case REP_RESULT: rc = rs->sr_err; break; default: LDAP_BUG(); } return rc; }
void quorum_global_init() { int rc; assert(quorum_list == QR_POISON); rc = ldap_pvt_thread_mutex_init(&quorum_mutex); if (rc) { Debug( LDAP_DEBUG_ANY, "mutex_init failed for quorum_mutex, rc = %d\n", rc ); LDAP_BUG(); exit( EXIT_FAILURE ); } quorum_list = NULL; }
/* callback that counts the returned entries, since the search * does not get to the point in slap_send_search_entries where * the actual count occurs */ static int dds_count_cb( Operation *op, SlapReply *rs ) { int *nump = (int *)op->o_callback->sc_private; switch ( rs->sr_type ) { case REP_SEARCH: (*nump)++; break; case REP_SEARCHREF: case REP_RESULT: break; default: LDAP_BUG(); } return 0; }
int meta_back_cancel( metaconn_t *mc, Operation *op, SlapReply *rs, ber_int_t msgid, int candidate, ldap_back_send_t sendok ) { metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; int rc = LDAP_OTHER; Debug( LDAP_DEBUG_TRACE, ">>> %s meta_back_cancel[%d] msgid=%d\n", op->o_log_prefix, candidate, msgid ); /* default behavior */ if ( META_BACK_TGT_ABANDON( mt ) ) { rc = ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); } else if ( META_BACK_TGT_IGNORE( mt ) ) { rc = ldap_pvt_discard( msc->msc_ld, msgid ); } else if ( META_BACK_TGT_CANCEL( mt ) ) { rc = ldap_cancel_s( msc->msc_ld, msgid, NULL, NULL ); } else { LDAP_BUG(); } Debug( LDAP_DEBUG_TRACE, "<<< %s meta_back_cancel[%d] err=%d\n", op->o_log_prefix, candidate, rc ); return rc; }
static int aci_mask( Operation *op, Entry *e, AttributeDescription *desc, struct berval *val, struct berval *aci, int nmatch, regmatch_t *matches, slap_access_t *grant, slap_access_t *deny, slap_aci_scope_t asserted_scope ) { struct berval bv, scope, perms, type, opts, sdn; int rc; ACL_INIT( *grant ); ACL_INIT( *deny ); assert( !BER_BVISNULL( &desc->ad_cname ) ); /* parse an aci of the form: oid # scope # action;rights;attr;rights;attr $ action;rights;attr;rights;attr # type # subject [NOTE: the following comment is very outdated, as the draft version it refers to (Ando, 2004-11-20)]. See draft-ietf-ldapext-aci-model-04.txt section 9.1 for a full description of the format for this attribute. Differences: "this" in the draft is "self" here, and "self" and "public" is in the position of type. <scope> = {entry|children|subtree} <type> = {public|users|access-id|subtree|onelevel|children| self|dnattr|group|role|set|set-ref} This routine now supports scope={ENTRY,CHILDREN} with the semantics: - ENTRY applies to "entry" and "subtree"; - CHILDREN applies to "children" and "subtree" */ /* check that the aci has all 5 components */ if ( acl_get_part( aci, 4, '#', NULL ) < 0 ) { return 0; } /* check that the aci family is supported */ /* FIXME: the OID is ignored? */ if ( acl_get_part( aci, 0, '#', &bv ) < 0 ) { return 0; } /* check that the scope matches */ if ( acl_get_part( aci, 1, '#', &scope ) < 0 ) { return 0; } /* note: scope can be either ENTRY or CHILDREN; * they respectively match "entry" and "children" in bv * both match "subtree" */ switch ( asserted_scope ) { case SLAP_ACI_SCOPE_ENTRY: if ( ber_bvcmp( &scope, &aci_bv[ ACI_BV_ENTRY ] ) != 0 && ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_SUBTREE ] ) != 0 ) { return 0; } break; case SLAP_ACI_SCOPE_CHILDREN: if ( ber_bvcmp( &scope, &aci_bv[ ACI_BV_CHILDREN ] ) != 0 && ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_SUBTREE ] ) != 0 ) { return 0; } break; case SLAP_ACI_SCOPE_SUBTREE: /* TODO: add assertion? */ return 0; } /* get the list of permissions clauses, bail if empty */ if ( acl_get_part( aci, 2, '#', &perms ) <= 0 ) { LDAP_BUG(); return 0; } /* check if any permissions allow desired access */ if ( aci_list_get_rights( &perms, &desc->ad_cname, val, grant, deny ) == 0 ) { return 0; } /* see if we have a DN match */ if ( acl_get_part( aci, 3, '#', &type ) < 0 ) { LDAP_BUG(); return 0; } /* see if we have a public (i.e. anonymous) access */ if ( ber_bvcmp( &aci_bv[ ACI_BV_PUBLIC ], &type ) == 0 ) { return 1; } /* otherwise require an identity */ if ( BER_BVISNULL( &op->o_ndn ) || BER_BVISEMPTY( &op->o_ndn ) ) { return 0; } /* see if we have a users access */ if ( ber_bvcmp( &aci_bv[ ACI_BV_USERS ], &type ) == 0 ) { return 1; } /* NOTE: this may fail if a DN contains a valid '#' (unescaped); * just grab all the berval up to its end (ITS#3303). * NOTE: the problem could be solved by providing the DN with * the embedded '#' encoded as hexpairs: "cn=Foo#Bar" would * become "cn=Foo\23Bar" and be safely used by aci_mask(). */ #if 0 if ( acl_get_part( aci, 4, '#', &sdn ) < 0 ) { return 0; } #endif sdn.bv_val = type.bv_val + type.bv_len + STRLENOF( "#" ); sdn.bv_len = aci->bv_len - ( sdn.bv_val - aci->bv_val ); /* get the type options, if any */ if ( acl_get_part( &type, 1, '/', &opts ) > 0 ) { opts.bv_len = type.bv_len - ( opts.bv_val - type.bv_val ); type.bv_len = opts.bv_val - type.bv_val - 1; } else { BER_BVZERO( &opts ); } if ( ber_bvcmp( &aci_bv[ ACI_BV_ACCESS_ID ], &type ) == 0 ) { return dn_match( &op->o_ndn, &sdn ); } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SUBTREE ], &type ) == 0 ) { return dnIsSuffix( &op->o_ndn, &sdn ); } else if ( ber_bvcmp( &aci_bv[ ACI_BV_ONELEVEL ], &type ) == 0 ) { struct berval pdn; dnParent( &sdn, &pdn ); return dn_match( &op->o_ndn, &pdn ); } else if ( ber_bvcmp( &aci_bv[ ACI_BV_CHILDREN ], &type ) == 0 ) { return ( !dn_match( &op->o_ndn, &sdn ) && dnIsSuffix( &op->o_ndn, &sdn ) ); } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SELF ], &type ) == 0 ) { return dn_match( &op->o_ndn, &e->e_nname ); } else if ( ber_bvcmp( &aci_bv[ ACI_BV_DNATTR ], &type ) == 0 ) { Attribute *at; AttributeDescription *ad = NULL; const char *text; rc = slap_bv2ad( &sdn, &ad, &text ); assert( rc == LDAP_SUCCESS ); rc = 0; for ( at = attrs_find( e->e_attrs, ad ); at != NULL; at = attrs_find( at->a_next, ad ) ) { if ( attr_valfind( at, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, &op->o_ndn, NULL, op->o_tmpmemctx ) == 0 ) { rc = 1; break; } } return rc; } else if ( ber_bvcmp( &aci_bv[ ACI_BV_GROUP ], &type ) == 0 ) { struct berval oc, at; if ( BER_BVISNULL( &opts ) ) { oc = aci_bv[ ACI_BV_GROUP_CLASS ]; at = aci_bv[ ACI_BV_GROUP_ATTR ]; } else { if ( acl_get_part( &opts, 0, '/', &oc ) < 0 ) { LDAP_BUG(); } if ( acl_get_part( &opts, 1, '/', &at ) < 0 ) { at = aci_bv[ ACI_BV_GROUP_ATTR ]; } } if ( aci_group_member( &sdn, &oc, &at, op, e, nmatch, matches ) ) { return 1; } } else if ( ber_bvcmp( &aci_bv[ ACI_BV_ROLE ], &type ) == 0 ) { struct berval oc, at; if ( BER_BVISNULL( &opts ) ) { oc = aci_bv[ ACI_BV_ROLE_CLASS ]; at = aci_bv[ ACI_BV_ROLE_ATTR ]; } else { if ( acl_get_part( &opts, 0, '/', &oc ) < 0 ) { LDAP_BUG(); } if ( acl_get_part( &opts, 1, '/', &at ) < 0 ) { at = aci_bv[ ACI_BV_ROLE_ATTR ]; } } if ( aci_group_member( &sdn, &oc, &at, op, e, nmatch, matches ) ) { return 1; } } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) { if ( acl_match_set( &sdn, op, e, NULL ) ) { return 1; } } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) { if ( acl_match_set( &sdn, op, e, (struct berval *)&aci_bv[ ACI_BV_SET_ATTR ] ) ) { return 1; } } else { /* it passed normalization! */ LDAP_BUG(); } return 0; }
static int rc_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; retcode_t *rd = (retcode_t *)on->on_bi.bi_private; int rc = ARG_BAD_CONF; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case RC_PARENT: if ( !BER_BVISEMPTY( &rd->rd_pdn )) { rc = value_add_one( &c->rvalue_vals, &rd->rd_pdn ); if ( rc == 0 ) { rc = value_add_one( &c->rvalue_nvals, &rd->rd_npdn ); } return rc; } rc = 0; break; case RC_ITEM: { retcode_item_t *rdi; int i; for ( rdi = rd->rd_item, i = 0; rdi; rdi = rdi->rdi_next, i++ ) { char buf[4096]; struct berval bv; char *ptr; bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); bv.bv_len += rdi->rdi_line.bv_len; ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( ptr, buf ); ptr = lutil_strncopy( ptr, rdi->rdi_line.bv_val, rdi->rdi_line.bv_len ); ber_bvarray_add( &c->rvalue_vals, &bv ); } rc = 0; } break; default: LDAP_BUG(); break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); rc = 0; } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } break; case RC_ITEM: if ( c->valx == -1 ) { retcode_item_t *rdi, *next; for ( rdi = rd->rd_item; rdi != NULL; rdi = next ) { next = rdi->rdi_next; retcode_item_destroy( rdi ); } } else { retcode_item_t **rdip, *rdi; int i; for ( rdip = &rd->rd_item, i = 0; i <= c->valx && *rdip; i++, rdip = &(*rdip)->rdi_next ) ; if ( *rdip == NULL ) { return 1; } rdi = *rdip; *rdip = rdi->rdi_next; retcode_item_destroy( rdi ); } rc = 0; break; default: LDAP_BUG(); break; } return rc; /* FIXME */ } switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } rd->rd_pdn = c->value_dn; rd->rd_npdn = c->value_ndn; rc = 0; break; case RC_ITEM: { retcode_item_t rdi = { BER_BVNULL }, **rdip; struct berval bv, rdn, nrdn; char *next = NULL; int i; if ( c->argc < 3 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"retcode-item <RDN> <retcode> [<text>]\": " "missing args" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( c->argv[ 1 ], 0, 0, &bv ); rc = dnPrettyNormal( NULL, &bv, &rdn, &nrdn, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to normalize RDN \"%s\": %d", c->argv[ 1 ], rc ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( !dnIsOneLevelRDN( &nrdn ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "value \"%s\" is not a RDN", c->argv[ 1 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( BER_BVISNULL( &rd->rd_npdn ) ) { /* FIXME: we use the database suffix */ if ( c->be->be_nsuffix == NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "either \"retcode-parent\" " "or \"suffix\" must be defined" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rd->rd_pdn, &c->be->be_suffix[ 0 ] ); ber_dupbv( &rd->rd_npdn, &c->be->be_nsuffix[ 0 ] ); } build_new_dn( &rdi.rdi_dn, &rd->rd_pdn, &rdn, NULL ); build_new_dn( &rdi.rdi_ndn, &rd->rd_npdn, &nrdn, NULL ); ch_free( rdn.bv_val ); ch_free( nrdn.bv_val ); rdi.rdi_err = strtol( c->argv[ 2 ], &next, 0 ); if ( next == c->argv[ 2 ] || next[ 0 ] != '\0' ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse return code \"%s\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } rdi.rdi_mask = SN_DG_OP_ALL; if ( c->argc > 3 ) { for ( i = 3; i < c->argc; i++ ) { if ( strncasecmp( c->argv[ i ], "op=", STRLENOF( "op=" ) ) == 0 ) { char **ops; int j; ops = ldap_str2charray( &c->argv[ i ][ STRLENOF( "op=" ) ], "," ); assert( ops != NULL ); rdi.rdi_mask = SN_DG_OP_NONE; for ( j = 0; ops[ j ] != NULL; j++ ) { if ( strcasecmp( ops[ j ], "add" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ADD; } else if ( strcasecmp( ops[ j ], "bind" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_BIND; } else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_COMPARE; } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_DELETE; } else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_MODIFY; } else if ( strcasecmp( ops[ j ], "rename" ) == 0 || strcasecmp( ops[ j ], "modrdn" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_RENAME; } else if ( strcasecmp( ops[ j ], "search" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_SEARCH; } else if ( strcasecmp( ops[ j ], "extended" ) == 0 ) { rdi.rdi_mask |= SN_DG_EXTENDED; } else if ( strcasecmp( ops[ j ], "auth" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_AUTH; } else if ( strcasecmp( ops[ j ], "read" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_READ; } else if ( strcasecmp( ops[ j ], "write" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_WRITE; } else if ( strcasecmp( ops[ j ], "all" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ALL; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown op \"%s\"", ops[ j ] ); ldap_charray_free( ops ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } ldap_charray_free( ops ); } else if ( strncasecmp( c->argv[ i ], "text=", STRLENOF( "text=" ) ) == 0 ) { if ( !BER_BVISNULL( &rdi.rdi_text ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"text\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text ); } else if ( strncasecmp( c->argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 ) { struct berval dn; if ( !BER_BVISNULL( &rdi.rdi_matched ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"matched\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn ); if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to prettify matched DN \"%s\"", &c->argv[ i ][ STRLENOF( "matched=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 ) { char **refs; int j; if ( rdi.rdi_ref != NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"ref\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( rdi.rdi_err != LDAP_REFERRAL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "providing \"ref\" " "along with a non-referral " "resultCode may cause slapd failures " "related to internal checks" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); } refs = ldap_str2charray( &c->argv[ i ][ STRLENOF( "ref=" ) ], " " ); assert( refs != NULL ); for ( j = 0; refs[ j ] != NULL; j++ ) { struct berval bv; ber_str2bv( refs[ j ], 0, 1, &bv ); ber_bvarray_add( &rdi.rdi_ref, &bv ); } ldap_charray_free( refs ); } else if ( strncasecmp( c->argv[ i ], "sleeptime=", STRLENOF( "sleeptime=" ) ) == 0 ) { if ( rdi.rdi_sleeptime != 0 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"sleeptime\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( lutil_atoi( &rdi.rdi_sleeptime, &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"sleeptime=%s\"", &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "unsolicited=", STRLENOF( "unsolicited=" ) ) == 0 ) { char *data; if ( !BER_BVISNULL( &rdi.rdi_unsolicited_oid ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"unsolicited\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } data = strchr( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], ':' ); if ( data != NULL ) { struct berval oid; if ( ldif_parse_line2( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], &oid, &rdi.rdi_unsolicited_data, NULL ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"unsolicited\"" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rdi.rdi_unsolicited_oid, &oid ); } else { ber_str2bv( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], 0, 1, &rdi.rdi_unsolicited_oid ); } } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) { char *arg = &c->argv[ i ][ STRLENOF( "flags=" ) ]; if ( strcasecmp( arg, "disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "pre-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "post-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_POST_DISCONNECT; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown flag \"%s\"", arg ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown option \"%s\"", c->argv[ i ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } } rdi.rdi_line.bv_len = 2*(c->argc - 1) + c->argc - 2; for ( i = 1; i < c->argc; i++ ) { rdi.rdi_line.bv_len += strlen( c->argv[ i ] ); } next = rdi.rdi_line.bv_val = ch_malloc( rdi.rdi_line.bv_len + 1 ); for ( i = 1; i < c->argc; i++ ) { *next++ = '"'; next = lutil_strcopy( next, c->argv[ i ] ); *next++ = '"'; *next++ = ' '; } *--next = '\0'; for ( rdip = &rd->rd_item; *rdip; rdip = &(*rdip)->rdi_next ) /* go to last */ ; *rdip = ( retcode_item_t * )ch_malloc( sizeof( retcode_item_t ) ); *(*rdip) = rdi; rc = 0; } break; default: rc = SLAP_CONF_UNKNOWN; break; } return rc; }
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 = "?"; LDAP_BUG(); } /* 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; }
static int meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapReply *rs, ldap_back_send_t sendok, int dolock ) { metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; struct berval binddn = BER_BVC( "" ), cred = BER_BVC( "" ); int method = LDAP_AUTH_NONE, rc; rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, sendok, &binddn, &cred, &method ); if ( rc == LDAP_SUCCESS && !LDAP_BACK_CONN_ISBOUND( msc ) ) { int msgid; switch ( method ) { case LDAP_AUTH_NONE: case LDAP_AUTH_SIMPLE: if(!dolock) { ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } for (;;) { rs->sr_err = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred, NULL, NULL, &msgid ); if ( rs->sr_err != LDAP_X_CONNECTING ) { break; } ldap_pvt_thread_yield(); } if(!dolock) { ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); } rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok, dolock ); if ( rc == LDAP_SUCCESS ) { /* set rebind stuff in case of successful proxyAuthz bind, * so that referral chasing is attempted using the right * identity */ LDAP_BACK_CONN_ISBOUND_SET( msc ); ber_bvreplace( &msc->msc_bound_ndn, &binddn ); if ( META_BACK_TGT_SAVECRED( mt ) ) { if ( !BER_BVISNULL( &msc->msc_cred ) ) { memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len ); } ber_bvreplace( &msc->msc_cred, &cred ); ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc ); } } break; default: LDAP_BUG(); break; } } return LDAP_BACK_CONN_ISBOUND( msc ); }
int bdb_bind( Operation *op, SlapReply *rs ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; Entry *e; Attribute *a; EntryInfo *ei; AttributeDescription *password = slap_schema.si_ad_userPassword; DB_TXN *rtxn; DB_LOCK lock; Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_bind) ": dn: %s\n", op->o_req_dn.bv_val); /* allow noauth binds */ switch ( be_rootdn_bind( op, NULL ) ) { case LDAP_SUCCESS: /* frontend will send result */ return rs->sr_err = LDAP_SUCCESS; default: /* give the database a chance */ /* NOTE: this behavior departs from that of other backends, * since the others, in case of password checking failure * do not give the database a chance. If an entry with * rootdn's name does not exist in the database the result * will be the same. See ITS#4962 for discussion. */ break; } rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); switch(rs->sr_err) { case 0: break; default: rs->sr_text = "internal error"; send_ldap_result( op, rs ); return rs->sr_err; } dn2entry_retry: /* get entry with reader lock */ rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, &lock ); switch(rs->sr_err) { case DB_NOTFOUND: case 0: break; case LDAP_BUSY: send_ldap_error( op, rs, LDAP_BUSY, "ldap_server_busy" ); return LDAP_BUSY; case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto dn2entry_retry; default: send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); return rs->sr_err; } e = ei->bei_e; if ( rs->sr_err == DB_NOTFOUND ) { if( e != NULL ) { bdb_cache_return_entry_r( bdb, e, &lock ); e = NULL; } rs->sr_err = LDAP_INVALID_CREDENTIALS; send_ldap_result( op, rs ); return rs->sr_err; } ber_dupbv( &op->oq_bind.rb_edn, &e->e_name ); /* check for deleted */ if ( is_entry_subentry( e ) ) { /* entry is an subentry, don't allow bind */ Debug( LDAP_DEBUG_TRACE, "entry is subentry\n" ); rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } if ( is_entry_alias( e ) ) { /* entry is an alias, don't allow bind */ Debug( LDAP_DEBUG_TRACE, "entry is alias\n" ); rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } if ( is_entry_referral( e ) ) { Debug( LDAP_DEBUG_TRACE, "entry is referral\n" ); rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } switch ( op->oq_bind.rb_method ) { case LDAP_AUTH_SIMPLE: a = attr_find( e->e_attrs, password ); if ( a == NULL ) { rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred, &rs->sr_text ) != 0 ) { /* failure; stop front end from sending result */ rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } rs->sr_err = 0; break; default: LDAP_BUG(); /* should not be reachable */ rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; rs->sr_text = "authentication method not supported"; } done: /* free entry and reader lock */ if( e != NULL ) { bdb_cache_return_entry_r( bdb, e, &lock ); } if ( rs->sr_err ) { send_ldap_result( op, rs ); rs_send_cleanup( rs ); } /* front end will send result on success (rs->sr_err==0) */ return rs->sr_err; }
static int dds_op_modify( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dds_info_t *di = (dds_info_t *)on->on_bi.bi_private; Modifications *mod; Entry *e = NULL; BackendInfo *bi = op->o_bd->bd_info; int was_dynamicObject = 0, is_dynamicObject = 0; struct berval bv_entryTtl = BER_BVNULL; time_t entryTtl = 0; char textbuf[ SLAP_TEXT_BUFLEN ]; if ( DDS_OFF( di ) ) { return SLAP_CB_CONTINUE; } /* bv_entryTtl stores the string representation of the entryTtl * across modifies for consistency checks of the final value; * the bv_val points to a static buffer; the bv_len is zero when * the attribute is deleted. * entryTtl stores the integer representation of the entryTtl; * its value is -1 when the attribute is deleted; it is 0 only * if no modifications of the entryTtl occurred, as an entryTtl * of 0 is invalid. */ bv_entryTtl.bv_val = textbuf; op->o_bd->bd_info = (BackendInfo *)on->on_info; rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn, slap_schema.si_oc_dynamicObject, slap_schema.si_ad_entryTtl, 0, &e ); if ( rs->sr_err == LDAP_SUCCESS && e != NULL ) { Attribute *a = attr_find( e->e_attrs, slap_schema.si_ad_entryTtl ); /* the value of the entryTtl is saved for later checks */ if ( a != NULL ) { unsigned long ttl; int rc; bv_entryTtl.bv_len = a->a_nvals[ 0 ].bv_len; memcpy( bv_entryTtl.bv_val, a->a_nvals[ 0 ].bv_val, bv_entryTtl.bv_len ); bv_entryTtl.bv_val[ bv_entryTtl.bv_len ] = '\0'; rc = lutil_atoul( &ttl, bv_entryTtl.bv_val ); assert( rc == 0 ); entryTtl = (time_t)ttl; } be_entry_release_r( op, e ); e = NULL; was_dynamicObject = is_dynamicObject = 1; } op->o_bd->bd_info = bi; rs->sr_err = LDAP_SUCCESS; for ( mod = op->orm_modlist; mod; mod = mod->sml_next ) { if ( mod->sml_desc == slap_schema.si_ad_objectClass ) { int i; ObjectClass *oc; switch ( mod->sml_op ) { case LDAP_MOD_DELETE: if ( mod->sml_values == NULL ) { is_dynamicObject = 0; break; } for ( i = 0; !BER_BVISNULL( &mod->sml_values[ i ] ); i++ ) { oc = oc_bvfind( &mod->sml_values[ i ] ); if ( oc == slap_schema.si_oc_dynamicObject ) { is_dynamicObject = 0; break; } } break; case LDAP_MOD_REPLACE: if ( mod->sml_values == NULL ) { is_dynamicObject = 0; break; } /* fallthru */ case LDAP_MOD_ADD: for ( i = 0; !BER_BVISNULL( &mod->sml_values[ i ] ); i++ ) { oc = oc_bvfind( &mod->sml_values[ i ] ); if ( oc == slap_schema.si_oc_dynamicObject ) { is_dynamicObject = 1; break; } } break; } } else if ( mod->sml_desc == slap_schema.si_ad_entryTtl ) { unsigned long uttl; time_t ttl; int rc; switch ( mod->sml_op ) { case LDAP_MOD_DELETE: case SLAP_MOD_SOFTDEL: /* FIXME? */ if ( mod->sml_values != NULL ) { if ( BER_BVISEMPTY( &bv_entryTtl ) || !bvmatch( &bv_entryTtl, &mod->sml_values[ 0 ] ) ) { rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE ); if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; } else { rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE; } goto done; } } bv_entryTtl.bv_len = 0; entryTtl = -1; break; case LDAP_MOD_REPLACE: bv_entryTtl.bv_len = 0; entryTtl = -1; /* fallthru */ case LDAP_MOD_ADD: case SLAP_MOD_SOFTADD: /* FIXME? */ case SLAP_MOD_ADD_IF_NOT_PRESENT: /* FIXME? */ assert( mod->sml_values != NULL ); assert( BER_BVISNULL( &mod->sml_values[ 1 ] ) ); if ( !BER_BVISEMPTY( &bv_entryTtl ) ) { rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE ); if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; } else { rs->sr_text = "attribute 'entryTtl' cannot have multiple values"; rs->sr_err = LDAP_CONSTRAINT_VIOLATION; } goto done; } rc = lutil_atoul( &uttl, mod->sml_values[ 0 ].bv_val ); ttl = (time_t)uttl; assert( rc == 0 ); if ( ttl > DDS_RF2589_MAX_TTL ) { rs->sr_err = LDAP_PROTOCOL_ERROR; rs->sr_text = "invalid time-to-live for dynamicObject"; goto done; } if ( ttl <= 0 || ttl > di->di_max_ttl ) { /* FIXME: I don't understand if this has to be an error, * or an indication that the requested Ttl has been * shortened to di->di_max_ttl >= 1 day */ rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; rs->sr_text = "time-to-live for dynamicObject exceeds administrative limit"; goto done; } entryTtl = ttl; bv_entryTtl.bv_len = mod->sml_values[ 0 ].bv_len; memcpy( bv_entryTtl.bv_val, mod->sml_values[ 0 ].bv_val, bv_entryTtl.bv_len ); bv_entryTtl.bv_val[ bv_entryTtl.bv_len ] = '\0'; break; case LDAP_MOD_INCREMENT: if ( BER_BVISEMPTY( &bv_entryTtl ) ) { rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE ); if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; } else { rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE; rs->sr_text = "modify/increment: entryTtl: no such attribute"; } goto done; } entryTtl++; if ( entryTtl > DDS_RF2589_MAX_TTL ) { rs->sr_err = LDAP_PROTOCOL_ERROR; rs->sr_text = "invalid time-to-live for dynamicObject"; } else if ( entryTtl <= 0 || entryTtl > di->di_max_ttl ) { /* FIXME: I don't understand if this has to be an error, * or an indication that the requested Ttl has been * shortened to di->di_max_ttl >= 1 day */ rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; rs->sr_text = "time-to-live for dynamicObject exceeds administrative limit"; } if ( rs->sr_err != LDAP_SUCCESS ) { rc = backend_attribute( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE ); if ( rc == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_text = NULL; rs->sr_err = LDAP_NO_SUCH_OBJECT; } goto done; } bv_entryTtl.bv_len = snprintf( textbuf, sizeof( textbuf ), "%ld", entryTtl ); break; default: LDAP_BUG(); break; } } else if ( mod->sml_desc == ad_entryExpireTimestamp ) { /* should have been trapped earlier */ assert( mod->sml_flags & SLAP_MOD_INTERNAL ); } } done:; if ( rs->sr_err == LDAP_SUCCESS ) { int rc; /* FIXME: this could be allowed when the Relax control is used... * in that case: * * TODO * * static => dynamic: * entryTtl must be provided; add * entryExpireTimestamp accordingly * * dynamic => static: * entryTtl must be removed; remove * entryTimestamp accordingly * * ... but we need to make sure that there are no subordinate * issues... */ rc = is_dynamicObject - was_dynamicObject; if ( rc ) { #if 0 /* fix subordinate issues first */ if ( get_relax( op ) ) { switch ( rc ) { case -1: /* need to delete entryTtl to have a consistent entry */ if ( entryTtl != -1 ) { rs->sr_text = "objectClass modification from dynamicObject to static entry requires entryTtl deletion"; rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; } break; case 1: /* need to add entryTtl to have a consistent entry */ if ( entryTtl <= 0 ) { rs->sr_text = "objectClass modification from static entry to dynamicObject requires entryTtl addition"; rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; } break; } } else #endif { switch ( rc ) { case -1: rs->sr_text = "objectClass modification cannot turn dynamicObject into static entry"; break; case 1: rs->sr_text = "objectClass modification cannot turn static entry into dynamicObject"; break; } rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; } if ( rc != LDAP_SUCCESS ) { rc = backend_attribute( op, NULL, &op->o_req_ndn, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE ); if ( rc == LDAP_INSUFFICIENT_ACCESS ) { rs->sr_text = NULL; rs->sr_err = LDAP_NO_SUCH_OBJECT; } } } } if ( rs->sr_err == LDAP_SUCCESS && entryTtl != 0 ) { Modifications *tmpmod = NULL, **modp; for ( modp = &op->orm_modlist; *modp; modp = &(*modp)->sml_next ) ; tmpmod = ch_calloc( 1, sizeof( Modifications ) ); tmpmod->sml_flags = SLAP_MOD_INTERNAL; tmpmod->sml_type = ad_entryExpireTimestamp->ad_cname; tmpmod->sml_desc = ad_entryExpireTimestamp; *modp = tmpmod; if ( entryTtl == -1 ) { /* delete entryExpireTimestamp */ tmpmod->sml_op = LDAP_MOD_DELETE; } else { time_t expire; char tsbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; struct berval bv; /* keep entryExpireTimestamp consistent * with entryTtl */ expire = slap_get_time() + entryTtl; bv.bv_val = tsbuf; bv.bv_len = sizeof( tsbuf ); slap_timestamp( &expire, &bv ); tmpmod->sml_op = LDAP_MOD_REPLACE; value_add_one( &tmpmod->sml_values, &bv ); value_add_one( &tmpmod->sml_nvalues, &bv ); tmpmod->sml_numvals = 1; } } if ( rs->sr_err ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; send_ldap_result( op, rs ); return rs->sr_err; } return SLAP_CB_CONTINUE; }
struct berbuf * backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... ) { va_list strs; ber_len_t cdlen; assert( dest != NULL ); assert( fmt != NULL ); assert( dest->bb_len == 0 || dest->bb_len > dest->bb_val.bv_len ); assert( dest->bb_val.bv_val == NULL || dest->bb_val.bv_len == strlen( dest->bb_val.bv_val ) ); #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_strfcat()\n" ); #endif /* BACKSQL_TRACE */ va_start( strs, fmt ); if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) { dest->bb_val.bv_val = (char *)ber_memalloc_x( BACKSQL_STR_GROW * sizeof( char ), memctx ); dest->bb_val.bv_len = 0; dest->bb_len = BACKSQL_STR_GROW; } cdlen = dest->bb_val.bv_len; for ( ; fmt[0]; fmt++ ) { ber_len_t cslen, grow; char *cstr, cc[ 2 ] = { '\0', '\0' }; struct berval *cbv; switch ( fmt[ 0 ] ) { /* berval */ case 'b': cbv = va_arg( strs, struct berval * ); cstr = cbv->bv_val; cslen = cbv->bv_len; break; /* length + string */ case 'l': cslen = va_arg( strs, ber_len_t ); cstr = va_arg( strs, char * ); break; /* string */ case 's': cstr = va_arg( strs, char * ); cslen = strlen( cstr ); break; /* char */ case 'c': /* * `char' is promoted to `int' when passed through `...' */ cc[0] = va_arg( strs, int ); cstr = cc; cslen = 1; break; default: LDAP_BUG(); } grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen ); if ( dest->bb_len - cdlen <= cslen ) { char *tmp_dest; #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): " "buflen=%d, cdlen=%d, cslen=%d " "-- reallocating dest\n", dest->bb_len, cdlen + 1, cslen ); #endif /* BACKSQL_TRACE */ tmp_dest = (char *)ber_memrealloc_x( dest->bb_val.bv_val, ( dest->bb_len ) + grow * sizeof( char ), memctx ); if ( tmp_dest == NULL ) { Debug( LDAP_DEBUG_ANY, "backsql_strfcat(): " "could not reallocate string buffer.\n" ); va_end( strs ); return NULL; } dest->bb_val.bv_val = tmp_dest; dest->bb_len += grow * sizeof( char ); #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): " "new buflen=%d, dest=%p\n", dest->bb_len, dest ); #endif /* BACKSQL_TRACE */ } assert( cstr != NULL ); memcpy( dest->bb_val.bv_val + cdlen, cstr, cslen + 1 ); cdlen += cslen; } va_end( strs ); #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "<==backsql_strfcat() (dest=\"%s\")\n", dest->bb_val.bv_val ); #endif /* BACKSQL_TRACE */ dest->bb_val.bv_len = cdlen; return dest; }
int frontend_init( void ) { /* data */ frontendDB = &slap_frontendDB; frontendDB->bd_self = frontendDB; /* biglock */ slap_biglock_init(frontendDB); /* ACLs */ frontendDB->be_dfltaccess = ACL_READ; /* limits */ frontendDB->be_def_limit.lms_t_soft = SLAPD_DEFAULT_TIMELIMIT; /* backward compatible limits */ frontendDB->be_def_limit.lms_t_hard = 0; frontendDB->be_def_limit.lms_s_soft = SLAPD_DEFAULT_SIZELIMIT; /* backward compatible limits */ frontendDB->be_def_limit.lms_s_hard = 0; frontendDB->be_def_limit.lms_s_unchecked = -1; /* no limit on unchecked size */ frontendDB->be_def_limit.lms_s_pr = 0; /* page limit */ frontendDB->be_def_limit.lms_s_pr_hide = 0; /* don't hide number of entries left */ frontendDB->be_def_limit.lms_s_pr_total = 0; /* number of total entries returned by pagedResults equal to hard limit */ ldap_pvt_thread_mutex_init( &frontendDB->be_pcl_mutex ); /* suffix */ frontendDB->be_suffix = ch_calloc( 2, sizeof( struct berval ) ); ber_str2bv( "", 0, 1, &frontendDB->be_suffix[0] ); BER_BVZERO( &frontendDB->be_suffix[1] ); frontendDB->be_nsuffix = ch_calloc( 2, sizeof( struct berval ) ); ber_str2bv( "", 0, 1, &frontendDB->be_nsuffix[0] ); BER_BVZERO( &frontendDB->be_nsuffix[1] ); /* info */ frontendDB->bd_info = &slap_frontendInfo; SLAP_BFLAGS(frontendDB) |= SLAP_BFLAG_FRONTEND; /* name */ frontendDB->bd_info->bi_type = "frontend"; /* known controls */ { int i; frontendDB->bd_info->bi_controls = slap_known_controls; for ( i = 0; slap_known_controls[ i ]; i++ ) { int cid; if ( slap_find_control_id( slap_known_controls[ i ], &cid ) == LDAP_CONTROL_NOT_FOUND ) { LDAP_BUG(); return -1; } frontendDB->bd_info->bi_ctrls[ cid ] = 1; frontendDB->be_ctrls[ cid ] = 1; } } /* calls */ frontendDB->bd_info->bi_op_abandon = fe_op_abandon; frontendDB->bd_info->bi_op_add = fe_op_add; frontendDB->bd_info->bi_op_bind = fe_op_bind; frontendDB->bd_info->bi_op_compare = fe_op_compare; frontendDB->bd_info->bi_op_delete = fe_op_delete; frontendDB->bd_info->bi_op_modify = fe_op_modify; frontendDB->bd_info->bi_op_modrdn = fe_op_modrdn; frontendDB->bd_info->bi_op_search = fe_op_search; frontendDB->bd_info->bi_extended = fe_extended; frontendDB->bd_info->bi_operational = fe_aux_operational; frontendDB->bd_info->bi_entry_get_rw = fe_entry_get_rw; frontendDB->bd_info->bi_entry_release_rw = fe_entry_release_rw; frontendDB->bd_info->bi_access_allowed = fe_access_allowed; frontendDB->bd_info->bi_acl_group = fe_acl_group; frontendDB->bd_info->bi_acl_attribute = fe_acl_attribute; #if 0 /* FIXME: is this too early? */ return backend_startup_one( frontendDB ); #endif return 0; }
static int monitor_subsys_rww_update( Operation *op, SlapReply *rs, Entry *e ) { monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private; Connection *c; ber_socket_t connindex; long nconns, nwritewaiters, nreadwaiters; int i; struct berval nrdn; Attribute *a; char buf[LDAP_PVT_INTTYPE_CHARS(long)]; long num = 0; ber_len_t len; assert( mi != NULL ); assert( e != NULL ); dnRdn( &e->e_nname, &nrdn ); for ( i = 0; !BER_BVISNULL( &monitor_rww[ i ].nrdn ); i++ ) { if ( dn_match( &nrdn, &monitor_rww[ i ].nrdn ) ) { break; } } if ( i == MONITOR_RWW_LAST ) { return SLAP_CB_CONTINUE; } nconns = nwritewaiters = nreadwaiters = 0; for ( c = connection_first( &connindex ); c != NULL; c = connection_next( c, &connindex ), nconns++ ) { if ( c->c_writewaiter ) { nwritewaiters++; } /* FIXME: ?!? */ if ( c->c_currentber != NULL ) { nreadwaiters++; } } connection_done(c); switch ( i ) { case MONITOR_RWW_READ: num = nreadwaiters; break; case MONITOR_RWW_WRITE: num = nwritewaiters; break; default: LDAP_BUG(); } snprintf( buf, sizeof( buf ), "%ld", num ); a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter ); assert( a != NULL ); len = strlen( buf ); if ( len > a->a_vals[ 0 ].bv_len ) { a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 ); if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) { BER_BVZERO( &a->a_vals[ 0 ] ); return SLAP_CB_CONTINUE; } } memcpy( a->a_vals[ 0 ].bv_val, buf, len + 1 ); a->a_vals[ 0 ].bv_len = len; /* FIXME: touch modifyTimestamp? */ return SLAP_CB_CONTINUE; }