A tarefa iniciada no z / OS não possui privilégios RACF

5

Desejo testar uma implementação do servidor JDBC em execução no z / OS. A abordagem usual seria definir um procedimento JCL e executá-lo como uma tarefa iniciada. A tarefa iniciada requer um ID do usuário sob o qual ela seria executada. Os jars JDBC são colocados em um sistema de arquivos ZFS que foi montado no OMVS.

O usuário da tarefa iniciada requer determinados privilégios do RACF. Isso foi fornecido com a seguinte JCL

//RUNRACF  EXEC PGM=IKJEFT01
//SYSUADS  DD DSN=SYS1.UADS,DISP=SHR
//SYSLBC   DD DSN=SYS1.BRODCAST,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
AU JDBCUSR NAME('JDBC STC USER') PASSWORD(JDBCUSR) -
    OWNER(IBMUSER) DFLTGRP(STCGROUP) -
    UACC(READ)  OMVS(HOME(/u/zfs4svr) PROGRAM(/bin/sh) UID(3005) -
FILEPROCMAX(131072))

RDEFINE STARTED SVRPROC.** STDATA(USER(JDBCUSR) GROUP(STCGROUP) -
TRUSTED(NO))

SETROPTS CLASSACT(STARTED)
SETROPTS RACLIST(STARTED) REFRESH

PERMIT BPX.SERVER ACCESS(READ) CLASS(FACILITY) -
  ID(JDBCUSR)

SETROPTS CLASSACT(FACILITY)
SETROPTS RACLIST(FACILITY) REFRESH

Quando eu inicio a tarefa, a seguinte mensagem de erro aparece no SYSOUT:

JVMJZBL1001N JZOS batch Launcher Version: 2.4.4 2013-05-07
JVMJZBL1002N (C) Copyright IBM Corp. 2005, 2012
JVMJZBL1009E Child shell process exited without printing environment; //STDENV should not contain 'exit' JVMJZBL1042E JZOS batch launcher failed, return code=101

Depois de pesquisar e ler o que a documentação de suporte da IBM tinha a dizer, Eu e meus colegas estávamos muito confusos. Eu tentei iniciar o servidor como um trabalho direto. O usuário do trabalho tinha privilégios de administrador do sistema. Isso funciona e podemos testar o servidor JDBC. Tentar executar o trabalho com o usuário para o procedimento resulta no mesmo erro mostrado acima.

É óbvio que o JDBCUSR não possui privilégios ou outros. Para executar o servidor como uma tarefa iniciada, preciso saber quais privilégios estão faltando. Certamente, não desejamos conceder os direitos de administrador do sistema de usuário da tarefa iniciada.

Existe alguma maneira de descobrir o que está faltando? Isso é muito frustrante.

Editar 11.10.2016

A JCL a seguir é o JOB que funciona quando <user> tem privilégios de administrador do sistema:

//V4JSRV   JOB USER=<user>,PASSWORD=<password>,REGION=200M
//*
//*******************************************************************
//* Call the server as a job
//*******************************************************************
//PROCS    JCLLIB ORDER=(ACHIM.JDBCSRV.CNTL)
//SRV      EXEC PROC=SRVPROC
//STDENV   DD DISP=SHR,DSN=ACHIM.JDBCSRV.CNTL(SRVENV)
//STRCTREP DD DISP=SHR,DSN=ACHIM.JDBCSRV.STRCTREP

O procedimento é assim:

//JDBCPROC  PROC JAVACLS='de.ubs.du.jdbcserver.Server',
//   ARGS='-p 5431 LOG-LEVEL=FINE',
//   LEPARM='',
//   LOGLVL='+T'
//JAVAJVM  EXEC PGM=JVMLDM70,REGION=200M,
//   PARM='&LEPARM/&LOGLVL &JAVACLS &ARGS'
//*JDBCPROC  PROC
//*JAVAJVM  EXEC PGM=JVMLDM70,REGION=200M,
//*   PARM='de.ubs.du.jdbcserver.Server -p 5431 LOG-LEVEL=FINE'
//STEPLIB  DD DSN=JVA700.SIEALNKE,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//ABNLIGNR DD DUMMY

