WebFOCUS DBA Exit

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.


Top of page

x
Reference: Sample Master File

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',$                             */

Top of page

x
Syntax: How to Call Parameters for the WebFOCUS DBA Exit
void xdbsc (long *iFunc, char *user_ID, char *secGrp, char *table, 
char *msg, void *token, long *rc, char *access, char *symbol, char 
*value)

where:

iFunc

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.

user_ID

Is the sign-on user ID.

secGrp

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.

table

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).

msg

Is the output parameter that displays an error message only in the case of a non-zero return code (indicating XDBSCF failure).

token

Is input to the WebFOCUS DBA Exit.

rc

Is the return code. A return code of 0 indicates success. A return code of 1 indicates failure and aborts the query.

access

Is only applicable to XDBSCF exits, and should be passed as a dummy input parameter for XDBSCP exit calls.

symbol

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).

value

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).



Example: Using the WebFOCUS DBA Exit

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