Example #1
0
int
wt_bind( Operation *op, SlapReply *rs )
{
    struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
	WT_SESSION *session;
	wt_ctx *wc;
	int rc;
	Entry *e = NULL;
	Attribute *a;
	AttributeDescription *password = slap_schema.si_ad_userPassword;

    Debug( LDAP_DEBUG_ARGS,
		   "==> " LDAP_XSTRING(wt_bind) ": dn: %s\n",
		   op->o_req_dn.bv_val, 0, 0);

	/* 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;
	}

	wc = wt_ctx_get(op, wi);
	if( !wc ){
		Debug( LDAP_DEBUG_ANY,
			   LDAP_XSTRING(wt_bind)
			   ": wt_ctx_get failed\n",
			   0, 0, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
        send_ldap_result( op, rs );
        return rs->sr_err;
	}

	/* get entry */
	rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
	switch( rc ) {
	case 0:
		break;
	case WT_NOTFOUND:
		rs->sr_err = LDAP_INVALID_CREDENTIALS;
		send_ldap_result( op, rs );
		return rs->sr_err;
	default:
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
        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", 0,
			   0, 0 );
		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", 0, 0, 0 );
		rs->sr_err = LDAP_INVALID_CREDENTIALS;
		goto done;
	}

	if ( is_entry_referral( e ) ) {
		Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
			   0, 0 );
		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:
		rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
		rs->sr_text = "authentication method not supported";
	}

done:
	/* free entry */
	if (e) {
		wt_entry_return(e);
	}
	if (rs->sr_err) {
		send_ldap_result( op, rs );
        if ( rs->sr_ref ) {
            ber_bvarray_free( rs->sr_ref );
			rs->sr_ref = NULL;
		}
	}
	return rs->sr_err;
}
Example #2
0
int
wt_compare( Operation *op, SlapReply *rs )
{
    struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
	Entry *e = NULL;
	int manageDSAit = get_manageDSAit( op );
	int rc;
	wt_ctx *wc = NULL;

	Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_compare) ": %s\n",
		   op->o_req_dn.bv_val, 0, 0 );

	wc = wt_ctx_get(op, wi);
	if( !wc ){
		Debug( LDAP_DEBUG_ANY,
			   LDAP_XSTRING(wt_compare)
			   ": wt_ctx_get failed\n",
			   0, 0, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
        send_ldap_result( op, rs );
        return rs->sr_err;
	}

	rs->sr_err = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
	switch( rs->sr_err ) {
	case 0:
	case WT_NOTFOUND:
		break;
	default:
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
		goto return_results;
	}

	if ( rs->sr_err == WT_NOTFOUND ) {
		if ( e != NULL ) {
			/* return referral only if "disclose" is granted on the object */
			if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
								   NULL, ACL_DISCLOSE, NULL ) )
			{
				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			} else {
				rs->sr_matched = ch_strdup( e->e_dn );
				if ( is_entry_referral( e )) {
					BerVarray ref = get_entry_referrals( op, e );
					rs->sr_ref = referral_rewrite( ref,
												   &e->e_name,
												   &op->o_req_dn,
												   LDAP_SCOPE_DEFAULT );
					ber_bvarray_free( ref );
				} else {
					rs->sr_ref = NULL;
				}
				rs->sr_err = LDAP_REFERRAL;
			}
			wt_entry_return( e );
			e = NULL;
		} else {
			rs->sr_ref = referral_rewrite( default_referral,
										   NULL,
										   &op->o_req_dn,
										   LDAP_SCOPE_DEFAULT );
			rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
		}

		rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
		send_ldap_result( op, rs );
		goto done;
	}

	if (!manageDSAit && is_entry_referral( e ) ) {
		/* return referral only if "disclose" is granted on the object */
		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
							  NULL, ACL_DISCLOSE, NULL ) )
		{
			rs->sr_err = LDAP_NO_SUCH_OBJECT;
		} else {
			/* entry is a referral, don't allow compare */
			rs->sr_ref = get_entry_referrals( op, e );
			rs->sr_err = LDAP_REFERRAL;
			rs->sr_matched = e->e_name.bv_val;
		}

		Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 0, 0 );

		send_ldap_result( op, rs );

		ber_bvarray_free( rs->sr_ref );
		rs->sr_ref = NULL;
		rs->sr_matched = NULL;
		goto done;
	}

	rs->sr_err = slap_compare_entry( op, e, op->orc_ava );

