⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modrdn.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* modrdn.c - bdb backend modrdn routine *//* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modrdn.c,v 1.160.2.12 2007/01/02 21:44:00 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2000-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */#include "portable.h"#include <stdio.h>#include <ac/string.h>#include "back-bdb.h"intbdb_modrdn( Operation	*op, SlapReply *rs ){	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;	AttributeDescription *children = slap_schema.si_ad_children;	AttributeDescription *entry = slap_schema.si_ad_entry;	struct berval	p_dn, p_ndn;	struct berval	new_dn = {0, NULL}, new_ndn = {0, NULL};	Entry		*e = NULL;	Entry		*p = NULL;	EntryInfo	*ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL;	/* LDAP v2 supporting correct attribute handling. */	LDAPRDN		new_rdn = NULL;	LDAPRDN		old_rdn = NULL;	char textbuf[SLAP_TEXT_BUFLEN];	size_t textlen = sizeof textbuf;	DB_TXN		*ltid = NULL, *lt2;	struct bdb_op_info opinfo = {0};	Entry dummy = {0};	Entry		*np = NULL;			/* newSuperior Entry */	struct berval	*np_dn = NULL;			/* newSuperior dn */	struct berval	*np_ndn = NULL;			/* newSuperior ndn */	struct berval	*new_parent_dn = NULL;	/* np_dn, p_dn, or NULL */	/* Used to interface with bdb_modify_internal() */	Modifications	*mod = NULL;		/* Used to delete old rdn */	int		manageDSAit = get_manageDSAit( op );	u_int32_t	locker = 0;	DB_LOCK		lock, plock, nplock;	int		num_retries = 0;	LDAPControl **preread_ctrl = NULL;	LDAPControl **postread_ctrl = NULL;	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];	int num_ctrls = 0;	int	rc;	int parent_is_glue = 0;	int parent_is_leaf = 0;	ctrls[num_ctrls] = NULL;	Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",		op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,		op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );	if( 0 ) {retry:	/* transaction retry */		if ( dummy.e_attrs ) {			attrs_free( dummy.e_attrs );			dummy.e_attrs = NULL;		}		if (e != NULL) {			bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);			e = NULL;		}		if (p != NULL) {			bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);			p = NULL;		}		if (np != NULL) {			bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np);			np = NULL;		}		Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn)				": retrying...\n", 0, 0, 0 );		rs->sr_err = TXN_ABORT( ltid );		ltid = NULL;		op->o_private = NULL;		op->o_do_not_cache = opinfo.boi_acl_cache;		if( rs->sr_err != 0 ) {			rs->sr_err = LDAP_OTHER;			rs->sr_text = "internal error";			goto return_results;		}		if ( op->o_abandon ) {			rs->sr_err = SLAPD_ABANDON;			goto return_results;		}		parent_is_glue = 0;		parent_is_leaf = 0;		bdb_trans_backoff( ++num_retries );	}	/* begin transaction */	rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, 		bdb->bi_db_opflags );	rs->sr_text = NULL;	if( rs->sr_err != 0 ) {		Debug( LDAP_DEBUG_TRACE,			LDAP_XSTRING(bdb_modrdn) ": txn_begin failed: "			"%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );		rs->sr_err = LDAP_OTHER;		rs->sr_text = "internal error";		goto return_results;	}	locker = TXN_ID ( ltid );	opinfo.boi_bdb = op->o_bd;	opinfo.boi_txn = ltid;	opinfo.boi_locker = locker;	opinfo.boi_err = 0;	opinfo.boi_acl_cache = op->o_do_not_cache;	op->o_private = &opinfo;	/* get entry */	rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,		locker, &lock );	switch( rs->sr_err ) {	case 0:	case DB_NOTFOUND:		break;	case DB_LOCK_DEADLOCK:	case DB_LOCK_NOTGRANTED:		goto retry;	case LDAP_BUSY:		rs->sr_text = "ldap server busy";		goto return_results;	default:		rs->sr_err = LDAP_OTHER;		rs->sr_text = "internal error";		goto return_results;	}	e = ei->bei_e;	/* FIXME: dn2entry() should return non-glue entry */	if (( rs->sr_err == DB_NOTFOUND ) ||		( !manageDSAit && e && is_entry_glue( e )))	{		if( e != NULL ) {			rs->sr_matched = ch_strdup( e->e_dn );			rs->sr_ref = is_entry_referral( e )				? get_entry_referrals( op, e )				: NULL;			bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, e);			e = NULL;		} else {			rs->sr_ref = referral_rewrite( default_referral, NULL,					&op->o_req_dn, LDAP_SCOPE_DEFAULT );		}		rs->sr_err = LDAP_REFERRAL;		send_ldap_result( op, rs );		ber_bvarray_free( rs->sr_ref );		free( (char *)rs->sr_matched );		rs->sr_ref = NULL;		rs->sr_matched = NULL;		goto done;	}	if ( get_assert( op ) &&		( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))	{		rs->sr_err = LDAP_ASSERTION_FAILED;		goto return_results;	}	/* check write on old entry */	rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );	if ( ! rs->sr_err ) {		switch( opinfo.boi_err ) {		case DB_LOCK_DEADLOCK:		case DB_LOCK_NOTGRANTED:			goto retry;		}		Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,			0, 0 );		rs->sr_text = "no write access to old entry";		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;		goto return_results;	}#ifndef BDB_HIER	rs->sr_err = bdb_cache_children( op, ltid, e );	if ( rs->sr_err != DB_NOTFOUND ) {		switch( rs->sr_err ) {		case DB_LOCK_DEADLOCK:		case DB_LOCK_NOTGRANTED:			goto retry;		case 0:			Debug(LDAP_DEBUG_ARGS,				"<=- " LDAP_XSTRING(bdb_modrdn)				": non-leaf %s\n",				op->o_req_dn.bv_val, 0, 0);			rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;			rs->sr_text = "subtree rename not supported";			break;		default:			Debug(LDAP_DEBUG_ARGS,				"<=- " LDAP_XSTRING(bdb_modrdn)				": has_children failed: %s (%d)\n",				db_strerror(rs->sr_err), rs->sr_err, 0 );			rs->sr_err = LDAP_OTHER;			rs->sr_text = "internal error";		}		goto return_results;	}	ei->bei_state |= CACHE_ENTRY_NO_KIDS;#endif	if (!manageDSAit && is_entry_referral( e ) ) {		/* parent is a referral, don't allow add */		rs->sr_ref = get_entry_referrals( op, e );		Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn)			": entry %s is referral\n", e->e_dn, 0, 0 );		rs->sr_err = LDAP_REFERRAL,		rs->sr_matched = e->e_name.bv_val;		send_ldap_result( op, rs );		ber_bvarray_free( rs->sr_ref );		rs->sr_ref = NULL;		rs->sr_matched = NULL;		goto done;	}	if ( be_issuffix( op->o_bd, &e->e_nname ) ) {#ifdef BDB_MULTIPLE_SUFFIXES		/* Allow renaming one suffix entry to another */		p_ndn = slap_empty_bv;#else		/* There can only be one suffix entry */		rs->sr_err = LDAP_NAMING_VIOLATION;		rs->sr_text = "cannot rename suffix entry";		goto return_results;#endif	} else {		dnParent( &e->e_nname, &p_ndn );	}	np_ndn = &p_ndn;	if ( p_ndn.bv_len != 0 ) {		/* Make sure parent entry exist and we can write its 		 * children.		 */		eip = ei->bei_parent;		rs->sr_err = bdb_cache_find_id( op, ltid,			eip->bei_id, &eip, 0, locker, &plock );		switch( rs->sr_err ) {		case 0:		case DB_NOTFOUND:			break;		case DB_LOCK_DEADLOCK:		case DB_LOCK_NOTGRANTED:			goto retry;		case LDAP_BUSY:			rs->sr_text = "ldap server busy";			goto return_results;		default:			rs->sr_err = LDAP_OTHER;			rs->sr_text = "internal error";			goto return_results;		}		p = eip->bei_e;		if( p == NULL) {			Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn)				": parent does not exist\n", 0, 0, 0);			rs->sr_err = LDAP_OTHER;			rs->sr_text = "old entry's parent does not exist";			goto return_results;		}	} else {		p = (Entry *)&slap_entry_root;	}	/* check parent for "children" acl */	rs->sr_err = access_allowed( op, p,		children, NULL,		op->oq_modrdn.rs_newSup == NULL ?			ACL_WRITE : ACL_WDEL,		NULL );	if ( !p_ndn.bv_len )		p = NULL;	if ( ! rs->sr_err ) {		switch( opinfo.boi_err ) {		case DB_LOCK_DEADLOCK:		case DB_LOCK_NOTGRANTED:			goto retry;		}		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;		Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,			0, 0 );		rs->sr_text = "no write access to old parent's children";		goto return_results;	}	Debug( LDAP_DEBUG_TRACE,		LDAP_XSTRING(bdb_modrdn) ": wr to children "		"of entry %s OK\n", p_ndn.bv_val, 0, 0 );		if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {		p_dn = slap_empty_bv;	} else {		dnParent( &e->e_name, &p_dn );	}	Debug( LDAP_DEBUG_TRACE,		LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n",		p_dn.bv_val, 0, 0 );	new_parent_dn = &p_dn;	/* New Parent unless newSuperior given */	if ( op->oq_modrdn.rs_newSup != NULL ) {		Debug( LDAP_DEBUG_TRACE, 			LDAP_XSTRING(bdb_modrdn)			": new parent \"%s\" requested...\n",			op->oq_modrdn.rs_newSup->bv_val, 0, 0 );		/*  newSuperior == oldParent? */		if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) {			Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: "				"new parent \"%s\" same as the old parent \"%s\"\n",				op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val, 0 );			op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */		}	}	/* There's a BDB_MULTIPLE_SUFFIXES case here that this code doesn't	 * support. E.g., two suffixes dc=foo,dc=com and dc=bar,dc=net.	 * We do not allow modDN	 *   dc=foo,dc=com	 *    newrdn dc=bar	 *    newsup dc=net	 * and we probably should. But since MULTIPLE_SUFFIXES is deprecated	 * I'm ignoring this problem for now.	 */	if ( op->oq_modrdn.rs_newSup != NULL ) {		if ( op->oq_modrdn.rs_newSup->bv_len ) {			np_dn = op->oq_modrdn.rs_newSup;			np_ndn = op->oq_modrdn.rs_nnewSup;			/* newSuperior == oldParent? - checked above */			/* newSuperior == entry being moved?, if so ==> ERROR */			if ( dnIsSuffix( np_ndn, &e->e_nname )) {				rs->sr_err = LDAP_NO_SUCH_OBJECT;				rs->sr_text = "new superior not found";				goto return_results;			}			/* Get Entry with dn=newSuperior. Does newSuperior exist? */			rs->sr_err = bdb_dn2entry( op, ltid, np_ndn,				&neip, 0, locker, &nplock );			switch( rs->sr_err ) {			case 0: np = neip->bei_e;			case DB_NOTFOUND:				break;			case DB_LOCK_DEADLOCK:			case DB_LOCK_NOTGRANTED:				goto retry;			case LDAP_BUSY:				rs->sr_text = "ldap server busy";				goto return_results;			default:				rs->sr_err = LDAP_OTHER;				rs->sr_text = "internal error";				goto return_results;			}			if( np == NULL) {				Debug( LDAP_DEBUG_TRACE,					LDAP_XSTRING(bdb_modrdn)					": newSup(ndn=%s) not here!\n",					np_ndn->bv_val, 0, 0);				rs->sr_text = "new superior not found";				rs->sr_err = LDAP_NO_SUCH_OBJECT;				goto return_results;			}			Debug( LDAP_DEBUG_TRACE,				LDAP_XSTRING(bdb_modrdn)				": wr to new parent OK np=%p, id=%ld\n",				(void *) np, (long) np->e_id, 0 );			/* check newSuperior for "children" acl */			rs->sr_err = access_allowed( op, np, children,				NULL, ACL_WADD, NULL );			if( ! rs->sr_err ) {				switch( opinfo.boi_err ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -