Пример #1
0
void PAR_warning(const Arg::StatusVector& v)
{
/**************************************
 *
 *	P A R _ w a r n i n g
 *
 **************************************
 *
 * Functional description
 *      This is for GBAK so that we can pass warning messages
 *      back to the client.  DO NOT USE this function until we
 *      fully implement warning at the engine level.
 *
 *	We will use the status vector like a warning vector.  What
 *	we are going to do is leave the [1] position of the vector
 *	as 0 so that this will not be treated as an error, and we
 *	will place our warning message in the consecutive positions.
 *	It will be up to the caller to check these positions for
 *	the message.
 *
 **************************************/
	fb_assert(v.value()[0] == isc_arg_warning);

	thread_db* tdbb = JRD_get_thread_data();

	// Make sure that the [1] position is 0 indicating that no error has occurred
	Arg::Gds p(FB_SUCCESS);

	// Now place your warning messages
	p.append(v);

	// Save into tdbb
	p.copyTo(tdbb->tdbb_status_vector);
}
Пример #2
0
//____________________________________________________________
//
//	Post an error sequence to the status vector.  Since an error
//	sequence can, in theory, be arbitrarily lock, pull a cheap
//	trick to get the address of the argument vector.
//
//	this is a copy of the routine found in err.c with the
//	exception that it uses a different error block - one which
//	is local to the V3 DSQL routines...
//
static void error_post(const Arg::StatusVector& v)
{
	// Save status vector in appropriate place
	v.copyTo(UDSQL_error->dsql_status);

	// Give up whatever we were doing and return to the user.
	Firebird::status_exception::raise(UDSQL_error->dsql_status);
}
Пример #3
0
void ERR_post_nothrow(const Arg::StatusVector& v)
/**************************************
 *
 *	E R R _ p o s t _ n o t h r o w
 *
 **************************************
 *
 * Functional description
 *	Create a status vector.
 *
 **************************************/
{
    fb_assert(v.value()[0] == isc_arg_gds);
    ISC_STATUS_ARRAY vector;
    v.copyTo(vector);
    ERR_make_permanent(vector);
    internal_post(vector);
}
Пример #4
0
bool ERR_post_warning(const Arg::StatusVector& v)
{
    /**************************************
     *
     *      E R R _ p o s t _ w a r n i n g
     *
     **************************************
     *
     * Functional description
     *	Post a warning to the current status vector.
     *
     **************************************/
    fb_assert(v.value()[0] == isc_arg_warning);

    size_t indx = 0, warning_indx = 0;
    ISC_STATUS* const status_vector = JRD_get_thread_data()->tdbb_status_vector;

    if (status_vector[0] != isc_arg_gds ||
            (status_vector[0] == isc_arg_gds && status_vector[1] == 0 &&
             status_vector[2] != isc_arg_warning))
    {
        // this is a blank status vector
        fb_utils::init_status(status_vector);
        indx = 2;
    }
    else
    {
        // find end of a status vector
        PARSE_STATUS(status_vector, indx, warning_indx);
        if (indx)
            --indx;
    }

    // stuff the warning
    if (indx + v.length() + 1 < ISC_STATUS_LENGTH)
    {
        memcpy(&status_vector[indx], v.value(), sizeof(ISC_STATUS) * (v.length() + 1));
        ERR_make_permanent(&status_vector[indx]);
        return true;
    }

    // not enough free space
    return false;
}
Пример #5
0
void UserManagement::checkSecurityResult(int errcode, IStatus* status,
	const char* userName, int operation)
{
	if (!errcode)
	{
	    return;
	}
	errcode = Auth::setGsecCode(errcode, operation);

	Arg::StatusVector tmp;
	tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
	if (errcode == GsecMsg22)
	{
		tmp << userName;
	}
	tmp.append(Arg::StatusVector(status));

	tmp.raise();
}
Пример #6
0
// We've got a blr error other than a syntax error. Handle it.
static void par_error(BlrReader& blrReader, const Arg::StatusVector& v, bool isSyntaxError)
{
	fb_assert(v.value()[0] == isc_arg_gds);

	// Don't bother to pass tdbb for error handling
	thread_db* tdbb = JRD_get_thread_data();

	if (isSyntaxError)
	{
		blrReader.seekBackward(1);
		Arg::Gds p(isc_invalid_blr);
		p << Arg::Num(blrReader.getOffset());
		p.append(v);
		p.copyTo(tdbb->tdbb_status_vector);
	}
	else
		v.copyTo(tdbb->tdbb_status_vector);

	// Give up whatever we were doing and return to the user.
	ERR_punt();
}
Пример #7
0
static ISC_STATUS error(ISC_STATUS* status, const Arg::StatusVector& v)
{
/**************************************
 *
 *	e r r o r
 *
 **************************************
 *
 * Functional description
 *	Stuff a status vector.
 *
 **************************************/
	return v.copyTo(status);
}
Пример #8
0
void ERR_make_permanent(Arg::StatusVector& v)
/**************************************
 *
 *	E R R _ m a k e _ p e r m a n e n t
 *
 **************************************
 *
 * Functional description
 *	Make strings in vector permanent
 *
 **************************************/
{
    ERR_make_permanent(const_cast<ISC_STATUS*>(v.value()));
}
Пример #9
0
void ERR_build_status(ISC_STATUS* status_vector, const Arg::StatusVector& v)
{
    /**************************************
     *
     *	E R R _  a p p e n d _ s t a t u s
     *
     **************************************
     *
     * Functional description
     *	Append the given status vector with the passed arguments.
     *
     **************************************/
    v.copyTo(status_vector);
    ERR_make_permanent(status_vector);
}
Пример #10
0
void UserManagement::execute(USHORT id)
{
#if (defined BOOT_BUILD || defined EMBEDDED)
	status_exception::raise(Arg::Gds(isc_wish_list));
#else
	if (!transaction || !commands[id])
	{
		// Already executed
		return;
	}

	if (id >= commands.getCount())
	{
		status_exception::raise(Arg::Gds(isc_random) << "Wrong job id passed to UserManagement::execute()");
	}

	ISC_STATUS_ARRAY status;
	int errcode = (!commands[id]->user_name_entered) ? GsecMsg18 :
		SECURITY_exec_line(status, database, transaction, commands[id], NULL, NULL);

	switch (errcode)
	{
	case 0: // nothing
	    break;
	case GsecMsg22:
		{
			Arg::StatusVector tmp;
			tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)) << Arg::Str(commands[id]->user_name);
			tmp.append(Arg::StatusVector(&status[0]));
			tmp.raise();
		}

	default:
		{
			Arg::StatusVector tmp;
			tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
			tmp.append(Arg::StatusVector(&status[0]));
			tmp.raise();
		}
	}

	delete commands[id];
	commands[id] = NULL;
