Запущенная задача в 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 Batch Launcher Версия: 2.4.4 2013-05-07
JVMJZBL1002N (C) Copyright IBM Corp. 2005, 2012
JVMJZBL1009E Процесс дочерней оболочки завершен без среды печати; //STDENV не должен содержать 'exit' JVMJZBL1042E Сбой пакетного запуска JZOS, код возврата =101
Изучив это и прочитав то, что говорилось в документации службы поддержки IBM, я и мои коллеги были в замешательстве. Затем я попытался запустить сервер как прямую работу. Пользователь для работы имел привилегии системного администратора. Это работает, и мы можем проверить сервер JDBC. Попытка запустить задание с пользователем для процедуры приводит к той же ошибке, как показано выше.
Очевидно, что JDBCUSR не хватает той или иной привилегии. Чтобы запустить сервер как запущенную задачу, мне нужно знать, каких привилегий не хватает. Мы, конечно же, не хотим предоставлять пользователю системного администратора права запускаемой задачи.
Есть ли способ узнать, чего не хватает? Это очень расстраивает.
Изменить 11.10.2016
Следующий JCL - это JOB, который работает, когда <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
Это еще не решение, но мне удалось локализовать проблему. Запущенная процедура работает, если ей присвоен атрибут TRUSTED. Это фактически означает, что запущенная задача рассматривается как "суперпользователь" в 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()
Почему мы получаем эту ошибку во время выполнения, неясно. На этом этапе это больше не выглядит как проблема с разрешениями.
1 ответ
Наконец-то у меня было время вернуться к этой проблеме. Первоначальная проблема была довольно неясной. После просмотра нескольких форумов стало ясно, что в члене ACHIM.JDBCSRV.CNTL(SRVENV) произошла ошибка. Содержит строку:
. /etc/profile
Удаление этого исправило первую ошибку, которая была вызвана неявным "выходом" в конце любого скрипта bash. Если вы делаете что-то похожее и действительно требуете настройки в /etc/profile
сценарий, тогда я могу только предложить вам скопировать содержимое сценария в вас //STDENV
данные.
После этого появилась новая ошибка:
java.lang.NoClassDefFoundError: de.ubs.du.jdbcserver.Server
Это было показано в правке (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) имеет разрешение на чтение.
Надеюсь, что этот тур открытий поможет кому-то еще попытаться смириться с подобными проблемами.