alias.c

来自「ldap服务器源码」· C语言 代码 · 共 241 行

C
241
字号
/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldbm/alias.c,v 1.47.2.4 2007/01/02 21:44:02 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 1998-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 <ac/socket.h>#include "slap.h"#include "back-ldbm.h"#include "proto-back-ldbm.h"static void new_superior(	struct berval *dn,	struct berval *oldSup,	struct berval *newSup,	struct berval *res );static int dnlist_subordinate(	BerVarray dnlist,	struct berval *dn );Entry *deref_internal_r(	Backend*	be,	Entry*		alias,	struct berval*	dn_in,	int*		err,	Entry**		matched,	const char**		text ){	struct berval dn;	struct ldbminfo *li = (struct ldbminfo *) be->be_private;	Entry *entry;	Entry *sup;	unsigned depth;	BerVarray dnlist;	assert( ( alias != NULL && dn_in == NULL )		|| ( alias == NULL && dn_in != NULL ) );	*matched = NULL;	*err = LDAP_NO_SUCH_OBJECT;	*text = NULL;	if( alias == NULL ) {		ber_dupbv( &dn, dn_in );		entry = dn2entry_r( be, &dn, &sup );	} else {		ber_dupbv( &dn, &alias->e_nname );		entry = alias;		sup = NULL;	}	dnlist = NULL;	ber_bvarray_add( &dnlist, &dn );	for( depth=0 ; ; depth++ ) {		if( entry != NULL ) {			Entry *newe;			struct berval aliasDN;			/* have entry, may be an alias */			if( !is_entry_alias( entry ) ) {				/* entry is not an alias */				break;			}			/* entry is alias */			if( depth > be->be_max_deref_depth ) {				*matched = entry;				entry = NULL;				*err = LDAP_ALIAS_DEREF_PROBLEM;				*text = "maximum deref depth exceeded";				break;			}			/* deref entry */			if( get_alias_dn( entry, &aliasDN, err, text )) {				*matched = entry;				entry = NULL;				break;			}			/* check if aliasDN is a subordinate of any DN in our list */			if( dnlist_subordinate( dnlist, &aliasDN ) ) {				ch_free( aliasDN.bv_val );				*matched = entry;				entry = NULL;				*err = LDAP_ALIAS_PROBLEM;				*text = "circular alias";				break;			}			/* attempt to dereference alias */			newe = dn2entry_r( be, &aliasDN, &sup );			ch_free( aliasDN.bv_val );			if( newe != NULL ) {				cache_return_entry_r(&li->li_cache, entry );				entry = newe;				ber_dupbv( &dn, &entry->e_nname );				ber_bvarray_add( &dnlist, &dn );				continue;			}						if ( sup != NULL ) {				cache_return_entry_r(&li->li_cache, entry );				entry = NULL;				continue;			}			/* no newe and no superior, we're done */			break;		} else if( sup != NULL ) {			/* have superior, may be an alias */			Entry *newe;			Entry *newSup;			struct berval supDN;			struct berval aliasDN;			if( !is_entry_alias( sup ) ) {				/* entry is not an alias */				*matched = sup;				sup = NULL;				break;			}			/* entry is alias */			if( depth > be->be_max_deref_depth ) {				*matched = sup;				entry = NULL;				*err = LDAP_ALIAS_DEREF_PROBLEM;				*text = "maximum deref depth exceeded";				break;			}			/* deref entry */			if( get_alias_dn( sup, &supDN, err, text )) {				*matched = sup;				break;			}			new_superior( &dn, &sup->e_nname, &supDN, &aliasDN );			free(supDN.bv_val);			/* check if aliasDN is a subordinate of any DN in our list */			if( dnlist_subordinate( dnlist, &aliasDN ) ) {				free(aliasDN.bv_val);				*matched = entry;				entry = NULL;				*err = LDAP_ALIAS_PROBLEM;				*text = "subordinate circular alias";				break;			}			/* attempt to dereference alias */			newe = dn2entry_r( be, &aliasDN, &newSup );			if( newe != NULL ) {				free(aliasDN.bv_val);				cache_return_entry_r(&li->li_cache, sup );				entry = newe;				ber_dupbv( &dn, &entry->e_nname );				ber_bvarray_add( &dnlist, &dn );				continue;			}						if ( newSup != NULL ) {				cache_return_entry_r(&li->li_cache, sup );				sup = newSup;				ber_dupbv( &dn, &aliasDN );				continue;			}			break;		} else {			/* no newe and no superior, we're done */			break;		}	}	ber_bvarray_free( dnlist );	return entry;}static void new_superior(	struct berval *dn,	struct berval *oldSup,	struct berval *newSup,	struct berval *newDN ){	size_t dnlen, olen, nlen;	assert( dn && oldSup && newSup && newDN );	dnlen = dn->bv_len;	olen = oldSup->bv_len;	nlen = newSup->bv_len;	newDN->bv_val = ch_malloc( dnlen - olen + nlen + 1 );	AC_MEMCPY( newDN->bv_val, dn->bv_val, dnlen - olen );	AC_MEMCPY( &newDN->bv_val[dnlen - olen], newSup->bv_val, nlen );	newDN->bv_val[dnlen - olen + nlen] = '\0';	return;}static int dnlist_subordinate(	BerVarray dnlist,	struct berval *dn ){	assert( dnlist != NULL );	for( ; dnlist->bv_val != NULL; dnlist++ ) {		if( dnIsSuffix( dnlist, dn ) ) {			return 1;		}	}	return 0;}

⌨️ 快捷键说明

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