|
|
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 f
Length: 15902 (0x3e1e)
Types: TextFile
Names: »find_entry.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/quipu/find_entry.c«
/* 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));
}