File:  [CSRG BSD Unix] / 43BSDReno / contrib / isode-beta / quipu / ds_list.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:12:56 2018 UTC (8 years, 1 month ago) by root
Branches: MAIN, BSD
CVS tags: HEAD, BSD43reno
BSD 4.3reno

/* ds_list.c - */

#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/quipu/ds_list.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif

/*
 * $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/quipu/ds_list.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
 *
 *
 * $Log: ds_list.c,v $
 * Revision 1.1.1.1  2018/04/24 16:12:56  root
 * BSD 4.3reno
 *
 * Revision 7.1  90/07/09  14:45:43  mrose
 * sync
 * 
 * Revision 7.0  89/11/23  22:17:09  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/connection.h"
#include "quipu/list.h"

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

do_ds_list (arg, error, result, binddn, target, di_p, dsp)
    register struct ds_list_arg          *arg;
    register struct ds_list_result       *result;
    struct DSError                      *error;
    DN                                  binddn;
    DN                                  target;
    struct di_block			**di_p;
    char				dsp;
{
Entry  entryptr;
int retval;
DN realtarget;

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

	if (!dsp)
		target = arg->lsa_object;

	switch(find_child_entry(target,&(arg->lsa_common),binddn,NULLDNSEQ,FALSE,&(entryptr),error,di_p))
	{
	case DS_OK:
	    /* Filled out entryptr - carry on */
	    break;
	case DS_CONTINUE:
	    /* Filled out di_p - what do we do with it ?? */
	    return(DS_CONTINUE);

	case DS_X500_ERROR:
	    /* Filled out error - what do we do with it ?? */
	    return(DS_X500_ERROR);
	default:
	    /* SCREAM */
	    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_list() - find_child_entry failed"));
	    return(DS_ERROR_LOCAL);
	}

	/* Strong authentication  */
	if ((retval = check_security_parms((caddr_t) arg,
			encode_DAS_ListArgumentData,
			arg->lsa_common.ca_security,
			arg->lsa_common.ca_sig, &binddn)) != 0)
	{
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = retval;
		return (DS_ERROR_REMOTE);
	}

	realtarget = get_copy_dn(entryptr);

	if (entryptr->e_leaf) {
		if ((entryptr->e_master != NULLAV) || (entryptr->e_slave != NULLAV)) {
			int res;
			/* PROBLEM: Might not list everything if user is entitled to more... */
			if (try_cache (arg,result,realtarget) == OK) {
				dn_free (realtarget);
				return (DS_OK);
			}
			res = constructor_dsa_info(realtarget,NULLDNSEQ,FALSE,entryptr,error,di_p);
			dn_free (realtarget);
			return res;
		}

		dn_free (realtarget);

		result->lsr_subordinates = NULLSUBORD;
		result->lsr_age  =  (time_t) 0 ;
		result->lsr_common.cr_requestor = NULLDN;
		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 (entryptr->e_parent);
		}
		result->lsr_cr = NULLCONTINUATIONREF;
		result->lsr_limitproblem = LSR_NOLIMITPROBLEM;
		return (DS_OK);
	}

	/* check parent will allow listing */
	if (check_acl (dsp ? NULLDN : binddn,ACL_READ, entryptr->e_acl->ac_child, realtarget) != OK) {
		if (dsp && (check_acl (binddn,ACL_READ, entryptr->e_acl->ac_child, realtarget) == OK)) {
			error->dse_type = DSE_SECURITYERROR;
			error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION;
			dn_free (realtarget);
			return (DS_ERROR_REMOTE);
		}
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		dn_free (realtarget);
		return (DS_ERROR_REMOTE);
	}

	if (entryptr->e_child == NULLENTRY) {
		int res;
		if (try_cache (arg,result,realtarget) == OK) {
			dn_free (realtarget);
			return (DS_OK);
		}
		res = constructor_dsa_info(realtarget,NULLDNSEQ,FALSE,entryptr,error,di_p);
		dn_free (realtarget);
		return res;		
	}

	dn_free (realtarget);

	build_result (arg,entryptr->e_child,result,error,dsp ? NULLDN : binddn, dsp);
	return (DS_OK);
}

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

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

	result->lsr_subordinates = NULLSUBORD;
	if (!dsp && manager (binddn))
	    size = arg->lsa_common.ca_servicecontrol.svc_sizelimit;
	else 
	    if ((size = MIN(admin_size,arg->lsa_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT) {
		size = admin_size;
		adminlimit = TRUE;
	    }

	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) && (size == SVC_NOSIZELIMIT || cnt < size) ; ptr=ptr->e_sibling) {
		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 = ptr->e_data;
			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;
			cnt++;
		}
	}
	sub->sub_next = NULLSUBORD;

	if ( (size != SVC_NOSIZELIMIT && cnt >= size) && (ptr!=NULLENTRY) )
		/* stopped look up due to size limit */
		/* need to send continuation reference */
		result->lsr_limitproblem = adminlimit ? 
			LSR_ADMINSIZEEXCEEDED : LSR_SIZELIMITEXCEEDED;
	else
		result->lsr_limitproblem = LSR_NOLIMITPROBLEM;

	dnend->dn_rdn = NULLRDN;
	dn_free (dn);
	rdn_free (dnrdn);
}


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);
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.