This section contains the following topics:
Authorization Function Declarations
Using the Authorization API, you can implement custom access control functionality. To implement custom access control functionality, you must:
The shared library must contain one or more functions defined as exportable symbols. SmApi.h defines all of the data structures necessary to create custom policy, rule, and response plug-ins.
For example, you might define an active policy that returns true if the user belongs to a particular organizational unit (ou) in an LDAP directory as defined in the parameter (param) field of the active policy expression.
For example, you might define an active response that returns a user’s common name (cn) if the user belongs to the ou specified in the param field of the active response expression.
For example, you might define an active rule that returns true if a user is a member of a group, such as Directory Administrator, that has permission to view a realm.
When extending the authorization API, include the SmApi.h header file:
#include "SmApi.h"
An active expression is a string of variable definitions that comprises an active policy, rule, or response. Active expressions are constructed in the Administrative UI using the following syntax:
<@ lib=<lib-spec> func=<func-spec> param=<func-params>@>
In the syntax example:
If you place the library in the default location, you need only specify the library file name rather than a path. Also, the extension .dll or .so is optional.
SiteMinder constructs the active expression from information provided in the Active Rule Editor, Active Policy Editor, or Active Response Attribute Editor dialog box.
An active expression in an application initiates the following tasks:
The specified user-defined function in the shared library returns a result to SiteMinder in the lpszOutBuf parameter. SiteMinder interprets this result according to the type of active expression, as follows:
The policy does not fire if the result returned in lpszOutBuf matches any of the following strings (not case-sensitive): FALSE, F, or 0.
Any other result value causes the policy to fire.
Otherwise, the behavior is the same as for Active Policies.
For example, you could specify a group name in the optional param variable of the active expression, then test for the group name in the function to determine the URL to pass back.
You specify the cookie name in the SiteMinder Response Attribute Editor.
Active rules are defined in the Administrative UI using the Active Rule Editor dialog box. To access this editor from the Rule Properties dialog box, select the Active Rule tab in the Advanced group box, then click Edit.
Active responses are defined in the Administrative UI using the Response Attribute Editor dialog box.
From the Response Properties dialog box, access the editor by clicking Create and select the Active Response button in the Attribute Kind group box on the Attribute Setup tab.
Active policies are defined in the Administrative UI using the Active Policy Editor dialog box.
From the Policies Properties dialog box, access this editor by selecting the Advanced tab and clicking Edit.
You can add arbitrary custom key/value pairs to the current session to pass HTTP headers and cookies to the Policy Server. These key/value pairs are kept in the session store; they have the same lifetime as the session. The name/value pairs are stored in the Expiry Data Table in the session store database. There can be maximum 5 entries for a session. The Active Plugin code can use the UserContext structure (Sm_Api_UserContext_t* lpUserContext) to set and retrieve these name/value pairs by calling fSetProp and fGetProp respectively. To set the value, fSetProp is called with lpszPropName as SM_SESSIONVAR(<name>) and lpszValueBuf as the value. To retrieve the value, fGetProp is called with lpszPropName as SM_SESSIONVAR(<name>)/ SM_SESSIONVAR and the value/values is returned in lpszValueBuf.
Note the following:
The shared library requires proper entry points. Each entry point in the shared library represents one or more active expressions and must be defined according to the specified syntax.
Note: If you are using Microsoft Visual Studio, export the function addresses to a modular definition file (.DEF) file. To export the function addresses, create a .DEF file, and in the export section of the .DEF file, list the functions that you want to invoke from the Active Rule or Active Policy. After you have created the .DEF file, add it to the Microsoft Visual Studio project.
The Policy Server calls a user-defined function to perform a custom policy, rule, or response operation.
You can assign the function any name. Through the active expression that you define in the Administrative UI, you advise SiteMinder of the function name and the name of the shared library where the function resides.
Syntax
int SM_EXTERN <func-spec> ( const Sm_Api_Context_t* lpApiContext, const Sm_Api_UserContext_t* lpUserContext, const Sm_Api_RequestContext_t* lpReqContext, const char* lpszParam, const int nBytesOutBuf, char* lpszOutBuf, const int nBytesErrBuf, char* lpszErrBuf );
Parameter |
I/O |
Description |
---|---|---|
lpApiContext |
I |
Pointer to the API context structure. |
lpUserContext |
I |
Pointer to the user context structure. |
lpReqContext |
I |
Pointer to the request context structure. |
lpszParam |
I |
Pointer to the buffer containing the null-terminated parameter string specified in <Param-String>. |
nBytesOutBuf |
I |
Maximum size of the output result buffer (4097 bytes). |
lpszOutBuf |
O |
Output buffer for the result to send to SiteMinder. |
nBytesErrBuf |
I |
Maximum size of the output error buffer (4097 bytes). |
lpszErrBuf |
O |
Output buffer to receive error text. SiteMinder displays the error text in the debug log file. |
Returns
The Policy Server calls this function to determine the Authorization API version that the custom library is compliant with.
Syntax
int SmQueryVersion ( const Sm_Api_Context_t* lpApiContext );
Parameter |
I/O |
Description |
---|---|---|
lpApiContext |
I |
A pointer to the API context structure. |
Returns
Returns the version number of the Authorization API. Currently the version supported is Sm_Api_Version_V3. This constant is defined in SmApi.h.
This samples provided in the following sections are located in:
sdk\samples\smazapi\smazapi.cpp
The syntax that precedes each sample, such as:
<@ lib="SmAzAPI" func="activeRule" param="" @>
is an example of the Generated Script that SiteMinder constructs in the SiteMinder Active Rule Editor, Active Policy Editor, or Active Response Attribute Editor dialog box from the information you provide in the dialog box.
To build sample active expressions for UNIX, use the makefile found in
<install_path>\sdk\samples\smazapi\makefile.
The example below returns true if the user has special access permission to view the realm. If the user has directory manager privileges, the user can view the realm.
<@ lib="SmAzAPI" func="activeRule" param="" @> ************************************************************* int SM_EXTERN activeRule( const Sm_Api_Context_t* lpApiContext, // the structure that provides API context const Sm_Api_UserContext_t* lpUserContext, // the structure that provides user context const Sm_Api_RequestContext_t* lpReqContext, // the structure that provides request context const char* lpszParam, // the parameter string (null-terminated) const int nBytesOutBuf, // the maximum size of the output buffer char* lpszOutBuf, // the output buffer to hold the null-terminated result const int nBytesErrBuf, // the maximum size of the error message buffer char* lpszErrBuf) // the output buffer to hold the null-terminated error message { /* User Context is required to use the functions like fGetProp, fSetProp.. */ if(!lpUserContext->bIsUserContext) { strncpy (lpszErrBuf, "No User Context ", nBytesErrBuf); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } /* // The DN to look for the attribute "uniquemember" // If the user is listed as the member of the above attribute, // it has directory manager privileges. */ char lpszDn[] = "cn=Directory Administrators,ou=Groups,o=airius.com"; char lpszDnvalue[256]; memset(lpszDnvalue, 0, sizeof(lpszDnvalue)); /* // fGetDnProp function is used to retrieve an attribute value // in a directory entry. */ int getResult = lpUserContext->fGetDnProp( lpUserContext->lpParam, lpszDn, "uniquemember", sizeof(lpszDnvalue), lpszDnvalue); /* // If no error occurs, fGenDnProp will return the length of the // buffer lpszDnvalue. Otherwise the function returns 0. */ if(getResult > 0) { /* Check to see if the user is present in the list. */ if(strpbrk(lpszDnvalue, lpUserContext->lpszUserName) != NULL) { /* The result "true" is placed in the output buffer. */ strncpy(lpszOutBuf, "true", nBytesOutBuf); lpszOutBuf[nBytesOutBuf-1] = '\0'; return strlen(lpszOutBuf); } else { strncpy(lpszOutBuf, "false", nBytesOutBuf); lpszOutBuf[nBytesOutBuf-1] = '\0'; return strlen(lpszOutBuf); } } else { strncpy(lpszErrBuf, "Failed to get attribute value for the DN ", nBytesErrBuf); strncat( (lpszErrBuf + strlen(lpszErrBuf)), lpszDn, (nBytesErrBuf-strlen(lpszErrBuf))); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } /* everything failed.... */ return 0; }
This active response returns the common name (cn) of the user, if the user belongs to the organizational unit specified in the parameter (param) field of the active response expression.
<@ lib="SmAzAPI" func="activeResponse" param="Human Resources" @> *********************************************************** int SM_EXTERN activeResponse( const Sm_Api_Context_t* lpApiContext, /* the structure that provides API context */ const Sm_Api_UserContext_t* lpUserContext, /* the structure that provides user context */ const Sm_Api_RequestContext_t* lpReqContext, /* the structure that provides request context */ const char* lpszParam, /* the parameter string (null-terminated) */ const int nBytesOutBuf, /* the maximum size of the output buffer */ char* lpszOutBuf, /* the output buffer to hold the null-terminated attribute value */ const int nBytesErrBuf, /* the maximum size of the error message buffer */ char* lpszErrBuf) /* the output buffer to hold the null-terminated error message */ { memset(lpszOutBuf, 0, sizeof(lpszOutBuf)); if(!lpUserContext->bIsUserContext) { strncpy (lpszErrBuf, "No User Context ", nBytesErrBuf); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } /* Store all the organizational units to which the user belongs. */ char lpszOrgUnit[30]; memset(lpszOrgUnit, 0, sizeof(lpszOrgUnit)); /* store the common name of the user. */ char lpszCN[30]; memset(lpszCN, 0, sizeof(lpszCN)); /* Check to see if a parameter is requested. */ if(lpszParam == NULL || strlen(lpszParam) == 0) { strncpy (lpszErrBuf, "Organizational unit is not entered ", nBytesErrBuf); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } /* Get all the organization units to which the user belongs. */ int getResult = lpUserContext->fGetProp ( lpUserContext->lpParam, "ou", /* Attribute name */ sizeof (lpszOrgUnit), lpszOrgUnit); if (getResult < 0) { strncpy (lpszErrBuf, "Failed to get organization unit for the user's profile ", nBytesErrBuf); strncat( (lpszErrBuf + strlen(lpszErrBuf)), lpUserContext->lpszUserName, (nBytesErrBuf-strlen(lpszErrBuf))); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } else { /* Check if the user belongs to the organization unit that is requested. */ if(strstr(lpszOrgUnit, lpszParam) != NULL) { if((lpUserContext->fGetProp(lpUserContext->lpParam, "cn",sizeof(lpszCN),lpszCN)) > 0) { strncpy(lpszOutBuf, lpszCN, nBytesOutBuf); lpszOutBuf[nBytesOutBuf-1] = '\0'; return strlen(lpszOutBuf); } /* end of fGetProp */ else { strncpy (lpszErrBuf, "Failed to get user common name from user's profile attribute ", nBytesErrBuf); strncat( (lpszErrBuf + strlen(lpszErrBuf)), lpUserContext->lpszUserName, (nBytesErrBuf-strlen(lpszErrBuf))); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } } /* end of strstr */ else { strncpy (lpszErrBuf, "The user does not belong to the requested organizational unit ", nBytesErrBuf); lpszErrBuf[nBytesErrBuf-1] = '\0'; return -1; } } /* everything failed.... */ return 0; } #ifndef _WIN32 } #endif
Copyright © 2014 CA.
All rights reserved.
|
|