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 d

⟦de1f27710⟧ TextFile

    Length: 7580 (0x1d9c)
    Types: TextFile
    Names: »ds_list.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/quipu/ds_list.c« 

TextFile

/* ds_list.c - */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_list.c,v 6.0 89/03/18 23:41:18 mrose Rel $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/ds_list.c,v 6.0 89/03/18 23:41:18 mrose Rel $
 *
 *
 * $Log:	ds_list.c,v $
 * Revision 6.0  89/03/18  23:41:18  mrose
 * Release 5.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/entry.h"
#include "quipu/list.h"

extern LLog * log_dsap;
extern Entry database_root;
Entry list_find_entry();
static int build_result();

#ifndef NO_STATS
extern LLog * log_stat;
extern int dn_print ();
#endif


do_ds_list (arg, error, result, binddn, target)
    register struct ds_list_arg          *arg;
    register struct ds_list_result       *result;
    struct DSError                      *error;
    DN                                  binddn;
    DN                                  target;
{
register Entry  entryptr;
ContinuationRef cont_ref_new ();

	DLOG (log_dsap,LLOG_TRACE,("ds_list"));

	if (target == NULLDN)
		target = arg->lsa_object;

#ifndef NO_STATS
	dn_decode (target);
	pslog (log_stat,LLOG_NOTICE,"list",dn_print,(caddr_t)target);
#endif

	if ((entryptr = list_find_entry (target,&arg->lsa_common,error,binddn)) != NULLENTRY) {
		if (entryptr->e_leaf) {
			if ((entryptr->e_master != NULLAV) || (entryptr->e_slave != NULLAV)) {
				if (try_cache (arg,result,target) == OK)
					return (DS_OK);
				error->dse_type = DSE_REFERRAL;
				if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_new (target,entryptr)) == NULLCONTINUATIONREF) {
					error->dse_type = DSE_SERVICEERROR;
					error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
					return (DS_ERROR_REMOTE);
				}
				return (DS_ERROR_CONNECT);
			}

			result->lsr_subordinates = NULLSUBORD;
			result->lsr_age  =  (time_t) 0 ;
			result->lsr_common.cr_requestor = NULLDN;
			result->lsr_object = NULLDN;
			result->lsr_common.cr_aliasdereferenced = FALSE;
			result->lsr_cr = NULLCONTINUATIONREF;
			result->lsr_limitproblem = LSR_NOLIMITPROBLEM;
			return (DS_OK);
		}
		if (entryptr->e_child == NULLENTRY) {
			/* NOT a leaf, but have not got child */
			if (try_cache (arg,result,target) == OK)
				return (DS_OK);
			error->dse_type = DSE_REFERRAL;
			if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_new (target,entryptr)) == NULLCONTINUATIONREF) {
				error->dse_type = DSE_SERVICEERROR;
				error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
				return (DS_ERROR_REMOTE);
			}
			return (DS_ERROR_CONNECT);
		}

		/* check parent will allow listing */
		if (check_acl (binddn,ACL_READ, entryptr->e_acl->ac_child, target) != OK) {
			error->dse_type = DSE_SECURITYERROR;
			error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
			return (DS_ERROR_REMOTE);
		}

		build_result (arg,entryptr->e_child,result,error,binddn);
		return (DS_OK);

	} else if (error->dse_type == DSE_REFERRAL) {
		if (try_cache (arg,result,target) == OK)
			return (DS_OK);
		return (DS_ERROR_CONNECT);
	}

	return (DS_ERROR_REMOTE);
}

