changes for asTrapWrite

This commit is contained in:
Marty Kraimer
2000-12-11 15:46:14 +00:00
parent 1fca6cb348
commit 703c3a838f
5 changed files with 221 additions and 11 deletions

View File

@@ -3,8 +3,8 @@ include $(TOP)/config/CONFIG_BASE
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
SRCS.c = ../asDbLib.c ../asCa.c asLib.c
LIBOBJS = asDbLib.o asCa.o asLib.o
SRCS.c = ../asDbLib.c ../asCa.c ../asTrapWrite.c asLib.c
LIBOBJS = asDbLib.o asCa.o asTrapWrite.o asLib.o
LIBNAME = asLibrary
include $(TOP)/config/RULES.Vx

View File

@@ -132,7 +132,9 @@ inp_body: tokenNAME
rule_config: tokenRULE rule_head rule_body
| tokenRULE rule_head
rule_head: '(' tokenINTEGER ',' tokenNAME ')'
rule_head: rule_head_manditory rule_head_options
rule_head_manditory: '(' tokenINTEGER ',' tokenNAME
{
asAccessRights rights;
@@ -151,6 +153,21 @@ rule_head: '(' tokenINTEGER ',' tokenNAME ')'
}
;
rule_head_options: ')'
| rule_log_options
rule_log_options: ',' tokenNAME ')'
{
if((strcmp($2,"TRAPWRITE")==0)) {
long status;
status = asAsgAddRuleOptions(yyAsgRule,AS_TRAP_WRITE);
if(status) yyerror("");
} else if((strcmp($2,"NOTRAPWRITE")!=0)) {
yyerror("Illegal access type");
}
free((void *)$2);
}
;
rule_body: '{' rule_list '}'
;
@@ -225,7 +242,7 @@ static int myParse(ASINPUTFUNCPTR inputfunction)
if (!FirstFlag) {
line_num=1;
yyFailed = FALSE;
yyreset(NULL);
yyreset();
yyrestart(NULL);
}
FirstFlag = 0;

View File

