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 f

⟦7b0b88d7f⟧ TextFile

    Length: 15902 (0x3e1e)
    Types: TextFile
    Names: »find_entry.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/quipu/find_entry.c« 

TextFile

/* find_entry.c - */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/find_entry.c,v 7.0 89/11/23 22:17:40 mrose Rel $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/find_entry.c,v 7.0 89/11/23 22:17:40 mrose Rel $
 *
 *
 * $Log:	find_entry.c,v $
 * Revision 7.0  89/11/23  22:17:40  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/commonarg.h"
#include "quipu/entry.h"
#include "quipu/ds_error.h"
#include "quipu/connection.h"

extern Entry database_root;
extern LLog * log_dsap;
extern time_t time();

int	  find_entry (object,ca,acl_who,dn_stack,master,ent_p,err,di_p)
DN		  object;
common_args	* ca;
DN		  acl_who;
struct dn_seq	* dn_stack;
int		  master;
Entry		* ent_p;
struct DSError	* err;
struct di_block	**di_p;
{
int deref = FALSE;
extern time_t cache_timeout;
DN dn_found;
int res;

	DLOG (log_dsap,LLOG_TRACE,("find_entry"));
	(void) dn_decode (acl_who);
	err->dse_type = DSE_NOERROR;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0) 
		deref = TRUE;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0)
		master = TRUE;

	switch(really_find_entry(object,deref,dn_stack,master,ent_p,err,di_p))
	{
	case DS_OK:
	    DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: OK"));
	    /* Have set up ent_p continue processing */
	    break;

	case DS_CONTINUE:
	    DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: CONT"));
#ifdef DEBUG
	    di_list_log((*di_p));
#endif
	    /* Have set up di_blocks of DSAs to be questioned */
	    return(DS_CONTINUE);

	case DS_X500_ERROR:
	    DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: X500_ERROR"));
	    /* Have set up an error */
	    return(DS_X500_ERROR);

	default:
	    /* Scream */
	    LLOG(log_dsap, LLOG_EXCEPTIONS, ("really_find_entry failed in find_entry 1"));
	    return(DS_ERROR_LOCAL);
	}

	/* if the returned entry is a CONSTRUCTOR, return a referral */
	if ((*ent_p)->e_data == E_TYPE_CONSTRUCTOR) {
	        DLOG(log_dsap, LLOG_DEBUG, ("find_entry - constructor"));
		dn_found = get_copy_dn (*ent_p);
		res = constructor_dsa_info(dn_found,dn_stack,FALSE,(*ent_p),err,di_p);
		dn_free (dn_found);
		return (res);
	}

	/* if the returned entry is a COPY, - check service controls */
	if ((*ent_p)->e_data != E_DATA_MASTER)
		if (master) {
		        DLOG(log_dsap, LLOG_DEBUG, ("find_entry - slave master needed"));
			dn_found = get_copy_dn (*ent_p);
			res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
			dn_free (dn_found);
			return (res);
		}

	if (((*ent_p)->e_data == E_TYPE_CACHE_FROM_MASTER) && 
		( time((time_t *)0) - (*ent_p)->e_age > cache_timeout)) {
	        DLOG(log_dsap, LLOG_DEBUG, ("find_entry - cache timed out"));
		dn_found = get_copy_dn (*ent_p);
		res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
		delete_cache (dn_found);
		dn_free (dn_found);
		return (res);
	}

	if ((*ent_p)->e_parent == NULLENTRY)
	{
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry: (*ent_p)->e_parent is NULLENTRY"));
		return (DS_OK);     /* no acl for root entry */
	}

	if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_parent->e_acl->ac_child, object) == NOTOK) {
		err->dse_type = DSE_SECURITYERROR;
		err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		return (DS_X500_ERROR);
	}

	if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_acl->ac_entry, object) == NOTOK) {
		err->dse_type = DSE_SECURITYERROR;
		err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		return (DS_X500_ERROR);
	}

	return (DS_OK);
}

