|
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: 11982 (0x2ece) Types: TextFile Names: »ds_modify.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/quipu/ds_modify.c«
/* ds_modify.c - */ #ifndef lint static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_modify.c,v 6.0 89/03/18 23:41:19 mrose Rel $"; #endif /* * $Header: /f/osi/quipu/RCS/ds_modify.c,v 6.0 89/03/18 23:41:19 mrose Rel $ * * * $Log: ds_modify.c,v $ * Revision 6.0 89/03/18 23:41:19 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/modify.h" #include "config.h" static check_remove_values (); static check_remove_type (); extern Entry database_root; extern LLog * log_dsap; #ifndef NO_STATS extern LLog * log_stat; extern int dn_print (); #endif struct acl *acl_list; int updateerror; do_ds_modifyentry (arg, error, binddn, target) struct ds_modifyentry_arg *arg; struct DSError *error; DN binddn; DN target; { Entry entryptr; Entry real_entry; struct entrymod *eptr; Entry entry_cpy (); int remove = NOTOK; extern AttributeType at_control; char * new_version (); DLOG (log_dsap,LLOG_TRACE,("ds_modifyentry")); if (target == NULLDN) target = arg->mea_object; #ifndef NO_STATS dn_decode (target); pslog (log_stat,LLOG_NOTICE,"modify",dn_print,(caddr_t)target); #endif /* stop aliases being dereferenced */ arg->mea_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; /* check for control sequence */ if (arg->mea_changes->em_type == EM_ADDATTRIBUTE) { as_decode (arg->mea_changes->em_what); if ( AttrT_cmp (arg->mea_changes->em_what->attr_type,at_control) == 0) { int res; res = dsa_control (arg->mea_changes->em_what,error,binddn); return (res); } } if ((real_entry = find_master_entry (target,&arg->mea_common,error,binddn)) != NULLENTRY) { if (real_entry->e_parent == NULLENTRY) { error->dse_type = DSE_NAMEERROR; error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; error->ERR_NAME.DSE_na_matched = NULLDN; return (DS_ERROR_REMOTE); } if (real_entry->e_parent->e_lock) { error->dse_type = DSE_SERVICEERROR; error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; return (DS_ERROR_REMOTE); } entryptr = entry_cpy (real_entry); acl_list = real_entry->e_acl; /* set up acl pointers in new entry */ if (unravel_attribute (entryptr,error,TRUE) != OK) { error->dse_type = DSE_SERVICEERROR; error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED; entry_free (entryptr); LLOG (log_dsap,LLOG_EXCEPTIONS,("modify - serious copying error")); return (DS_ERROR_REMOTE); } if (check_acl (binddn, ACL_ADD, acl_list->ac_entry,target) == NOTOK) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; entry_free (entryptr); return (DS_ERROR_REMOTE); } if (check_acl (binddn, ACL_WRITE, acl_list->ac_entry,target) == OK) remove = OK; for (eptr = arg->mea_changes; eptr!=NULLMOD; eptr=eptr->em_next){ as_decode (eptr->em_what); switch (eptr->em_type) { case EM_ADDVALUES: if (mod_add_value (entryptr,eptr->em_what,error,binddn,target) != OK) { entry_free (entryptr); return (DS_ERROR_REMOTE); } break; case EM_ADDATTRIBUTE: if (add_attribute (entryptr,eptr->em_what,error,binddn,target) != OK) { entry_free (entryptr); return (DS_ERROR_REMOTE); } break; case EM_REMOVEATTRIBUTE: /* must not do this if attribute is rdn */ if (check_remove_type (entryptr->e_name,eptr->em_what->attr_type) == NOTOK) { error->dse_type = DSE_UPDATEERROR; error->ERR_UPDATE.DSE_up_problem = updateerror;; entry_free (entryptr); return (DS_ERROR_REMOTE); } if (remove == OK) { if (remove_attribute (entryptr,eptr->em_what->attr_type,error,binddn,target) != OK) { entry_free (entryptr); return (DS_ERROR_REMOTE); } } else { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; entry_free (entryptr); return (DS_ERROR_REMOTE); } break; case EM_REMOVEVALUES: if (check_remove_values (entryptr->e_name, eptr->em_what) == NOTOK) { error->dse_type = DSE_UPDATEERROR; error->ERR_UPDATE.DSE_up_problem = updateerror;; entry_free (entryptr); return (DS_ERROR_REMOTE); } if (remove == OK) { if (remove_value (entryptr,eptr->em_what,error,binddn,target) != OK) { entry_free (entryptr); return (DS_ERROR_REMOTE); } } else { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; entry_free (entryptr); return (DS_ERROR_REMOTE); } break; } } if (unravel_attribute (entryptr,error,TRUE) != OK) { entry_free (entryptr); return (DS_ERROR_REMOTE); } else if (check_schema (entryptr,NULLATTR,error,TRUE) == OK) { /* changes made OK, so add new entry into tree */ if (entryptr->e_parent == NULLENTRY) { database_root = entryptr; entry_free (real_entry); } else { /* we MUST be the first child - see find_entry */ entryptr->e_parent->e_child = entryptr; entry_free (real_entry); /* now alter all parent pointers */ for (real_entry = entryptr->e_child; real_entry!=NULLENTRY; real_entry=real_entry->e_sibling) real_entry->e_parent = entryptr; } if (entryptr->e_parent != NULLENTRY) entryptr->e_parent->e_edbversion = new_version(); if (journal (entryptr) != OK) fatal (-33,"modify rewrite failed - check database"); return (DS_OK); } else { entry_free (entryptr); return (DS_ERROR_REMOTE); } } else if (error->dse_type == DSE_REFERRAL) { return (DS_ERROR_CONNECT); } return (DS_ERROR_REMOTE); } remove_attribute (eptr,at,error,requestor,dn) Entry eptr; AttributeType at; struct DSError *error; DN requestor,dn; { register Attr_Sequence as, trail= NULLATTR; DLOG (log_dsap,LLOG_DEBUG,("remove attribute")); AttrT_decode (at); for (as=eptr->e_attributes; as!=NULLATTR; as=as->attr_link) { if ((AttrT_cmp (as->attr_type,at)) == 0) break; trail = as; } if (as == NULLATTR) { error->dse_type = DSE_ATTRIBUTEERROR; error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (at); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; return (DS_ERROR_REMOTE); } if (check_acl(requestor,ACL_WRITE,as->attr_acl,dn) == NOTOK) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; return (NOTOK); } if (trail == NULLATTR) { /* first in sequence */ eptr->e_attributes = as->attr_link; as_comp_free (as); } else as_delnext (trail); return (OK); } static check_remove_type (rdn,at) register RDN rdn; register AttributeType at; { extern AttributeType at_objectclass; #ifdef STOP_OBJECTCLASS_MODS if ( AttrT_cmp (at,at_objectclass) == 0) { updateerror = DSE_UP_NOOBJECTCLASSMODS; return (NOTOK); } #endif /* check attribute type is not distinguished */ for (; rdn!=NULLRDN; rdn=rdn->rdn_next) if (AttrT_cmp (rdn->rdn_at,at) == 0) { updateerror = DSE_UP_NOTONRDN; return (NOTOK); } return (OK); } static check_remove_values (rdn,as) register RDN rdn; register Attr_Sequence as; { register AV_Sequence as_avs; struct DSError error; extern AttributeType at_objectclass; #ifdef STOP_OBJECTCLASS_MODS if ( AttrT_cmp (as->attr_type,at_objectclass) == 0) { updateerror = DSE_UP_NOOBJECTCLASSMODS; return (NOTOK); } #endif /* check that the value trying to remove is not distinguished */ for (; rdn!=NULLRDN; rdn=rdn->rdn_next) if (AttrT_cmp (rdn->rdn_at,as->attr_type) == 0) for (as_avs=as->attr_value; as_avs!=NULLAV; as_avs=as_avs->avseq_next) if (AttrV_cmp (rdn->rdn_av,as_avs->avseq_av,&error) == 0) { ds_error_free (&error); updateerror = DSE_UP_NOOBJECTCLASSMODS; return (NOTOK); } return (OK); } remove_value (eptr,rmas,error,requestor,dn) Entry eptr; Attr_Sequence rmas; struct DSError *error; DN requestor,dn; { register Attr_Sequence as; register AV_Sequence avs,trail = NULLAV; int i; DLOG (log_dsap,LLOG_DEBUG,("remove attribute value")); for (as=eptr->e_attributes; as!=NULLATTR; as=as->attr_link) { if ((AttrT_cmp (as->attr_type,rmas->attr_type)) == 0) break; } if (as == NULLATTR) { error->dse_type = DSE_ATTRIBUTEERROR; error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (rmas->attr_type); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; return (DS_ERROR_REMOTE); } if (check_acl(requestor,ACL_WRITE,as->attr_acl,dn) == NOTOK) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; return (NOTOK); } for (avs=as->attr_value; avs!=NULLAV; avs=avs->avseq_next) { if ((i = AttrV_cmp(avs->avseq_av,rmas->attr_value->avseq_av,error)) == 0) break; if (i == -2) { error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (as->attr_type); return (DS_ERROR_REMOTE); } trail = avs; } if (avs == NULLAV) { error->dse_type = DSE_ATTRIBUTEERROR; error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (rmas->attr_type); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = AttrV_cpy (rmas->attr_value->avseq_av); error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; return (DS_ERROR_REMOTE); } if (trail == NULLAV) { /* first in sequence */ as->attr_value = avs->avseq_next; avs_comp_free (avs); } else avs_delnext (trail); return (OK); } add_attribute (eptr,newas,error,requestor,dn) Entry eptr; Attr_Sequence newas; struct DSError *error; DN requestor,dn; { DLOG (log_dsap,LLOG_DEBUG,("add attribute")); if (as_find_type (eptr->e_attributes,newas->attr_type) != NULLATTR) { error->dse_type = DSE_UPDATEERROR; error->ERR_UPDATE.DSE_up_problem = DSE_UP_ALREADYEXISTS; DLOG (log_dsap,LLOG_DEBUG,("add exists error")); return (NOTOK); } if (check_acl(requestor,ACL_WRITE,acl_list->ac_default,dn) == NOTOK) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; DLOG (log_dsap,LLOG_DEBUG,("add acl failed")); return (NOTOK); } eptr->e_attributes = as_merge (as_cpy(newas),eptr->e_attributes); return (OK); } mod_add_value (eptr,newas,error,requestor,dn) Entry eptr; Attr_Sequence newas; struct DSError *error; DN requestor,dn; { register Attr_Sequence as; DLOG (log_dsap,LLOG_DEBUG,("add value")); if ( (as = as_find_type (eptr->e_attributes,newas->attr_type)) == NULLATTR) { error->dse_type = DSE_ATTRIBUTEERROR; error->ERR_ATTRIBUTE.DSE_at_name = dn_cpy (dn); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_NOSUCHATTRIBUTE; error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (newas->attr_type); error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; return (NOTOK); } if (check_acl(requestor,ACL_WRITE,as->attr_acl,dn) == NOTOK) { error->dse_type = DSE_SECURITYERROR; error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; DLOG (log_dsap,LLOG_DEBUG,("add acl failed")); return (NOTOK); } eptr->e_attributes = as_merge (as_cpy(newas),eptr->e_attributes); return (OK); }