#endif
}
Пример #11
0
void ERR_warning(const Arg::StatusVector& v)
{
    /**************************************
     *
     *	E R R _ w a r n i n g
     *
     **************************************
     *
     * Functional description
     *	Write an error out to the status vector but
     *	don't throw an exception.  This allows
     *	sending a warning message back to the user
     *	without stopping execution of a request.  Note
     *	that subsequent errors can supersede this one.
     *
     **************************************/
    thread_db* tdbb = JRD_get_thread_data();
    ISC_STATUS* s = tdbb->tdbb_status_vector;

    v.copyTo(s);
    ERR_make_permanent(s);
    DEBUG;
    tdbb->getRequest()->req_flags |= req_warning;
}
Пример #12
0
void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle)
{
	jrd_tra* oldTran = traHandle ? *traHandle : nullptr;
	if (att_transactions)
	{
		int n = 0;
		bool err = false;
		for (const jrd_tra* tra = att_transactions; tra; tra = tra->tra_next)
		{
			n++;
			if (tra != oldTran && !(tra->tra_flags & TRA_prepared))
				err = true;
		}

		// Cannot reset user session
		// There are open transactions (@1 active)
		if (err)
		{
			ERR_post(Arg::Gds(isc_ses_reset_err) <<
				Arg::Gds(isc_ses_reset_open_trans) << Arg::Num(n));
		}
	}

	// TODO: trigger before reset

	ULONG oldFlags = 0;
	SSHORT oldTimeout = 0;
	if (oldTran)
	{
		oldFlags = oldTran->tra_flags;
		oldTimeout = oldTran->tra_lock_timeout;

		try
		{
			// It will also run run ON TRANSACTION ROLLBACK triggers
			JRD_rollback_transaction(tdbb, oldTran);
			*traHandle = nullptr;
		}
		catch (const Exception& ex)
		{
			Arg::StatusVector error;
			error.assign(ex);
			error.prepend(Arg::Gds(isc_ses_reset_err));
			error.raise();
		}

		// Session was reset with warning(s)
		// Transaction is rolled back due to session reset, all changes are lost
		if (oldFlags & TRA_write)
		{
			ERR_post_warning(Arg::Warning(isc_ses_reset_warn) <<
				Arg::Gds(isc_ses_reset_tran_rollback));
		}
	}

	// reset DecFloat
	att_dec_status = DecimalStatus::DEFAULT;
	att_dec_binding = DecimalBinding::DEFAULT;

	// reset timeouts
	setIdleTimeout(0);
	setStatementTimeout(0);

	// reset context variables
	att_context_vars.clear();

	// reset role
	if (att_user->resetRole())
		SCL_release_all(att_security_classes);

	// reset GTT's
	releaseGTTs(tdbb);

	if (oldTran)
	{
		try
		{
			jrd_tra* newTran = TRA_start(tdbb, oldFlags, oldTimeout);

			// run ON TRANSACTION START triggers
			JRD_run_trans_start_triggers(tdbb, newTran);

			tdbb->setTransaction(newTran);
			*traHandle = newTran;
		}
		catch (const Exception& ex)
		{
			Arg::StatusVector error;
			error.assign(ex);
			error.prepend(Arg::Gds(isc_ses_reset_err));
			error.raise();
		}
	}

	// TODO: trigger after reset
}