return_results:
	send_ldap_result( op, rs );

	switch ( rs->sr_err ) {
	case LDAP_COMPARE_FALSE:
	case LDAP_COMPARE_TRUE:
		rs->sr_err = LDAP_SUCCESS;
		break;
	}

done:
	if ( e != NULL ) {
		wt_entry_return( e );
	}
    return rs->sr_err;
}
Example #3
0
int
wt_modify( Operation *op, SlapReply *rs )
{
	struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
	wt_ctx *wc = NULL;
	Entry		*e = NULL;
	int		manageDSAit = get_manageDSAit( op );
	char textbuf[SLAP_TEXT_BUFLEN];
	size_t textlen = sizeof textbuf;
	Entry		dummy = {0};

	LDAPControl **preread_ctrl = NULL;
	LDAPControl **postread_ctrl = NULL;
	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
	int num_ctrls = 0;

	int rc;

	Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(wt_modify) ": %s\n",
		   op->o_req_dn.bv_val, 0, 0 );

#ifdef LDAP_X_TXN
	if( op->o_txnSpec && txn_preop( op, rs ))
		return rs->sr_err;
#endif

	ctrls[num_ctrls] = NULL;

	wc = wt_ctx_get(op, wi);
	if( !wc ){
        Debug( LDAP_DEBUG_ANY,
			   LDAP_XSTRING(wt_add)
			   ": wt_ctx_get failed\n",
			   0, 0, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
        send_ldap_result( op, rs );
        return rs->sr_err;
	}

	/* Don't touch the opattrs, if this is a contextCSN update
	 * initiated from updatedn */
	if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next ||
		 op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) {

		slap_mods_opattrs( op, &op->orm_modlist, 1 );
	}

	/* get entry */
	rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
	switch( rc ) {
	case 0:
		break;
	case WT_NOTFOUND:
		Debug( LDAP_DEBUG_ARGS,
			   "<== " LDAP_XSTRING(wt_delete)
			   ": no such object %s\n",
			   op->o_req_dn.bv_val, 0, 0);
		/* TODO: lookup referrals */
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		goto return_results;
	default:
		Debug( LDAP_DEBUG_ANY,
			   LDAP_XSTRING(wt_modify)
			   ": wt_dn2entry failed (%d)\n",
			   rc, 0, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "internal error";
		goto return_results;
	}

	if ( !manageDSAit && is_entry_referral( e ) ) {
		/* entry is a referral, don't allow modify */
		rs->sr_ref = get_entry_referrals( op, e );

		Debug( LDAP_DEBUG_TRACE,
			   LDAP_XSTRING(wt_modify) ": entry is referral\n",
			   0, 0, 0 );

		rs->sr_err = LDAP_REFERRAL;
		rs->sr_matched = e->e_name.bv_val;
		rs->sr_flags = REP_REF_MUSTBEFREED;
		send_ldap_result( op, rs );
		rs->sr_matched = NULL;
		goto done;
	}

	if ( get_assert( op ) &&
		 ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
	{
		rs->sr_err = LDAP_ASSERTION_FAILED;
		goto return_results;
	}

	if( op->o_preread ) {
		if( preread_ctrl == NULL ) {
			preread_ctrl = &ctrls[num_ctrls++];
			ctrls[num_ctrls] = NULL;
		}
		if ( slap_read_controls( op, rs, e,
			&slap_pre_read_bv, preread_ctrl ) )
		{
			Debug( LDAP_DEBUG_TRACE,
				"<=- " LDAP_XSTRING(wt_modify) ": pre-read "
				"failed!\n", 0, 0, 0 );
			if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
				/* FIXME: is it correct to abort
				 * operation if control fails? */
				goto return_results;
			}
		}
	}

	/* begin transaction */
	rc = wc->session->begin_transaction(wc->session, NULL);
	if( rc ) {
		Debug( LDAP_DEBUG_TRACE,
			   LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
			   wiredtiger_strerror(rc), rc, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "begin_transaction failed";
		goto return_results;
	}
	Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(wt_modify) ": session id: %p\n",
		   wc->session, 0, 0 );

	/* Modify the entry */
	dummy = *e;
	rs->sr_err = wt_modify_internal( op, wc, op->orm_modlist,
									 &dummy, &rs->sr_text, textbuf, textlen );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE,
			   LDAP_XSTRING(wt_modify) ": modify failed (%d)\n",
			   rs->sr_err, 0, 0 );
		/* Only free attrs if they were dup'd.  */
		if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
		goto return_results;
	}

	/* change the entry itself */
	rs->sr_err = wt_id2entry_update( op, wc->session, &dummy );
	if ( rs->sr_err != 0 ) {
		Debug( LDAP_DEBUG_TRACE,
			   LDAP_XSTRING(wt_modify) ": id2entry update failed " "(%d)\n",
			   rs->sr_err, 0, 0 );
		if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) {
			rs->sr_text = "entry too big";
		} else {
			rs->sr_err = LDAP_OTHER;
			rs->sr_text = "entry update failed";
		}
		goto return_results;
	}

	if( op->o_noop ) {
		wc->session->rollback_transaction(wc->session, NULL);
		rs->sr_err = LDAP_X_NO_OPERATION;
		goto return_results;
	}

	/* Only free attrs if they were dup'd.  */
	if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;

	rc = wc->session->commit_transaction(wc->session, NULL);
	if( rc ) {
		Debug( LDAP_DEBUG_TRACE,
			   "<== " LDAP_XSTRING(wt_modify)
			   ": commit failed: %s (%d)\n",
			   wiredtiger_strerror(rc), rc, 0 );
		rs->sr_err = LDAP_OTHER;
		rs->sr_text = "commit failed";
		goto return_results;
	}

	Debug( LDAP_DEBUG_TRACE,
		   LDAP_XSTRING(wt_modify) ": updated%s id=%08lx dn=\"%s\"\n",
		   op->o_noop ? " (no-op)" : "",
		   dummy.e_id, op->o_req_dn.bv_val );

	if( op->o_postread ) {
		if( postread_ctrl == NULL ) {
			postread_ctrl = &ctrls[num_ctrls++];
			ctrls[num_ctrls] = NULL;
		}
		if( slap_read_controls( op, rs, &dummy,
								&slap_post_read_bv, postread_ctrl ) )
		{
			Debug( LDAP_DEBUG_TRACE,
				   "<=- " LDAP_XSTRING(wt_modify)
				   ": post-read failed!\n", 0, 0, 0 );
			if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
				/* FIXME: is it correct to abort
				 * operation if control fails? */
				goto return_results;
			}
		}
	}
	if( num_ctrls ) rs->sr_ctrls = ctrls;

	rs->sr_err = LDAP_SUCCESS;
	rs->sr_text = NULL;

return_results:
	if( dummy.e_attrs ) {
		attrs_free( dummy.e_attrs );
	}
	send_ldap_result( op, rs );

done:
	slap_graduate_commit_csn( op );

	if( e != NULL ) {
		wt_entry_return( e );
	}

	if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
		slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
		slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
	}
	if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
		slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
		slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
	}

	rs->sr_text = NULL;

	return rs->sr_err;
}