int	  find_child_entry (object,ca,acl_who,dn_stack,master,ent_p,err,di_p)
DN                        object;
common_args             * ca;
DN    			  acl_who;
struct dn_seq		* dn_stack;
int			  master;
Entry			* ent_p;
struct DSError          * err;
struct di_block		**di_p;
{
/* this is very similar to find_entry(), except a top level */
/* constructor is allowed */
int deref = FALSE;
int res;
DN dn_found;

	DLOG (log_dsap,LLOG_DEBUG,("find_child_entry"));
	(void) dn_decode (acl_who);
	err->dse_type = DSE_NOERROR;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
		deref = TRUE;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0)
		master = TRUE;

	switch(really_find_entry(object,deref,dn_stack,master,ent_p,err,di_p))
	{
	case DS_OK:
	    DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: OK"));
	    /* Have set up ent_p continue processing */
	    break;

	case DS_CONTINUE:
	    DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: CONTINUE"));
#ifdef DEBUG
	    di_list_log((*di_p));
#endif
	    /* Have set up di_blocks of DSAs to be questioned */
	    return(DS_CONTINUE);

	case DS_X500_ERROR:
	    /* Have set up an error */
	    DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: X500_ERROR"));
	    return(DS_X500_ERROR);

	default:
	    /* Scream */
	    LLOG(log_dsap, LLOG_EXCEPTIONS, ("really_find_entry failed in find_entry 1"));
	    return(DS_ERROR_LOCAL);
	}

	/* check to see if children OK */
	if (((*ent_p)->e_child != NULLENTRY) && ((*ent_p)->e_allchildrenpresent == TRUE))
	{
	    DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children OK"));
		switch ((*ent_p)->e_child->e_data) {
		case E_DATA_MASTER:
			DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children masters"));
			break;
		case E_TYPE_SLAVE:
			/* see if we can use a copy ... */
			DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children slaves"));
		    	if (master) {
				dn_found = get_copy_dn (*ent_p);
				res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
				dn_free (dn_found);
				return (res);
		    	}
			break;
		default:
			DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - default"));
			dn_found = get_copy_dn (*ent_p);
			res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
			dn_free (dn_found);
			return (res);
		}
	}
	else {
	    DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children NOTOK"));
		if ((*ent_p)->e_leaf)
		{
			DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - leaf"));
			return (DS_OK);
		}
		dn_found = get_copy_dn (*ent_p);
		res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
		dn_free (dn_found);
		return (res);
	}

	if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_acl->ac_child, object) == NOTOK) {
		err->dse_type = DSE_SECURITYERROR;
		err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		return (DS_X500_ERROR);
		}

	return (DS_OK);
}

int	  really_find_entry (object, deref, dn_stack, master, ent_p, err, di_p)
DN		  object;
int		  deref;
struct dn_seq	* dn_stack;
int		  master;	/* Generate only master references - NB
				   does not imply returned entry is master */
Entry		* ent_p;
struct DSError	* err;
struct di_block	**di_p;
{
Entry  trail;
register RDN    a_rdn, b_rdn;
DN     dn, dn_trail = NULLDN;

	DLOG (log_dsap,LLOG_TRACE,("really find entry"));

	if (deref == -2) {
		/* alias loop */
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
		err->ERR_NAME.DSE_na_matched = NULLDN;
		return (DS_X500_ERROR);
	}

	if (dn_decode (object) == NOTOK) {
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_INVALIDATTRIBUTESYNTAX;
		err->ERR_NAME.DSE_na_matched = dn_cpy(object);
		return (DS_X500_ERROR);
	}

	if (database_root == NULLENTRY) {
		LLOG (log_dsap,LLOG_NOTICE,("null root !!!"));
		return(dsa_info_parent(object, err, di_p, master));
	}

	if ((dn = object) == NULLDN)
	{
		DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: database_root"));
		(*ent_p) = database_root;
		return (DS_OK);
	}

	b_rdn = dn->dn_rdn;
	if (((*ent_p) = database_root->e_child) == NULLENTRY) {
		DLOG(log_dsap, LLOG_DEBUG, ("database->e_child == NULLENTRY"));
		return (no_reply_child (object,dn,dn_stack,master,database_root,err,di_p));
	}

