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

⟦afb1d8b7b⟧ TextFile

    Length: 8079 (0x1f8f)
    Types: TextFile
    Names: »ds_add.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/quipu/ds_add.c« 

TextFile

/* ds_add.c - */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_add.c,v 7.1 90/01/11 18:37:19 mrose Exp $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/ds_add.c,v 7.1 90/01/11 18:37:19 mrose Exp $
 *
 *
 * $Log:	ds_add.c,v $
 * Revision 7.1  90/01/11  18:37:19  mrose
 * real-sync
 * 
 * Revision 7.0  89/11/23  22:17:03  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 "quipu/add.h"
#include "quipu/malloc.h"

extern Entry database_root;
extern LLog * log_dsap;
extern int local_master_size;
extern int encode_DAS_AddEntryArgumentData();

do_ds_addentry (arg, error, binddn,target,di_p,dsp)
    struct ds_addentry_arg      *arg;
    struct DSError              *error;
    DN                          binddn;
    DN                          target;
    struct di_block		**di_p;
    char dsp;
{
Entry  entryptr,ptr;
register DN  dntop, dn = NULLDN;
DN  trail = NULLDN;
extern Entry database_root;
ContinuationRef cont_ref_parent ();
char * new_version ();
int retval;
extern int read_only;

	DLOG (log_dsap,LLOG_TRACE,("ds_add"));

	if (!dsp)
		target = arg->ada_object;

	(void) dn_decode (target);

	/* stop aliases being dereferenced */
	arg->ada_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS;

	error ->dse_type = DSE_NOERROR;
	/* first of all see if entry exists */

	if (target == NULLDN) {
		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);
	}

	switch (find_entry (target,&(arg->ada_common),binddn,NULLDNSEQ,FALSE,&entryptr, error, di_p)) 
	{
	case DS_OK:
		error->dse_type = DSE_UPDATEERROR;
		error->ERR_UPDATE.DSE_up_problem = DSE_UP_ALREADYEXISTS;
		return(DS_ERROR_REMOTE);
	case DS_CONTINUE:
	    /* Filled out di_p - what do we do with it ?? */
	    return(DS_CONTINUE);
	case DS_X500_ERROR:
	    /* Filled out error - what do we do with it ?? */
	    if ((error->dse_type != DSE_NAMEERROR) || (error->ERR_NAME.DSE_na_problem != DSE_NA_NOSUCHOBJECT)) {
		return(DS_X500_ERROR);
	    }
	    ds_error_free (error);  /* not interested - know it does not exist */
	    break;
	default:
	    /* SCREAM */
	    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_read() - find_entry failed"));
	    return(DS_ERROR_LOCAL);
	}

	/* object does not exist, so create it */

	/* Strong authentication  */
	if ((retval = check_security_parms((caddr_t) arg, 
				encode_DAS_AddEntryArgumentData, 
				arg->ada_common.ca_security,
				arg->ada_common.ca_sig, &binddn)) != 0)
	{
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = retval;
		return (DS_ERROR_REMOTE);
	}

	DLOG (log_dsap,LLOG_TRACE,("add - find parent"));

	if ((dntop = dn_cpy(target)) != NULLDN)
		for (dn=dntop; dn->dn_parent != NULLDN; dn=dn->dn_parent)
			trail = dn;

	if (trail == NULLDN) {
		dntop = NULLDN;
		entryptr = database_root;
		if (entryptr->e_data != E_DATA_MASTER) {
			error->dse_type = DSE_REFERRAL;
        		error->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
			if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (NULLDN)) == NULLCONTINUATIONREF) {
				error->dse_type = DSE_SERVICEERROR;
				error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
			}
			return (DS_ERROR_CONNECT);
		}
	} else {
		trail->dn_parent = NULLDN;
		switch(find_child_entry(dntop,&(arg->ada_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p))
		{
		case DS_OK:
		    /* Filled out entryptr - carry on */
		    break;
		case DS_CONTINUE:
		    /* Filled out di_p - what do we do with it ?? */
		    /* When add returns DS_CONTINUE the target must be changed */
		    return(DS_CONTINUE);

		case DS_X500_ERROR:
		    /* Filled out error - what do we do with it ?? */
		    return(DS_X500_ERROR);
		default:
		    /* SCREAM */
		    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_add() - find_child_entry failed"));
		    return(DS_ERROR_LOCAL);
		}
	}

	if ( read_only || ((entryptr->e_parent != NULLENTRY) && (entryptr->e_parent->e_lock))) {
		error->dse_type = DSE_SERVICEERROR;
		error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
		dn_free (dntop);
		dn_free (dn);
		return (DS_ERROR_REMOTE);
	}

	/* not prepared to accept operation over DSP */
	if (dsp) {
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION;
		dn_free (dntop);
		dn_free (dn);
		return (DS_ERROR_REMOTE);
	}

	DLOG (log_dsap,LLOG_TRACE,("add - acl"));
	if (check_acl (binddn,ACL_ADD,entryptr->e_acl->ac_child,dntop) == NOTOK) {
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		dn_free (dntop);
		dn_free (dn);
		return (DS_ERROR_REMOTE);
	}

	DLOG (log_dsap,LLOG_TRACE,("add - default"));

	DATABASE_HEAP;

	ptr = get_default_entry (entryptr);
	ptr->e_name = rdn_cpy (dn->dn_rdn);
	ptr->e_attributes = as_cpy (arg->ada_entry);
 
	modify_attr (ptr,binddn);

	DLOG (log_dsap,LLOG_TRACE,("add - unravel"));
	if (unravel_attribute (ptr,error,TRUE) != OK) {
		dn_free (dntop);
		dn_free (dn);
		entry_free (ptr);
		GENERAL_HEAP;
		return (DS_ERROR_REMOTE);
	}

	DLOG (log_dsap,LLOG_TRACE,("add - schema"));
	if (check_schema (ptr,NULLATTR,error,TRUE) != OK) {
		dn_free (dntop);
		dn_free (dn);
		entry_free (ptr);
		GENERAL_HEAP;
		return (DS_ERROR_REMOTE);
	}

	GENERAL_HEAP;

	dn_free (dn);
	dn_free (dntop);
		
	if ( entryptr->e_leaf) {
		Attr_Sequence newas;
		AttributeType newat;

		entryptr->e_child = ptr;
		/* add master and slave attributes */

		DATABASE_HEAP;

		if ((entryptr->e_parent->e_slave == NULLAV) && (entryptr->e_parent->e_master == NULLAV)) {
			extern char * mydsaname;
			newat = AttrT_new (MASTERDSA_OID);
			entryptr->e_master = str2avs (mydsaname,newat);
			newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
			entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
		} else {
			if ((entryptr->e_master = avs_cpy(entryptr->e_parent->e_master)) != NULLAV) {
				newat = AttrT_new (MASTERDSA_OID);
				newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
				entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
			}
			if ((entryptr->e_slave = avs_cpy (entryptr->e_parent->e_slave)) != NULLAV) {
				newat = AttrT_new (SLAVEDSA_OID);
				newas = as_comp_new (newat,entryptr->e_slave,NULLACL_INFO);
				entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
			}
		}
		/* add new QuipuNonLeaf objectclass */
		newat = AttrT_new (OBJECTCLASS_OID);
		newas = as_comp_new (newat,str2avs(NONLEAFOBJECT,newat),NULLACL_INFO);
		entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);

		if (entryptr->e_parent != NULLENTRY) {
			if (entryptr->e_parent->e_edbversion)
				free (entryptr->e_parent->e_edbversion);
			entryptr->e_parent->e_edbversion = new_version();
		}
		if (entryptr->e_edbversion)
			free (entryptr->e_edbversion);
		entryptr->e_edbversion = new_version();
		ptr->e_edbversion = new_version();
		entryptr->e_allchildrenpresent = TRUE;

		modify_attr (entryptr,binddn);
		if (unravel_attribute (entryptr,error,TRUE) != OK) 
			fatal (-31,"serious schema error");

		if (journal (ptr) == NOTOK)
			fatal (-32,"add journal (2) failure - check database");

		entryptr->e_leaf = FALSE;
		/* rewrite the parent as well */
		if (journal (entryptr) != OK)
			fatal (-31,"add parent journal failed - check database");

		GENERAL_HEAP;

		local_master_size++;
		return (OK);

	} else {
		ptr->e_sibling = entryptr->e_child;
		entryptr->e_child = ptr;
	}

	if (ptr->e_parent != NULLENTRY) {
		if (ptr->e_parent->e_edbversion)
			free (ptr->e_parent->e_edbversion);
		ptr->e_parent->e_edbversion = new_version();
	}
	if (journal (ptr) == NOTOK)
		fatal (-32,"add journal failure - check database");

	local_master_size++;
	return (DS_OK);
}