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