Como você pode ver, o trabalho não faz mais do que executar o procedimento. Quando <user> é o nome de usuário para o procedimento iniciado, o erro acima é produzido, quando é um usuário administrador, então a tarefa é executada normalmente. Obviamente, para iniciá-lo como uma tarefa iniciada, o proc é copiado para uma biblioteca pública de proc (USER.PROCLIB para ser preciso).

Não há nada especialmente espetacular em nada disso. Na verdade, é bem banal. É por isso que suspeitamos que seja um problema do RACF.

Editar (2) 11.10.2016

Ainda não é uma solução, mas consegui localizar o problema. O procedimento iniciado funciona se for atribuído o atributo TRUSTED. Isso significa efetivamente que a tarefa iniciada é tratada como um "superusuário" no z / OS Unix (em outras palavras, possui privilégios de root). Então, agora é uma questão de determinar exatamente o que nosso servidor precisa, que até hoje só está disponível quando executado por um superusuário. Quando eu descobrir, vou postar uma solução.

Editar (3) 12.12.2016

Depois de adicionar o rastreio (consulte o proc modificado acima), ocorre o seguinte erro:

JVMJZBL2999T ->invokeMain()                                                           
JVMJZBL2999T javaClassName: 'de.ubs.du.jdbcserver.Server'                              
JVMJZBL2999T Arg 1='-p'                                                                
JVMJZBL2999T Arg 2='5431'                                                              
JVMJZBL2999T Arg 3='LOG-LEVEL=FINE'                                                    
JVMJZBL1023N Invoking de.ubs.du.jdbcserver.Server.main()...                            
JVMJZBL1056I Arguments to main...                                                      
JVMJZBL1057I -p                                                                        
JVMJZBL1057I 5431                                                                      
JVMJZBL1057I LOG-LEVEL=FINE                                                            
JVMJZBL2999T -> JniUtil.convert()                                                      
JVMJZBL2999T <- JniUtil.convert()                                                      
JVMJZBL2008E Could not find or load class: de.ubs.du.jdbcserver.Server                 
JVMJZBL2999T -> JniUtil.writeStackTrace()                                              
JVMJZBL2007E Stack trace follows:                                                      
java.lang.NoClassDefFoundError: de.ubs.du.jdbcserver.Server                            
Caused by: java.lang.ClassNotFoundException: de.ubs.du.jdbcserver.Server               
.at java.net.URLClassLoader.findClass(URLClassLoader.java:588)                         
.at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:756)                        
.at java.lang.ClassLoader.loadClass(ClassLoader.java:724)                              
.at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:313)                      
.at java.lang.ClassLoader.loadClass(ClassLoader.java:703)                              
JVMJZBL2999T <- JniUtil.writeStackTrace()                                              

JVMJZBL2999T <- invokeMain()                                                           
JVMJZBL2999T <- run()                                                                  
JVMJZBL2999T -> cleanup()                                                              
JVMJZBL1014I Waiting for non-deamon Java threads to finish before exiting...           
JVMJZBL2999T JvmExitHook entered with exitCode=0, javaMainReturnedOrThrewException=0   
JVMJZBL1042E JZOS batch launcher failed, return code=100                               
JVMJZBL2999T DestroyJavaVM elapsed time=0.031311 seconds, cpu time=0.021000 seconds    
JVMJZBL2999I JZOS batch launcher elapsed time=7 seconds, cpu time=5.090000 seconds     
JVMJZBL1047W JZOS batch launcher completed with Java exception, return code=100        
JVMJZBL2999T <- cleanup()

O motivo pelo qual estamos recebendo este erro de tempo de execução não está claro. Nesta fase, não parece mais um problema de permissões.

    
por Achim Schmitz 10.10.2016 / 12:54

1 resposta

0

Finalmente, tive tempo de voltar a este problema. O problema original era bastante obscuro. Depois de olhar para vários fóruns, finalmente ficou claro que havia um erro no membro ACHIM.JDBCSRV.CNTL (SRVENV). Ele continha a linha:

