XML Service Work

XMLService.XMLServiceWork History

Hide minor edits - Show changes to markup

Changed lines 1075-1077 from:

https://bitbucket.org/litmis/ibmichroot

to:

https://github.com/IBM/ibmichroot

Changed lines 1255-1257 from:
  • https://bitbucket.org/litmis/ibmichroot/overview
to:
  • https://github.com/IBM/ibmichroot
Changed line 2074 from:

https://bitbucket.org/inext/xmlservice-rpg

to:

https://github.com/IBM/xmlservice/

Added lines 2-13:
      * *java (1.9.2)               
      *    - start JVM allowing user classpath
      *      <cmd>ADDENVVAR ENVVAR(CLASSPATH) VALUE(‘$ours’) 
      *           REPLACE(*YES)</cmd>
      *      <pgm>… calling my RPG w/JAVA … </pgm>
      * *sqljava or *dbgjava (port 30000) (1.9.2)            
      *    - start JVM allowing DB2 classpath (no user control)
      *       SQLJ.INSTALL_JAR into schema
      *       /QIBM/UserData/OS400/SQLLib/Function/jar/(schema) 
Added lines 2-14:
      *****************************************************
     P PaseStart32     B                   export
     D PaseStart32     PI             1N
     D   myMax                       10i 0 value
     D   paseCtl                           likeds(paseRec_t)
      * vars
     Diarg             DS
     D ipgm                          30A   inz(‘/usr/lib/start32′)
     D iarg1                           *   inz(*NULL)
     D iargend                         *   inz(*NULL)
Added lines 1-32:
      *****************************************************
      * JVM the RPG way
      *****************************************************
     P jvmRPG          B
     D jvmRPG          PI            10I 0
      *
     d rc              s             10i 0 inz(-1)
     D myfunc          S             10A   inz(*BLANKS)
     D propstr         S               O   CLASS(*JAVA:'java.lang.String')
     D makeString      PR              O   EXTPROC(*JAVA:'java.lang.String':
     D                                      *CONSTRUCTOR)
     D    bytes                    4096A   CONST VARYING
      /free
       Monitor;

       myfunc = 'jvmRPG';
       propstr = makeString('java.class.path');
       rc = 0;

       On-error;
         errsSevere(QP2_ERROR_ILECALL_FAIL:myfunc);
       Endmon;

       return rc;
      /end-free
     P                 E

Added lines 1-13:

Clark:

Solved my customer’s problem by setting FastCGI CCSID to 819 (latin), and having them tell the web browser to treat content as iso-8859–1, by using php’s header() function, as follows, at the top of their script, before any html output: header(‘Content-type: text/html; charset=iso-8859–1′);

Their data was indeed 7-bit ASCII, so the above took care of the problem.

The 819 for FastCGI took care of the data length, but characters were still displaying as black triangles with question marks. The header() function with correct charset solved the output part.

DRDA ports - https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/ddp/rbal1ports.htm

Added lines 1-38:
                Work with Relational Database Directory Entries

 Position to  . . . . . .                     

 Type options, press Enter.
   1=Add   2=Change   4=Remove   5=Display details   6=Print details

                             Remote
 Option  Entry               Location                  Text
   1     INUXME            
         M128584T            ut28p63.rch.stglabs.ib >  Entry added by system
         UT28P63             *LOCAL
         UT28P64             ut28p64.rch.stglabs.ib >
         UT28P65             ut28p65.rch.stglabs.ib >

                     Add RDB Directory Entry (ADDRDBDIRE)    

 Type choices, press Enter.

 Entry:
   Relational database  . . . . . > INUXME                   
   Relational database alias  . .   *NONE                    
 Remote location:
   Name or address  . . . . . . .   mylinux.ibm.com                             



   Type . . . . . . . . . . . . . > *IP           *SNA, *IP
 Port number or service program     *DRDA            
 Remote authentication method:
   Preferred method . . . . . . .   *USRENCPWD    *USRENCPWD, *USRID...
   Allow lower authentication . .   *ALWLOWER     *ALWLOWER, *NOALWLOWER

