|
I just saw your notes entry. I believe this is related to
the problem at ECT in Holland ?
Maybe you received my mail send to the customer, there I explained
that the forever lifetime is not a really nice thing. The immediate
CPU usage is, as far as I believe, a well know effect.
I don't know how the ACMSxp task server works. DO they use keyfile ?
or do they use the login context ? If it's a keyfile based way
to authenticate, then it would be the best to have two threads
running in the Task server doing the reauthentication and the
password change.
I havce attached an server example....
Let me know if this helps
Marco
/*
*****************************************************************
* *
* Copyright (c) Digital Equipment Corporation, 1991, 1993 *
* *
* The software contained on this media is proprietary to *
* and embodies the confidential technology of Digital *
* Equipment Corporation. Possession, use, duplication or *
* dissemination of the software and media is authorized only *
* pursuant to a valid written license from Digital Equipment *
* Corporation. *
* *
* This script is provided as part of the MCS ADDED VALUE *
* SERVICES *
* developed by MCS Services (UNIX Software Support) *
* Ruemlang / Switzerland *
* *
*****************************************************************
*
* Comment: This is a generic dce server,
*
* HISTORY
*
* oct.95, bill
*
*---------------------------------------------------------------*/
#include <stdio.h>
#include <pthread.h>
#include "check_status.h"
#include "dep.h"
/* DON'T change any line beyond this line */
/*----------------------------------------*/
void establish_identity (error_status_t *);
int
main(int argc, char *argv[])
{
unsigned_char_t *server_name;
rpc_binding_vector_t *bind_vector_p;
unsigned32 status;
int i;
/* Register interface with rpc runtime. */
rpc_server_register_if(IFSPEC, NULL,
NULL, &status);
CHECK_STATUS (status,"unable to register i/f",ABORT);
/* We want to use all supported protocol sequences. */
rpc_server_use_all_protseqs(rpc_c_protseq_max_reqs_default, &status);
CHECK_STATUS (status,"use_all_protseqs failed",ABORT);
/*
* Establish this server's identity by setting up the
* appropriate login context.
*/
establish_identity (&status);
CHECK_STATUS (status,"Cannot establish server identity",ABORT);
/*
* Register authentication info with RPC.
*/
rpc_server_register_auth_info((unsigned_char_t *)SERVER_PRINCIPAL_NAME,
rpc_c_authn_dce_secret, NULL /*default key retrieval function*/,
KEYTAB, &status);
CHECK_STATUS (status,"server_register_auth_info failed",ABORT);
/*
* Continue with the normal initialization sequence.
* Get our bindings...
*/
rpc_server_inq_bindings(&bind_vector_p, &status);
CHECK_STATUS (status,"server_inq_bindings failed",ABORT);
/* Register binding information with the endpoint map. */
rpc_ep_register(IFSPEC, bind_vector_p,
NULL,
(unsigned_char_t *) ANNOTATION, &status);
CHECK_STATUS (status,"ep_register failed",ABORT);
/*
* Export binding information into the namespace.
*/
rpc_ns_binding_export(rpc_c_ns_syntax_dce,
(unsigned_char_t *) NSENTRYNAME,
IFSPEC, bind_vector_p,
NULL, &status);
CHECK_STATUS (status,"export failed",ABORT);
/* Listen for remote calls. */
fprintf(stderr, "Server listening...\n");
rpc_server_listen(rpc_c_listen_max_calls_default, &status);
CHECK_STATUS (status,"server_listen failed",ABORT);
/* We don't expect to return from the listen loop. */
fprintf(stderr, "Unexpected return from rpc_server_listen\n");
exit(1);
}
/*
* establish_identity.
*
* Internal routine to establish this server as the SERVER_PRINCIPAL
* principal.
*/
#include <dce/sec_login.h>
void establish_identity (error_status_t *o_status)
{
sec_login_handle_t login_context;
sec_login_auth_src_t auth_src;
void *server_key;
error_status_t status;
boolean32 identity_valid;
boolean32 reset_passwd;
pthread_t refresh_login_context_thread;
pthread_t key_mgmt_thread;
void refresh_login_context_rtn ();
void key_mgmt_rtn ();
pthread_attr_t mgr_thread_attr;
/*
* Set up the network identity for this server principal.
* The network credentials obtained are sealed and must be
* unsealed with the server's secret key before they can
* be used.
*/
sec_login_setup_identity((unsigned_char_p_t)SERVER_PRINCIPAL_NAME,
sec_login_no_flags,
&login_context, &status);
CHECK_STATUS (status,"unable to set up identity",ABORT);
/*
* Retrieve the server's secret key from the private keytab
* file.
*/
sec_key_mgmt_get_key(rpc_c_authn_dce_secret, KEYTAB,
SERVER_PRINCIPAL_NAME,
0, /* return most recent version */
&server_key, &status);
CHECK_STATUS (status,"unable to retrieve key",ABORT);
/*
* Unseal the network identity using the server's secret key.
*/
identity_valid = sec_login_validate_identity(login_context,
server_key, &reset_passwd, &auth_src, &status);
/*
* Free the secret key as soon as we are done with it.
*/
sec_key_mgmt_free_key (&server_key, &status);
CHECK_STATUS (status,"unable to free key",ABORT);
if (identity_valid)
{
/*
* Make sure that the server identity was validated by
* the network -
* i.e., the security server, instead of local data.
*/
if (auth_src != sec_login_auth_src_network)
{
fprintf (stderr, "Server has no network credentials\n");
exit (1);
}
/*
* We make this login context the default for this process.
*/
sec_login_set_context(login_context, &status);
CHECK_STATUS (status,"unable to set login context",ABORT);
/*
* Make sure that all threads have a minimum stack size
*/
pthread_attr_create (&mgr_thread_attr);
pthread_attr_setstacksize(&mgr_thread_attr,DEF_STACKSIZE);
/*
* Start up a thread to refresh the login context when it
* expires.
*/
if (( pthread_create (&refresh_login_context_thread,
mgr_thread_attr,
(pthread_startroutine_t)
refresh_login_context_rtn,
(pthread_addr_t)login_context) ) == -1)
exit (1);
/*
* Start up a thread to manage our secret key.
*/
if (( pthread_create (&key_mgmt_thread, mgr_thread_attr,
(pthread_startroutine_t) key_mgmt_rtn,
(pthread_addr_t)NULL) ) == -1)
exit (1);
/*
* Delete the attribute
*/
pthread_attr_delete (&mgr_thread_attr);
*o_status = status;
}
else
{
error_status_t temp_status;
CHECK_STATUS (status,"unable to validate network identity",RESUME);
/* Reclaim the storage */
sec_login_purge_context (&login_context, &temp_status);
CHECK_STATUS (temp_status,"unable to purge login context",ABORT);
*o_status = status;
return;
}
}
/*
* A thread to periodically change the server's secret key.
*/
void key_mgmt_rtn ()
{
error_status_t status;
fprintf (stderr, "key mgmt thread started up\n");
while (1)
{
sec_key_mgmt_manage_key (rpc_c_authn_dce_secret,
KEYTAB, SERVER_PRINCIPAL_NAME, &status);
CHECK_STATUS (status,"key mgmt failure",ABORT);
}
}
/*
* A thread to periodically refresh the credentials contained in a
* login context.
*/
#include <sys/time.h>
void refresh_login_context_rtn (sec_login_handle_t login_context)
{
struct timeval current_time;
struct timezone tz;
struct timespec delay;
signed32 expiration;
signed32 delay_time;
unsigned32 used_kvno;
boolean32 reset_passwd;
boolean32 identity_valid;
void *server_key;
sec_login_auth_src_t auth_src;
error_status_t status;
#define MINUTE 60
while (1)
{
#ifdef BSD
/* BSD version of gettimeofday has a timezone parameter. */
gettimeofday (¤t_time, &tz);
#else
gettimeofday (¤t_time);
#endif
sec_login_get_expiration (login_context, &expiration, &status);
if ((status != rpc_s_ok) && (status != sec_login_s_not_certified))
{
fprintf (stderr, "Cannot get login context expiration time\n");
exit (1);
}
/* Wait until shortly before the login context expires... */
delay_time = expiration - current_time.tv_sec - (10*MINUTE);
if (delay_time > 0)
{
delay.tv_sec = delay_time;
delay.tv_nsec = 0;
pthread_delay_np (&delay);
}
sec_login_refresh_identity (login_context, &status);
CHECK_STATUS (status, "cannot refresh identity", ABORT);
/*
* Retrieve the server's secret key from the private keytab
* file.
*/
sec_key_mgmt_get_key(rpc_c_authn_dce_secret, KEYTAB,
SERVER_PRINCIPAL_NAME,
0, /* return most recent version */
&server_key, &status);
CHECK_STATUS (status,"unable to retrive key",ABORT);
/*
* The refreshed login context still needs to be validated.
*/
identity_valid = sec_login_validate_identity(login_context,
server_key, &reset_passwd, &auth_src, &status);
/*
* Free the secret key as soon as we are done with it.
*/
sec_key_mgmt_free_key (server_key, &status);
CHECK_STATUS (status,"unable to free key",ABORT);
if (! identity_valid)
{
error_status_t temp_status;
/* Reclaim the storage */
sec_login_purge_context (&login_context, &temp_status);
CHECK_STATUS (temp_status,"unable to purge login context",ABORT);
/* Report original error. */
CHECK_STATUS (status,
"unable to validate network identity",ABORT);
}
} /* end of while(1) */
}
|