|
|
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 d
Length: 7580 (0x1d9c)
Types: TextFile
Names: »ds_list.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/quipu/ds_list.c«
/* 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);
}