![]() |
Kerberos Login Principal Translation Plugin API |
This documentation applies to Mac OS X 10.2 and later.
A principal translation plugin provides realm-specific principal translation. For example, if a realm allows the users to type their full names into the Kerberos Login dialog and looks up their Kerberos principals in an outside database (such as the Dartmouth Name Directory), then the administrators of that realm can provide a plugin to perform the translation.
Principal translation plugins are invoked by the Kerberos Login API whenever a string needs to be converted to a Kerberos principal. For example, the translation is applied to the name, instance, and realm entered by the user into the Kerberos Login dialog.
In order to activate a principal translation plugin for a realm, the realm stanza in the edu.mit.Kerberos
file has to include a principal_translation
line:
REALM.NOWHERE.EDU = {
...
principal_translation = "PluginName"
}
On that line, PluginName
, should be a unique string describing the plugin. The string must not be longer than 127 characters, and must end in ".principalTranslator
".
The plugin file itself has to be located in the directory /Library/Kerberos Plug-Ins/
(note space and hyphen) - you may have to create this directory if it doesn't already exist.
A principal translation plugin must be a Mach-O bundle with a name ending in ".principalTranslator
".
The plugin must export three functions, which are detailed in the next section.
The plugin can contain any other code, data, or resources, but be mindful that it can be executed by arbitrary applications, and therefore should be careful not to affect the application's resources or resource handling.
All three of these functions must be exported by every principal translation plugin. All functions use C linkage and standard Mach-O calling conventions.
The functions and related type declarations are specified in the /System/Library/Frameworks/Kerberos.framework/Headers/KLPrincipalTranslation.h
header file.
OSErr KerberosLoginPrincipalTranslation_InitializePlugin (
KLPT_APIVersion inAPIVersion);
This function is called by the Kerberos Login API when the plugin is loaded. The function must return noErr
only if the plugin understands the API version passed in inAPIVersion
; otherwise, it should return paramErr
.
If this function returns anything but noErr
, the other functions will not be called.
For example, a plugin which only understands the version 1 of the API (which is the current version), would do this:
KLStatus KerberosLoginPrincipalTranslation_InitializePlugin (
KLPT_APIVersion inAPIVersion)
{
if (inAPIVersion == kKLPT_APIVersion1) {
return noErr;
} else {
return paramErr;
}
}
KLStatus KerberosLoginPrincipalTranslation_TranslatePrincipal (
const char* inName,
const char* inInstance,
const char* inRealm,
const char** outName,
const char** outInstance,
const char** outRealm,
KLBoolean* outChanged);
This function performs principal translation. On input, inName
, inInstance
, and inRealm
point to the components of the untranslated principal as C strings.
The function translates the principal components, and returns the translated components as newly allocated C strings in *outName
, *outInstance
, *outRealm
. The memory for the translated components is allocated by this function.
The translation function must satisfy the following two constraints:
This property is also known as idempotency. When you are debugging your plugin, you should test it very carefully to make sure it behaves this way.
If the principal translation is successful, the function sets *outChanged
to true, and returns noErr
.
In case no translation is necessary, the function may return false in *outChanged
, in which case the values returned in *outName
, *outInstance
, *outRealm
will be ignored by the Kerberos Login library. The function is not obligated to take this shortcut -- it can also just copy the old components into new memory. It must not, however, just return pointers to the input components in the output components without allocating memory for them.
If the functions fails to perform the translation, it should return an appropriate error code and leave all outputs unchanged. For more information on error handling in principal translation plugins and reporting error messages to the user, see the error handling section below.
If an error occurs, the function should clean up after itself and leave all output components unchanged.
For example, a plugin which removes trailing letters 'x' from a principal would work like this:
OSErr KerberosLoginPrincipalTranslation_TranslatePrincipal (
const char* inName,
const char* inInstance,
const char* inRealm,
const char** outName,
const char** outInstance,
const char** outRealm,
KLBoolean* outChanged)
{
*outChanged = false;
OSErr err = noErr;
UInt32 nameLength = strlen (inName);
UInt32 instanceLength = strlen (inInstance);
UInt32 realmLength = strlen (inRealm);
char* newName = NewPtr (nameLength + 1);
char* newInstance = NewPtr (instanceLength + 1);
char* newRealm = NewPtr (realmLength + 1);
if ((newName == nil) || (newInstance == nil) || (newRealm == nil)) {
err = memFullErr;
}
if (err == noErr) {
strcpy (newName, inName);
strcpy (newInstance, inInstance);
strcpy (newRealm, inRealm);
// Remove trailing 'x'
for (UInt32 i = 0; i < nameLength; i++) {
if (newName [nameLength - i - 1] == 'x') {
newName [nameLength - i - 1] = '\0';
} else {
break;
}
}
*outName = newName;
*outInstance = inInstance;
*outRealm = inRealm;
*outChanged = true;
} else {
if (newName != nil) {
DisposePtr (newName);
}
if (newInstance != nil) {
DisposePtr (newInstance);
}
if (newRealm != nil) {
DisposePtr (newRealm);
}
}
return err;
}
void KerberosLoginPrincipalTranslation_ReleasePrincipal (
const char* inName,
const char* inPrincipal,
const char* inRealm);
This function is called by the Kerberos Login API to release the memory allocated by the principal translation function. It is only called if the principal translation function returned noErr
.
For example, the plugin example above, which allocated all three components with NewPtr()
would release them like this:
void KerberosLoginPrincipalTranslation_ReleasePrincipal (
char* inName,
char* inInstance,
char* inRealm)
{
DisposePtr (inName);
DisposePtr (inInstance);
DisposePtr (inRealm);
}
KerberosLoginPrincipalTranslation_TranslatePrincipal()
is allowed to return private error codes. This error code will be propagated to the caller of the Kerberos Login API, which in turn calls KLGetErrorString()
to translate the error into a message for the user. The private error codes must not conflict with any existing Mac OS error codes.
In order to allow the Kerberos Login API to translate the plugin's error codes into user messages, the plugin should register its errors with the KerberosErrors API. After that, errors returned by the plugin will be mapped to the strings in the plugin's error table.