Пример #1
0
/*
 * Callers should have already allocated *gerstr to hold at least
 * "entryLevelRights: adnvxxx\n".
 */
unsigned long
_ger_get_entry_rights (
	Slapi_PBlock *gerpb,
	Slapi_Entry *e,
	const char *subjectndn,
	char **gerstr,
	size_t *gerstrsize,
	size_t *gerstrcap,
	char **errbuf
	)
{
	unsigned long entryrights = 0;
	Slapi_RDN *rdn = NULL;
	char *rdntype = NULL;
	char *rdnvalue = NULL;

	_append_gerstr(gerstr, gerstrsize, gerstrcap, "entryLevelRights: ", NULL);

	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
		"_ger_get_entry_rights - SLAPI_ACL_READ\n" );
	if (acl_access_allowed(gerpb, e, "*", NULL, SLAPI_ACL_READ) == LDAP_SUCCESS)
	{
		/* v - view e */
		entryrights |= SLAPI_ACL_READ;
		_append_gerstr(gerstr, gerstrsize, gerstrcap, "v", NULL);
	}
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
		"_ger_get_entry_rights - SLAPI_ACL_ADD\n" );
	if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_ADD) == LDAP_SUCCESS)
	{
		/* a - add child entry below e */
		entryrights |= SLAPI_ACL_ADD;
		_append_gerstr(gerstr, gerstrsize, gerstrcap, "a", NULL);
	}
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
		"_ger_get_entry_rights - SLAPI_ACL_DELETE\n" );
	if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_DELETE) == LDAP_SUCCESS)
	{
		/* d - delete e */
		entryrights |= SLAPI_ACL_DELETE;
		_append_gerstr(gerstr, gerstrsize, gerstrcap, "d", NULL);
	}
    
    if (config_get_moddn_aci()) {
        /* The server enforces the new MODDN aci right.
         * So the status 'n' is set if this right is granted.
         * Opposed to the legacy mode where this flag is set if 
         * WRITE was granted on rdn attrbibute
         */
        if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) {
            slapi_log_err(SLAPI_LOG_ACL, plugin_name,
                    "_ger_get_entry_rights - SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn(e));
            /* n - rename e */
            entryrights |= SLAPI_ACL_MODDN;
            _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL);
        }
    } else {
        /*
         * Some limitation/simplification applied here:
         * - The modrdn right requires the rights to delete the old rdn and
         *   the new one. However we have no knowledge of what the new rdn
         *   is going to be.
         * - In multi-valued RDN case, we check the right on
         *   the first rdn type only for now.
         */
        rdn = slapi_rdn_new_dn(slapi_entry_get_ndn(e));
        slapi_rdn_get_first(rdn, &rdntype, &rdnvalue);
        if (NULL != rdntype) {
            slapi_log_err(SLAPI_LOG_ACL, plugin_name,
                    "_ger_get_entry_rights - SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype);
            if (acl_access_allowed(gerpb, e, rdntype, NULL,
                    ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS &&
                    acl_access_allowed(gerpb, e, rdntype, NULL,
                    ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) {
                /* n - rename e */
                entryrights |= SLAPI_ACL_WRITE;
                _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL);
            }
        }
        slapi_rdn_free(&rdn);
    }
	if ( entryrights == 0 )
	{
		_append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
	}

	_append_gerstr(gerstr, gerstrsize, gerstrcap, "\n", NULL);

	return entryrights;
}
Пример #2
0
Slapi_RDN *slapi_rdn_new_sdn( const Slapi_DN *sdn )
{
	return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn ) );
}
Пример #3
0
Slapi_RDN *slapi_rdn_new_rdn( const Slapi_RDN *fromrdn )
{
	return slapi_rdn_new_dn( fromrdn->bv.bv_val );
}
Пример #4
0
static int
urp_add_resolve_parententry (Slapi_PBlock *pb, char *sessionid, Slapi_Entry *entry, Slapi_Entry *parententry, CSN *opcsn)
{
	Slapi_DN *parentdn = NULL;
	Slapi_RDN *add_rdn = NULL;
	char *newdn = NULL;
	int ldap_rc;
	int rc = 0;
	Slapi_DN *sdn = NULL;

	if( is_suffix_entry (pb, entry, &parentdn) )
	{
		/* It's OK for the suffix entry's parent to be absent */ 
		rc= 0;
		PROFILE_POINT; /* Add Conflict; Suffix Entry */
		goto bailout;
	}

	/* The entry is not a suffix. */
	if(parententry==NULL) /* The parent entry was not found. */
	{
		/* Create a glue entry to stand in for the absent parent */
		slapi_operation_parameters *op_params;
		slapi_pblock_get( pb, SLAPI_OPERATION_PARAMETERS, &op_params );
		ldap_rc = create_glue_entry (pb, sessionid, parentdn, op_params->p.p_add.parentuniqueid, opcsn);
		if ( LDAP_SUCCESS == ldap_rc )
		{
			/* The backend code should now search for the parent again. */
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY);
			PROFILE_POINT; /* Add Conflict; Orphaned Entry; Glue Parent */
		}
		else
		{
			/*
			 * Error. The parent can't be created as a glue entry.
			 * This will cause replication divergence and will
			 * require admin intercession
			 */
			ldap_rc= LDAP_OPERATIONS_ERROR;
			slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_rc);
			rc= -1; /* Abort this Operation */
			PROFILE_POINT; /* Add Conflict; Orphaned Entry; Impossible to create parent; Refuse Change. */
		}
		goto bailout;
	}

	if(is_tombstone_entry(parententry)) /* The parent is a tombstone */
	{
		/* The parent entry must be resurected from the dead. */
		ldap_rc = tombstone_to_glue (pb, sessionid, parententry, parentdn, REASON_RESURRECT_ENTRY, opcsn);
		if ( ldap_rc != LDAP_SUCCESS )
		{
			ldap_rc= LDAP_OPERATIONS_ERROR;
			slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_rc);
			rc = -1; /* Abort the operation */
		}
		else
		{
			/* The backend add code should now search for the parent again. */
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY);
		}
		PROFILE_POINT; /* Add Conflict; Orphaned Entry; Parent Was Tombstone */
		goto bailout;
	}

	/* The parent is healthy */
	/* Now we need to check that the parent has the correct DN */
	if (slapi_sdn_isparent(slapi_entry_get_sdn(parententry), slapi_entry_get_sdn(entry)))
	{
		rc= 0; /* OK, Add the entry */
		PROFILE_POINT; /* Add Conflict; Parent Exists */
		goto bailout;
	}

	/* 
	 * Parent entry doesn't have a DN parent to the entry.
	 * This can happen if parententry was renamed due to
	 * conflict and the child entry was created before
	 * replication occured. See defect 530942.
	 * We need to rename the entry to be child of its parent.
	 */
	add_rdn = slapi_rdn_new_dn(slapi_entry_get_dn_const (entry));
	newdn = slapi_dn_plus_rdn(slapi_entry_get_dn_const (parententry), slapi_rdn_get_rdn(add_rdn));
	slapi_entry_set_normdn ( entry, newdn );

	/* slapi_pblock_get(pb, SLAPI_ADD_TARGET, &dn); */
	slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn);
	slapi_sdn_free(&sdn);

	sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(entry));
	slapi_pblock_set(pb, SLAPI_ADD_TARGET_SDN, sdn);

	slapi_log_error ( slapi_log_urp, sessionid,
			"Parent was renamed. Renamed the child to %s\n", newdn );
	rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
	PROFILE_POINT; /* Add Conflict; Parent Renamed; Rename Operation Entry */

bailout:
	if (parentdn)
		slapi_sdn_free(&parentdn);
	slapi_rdn_free(&add_rdn);
	return rc;
}