. /etc/profile

Remover isso corrigiu o primeiro erro, que foi causado pela "saída" implícita no final de qualquer script bash. Se você estiver fazendo algo semelhante e realmente precisar das configurações no script /etc/profile , só posso sugerir que você copie o conteúdo do script para você //STDENV data.

Depois disso, um novo erro apareceu:

java.lang.NoClassDefFoundError: de.ubs.du.jdbcserver.Server

Isso foi mostrado na edição (3) acima. Isso acabou por ser um problema de permissões. No trabalho para configurar as permissões do RACF, há o seguinte no DD SYSTSIN:

OMVS(HOME(/u/zfs4svr)...

Isso especifica um ponto de montagem para o sistema de arquivos ZFS contendo os jars usados pelo JDBCUSR, quando a tarefa é iniciada. O trabalho de montagem correspondente foi executado por um usuário administrador. Os passos relevantes da tarefa são:

//REPRO    EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  DELETE '<HLQ>.JDBCSRV.ZFS'
  SET MAXCC = 0
  DEFINE CLUSTER ( -
     NAME('<HLQ>.JDBCSRV.ZFS') -
     LINEAR CYL(50 1) -
     SHAREOPTIONS(3,3) -
  )
  REPRO INDATASET(<HLQ>.JDBCSRV.REPRO) -
         OUTDATASET(<HLQ>.JDBCSRV.ZFS)
//****************************************************
//SHELLCMD EXEC PGM=BPXBATCH,COND=(4,LT),
//    PARM='SH mkdir -p /u/zfs4fb'
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//*************************************************
//SHELLCMD EXEC PGM=BPXBATCH,COND=(4,LT),
//    PARM='SH chown -R JDBCUSR:STCGROUP /u/zfs4fb'
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//**************************************************
//SHELLCMD EXEC PGM=BPXBATCH,COND=(4,LT),
//    PARM='SH chmod -R 770 /u/zfs4fb'
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//**************************************************
//MOUNT    EXEC PGM=IKJEFT01,COND=(4,LT)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
  MOUNT -
     FILESYSTEM('''<HLQ>.JDBCSRV.ZFS''') -
     TYPE(HFS) -
     MODE(RDWR) -
     MOUNTPOINT('/u/zfs4fb')        

A dificuldade aqui foi o fato de que o proprietário e os direitos para /u/zfs4fb estão configurados para permitir acesso ao JDBCUSR, no entanto, os pacotes contidos ainda são de propriedade do usuário que executa o trabalho. Alteramos o acesso de leitura / gravação para o conteúdo diretamente no OMVS. Isso resolveu o problema. Para corrigir isso no script, a ordem dos passos de trabalho precisa ser alterada. Nesse caso, colocar as etapas de 2 //SHELCMD com os comandos chmod e chown após a etapa //MOUNT corrige o problema

Houve outras questões com a nossa tarefa. Na inicialização do servidor, a propriedade user.dir é usada. Eu não tenho certeza apenas onde, mas parece ter a ver com a JVM para z / OS. Demorou um pouco de ajustes, já que não pudemos determinar de onde vem o valor. Quando executado como um job submetido por um usuário administrador (IBMUSER), o valor era "/ u / ibmuser". No entanto, quando executado como uma tarefa iniciada, o valor era ".", O que causou o erro:

java.lang.ExceptionInInitializerError                         
.at java.lang.J9VMInternals.initialize(J9VMInternals.java:258)
...
Caused by: java.lang.RuntimeException: default directory must be absolute 
.at sun.nio.fs.UnixFileSystem.<init>(UnixFileSystem.java:55)              
...

A correção foi colocar o comando cd /u/zfs4fb no final do script do ambiente //STDENV . Isso pode realmente ser qualquer diretório para o qual o usuário STC (neste caso, JDBCUSR) tenha permissão de leitura.

Espero que este tour de descoberta ajude alguém a tentar resolver problemas semelhantes.

    
por 10.04.2017 / 15:05