You are here
:: Home
:: Documentation
:: Miscellaneous
:: Enabling SAF Security
Enabling SAF Security
This document describes how to configure your Tomcat installation to use SAF for J2EE user
Authentication and Authorization.
These instructions require modifications to the Tomcat server.xml file. Make a backup copy
before making any changes. Note: All tomcat configuration files, including server.xml are in
codepage ISO8859-1 (ASCII). See editing ASCII files on the mainframe for
more details.
Configuring Tomcat to use SAF for user authentication and authorization is different
than running Tomcat under a Java security manager. For instructions on how to do this,
see: Tomcat and the Java SecurityManager
Note: These instructions make a distinction
between CATALINA_HOME and CATALINA_BASE. The steps will also work if CATALINA_HOME
== CATALINA_BASE.
- set the program controlled extended attribute on the JZOS shared libraries:
extattr +p libjzos*.so
Note: Your userid must be authorized to set this attribute. If you are not
authorized, your system programmer will either need to set the attribute, or grant you the
authority to do it. See the troubleshooting section below for more details.
- Program control the PDSE library that contains the JZOSVMxx modules:
RALTER PROGRAM * ADDMEM ('<JZOS_PDSE_LOADLIB>'//NOPADCHK) UACC(READ)
SETROPTS WHEN(PROGRAM) REFRESH
Also at this time, you may want to confirm that the c/c++ runtime libraries are also program
controlled. They should be, but if they were missed during installation, the SAF calls will not
work properly. See the troubleshooting section below for more details on how to do this.
- Make a backup copy of the file <CATALINA_BASE>/conf/server.xml.
- Edit server.xml and add the following listener element:
<Listener className="com.dovetail.zos.tomcat.SafLifecycleListener" />
Before this element:
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
- Just below the listener element, change the UserDatabase element to look like this:
For Tomcat 5.5.X and 6.0.X
<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="z/OS Role database"
factory="com.dovetail.zos.tomcat.SafRoleDatabaseFactory"
pathname="conf/saf-roles.xml" />
For Tomcat 5.0.X
<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="z/OS Role database.">
</Resource>
<ResourceParams name="UserDatabase">
<parameter>
<name>factory</name>
<value>com.dovetail.zos.tomcat.SafRoleDatabaseFactory</value>
</parameter>
<parameter>
<name>pathname</name>
<value>conf/saf-roles.xml</value>
</parameter>
</ResourceParams>
The resource name must remain UserDatabase in order for the
Tomcat JMX admin page to work properly - don't change it.
- Edit server.xml and comment out the active Realm element (usually UserDatabaseRealm):
<!--
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
debug="0" resourceName="UserDatabase"/>
-->
Then insert the following Realm:
<Realm className="com.dovetail.zos.tomcat.SafRealm" resourceName="UserDatabase" />
- Download the latest saf_realm.zip file for the version of Tomcat you are using from the downloads page.
- FTP this file (in binary) to z/OS and extract its contents to a temporary directory:
jar -xvf saf_realm_5.5_1.2.4.zip OR
jar -xvf saf_realm_5.0_1.2.4.zip
- Copy the extracted saf_realm.jar to the Tomcat installation:
For Tomcat 6.0.X
cp saf_realm.jar <CATALINA_HOME>/lib
For Tomcat 5.0.X and 5.5.X
cp saf_realm.jar <CATALINA_HOME>/server/lib
- Copy the extracted saf-roles.xml file to the Tomcat configuration directory:
cp saf-roles.xml <CATALINA_BASE>/conf/saf-roles.xml
- Add desired role/saf mappings to the newly copied file
<TOMCAT_HOME>/conf/saf-roles.xml. This file initially has two mappings; the "admin" and
"manager" role. In order to operate the Administration and Manager pages under tomcat, the
authenticated user must have the SAF authority described by this entry.
<?xml version='1.0' encoding='utf-8'?>
<saf-roles>
<role rolename="admin" safclass="FACILITY" safentity="BPX.SERVER" saflevel="READ"/>
<role rolename="manager" safclass="FACILITY" safentity="BPX.SERVER" saflevel="READ"/>
<saf-roles>
Tomcat 6.0.x Note: The admin webapp is no longer supplied with Tomcat, so the admin
role is not defined in the 6.0 version of saf-roles.xml.
The following table describes the role element attributes:
attribute
|
Description
|
Required
|
Default
|
rolename
|
The J2EE role to be mapped
|
Yes
|
n/a
|
safclass
|
The SAF class, e.g FACILITY, DATASET, etc...
|
No
|
EJBROLE
|
safentity
|
The SAF entity within the safclass, e.g BPX.SERVER, 'dsn',
etc...
|
Yes
|
n/a
|
saflevel
|
The SAF authority level. One of ALTER, CONTROL.
READ, UPDATE
|
No
|
READ
|
This file can be directly edited prior to starting Tomcat.
- SUBMIT the TOMCAT JCL and when started, bring up the Tomcat manager page:
http://your.domain:8080/manager/html
- Supply the desired SAF userid and password as credentials.
If everything is setup and configured correctly, the Tomcat manager page will
display. If not, check the STDOUT and STDERR
DDs for more information. The SafRealm classes will dump diagnostic info if authorization fails.
- Once Tomcat is running, roles can be added, deleted and modified via the admin
interface. To specify a mapping using the admin interface, supply the saf attributes in the
role's description field using the following format:
{safclass}/{safentity}/{saflevel} - Note that all three components are required when using the admin page
Changes are immediately written to the saf-roles.xml ile.
Tomcat 6.0.x Note: The admin webapp is no longer supplied with Tomcat, so changes to the
saf-roles.xml file should be made manually
Troubleshooting SAF security problems with SafTest
Getting Tomcat configured properly to work with SAF can be tricky. This section
contains some diagnostic information and tests that can be run to help determine where the
problem(s) exist.
SafTest
This C program performs simple SAF authentication and authorization
testing.
Usage:
SafTest userid password safClass safEntity
Description:
The program first attempts to authenticate userid with the supplied password, then attempts to
test READ level access of the safEntity in the supplied safClass. In order for the authentication
portion to succeed, the executable itself must be program controlled. To turn on program control,
the extattr command should be run:
extattr +p SafTest
Check that the program control bit was properly set by running:
ls -E SafTest
If the bit is properly set, a "p" will appear in the second position of the extended attributes list
for the program:
-rwxr-xr-x -ps- 1 GOETZE1 TEST 155648 Jul 16 13:00 SafTest
If an error occured running extattr, the current needs to be authorized to set this bit.
Have a system programmer grant this authority:
RDEFINE FACILITY BPX.FILEATTR.PROGCTL UACC(NONE)
PERMIT BPX.FILEATTR.PROGCTL CLASS(FACILITY) ID(<user_id>) ACCESS(READ)
SETROPTS RACLIST(FACILITY) REFRESH
Java version of SafTest
There is also a java version of this program which tests the java libraries as well the C
runtimes.
The class name is com.dovetail.jzos.testing.SafTest and
it should be invoked with the same arguments as the C version. It's probably best to start with
the C version, as fewer libraries are involved. Once the C version runs successfully, try invoking
the Java version from the z/OS shell. Finally, invoke the Java version from the JZOS batch
environment by modifying and submitting the RUN13 or RUN14 JCL:
...
//JAVA EXEC PROC=EXJZOSVM,
// JAVACLS='com.dovetail.jzos.testing.SafTest',
// ARGS='GOETZE1 mypass FACILITY BPX.DAEMON'
//STDENV DD *
...
Check, STDOUT, STDERR and the system log for details in case of a failure. The system log may
contain
the name of the library that failed.
Examples:
SafTest GOETZE1 mypass FACILITY BPX.DAEMON
This will try to authenticate the userid GOETZE1 with "mypass", then attempt to check READ
authority of the BPX.DAEMON entity in the SAF class FACILITY.
The program will display results according to the authority of the current user's
capabilities in combination with the userid supplied to the program.
The test must run successfully. If it doesn't, the current user probably doesn't
have the proper authority to run JZOS within SAF.
In the results that follow, ERRNO and ERRNO2 codes are displayed. For more information about
the ERRNO and ERRNO2 (errnojr) codes, see the following IBM publication:
z/OS V1R1.0 UNIX System Services Messages and Codes - SA22-7807-00 (PDF)
In this document, ERRNO is a ReturnCode and the last 4 digits of ERRNO2 is the ReasonCode
Successful execution:
Attempting to authenticate: GOETZE1
Authenticated!
Attempting to authorize: GOETZE1 for FACILITY entity= BPX.DAEMON
Authorization Check succeeded!
The program controlled bit was not properly set:
Attempting to authenticate: GOETZE2
Authentication failed. ERRNO= 157 ERRNO2= 90c02af
Attempting to authorize: GOETZE2 for FACILITY entity= BPX.DAEMON
Authorization Check failed. ERRNO= 139 ERRNO2= 93802af
Here, the 02af low order word of ERRNO2 indicates:
JREnvDirty
The specified function is not supported in an address space
where a load was done that is not program controlled.
Action: Make sure that programs being loaded from this
address space are defined as program controlled.
All of the required libraries, including the C/C++ runtime libs need to
be program controlled. Have system programmer program control the
runtime libraries (The TSO command RLIST PROGRAM * all can be used to
check the status of these libraries):
RALTER PROGRAM * ADDMEM ('<JZOS_PDSE_LOADLIB>'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('SYS1.LINKLIB'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('SYS1.CSSLIB'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('CEE.SCEERUN'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('CEE.SCEERUN2'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('CBC.SCLBDLL'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('SYS1.SEZALINK'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('DSN710.SDSNEXIT'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('DSN710.SDSNLOAD'//NOPADCHK) UACC(READ)
RALTER PROGRAM * ADDMEM ('DSN710.SDSNLOD2'//NOPADCHK) UACC(READ)
SETROPTS WHEN(PROGRAM) REFRESH
The userid being checked does not have READ level access:
Attempting to authenticate: GOETZE2
Authenticated!
Attempting to authorize: GOETZE2 for FACILITY entity= BPX.DAEMON
Authorization Check failed. ERRNO= 139 ERRNO2= 93800d9
Here, the 00d9 low order word of ERRNO2 indicates:
JRNoResourceAccess
The user specified by the caller does not have the access specified to the resource.
Action: If the user requires access to the resource, have an authorized user grant
the user access permission.
The current userid does not have BPX.SERVER READ authority:
Attempting to authenticate: GOETZE1
Authenticated!
Attempting to authorize: GOETZE1 for FACILITY entity= BPX.DAEMON
Authorization Check failed. ERRNO= 139 ERRNO2= 93800d8
Here, the 00d8 low order word of ERRNO2 indicates:
JRNotServerAuthorized
The calling address space is not permitted to the BPX.SERVER
Facility class or the BPX.SERVER Facility class is undefined
and caller not a superuser (UID=0).
Action: Permit the caller's process to the BPX.SERVER
Facility class or make the caller a superuser (UID=0).
Have a system programmer grant the current user this access:
RDEFINE FACILITY BPX.SERVER UACC(NONE)
PERMIT BPX.SERVER CLASS(FACILITY) ID(<user_id>) ACC(read)
SETROPTS RACLIST(FACILITY) REFRESH
The SAF entity is not defined, or SAF class is not active:
Attempting to authenticate: GOETZE1
Authenticated!
Attempting to authorize: GOETZE1 for EJBROLE entity= WEBAPP.USER
Authorization Check failed. ERRNO= 143 ERRNO2= 93800cf
Here, the 00cf low order word of ERRNO2 indicates:
JRSAFResourceUndefined
The resource specified by the caller is not defined to RACF.
Action: Define the specified resource to RACF or correct the
resource name and retry.
Have a system programmer activate as follows:
RDEFINE EJBROLE WEBAPP.USER UACC(NONE)
SETROPTS CLASSACT(EJBROLE)
SETROPTS WHEN(EJBROLE) REFRESH