Ejemplo n.º 1
0
/*{
** Name: qeu_devent 	- Drop an event definition.
**
** External QEF call:   status = qef_call(QEU_DEVENT, &qeuq_cb);
**
** Description:
**	Drop the event tuple and the event text from the appropriate
**	tables (iievent and iiqrytext).  An event may only be dropped
**	by name as a result of the DROP EVENT statement.
**
**	The single event tuple is deleted based on its name and owner (since
**	the iievent table is hashed on name and owner this is a singleton
**	keyed retrieval).  If the event tuple wasn't fetched, then an error
**	is returned to the user.
**
**	If the event was found then all permits applied to this event
**	are dropped (using qeu_dprot with the dummy event/table ids and
**	without a permit number to indicate ALL protection tuples).  In
**	this case qeu_dprot need not recheck that the event does exist.
**	Note that the qeu_dprot routine will open and close iiqrytext
**	to remove the text associated with the event permit.
**
**	Following permit removal all query text tuples associated with the
**	CREATE EVENT statement are removed from iiqrytext based on the
**	query text ids in the fetched event tuple.
**
** Inputs:
**      qef_cb                  QEF session control block
**      qeuq_cb
**	    .qeuq_eflag	        Designate error handling for user errors.
**		QEF_INTERNAL	Return error code.
**		QEF_EXTERNAL	Send message to user.
**	    .qeuq_culd		Number of event tuples.  Must be 1.
**	    .qeuq_uld_tup	Event tuple:
**		.dbe_name	Event name.
**		.dbe_owner	Event owner.
**		.dbe_type	Event type - ignored until there are more.
**				Remaining fields are assigned and used here.
**	    .qeuq_db_id		Database id.
**	    .qeuq_d_id		DMF session id.
**
** Outputs:
**      qeuq_cb
**	    .error.err_code	E_QE0002_INTERNAL_ERROR
**				E_QE0017_BAD_CB
**				E_QE0018_BAD_PARAM_IN_CB
**				E_QE0022_ABORTED
**				E_QE020B_EVENT_ABSENT (ret E_QE0025_USER_ERROR)
**	Returns:
**	    E_DB_{OK, WARN, ERROR, FATAL}
**	Exceptions:
**	    none
**
** History:
**	28-aug-89 (neil)
**	    Written for Terminator II/alerters.
**	09-feb-90 (neil)
**	   Added auditing functionality.
**	03-mar-90 (neil)
**	   Modify interface to que_dprot to indicate from DROP EVENT.
**	24-jun-92 (andre)
**	    after deleting IIEVENT tuple, call qeu_d_cascade to handle
**	    destruction of IIPROTECT, IIQRYTEXT tuples and marking dependent
**	    dbprocs dormant
**	08-sep-92 (andre)
**	    before calling qeu_d_cascade(), reset QEU_DROP_TEMP_TABLE in
**	    qeuq_flag_mask
**	24-jun-93 (robf)
**	    Perform MAC access check prior to drop of event. If no access is
**	    allowed then treat as non-existent event.
**	10-sep-93 (andre)
**	    before calling qeu_d_cascade(), set QEU_FORCE_QP_INVALIDATION in
**	    qeuq_flag_mask
**	21-sep-93 (stephenb)
**	    Replace generic I_SX2032_EVENT_ACCESS with I_SX203C_EVENT_DROP.
**	08-oct-93 (andre)
**	    qeu_d_cascade() expects one more parameter - an address of a 
**	    DMT_TBL_ENTRY describing table/view/index being dropped; for all 
**	    other types of objects, NULL must be passed
**	14-oct-93 (robf)
**          Make sure access check is on tuple being  deleted, not input tuple.
**	7-dec-93 (robf)
**          Check if event is in used by an alarm, if so reject the operation.
**	7-jun-94 (robf)
**          audit the security label for the event correctly on B1, this 
**	    ensures level auditing picks up the change. (Previously we were 
**	    auditing the input tuple security label, which was empty,
**	    not the delete tuple security label). Also don't try to
**	    but this makes the case clearer)
**	12-oct-94 (ramra01)
**	    Initialize variable local_status before use - 65258
**	13-jun-96 (nick)
**	    Above change didn't actually work.
**
*/
DB_STATUS
qeu_devent(
QEF_CB          *qef_cb,
QEUQ_CB		*qeuq_cb)
{
    QEU_CB	    	tranqeu;	/* For transaction request */
    bool	    	transtarted = FALSE;
    QEU_CB	    	evqeu;		/* For iievent table */
    QEF_DATA	    	evqef_data;
    DB_IIEVENT	    	*evtuple;	/* Input tuple with name and owner */
    DB_IIEVENT	    	evtuple_del;	/* Tuple currently being deleted */
    bool	    	event_opened = FALSE;
    DMR_ATTR_ENTRY  	evkey_array[2];	/* Key values from iievent */
    DMR_ATTR_ENTRY  	*evkey_ptr_array[2];
    DB_STATUS	    	status;
    DB_STATUS		local_status = E_DB_OK;
    i4	    	error;
    DB_ERROR		err;

    for (;;)	/* Dummy for loop for error breaks */
    {
	/* Validate CB and parameters */
	if (qeuq_cb->qeuq_type != QEUQCB_CB ||
            qeuq_cb->qeuq_length != sizeof(QEUQ_CB))
	{
	    status = E_DB_ERROR;
	    error = E_QE0017_BAD_CB;
	    break;
	}
	if (   (qeuq_cb->qeuq_culd != 1 || qeuq_cb->qeuq_uld_tup == NULL)
            || (qeuq_cb->qeuq_db_id == NULL)
            || (qeuq_cb->qeuq_d_id == 0))
	{
	    status = E_DB_ERROR;
	    error = E_QE0018_BAD_PARAM_IN_CB;
	    break;
	}
	/*
	** Check to see if transaction is in progress, if so set a local
	** transaction, otherwise we'll use the user's transaction.
	*/
	if (qef_cb->qef_stat == QEF_NOTRAN)
	{
	    tranqeu.qeu_type = QEUCB_CB;
	    tranqeu.qeu_length = sizeof(QEUCB_CB);
	    tranqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
	    tranqeu.qeu_d_id = qeuq_cb->qeuq_d_id;
	    tranqeu.qeu_flag = 0;
	    status = qeu_btran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {
		error = tranqeu.error.err_code;
		break;
	    }
	    transtarted = TRUE;
	}
	/* Escalate the transaction to MST */
	if (qef_cb->qef_auto == QEF_OFF)
	    qef_cb->qef_stat = QEF_MSTRAN;

	evtuple  = (DB_IIEVENT *)qeuq_cb->qeuq_uld_tup->dt_data;

	/* Open iievent tables */
	evqeu.qeu_type = QEUCB_CB;
        evqeu.qeu_length = sizeof(QEUCB_CB);
        evqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
        evqeu.qeu_lk_mode = DMT_IX;
        evqeu.qeu_flag = DMT_U_DIRECT;
        evqeu.qeu_access_mode = DMT_A_WRITE;
	evqeu.qeu_mask = 0;

        evqeu.qeu_tab_id.db_tab_base  = DM_B_EVENT_TAB_ID;   /* Open iievent */
        evqeu.qeu_tab_id.db_tab_index = DM_I_EVENT_TAB_ID; 
	status = qeu_open(qef_cb, &evqeu);
	if (status != E_DB_OK)
	{
	    error = evqeu.error.err_code;
	    break;
	}
	event_opened = TRUE;

	evqeu.qeu_count = 1;	   	    /* Initialize event-specific qeu */
        evqeu.qeu_tup_length = sizeof(DB_IIEVENT);
	evqeu.qeu_output = &evqef_data;
	evqef_data.dt_next = NULL;
        evqef_data.dt_size = sizeof(DB_IIEVENT);
        evqef_data.dt_data = (PTR)&evtuple_del;

	/*
	** Position iievent table based on name & owner and drop specific
	** event.  If we can't find it issue an error.
	*/
	evqeu.qeu_getnext = QEU_REPO;

	/* Get event that matches (keyed on) event name and owner */
	evqeu.qeu_klen = 2;
	evqeu.qeu_key = evkey_ptr_array;
	evkey_ptr_array[0] = &evkey_array[0];
	evkey_ptr_array[0]->attr_number = DM_1_EVENT_KEY;
	evkey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	evkey_ptr_array[0]->attr_value = (char *)&evtuple->dbe_name;
	evkey_ptr_array[1] = &evkey_array[1];
	evkey_ptr_array[1]->attr_number = DM_2_EVENT_KEY;
	evkey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	evkey_ptr_array[1]->attr_value = (char *)&evtuple->dbe_owner;
	evqeu.qeu_qual = NULL;
	evqeu.qeu_qarg = NULL;
	status = qeu_get(qef_cb, &evqeu);
	if (status != E_DB_OK)
	{
	    if (evqeu.error.err_code == E_QE0015_NO_MORE_ROWS)
	    {
		(VOID)qef_error(E_QE020B_EVENT_ABSENT, 0L,
				E_DB_ERROR, &error, &qeuq_cb->error, 1,
				qec_trimwhite(sizeof(evtuple->dbe_name),
					      (char *)&evtuple->dbe_name),
				(PTR)&evtuple->dbe_name);
		error = E_QE0025_USER_ERROR;
	    }
	    else	/* Other error */
	    {
		error = evqeu.error.err_code;
	    }
	    break;
	} /* If no event found */
	
	break;
    } /* End dummy for loop */

    /* Handle any error messages */
    if (status != E_DB_OK)
    {
	(VOID) qef_error(error, 0L, status, &error, &qeuq_cb->error, 0);
    }
    else
    {
	QEUQ_CB	    dqeuq;
	STRUCT_ASSIGN_MACRO(*qeuq_cb, dqeuq);
	dqeuq.qeuq_flag_mask &= ~QEU_DROP_TEMP_TABLE;
	dqeuq.qeuq_flag_mask |= QEU_FORCE_QP_INVALIDATION;
	dqeuq.qeuq_rtbl = &evtuple_del.dbe_uniqueid;
	STRUCT_ASSIGN_MACRO(evtuple_del.dbe_txtid, dqeuq.qeuq_qid);
	dqeuq.qeuq_uld_tup = &evqef_data;
	/*
	** Check if dbevent used by alarm, if so we can't drop it
	*/
	if(qeu_ev_used_with_alarm(qef_cb, qeuq_cb, &evtuple_del.dbe_uniqueid)
				!=E_DB_OK)
	{
	        (VOID) qef_error(E_US2479_9337_ALARM_USES_EVENT, 
			0L, local_status,
			 &error, &qeuq_cb->error, 2,
			 qec_trimwhite(sizeof(evtuple->dbe_owner),
					(char*)&evtuple->dbe_owner),
			 (PTR)&evtuple->dbe_owner,
			 qec_trimwhite(sizeof(evtuple->dbe_name),
					(char*)&evtuple->dbe_name),
			 (PTR)&evtuple->dbe_name);
		error = E_QE0025_USER_ERROR;
		status=E_DB_ERROR;
	}
	
	if(status==E_DB_OK)
	{
		/*
		** perform cascading destruction - qeu_d_cascade() handles its
		** own error reporting
		*/
		STRUCT_ASSIGN_MACRO(*qeuq_cb, dqeuq);
		dqeuq.qeuq_flag_mask &= ~((i4) QEU_DROP_TEMP_TABLE);
		dqeuq.qeuq_rtbl = &evtuple_del.dbe_uniqueid;
		STRUCT_ASSIGN_MACRO(evtuple_del.dbe_txtid, dqeuq.qeuq_qid);
		dqeuq.qeuq_uld_tup = &evqef_data;

	/* perform cascading destruction of the dbevent */
	status = qeu_d_cascade(qef_cb, &dqeuq, (DB_QMODE) DB_EVENT, 
	    (DMT_TBL_ENTRY *) NULL);

		if (status != E_DB_OK)
		{
		    STRUCT_ASSIGN_MACRO(dqeuq.error, qeuq_cb->error);
		}
	}
    }

    /* Audit DROP EVENT if so far so good */
    if ( status == E_DB_OK && Qef_s_cb->qef_state & QEF_S_C2SECURE )
    {
	DB_ERROR    e_error;
	status = qeu_secaudit(FALSE, qef_cb->qef_ses_id, 
	      evtuple->dbe_name.db_ev_name, &evtuple->dbe_owner, DB_EVENT_MAXNAME,
	      SXF_E_EVENT, I_SX203C_EVENT_DROP, SXF_A_SUCCESS | SXF_A_DROP,
	      &e_error);
    }

    /* Close off all the tables and transaction */
    if (event_opened)
    {
	local_status = qeu_close(qef_cb, &evqeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(evqeu.error.err_code, 0L, local_status,
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    if (transtarted)
    {
	if (status == E_DB_OK)
	    local_status = qeu_etran(qef_cb, &tranqeu);
	else
	    local_status = qeu_atran(qef_cb, &tranqeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(tranqeu.error.err_code, 0L, local_status,
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    return (status);
} /* qeu_devent */
Ejemplo n.º 2
0
/*{
** Name: qeu_dsecalarm 	- Drop single or all alarm definition.
**
** External QEF call:   status = qef_call(QEU_DSECALM, &qeuq_cb);
**
** Description:
**	Drop the alarm tuple, the alarm text from the appropriate tables 
**	(iisecalarm, iiqrytext and update the table "relstat" field. An
**	alarm can be dropped either by name (when the DROP SECURITY_ALARM
**      statement is issued) or by object id (when its associated object 
**      is dropped).
**
**	When originating from the DROP SECURITY_ALARM  statement the single 
**	alarm tuple is deleted based on its name - provided in the
**	qeuq_uld_tup parameter.  In this case the single alarm is fetched
**	(to collect the text, table id) and deleted.  If it wasn't
**	found then an error is returned.  
**
**	When originating from a DROP TABLE statement (this is similar to
**	the DROP INTEGRITY ON table ALL), all tuples that satisfy the
**	table-id are fetched (to collect their text ids) and dropped.
**	If none are found no error is returned.  
**
**	For each alarm that is dropped the text tuples are
**	also dropped based on the ids collected from the fetched alarm.
**
**	The way this routine works is the following:
**
**	    set up QEU CB's for iisecalarm, iiqrytext and open tables;
**	    if (DROP SECURITY_ALARM) then
**		set up iisecalarm "qualified" name and owner;
**	    else
**		set up iisecalarm "keyed" on DROP object id;
**	    endif;
**	    for (all alarm tuples found) loop
**		get alarm tuple;
**		if (not found) then
**		    if (DROP SECURITY_ALARM) then
**			error - alarm does not exist;
**			break;
**		    else
**			clear error;
**			break;
**		    endif;
**		endif;
**		set up iiqrytext keys based on alarm text id;
**		for (all text tuples found) loop
**		    get text tuple;
**		    delete text tuple;
**		endloop;
**		delete current alarm tuple;
**		if (DROP SECURITY_ALARM) then
**		    endloop;
**		endif;
**	    endloop;
**	    close tables;
**
** Inputs:
**      qef_cb                  QEF session control block
**      qeuq_cb
**	    .qeuq_eflag	        Designate error handling for user errors.
**		QEF_INTERNAL	Return error code.
**		QEF_EXTERNAL	Send message to user.
**	    .qeuq_rtbl		Table id of alarm - if DROP TABLE.  If DROP
**				SECURITY_ALARM then this is ignored.
**	    .qeuq_cr		Must be 1 if DROP SECURITY_ALARM, 0 
**				if DROP TABLE.
**	    .qeuq_uld_tup	Alarm tuple to be deleted - if DROP 
**				SECURITY_ALARM, otherwise this is ignored:
**		.dba_alarmname	alarm name *or*
**		.dba_alarmno	Alarm number
**	    .qeuq_db_id		Database id.
**	    .qeuq_d_id		DMF session id.
**	from_drop_alarm		TRUE if called from DROP SECURITY_ALARM
**	
** Outputs:
**      qeuq_cb
**	    .error.err_code	E_QE0002_INTERNAL_ERROR
**				E_QE0017_BAD_CB
**				E_QE0018_BAD_PARAM_IN_CB
**				E_QE0022_ABORTED
**	Returns:
**	    E_DB_{OK, WARN, ERROR, FATAL}
**	Exceptions:
**	    none
**
** History:
**	26-nov-93 (robf)
**	    Written for Secure 2.0
**	30-dec-93 (robf)
**          Don't  write audit records if called implicitly during drop
**	    of a table.
**	16-feb-94 (robf)
**          Check DROP ALL flag from  qeuq_cb.qeuq_permit_mask & QEU_DROP_ALL,
**	    so we loop appropriately when there are several alarms on
**	    the object to be dropped.
*/
DB_STATUS
qeu_dsecalarm(
QEF_CB          *qef_cb,
QEUQ_CB		*qeuq_cb,
bool		from_drop_alarm)
{
    QEU_CB	    	tranqeu;	/* For transaction request */
    bool	    	transtarted = FALSE;	    
    QEU_CB	    	aqeu;		/* For iisecalarm table */
    QEF_DATA	    	aqef_data;
    DB_SECALARM	    	*atuple_name;	/* Input tuple with name or id */
    DB_SECALARM	    	atuple;		/* Tuple currently being deleted */
    bool	    	alarm_opened = FALSE;
    DMR_ATTR_ENTRY  	akey_array[3];
    DMR_ATTR_ENTRY  	*akey_ptr_array[3];
    QEU_CB	    	qqeu;		/* For iiqrytext table */
    QEU_QUAL_PARAMS	qparams;
    DB_IIQRYTEXT	qtuple;
    QEF_DATA	    	qqef_data;
    bool	    	qtext_opened = FALSE;
    DMR_ATTR_ENTRY  	qkey_array[2];
    DMR_ATTR_ENTRY  	*qkey_ptr_array[2];
    bool		drop_specific_alarm;	/* TRUE if dropping a specific
						** alarm */
    char		obj_type;
    char		*alarm_name;
    DB_STATUS	    	status, local_status;
    i4	    	error;
    DB_ERROR 		e_error;
    SXF_ACCESS		access;
    SXF_EVENT		evtype;
    DB_OWN_NAME		objowner;

    for (;;)	/* Dummy for loop for error breaks */
    {
	MEfill(sizeof(objowner),' ',(PTR)&objowner);

	/* Validate CB and parameters */
	if (qeuq_cb->qeuq_type != QEUQCB_CB ||
            qeuq_cb->qeuq_length != sizeof(QEUQ_CB))	
	{
	    status = E_DB_ERROR;
	    error = E_QE0017_BAD_CB;
	    break;
	}
	if (   (qeuq_cb->qeuq_rtbl == NULL && qeuq_cb->qeuq_cr == 0)
            || (qeuq_cb->qeuq_db_id == NULL)
            || (qeuq_cb->qeuq_d_id == 0))
	{
	    status = E_DB_ERROR;
	    error = E_QE0018_BAD_PARAM_IN_CB;
	    break;
	}

	drop_specific_alarm = from_drop_alarm;

	/*
	** If passed DROP ALL then not dropping  specific alarm
	*/
	if(qeuq_cb->qeuq_permit_mask & QEU_DROP_ALL)
		drop_specific_alarm=FALSE;


	/* 
	** Check to see if transaction is in progress, if so set a local
	** transaction, otherwise we'll use the user's transaction.
	*/
	if (qef_cb->qef_stat == QEF_NOTRAN)
	{
	    tranqeu.qeu_type = QEUCB_CB;
	    tranqeu.qeu_length = sizeof(QEUCB_CB);
	    tranqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
	    tranqeu.qeu_d_id = qeuq_cb->qeuq_d_id;
	    tranqeu.qeu_flag = 0;
	    tranqeu.qeu_mask = 0;
	    status = qeu_btran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {	
		error = tranqeu.error.err_code;
		break;	
	    }	    
	    transtarted = TRUE;
	}
	/* Escalate the transaction to MST */
	if (qef_cb->qef_auto == QEF_OFF)
	    qef_cb->qef_stat = QEF_MSTRAN;


	/* Open iisecalarm, iiqrytext tables */
	aqeu.qeu_type = QEUCB_CB;
        aqeu.qeu_length = sizeof(QEUCB_CB);
        aqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
        aqeu.qeu_lk_mode = DMT_IX;
        aqeu.qeu_flag = DMT_U_DIRECT;
        aqeu.qeu_access_mode = DMT_A_WRITE;
	aqeu.qeu_mask = 0;
	STRUCT_ASSIGN_MACRO(aqeu, qqeu);	/* Quick initialization */

	/* Open iisecalarm */
        aqeu.qeu_tab_id.db_tab_base = DM_B_IISECALARM_TAB_ID;    
        aqeu.qeu_tab_id.db_tab_index = DM_I_IISECALARM_TAB_ID; 	
	status = qeu_open(qef_cb, &aqeu);
	if (status != E_DB_OK)
	{
	    error = aqeu.error.err_code;
	    break;
	}
	alarm_opened = TRUE;

        qqeu.qeu_tab_id.db_tab_base = DM_B_QRYTEXT_TAB_ID; /* Open iiqrytext */
        qqeu.qeu_tab_id.db_tab_index = DM_I_QRYTEXT_TAB_ID; 	
	status = qeu_open(qef_cb, &qqeu);
	if (status != E_DB_OK)
	{
	    error = qqeu.error.err_code;
	    break;
	}
	qtext_opened = TRUE;

	aqeu.qeu_count = 1;	   	    /* Initialize alarm-specific qeu */
        aqeu.qeu_tup_length = sizeof(DB_SECALARM);
	aqeu.qeu_output = &aqef_data;
	aqef_data.dt_next = NULL;
        aqef_data.dt_size = sizeof(DB_SECALARM);
        aqef_data.dt_data = (PTR)&atuple;

	qqeu.qeu_count = 1;	   	    /* Initialize qtext-specific qeu */
        qqeu.qeu_tup_length = sizeof(DB_IIQRYTEXT);
	qqeu.qeu_output = &qqef_data;
	qqef_data.dt_next = NULL;
        qqef_data.dt_size = sizeof(DB_IIQRYTEXT);
        qqef_data.dt_data = (PTR)&qtuple;

	/*
	** If DROP SECURITY_ALARM then position iisecalarm table based on 
	** alarm name or numbr
	** and drop the specific alarm (if we can't find it issue an error).
	** Positioning is done via qeu_qalarm_by_name/id.  
	** If DROP TABLE then fetch and drop ALL alarms applied to the table.
	*/
	aqeu.qeu_getnext = QEU_REPO;
	if (from_drop_alarm)		
	{
	    /*
	    ** Might be scanning for database/installation alarms
	    ** or special DROP ALL processing.
	    */
            atuple_name   = (DB_SECALARM *)qeuq_cb->qeuq_uld_tup->dt_data;
	    alarm_name=(char*)&atuple_name->dba_alarmname;

	    /*
	    ** alarmno -1 indicates all alarms when qualifying
	    */
	    if(qeuq_cb->qeuq_permit_mask & QEU_DROP_ALL)
		atuple_name->dba_alarmno= -1;
	    /* Get alarm that matches alarm name (qualified) */
	    qparams.qeu_qparms[0] = (PTR) atuple_name;
	    aqeu.qeu_klen = 0;				/* Not keyed */
	    aqeu.qeu_qual = qeu_qalarm_by_name;
	    aqeu.qeu_qarg = &qparams;
	}
	else				/* DROP TABLE */
	{
	    /* Get alarm that applies to specific table id (keyed) */
	    obj_type=DBOB_TABLE;
	    alarm_name="unknown";

	    aqeu.qeu_klen = 3;
	    aqeu.qeu_key = akey_ptr_array;
	    akey_ptr_array[0] = &akey_array[0];
	    akey_ptr_array[1] = &akey_array[1];
	    akey_ptr_array[2] = &akey_array[2];

	    akey_ptr_array[0]->attr_number = DM_1_IISECALARM_KEY;
	    akey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	    akey_ptr_array[0]->attr_value = (char*)&obj_type;

	    akey_ptr_array[1]->attr_number = DM_2_IISECALARM_KEY;
	    akey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	    akey_ptr_array[1]->attr_value =
				    (char *)&qeuq_cb->qeuq_rtbl->db_tab_base;
	    akey_ptr_array[2]->attr_number = DM_3_IISECALARM_KEY;
	    akey_ptr_array[2]->attr_operator = DMR_OP_EQ;
	    akey_ptr_array[2]->attr_value =
				    (char *)&qeuq_cb->qeuq_rtbl->db_tab_index;
	    aqeu.qeu_qual = NULL;
	    aqeu.qeu_qarg = NULL;
	}
	for (;;)		/* For all alarm tuples found */
	{
	    status = qeu_get(qef_cb, &aqeu);
	    if (status != E_DB_OK)
	    {
		if (aqeu.error.err_code == E_QE0015_NO_MORE_ROWS)
		{
		    if (drop_specific_alarm)
		    {
			(VOID)qef_error(E_US2473_9331_ALARM_ABSENT, 0L,
				    E_DB_ERROR, &error, &qeuq_cb->error, 1,
				    qec_trimwhite(sizeof(atuple_name->dba_alarmname),
						alarm_name),
				    (PTR)alarm_name);
			error = E_QE0000_OK;
			status=E_DB_OK;
		    }
		    else	/* No [more] alarms for table */
		    {
			error = E_QE0000_OK;
			status = E_DB_OK;
		    }
		}
		else	/* Other error */
		{
		    error = aqeu.error.err_code;
		}
		break;
	    } /* If no alarms found */
	    aqeu.qeu_getnext = QEU_NOREPO;
            aqeu.qeu_klen = 0;
	    
	    status = E_DB_OK;

            /* Postion iiqrytxt table for query id associated with this alarm */
	    qkey_ptr_array[0] = &qkey_array[0];
	    qkey_ptr_array[1] = &qkey_array[1];
	    qqeu.qeu_getnext = QEU_REPO;
	    qqeu.qeu_klen = 2;       
	    qqeu.qeu_key = qkey_ptr_array;
	    qkey_ptr_array[0]->attr_number = DM_1_QRYTEXT_KEY;
	    qkey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	    qkey_ptr_array[0]->attr_value =
				(char *)&atuple.dba_txtid.db_qry_high_time;
	    qkey_ptr_array[1]->attr_number = DM_2_QRYTEXT_KEY;
	    qkey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	    qkey_ptr_array[1]->attr_value =
				(char *)&atuple.dba_txtid.db_qry_low_time;
	    qqeu.qeu_qual = NULL;
	    qqeu.qeu_qarg = NULL;
	    for (;;)		/* For all query text tuples */
	    {
		status = qeu_get(qef_cb, &qqeu);
		if (status != E_DB_OK)
		{
		    error = qqeu.error.err_code;
		    break;
		}
		qqeu.qeu_klen = 0;
		qqeu.qeu_getnext = QEU_NOREPO;
		status = qeu_delete(qef_cb, &qqeu);
		if (status != E_DB_OK)
		{
		    error = qqeu.error.err_code;
		    break;
		}
	    } /* For all query text tuples */
	    if (error != E_QE0015_NO_MORE_ROWS)
		break;

	    if(atuple.dba_objtype==DBOB_TABLE)
	    {
    		DMT_CHAR_ENTRY  	char_spec;	
    		DMT_CB	    	dmt_cb;
	    	/* 
            	** Alter the table relstat to flag alarms. This 
		** validates that the table exists and ensures that we 
		** get an exclusive lock on it.
           	*/
	    	char_spec.char_id = DMT_C_ALARM;    
	    	char_spec.char_value = DMT_C_ON;
		MEfill(sizeof(DMT_CB), 0, (PTR) &dmt_cb);
	    	dmt_cb.dmt_flags_mask = 0;
	    	dmt_cb.dmt_db_id = qeuq_cb->qeuq_db_id;
	    	dmt_cb.dmt_char_array.data_in_size = sizeof(DMT_CHAR_ENTRY);
	    	dmt_cb.dmt_char_array.data_address = (PTR)&char_spec;
	    	dmt_cb.length = sizeof(DMT_CB);
	    	dmt_cb.type = DMT_TABLE_CB;
	    	dmt_cb.dmt_id.db_tab_base  = atuple.dba_objid.db_tab_base;
	    	dmt_cb.dmt_id.db_tab_index = atuple.dba_objid.db_tab_index;
	    	dmt_cb.dmt_tran_id = qef_cb->qef_dmt_id;
	    	status = dmf_call(DMT_ALTER, &dmt_cb);
	    	if (status != E_DB_OK)
    	    	{
		    error = dmt_cb.error.err_code;
		    if (error == E_DM0054_NONEXISTENT_TABLE)
		    {
			error = E_QE0025_USER_ERROR;
			status = E_DB_OK;	/* Still remove the alarm */
		    }
		    else
		    {
			/* 
			** Some other error
			*/
	        	break;
		    }
	    	}
	     }
	     else if(!(atuple.dba_flags&DBA_ALL_DBS))
	     {
		/*
		** Check access to the  database, also get the security label
		** for later use
		*/
	    	status=qeu_db_exists(qef_cb, qeuq_cb,
		    (DB_DB_NAME *)&atuple.dba_objname, SXF_A_CONTROL, &objowner);
	    	if(status==E_DB_ERROR)
	    	{
			/* Error, no access to database */
			break;
	    	}
	    	else  if  (status==E_DB_WARN)
	    	{
			/* Database not found */
			status=E_DB_ERROR;
			/* E_US2474_9332_ALARM_NO_DB */
	        	(VOID)qef_error(9332, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(atuple.dba_objname),
					  (char *)&atuple.dba_objname),
			    (PTR)&atuple.dba_objname);
			break;
		}
	    }
	    /* Now delete the current alarm tuple */
	    status = qeu_delete(qef_cb, &aqeu);
	    if (status != E_DB_OK)
	    {
		error = aqeu.error.err_code;
		break;
	    }
		
	    /*
	    ** If  doing a specific DROP SECURITY_ALARM we're done with this 
	    ** loop. 
	    ** Otherwise continue with next alarm applied to table.
	    */
	    if (drop_specific_alarm)
		break;
	} /* For all alarm found */

	if (status != E_DB_OK)
	    break;

	break;
    } /* End dummy for loop */

    /* Handle any error messages */
    if (status != E_DB_OK)
	(VOID) qef_error(error, 0L, status, &error, &qeuq_cb->error, 0);
    
    /* Close off all the tables and transaction */
    if (alarm_opened)
    {
	local_status = qeu_close(qef_cb, &aqeu);    
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(aqeu.error.err_code, 0L, local_status, 
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    if (qtext_opened)
    {
	local_status = qeu_close(qef_cb, &qqeu);    
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(qqeu.error.err_code, 0L, local_status, 
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    if (transtarted)
    {
	if (status == E_DB_OK)
	    local_status = qeu_etran(qef_cb, &tranqeu);
	else
	    local_status = qeu_atran(qef_cb, &tranqeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(tranqeu.error.err_code, 0L, local_status, 
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    /*
    ** Dropping an alarm is a control operation on the base object
    ** (database/table).
    */
    if( from_drop_alarm==TRUE && Qef_s_cb->qef_state & QEF_S_C2SECURE )
    {
        if(atuple.dba_objtype==DBOB_DATABASE)
        {
	    evtype=SXF_E_DATABASE;
	    /*
	    ** Database label/owner should be set in db_exists request above
	    */
        }
        else
        {
	    evtype=SXF_E_TABLE;
        }
        if(status==E_DB_OK)
	    access=(SXF_A_CONTROL|SXF_A_SUCCESS);
        else
	    access=(SXF_A_CONTROL|SXF_A_FAIL);
        if(qeu_secaudit(FALSE, qef_cb->qef_ses_id,
		(char *)&atuple.dba_objname,
		&objowner,
		sizeof(atuple.dba_objname), 
		evtype,
		I_SX202E_ALARM_DROP,
		access,
		&e_error)!=E_DB_OK)
        {
	    error = e_error.err_code;
	    status=E_DB_ERROR;
        }
    }
    if(status!=E_DB_OK)
    {
    	(VOID) qef_error(E_QE028C_DROP_ALARM_ERR, 0L, local_status, 
		     &error, &qeuq_cb->error, 0);
	qeuq_cb->error.err_code= E_QE0025_USER_ERROR;
    }
    return (status);
} /* qeu_dsecalarm */
Ejemplo n.º 3
0
/*{
** Name: qeu_cevent 	- Store event information for one event.
**
** External QEF call:   status = qef_call(QEU_CEVENT, &qeuq_cb);
**
** Description:
**	Add the event tuple and the event query text to the appropriate
**	tables (iievent and iiqrytext).
**
**	Most of the event tuple was filled by the parser from the CREATE EVENT
**	statement, except that since this is the first access to iievent,
**	the uniqueness of the event name (within the current user scope) is
**	validated here.  First, all events that have the same name and
**	owner are fetched (the iievent table is hashed on name and owner
**	so this is a singleton keyed retrieval).  If there are any then
**	the event is a duplicate and an error is returned.  If this is
**	unique then the event is entered into iievent.
**
**	To allow permissions to apply to events, an event tuple includes
**	a "dummy table id" (much like database procedures).  This id is
**	retrieved from DMU_GET_TABID.
**
**	An internal qrytext id (time-stamp) is created and all the qrytext
**	tuples associated with the event are entered into iiqrytext.
**	Note that the size of CREATE EVENT query text is never likely to
**	be more than one iiqrytext tuple, but the code allows more than
**	one tuple in case a WITH clause is added in the future (extending
**	the length of the statement).
**
**	The current "create date" is retrieved from ADF (using date("now")).
**
** Inputs:
**      qef_cb                  QEF session control block
**      qeuq_cb
**	    .qeuq_eflag	        Designate error handling for user errors.
**		QEF_INTERNAL	Return error code.
**		QEF_EXTERNAL	Send message to user.
**	    .qeuq_cq		Number of query text tuples.
**	    .qeuq_qry_tup	Query text tuples.
**	    .qeuq_culd		Number of event tuples.  Must be 1.
**	    .qeuq_uld_tup	Event tuple:
**		.dbe_name	Event name.
**		.dbe_owner	Event owner.
**		.dbe_type	Event type.
**				The remaining fields are filled here.
**	    .qeuq_db_id		Database id.
**	    .qeuq_d_id		DMF session id.
**
** Outputs:
**      qeuq_cb
**	    .error.err_code	E_QE0002_INTERNAL_ERROR
**				E_QE0017_BAD_CB
**				E_QE0018_BAD_PARAM_IN_CB
**				E_QE0022_ABORTED
**				E_QE020A_EVENT_EXISTS (ret E_QE0025_USER_ERROR)
**	Returns:
**	    E_DB_{OK, WARN, ERROR, FATAL}
**	Exceptions:
**	    none
**
** History:
**	28-aug-89 (neil)
**	    Written for Terminator II/alerters.
**	09-feb-90 (neil)
**	   Added auditing functionality.
**	03-mar-90 (neil)
**	   Clear adf_constants before calling ADF.  The problem was that the
**	   session CB may have been pointing at "old" data which had been
**	   reused for other things.
**	19-may-93 (anitap)
**	    Added support to create implicit schema for dbevent.
**	07-jul-93 (anitap)
**	    Added two arguments qef_rcb & qeuq_cb to qea_schema() instead of
**	    PTR.
**	    Changed assignment of flag to IMPLICIT_SCHEMA.
**	21-sep-93 (stephenb)
**	    Replace generic I_SX2032_EVENT_ACCESS with I_SX2032_EVENT_CREATE. 
**	27-oct-93 (andre)
**	    As a part of fix for bug 51852 (which was reported in 6.4 but can
**	    and will manifest itself in 6.5 as soon as someone places some 
**	    stress on the DBMS), we want to use the dbevent id (really 
**	    guaranteed to be unique) instead of timestamps (allegedly unique, 
**	    but in fact may be non-unique if several objects get created in 
**	    rapid succession on a reasonably fast box) to identify IIQRYTEXT 
**	    tuples associated with a given dbevent.  This id (pumped through 
**	    randomizing function) will be used to key into IIQRYTEXT 
*/
DB_STATUS
qeu_cevent(
QEF_CB          *qef_cb,
QEUQ_CB		    *qeuq_cb)
{
    DB_IIEVENT    	*evtuple;	/* New event tuple */
    DB_IIEVENT    	evtuple_temp;	/* Tuple and 			   */
    DMR_ATTR_ENTRY  	evkey_array[2];	/*       keys for uniqueness check */
    DMR_ATTR_ENTRY  	*evkey_ptr_array[2];
    DMU_CB		dmu_cb;		/* For unique table-id request */
    DB_DATA_VALUE	evcreate_dv;	/* For create date */
    DB_IIQRYTEXT	*qtuple;	/* Event text */
    DB_TAB_ID		randomized_id;
    i4		    	i;		/* Querytext counter  */
    QEF_DATA	    	*next;		/*   and data pointer */
    DB_STATUS	    	status, local_status;
    DB_ERROR		e_error;
    i4	    	error;
    bool	    	tbl_opened = FALSE;
    QEU_CB	    	tranqeu;	/* May need a transaction */
    bool	    	transtarted = FALSE;
    QEU_CB	    	qeu;
    QEF_DATA	    	qef_data;
    i4			flag = IMPLICIT_SCHEMA;
    QEF_RCB	        *qef_rcb = (QEF_RCB *)NULL;

    for (;;)	/* Dummy for loop for error breaks */
    {
	/* Validate CB and parameters */
	if (qeuq_cb->qeuq_type != QEUQCB_CB ||
            qeuq_cb->qeuq_length != sizeof(QEUQ_CB))
	{
	    status = E_DB_ERROR;
	    error = E_QE0017_BAD_CB;
	    break;
	}
	if (   (qeuq_cb->qeuq_cq == 0   || qeuq_cb->qeuq_qry_tup == NULL)
            || (qeuq_cb->qeuq_culd != 1 || qeuq_cb->qeuq_uld_tup == NULL)
            || (qeuq_cb->qeuq_db_id == NULL)
            || (qeuq_cb->qeuq_d_id == 0))
	{
	    status = E_DB_ERROR;
	    error = E_QE0018_BAD_PARAM_IN_CB;
	    break;
	}

	/*
	** Check to see if transaction is in progress, if so set a local
	** transaction, otherwise we'll use the user's transaction.
	*/
	if (qef_cb->qef_stat == QEF_NOTRAN)
	{
	    tranqeu.qeu_type = QEUCB_CB;
	    tranqeu.qeu_length = sizeof(QEUCB_CB);
	    tranqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
	    tranqeu.qeu_d_id = qeuq_cb->qeuq_d_id;
	    tranqeu.qeu_flag = 0;
	    status = qeu_btran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {
		error = tranqeu.error.err_code;
		break;
	    }
	    transtarted = TRUE;
	}
	/* Escalate the transaction to MST */
	if (qef_cb->qef_auto == QEF_OFF)
	    qef_cb->qef_stat = QEF_MSTRAN;

	evtuple = (DB_IIEVENT *)qeuq_cb->qeuq_uld_tup->dt_data;

	/* Validate that the event name/owner is unique */
	qeu.qeu_type = QEUCB_CB;
        qeu.qeu_length = sizeof(QEUCB_CB);
        qeu.qeu_tab_id.db_tab_base  = DM_B_EVENT_TAB_ID;
        qeu.qeu_tab_id.db_tab_index  = DM_I_EVENT_TAB_ID;
        qeu.qeu_db_id = qeuq_cb->qeuq_db_id;
        qeu.qeu_lk_mode = DMT_IX;
        qeu.qeu_flag = DMT_U_DIRECT;
        qeu.qeu_access_mode = DMT_A_WRITE;
	qeu.qeu_mask = 0;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;

	/* Retrieve the same named/owned event - if not there then ok */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_IIEVENT);
	qeu.qeu_output = &qef_data;
	qef_data.dt_next = NULL;
        qef_data.dt_size = sizeof(DB_IIEVENT);
        qef_data.dt_data = (PTR)&evtuple_temp;
	qeu.qeu_getnext = QEU_REPO;
	qeu.qeu_klen = 2;			/* Keyed on name and owner */
	qeu.qeu_key = evkey_ptr_array;
	evkey_ptr_array[0] = &evkey_array[0];
	evkey_ptr_array[0]->attr_number = DM_1_EVENT_KEY;
	evkey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	evkey_ptr_array[0]->attr_value = (char *)&evtuple->dbe_name;
	evkey_ptr_array[1] = &evkey_array[1];
	evkey_ptr_array[1]->attr_number = DM_2_EVENT_KEY;
	evkey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	evkey_ptr_array[1]->attr_value = (char *)&evtuple->dbe_owner;
	qeu.qeu_qual = NULL;
	qeu.qeu_qarg = NULL;
	status = qeu_get(qef_cb, &qeu);
	if (status == E_DB_OK)		/* Found the same event! */
	{
	    (VOID)qef_error(E_QE020A_EVENT_EXISTS, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(evtuple->dbe_name),
					  (char *)&evtuple->dbe_name),
			    (PTR)&evtuple->dbe_name);
	    error = E_QE0025_USER_ERROR;
	    break;
	}
	if (qeu.error.err_code != E_QE0015_NO_MORE_ROWS)
	{
	    error = qeu.error.err_code;	 /* Some other error */
	    break;
	}
	/* The event is unique - append it */

	status = E_DB_OK;

	/*
	** Get unique event id (a table id) from DMF.  This id enables
	** permissions to be associated with the event.
	*/
	dmu_cb.type = DMU_UTILITY_CB;
	dmu_cb.length = sizeof(DMU_CB);
	dmu_cb.dmu_flags_mask = 0;
	dmu_cb.dmu_tran_id = qef_cb->qef_dmt_id;
	dmu_cb.dmu_db_id = qeuq_cb->qeuq_db_id;
	status = dmf_call(DMU_GET_TABID, &dmu_cb);
	if (status != E_DB_OK)
	{
	    error = dmu_cb.error.err_code;
	    break;
	}
	evtuple->dbe_uniqueid.db_tab_base  = dmu_cb.dmu_tbl_id.db_tab_base;
	evtuple->dbe_uniqueid.db_tab_index = dmu_cb.dmu_tbl_id.db_tab_index;

	/*
	** use dbevent id to generate randomized id which will be used to 
	** identify IIQRYTEXT tuples associated with this dbevent
	*/
	randomized_id.db_tab_base = 
	    ulb_rev_bits(evtuple->dbe_uniqueid.db_tab_base);
	randomized_id.db_tab_index = 
	    ulb_rev_bits(evtuple->dbe_uniqueid.db_tab_index);

	/* set text id to "randomized" id */
	evtuple->dbe_txtid.db_qry_high_time = randomized_id.db_tab_base;
	evtuple->dbe_txtid.db_qry_low_time  = randomized_id.db_tab_index;

	/* Get the create date of the event */
	evcreate_dv.db_datatype = DB_DTE_TYPE;
	evcreate_dv.db_prec = 0;
	evcreate_dv.db_length = sizeof(DB_DATE);
	evcreate_dv.db_data = (PTR)&evtuple->dbe_create;
	evcreate_dv.db_collID = -1;
	qef_cb->qef_adf_cb->adf_constants = NULL;
	status = adu_datenow(qef_cb->qef_adf_cb, &evcreate_dv);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}

	/* Insert single event tuple */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_IIEVENT);
	qeu.qeu_input = qeuq_cb->qeuq_uld_tup; /* Which points at evtuple */
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;

	/*
	** Update all query text tuples with query id - validate list.  Even
	** though we will probably have just one text tuple this is set up
	** for syntactic extensions to the CREATE EVENT statement.
	*/
	next = qeuq_cb->qeuq_qry_tup;
	for (i = 0; i < qeuq_cb->qeuq_cq; i++)
	{
	    qtuple = (DB_IIQRYTEXT *)next->dt_data;
	    next = next->dt_next;
	    qtuple->dbq_txtid.db_qry_high_time = randomized_id.db_tab_base;
	    qtuple->dbq_txtid.db_qry_low_time  = randomized_id.db_tab_index;
	    if (i < (qeuq_cb->qeuq_cq -1) && next == NULL)
	    {
		error = E_QE0018_BAD_PARAM_IN_CB;
		status = E_DB_ERROR;
		break;
	    }
	} /* for all query text tuples */
	if (status != E_DB_OK)
	    break;

	/* Insert all query text tuples */
	qeu.qeu_tab_id.db_tab_base = DM_B_QRYTEXT_TAB_ID;
	qeu.qeu_tab_id.db_tab_index = 0L;
	qeu.qeu_mask = 0;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	qeu.qeu_count = qeuq_cb->qeuq_cq;
        qeu.qeu_tup_length = sizeof(DB_IIQRYTEXT);
	qeu.qeu_input = qeuq_cb->qeuq_qry_tup;
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;

        status = qea_schema(qef_rcb, qeuq_cb, qef_cb, 
		(DB_SCHEMA_NAME *)&evtuple->dbe_owner, flag);
        if (status != E_DB_OK)
        {
           error = qeuq_cb->error.err_code;
           break;
        }

	if (transtarted)		   /* If we started a transaction */
	{
	    status = qeu_etran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {
		error = tranqeu.error.err_code;
		break;
	    }
	}


	/* Audit CREATE EVENT */
	if ( Qef_s_cb->qef_state & QEF_S_C2SECURE )
	{
	    status = qeu_secaudit(FALSE, qef_cb->qef_ses_id, 
		  evtuple->dbe_name.db_ev_name, &evtuple->dbe_owner, DB_EVENT_MAXNAME,
		  SXF_E_EVENT, I_SX2032_EVENT_CREATE, 
		  SXF_A_SUCCESS | SXF_A_CREATE, &e_error);

	    if (status != E_DB_OK)
		break;
	}

	qeuq_cb->error.err_code = E_QE0000_OK;
	return (E_DB_OK);
    } /* End dummy for */

    /* call qef_error to handle error messages */
    (VOID) qef_error(error, 0L, status, &error, &qeuq_cb->error, 0);

    /* Close off all the tables. */
    local_status = E_DB_OK;
    if (tbl_opened)		    /* If system table opened, close it */
    {
	local_status = qeu_close(qef_cb, &qeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(qeu.error.err_code, 0L, local_status, &error,
		    	     &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }

    if (transtarted)		   /* If we started a transaction */
    {
        local_status = qeu_atran(qef_cb, &tranqeu);
        if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(tranqeu.error.err_code, 0L, local_status,
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
    return (status);
} /* qeu_cevent */
Ejemplo n.º 4
0
DB_STATUS
qeu_csecalarm(
QEF_CB          *qef_cb,
QEUQ_CB		    *qeuq_cb)
{
    DB_IIQRYTEXT	*qtuple;	/* Alarm text */
    DB_SECALARM    	*atuple;	/* New alarm tuple */
    DB_SECALARM    	atuple_temp;	/* Tuple to check for uniqueness */
    DB_STATUS	    	status, local_status;
    i4	    	error=0;
    bool	    	transtarted = FALSE;	    
    bool	    	tbl_opened = FALSE;
    i4		    	i;		/* Querytext tuple counter */
    QEF_DATA	    	*next;		/*	     and data pointer       */
    QEU_CB	    	tranqeu;
    QEU_CB	    	qeu;
    QEU_QUAL_PARAMS	qparams;
    DB_QRY_ID	    	qryid;		/* Ids for query text */
    QEF_DATA	    	qef_data;
    bool		loop=FALSE;
    QEF_RCB		qef_rcb;
    i4		number;
    DMR_ATTR_ENTRY  	akey_array[3];
    DMR_ATTR_ENTRY  	*akey_ptr_array[3];
    DMT_CHAR_ENTRY  	char_spec;	/* DMT_ALTER specification */
    DMT_CB	    	dmt_cb;
    DB_ERROR 		e_error;
    SXF_ACCESS		access;
    SXF_EVENT		evtype;
    DB_OWN_NAME		objowner;

    do
    {
	MEfill(sizeof(objowner),' ',(PTR)&objowner);

	/* Validate CB and parameters */
	if (qeuq_cb->qeuq_type != QEUQCB_CB ||
            qeuq_cb->qeuq_length != sizeof(QEUQ_CB))	
	{
	    status = E_DB_ERROR;
	    error = E_QE0017_BAD_CB;
	    break;
	}
	if (   qeuq_cb->qeuq_cq == 0 || qeuq_cb->qeuq_qry_tup == NULL
            || ( qeuq_cb->qeuq_uld_tup == NULL)
            || (qeuq_cb->qeuq_db_id == NULL)
            || (qeuq_cb->qeuq_d_id == 0))
	{
	    status = E_DB_ERROR;
	    error = E_QE0018_BAD_PARAM_IN_CB;
	    break;
	}
        qef_rcb.qef_cb = qef_cb;
        qef_rcb.qef_db_id = qeuq_cb->qeuq_db_id;
        qef_cb->qef_dbid = qeuq_cb->qeuq_db_id;
		
	/* 
	** Check to see if transaction is in progress, if so set a local
	** transaction, otherwise we'll use the user's transaction.
	*/
	if (qef_cb->qef_stat == QEF_NOTRAN)
	{
	    tranqeu.qeu_type = QEUCB_CB;
	    tranqeu.qeu_length = sizeof(QEUCB_CB);
	    tranqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
	    tranqeu.qeu_d_id = qeuq_cb->qeuq_d_id;
	    tranqeu.qeu_flag = 0;
	    tranqeu.qeu_mask = 0;
	    status = qeu_btran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {	
		error = tranqeu.error.err_code;
		break;	
	    }	    
	    transtarted = TRUE;
	}
	/* Escalate the transaction to MST */
	if (qef_cb->qef_auto == QEF_OFF)
	    qef_cb->qef_stat = QEF_MSTRAN;

	atuple = (DB_SECALARM *)qeuq_cb->qeuq_uld_tup->dt_data;

        /* For  database alarms, make sure the database exists */
	if(atuple->dba_objtype==DBOB_DATABASE &&
	   !(atuple->dba_flags&DBA_ALL_DBS))
	{
	    status=qeu_db_exists(qef_cb, qeuq_cb, 
		(DB_DB_NAME *)&atuple->dba_objname, SXF_A_CONTROL, &objowner);
	    if(status==E_DB_ERROR)
	    {
		/* Error checking database name */
		break;
	    }
	    else  if  (status==E_DB_WARN)
	    {
		/* Database not found */
		status=E_DB_ERROR;
		/* E_US2474_9332_ALARM_NO_DB */
	        (VOID)qef_error(9332, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(atuple->dba_objname),
					  (char *)&atuple->dba_objname),
			    (PTR)&atuple->dba_objname);
		break;
	    }
	}
	else if(atuple->dba_objtype==DBOB_TABLE)
	{
	    /* 
            ** Alter the table relstat to flag alarms exist. This validates that
            ** the table exists and ensures that we get an exclusive lock on it.
            */
	    char_spec.char_id = DMT_C_ALARM;      /* create alarm code */
	    char_spec.char_value = DMT_C_ON;
	    MEfill(sizeof(DMT_CB), 0, (PTR) &dmt_cb);
	    dmt_cb.dmt_flags_mask = 0;
	    dmt_cb.dmt_db_id = qeuq_cb->qeuq_db_id;
	    dmt_cb.dmt_char_array.data_in_size = sizeof(DMT_CHAR_ENTRY);
	    dmt_cb.dmt_char_array.data_address = (PTR)&char_spec;
	    dmt_cb.length = sizeof(DMT_CB);
	    dmt_cb.type = DMT_TABLE_CB;
	    dmt_cb.dmt_id.db_tab_base  = atuple->dba_objid.db_tab_base;
	    dmt_cb.dmt_id.db_tab_index = atuple->dba_objid.db_tab_index;
	    dmt_cb.dmt_tran_id = qef_cb->qef_dmt_id;
	    status = dmf_call(DMT_ALTER, &dmt_cb);
	    if (status != E_DB_OK)
    	    {
	        error = dmt_cb.error.err_code;
	        break;
	    }
	}
	/* Get a unique query id */
	TMnow((SYSTIME *)&qryid);
	atuple->dba_txtid.db_qry_high_time = qryid.db_qry_high_time;
	atuple->dba_txtid.db_qry_low_time  = qryid.db_qry_low_time;

	/* Get a unique alarm id */
        
        status = qea_reserveID(&atuple->dba_alarmid, 
			qef_cb, &qef_rcb.error);

	if (status != E_DB_OK)
	{   
		error = qef_rcb.error.err_code;  
		break; 
	}
	/*
	** Generate an alarm name if needed, all blanks indicates no
	** name specified. This is required for uniqueness check below.
	*/
	if(!STskipblank( (char*)&atuple->dba_alarmname, 
				sizeof(atuple->dba_alarmname)))
	{
		status=qeu_gen_alarm_name(
			atuple->dba_objtype,
			(char*)&atuple->dba_objname,
			&qef_rcb,
			&atuple->dba_alarmid,
			(char*)&atuple->dba_alarmname,
			&error);
		if(status!=E_DB_OK)
			break;
	}
	/* Validate that the alarm name is unique */
	qeu.qeu_type = QEUCB_CB;
        qeu.qeu_length = sizeof(QEUCB_CB);
        qeu.qeu_tab_id.db_tab_base  = DM_B_IISECALARM_TAB_ID;
        qeu.qeu_tab_id.db_tab_index  = DM_I_IISECALARM_TAB_ID;
        qeu.qeu_db_id = qeuq_cb->qeuq_db_id;
        qeu.qeu_lk_mode = DMT_IX;
        qeu.qeu_flag = DMT_U_DIRECT;
        qeu.qeu_access_mode = DMT_A_WRITE;
	qeu.qeu_mask = 0;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	atuple->dba_alarmno=0;

	/* Retrieve the same named alarm - if not there then ok */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_output = &qef_data;
	qef_data.dt_next = NULL;
        qef_data.dt_size = sizeof(DB_SECALARM);
        qef_data.dt_data = (PTR)&atuple_temp;
	qeu.qeu_getnext = QEU_REPO;
	qeu.qeu_klen = 0;				/* Not keyed */
	qparams.qeu_qparms[0] = (PTR) atuple;	/* What we're looking for */
	qeu.qeu_qual = qeu_qalarm_by_name;
	qeu.qeu_qarg = &qparams;
	status = qeu_get(qef_cb, &qeu);
	if (status == E_DB_OK)		/* Found the same alarm! */
	{
	    (VOID)qef_error(E_US2472_9330_ALARM_EXISTS, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(atuple->dba_alarmname),
					  (char *)&atuple->dba_alarmname),
			    (PTR)&atuple->dba_alarmname);
	    error = E_QE0025_USER_ERROR;
	    break;
	}
	if (qeu.error.err_code != E_QE0015_NO_MORE_ROWS)
	{
	    /* Some other error */
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened=FALSE;
	/*
	** Generate a unique alarm number. This is primarily for
	** backwards compatibility with "anonymous" alarms which had
	** to be dropped by number, not name.
	*/
	
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_input = &qef_data;
	qeu.qeu_output = &qef_data;
	qef_data.dt_next = 0;
        qef_data.dt_size = sizeof(DB_SECALARM);
        qef_data.dt_data = (PTR) &atuple_temp;
	
	qeu.qeu_getnext = QEU_REPO;
	qeu.qeu_klen = 3;       
	qeu.qeu_key = akey_ptr_array;
	akey_ptr_array[0] = &akey_array[0];
	akey_ptr_array[1] = &akey_array[1];
	akey_ptr_array[2] = &akey_array[2];

	akey_ptr_array[0]->attr_number = DM_1_IISECALARM_KEY;
	akey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[0]->attr_value = (char*) &atuple->dba_objtype;

	akey_ptr_array[1]->attr_number = DM_2_IISECALARM_KEY;
	akey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[1]->attr_value = (char*) &atuple->dba_objid.db_tab_base;
        
	akey_ptr_array[2]->attr_number = DM_3_IISECALARM_KEY;
	akey_ptr_array[2]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[2]->attr_value = (char*) &atuple->dba_objid.db_tab_index;
        
	qeu.qeu_qual = 0;
	qeu.qeu_qarg = 0;
     
	/* 
        ** Get all alarm tuples for this object
        ** and determine the next alarm number.
        */
	status = E_DB_OK;
	number = 0;
	while (status == E_DB_OK)
	{
            status = qeu_get(qef_cb, &qeu);
	    if (status != E_DB_OK)
	    {
		error = qeu.error.err_code;
		break;
	    }
	    qeu.qeu_getnext = QEU_NOREPO;
            qeu.qeu_klen = 0;
	    if (atuple_temp.dba_alarmno > number)
                number = atuple_temp.dba_alarmno;
	}
	if (error != E_QE0015_NO_MORE_ROWS)
	    break;
 
	/* 
        ** We have to add 1 to derive the next alarm number.
	*/
	atuple->dba_alarmno=number+1;

	/* Save the alarm tuple */
	status = E_DB_OK;
		
	/* Insert single alarm tuple */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_input = qeuq_cb->qeuq_uld_tup;
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);    
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;

	/* Update all query text tuples with query id - validate list */
	next = qeuq_cb->qeuq_qry_tup;
	for (i = 0; i < qeuq_cb->qeuq_cq; i++)
	{
	    qtuple = (DB_IIQRYTEXT *)next->dt_data;
	    next = next->dt_next;
	    qtuple->dbq_txtid.db_qry_high_time = qryid.db_qry_high_time;
	    qtuple->dbq_txtid.db_qry_low_time  = qryid.db_qry_low_time;
	    if (i < (qeuq_cb->qeuq_cq -1) && next == NULL)
	    {
		error = E_QE0018_BAD_PARAM_IN_CB;
		status = E_DB_ERROR;
		break;
	    }
	} /* for all query text tuples */
	if (status != E_DB_OK)
	    break;

	/* Insert all query text tuples */
	qeu.qeu_tab_id.db_tab_base = DM_B_QRYTEXT_TAB_ID;
	qeu.qeu_tab_id.db_tab_index = 0L;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	qeu.qeu_count = qeuq_cb->qeuq_cq;
        qeu.qeu_tup_length = sizeof(DB_IIQRYTEXT);
	qeu.qeu_input = qeuq_cb->qeuq_qry_tup;
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);    
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;
	
	if (transtarted)		   /* If we started a transaction */
	{
	    status = qeu_etran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {
		error = tranqeu.error.err_code;
		break;
	    }
	}
    }
    while(loop);

    /* call qef_error to handle error messages */
    if(error)
	    (VOID) qef_error(error, 0L, status, &error, &qeuq_cb->error, 0);
    
    /* Close off all the tables. */
    local_status = E_DB_OK;
    if (tbl_opened)		    /* If system table opened, close it */
    {
	local_status = qeu_close(qef_cb, &qeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(qeu.error.err_code, 0L, local_status, &error, 
		    	     &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }

    if (transtarted)		   /* If we started a transaction */
    {
        local_status = qeu_atran(qef_cb, &tranqeu);
        if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(tranqeu.error.err_code, 0L, local_status, 
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
  
    if ( Qef_s_cb->qef_state & QEF_S_C2SECURE )
    {
	if(atuple->dba_objtype==DBOB_DATABASE)
	{
	    evtype=SXF_E_DATABASE;
	}
	else
	{
	    evtype=SXF_E_TABLE;
	}
	/*
	** Creating an alarm is a control operation on the base object
	** (database/table)
	*/
	if(status==E_DB_OK)
	    access=(SXF_A_CONTROL|SXF_A_SUCCESS);
	else
	    access=(SXF_A_CONTROL|SXF_A_FAIL);
	if(qeu_secaudit(FALSE, qef_cb->qef_ses_id,
		    (char *)&atuple->dba_objname,
		    &objowner,
		    sizeof(atuple->dba_objname),
		    evtype,
		    I_SX202D_ALARM_CREATE,
		    access,
		    &e_error)!=E_DB_OK)
	{
		error = e_error.err_code;
		status=E_DB_ERROR;
	}
    }

    /*
    ** Log QEF create error
    */
    if(status!=E_DB_OK)
    {
    	(VOID) qef_error(E_QE028B_CREATE_ALARM_ERR, 0L, local_status, 
		     &error, &qeuq_cb->error, 0);
	qeuq_cb->error.err_code= E_QE0025_USER_ERROR;
    }
    return (status);
} /* qeu_csecalarm */