Gateway application with separate security sessions

In the scenario shown in the code below, the Open Server application acts as a gateway between the client and another server. The network identity used to establish the security session between the client and the gateway application may be different from that used to establish the security session between the gateway and the remote server.

The gateway application completes the login security negotiation with its client, pending the final login acknowledgment, before calling the connection handler. The connection handler needs to initiate a security-session-based login to the remote server using Client-Library calls before sending a srv_senddone(SRV_DONE_FINAL) to the client to complete the login. An example connection handler follows:

CS_RETCODE CS_PUBLIC connect_handler(spp) 
 SRV_PROC *spp;
 {
    CS_CONNECTION   *conn;    /* the connection handle */
    CS_BOOL         trueval = CS_TRUE;
    CS_INT          outlen;
  ......
  allocate and set user data in spp...
  ......
  /* Allocate a connection handle */
    if (ct_con_alloc(Context, &(userdata->conn)) == CS_FAIL) 
    {
       clean up and report error...
      return(CS_FAIL);
   }
   ......
   conn = userdata->conn;
    /* 
    ** Initiate security session based login with the remote
    ** server. The user name used here may be the same as the 
    ** client user name or different 
    */
    if (ct_con_props(conn, CS_SET, CS_USERNAME, 
        (CS_VOID*)Username, STRLEN(Username), (CS_INT*)NULL)
        == CS_FAIL)
    {
       handle failure...
   }
   /* 
    ** Set the desired security mechanism(s) or use the default
    ** security mechanism.
    */
    if (ct_con_props(conn, CS_SET, CS_SEC_MECHANISM,
          (CS_VOID*)Mechanismname, STRLEN(Mechanismname), 
          (CS_INT*)NULL) == CS_FAIL)
    {
       handle failure...
   }
   /* Set the security service-network authentication */
    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 required
   get and set the user’s application name, response capabilities
   set the locale and other login properties
   /* Attempt a connection to the remote server */
    if (ct_connect(conn, Servername, CS_NULLTERM) == CS_FAIL)
    {
       cleanup...
       return(CS_FAIL);
    }
   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);
 }