	a_rdn = (*ent_p)->e_name ;

	for(;;) { /* break or return out */
		trail = NULLENTRY;
		while (rdn_cmp (a_rdn, b_rdn) != OK) {
			trail = (*ent_p);
			(*ent_p) = (*ent_p)->e_sibling ;
			if ( (*ent_p) == NULLENTRY ) 
				return (no_reply_edb (object,dn_trail,dn_stack,master,trail->e_parent,err,di_p));
			a_rdn = (*ent_p)->e_name ;
		}

		/* make found element first in list - optimistaion */
		if (trail != NULLENTRY) {  /* NOT already the first */
			trail->e_sibling = (*ent_p)->e_sibling;
			(*ent_p)->e_sibling = (*ent_p)->e_parent->e_child;
			(*ent_p)->e_parent->e_child = (*ent_p);
		}

		if ( (*ent_p)->e_alias != NULLDN )
			/* got an alias entry */
			if (deref != FALSE) {
				Entry	  new_entry;
				int	  new_deref;

				err->dse_type = DSE_NAMEERROR;
				new_deref = (deref == -1) ? -2 : -1;
				switch(really_find_entry ((*ent_p)->e_alias,new_deref,dn_stack,master,&(new_entry),err,di_p))
				{
				case DS_OK:
				    DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:OK"));
				    (*ent_p) = new_entry;
				    break;
				case DS_CONTINUE:
				    DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:CONT"));
					DLOG(log_dsap, LLOG_DEBUG, ("Alias ?"));
#ifdef DEBUG
	        			di_list_log((*di_p));
#endif
					return(DS_CONTINUE);
				case DS_X500_ERROR:
				    DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:X500ERR"));
					if ((err->dse_type == DSE_NAMEERROR) && 
						( err->ERR_NAME.DSE_na_problem == DSE_NA_ALIASDEREFERENCE)) {
						if (err->ERR_NAME.DSE_na_matched == NULLDN) {
							DN tmp_dn;
							tmp_dn = dn->dn_parent;
							dn->dn_parent = NULLDN;
							err->ERR_NAME.DSE_na_matched = dn_cpy(object);
							dn->dn_parent = tmp_dn;
						}
						return (DS_X500_ERROR);
					} else {
						ds_error_free (err);
						err->dse_type = DSE_NAMEERROR;
						err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASPROBLEM;
						err->ERR_NAME.DSE_na_matched = dn_cpy((*ent_p)->e_alias);
						return (DS_X500_ERROR);
					}
				default:
				    DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:localerror"));
					return(DS_ERROR_LOCAL);
				}
				

			} else if ( dn->dn_parent == NULLDN)
			{
				DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?1"));
				return(DS_OK);
			}
			else {
				/* alias on route - error in this case */
				DN tmp_dn;
				err->dse_type = DSE_NAMEERROR;
				err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
				tmp_dn = dn->dn_parent;
				dn->dn_parent = NULLDN;
				err->ERR_NAME.DSE_na_matched = dn_cpy(object);
				dn->dn_parent = tmp_dn;
				return (DS_X500_ERROR);
			}


		if ( dn->dn_parent == NULLDN)
		{
			DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?2"));
			return (DS_OK);
		}

		if ( (*ent_p)->e_child == NULLENTRY ) {
			return (no_reply_child (object,dn,dn_stack,master,(*ent_p),err,di_p));
		}

		dn_trail = dn;
		dn = dn->dn_parent;
		b_rdn = dn->dn_rdn;

		(*ent_p) = (*ent_p)->e_child;
		a_rdn = (*ent_p)->e_name;
	}
	/* NOTREACHED */
}


