A C/C ++ application calls the SAF user mapping plug-in interface
to retrieve the local z/OS® identity
for a user who was authenticated on a different platform. The interface
consists of three services that perform the following functions:
- Initialize the connection with the plug-in implementation. This
function is invoked once.
- Search in a repository of user ID mappings for a mapping between
the source user credential and the local SAF user credentials. This
function is invoked as many times as needed.
- Close the connection with the plug-in implementation. This function
is invoked once.
The following diagram illustrates the interactions between a C/C++
application, the DLL (dynamic link library) of the SAF user mapping
interface, and the default plug-in implementation.
Figure 1. SAF user mapping using EIM
The following example is a fragment of a C application using the
plug-in implementation.
#pragma runopts(POSIX(ON))
#include <stdio.h>
#include <irrspim.h>
void printmErr(SafmapErr *);
int main()
{
int mRc = 0;
char * aData = NULL;
char * dllName = NULL;
int i = 0;
SafmapHandle * mh = NULL;
SafmapErr * mErr = NULL;
SafmapErr mErrData;
SafmapHandle mHandle;
SafmapResult * mResult = NULL;
char mResultData[sizeof(SafmapResult) + 8 + 1];
SafmapCreds * sUser = NULL;
SafmapCreds sUserData;
/*-- Initialize the plug-in --------------------*/
bzero((char *) &mHandle, sizeof(SafmapHandle));
mh = &mHandle
dllName = SAFMAP_DEFAULT_PLUGIN;
bzero((char *) &mErrData, sizeof(mErrData));
mErr = &mErrData
mRc = safMappingInit (mh, dllName, mErr);
if (mRc > 0) {
fprintf(stderr, "safMappingInit() failed. rc =%i\n", mRc);
printmErr(mErr);
return (-1);
}
/*-- Lookup a user mapping ---------------------*/
bzero((char *) &sUserData, sizeof(SafmapCreds));
sUser = &sUserData
sUser->credsType = SAFMAP_REGISTRY_USER;
sUser->credsCCSID = SAFMAP_DEFAULT_CCSID;
sUser->credsData.RegistryUser.registry = "My Kerberos Realm";
sUser->credsData.RegistryUser.user = "kuser";
aData = NULL;
bzero((char *) &mResultData, sizeof(mResultData));
mResult = (SafmapResult *) &mResultData
mResult->bytesAvailable =
sizeof(mResultData) - sizeof(SafmapResult) + 1;
mResult->resultCreds.credsType = SAFMAP_USER_ONLY;
bzero((char *) &mErrData, sizeof(mErrData));
mRc = safMappingLookup(mh, sUser, aData, mResult, mErr);
switch (mRc) {
case 0:
fprintf(stderr, "safMappingLookup() returned userid %s.\n",
mResult->resultCreds.credsData.UserOnly.user);
break;
case SAFMAP_WARNING:
fprintf(stderr, "safMappingLookup() returned a warning.\n");
break;
case SAFMAP_ERROR:
fprintf(stderr, "safMappingLookup() returned an error.\n");
break;
case SAFMAP_SEVERE:
fprintf(stderr, "safMappingLookup() returned a severe error.\n");
break;
}
printmErr(mErr);
if (mRc > 0)
return (-1);
/*-- Close the connection with the plug-in -----*/
bzero((char *) &mErrData, sizeof(mErrData));
mRc = safMappingTerm(mh, mErr);
if (mRc > 0) {
fprintf(stderr, "safMappingTerm() failed. rc = %i\n", mRc);
printmErr(mErr);
return (-1);
}
}
void printmErr( SafmapErr * mErr)
{
fprintf(stderr, "mErr->mpiReturnCode %i\n", mErr->mpiReturnCode);
fprintf(stderr, "mErr->mpiReasonCode %i\n", mErr->mpiReasonCode);
fprintf(stderr, "mErr->mpiVersion %s\n", mErr->mpiVersion);
fprintf(stderr, "mErr->mpiInfo %s\n", mErr->mpiInfo);
fprintf(stderr, "mErr->message %s\n", mErr->message);
return;
}
The application can be compiled from JCL or the z/OS UNIX System Services. The default
plug-in implementation requires the execution environment to be running
with POSIX(ON).
If the application that is calling the plug-in interface is in
the z/OS UNIX shell,
and POSIX is already set to ON, nothing needs to be done.
If the application is running from a batch job or TSO, POSIX must
be explicitly turned on. There are a number of methods available.
The sample code shows the use of the #pragma runopts. Another option
is to specify the runtime option as an LE (Language Environment®) parameter
on the exec statement. For detailed information about how to use the
LE parameters, see z/OS Language Environment Programming Guide.