Назад | Перейти на главную страницу

Запущенной задаче в z / OS не хватает прав RACF

Я хочу протестировать реализацию сервера JDBC, работающего под z / OS. Обычный подход - определить процедуру JCL и запустить ее как запущенную задачу. Для запущенной задачи требуется идентификатор пользователя, под которым она будет работать. Банки JDBC помещаются в файловую систему ZFS, которая смонтирована в OMVS.

Пользователю для запущенной задачи требуются определенные привилегии RACF Это было предоставлено следующим 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

Когда я запускаю задачу, в SYSOUT появляется следующее сообщение об ошибке:

JVMJZBL1001N Пакетная программа запуска JZOS Версия: 2.4.4 07.05.2013
JVMJZBL1002N (C) Авторские права IBM Corp.2005, 2012
JVMJZBL1009E Дочерний процесс оболочки завершился без среды печати; // STDENV не должен содержать 'exit' JVMJZBL1042E Не удалось запустить пакетную программу JZOS, код возврата = 101

Посмотрев это и прочитав, что Документация по поддержке IBM должен был сказать, я и мои коллеги были очень сбиты с толку. Затем я попытался запустить сервер как прямую работу. Пользователь, выполнявший задание, имел права системного администратора. Это работает, и мы можем протестировать сервер JDBC. Попытка запустить задание с пользователем для процедуры приводит к той же ошибке, что и показанная выше.

Очевидно, что JDBCUSR не обладает теми или иными привилегиями. Чтобы запустить сервер как запущенную задачу, мне нужно знать, каких привилегий не хватает. Мы, конечно, не хотим давать пользователю запускаемой задачи права администратора системы.

Есть ли способ узнать, чего не хватает? Это очень расстраивает.

Изменить 11.10.2016

Следующий JCL - это ЗАДАНИЕ, которое действительно работает, когда <user> имеет права системного администратора:

//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

Порядок действий выглядит так:

//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

Как видите, задание не делает ничего, кроме запуска процедуры. когда <user> - это имя пользователя для запущенной процедуры, возникает ошибка, указанная выше, когда это пользователь с правами администратора, тогда задание выполняется нормально. Очевидно, чтобы запустить его как запущенную задачу, процесс копируется в публичную библиотеку процессов (точнее, USER.PROCLIB).

В этом нет ничего особенно впечатляющего. На самом деле это довольно банально. Вот почему мы подозреваем, что это проблема RACF.

Изменить (2) 11.10.2016

Пока это не решение, но мне удалось локализовать проблему. Запущенная процедура функционирует, если ей присвоен атрибут ДОВЕРИЯ. Это фактически означает, что запущенная задача рассматривается как "суперпользователь" в z / OS Unix (другими словами, она имеет привилегии root). Итак, теперь нужно определить, что именно нужно нашему серверу, что на сегодняшний день доступно только при запуске суперпользователем. Когда узнаю, выложу решение.

Изменить (3) 12.12.2016

После добавления трассировки (см. Модифицированный процесс выше) возникает следующая ошибка:

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

Непонятно, почему мы получаем эту ошибку времени выполнения. На данном этапе это больше не похоже на проблему с разрешениями.

Наконец-то у меня было время вернуться к этой проблеме. Первоначальная проблема была довольно неясной. После просмотра нескольких форумов наконец стало ясно, что в члене ACHIM.JDBCSRV.CNTL (SRVENV) произошла ошибка. В нем была строка:

. /etc/profile

Удаление этого исправило первую ошибку, которая была вызвана неявным «выходом» в конце любого сценария bash. Если вы делаете что-то подобное и действительно нуждаетесь в настройках в /etc/profile скрипт, то я могу только предложить вам скопировать содержимое скрипта в вас //STDENV данные.

После этого появилась новая ошибка:

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

Это было показано в edit (3) выше. Оказалось, что это проблема с разрешениями. В задании по настройке разрешений RACF в SYSTSIN DD есть следующее:

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

Это указывает точку монтирования для файловой системы ZFS, содержащей jar-файлы, используемые JDBCUSR, при запуске задачи. Соответствующее задание монтирования было выполнено пользователем с правами администратора. Соответствующие этапы работы:

//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')        

Сложность здесь заключалась в том, что владелец и права на /u/zfs4fb настроены на разрешение доступа JDBCUSR, однако пакеты внутри по-прежнему принадлежат пользователю, выполняющему задание. Мы изменили доступ для чтения / записи к содержимому прямо в OMVS. Это устранило проблему. Чтобы исправить это в сценарии, необходимо изменить порядок шагов задания. В этом случае, поместив 2 //SHELCMD шаги с chmod и chown команды после //MOUNT шаг исправляет проблему

С нашей задачей были другие проблемы. При инициализации сервера свойство user.dir используется. Я не уверен, где именно, но, похоже, это связано с JVM для z / OS. Потребовалось немного повозиться, так как мы не могли определить, откуда берется значение. При запуске как задание, отправленное пользователем с правами администратора (IBMUSER), значение было "/ u / ibmuser". Однако при запуске в качестве запущенной задачи значение было «.», Что вызывало ошибку:

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

Исправление заключалось в размещении команды cd /u/zfs4fb в конце //STDENV сценарий окружения. Фактически это может быть любой каталог, для которого пользователь STC (в данном случае JDBCUSR) имеет разрешение на чтение.

Надеюсь, этот тур по открытиям поможет кому-то еще, пытающемуся решить подобные проблемы.