@@ -77,6 +77,7 @@ static long asHagAddHost(HAG *phag,char *host);
static ASG *asAsgAdd(char *asgName);
static long asAsgAddInp(ASG *pasg,char *inp,int inpIndex);
static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level);
static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask);
static long asAsgRuleUagAdd(ASGRULE *pasgrule,char *name);
static long asAsgRuleHagAdd(ASGRULE *pasgrule,char *name);
static long asAsgRuleCalc(ASGRULE *pasgrule,char *calc);
@@ -477,6 +478,7 @@ long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt)
/*The dump routines do not lock. Thus they may get inconsistant data.*/
/*HOWEVER if they did lock and a user interrupts one of then then BAD BAD*/
static char *asAccessName[] = {"NONE","READ","WRITE"};
static char *asTrapOption[] = {"NOTRAPWRITE","TRAPWRITE"};
static char *asLevelName[] = {"ASL0","ASL1"};
int epicsShareAPI asDump(
void (*memcallback)(struct asgMember *),
@@ -553,8 +555,9 @@ int epicsShareAPI asDump(
while(pasgrule) {
int print_end_brace;
printf("\tRULE(%d,%s)",
pasgrule->level,asAccessName[pasgrule->access]);
printf("\tRULE(%d,%s,%s)",
pasgrule->level,asAccessName[pasgrule->access],
asTrapOption[pasgrule->trapMask]);
pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList);
pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList);
if(pasguag || pasghag || pasgrule->calc) {
@@ -604,7 +607,9 @@ int epicsShareAPI asDump(
else
printf(" Illegal Level %d",pasgclient->level);
if(pasgclient->access>=0 && pasgclient->access<=2)
printf(" %s",asAccessName[pasgclient->access]);
printf(" %s %s",
asAccessName[pasgclient->access],
asTrapOption[pasgclient->trapMask]);
else
printf(" Illegal Access %d",pasgclient->access);
if(clientcallback) clientcallback(pasgclient);
@@ -710,8 +715,9 @@ int epicsShareAPI asDumpRules(char *asgname)
while(pasgrule) {
int print_end_brace;
printf("\tRULE(%d,%s)",
pasgrule->level,asAccessName[pasgrule->access]);
printf("\tRULE(%d,%s,%s)",
pasgrule->level,asAccessName[pasgrule->access],
asTrapOption[pasgrule->trapMask]);
pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList);
pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList);
if(pasguag || pasghag || pasgrule->calc) {
@@ -783,7 +789,9 @@ int epicsShareAPI asDumpMem(char *asgname,void (*memcallback)(ASMEMBERPVT),int c
else
printf(" Illegal Level %d",pasgclient->level);
if(pasgclient->access>=0 && pasgclient->access<=2)
printf(" %s",asAccessName[pasgclient->access]);
printf(" %s %s",
asAccessName[pasgclient->access],
asTrapOption[pasgclient->trapMask]);
else
printf(" Illegal Access %d",pasgclient->access);
printf("\n");
@@ -909,6 +917,7 @@ static long asComputeAsgPvt(ASG *pasg)
static long asComputePvt(ASCLIENTPVT asClientPvt)
{
asAccessRights access=asNOACCESS;
int trapMask=0;
ASGCLIENT *pasgclient = asClientPvt;
ASGMEMBER *pasgMember;
ASG *pasg;
@@ -961,12 +970,15 @@ check_hag:
}
check_calc:
if(!pasgrule->calc
|| (!(pasg->inpBad & pasgrule->inpUsed) && (pasgrule->result==1)))
|| (!(pasg->inpBad & pasgrule->inpUsed) && (pasgrule->result==1))) {
access = pasgrule->access;
trapMask = pasgrule->trapMask;
}
next_rule:
pasgrule = (ASGRULE *)ellNext((ELLNODE *)pasgrule);
}
pasgclient->access = access;
pasgclient->trapMask = trapMask;
if(pasgclient->pcallback && oldaccess!=access) {
(*pasgclient->pcallback)(pasgclient,asClientCOAR);
}
@@ -1205,6 +1217,7 @@ static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level)
if(!pasg) return(0);
pasgrule = asCalloc(1,sizeof(ASGRULE));
pasgrule->access = access;
pasgrule->trapMask = 0;
pasgrule->level = level;
ellInit(&pasgrule->uagList);
ellInit(&pasgrule->hagList);
@@ -1212,6 +1225,16 @@ static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level)
return(pasgrule);
}
static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask)
{
if(!pasgrule) {
errMessage(S_asLib_badConfig," Access Security internal failure");
return(0);
}
pasgrule->trapMask = trapMask;
return(0);
}
static long asAsgRuleUagAdd(ASGRULE *pasgrule,char *name)
{
ASGUAG *pasguag;

166
src/as/asTrapWrite.c Normal file
View File

@@ -0,0 +1,166 @@
/*asTrapWrite.c */
/* Author: Marty Kraimer Date: 07NOV2000 */
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
**********************************************************************/
/* Matthias Clausen and Vladis Korobov at DESY
* implemented the first logging of Channel Access Puts
* This implementation uses many ideas from their implementation
*/
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "callback.h"
#include "freeList.h"
#include "asLib.h"
#include "asTrapWrite.h"
#include "semLib.h"
#include "ellLib.h"
typedef struct listenerPvt {
ELLNODE node;
struct listener *plistener;
void *userPvt;
}listenerPvt;
typedef struct listener{
ELLNODE node;
asTrapWriteListener func;
}listener;
typedef struct writeMessage {
ELLNODE node;
asTrapWriteMessage message;
ELLLIST listenerPvtList;
}writeMessage;
typedef struct asTrapWritePvt
{
ELLLIST listenerList;
ELLLIST writeMessageList;
void *freeListWriteMessage;
void *freeListListenerPvt;
SEM_ID lock;
}asTrapWritePvt;
static asTrapWritePvt *pasTrapWritePvt = 0;
static void asTrapWriteInit(void)
{
pasTrapWritePvt = calloc(1,sizeof(asTrapWritePvt));
ellInit(&pasTrapWritePvt->listenerList);
ellInit(&pasTrapWritePvt->writeMessageList);
freeListInitPvt(
&pasTrapWritePvt->freeListWriteMessage,sizeof(writeMessage),20);
freeListInitPvt(
&pasTrapWritePvt->freeListListenerPvt,sizeof(listenerPvt),20);
pasTrapWritePvt->lock = semMCreate(
SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY);
}
asTrapWriteId epicsShareAPI asTrapWriteRegisterListener(
asTrapWriteListener func)
{
listener *plistener;
if(pasTrapWritePvt==0) asTrapWriteInit();
plistener = calloc(1,sizeof(listener));
plistener->func = func;
semTake(pasTrapWritePvt->lock,WAIT_FOREVER);
ellAdd(&pasTrapWritePvt->listenerList,&plistener->node);
semGive(pasTrapWritePvt->lock);
return((asTrapWriteId)plistener);
}
void epicsShareAPI asTrapWriteUnregisterListener(asTrapWriteId id)
{
listener *plistener = (listener *)id;
writeMessage *pwriteMessage;
if(pasTrapWritePvt==0) return;
semTake(pasTrapWritePvt->lock,WAIT_FOREVER);
pwriteMessage = (writeMessage *)ellFirst(&pasTrapWritePvt->writeMessageList);
while(pwriteMessage) {
listenerPvt *plistenerPvt
= (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList);
while(plistenerPvt) {
listenerPvt *pnext
= (listenerPvt *)ellNext(&plistenerPvt->node);
if(plistenerPvt->plistener == plistener) {
ellDelete(&pwriteMessage->listenerPvtList,&plistenerPvt->node);
freeListFree(pasTrapWritePvt->freeListListenerPvt,(void *)plistenerPvt);
}
plistenerPvt = pnext;
}
pwriteMessage = (writeMessage *)ellNext(&pwriteMessage->node);
}
ellDelete(&pasTrapWritePvt->listenerList,&plistener->node);
free((void *)plistener);
semGive(pasTrapWritePvt->lock);
}
void * epicsShareAPI asTrapWriteBeforeWrite(
char *userid,char *hostid,void *addr)
{
writeMessage *pwriteMessage;
listener *plistener;
listenerPvt *plistenerPvt;
if(pasTrapWritePvt==0) return(0);
if(ellCount(&pasTrapWritePvt->listenerList)<=0) return 0;
pwriteMessage = (writeMessage *)freeListCalloc(
pasTrapWritePvt->freeListWriteMessage);
pwriteMessage->message.userid = userid;
pwriteMessage->message.hostid = hostid;
pwriteMessage->message.serverSpecific = addr;
ellInit(&pwriteMessage->listenerPvtList);
semTake(pasTrapWritePvt->lock,WAIT_FOREVER);
ellAdd(&pasTrapWritePvt->writeMessageList,&pwriteMessage->node);
plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList);
while(plistener) {
plistenerPvt = (listenerPvt *)freeListCalloc(
pasTrapWritePvt->freeListListenerPvt);
plistenerPvt->plistener = plistener;
pwriteMessage->message.userPvt = 0;
(*plistener->func)(&pwriteMessage->message,0);
plistenerPvt->userPvt = pwriteMessage->message.userPvt;
ellAdd(&pwriteMessage->listenerPvtList,&plistenerPvt->node);
plistener = (listener *)ellNext(&plistener->node);
}
semGive(pasTrapWritePvt->lock);
return((void *)pwriteMessage);
}
void epicsShareAPI asTrapWriteAfterWrite(void *pvt)
{
writeMessage *pwriteMessage = (writeMessage *)pvt;
listenerPvt *plistenerPvt;
if(pwriteMessage==0 || pasTrapWritePvt==0) return;
semTake(pasTrapWritePvt->lock,WAIT_FOREVER);
plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList);
while(plistenerPvt) {
listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node);
listener *plistener;
plistener = plistenerPvt->plistener;
pwriteMessage->message.userPvt = plistenerPvt->userPvt;
(*plistener->func)(&pwriteMessage->message,1);
ellDelete(&pwriteMessage->listenerPvtList,&plistenerPvt->node);
freeListFree(pasTrapWritePvt->freeListListenerPvt,(void *)plistenerPvt);
plistenerPvt = pnext;
}
ellDelete(&pasTrapWritePvt->writeMessageList,&pwriteMessage->node);
freeListFree(pasTrapWritePvt->freeListWriteMessage,(void *)pwriteMessage);
semGive(pasTrapWritePvt->lock);
}

View File

@@ -678,6 +678,7 @@ struct client *client
struct channel_in_use *pciu;
int v41;
long status;
void *asWritePvt;
pciu = MPTOPCIU(mp);
if(!pciu){
@@ -725,11 +726,14 @@ struct client *client
mp->m_count);
#endif
asWritePvt = asTrapWriteBefore(pciu->asClientPVT,
pciu->client->pUserName,pciu->client->pHostName,(void *)&pciu->addr);
status = db_put_field(
&pciu->addr,
mp->m_dataType,
mp + 1,
mp->m_count);
asTrapWriteAfter(asWritePvt);
if (status < 0) {
SEND_LOCK(client);
send_err(