static int build_result (arg,ptr,result,error,binddn)
register Entry ptr;
struct ds_list_arg    *arg;
struct ds_list_result *result;
struct DSError * error;
DN binddn;
{
register struct subordinate *sub;
register struct subordinate *trail = NULLSUBORD;
DN dn;
DN dnend;
RDN dnrdn;
int size;
register int cnt;
extern int admin_size;

	DLOG (log_dsap,LLOG_DEBUG,("building list results"));

	result->lsr_subordinates = NULLSUBORD;
	if ((size = MIN(admin_size,arg->lsa_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT)
		size = admin_size;

	result->lsr_age  =  (time_t) 0 ;
	result->lsr_common.cr_requestor = NULLDN;
	/* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */
	/* the alias will have been derefeferenced -signified by   */
	/* NO_ERROR !!! */
	if ( error->dse_type == DSE_NOERROR ) {
		result->lsr_object = NULLDN;
		result->lsr_common.cr_aliasdereferenced = FALSE;
	} else {
		result->lsr_common.cr_aliasdereferenced = TRUE;
		result->lsr_object = get_copy_dn (ptr->e_parent);
	}
	result->lsr_cr = NULLCONTINUATIONREF;

	dn = get_copy_dn (ptr);
	for (dnend = dn; dnend->dn_parent != NULLDN; dnend=dnend->dn_parent)
		;  /* NO-OP */
	dnrdn = dnend->dn_rdn;

	for (cnt =0; (ptr!=NULLENTRY) && (cnt < size) ; ptr=ptr->e_sibling, cnt++) {
		dnend->dn_rdn = ptr->e_name;
		if (check_acl (binddn,ACL_READ,ptr->e_acl->ac_entry,dn) == OK) {
			sub = (struct subordinate *) smalloc (sizeof(struct subordinate));
			sub->sub_copy =  INFO_MASTER;
			sub->sub_rdn = rdn_cpy(ptr->e_name);
			sub->sub_aliasentry = (ptr->e_alias == NULLDN ? FALSE : TRUE);
			if (trail != NULLSUBORD)
				trail->sub_next = sub;
			else
				result->lsr_subordinates = sub;
			trail = sub;
		}
	}
	sub->sub_next = NULLSUBORD;

	if ( (cnt >= size) && (ptr!=NULLENTRY) )
		/* stoped look up due to size limit */
		/* need to send continuation reference */
		result->lsr_limitproblem = LSR_SIZELIMITEXCEEDED;
	else
		result->lsr_limitproblem = LSR_NOLIMITPROBLEM;
	dnend->dn_rdn = NULLRDN;
	dn_free (dn);
	rdn_free (dnrdn);
}


Entry list_find_entry (object,ca,err,acl_who)
DN                      object;
common_args             *ca;
struct DSError          *err;
DN    acl_who;
{

/* this is very similar to find_entry(), except a top level */
/* constructor is allowed */

register Entry  the_entry;
char deref = FALSE;

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

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

	if ((the_entry = really_find_entry (object,err,deref)) == NULLENTRY)
		return (NULLENTRY);

	/* check to see if children OK */
	if ((the_entry->e_child != NULLENTRY) && (the_entry->e_allchildrenpresent == TRUE))
		switch (the_entry->e_child->e_data) {
		case E_DATA_MASTER:
			break;
		case E_TYPE_SLAVE:
			/* see if we can use a copy ... */
		    	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0) {
				constructor_referral_aux (the_entry,err,object) ;
				return (NULLENTRY);
		    	}
			break;
		default:
			constructor_referral_aux (the_entry,err,object) ;
			return (NULLENTRY);
		}
	else {
		if (the_entry->e_leaf)
			return (the_entry);
		constructor_referral_aux (the_entry,err,object) ;
		return (NULLENTRY);
	}

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

	return (the_entry);
}


try_cache (arg,result,target)
    register struct ds_list_arg          *arg;
    register struct ds_list_result       *result;
    DN 					 target;
{
struct list_cache *ptr;
struct subordinate * subord_cpy();

	if ((arg->lsa_common.ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) == 0) {
		if ((ptr = find_list_cache (target,arg->lsa_common.ca_servicecontrol.svc_sizelimit)) != NULLCACHE) {
			DLOG (log_dsap,LLOG_DEBUG,("building list results using cache"));
			result->lsr_subordinates = subord_cpy(ptr->list_subs);
			result->lsr_age  =  (time_t) 0 ;
			result->lsr_common.cr_aliasdereferenced = FALSE;
			result->lsr_common.cr_requestor = NULLDN;
			result->lsr_object = NULLDN;
			result->lsr_cr = NULLCONTINUATIONREF;
			result->lsr_limitproblem = ptr->list_problem;
			return (OK);
		}
	}

	return (NOTOK);
}