Added lines 1-342:
SQLRETURN tool_key_cmd_run(tool_struct_t * tool, tool_node_t ** curr_node) {
  SQLRETURN sqlrc = SQL_SUCCESS;
  SQLRETURN sqlrc1 = SQL_SUCCESS;
  int h = 0, i = 0, j = 0;
  int key = 0;
  char * val = NULL;
  int lvl = 0;
  int max = 0;
  int go = 1;
  char * cmd = NULL;
  int len = 0;
  int fetch_odd = 0;
  int fetch_recs = 0;
  int isRexx = 0;
  int isRexxError = 0;
  char * lastLF = NULL;
  char * posLF = NULL;
  int isQsh = 0;
  int isQshLen = 0;
  int isQshRow = 0;
  int isQshError = 0;
  char * qshVal = NULL;
  int save_conn_type = 0;
  SQLCHAR qshRow[50];
  SQLHANDLE hstmt = 0;
  SQLHANDLE hstmt2 = 0;
  SQLCHAR cmd_tmp[TOOL400_MAX_CMD_BUFF];
  SQLCHAR query_string[TOOL400_MAX_CMD_BUFF];
  SQLCHAR col_name[69];
  SQLCHAR col_val[69];
  SQLINTEGER col_len = 0;
  tool_key_conn_struct_t * tconn = (tool_key_conn_struct_t *) tool->tconn;
  tool_node_t * node = *curr_node;
  tool_key_cmd_struct_t * tcmd = (tool_key_cmd_struct_t *) node;
  /* current node (output) */
  tool->curr = node;

  /* ctor */
  tcmd->hstmt = 0;
  tcmd->cmd_len = 0;
  memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));

  /* save conn type (not support in memory for rexx or qsh) */
  save_conn_type = tconn->conn_type;

  /* cmd attributes (parser order 1st) */
  for (i=0; i < TOOL400_ATTR_MAX && node->akey[i]; i++) {
    key = node->akey[i];
    val = node->aval[i];
    lvl = node->ord;
    tool_dump_attr(sqlrc, "cmd_run(a)", i, lvl, key, val);
    switch (key) {
    /* "exec":"CHGLIBL LIBL(DB2JSON QTEMP) CURLIB(DB2JSON)"
     */
    case TOOL400_CMD_EXEC:
      cmd = val;
      break;
    /* "rexx":"STRREXPRC SRCMBR(CMDIO) SRCFILE(DB2JSON/QREXSRC) PARM('456 RTVJOBA CCSID(?N) USRLIBL(?)')"
     * select * from qtemp/out456
     */
    case TOOL400_CMD_REXX:
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt);
      isRexx = hstmt;
      sprintf(tcmd->cmd_buff,"STRREXPRC SRCMBR(CMDIO) SRCFILE(DB2JSON/QREXSRC) PARM('%d %s')",isRexx,val);
      cmd = tcmd->cmd_buff;
      /* in memory option? (not support rexx -- not work chroot) */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        tconn->conn_type = TOOL400_CONN_TYPE_SET;
      }
      break;
    /* "qsh":"STRQSH CMD('ls -1 /home/adc')"
     * select * from qtemp/out456
     */
    case TOOL400_CMD_QSH:
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt);
      isQsh = hstmt;
      cmd = qshVal = val;
      /* in memory option? (not support qsh -- not work chroot) */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        tconn->conn_type = TOOL400_CONN_TYPE_SET;
      }
      break;
    default:
      break;
    }
  }
  /* output */
  tool_output_cmd_beg(tool, cmd);
  /* qsh */
  if (isQsh) {
    for (h=0;h<7;h++) {
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt2);
      memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
      cmd = tcmd->cmd_buff;
      switch(h) {
      case 0:
        sprintf(cmd,"DLTF FILE(QTEMP/OUT%d)", isQsh);
        break;
      case 1:
        sprintf(cmd,"CRTSRCPF FILE(QTEMP/OUT%d) RCDLEN(80) MBR(OUT%d)", isQsh, isQsh);
       break;
      case 2:
        sprintf(cmd,"CLRPFM FILE(QTEMP/OUT%d) MBR(OUT%d)", isQsh);
        break;
      case 3:
        sprintf(cmd,"RMVENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG)");
        break;
      case 4:
        sprintf(cmd,"ADDENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE('Y')");
        break;
      case 5:
        sprintf(cmd,"RMVENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT)");
        break;
      case 6:
        sprintf(cmd,"ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE('FILE=/qsys.lib/qtemp.lib/out%d.file/out%d.mbr')", isQsh, isQsh);
        break;
      default:
        break;
      }
      /* sql actual len cmd (ignore escape quotes) */
      tcmd->cmd_len = strlen(cmd);
      /* escape single quotes */
      memset(cmd_tmp,0,TOOL400_MAX_CMD_BUFF);
      for (i=0, j=0; i < tcmd->cmd_len && j < TOOL400_MAX_CMD_BUFF; i++, j++) {
        cmd_tmp[j] = cmd[i];
        /* found single quote, add another single quote */
        if (cmd_tmp[j] == '\'') {
          j++;
          cmd_tmp[j] = '\'';
        }
      }
      cmd = cmd_tmp;
      memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
      /* in memory option? */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        sqlrc = iCall400Cmd(cmd, tcmd->cmd_len);
      } else {
        sprintf(tcmd->cmd_buff,"CALL QSYS2.QCMDEXC('%s',%d)", cmd, tcmd->cmd_len);
        sqlrc = SQLExecDirect(hstmt2, tcmd->cmd_buff, (SQLINTEGER)SQL_NTS);
      }
      sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
    } /* loop h */
    /* STRQSH CMD */
    memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
    sprintf(tcmd->cmd_buff,"STRQSH CMD('%s')",qshVal);
    cmd = tcmd->cmd_buff;
  } /* isQsh */
  /* sql actual len cmd (ignore escape quotes) */
  tcmd->cmd_len = strlen(cmd);
  /* escape single quotes */
  memset(cmd_tmp,0,TOOL400_MAX_CMD_BUFF);
  for (i=0, j=0; i < tcmd->cmd_len && j < TOOL400_MAX_CMD_BUFF; i++, j++) {
    cmd_tmp[j] = cmd[i];
    /* found single quote, add another single quote */
    if (cmd_tmp[j] == '\'') {
      j++;
      cmd_tmp[j] = '\'';
    }
  }
  /* statement */
  sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHDBC) tconn->hdbc, &tcmd->hstmt);
  /* in memory option? */
  if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
    sqlrc = iCall400Cmd(cmd, tcmd->cmd_len);
  } else {
    cmd = cmd_tmp;
    memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
    sprintf(tcmd->cmd_buff,"CALL QSYS2.QCMDEXC('%s',%d)", cmd, tcmd->cmd_len);
    /* prepare */
    if (sqlrc == SQL_SUCCESS) {
      sqlrc = SQLPrepare((SQLHSTMT)tcmd->hstmt, (SQLCHAR*)tcmd->cmd_buff, (SQLINTEGER)SQL_NTS);
    }
    sqlrc = tool_sql_errors(tool, tcmd->hstmt, SQL_HANDLE_STMT, sqlrc);
    /* execute */
    if (sqlrc == SQL_SUCCESS) {
      sqlrc = SQLExecute((SQLHSTMT)tcmd->hstmt);
    }
    sqlrc = tool_sql_errors(tool, tcmd->hstmt, SQL_HANDLE_STMT, sqlrc);
  }
  /* ======
   * qsh output 
   */
  if (isQsh && sqlrc == SQL_SUCCESS) {
    /* query QTEMP.OUT456 */
    memset(query_string,0,sizeof(query_string));
    sprintf(query_string,"select SRCDTA from QTEMP.OUT%d",isQsh);
    sqlrc = SQLExecDirect(hstmt, query_string, (SQLINTEGER)SQL_NTS);
    col_len = sizeof(col_val);
    memset(col_val,0,sizeof(col_val));
    sqlrc = SQLBindCol((SQLHSTMT)hstmt,
                         1,
                         SQL_CHAR, 
                         col_val,
                         col_len,
                         &col_len);
    /* fetch */
    memset(cmd_tmp,0,sizeof(cmd_tmp));
    sqlrc = SQL_SUCCESS;
    tool_output_record_array_beg(tool);
    while (sqlrc == SQL_SUCCESS) {
      col_len = sizeof(col_val);
      memset(col_val,0,sizeof(col_val));
      sqlrc = SQLFetch(hstmt);
      if (sqlrc == SQL_NO_DATA_FOUND || sqlrc < SQL_SUCCESS ) {
        if (!fetch_recs) {
          tool_output_record_no_data_found(tool, 0);
        } else {
          sqlrc = SQL_SUCCESS;
        }
        break;
      }
      fetch_recs += 1;
      strcat(cmd_tmp,col_val);
      /* find LF for rows */
      lastLF = cmd_tmp;
      posLF = ile_pgm_find_new_line(lastLF, FLAG_STR_COMPILE);
      while (posLF) {
        isQshRow++;
        memset(qshRow,0,sizeof(qshRow));
        sprintf(qshRow,"R%d", isQshRow);
        posLF[0] = '\0';
        isQshLen = strlen(lastLF);
        tool_output_record_row_beg(tool);
        tool_output_record_name_value(tool, qshRow, lastLF, SQL_CHAR, isQshLen);
        tool_output_record_row_end(tool);
        lastLF = posLF + 1;
        posLF = ile_pgm_find_new_line(lastLF, FLAG_STR_COMPILE);
      }
      /* shift remain data */
      posLF = lastLF;
      lastLF = cmd_tmp + sizeof(cmd_tmp);
      if (posLF < lastLF) {
        strcpy(cmd_tmp, posLF);
        posLF = cmd_tmp;
        isQshLen = strlen(posLF);
        posLF = cmd_tmp + isQshLen;
        memset(posLF, 0, sizeof(cmd_tmp) - isQshLen);
      }
    } /* fetch loop */
    /* out remain data */
    ile_pgm_trim(cmd_tmp, sizeof(cmd_tmp), FLAG_STR_COMPILE);
    lastLF = cmd_tmp;
    isQshLen = strlen(lastLF);
    if (isQshLen) {
      posLF = cmd_tmp + isQshLen;
      isQshRow++;
      memset(qshRow,0,sizeof(qshRow));
      sprintf(qshRow,"R%d", isQshRow);
      posLF[0] = '\0';
      tool_output_record_row_beg(tool);
      tool_output_record_name_value(tool, qshRow, lastLF, SQL_CHAR, isQshLen);
      tool_output_record_row_end(tool);
    }
    tool_output_record_array_end(tool);
  }
  /* ======
   * rexx output 
   */
  else if (isRexx && sqlrc == SQL_SUCCESS) {
    /* query QTEMP.OUT456 */
    memset(query_string,0,sizeof(query_string));
    sprintf(query_string,"select SRCDTA from QTEMP.OUT%d",isRexx);
    sqlrc = SQLExecDirect(hstmt, query_string, (SQLINTEGER)SQL_NTS);
    col_len = sizeof(col_val);
    memset(col_val,0,sizeof(col_val));
    sqlrc = SQLBindCol((SQLHSTMT)hstmt,
                         1,
                         SQL_CHAR, 
                         col_val,
                         col_len,
                         &col_len);
    /* fetch */
    memset(cmd_tmp,0,sizeof(cmd_tmp));
    sqlrc = SQL_SUCCESS;
    tool_output_record_array_beg(tool);
    while (sqlrc == SQL_SUCCESS) {
      col_len = sizeof(col_val);
      memset(col_val,0,sizeof(col_val));
      sqlrc = SQLFetch(hstmt);
      if (sqlrc == SQL_NO_DATA_FOUND || sqlrc < SQL_SUCCESS ) {
        if (!fetch_recs) {
          tool_output_record_no_data_found(tool, 0);
        } else {
          sqlrc = SQL_SUCCESS;
        }
        break;
      }
      fetch_recs += 1;
      /* start name ("name":"value") */
      if (col_val[7]==':') {
        /* DEADBEE: remove */
        memcpy(col_val,&col_val[8],sizeof(col_val)-9);
        if (fetch_odd > 1) {
          tool_output_record_row_beg(tool);
          tool_output_record_name_value(tool, col_name, cmd_tmp, SQL_CHAR, col_len);
          tool_output_record_row_end(tool);
          /* rexx error? */
          if (!strcmp(col_name,"error")) {
            isRexxError = 1;
          }
        }
        fetch_odd = 1;
        memcpy(col_name, col_val, sizeof(col_val));
        ile_pgm_trim(col_name, sizeof(col_val), FLAG_STR_COMPILE);
        memset(cmd_tmp,0,sizeof(cmd_tmp));
      } else {
        /* DEADBEEF remove */
        memcpy(col_val,&col_val[8],sizeof(col_val)-9);
        fetch_odd += 1;
        strcat(cmd_tmp,col_val);
        ile_pgm_trim(cmd_tmp, sizeof(cmd_tmp), FLAG_STR_COMPILE);
      }
    } /* fetch loop */
    tool_output_record_array_end(tool);
  }
  /* rexx or qsh errors ? */
  if (isRexxError || isQshError) {
    sqlrc = tool_sql_errors(tool, hstmt, SQL_HANDLE_STMT, SQL_ERROR);
  }
  /* output */
  tool_output_cmd_end(tool);
  /* close */
  if (tcmd->hstmt) {
    sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, tcmd->hstmt);
  }
  tcmd->hstmt = 0;
  if (hstmt) {
    /* maybe should ... DLTF FILE(QTEMP/OUT) */
    sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
  }
  hstmt = 0;

  /* restore conn type (not support in memory for rexx or qsh) */
  tconn->conn_type = save_conn_type;

  return sqlrc;
}
Added lines 4-5:

Apache 2.4 vulnerabilities

Added lines 2-3:

quifax, Apache Struts, & CVE-2017-5638 Vulnerability

Changed line 1 from:
to:

IBM CVE-2017-5638