int	  referral_dsa_info (object,dn_stack,master,ptr,err,di_p,chain)
DN		  object;
struct dn_seq	* dn_stack;
int		  master;
Entry		  ptr;
struct DSError	* err;
struct di_block	**di_p;
char chain;
{
int ret;
struct di_block     * di_tmp;

	DLOG (log_dsap,LLOG_TRACE,("referral dsa_info"));
	/* generate a referral to a DUA if possible */

	if (ptr != NULLENTRY)
		ptr=ptr->e_parent;

	if ((ret = constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p)) != DS_CONTINUE)
		return ret;

	/* Try to make a referral - if not schedule a chain !!! */
	if (chain)
		return DS_CONTINUE;

	/* PROBLEM: The following will get the best referral from our point 
	 * of view.  This may not be the same from the DUAs point of view !!!
         */
	sort_dsa_list (di_p);
        for(di_tmp= *di_p; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
        {
                if(di_tmp->di_state == DI_DEFERRED)
                        continue;

                if(di2cref(di_tmp, err, CN_CTX_X500_DAP) == OK)
                    return (DS_X500_ERROR);	/* return the referral !! */
        }
	return DS_CONTINUE;

}

int	  constructor_dsa_info (object,dn_stack,master,ptr,err,di_p)
DN		  object;
struct dn_seq	* dn_stack;
int		  master;
Entry		  ptr;
struct DSError	* err;
struct di_block	**di_p;
{
	DLOG (log_dsap,LLOG_TRACE,("constructor dsa_info"));

	if (ptr != NULLENTRY)
		ptr=ptr->e_parent;
		
	return(constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p));
}

int	  constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p)
DN		  object;
struct dn_seq	* dn_stack;
int		  master;
Entry		  ptr;
struct DSError	* err;
struct di_block	**di_p;
{
	DLOG (log_dsap,LLOG_TRACE,("construct dsa_info aux"));

	/* follow entry back, until something that is not a CONSTRUCTOR */

	for (; ptr!= NULLENTRY; ptr=ptr->e_parent)
		if ((ptr->e_data != E_TYPE_CONSTRUCTOR) && (ptr->e_data != E_TYPE_CACHE_FROM_MASTER)) {
			if ( (ptr->e_master == NULLAV) && (ptr->e_slave == NULLAV))
				continue ;
			return(dsa_info_new(object,dn_stack,master,ptr,err,di_p));
		}

	return(dsa_info_parent(object,err,di_p,master));
}

int	  no_reply_child (object,dn,dn_stack,master,entryptr,err,di_p)
DN		  object;
DN		  dn; 	/* tail - not matched */
struct dn_seq	* dn_stack;
int		  master;
Entry		  entryptr;
struct DSError	* err;
struct di_block	**di_p;
{
DN dn_tmp;
	
	DLOG (log_dsap,LLOG_TRACE,("no reply child"));

	if (entryptr->e_leaf)
	{
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;

		return(DS_X500_ERROR);
	}
	
	if ( (entryptr->e_master != NULLAV) || (entryptr->e_slave != NULLAV))
	{
		return(dsa_info_new (object, dn_stack, master, entryptr, err, di_p));
	}

	if (entryptr->e_child == NULLENTRY) {
		return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
	}

	if ((entryptr->e_child->e_data == E_DATA_MASTER)
		|| ((! master) && (entryptr->e_child->e_data == E_TYPE_SLAVE))) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;
		return(DS_X500_ERROR);
	} 

	return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
}

int	  no_reply_edb (object,dn,dn_stack,master,entryptr,err,di_p)
DN		  object;
DN		  dn; 	/* tail - not matched */
struct dn_seq	* dn_stack;
int		  master;
Entry		  entryptr;
struct DSError	* err;
struct di_block	**di_p;
{
DN dn_tmp;

	DLOG (log_dsap,LLOG_TRACE,("no reply edb"));

	if (entryptr->e_leaf) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;

		return(DS_X500_ERROR);
	}

	if (entryptr->e_child == NULLENTRY) {
		return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
	}

	if ((entryptr->e_child->e_data == E_DATA_MASTER)
		|| ((! master) && (entryptr->e_child->e_data == E_TYPE_SLAVE))) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;
		return(DS_X500_ERROR);
	}

	/* build a referral */
	return(constructor_dsa_info_aux(object,dn_stack,master,entryptr,err,di_p));
}