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