DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T g

⟦b9d131ee2⟧ TextFile

    Length: 15443 (0x3c53)
    Types: TextFile
    Names: »get_dsa_info.c«

Derivation

└─⟦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« 

TextFile

/* 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;
}