blob: 065745782773c226bd5332c276d06a28f06c7171 [file] [log] [blame]
/*
* Copyright (c) 2006 Dell, Inc.
* by Praveen K Paladugu <praveen_paladugu@dell.com>
* Licensed under the GNU General Public license, version 2.
*/
#include "wsman_config.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-client-api.h"
#include "wsman-xml-serializer.h"
#include <wsman-client-transport.h>
#include <wsman-debug.h>
#include "wsman-soap-envelope.h"
#include "wsman-soap-message.h"
#include "wsman-dispatcher.h"
#include "redirect.h"
WsXmlDocH redirect_generate_fault( WsXmlDocH in_doc, WsManClient *cl);
char* redirect_fault_msg (char * last_error_string);
//DEBUG
static void xml_print( WsXmlDocH doc);
int Redirect_transfer_action ( SoapOpH op,
void* appData,
void *opaqueData)
{
//Same function to be called for Get, Put, Create, Delete Actions
WsmanMessage *msg = wsman_get_msg_from_op(op);
SoapH soap = soap_get_op_soap(op);
WsXmlDocH in_doc = soap_get_op_doc(op, 1);
WsContextH cntx = ws_create_ep_context(soap, in_doc);
WsManClient *cl=NULL;
WsXmlDocH response=NULL;
debug ("Test Get Endpoint Called");
cl = setup_redirect_client(cntx, msg->auth_data.username, msg->auth_data.password );
wsman_send_request(cl,cntx->indoc);
if (wsmc_get_last_error(cl) != WS_LASTERR_OK ){
//CURL/ HTTP errors
soap_set_op_doc(op,
redirect_generate_fault( cntx->indoc , cl),
0);
return 1;
}
response = wsmc_build_envelope_from_response(cl);
soap_set_op_doc(op,
ws_xml_duplicate_doc(response), 0);
wsmc_release(cl);
return 0;
}
int Redirect_Get_EP( SoapOpH op,
void* appData,
void *opaqueData)
{
return Redirect_transfer_action(op,appData, opaqueData);
}
int Redirect_Create_EP( SoapOpH op,
void* appData,
void *opaqueData)
{
return Redirect_transfer_action(op,appData, opaqueData);
}
int Redirect_Delete_EP( SoapOpH op,
void* appData,
void *opaqueData)
{
return Redirect_transfer_action(op,appData, opaqueData);
}
int Redirect_Put_EP( SoapOpH op,
void* appData,
void *opaqueData)
{
return Redirect_transfer_action(op,appData, opaqueData);
}
int Redirect_Enumerate_EP(WsContextH cntx,
WsEnumerateInfo* enumInfo,
WsmanStatus *status, void *opaqueData)
{
WsXmlNodeH r_header=NULL, r_node=NULL, r_body=NULL, r_opt=NULL;
WsXmlDocH r_response=NULL;
char *resource_uri, *remote_enumContext=NULL;
int op;
WsManClient *cl=NULL;
//The redirected Enumeration request must have RequestTotalItemsCountEstimate enabled
r_header = ws_xml_get_soap_header(cntx->indoc);
if ( (r_node = ws_xml_get_child(r_header,0,XML_NS_WS_MAN, WSM_REQUEST_TOTAL )) == NULL )
ws_xml_add_child(r_header, XML_NS_WS_MAN, WSM_REQUEST_TOTAL, NULL);
cl = setup_redirect_client(cntx, enumInfo->auth_data.username, enumInfo->auth_data.password);
//Set the enumInfo flags based on the indoc. This is required while handling the response in wsenum_eunmerate_stub
r_body=ws_xml_get_soap_body(cntx->indoc);
if ( ( r_node = ws_xml_get_child(r_body ,0, XML_NS_ENUMERATION, WSENUM_ENUMERATE )) != NULL )
{
if ( (r_opt = ws_xml_get_child(r_node,0,XML_NS_WS_MAN,WSM_OPTIMIZE_ENUM )) != NULL )
enumInfo->flags |= WSMAN_ENUMINFO_OPT ;
}
wsman_send_request(cl,cntx->indoc);
if (wsmc_get_last_error(cl) != WS_LASTERR_OK ){
//CURL or HTTP errors
enumInfo->pullResultPtr = NULL;
status->fault_code = WSMAN_INTERNAL_ERROR;
status->fault_detail_code = 0;
status->fault_msg = redirect_fault_msg( wsman_transport_get_last_error_string( wsmc_get_last_error(cl) ) );
return 1;
}
r_response = wsmc_build_envelope_from_response(cl);
if ( wsman_is_fault_envelope(r_response)){
enumInfo->pullResultPtr = NULL;
wsman_get_fault_status_from_doc(r_response, status);
return 1;
}
//Get the Estimated Total No.of Items from the response.
r_header=ws_xml_get_soap_header(r_response);
r_node=ws_xml_get_child(r_header,0,XML_NS_WS_MAN, WSM_TOTAL_ESTIMATE );
enumInfo->totalItems=(!r_node) ? 0: atoi(ws_xml_get_node_text(r_node));
//Get the remote context
remote_enumContext = wsmc_get_enum_context(r_response);
//Set the pullResultPtr only if some Enum Items are returned, in optimized mode.
r_body= ws_xml_get_soap_body(r_response);
if ( (r_node = ws_xml_get_child(r_body,0,XML_NS_ENUMERATION, WSENUM_ENUMERATE_RESP )) != NULL &&
( ws_xml_get_child(r_node,0,XML_NS_WS_MAN,WSENUM_ITEMS) != NULL) )
{
enumInfo->pullResultPtr = r_response;
if( strlen(remote_enumContext) != 0 )
strncpy(enumInfo->enumId, remote_enumContext, strlen(remote_enumContext)+1);
else // If all the instances are returned, the context will be NULL
enumInfo->enumId[0]='\0';
}
else{
//If not items are returned, set the context and return.
strncpy(enumInfo->enumId, remote_enumContext, strlen(remote_enumContext)+1);
ws_xml_destroy_doc(r_response);
}
wsmc_release(cl);
if (remote_enumContext != NULL)
free(remote_enumContext);
return 0;
}
int Redirect_Release_EP(WsContextH cntx,
WsEnumerateInfo* enumInfo,
WsmanStatus *status, void *opaqueData)
{
WsManClient *cl=NULL;
WsXmlDocH response=NULL;
cl = setup_redirect_client(cntx, enumInfo->auth_data.username, enumInfo->auth_data.password);
wsman_send_request(cl,cntx->indoc);
if (wsmc_get_last_error(cl) != WS_LASTERR_OK ){
//just return for now, as the release_stub is not handling the status codes.
return 1;
}
response=wsmc_build_envelope_from_response(cl);
//The status value is not used in the release stub. So, just return, if fault or not.
return wsman_is_fault_envelope(response);
}
int Redirect_Pull_EP(WsContextH cntx, WsEnumerateInfo* enumInfo,
WsmanStatus *status, void *opaqueData)
{
WsXmlDocH doc=NULL,response=NULL;
WsManClient *cl=NULL;
int retVal=0;
cl = setup_redirect_client( cntx, enumInfo->auth_data.username, enumInfo->auth_data.password);
wsman_send_request(cl,cntx->indoc);
if (wsmc_get_last_error(cl) != WS_LASTERR_OK ){
//CURL or HTTP errors
enumInfo->pullResultPtr = NULL;
status->fault_code = WSMAN_INTERNAL_ERROR;
status->fault_detail_code = 0;
status->fault_msg = redirect_fault_msg( wsman_transport_get_last_error_string( wsmc_get_last_error(cl) ) );
return 1;
}
response = wsmc_build_envelope_from_response(cl);
if ( ! wsman_is_fault_envelope(response) )
enumInfo->pullResultPtr = response;
else{
//If there a fault, return the status code.
enumInfo->pullResultPtr = NULL;
wsman_get_fault_status_from_doc (response, status);
retVal=1;
}
wsmc_release(cl);
return retVal;
}
int Redirect_Custom_EP( SoapOpH op,
void* appData,
void *opaqueData )
{
//By passing the stubs. Called from process_inbound_operation
//Fix the wsa:To element in the forwarded request?? Nothing is verifying the URL in this element anyway.
return Redirect_transfer_action(op,appData, opaqueData);
}
static void xml_print( WsXmlDocH doc)
{
ws_xml_dump_node_tree(stdout, ws_xml_get_doc_root(doc));
return;
}
WsXmlDocH redirect_generate_fault( WsXmlDocH in_doc, WsManClient *cl)
{
WS_LASTERR_Code last_error =wsmc_get_last_error(cl);
char *last_error_string = wsman_transport_get_last_error_string(last_error);
return wsman_generate_fault(in_doc, WSMAN_INTERNAL_ERROR, 0,
redirect_fault_msg(last_error_string) );
}
char* redirect_fault_msg (char * last_error_string)
{
char *prepend_string = "Redirect Plugin: ";
char* fault_msg =calloc(1,strlen(prepend_string)+strlen(last_error_string)+2);
strncpy(fault_msg, prepend_string, strlen(prepend_string));
strncat(fault_msg, last_error_string, strlen(last_error_string));
return fault_msg;
}