|
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 u
Length: 20746 (0x510a) Types: TextFile Names: »update.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/quipu/update.c«
/* update.c - write EDB back to disk after modify */ #ifndef lint static char *rcsid = "$Header: /f/osi/quipu/RCS/update.c,v 7.1 89/12/19 16:20:54 mrose Exp $"; #endif /* * $Header: /f/osi/quipu/RCS/update.c,v 7.1 89/12/19 16:20:54 mrose Exp $ * * * $Log: update.c,v $ * Revision 7.1 89/12/19 16:20:54 mrose * sync * * Revision 7.0 89/11/23 22:18:18 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/entry.h" #include "tailor.h" #include "quipu/read.h" #include "quipu/dua.h" #include "quipu/connection.h" #ifndef NO_STATS extern LLog * log_stat; #endif extern int dn_print (); extern LLog * log_dsap; extern char remote_lookup; extern int local_slave_size; extern int slave_edbs; struct oper_act * oper_alloc(); struct oper_act * make_get_edb_op(); /* routine name is historic - not significant */ journal (myentry) Entry myentry; { char * filename, *dn2edbfile(); char savefile [LINESIZE], newfile[LINESIZE]; DN dn; extern char * treedir; extern char * parse_file; Entry liststart; extern int errno; if (myentry == NULLENTRY) { LLOG (log_dsap,LLOG_FATAL,("update edb problem")); return NOTOK; } if ((myentry->e_parent != NULLENTRY) && (myentry->e_parent->e_leaf)) { liststart = myentry; dn = get_copy_dn (liststart->e_parent); if ((filename = dn2edbfile (dn)) == NULLCP) { dn_free (dn); return NOTOK; } myentry->e_parent->e_leaf = FALSE; /* not a leaf now !! */ if ( write_edb(liststart,filename) != OK) return NOTOK; } else { if (myentry->e_parent == NULLENTRY) { liststart = myentry; dn = NULLDN; } else { liststart = myentry->e_parent->e_child; dn = get_copy_dn (liststart->e_parent); } if ((filename = dn2edbfile (dn)) == NULLCP) { dn_free (dn); return NOTOK; } (void) strcpy (newfile,filename); (void) strcat (newfile,".new"); if ( write_edb(liststart,newfile) != OK) { (void) unlink (newfile); return NOTOK; } (void) strcpy (savefile,filename); (void) strcat (savefile,".bak"); (void) unlink (savefile); if (link (filename, savefile) == NOTOK) SLOG (log_dsap, LLOG_EXCEPTIONS, savefile, ("unable to link %s to", filename)); if (rename (newfile, filename) == NOTOK) { SLOG (log_dsap, LLOG_EXCEPTIONS, filename, ("unable to rename %s to", newfile)); if (link (savefile, filename) == NOTOK && !fileexists (filename)) LLOG (log_dsap, LLOG_EXCEPTIONS, ("and couldn't get old file back - PANIC!!!")); return NOTOK; } } return OK; } modify_attr (eptr,who) Entry eptr; DN who; { AttributeType at; AttributeValue av; AV_Sequence avs; Attr_Sequence as, old; extern int no_last_mod; extern char *new_version (); if (no_last_mod) return; if ((at = AttrT_new (LAST_MOD_OID)) == NULLAttrT) { LLOG (log_dsap, LLOG_EXCEPTIONS, ("last mod oid missing")); return; } av = AttrV_alloc (); av->av_syntax = str2syntax ("UTCTime"); av->av_struct = (caddr_t) new_version(); avs = avs_comp_new(av); if ((old = as_find_type (eptr->e_attributes,at)) == NULLATTR) { as = as_comp_new (at,avs,NULLACL_INFO); eptr->e_attributes = as_merge (eptr->e_attributes,as); } else { avs_free (old->attr_value); old->attr_value = avs; AttrT_free (at); } if ((at = AttrT_new (MOD_BY_OID)) == NULLAttrT) { LLOG (log_dsap, LLOG_EXCEPTIONS, ("last mod by oid missing")); return; } av = AttrV_alloc (); av->av_syntax = str2syntax ("DN"); av->av_struct = (caddr_t) dn_cpy (who); avs = avs_comp_new(av); if ((old = as_find_type (eptr->e_attributes,at)) == NULLATTR) { as = as_comp_new (at,avs,NULLACL_INFO); eptr->e_attributes = as_merge (eptr->e_attributes,as); } else { avs_free (old->attr_value); old->attr_value = avs; AttrT_free (at); } } do_get_edb (arg,error,result,binddn) struct getedb_arg *arg; struct DSError *error; struct getedb_result *result; DN binddn; { Entry eptr; extern DN mydsadn; Entry my_entry; AV_Sequence avs; struct edb_info * dsainfo; char proceed = FALSE; struct dn_seq * dnseq; struct di_block * di; (void) dn_decode (arg->ga_entry); DLOG (log_dsap,LLOG_DEBUG,("getedb '%s'",arg->ga_version)); switch(really_find_entry (arg->ga_entry,FALSE,NULLDNSEQ,FALSE,&(eptr),error,&(di))) { case DS_OK: /* * Entry has been found and returned via eptr. * Go through and process this entry. */ break; case DS_CONTINUE: /* * Get edb operations should never generate referrals. * Free the di_blocks generated and return an error. */ error->dse_type = DSE_SERVICEERROR; error->ERR_SERVICE.DSE_sv_problem = DSE_SV_CHAININGREQUIRED; return (DS_X500_ERROR); case DS_X500_ERROR: /* something wrong with the request - error should be filled out */ return(DS_X500_ERROR); default: LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_get_edb() - really_find_entry() failed")); error->dse_type = DSE_SERVICEERROR; error->ERR_SERVICE.DSE_sv_problem = DSE_SV_DITERROR; return (DS_X500_ERROR); } if ((my_entry = local_find_entry (mydsadn,TRUE)) == NULLENTRY) fatal (84,"my entry has gone - no getedb"); /* Check we will send to this DSA */ for (avs = my_entry->e_dsainfo->dsa_attr ; avs != NULLAV; avs=avs->avseq_next) { if (avs->avseq_av.av_struct == NULL) continue; dsainfo = (struct edb_info *) avs->avseq_av.av_struct; if (dn_cmp(dsainfo->edb_name,arg->ga_entry) == 0) { for (dnseq=dsainfo->edb_allowed; dnseq!=NULLDNSEQ; dnseq=dnseq->dns_next) { if (dn_cmp(dnseq->dns_dn,binddn) == 0) { proceed = TRUE; break; } } } if (proceed) break; } if (!proceed) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; return (DS_ERROR_REMOTE); } if ((eptr->e_child == NULLENTRY) || ((eptr->e_child->e_data != E_DATA_MASTER) && (eptr->e_child->e_data != E_TYPE_SLAVE))) { error->dse_type = DSE_SERVICEERROR; error->ERR_SERVICE.DSE_sv_problem = DSE_SV_DITERROR; return (DS_X500_ERROR); } if (eptr->e_edbversion != NULLCP) { DLOG(log_dsap, LLOG_DEBUG, ("edb_ver = %s", eptr->e_edbversion)); if (lexequ (arg->ga_version,eptr->e_edbversion) == 0) { result->gr_version = eptr->e_edbversion; result->gr_edb = NULLENTRY; result->gr_next = NULL_GETRESULT; return (DS_OK); } } else eptr->e_edbversion = new_version(); result->gr_version = eptr->e_edbversion; result->gr_edb = eptr->e_child; result->gr_next = NULL_GETRESULT; return (DS_OK); } slave_update () { extern time_t lastedb_update, time(); (void) update_aux (NULLDN, 0); lastedb_update = time((time_t *)0); } update_aux (dn, isroot) DN dn; int isroot; { Entry my_entry, make_path(); Entry find_sibling(); extern DN mydsadn; struct edb_info * dsainfo; Entry eptr; static char *version = NULLCP; AV_Sequence avs; AV_Sequence avs_head; int success; DLOG (log_dsap,LLOG_TRACE,("slave update")); if ((my_entry = local_find_entry (mydsadn,TRUE)) == NULLENTRY) fatal (82,"Can't update slaves - my entry has gone"); avs_head = avs_cpy(my_entry->e_dsainfo->dsa_attr); #ifdef REMOVE_FOR_6_0 { int loop; for (loop=0 ; loop <2 ; loop++) { #endif for (avs = avs_head ; avs != NULLAV; avs=avs->avseq_next) { if (avs->avseq_av.av_struct == NULL) continue; dsainfo = (struct edb_info *) avs->avseq_av.av_struct; if (dsainfo->edb_getfrom == NULLDN) continue; /* not an EDB to update */ if ((dn || isroot) && dn_cmp (dn, dsainfo -> edb_name) != OK) continue; /* not an EDB this time */ if ((eptr = local_find_entry (dsainfo->edb_name,FALSE)) == NULLENTRY) { version = "0000000000Z"; eptr = make_path (dsainfo->edb_name); } else { if((version = eptr->e_edbversion) == NULLCP) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("update_aux: edbversion was NULLCP")); version = "0000000000Z"; } } #ifdef REMOVE_FOR_6_0 success = send_get_edb(version, dsainfo->edb_name, dsainfo->edb_getfrom,loop); #else success = send_get_edb(version, dsainfo->edb_name, dsainfo->edb_getfrom); #endif if(dn || isroot) break; dsa_wait (0); /* accept any results of previous ops */ } #ifdef REMOVE_FOR_6_0 } } #endif avs_free (avs_head); return((dn || isroot) ? success : OK); } #ifdef REMOVE_FOR_6_0 int send_get_edb (version,dn,from,loop) char * version; DN dn,from; int loop; #else int send_get_edb (version,dn,from) char * version; DN dn,from; #endif { struct di_block * di; struct DSError error; struct oper_act * on; char buffer[BUFSIZ]; PS ps; #ifdef REMOVE_FOR_6_0 Entry ptr; if ((ptr = local_find_entry (from,FALSE)) != NULLENTRY) if (quipu_ctx_supported (ptr) == 1) { /* probably 5.0 based - send SYNC DAP call */ if (loop == 0) do_sync_getedb (dn,ptr); return OK; } if (loop == 0) return OK; #endif switch(get_dsa_info(from, NULLDNSEQ, &(error), &(di))) { case DS_OK: /* * di is a completed dsa info block * Make a get_edb operation from it, attempt to send the operation * and link the operation onto the global list of get_edb * operations. */ if (ps = ps_alloc (str_open)) { if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) { ps_printf (ps, "contact "); dn_print (ps, from, EDBOUT); ps_printf (ps, " for "); if (dn) dn_print (ps, dn, EDBOUT); *ps -> ps_ptr = NULL; LLOG (log_dsap, LLOG_NOTICE, ("%s", buffer)); } (void) ps_free (ps); } #ifdef DEBUG DLOG(log_dsap, LLOG_DEBUG, ("send_get_edb - get_dsa_info OK:")); di_list_log(di); #endif if((on = make_get_edb_op(dn, version, di)) == NULLOPER) { /* Flake out screaming */ LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op failed for send_get_edb")); return(NOTOK); } if(oper_chain(on) != OK) { LLOG(log_dsap, LLOG_NOTICE, ("Could not chain a getEDB operation")); return(NOTOK); } on->on_next_task = get_edb_ops; get_edb_ops = on; return(OK); case DS_CONTINUE: /* * di is a deferred dsa info block * make the operation and suspend waiting for the di_block to be * woken up. */ #ifdef DEBUG DLOG(log_dsap, LLOG_DEBUG, ("send_get_edb - get_dsa_info CONT:")); di_list_log(di); #endif if((on = make_get_edb_op(dn, version, di)) == NULLOPER) { /* Flake out screaming */ LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op failed for send_get_edb")); return(NOTOK); } on->on_state = ON_DEFERRED; on->on_next_task = get_edb_ops; get_edb_ops = on; if (ps = ps_alloc (str_open)) { if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) { ps_printf (ps, "contact "); dn_print (ps, from, EDBOUT); ps_printf (ps, " for "); if (dn) dn_print (ps, dn, EDBOUT); *ps -> ps_ptr = NULL; LLOG (log_dsap, LLOG_NOTICE, ("%s", buffer)); } (void) ps_free (ps); } return(OK); case DS_X500_ERROR: /* Error encountered generating di_block */ LLOG(log_dsap, LLOG_NOTICE, ("send_get_edb - get_dsa_info returned X500 ERROR")); log_ds_error (&error); ds_error_free (&error); return(NOTOK); default: LLOG(log_dsap, LLOG_EXCEPTIONS, ("send_get_edb - get_dsa_info unexpected return")); return(NOTOK); } /* NOTREACHED */ } process_edb(on) struct oper_act * on; { extern DN mydsadn; Entry make_path(), find_sibling(); Entry new_entry, old_entry, temp, sibl, next; Entry eptr; /* up 'n' down to make sure first child !!! */ struct DSError error; struct getedb_result * result = &(on->on_resp.resp_res.dcr_dsres.res_ge); int entry_cnt = 0; if ((eptr = local_find_entry (on->on_req.dca_dsarg.arg_ge.ga_entry,FALSE)) == NULLENTRY) { LLOG (log_dsap, LLOG_EXCEPTIONS, ("Updating something which does not exist !!!")); return; } if ((new_entry = result->gr_edb) == NULLENTRY) { DLOG (log_dsap, LLOG_NOTICE,(" EDBs are the same (%d): %s",on->on_id,on->on_getedb_ver)); return; } else { DLOG (log_dsap, LLOG_NOTICE,(" EDB updated from (%d): %s to: %s", on->on_id,on->on_getedb_ver, result->gr_version)); ; } if (eptr->e_edbversion) free (eptr->e_edbversion); if (result->gr_version == NULLCP) { eptr->e_edbversion = "Unknown"; LLOG(log_dsap, LLOG_EXCEPTIONS, ("EDBRES: NULL version")); } else eptr->e_edbversion = strdup (result->gr_version); for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) { temp->e_parent = eptr; if (unravel_attribute (temp,&error,TRUE) != OK) { LLOG (log_dsap,LLOG_EXCEPTIONS, ("Error in new EDB - continuing with old")); log_ds_error (&error); return; } } for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) { entry_cnt++; if ((old_entry = find_sibling (temp->e_name,eptr->e_child)) != NULLENTRY) { temp->e_leaf = FALSE; temp->e_allchildrenpresent = old_entry->e_allchildrenpresent; temp->e_child = old_entry->e_child; for (sibl = temp->e_child; sibl != NULLENTRY; sibl=sibl->e_sibling) sibl->e_parent = temp; if (old_entry->e_edbversion != NULLCP) temp->e_edbversion = strdup (old_entry->e_edbversion); } } if (eptr->e_child == NULLENTRY) slave_edbs++; for (temp = eptr->e_child; temp != NULLENTRY; temp=next) { next = temp->e_sibling; local_slave_size--; entry_free (temp); } local_slave_size += entry_cnt; eptr->e_child = new_entry; #ifndef NO_STATS { DN tmp_dn; tmp_dn = get_copy_dn (eptr); pslog (log_stat,LLOG_NOTICE,"Slave update",dn_print,(caddr_t)tmp_dn); dn_free (tmp_dn); } #endif if (journal (new_entry) != OK) fatal (-79,"Lost old EDB, can't write new one !!!"); if (local_find_entry (mydsadn,TRUE) == NULLENTRY) fatal (-80,"My entry has disappeared from the DIT !!!"); } /* * get_edb_fail_wakeup suffices for both fail and error conditions * arising on a get edb operation. */ get_edb_fail_wakeup(on) struct oper_act * on; { struct oper_act * on_tmp; struct oper_act **on_p; DLOG(log_dsap, LLOG_TRACE, ("get_edb_fail_wakeup")); /* Should do extra logging here */ on_p = &(get_edb_ops); for(on_tmp = get_edb_ops; on_tmp != NULLOPER; on_tmp = on_tmp->on_next_task) { if(on_tmp == on) break; on_p = &(on_tmp->on_next_task); } if(on_tmp != NULLOPER) { (*on_p) = on_tmp->on_next_task; } else { LLOG(log_dsap, LLOG_EXCEPTIONS, ("get_edb_fail_wakeup - op escaped from get_edb_ops (the global list)")); } oper_conn_extract(on); oper_free(on); } struct oper_act * make_get_edb_op(dn, version, di) DN dn; char * version; struct di_block * di; { struct di_block * di_tmp; struct oper_act * on_tmp; struct getedb_arg * arg; DLOG(log_dsap, LLOG_TRACE, ("make_get_edb_op")); if((on_tmp = oper_alloc()) == NULLOPER) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_edb_op - out of memory")); return(NULLOPER); } on_tmp->on_type = ON_TYPE_GET_EDB; on_tmp->on_arg = &(on_tmp->on_req); on_tmp->on_req.dca_dsarg.arg_type = OP_GETEDB; on_tmp->on_getedb_ver = version; arg = &(on_tmp->on_req.dca_dsarg.arg_ge); arg->ga_entry = dn_cpy(dn); arg->ga_version = strdup(version); DLOG(log_dsap, LLOG_NOTICE, ("EDBARG: ver = %s", arg->ga_version)); on_tmp->on_dsas = di; for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) { #ifdef DEBUG DLOG(log_dsap, LLOG_DEBUG, ("Linking a di_block to this op")); di_log(di_tmp); #endif di_tmp->di_type = DI_OPERATION; di_tmp->di_oper = on_tmp; } return(on_tmp); } get_edb_extract(on) struct oper_act * on; { struct oper_act * on_tmp; struct oper_act **next_on; next_on = &(get_edb_ops); for(on_tmp=get_edb_ops; on_tmp!=NULLOPER; on_tmp=on_tmp->on_next_task) { if(on_tmp == on) break; next_on = &(on_tmp->on_next_task); } if(on_tmp != NULLOPER) { (*next_on) = on_tmp->on_next_task; } else { LLOG(log_dsap, LLOG_EXCEPTIONS, ("Not on get_edb list")); } } #ifdef REMOVE_FOR_6_0 Entry read_edb (version,dn,addr) char ** version; DN dn; struct PSAPaddr * addr; { struct DSError error; static struct ds_bind_arg bindarg; static struct ds_bind_arg bindresult; static struct ds_bind_error binderr; int ad; struct getedb_arg arg; struct getedb_result result; Entry my_entry; extern DN mydsdn; char * passwd, *get_entry_passwd(); /* read from of remote DSA */ /* Do synchronus read for now */ /* Async read eventually */ { char buffer[BUFSIZ]; PS ps; if (ps = ps_alloc (str_open)) { if (str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) { ps_printf (ps, "SYNC update of @"); if (dn) dn_print (ps, dn, EDBOUT); *ps -> ps_ptr = NULL; /* XXX: should be NOTICE, but since we are synchronous... */ LLOG (log_dsap, LLOG_EXCEPTIONS, ("%s", buffer)); } (void) ps_free (ps); } } bindarg.dba_version = DBA_VERSION_V1988; bindarg.dba_auth_type = DBA_AUTH_SIMPLE; bindarg.dba_time1 = NULLCP; bindarg.dba_time2 = NULLCP; if ((my_entry = local_find_entry (mydsadn ,TRUE)) == NULLENTRY) { bindarg.dba_dn = NULLDN; bindarg.dba_auth_type = DBA_AUTH_NONE; bindarg.dba_passwd[0] = 0; bindarg.dba_passwd_len = 0; } else { bindarg.dba_dn = dn_cpy(mydsadn); if ( (passwd = get_entry_passwd(my_entry->e_attributes)) != NULLCP) { (void) strncpy (bindarg.dba_passwd,passwd,DBA_MAX_PASSWD_LEN); bindarg.dba_passwd_len = strlen (passwd); } else { bindarg.dba_auth_type = DBA_AUTH_NONE; bindarg.dba_passwd[0] = 0; bindarg.dba_passwd_len = 0; } } if (dap_bind (&ad, &bindarg, &binderr, &bindresult,addr) != OK) { LLOG (log_dsap,LLOG_EXCEPTIONS,("getedb bind failed")); bind_arg_free (&bindarg); return (NULLENTRY); } bind_arg_free (&bindarg); bind_arg_free (&bindresult); arg.ga_entry = dn; arg.ga_version = *version; DLOG(log_dsap, LLOG_NOTICE, ("EDBARG: ver = %s", arg.ga_version)); if (getedb (&arg,&error,&result,ad) != OK) { LLOG (log_dsap,LLOG_EXCEPTIONS,("getedb remote operation failed")); log_ds_error (&error); ds_error_free (&error); (void) dap_unbind (ad); return (NULLENTRY); } (void) dap_unbind (ad); *version = result.gr_version; if (result.gr_version == NULLCP) LLOG(log_dsap, LLOG_NOTICE, ("EDBRES: NULL version")); else DLOG(log_dsap, LLOG_NOTICE, ("EDBRES: ver = %s", result.gr_version)); /* XXX: should be NOTICE, but since we are synchronous... */ if (result.gr_edb == NULLENTRY) LLOG (log_dsap, LLOG_EXCEPTIONS, (" EDBs are the same: %s", *version)); else LLOG (log_dsap, LLOG_EXCEPTIONS, (" EDB updated: %s", *version)); return (result.gr_edb); } do_sync_getedb (dn, dsa) DN dn; Entry dsa; { Entry make_path(); Entry find_sibling(); extern DN mydsadn; Entry new_entry, eptr, old_entry, temp, sibl, next; struct DSError error; static char *version = NULLCP; int entry_cnt = 0; DLOG (log_dsap,LLOG_TRACE,("slave update")); if ((eptr = local_find_entry (dn,FALSE)) == NULLENTRY) { version = "0000000000Z"; eptr = make_path (dn); } else version = eptr->e_edbversion; if ((new_entry = read_edb (&version,dn,dsa->e_dsainfo->dsa_addr)) == NULLENTRY) return; if (version == NULLCP) eptr->e_edbversion = "Unknown"; else eptr->e_edbversion = strdup (version); for (temp = new_entry; temp != NULLENTRY; temp=temp->e_sibling) { temp->e_parent = eptr; entry_cnt++; if (unravel_attribute (temp,&error,TRUE) != OK) { LLOG (log_dsap,LLOG_EXCEPTIONS, ("Error in new EDB - continuing with old")); log_ds_error (&error); return; } if ((old_entry = find_sibling (temp->e_name,eptr->e_child)) != NULLENTRY) { temp->e_leaf = FALSE; temp->e_allchildrenpresent = old_entry->e_allchildrenpresent; temp->e_child = old_entry->e_child; for (sibl = temp->e_child; sibl != NULLENTRY; sibl=sibl->e_sibling) sibl->e_parent = temp; if (old_entry->e_edbversion != NULLCP) temp->e_edbversion = strdup (old_entry->e_edbversion); } } for (temp = eptr->e_child; temp != NULLENTRY; temp=next) { next = temp->e_sibling; local_slave_size--; entry_free (temp); } local_slave_size += entry_cnt; eptr->e_child = new_entry; if (journal (new_entry) != OK) fatal (-45,"Lost old EDB, can't write new one !!!"); #ifndef NO_STATS else pslog (log_stat,LLOG_NOTICE,"slave update",dn_print,(caddr_t)dn); #endif if (local_find_entry (mydsadn,TRUE) == NULLENTRY) fatal (-80,"My entry has disappeared form the DIT !!!"); } #endif