DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦43d17b8fe⟧ TextFile

    Length: 11982 (0x2ece)
    Types: TextFile
    Names: »ds_modify.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/quipu/ds_modify.c« 

TextFile

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