////////////////////////////////////////////////////////////
//
// Declaration of classes
// DceCallAttributes and
// DceCall - a caller's wrapper of a DCE interface
//
// No exception handling !
//
// Copyright 2001
//
////////////////////////////////////////////////////////////
#ifndef __DCECALL_H__
#define __DCECALL_H__
#include <dce/sec_login.h>
#include "DceInterface.h"
// DceCallAttributes
class DceCallAttributes: public DceInterface
{
friend class DceCall;
public:
int status;
DceCallAttributes();
DceCallAttributes(const DceCallAttributes&);
~DceCallAttributes();
DceCallAttributes& operator=(const DceCallAttributes&);
// syntax code read from an environment variable
// or use DCE, if it is not set
int set_entry_name(const char *name);
// takes precedence over linked interface id
// (conflicts with polimorphic interfaces)
int link_server_id(const char * string_id) // its length is UUID_STRING_LEN
{ return linked_server_id.set(string_id); }
int set_secure()
{security_is_set=true; return 0;}
// default rpc_c_protect_level_default
int set_protection_level( unsigned z=rpc_c_protect_level_none)
{ protection_level=z; return 0;}
// default rpc_c_authn_default
int set_authentication_service( unsigned z=rpc_c_authn_none)
{ authentication_service=z; return 0;}
// default rpc_c_authz_none (!)
int set_authorization_service( unsigned z)
{ authorization_service=z; return 0;}
// if not set - name is not checked
int set_server_principal_name(const char *z);
// login_context
// if none is set - default login context is used
// for nested calls, server's login context is automatically refreshed
// default - current login context
int use_server_login_context(const sec_login_handle_t *z)
{ server_login_handle=z; login_type=server_context; return 0;}
// default sec_login_auth_src_network
// others: sec_login_auth_src_local, sec_login_auth_src_overridden
int set_login_service(sec_login_auth_src_t z)
{ login_service=z; return 0;}
private:
enum LoginType
{
current_context,
server_context
};
bool security_is_set;
unsigned32 entry_name_syntax;
unsigned_char_t *entry_name;
unsigned_char_t *server_principal_name;
unsigned32 protection_level,
authentication_service,
authorization_service;
DceUuid linked_server_id;
sec_login_flags_t login_flags;
int login_type;
sec_login_auth_src_t login_service;
const sec_login_handle_t *server_login_handle;
};
// DceCall
// a base class for dce calls wrapers
class DceCall
{
DceCall(const DceCall&); // forbidden
DceCall& operator=(const DceCall&); // forbidden
public:
DceCall(){initialize();} // for arrays
DceCall(const DceCallAttributes& z)
{initialize(); set_attributes(z);}
virtual ~DceCall();
int set_attributes(const DceCallAttributes& z);
int set_instance_id(const char* z); // for logging
// default is 3 times
int set_retries(int z){rpc_retries=z; return 0;}
int reset_binding(); // in case a deamon dced was interrupted
int get_linked_id(DceUuid& z)
{ return z.set(linked_id); }
protected:
handle_t binding_handle;
rpc_ns_handle_t import_context;
DceCallAttributes dce_call_attributes;
bool is_set, is_bound, secure;
char * instance_id; // for logging
uuid_t linked_id; // actual
int rpc_retries;
int initialize();
int binding_begin();
int binding_next();
int binding_done();
int start_binding();
// default implementation writes to stdout
// provide a custom logging function, if needed
virtual int dce_log(const char *message, error_status_t status);
};
#endif
/*
An implementation of a wraper MyDceCall of an interface
int func(rpc_error_status* rpc_error_status,handle_t binding_handle,int z);
when rpc errors are passed through rpc_error_status with the help of ACF file.
Note that binding_handle is a member in DceCall class.
1.
class MyDceCall: public DceCall
{
public:
int func(int z);
...
};
2.
int MyDceCall::func(int z)
{
error_status_t rpc_error_status=rpc_s_ok;
int g=0;
if(start_binding()) return -1;
for(int count=0;count<rpc_retries;++count)
{
g=::func(rpc_error_status,binding_handle,z);
if(rpc_error_status==rpc_s_ok) break;
if( binding_next() ) break;
}
if(rpc_error_status!=rpc_s_ok) return -2;
return g;
}
***************
A calling sequence:
DceCallAttributes call_attributes;
// set attributes including Interface here
MyDceCall my_wraper(call_attributes);
int g=my_wraper.func(0);
****************
For functionality presented to a client in a form
int g=my_wraper.func(int z);
create an interface with two additional patameters
rpc_error_status and handle_t,
for example
int func(rpc_error_status* rpc_error_status, handle_t binding_handle,int z).
and provide an ACF file for an idl compiler to pass rpc errors
through rpc_error_status in addition to errors
passed by this interface implementation
*/