How to: Reference: |
The WebFOCUS DBA Exit requires a custom C program compiled into a module called XDBSC. This file must be stored in the directory pointed to by the IBICPG variable defined in the WebFOCUS Reporting Server environment. A DBA Exit will be called when the server-based Master File is accessed. The symbolic variable used for the call of this exit is an @ character. The ID that is passed to the exit is the connected user ID.
In the following sample Master File, the symbolic variables (for example, @FIELD) can be placed anywhere in the VALUE statement, so complex logic can be implemented. A VALUE statement can be a single parameter in which the exit provides the entire restriction statement.
/* END */ /* DBA=DOGBERT, $ */ /* USER=SSFULL, ACCESS=R, $ */ /* USER=JILL, ACCESS=R, RESTRICT=VALUE, NAME=SYSTEM, */ /* VALUE = @FIELD @EQUALITY '@VALUE',$ */ /* USER=ROBERT, ACCESS=R, RESTRICT=VALUE, NAME=SYSTEM, */ /* VALUE = COUNTRY EQ '@ROBERT',$ */ /* USER=NATALIE, ACCESS=R, RESTRICT=VALUE, NAME=SYSTEM, */ /* VALUE = COUNTRY EQ 'JAPAN',$ */ /* USER=TERRY, ACCESS=R, RESTRICT=VALUE, NAME=SYSTEM, */ /* VALUE = COUNTRY EQ '@VARIOUS',$ */
void xdbsc (long *iFunc, char *user_ID, char *secGrp, char *table, char *msg, void *token, long *rc, char *access, char *symbol, char *value)
where:
Is input to the WebFOCUS DBA Exit. This value defines the type of exit to call. Possible values are:
1 - XDBSCP (POST) is called to determine what security group the user should be in for this table.
2 - XDBSCF (FETCH) is called for each symbolic variable specified in the value restriction expressions for the security group resulting from XDBSCP.
Is the sign-on user ID.
For XDBSCP, there is input to and output from the exit. On input, this is the security group that the user signed on with or has been given by the logon exit. Upon exiting, this is the security group that should be used for this query. For XDBSCF, input to the exit is from the previous XDBSCP call.
Is the input parameter that indicates the table for the query. This is a zero-delimited string with a maximum length of 20, including the string termination character (\0).
Is the output parameter that displays an error message only in the case of a non-zero return code (indicating XDBSCF failure).
Is input to the WebFOCUS DBA Exit.
Is the return code. A return code of 0 indicates success. A return code of 1 indicates failure and aborts the query.
Is only applicable to XDBSCF exits, and should be passed as a dummy input parameter for XDBSCP exit calls.
Is only applicable to XDBSCF exits, and should be passed as a dummy input parameter for XDBSCP exit calls. This is the symbol (parm) name without the '@' prefix. This is a zero-delimited string with maximum length of 68, including the string termination character (\0).
Is only applicable to XDBSCF exits, and should be passed as a dummy output parameter for XDBSCP exit calls. This parameter indicates the value to be substituted for the symbol. If multiple values are specified, they must be separated by \0 and \0\0 to indicate the end of list. This parameter has a maximum length of 4096, including the string termination character (\0).
The following example uses the Sample Master File to limit user access to data sources.
Compilation and usage of this exit follows the standard methods for user subroutines, which is gencpgm on most platforms. Next, copy the exit to the user directory of EDACONF, or set the environment variable IBICPG to the name of the actual working directory. For more information, see the Stored Procedures Reference manual.
/* XDBSC DBA Security Plug-in */ /* */ #include <string.h> #include <stdio.h> #include <errno.h> #define F_POST 1 /* XDBSCP */ #define F_FETCH 2 /* XDBSCF */ void xdbsc(long *iFunc, char *user_ID, char *secGrp, char *table, char *msg, void *token, long *pRC, char *access, char *symbol, char *value) /* Last 3 args for F_FETCH only */ { char ubuf[9], gbuf[9]; FILE *logFile; memcpy(ubuf, user_ID, 8); ubuf[8] = '\0'; memcpy(gbuf, secGrp, 8); gbuf[8] = '\0'; errno = 0;
/* */ /* The logging intended in this example is to confirm */ /* behavior in "edastart -t" mode and then turn */ /* off logging or comment it out until needed again. */ /* */ /* This example is coded with a compilation flag for IBM Mainframe */ /* to activate. It writes to stderr as the simplest way to capture */ /* output. */ /* If you are in an IBM Mainframe environemnt, make sure that you */ /* compile with a DEFINE(IBMMF=1) and have STDOUT declared in the */ /* start up JCL. In this environment, stderr is routed to stdout */ /* for "edastart -t" mode and a trace file for server mode use. */ /* */ /* On non IBM Mainframe environments the default is to code as a */ /* local file for "edastart -t" mode. For a server, use a full path*/ /* so that the log is common to all agents and remains between */ /* agents uses. For example: */ /* logFile = fopen("/home/iadmin/ibi/srv51/ffs/xdbsc.log", "a"); */ /* logFile = fopen("EDA:[IADMIN.IBI.SRV51.FFS]XDBSC.LOG", "a"); */ /* logFile = fopen("c:\tmp\xdbsc.log", "a"); */ /* */ /* Note: Only IBM Mainfram needs the IBMMF compilation flag. */ /* */
#ifdef IBMMF logFile = stderr; #else logFile = fopen("xdbsc.log", "a"); if (errno != 0) printf("!!!! errno = %d: %s\n", errno, strerror(errno)); #endif strcpy(msg, " "); /* Clear buffer for fprintf */ if (logFile) { if (*iFunc == F_POST) { /* Change/Add/Format values needed for site */ fprintf(logFile, "xdbsc: iFunc=%ld, ID=%s, grp=%s, table=%s, msg=%s, token=%p, rc=%ld\n", *iFunc, ubuf, gbuf, table, msg, token, *pRC); #ifndef IBMMF fclose(logFile); #endif } } *pRC = 0; /* Successful return */
if (*iFunc == F_POST) return; /* */ /* Place your site specific if else logic here, using the */ /* passed in values as criteria. Nothing above this section */ /* should have major changes except for any log control you */ /* may want performed. Primary work is done in this section.*/ /* */ if ( (memcmp(user_ID, "edaqa0 ", 8) == 0) || (memcmp(user_ID, "EDAQA0 ", 8) == 0) ) { if (strcmp(symbol, "FIELD") == 0) strcpy(value, "COUNTRY"); else if (strcmp(symbol, "EQUALITY") == 0) strcpy(value, "EQ"); else if (strcmp(symbol, "VALUE") == 0) strcpy(value, "FRANCE"); else if (strcmp(symbol, "ROBERT") == 0) strcpy(value, "ENGLAND");
else { strcpy(value, "DBA Failure"); strcpy(msg, "XDBCS DBA Exit: If Else Logic Failure!\n"); *pRC = -1; /* 0 causes the value to still substitute (so value */ /* should be one that is unlikely to match a */ /* real value so it always returns no records) */ /* and gives the standard ACCESS LIMITED BY */ /* PASSWORD message. */ /* */ /* Non Zero causes abort query with msg value and */ /* (FOC047) THE USER DOES NOT HAVE SUFFICIENT */ /* ACCESS RIGHTS TO THE FILE: *table * */ /* and BYPASSING TO END OF COMMAND message. */ /* */ /* So depending on need you might use a value of */ /* zero for a fail. */ } }
else if (memcmp(user_ID, "NORMAN ", 8) == 0) { strcpy(value, "JAPAN"); } else { strcpy(value, "ITALY"); } if (logFile) { if (*iFunc == F_FETCH) { /* Change/Add/Format values needed for site */ fprintf(logFile, "xdbsc: iFunc=%ld, ID=%s, grp=%s, table=%s, msg=%s, token=%p, rc=%ld", *iFunc, ubuf, gbuf, table, msg, token, *pRC); fprintf(logFile,", access=%s, symbol=%s, value=%s\n", access, symbol, value); #ifndef IBMMF fclose(logFile); #endif } } }
WebFOCUS |