The Open Server application can also act as a gateway between the client and another server, but the gateway application uses the delegated client credentials when establishing the security session with the remote server. A client can delegate only its own credentials.
The client needs to request the CS_SEC_DELEGATION service so that the Open Server application can obtain the delegated credentials once the security session is established.
As in “Simple application using a security session”, the security session between the client and the gateway Open Server application is established, except for the final login acknowledgment.
In the connection handler, the gateway application:
Retrieves the delegated credentials using srv_thread_props(CS_GET, SRV_T_SEC_DELEGCRED).
Using ct_con_props(CS_SET, CS_SEC_CREDENTIALS), sets the delegated credentials in the Client-Library connection structure for use in connecting to the remote server.
Attempts to connect to the remote server using ct_connect.
Sends a srv_senddone(SRV_DONE_FINAL), to acknowledge the client’s login.
An example connection handler follows:
CS_RETCODE CS_PUBLIC connect_handler(spp)
SRV_PROC *spp;
{
CS_CONNECTION *conn; /* Connection handle */
CS_VOID *creds; /* security credentials */
CS_BOOL trueval = CS_TRUE;
CS_BOOL boolval;
CS_CHAR mechanismname[MAX_NAMESIZE];
CS_CHAR username[MAX_NAMESIZE];
CS_INT outlen;
......
allocate and set user data in spp
......
/* Allocate a connection handle for the connection attempt. */
if (ct_con_alloc(Context, &(userdata->conn)) == CS_FAIL)
{
return(CS_FAIL);
}
......
conn = userdata->conn;
/*
** Initiate security session based login to the target server
*/
/* Retrieve the client user name */
if (srv_thread_props(spp, CS_GET, SRV_T_USER,
(CS_VOID *)username, MAX_NAMESIZE, &outlen) == CS_FAIL)
{
handle failure... }
/*
** Set the client’s security principal name to connect to the
** target server
*/
if (ct_con_props(conn, CS_SET, CS_USERNAME,
(CS_VOID *)username, outlen, (CS_INT *)NULL) == CS_FAIL)
{
handle failure... }
/* Retrieve and set the security mechanism */
if (srv_thread_props(spp, CS_GET, SRV_T_SEC_MECHANISM,
(CS_VOID *)mechanismname, MAX_NAMESIZE, &outlen)
== CS_FAIL)
{
handle failure... }
if (ct_con_props(conn, CS_SET, CS_SEC_MECHANISM,
(CS_VOID *)mechanismname, outlen, (CS_INT *)NULL)
== CS_FAIL)
{
handle failure... }
/*
** Set security service-network authentication. Alternatively
** retrieve services from the current thread and set it.
*/
if (ct_con_props(conn, CS_SET, CS_SEC_NETWORKAUTH,
(CS_VOID *)&trueval, CS_SIZEOF(CS_BOOL), (CS_INT *)NULL)
== CS_FAIL)
{
handle failure... }
set other security services if needed...
/* Ensure that the client enabled security delegation */
if (srv_thread_props(spp, CS_GET, SRV_T_SEC_DELEGATION,
(CS_VOID *)&boolval, CS_SIZEOF(CS_BOOL), (CS_INT *)NULL)
== CS_FAIL)
{
handle failure...
}
if (boolval != CS_TRUE)
{
/* delegation not handled on this dialog */
handle failure... }
/* Retrieve the delegated credentials */
if (srv_thread_props(spp, CS_GET, SRV_T_SEC_DELEGCRED,
(CS_VOID *)&creds, CS_SIZEOF(CS_VOID*), (CS_INT *)NULL)
== CS_FAIL)
{
handle failure...
}
/*
** Set the delegated credentials to authenticate to the target
** server.
*/
if (ct_con_props(conn, CS_SET, CS_SEC_CREDENTIALS,
(CS_VOID *)&creds, CS_SIZEOF(CS_VOID *), (CS_INT *)NULL)
== CS_FAIL)
{
handle failure... }
get and set the user’s application name and response capabilities...
set the locale and other properties...
/* Attempt a connection to the remote server */
if (ct_connect(conn, Servername, CS_NULLTERM) == CS_FAIL)
{
handle failure... }
Get and set the REQUEST capabilities...
Get and set the RESPONSE capabilities...
......
/*
** You do not need to test this srv_senddone’s return value
** since Open Server will kill this thread if this call fails.
*/
(CS_VOID)srv_senddone(spp, SRV_DONE_FINAL, CS_TRAN_UNDEFINED,
(CS_INT)0);
return(CS_SUCCEED);
}