You've probably seen this type of commercial many times on television: a frazzled individual vents his or her frustration over the difficulty of accomplishing some task, and finally cries out, "There must be a better way!" At which point the announcer chimes in, with a smooth and confident voice, "There is!" And then you get the product pitch (and it all concludes with the smiling, nodding approval of the formerly rattled, now happy-in-accomplishment user of the promoted product or service).
OK, now imagine you're a security administrator. You've got end users who log into an application server using their network IDs. An application running in that server accesses DB2 for z/OS data via TCP/IP connections (from a DB2 perspective, it is a DRDA requester). In connecting to DB2, the application utilizes a particular ID and password. You had a DBA create a DB2 role and a trusted context to prevent misuse of the application's security credentials, but still you were confronted with a seemingly vexing challenge: for audit purposes, and for purposes of granting DB2 privileges in a more fine-grained fashion versus having all of the application's users exercise the privileges granted to the application's DB2 authorization ID, you want to use RACF IDs to represent application users on the mainframe system. For several reasons, however, the RACF IDs that you use are different in form from the network IDs that the end users utilize for client-side authentication. The users have already done their authentication duty, and you don't want them to have to be concerned with the RACF IDs with which you want to associate their DB2 data access activities; furthermore, you don't want to have to define a different RACF ID for each and every individual application user -- you want the flexibility to assign a particular subset of the users to a single RACF ID.
What to do? Define a different RACF ID for each of the application's users? Ask each user to keep track of, and to use as appropriate, a RACF ID (and password) in addition to his or her network ID? ISN'T THERE A BETTER WAY?!?
Yes, there is. It's called enterprise identity mapping, and it's a capability that you can use with DB2 10 for z/OS. Truth be told, enterprise identity mapping (EIM) could be used in a DB2 9 system, but getting it set up in that environment was a pretty complex undertaking. With DB2 10 (and with some operating system enhancements initially delivered with z/OS 1.11), exploitation of EIM functionality got much easier. In this blog entry, I'll provide a high-level overview of the steps associated with EIM implementation in a DB2 10 setting. More detailed information can be found in the IBM "redbook" titled DB2 10 for z/OS Technical Overview (see section 10.6.2, "z/OS Security Server identity propagation"), and in the DB2 10 for z/OS Managing Security manual (see the information under the heading, "Implementing DB2 support for distributed identity filters"). Basically, there are three parts to this whole.
The RACF part
The key step here is use of the RACMAP command to associate a distributed user identity with a RACF ID. Mike Kearney, a colleague of mine who's a z/OS security expert, leads workshops that cover, among other things, enterprise identity mapping. Mike uses a command like the one following to illustrate the use of RACMAP for EIM (I've changed some of the resource names around):
RACMAP ID(USER1) MAP USERDIDFILTER(name('cn=rsmith,ou=users,o=DSC'))
In this example, 'USER1' is a RACF ID to which you want a distributed user identity to map, 'rsmith' is the distributed user identity of interest, and 'dg27.dallas.ibm.com:437' identifies the registry in which the distributed user name is defined. Note that I could have used a wild card character (an asterisk, or '*') instead of the specific distributed user identity 'rsmith' in the "name" part of the USERDIDFILTER portion of the command, and that's where the flexibility of this approach comes in: had I done that, the RACMAP command above would have enabled RACF to map any distributed user identity defined in the registry 'dg27.dallas.ibm.com:437' to RACF ID 'USER1'; so, I can do 1-to-1 mapping of distributed user identities to RACF IDs, or I can do a many-to-1 mapping, with all distributed user identities defined in a particular registry mapping to a single RACF ID. Use 1-to-1 or many-to-1 mapping, or both, depending on your particular needs.
The DB2 part
As it pertains to DB2 for z/OS, RACF distributed user identity mapping is supported in relation to a DB2 trusted context. That trusted context would define the circumstances in which the privileges granted to a role could be exercised by a user. So, suppose I want a user (or a set of users, referring to the many-to-1 mapping mentioned above) to have the privileges granted to a role, called APPL1_ROLE, when accessing the DB2 database via an application that connects to the DB2 subsystem using the authorization ID 'APPL1SYS', from an application server at IP address 184.108.40.206. Further, I want the end user ID of the person using the application (i.e., the network ID used by that person to authenticate on the client side) to map to RACF user ID 'USER1' (referring to the example in "The RACF part" of this blog entry, above). In that case, my CREATE TRUSTED CONTEXT statement would look something like this:
CREATE TRUSTED CONTEXT APPL1_TRUST
BASED UPON CONNECTION USING SYSTEM AUTHID APPL1SYS
ATTRIBUTES (ADDRESS ‘220.127.116.11’)
WITH USE FOR USER1 ROLE APPL1_ROLE;
The application part
For a client application to do its part in EIM, it needs to 1) get a trusted context-based connection to the DB2 for z/OS server, and 2) request an authorization ID switch for that trusted context-based connection (in doing that, the application passes to DB2 the distributed user identity and the name of the associated registry). These actions can be accomplished by way of the IBM WebSphere Application Server, if the application executes in that environment. If some other application server that does not provide this functionality is being used, the required actions can still be accomplished by way of APIs for Java, CLI/ODBC, and NET. These APIs support establishing a trusted connection and switching a distributed user identity for such a connection. Here is a link to information about the JDBC APIs for trusted context-based connection creation and distributed user identity switching, in the DB2 10 for z/OS Information Center on the Web:
And here is a link to information on the CLI/ODBC function used to establish a trusted connection:
And a link to the CLI/ODBC function used to switch user identities on a trusted connection:
Flexibility without complicating things for end-users
Put it all together, and you have a flexible and powerful means of mapping distributed user identities to RACF IDs, with no requirement for application end users to do anything different than what they're doing today. That's a better way.