#include <dce/schannel.h>
#include <schnauth.h>
#define MAX_SERVER_PRINC_NAME_LEN 500
GLOBAL unsigned32 rpc_g_schnauth_alloc_count = 0;
GLOBAL unsigned32 rpc_g_schnauth_free_count = 0;
INTERNAL rpc_auth_rpc_prot_epv_p_t rpc_g_schnauth_rpc_prot_epv[RPC_C_PROTOCOL_ID_MAX];
INTERNAL void rpc__schnauth_inq_access_token(
rpc_auth_info_p_t auth_info,
rpc_access_token_p_t* token,
unsigned32 *stp
);
INTERNAL rpc_auth_epv_t rpc_g_schnauth_epv =
{
rpc__schnauth_bnd_set_auth,
rpc__schnauth_srv_reg_auth,
rpc__schnauth_mgt_inq_def,
rpc__schnauth_inq_my_princ_name,
rpc__schnauth_free_info,
rpc__schnauth_free_key,
rpc__schnauth_resolve_identity,
rpc__schnauth_release_identity,
rpc__schnauth_inq_sec_context,
rpc__schnauth_inq_access_token,
};
PRIVATE void rpc__schnauth_bnd_set_auth
(
unsigned_char_p_t server_name,
rpc_authn_level_t level,
rpc_auth_identity_handle_t auth_ident,
rpc_authz_protocol_id_t authz_prot,
rpc_binding_handle_t binding_h ATTRIBUTE_UNUSED,
rpc_auth_info_p_t *infop,
unsigned32 *stp
)
{
int st = rpc_s_ok;
rpc_schnauth_info_p_t schnauth_info = NULL;
rpc_schannel_auth_info_p_t auth_info = NULL;
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_bnd_set_auth)\n"));
auth_info = (rpc_schannel_auth_info_p_t)auth_ident;
rpc_g_schnauth_alloc_count++;
RPC_MEM_ALLOC(schnauth_info, rpc_schnauth_info_p_t, sizeof(*schnauth_info),
RPC_C_MEM_UTIL, RPC_C_MEM_WAITOK);
if ((authz_prot != rpc_c_authz_name) &&
(authz_prot != rpc_c_authz_dce))
{
st = rpc_s_authn_authz_mismatch;
goto poison;
}
if ((level != rpc_c_authn_level_default) &&
(level != rpc_c_authn_level_pkt_integrity) &&
(level != rpc_c_authn_level_pkt_privacy))
{
st = rpc_s_unsupported_authn_level;
goto poison;
}
if (auth_info->domain_name != NULL) {
server_name = rpc_stralloc(auth_info->domain_name);
if (server_name == NULL) {
st = rpc_s_no_memory;
goto poison;
}
}
RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, (
"(rpc__schnauth_bnd_set_auth) %x created (now %d active)\n",
schnauth_info, rpc_g_schnauth_alloc_count - rpc_g_schnauth_free_count));
memset(schnauth_info, 0, sizeof(*schnauth_info));
RPC_MUTEX_INIT(schnauth_info->lock);
schnauth_info->auth_info.server_princ_name = server_name;
schnauth_info->auth_info.authn_level = level;
schnauth_info->auth_info.authn_protocol = rpc_c_authn_schannel;
schnauth_info->auth_info.authz_protocol = authz_prot;
schnauth_info->auth_info.is_server = 0;
schnauth_info->auth_info.u.auth_identity = auth_ident;
schnauth_info->auth_info.refcount = 1;
memcpy(schnauth_info->sec_ctx.session_key, auth_info->session_key, 16);
schnauth_info->sec_ctx.domain_name = rpc_stralloc(auth_info->domain_name);
if (schnauth_info->sec_ctx.domain_name == NULL) {
st = rpc_s_no_memory;
goto poison;
}
schnauth_info->sec_ctx.fqdn = rpc_stralloc(auth_info->fqdn);
if (schnauth_info->sec_ctx.fqdn == NULL) {
st = rpc_s_no_memory;
goto poison;
}
schnauth_info->sec_ctx.machine_name = rpc_stralloc(auth_info->machine_name);
if (schnauth_info->sec_ctx.machine_name == NULL) {
st = rpc_s_no_memory;
goto poison;
}
schnauth_info->sec_ctx.sender_flags = rpc_schn_initiator_flags |
auth_info->sender_flags;
poison:
*infop = (rpc_auth_info_p_t) &schnauth_info->auth_info;
*stp = st;
}
PRIVATE void rpc__schnauth_init
(
rpc_auth_epv_p_t *epv,
rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv,
unsigned32 *st
);
#include <comp.h>
void rpc__schnauth_init_func(void)
{
static rpc_authn_protocol_id_elt_t auth[1] = {
{ rpc__schnauth_init,
rpc_c_authn_schannel,
dce_c_rpc_authn_protocol_schannel,
NULL,
rpc_g_schnauth_rpc_prot_epv }
};
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__module_init_func)\n"));
rpc__register_authn_protocol(auth, 1);
}
PRIVATE void rpc__schnauth_init
(
rpc_auth_epv_p_t *epv,
rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv,
unsigned32 *st
)
{
unsigned32 prot_id;
rpc_auth_rpc_prot_epv_t *prot_epv;
unsigned32 dbg_st;
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_init)\n"));
prot_id = rpc__schnauth_cn_init(&prot_epv, st);
if (*st == rpc_s_ok)
{
rpc_g_schnauth_rpc_prot_epv[prot_id] = prot_epv;
}
*epv = &rpc_g_schnauth_epv;
*rpc_prot_epv = rpc_g_schnauth_rpc_prot_epv;
*st = rpc_s_ok;
}
PRIVATE void rpc__schnauth_free_info
(
rpc_auth_info_p_t *info
)
{
rpc_schnauth_info_p_t schnauth_info = (rpc_schnauth_info_p_t)*info ;
char *info_type;
unsigned32 tst;
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_free_info)\n"));
info_type = (*info)->is_server?"server":"client";
RPC_MUTEX_DELETE(schnauth_info->lock);
if ((*info)->server_princ_name)
{
rpc_string_free(&(*info)->server_princ_name, &tst);
}
(*info)->u.s.privs = 0;
if (schnauth_info->sec_ctx.machine_name)
{
rpc_string_free(&schnauth_info->sec_ctx.machine_name, &tst);
}
if (schnauth_info->sec_ctx.domain_name)
{
rpc_string_free(&schnauth_info->sec_ctx.domain_name, &tst);
}
if (schnauth_info->sec_ctx.fqdn)
{
rpc_string_free(&schnauth_info->sec_ctx.fqdn, &tst);
}
memset(schnauth_info, 0x69, sizeof(*schnauth_info));
RPC_MEM_FREE(schnauth_info, RPC_C_MEM_UTIL);
rpc_g_schnauth_free_count++;
RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, (
"(rpc__schnauth_release) freeing %s auth_info (now %d active).\n",
info_type, rpc_g_schnauth_alloc_count - rpc_g_schnauth_free_count));
*info = NULL;
}
PRIVATE void rpc__schnauth_mgt_inq_def
(
unsigned32 *authn_level,
unsigned32 *stp
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_mgt_inq_def)\n"));
*authn_level = rpc_c_authn_level_pkt_privacy;
*stp = rpc_s_ok;
}
PRIVATE void rpc__schnauth_srv_reg_auth
(
unsigned_char_p_t server_name ATTRIBUTE_UNUSED,
rpc_auth_key_retrieval_fn_t get_key_func ATTRIBUTE_UNUSED,
dce_pointer_t arg ATTRIBUTE_UNUSED,
unsigned32 *stp
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_srv_reg_auth)\n"));
*stp = rpc_s_ok;
}
PRIVATE void rpc__schnauth_inq_my_princ_name
(
unsigned32 name_size,
unsigned_char_p_t name,
unsigned32 *stp
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_inq_my_princ_name)\n"));
if (name_size > 0) {
rpc__strncpy(name, (unsigned char *)"", name_size - 1);
}
*stp = rpc_s_ok;
}
PRIVATE void rpc__schnauth_free_key
(
rpc_key_info_p_t *key_info ATTRIBUTE_UNUSED
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_free_key)\n"));
}
PRIVATE error_status_t rpc__schnauth_resolve_identity
(
rpc_auth_identity_handle_t in_identity ATTRIBUTE_UNUSED,
rpc_auth_identity_handle_t *out_identity ATTRIBUTE_UNUSED
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_resolve_identity)\n"));
*out_identity = in_identity;
return rpc_s_ok;
}
PRIVATE void rpc__schnauth_release_identity
(
rpc_auth_identity_handle_t *identity ATTRIBUTE_UNUSED
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_release_identity)\n"));
}
PRIVATE void rpc__schnauth_inq_sec_context
(
rpc_auth_info_p_t auth_info ATTRIBUTE_UNUSED,
void **mech_context,
unsigned32 *st
)
{
RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE,
("(rpc__schnauth_inq_sec_context)\n"));
*mech_context = NULL;
*st = rpc_s_ok;
}
INTERNAL void rpc__schnauth_inq_access_token(
rpc_auth_info_p_t auth_info,
rpc_access_token_p_t* token,
unsigned32 *stp
)
{
*token = NULL;
*stp = rpc_s_ok;
return;
}