changes for asTrapWrite
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
166
src/as/asTrapWrite.c
Normal 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);
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user