LAPI 9.7.0 - LL_SessionAllocFromCookieEx returns unuseable session
Hi there. I think, I found a bug in LAPI 9.7, would be glad if you could verify it.Thanks and regards,Kurt GabathulerOpentext, BaselProblem:LL_SessionAllocFromCookieEx succeedes, but LAPI function calls using the session fail returning "Invalid username/password specified. This only happens in combination with LAPI 9.7.0. The same code works fine with LAPI 9.6.0. Direct and HTTP connections show the same behaviour.Test Environment:C++ LAPI 9.7.0, verified on Windows and Linux Redhat ES 4LES 9.7.0 running on Windows.Test Case Code (can be also found in the attachment):// 1) Create session using LL_SessionAllocEx// 2) LL_GetCurrentUserID succeedes// 3) Look for "llcookie" within cookie list returned by LL_GetCookieInfo// 4) free the session// 5) recreate session using LL_SessionAllocFromCookieEx and the "llcookie" string// 6) LL_GetCurrentUserID fails#include #include #include #include "lapi.h"#include "lapi_users.h"const char* cHost = "myserver";long nPort = 2099;const char* cUser = "admin";const char* cPass = "livelink";int main(){ LLSTATUS status = LL_OK; LLSESSION llSession = NULL; LLVALUE llCookieList = 0; long nCookieList = 0; LLVALUE llCookie = 0; const char* cCookieName = NULL; const char* cCookieValue = NULL; long nUserId = 0; // Initialize LAPI status = LL_Initialize( LL_HEADER_VERSION ); if ( status == LL_OK ) { printf( "\nInitialized LAPI\n" ); } // Connect To Livelink if ( status == LL_OK ) { status = LL_SessionAllocEx( &llSession, cHost, nPort, "", cUser, cPass, NULL); } if ( status == LL_OK ) { printf( "Connected to Livelink\n\n" ); } // Test LAPI Function Call Using The Session if( status == LL_OK ) { nUserId = 0; status = LL_GetCurrentUserID( llSession, &nUserId ); if( status == LL_OK ) { printf("Current User ID: %d\n\n", nUserId); } else { printf("GetCurrentUserID failed\n\n", nUserId); } } // Get Cookie Info if ( status == LL_OK ) { status = LL_ValueAlloc( &llCookieList ); } if ( status == LL_OK ) { status = LL_GetCookieInfo( llSession, llCookieList ); } // Get Number Of Cookies Returned if ( status == LL_OK ) { status = LL_ValueGetWidth( llCookieList, &nCookieList ); } // Find LLCookie if ( status == LL_OK ) { printf( "GetCookieInfo returned %d Cookies\n\n", nCookieList ); for ( int i = 0; i < nCookieList; ++i ) { if ( status == LL_OK ) { LL_ValueAlloc( &llCookie ); } if ( status == LL_OK ) { status = LL_ListGetValue( llCookieList, i, llCookie ); } if ( status == LL_OK ) { status = LL_AssocGetStringPtr( llCookie, "Name", &cCookieName ); } if ( status == LL_OK ) { if ( strcmp( cCookieName, "llcookie" ) == 0 ) { status = LL_AssocGetStringPtr( llCookie, "Value", &cCookieValue ); printf( "LLCookie = '%s'\n\n", cCookieValue ); } } if ( status == LL_OK ) { LL_ValueFree( llCookie ); llCookie = NULL; } } if( status == LL_OK && cCookieValue == NULL ) { printf( "LLCookie not found...\n\n" ); } } // Free The Session if ( status == LL_OK ) { status = LL_SessionFree( llSession ); llSession = 0; } if( status == LL_OK ) { printf( "Session Freed\n\n" ); } // Create Session Again Using The LLCookie String We Found Before if( status == LL_OK && cCookieValue ) { status = LL_SessionAllocFromCookieEx( &llSession, cHost, nPort, cCookieValue, NULL ); if( status == LL_OK ) { printf( "Connected to Livelink again using the previous LLCookie value\n\n" ); } else { printf( "LL_SessionAllocFromCookieEx Failed...\n\n" ); } } // Test LAPI Function Call Using The Session if( status == LL_OK ) { nUserId = 0; status = LL_GetCurrentUserID( llSession, &nUserId ); if( status == LL_OK ) { printf("Current User ID: %d\n\n", nUserId); } else { printf("GetCurrentUserID failed\n\n", nUserId); } } // Error Output if ( status != LL_OK ) { printf( "Status=%li (%#lx)\n", status, status ); if ( llSession != NULL ) { char buf1[256]; char buf2[256]; char buf3[256]; LLLONG stat = LL_OK; LLLONG siz = 0; LLVALUE message = NULL; LLVALUE errMsg = NULL; LLVALUE apiError = NULL; LLSTATUS status2 = LL_OK; LL_ValueAlloc( &message ); LL_ValueAlloc( &errMsg ); LL_ValueAlloc( &apiError ); LL_GetErrorMsg( llSession, &stat, message, errMsg, apiError ); printf( "Session failure status is %li (%#lx)\n", stat, stat ); status2 = LL_ValueIsDefined( message ); if ( status2 == LL_OK ) LL_ValueGetString( message, buf1, sizeof( buf1 ), &siz ); else buf1[0] = '\0'; status2 = LL_ValueIsDefined( errMsg ); if ( status2 == LL_OK ) LL_ValueGetString( errMsg, buf2, sizeof( buf2 ), &siz ); else buf2[0] = '\0'; status2 = LL_ValueIsDefined( apiError ); if ( status2 == LL_OK ) LL_ValueGetString( apiError, buf3, sizeof( buf3 ), &siz ); else buf3[0] = '\0'; if ( buf1[0] != '\0' || buf2[0] != '\0' || buf3[0] != '\0' ) { printf( "Message=%s\nerrMsg=%s\napiError=%s\n", buf1, buf2, buf3 ); } LL_ValueFree( message ); LL_ValueFree( errMsg ); LL_ValueFree( apiError ); } } if ( llCookieList ) { LL_ValueFree( llCookieList ); llCookieList = NULL; } // Free the session if ( llSession ) { LL_SessionFree( llSession ); llSession = NULL; } // Uninitialize LAPI LL_Uninitialize(); printf( "\nEnd of sample\n\n" ); return status;}