/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright Likewise Software
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the license, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy
* of the GNU Lesser General Public License along with this program. If
* not, see .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
#include "lwrpcrt.h"
#include
#include
#include
#include
RPC_STATUS WideChar16ToMultiByte(PWSTR input, idl_char **output)
{
if (input == NULL)
{
*output = NULL;
}
else
{
*output = (idl_char *)awc16stombs(input);
if(*output == NULL)
{
if(errno == ENOMEM)
return rpc_s_no_memory;
return rpc_s_invalid_arg;
}
}
return rpc_s_ok;
}
RPC_STATUS MultiByteToWideChar16(idl_char *input, PWSTR *output)
{
*output = ambstowc16s((char *)input);
if(*output == NULL)
{
if(errno == ENOMEM)
return rpc_s_no_memory;
return rpc_s_invalid_arg;
}
return rpc_s_ok;
}
#define CONVERT_INPUTSTR(var) \
idl_char *converted_##var = NULL; \
if(status == rpc_s_ok) \
status = WideChar16ToMultiByte((var), &converted_##var);
#define DECLARE_OUTPUTSTR(var) \
idl_char *temp_##var = NULL; \
*(var) = NULL;
#define CONVERT_OUTPUTSTR(var) \
if(temp_##var != NULL) \
{ \
RPC_STATUS unused_status; \
if(status == rpc_s_ok) \
status = MultiByteToWideChar16(temp_##var, (var)); \
rpc_string_free(&temp_##var, &unused_status); \
}
#define OUTPUTSTR(var) &temp_##var
#define INPUTSTR(var) converted_##var
#define FREE_INPUTSTR(var) \
if(converted_##var != NULL) \
{ \
free(converted_##var); \
converted_##var = NULL; \
}
RPC_STATUS RpcCompatExceptionToCode(dcethread_exc *exc)
{
RPC_STATUS status;
if((status = dcethread_exc_getstatus(exc)) == -1)
return RPC_S_INTERNAL_ERROR;
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS g_lastcode = 0;
RPC_STATUS RpcCompatReturnLastCode()
{
return g_lastcode;
}
RpcCompatReturnCodeFuncPtr RpcCompatReturnLater(RPC_STATUS value)
{
g_lastcode = value;
return RpcCompatReturnLastCode;
}
RPC_STATUS RpcStringBindingComposeA(
/* [in] */ UCHAR *string_object_uuid,
/* [in] */ UCHAR *string_protseq,
/* [in] */ UCHAR *string_netaddr,
/* [in] */ UCHAR *string_endpoint,
/* [in] */ UCHAR *string_options,
/* [out] */ UCHAR **string_binding
)
{
RPC_STATUS status;
rpc_string_binding_compose(
(idl_char *)string_object_uuid,
(idl_char *)string_protseq,
(idl_char *)string_netaddr,
(idl_char *)string_endpoint,
(idl_char *)string_options,
(idl_char **)string_binding,
&status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcStringBindingComposeW(
/* [in] */ PWSTR string_object_uuid,
/* [in] */ PWSTR string_protseq,
/* [in] */ PWSTR string_netaddr,
/* [in] */ PWSTR string_endpoint,
/* [in] */ PWSTR string_options,
/* [out] */ PWSTR *string_binding
)
{
RPC_STATUS status = rpc_s_ok;
CONVERT_INPUTSTR(string_object_uuid);
CONVERT_INPUTSTR(string_protseq);
CONVERT_INPUTSTR(string_netaddr);
CONVERT_INPUTSTR(string_endpoint);
CONVERT_INPUTSTR(string_options);
DECLARE_OUTPUTSTR(string_binding);
if(status == rpc_s_ok)
{
rpc_string_binding_compose(INPUTSTR(string_object_uuid),
INPUTSTR(string_protseq),
INPUTSTR(string_netaddr),
INPUTSTR(string_endpoint),
INPUTSTR(string_options),
OUTPUTSTR(string_binding),
&status);
}
FREE_INPUTSTR(string_object_uuid);
FREE_INPUTSTR(string_protseq);
FREE_INPUTSTR(string_netaddr);
FREE_INPUTSTR(string_endpoint);
FREE_INPUTSTR(string_options);
CONVERT_OUTPUTSTR(string_binding);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcBindingFromStringBindingA(
/* [in] */ UCHAR *string_binding,
/* [out] */ RPC_BINDING_HANDLE *binding_handle
)
{
RPC_STATUS status;
rpc_binding_from_string_binding((idl_char *)string_binding, binding_handle, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcBindingFromStringBindingW(
/* [in] */ PWSTR string_binding,
/* [out] */ RPC_BINDING_HANDLE *binding_handle
)
{
RPC_STATUS status = rpc_s_ok;
CONVERT_INPUTSTR(string_binding);
if(status == rpc_s_ok)
{
rpc_binding_from_string_binding(
INPUTSTR(string_binding),
binding_handle,
&status);
}
FREE_INPUTSTR(string_binding);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcBindingSetAuthInfoA(
/* [in] */ RPC_BINDING_HANDLE binding_h,
/* [in] */ UCHAR* server_princ_name,
/* [in] */ DWORD authn_level,
/* [in] */ DWORD authn_protocol,
/* [in] */ RPC_AUTH_IDENTITY_HANDLE auth_identity,
/* [in] */ DWORD authz_protocol
)
{
RPC_STATUS status;
rpc_binding_set_auth_info(
binding_h,
server_princ_name,
authn_level,
authn_protocol,
auth_identity,
authz_protocol,
&status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcBindingSetAuthInfoW(
/* [in] */ RPC_BINDING_HANDLE binding_h,
/* [in] */ PWSTR server_princ_name,
/* [in] */ DWORD authn_level,
/* [in] */ DWORD authn_protocol,
/* [in] */ RPC_AUTH_IDENTITY_HANDLE auth_identity,
/* [in] */ DWORD authz_protocol
)
{
RPC_STATUS status = rpc_s_ok;
CONVERT_INPUTSTR(server_princ_name);
if (status == rpc_s_ok)
{
rpc_binding_set_auth_info(
binding_h,
INPUTSTR(server_princ_name),
authn_level,
authn_protocol,
auth_identity,
authz_protocol,
&status);
}
FREE_INPUTSTR(server_princ_name);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcStringFreeA(
/* [in, out] */ PUCHAR *string
)
{
RPC_STATUS status = rpc_s_ok;
rpc_string_free((idl_char **)string, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcStringFreeW(
/* [in, out] */ PWSTR *string
)
{
//We allocated this string, not dce rpc
if(*string != NULL)
{
free(*string);
*string = NULL;
}
return ERROR_SUCCESS;
}
RPC_STATUS RpcBindingFree(
/* [in, out] */ RPC_BINDING_HANDLE *binding_handle
)
{
RPC_STATUS status = rpc_s_ok;
rpc_binding_free(binding_handle, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcServerUseProtseqEpA(
/* [in] */ PUCHAR protseq,
/* [in] */ unsigned int max_call_requests,
/* [in] */ PUCHAR endpoint,
void *security /*not used*/
)
{
RPC_STATUS status = rpc_s_ok;
rpc_server_use_protseq_ep((idl_char *)protseq, max_call_requests, (idl_char *)endpoint, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcServerUseProtseqEpW(
/* [in] */ PWSTR protseq,
/* [in] */ unsigned int max_call_requests,
/* [in] */ PWSTR endpoint,
void *security /*not used*/
)
{
RPC_STATUS status = rpc_s_ok;
CONVERT_INPUTSTR(protseq);
CONVERT_INPUTSTR(endpoint);
if(status == rpc_s_ok)
{
rpc_server_use_protseq_ep(INPUTSTR(protseq),
max_call_requests,
INPUTSTR(endpoint),
&status);
}
FREE_INPUTSTR(protseq);
FREE_INPUTSTR(endpoint);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcServerRegisterIf(
/* [in] */ RPC_IF_HANDLE if_spec,
/* [in] */ UUID *mgr_type_uuid,
/* [in] */ RPC_MGR_EPV *mgr_epv
)
{
RPC_STATUS status = rpc_s_ok;
rpc_server_register_if(if_spec, mgr_type_uuid, mgr_epv, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS RpcServerListen(
unsigned32 minimum_call_threads, /*not used*/
/* [in] */ unsigned32 max_calls_exec,
unsigned32 dont_wait /*not used*/
)
{
RPC_STATUS status = rpc_s_ok;
rpc_server_listen(max_calls_exec, &status);
return LwMapDCEStatusToWinerror(status);
}
RPC_STATUS LwMapDCEStatusToWinerror(
RPC_STATUS dceStatus
)
{
switch(dceStatus)
{
case rpc_s_ok:
return RPC_S_OK;
case rpc_s_op_rng_error:
return RPC_S_PROCNUM_OUT_OF_RANGE;
case rpc_s_not_in_call:
return RPC_S_NO_CALL_ACTIVE;
case rpc_s_no_port:
return RPC_S_OUT_OF_RESOURCES;
case rpc_s_invalid_string_binding:
return RPC_S_INVALID_STRING_BINDING;
case rpc_s_wrong_kind_of_binding:
return RPC_S_WRONG_KIND_OF_BINDING;
case rpc_s_invalid_binding:
return RPC_S_INVALID_BINDING;
case rpc_s_protseq_not_supported:
return RPC_S_PROTSEQ_NOT_SUPPORTED;
case rpc_s_invalid_rpc_protseq:
return RPC_S_INVALID_RPC_PROTSEQ;
case uuid_s_invalid_string_uuid:
return RPC_S_INVALID_STRING_UUID;
case rpc_s_invalid_endpoint_format:
return RPC_S_INVALID_ENDPOINT_FORMAT;
case rpc_s_inval_net_addr:
return RPC_S_INVALID_NET_ADDR;
case rpc_s_endpoint_not_found:
return RPC_S_NO_ENDPOINT_FOUND;
case rpc_s_invalid_timeout:
return RPC_S_INVALID_TIMEOUT;
case rpc_s_object_not_found:
return RPC_S_OBJECT_NOT_FOUND;
case rpc_s_already_registered:
return RPC_S_ALREADY_REGISTERED;
case rpc_s_type_already_registered:
return RPC_S_TYPE_ALREADY_REGISTERED;
case rpc_s_already_listening:
return RPC_S_ALREADY_LISTENING;
case rpc_s_no_protseqs_registered:
return RPC_S_NO_PROTSEQS_REGISTERED;
case rpc_s_not_listening:
return RPC_S_NOT_LISTENING;
case rpc_s_unknown_mgr_type:
return RPC_S_UNKNOWN_MGR_TYPE;
case rpc_s_unknown_if:
return RPC_S_UNKNOWN_IF;
case rpc_s_no_bindings:
return RPC_S_NO_BINDINGS;
case rpc_s_no_protseqs:
return RPC_S_NO_PROTSEQS;
case rpc_s_no_rem_endpoint:
return RPC_S_CANT_CREATE_ENDPOINT;
case rpc_s_connect_no_resources:
return RPC_S_OUT_OF_RESOURCES;
case ept_s_server_unavailable:
return RPC_S_SERVER_UNAVAILABLE;
case rpc_s_server_too_busy:
return RPC_S_SERVER_TOO_BUSY;
case rpc_s_invalid_call_opt:
return RPC_S_INVALID_NETWORK_OPTIONS;
case rpc_s_call_failed:
return RPC_S_CALL_FAILED;
case rpc_s_call_faulted:
return RPC_S_CALL_FAILED_DNE;
case rpc_s_protocol_error:
return RPC_S_PROTOCOL_ERROR;
case rpc_s_tsyntaxes_unsupported:
return RPC_S_UNSUPPORTED_TRANS_SYN;
case rpc_s_unsupported_type:
return RPC_S_UNSUPPORTED_TYPE;
case rpc_s_fault_invalid_tag:
return RPC_S_INVALID_TAG;
case rpc_s_fault_invalid_bound:
return RPC_S_INVALID_BOUND;
case rpc_s_no_entry_name:
return RPC_S_NO_ENTRY_NAME;
case rpc_s_invalid_name_syntax:
return RPC_S_INVALID_NAME_SYNTAX;
case rpc_s_unsupported_name_syntax:
return RPC_S_UNSUPPORTED_NAME_SYNTAX;
case uuid_s_no_address:
return RPC_S_UUID_NO_ADDRESS;
case ept_s_cant_access:
return RPC_S_DUPLICATE_ENDPOINT;
case rpc_s_unsupported_auth_subtype:
return RPC_S_UNKNOWN_AUTHN_TYPE;
case rpc_s_max_calls_too_small:
return RPC_S_MAX_CALLS_TOO_SMALL;
case rpc_s_string_too_long:
return RPC_S_STRING_TOO_LONG;
case rpc_s_binding_has_no_auth:
return RPC_S_BINDING_HAS_NO_AUTH;
case rpc_s_unknown_authn_service:
return RPC_S_UNKNOWN_AUTHN_SERVICE;
case rpc_s_authn_authz_mismatch:
return RPC_S_UNKNOWN_AUTHZ_SERVICE;
case rpc_s_nothing_to_export:
return RPC_S_NOTHING_TO_EXPORT;
case rpc_s_incomplete_name:
return RPC_S_INCOMPLETE_NAME;
case rpc_s_invalid_vers_option:
return RPC_S_INVALID_VERS_OPTION;
case rpc_s_no_more_members:
return RPC_S_NO_MORE_MEMBERS;
case rpc_s_not_all_objs_unexported:
return RPC_S_NOT_ALL_OBJS_UNEXPORTED;
case rpc_s_interface_not_found:
return RPC_S_INTERFACE_NOT_FOUND;
case rpc_s_entry_already_exists:
return RPC_S_ENTRY_ALREADY_EXISTS;
case rpc_s_entry_not_found:
return RPC_S_ENTRY_NOT_FOUND;
case rpc_s_name_service_unavailable:
return RPC_S_NAME_SERVICE_UNAVAILABLE;
case rpc_s_invalid_naf_id:
return RPC_S_INVALID_NAF_ID;
case rpc_s_not_supported:
return RPC_S_CANNOT_SUPPORT;
case rpc_s_context_id_not_found:
return RPC_S_NO_CONTEXT_AVAILABLE;
case uuid_s_internal_error:
return RPC_S_INTERNAL_ERROR;
case rpc_s_fault_int_div_by_zero:
return RPC_S_ZERO_DIVIDE;
case rpc_s_cant_bind_socket:
return RPC_S_ADDRESS_ERROR;
case rpc_s_fault_fp_div_by_zero:
return RPC_S_FP_DIV_ZERO;
case rpc_s_fault_fp_underflow:
return RPC_S_FP_UNDERFLOW;
case rpc_s_fault_fp_overflow:
return RPC_S_FP_OVERFLOW;
case rpc_s_call_queued:
return RPC_S_CALL_IN_PROGRESS;
case rpc_s_no_more_bindings:
return RPC_S_NO_MORE_BINDINGS;
case rpc_s_no_interfaces:
return RPC_S_NO_INTERFACES;
case rpc_s_call_cancelled:
return RPC_S_CALL_CANCELLED;
case rpc_s_binding_incomplete:
return RPC_S_BINDING_INCOMPLETE;
case rpc_s_comm_failure:
return RPC_S_COMM_FAILURE;
case rpc_s_auth_method:
return RPC_S_INVALID_AUTH_IDENTITY;
case rpc_s_unsupported_authn_level:
return RPC_S_UNSUPPORTED_AUTHN_LEVEL;
case rpc_s_invalid_credentials:
return RPC_S_NO_PRINC_NAME;
case rpc_s_unknown_error:
return RPC_S_NOT_RPC_ERROR;
case rpc_m_cant_create_uuid:
return RPC_S_UUID_LOCAL_ONLY;
case rpc_s_cancel_timeout:
return RPC_S_NOT_CANCELLED;
case rpc_s_group_member_not_found:
return RPC_S_GROUP_MEMBER_NOT_FOUND;
case rpc_s_invalid_object:
return RPC_S_INVALID_OBJECT;
case rpc_s_wrong_pickle_type:
return RPC_S_ENTRY_TYPE_MISMATCH;
case rpc_s_no_interfaces_exported:
return RPC_S_INTERFACE_NOT_EXPORTED;
case rpc_s_profile_not_found:
return RPC_S_PROFILE_NOT_ADDED;
case ept_s_invalid_entry:
return EPT_S_INVALID_ENTRY;
case ept_s_cant_perform_op:
return EPT_S_CANT_PERFORM_OP;
case ept_s_not_registered:
return EPT_S_NOT_REGISTERED;
case ept_s_cant_create:
return EPT_S_CANT_CREATE;
case uuid_s_no_memory:
case rpc_s_no_memory:
case ept_s_no_memory:
case dce_cs_c_cannot_allocate_memory:
return ERROR_OUTOFMEMORY;
case rpc_s_rpcd_comm_failure:
case rpc_s_cannot_connect:
return ERROR_CONNECTION_REFUSED;
case rpc_s_connection_aborted:
return ERROR_CONNECTION_ABORTED;
case rpc_s_connection_closed:
return ERROR_GRACEFUL_DISCONNECT;
case rpc_s_connect_timed_out:
return WSAETIMEDOUT;
case rpc_s_connect_rejected:
return ERROR_CONNECTION_REFUSED;
case rpc_s_connect_closed_by_rem:
return WSAEDISCON;
case rpc_s_cant_create_socket:
return ERROR_CANNOT_MAKE;
case rpc_s_invalid_arg:
return RPC_S_INVALID_ARG;
default:
return RPC_S_INTERNAL_ERROR;
}
}
RPC_STATUS DceErrorInqTextA(
unsigned32 convert_status,
/* [out] */ UCHAR *error_text
)
{
int dce_status = 0;
dce_error_inq_text(convert_status, (idl_char *)error_text, &dce_status);
return LwMapDCEStatusToWinerror(dce_status);
}
RPC_STATUS DceErrorInqTextW(
unsigned32 convert_status,
/* [out] */ PWSTR error_text
)
{
int dce_status = 0;
dce_error_string_t errstr;
dce_error_inq_text(convert_status, (idl_char *)errstr, &dce_status);
if (dce_status == rpc_s_ok)
{
mbstowc16s(error_text, errstr, DCE_C_ERROR_STRING_LEN);
}
return LwMapDCEStatusToWinerror(dce_status);
}