|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 15443 (0x3c53)
Types: TextFile
Names: »get_dsa_info.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/quipu/get_dsa_info.c«
/* get_dsa_info.c - Get DSA info given its distinguished name */
#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/get_dsa_info.c,v 7.2 89/12/19 16:20:36 mrose Exp $";
#endif
/*
* $Header: /f/osi/quipu/RCS/get_dsa_info.c,v 7.2 89/12/19 16:20:36 mrose Exp $
*
*
* $Log: get_dsa_info.c,v $
* Revision 7.2 89/12/19 16:20:36 mrose
* sync
*
* Revision 7.1 89/11/24 16:21:59 mrose
* sync
*
* Revision 7.0 89/11/23 22:17:42 mrose
* Release 6.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
#include "quipu/util.h"
#include "quipu/read.h"
#include "quipu/entry.h"
#include "quipu/dua.h"
#include "quipu/bind.h"
#include "quipu/connection.h"
extern LLog * log_dsap;
extern DN mydsadn;
struct oper_act * oper_alloc();
struct di_block * di_alloc();
struct oper_act * make_get_dsa_info_op();
/*
* This routine is used to read the info (including presentation address)
* for a dsa given its distinguished name.
* This is called during the DSA initialisation, to find the name THIS dsa.
*/
int get_dsa_info(dn, dn_stack, err, di_p)
DN dn;
struct dn_seq * dn_stack;
struct DSError * err;
struct di_block **di_p;
{
struct di_block * di_tmp;
struct di_block * di_lookup;
struct oper_act * on = NULLOPER;
int res;
DLOG (log_dsap,LLOG_TRACE,("get_dsa_info()"));
(void) dn_decode (dn);
if (dn_in_dnseq(dn, dn_stack))
{
LLOG (log_dsap,LLOG_NOTICE,("get_dsa_info - loop detected"));
err->dse_type = DSE_SERVICEERROR;
err->dse_un.dse_un_service.DSE_sv_problem = DSE_SV_LOOPDETECT;
return(DS_X500_ERROR);
}
/* if asking about me, use my cached entry */
if (dn_cmp (dn,mydsadn) == 0)
{
LLOG (log_dsap,LLOG_NOTICE,("get_dsa_info - referring to self :-)"));
err->dse_type = DSE_SERVICEERROR;
err->dse_un.dse_un_service.DSE_sv_problem = DSE_SV_DITERROR;
return(DS_X500_ERROR);
}
(*di_p) = di_alloc();
(*di_p)->di_type = DI_TASK;
(*di_p)->di_dn = dn_cpy(dn);
(*di_p)->di_target = NULLDN;
(*di_p)->di_reftype = RT_UNDEFINED;
(*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED;
(*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS;
/*
* Check for a GetDSAInfo operation already in the pipeline.
*/
for(di_tmp=deferred_dis; di_tmp != NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
{
if(dn_cmp(dn, di_tmp->di_dn) == 0)
{
(*di_p)->di_state = DI_DEFERRED;
(*di_p)->di_entry = NULLENTRY;
/* link to the performing operation */
(*di_p)->di_perform = di_tmp->di_perform;
/* Add to wake list leaving global block first to be woken */
(*di_p)->di_wake_next = di_tmp->di_wake_next;
di_tmp->di_wake_next = (*di_p);
DLOG(log_dsap, LLOG_DEBUG, ("Found global deferred di_block:"));
#ifdef DEBUG
di_list_log((*di_p));
#endif
return(DS_CONTINUE);
}
}
if ((res = really_find_entry(dn, TRUE, dn_stack, FALSE, &((*di_p)->di_entry), err, &(di_lookup))) == DS_OK)
/* is it really OK ??? */
if (((*di_p)->di_entry ->e_data == E_TYPE_CONSTRUCTOR)
|| ((*di_p)->di_entry->e_dsainfo == NULL)
|| ((*di_p)->di_entry->e_dsainfo->dsa_addr == NULLPA)) {
DN dn_found;
DLOG(log_dsap, LLOG_NOTICE, ("rfe returned a constructor"));
dn_found = get_copy_dn((*di_p)->di_entry);
res = constructor_dsa_info(dn_found,dn_stack,FALSE,(*di_p)->di_entry,err,&(di_lookup));
dn_free (dn_found);
}
switch (res)
{
case DS_OK:
/* really_find_entry has found the entry and placed it in di_entry */
DLOG(log_dsap, LLOG_DEBUG, ("get_dsa_info - really_fe returns DS_OK"));
(*di_p)->di_state = DI_COMPLETE;
#ifdef DEBUG
di_list_log((*di_p));
#endif
return(DS_OK);
case DS_CONTINUE:
/*
* A list of di_blocks (di_lookup) has been generated by get_dsa_info.
* These should be used to chain the get_dsa_info operation.
* Attempt to generate an operation using the di_blocks returned
* and if successful, defer the current di_block to it.
*/
DLOG(log_dsap, LLOG_DEBUG, ("gdi rfe returned DS_CONT:"));
#ifdef DEBUG
di_list_log(di_lookup);
#endif
if((on = make_get_dsa_info_op(dn, di_lookup)) == NULLOPER)
{
/* Flake out screaming */
LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_dsa_info_op failed for get_dsa_info"));
free((char *)*di_p);
(*di_p) = NULL_DI_BLOCK;
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
return(DS_X500_ERROR);
}
if(oper_chain(on) != OK)
{
/* Flake out screaming */
LLOG(log_dsap, LLOG_NOTICE, ("send_op failed for get_dsa_info"));
free((char *)*di_p);
(*di_p) = NULL_DI_BLOCK;
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
return(DS_X500_ERROR);
}
di_tmp = di_alloc();
di_tmp->di_dn = dn_cpy(dn);
DLOG(log_dsap, LLOG_DEBUG, ("get_dsa_info allocates di_block with dn[%x]", di_tmp->di_dn));
di_tmp->di_state = DI_DEFERRED;
di_tmp->di_type = DI_GLOBAL;
di_tmp->di_perform = on;
on->on_wake_list = di_tmp; /* wake globals first */
(*di_p)->di_state = DI_DEFERRED;
(*di_p)->di_perform = on;
/* Add to wake list leaving global block first to be woken */
(*di_p)->di_wake_next = NULL_DI_BLOCK;
di_tmp->di_wake_next = (*di_p);
di_tmp->di_next = deferred_dis;
deferred_dis = di_tmp;
DLOG(log_dsap, LLOG_DEBUG, ("gdi DS_CONT: generated:"));
#ifdef DEBUG
di_list_log((*di_p));
#endif
return(DS_CONTINUE);
case DS_X500_ERROR:
/* something wrong with the request - err should be filled out */
DLOG(log_dsap, LLOG_DEBUG, ("gdi X500_ERROR"));
free((char *)*di_p);
(*di_p) = NULL_DI_BLOCK;
return(DS_X500_ERROR);
default:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unexpected return from read_dsa_info"));
free((char *)*di_p);
(*di_p) = NULL_DI_BLOCK;
err->dse_type = DSE_SERVICEERROR;
err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
return(DS_X500_ERROR);
}
}
dsa_info_result_wakeup(on)
struct oper_act * on;
{
EntryInfo * ent_res;
Entry di_ent;
struct di_block * di;
struct di_block * next_di;
struct di_block **di_p;
Entry cache_dsp_entry();
DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup()"));
/*
* Cache the entry returned, flake out if it is not unravellable,
* otherwise grab a reference to the unravelled entry.
*/
ent_res = &(on->on_resp.resp_res.dcr_dsres.res_rd.rdr_entry);
if((di_ent = cache_dsp_entry (ent_res)) == NULLENTRY)
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("dsa_info_result_wakeup - cache_dsp_entry failure"));
dsa_info_error_wakeup(on);
return;
}
DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - cached dsa_info"));
/*
* First block on the wake up list should be the global marker.
* Verify this and remove it.
*/
if(on->on_wake_list->di_type != DI_GLOBAL)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("First di_block to wake not global"));
}
else
{
di_p = &(deferred_dis);
for(di = deferred_dis; di != NULL_DI_BLOCK; di=(*di_p))
{
if(di == on->on_wake_list)
break;
di_p = &(di->di_next);
}
if(di == NULL_DI_BLOCK)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Global di_block wasn't on global list"));
}
else
{
(*di_p)=di->di_next;
}
}
DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - dealt with global block"));
for(di = on->on_wake_list->di_wake_next; di != NULL_DI_BLOCK; di = next_di)
{
next_di = di->di_wake_next;
di->di_state = DI_COMPLETE;
di->di_entry = di_ent;
switch(di->di_type)
{
case DI_OPERATION:
if (di->di_oper == NULLOPER) {
di_free (di);
break;
}
if(di->di_oper->on_state == ON_DEFERRED)
{
if (oper_chain(di->di_oper) != OK) {
LLOG (log_dsap,LLOG_EXCEPTIONS, ("oper_chain failed in dsa_info_wakeup"));
di_free(di);
}
}
break;
case DI_TASK:
task_dsa_info_wakeup(di);
di_free(di);
break;
default:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("get_dsa_info_aux - unknown di-type %d",di->di_type));
oper_extract(on);
return;
}
}
DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - woke all blocks"));
/*
* Everthing should have been woken up by now so the di_blocks on
* the wake list and the operation itself can be extracted.
*/
di_free(on->on_wake_list);
oper_extract(on);
}
dsa_info_error_wakeup(on)
struct oper_act * on;
{
struct DSError * err = &(on->on_resp.resp_err);
struct di_block * di;
/*
* Error can fall into 3 categories:
* 1) Problem with remote DSA performing operation - try another;
* 2) A referral error - follow the referral;
* 3) An error with the operation itself;
*/
switch(err->dse_type)
{
case DSE_NOERROR:
LLOG(log_dsap, LLOG_NOTICE, ("dsa_info_error_wakeup - No Error!"));
dsa_info_fail_wakeup(on);
return;
case DSE_REFERRAL:
LLOG(log_dsap, LLOG_NOTICE, ("dsa_info_error_wakeup - DAP Referral!"));
case DSE_DSAREFERRAL:
if(oper_rechain(on) == OK)
return;
/* Fall through */
default:
DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_error_wakeup - Assuming all non-referral errors are to be propogated"));
/* Lose the di_block */
for(di=on->on_wake_list; di!=NULL_DI_BLOCK; di=di->di_wake_next)
{
switch(di->di_type)
{
case DI_OPERATION:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake oper"));
oper_log(di->di_oper);
break;
case DI_TASK:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake task"));
task_log(di->di_task);
break;
case DI_GLOBAL:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake global"));
break;
default:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_info_error_wakeup - invalid di_type"));
break;
}
}
return;
}
}
dsa_info_fail_wakeup(on)
struct oper_act * on;
{
/*
* Last attempt to get dsa info failed somehow.
* If there are any more "di_block"s to attempt it must be
* worth a go (perhaps this depends on the failure which
* has occurrred).
*/
if(on->on_dsas)
{
if(oper_chain(on) == OK)
return;
}
if(on->on_dsas)
{
/* oper_chain must be awaiting deferred di_blocks */
return;
}
/*
* There is nowhere left to chain this operation to so no way to get
* the dsa info required. Walk through the wake up list extracting,
* waking things up and tidying up afterwords.
*/
}
char * get_entry_passwd (as)
Attr_Sequence as;
{
extern AttributeType at_password;
Attr_Sequence at;
if ((at = as_find_type (as,at_password)) == NULLATTR)
return (NULLCP);
if (at->attr_value == NULLAV)
return (NULLCP);
if (at->attr_value->avseq_av.av_struct == NULL)
return (NULLCP);
return( (char *)at->attr_value->avseq_av.av_struct);
}
make_dsa_bind_arg (arg)
struct ds_bind_arg *arg;
{
#ifdef NEXT_VERSION
Entry my_entry;
char * passwd;
arg->dba_version = DBA_VERSION_V1988;
arg->dba_auth_type = DBA_AUTH_SIMPLE;
arg->dba_time1 = NULLCP;
arg->dba_time2 = NULLCP;
if ((my_entry = local_find_entry (mydsadn ,TRUE)) == NULLENTRY) {
arg->dba_dn = NULLDN;
arg->dba_auth_type = DBA_AUTH_NONE;
arg->dba_passwd[0] = 0;
arg->dba_passwd_len = 0;
} else {
arg->dba_dn = dn_cpy(mydsadn);
if ( (passwd = get_entry_passwd(my_entry->e_attributes)) != NULLCP) {
(void) strncpy (arg->dba_passwd,passwd,DBA_MAX_PASSWD_LEN);
arg->dba_passwd_len = strlen (passwd);
} else {
arg->dba_auth_type = DBA_AUTH_NONE;
arg->dba_passwd[0] = 0;
arg->dba_passwd_len = 0;
}
}
#else
arg->dba_version = DBA_VERSION_V1988;
arg->dba_auth_type = DBA_AUTH_SIMPLE;
arg->dba_time1 = NULLCP;
arg->dba_time2 = NULLCP;
arg->dba_passwd[0] = 0;
arg->dba_passwd_len = 0;
arg->dba_dn = dn_cpy(mydsadn);
#endif
}
struct oper_act * make_get_dsa_info_op(dn, di)
DN dn;
struct di_block * di;
{
struct di_block * di_tmp;
struct oper_act * on_tmp;
struct ds_read_arg * arg;
DLOG(log_dsap, LLOG_TRACE, ("make_get_dsa_info_op"));
if((on_tmp = oper_alloc()) == NULLOPER)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_dsa_info_op - out of memory"));
return(NULLOPER);
}
on_tmp->on_type = ON_TYPE_GET_DSA_INFO;
on_tmp->on_arg = &(on_tmp->on_req);
set_my_chain_args(&(on_tmp->on_req.dca_charg), dn);
on_tmp->on_req.dca_dsarg.arg_type = OP_READ;
arg = &(on_tmp->on_req.dca_dsarg.arg_rd);
set_my_common_args(&(arg->rda_common));
arg->rda_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH;
arg->rda_object = dn_cpy(dn); /* The important bit */
arg->rda_eis.eis_allattributes = TRUE;
arg->rda_eis.eis_select = NULLATTR;
arg->rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
on_tmp->on_dsas = di;
for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
{
di_tmp->di_type = DI_OPERATION;
di_tmp->di_oper = on_tmp;
}
return(on_tmp);
}
set_my_chain_args(cha, dn)
struct chain_arg * cha;
DN dn;
{
cha->cha_originator = dn_cpy(mydsadn);
cha->cha_target = dn_cpy(dn);
cha->cha_progress.op_resolution_phase = OP_PHASE_NOTSTARTED;
cha->cha_progress.op_nextrdntoberesolved = OP_PHASE_NOTDEFINED;
cha->cha_trace = NULLTRACEINFO;
cha->cha_aliasderef = CA_NO_ALIASDEREFERENCED;
cha->cha_aliasedrdns = CA_NO_ALIASDEREFERENCED;
cha->cha_returnrefs = FALSE;
cha->cha_reftype = RT_SUBORDINATE;
cha->cha_domaininfo = NULLPE;
cha->cha_timelimit = NULLCP;
}
set_my_common_args(ca)
struct common_args * ca;
{
ca->ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
ca->ca_servicecontrol.svc_prio = SVC_PRIO_HIGH;
ca->ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
ca->ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
ca->ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;
ca->ca_requestor = dn_cpy(mydsadn);
ca->ca_progress.op_resolution_phase = OP_PHASE_NOTSTARTED;
ca->ca_progress.op_nextrdntoberesolved = OP_PHASE_NOTDEFINED;
ca->ca_aliased_rdns = CA_NO_ALIASDEREFERENCED;
ca->ca_security = (struct security_parms *) NULL;
ca->ca_sig = (struct signature *) NULL;
ca->ca_extensions = (struct extension *) NULL;
}
quipu_ctx_supported (ptr)
Entry ptr;
{
AV_Sequence avs, oc_avs();
Attr_Sequence as;
extern OID quipu_dsa_oid;
extern AttributeType at_applctx;
char dap_only = TRUE;
char res = 1;
static OID dsp = NULLOID;
static OID quipu_dsp = NULLOID;
/* return 0 if "ptr" is not a quipu DSA */
/* return 1 if "ptr" represents a quipu_dsa (by objectclass) */
/* return 2 if "ptr" represents a quipu_dsa with quipu context */
/* return -1 if "ptr" represents a DAP only DSA */
/* Should we use QuipuDSP to a non-Quipu DSA, if is claims
* to support it - currently implemented as "NO" ?
*/
if ((avs = oc_avs(ptr->e_attributes)) == NULLAV)
/* no objectclass attribute !!! */
return 0;
if (!check_in_oc (quipu_dsa_oid,avs))
res = 0; /* not a quipu DSA */
if (( as = as_find_type (ptr->e_attributes,at_applctx)) == NULLATTR)
return 1;
if (dsp == NULLOID) {
/* will both be null first time around... */
dsp = oid_cpy (DIR_SYSTEM_AC);
quipu_dsp = oid_cpy (DIR_QUIPU_AC);
}
for (avs=as->attr_value; avs != NULLAV; avs=avs->avseq_next) {
if ((res != 0) && (oid_cmp ((OID)avs->avseq_av.av_struct, quipu_dsp) == 0 ))
return 2;
if (oid_cmp ((OID)avs->avseq_av.av_struct, dsp) == 0 )
dap_only = FALSE;
}
if (dap_only)
return -1;
return res;
}