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

📄 chain.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 4 页
字号:
 */enum {	CH_CHAINING = 1,	CH_CACHE_URI,	CH_MAX_DEPTH,	CH_RETURN_ERR,	CH_LAST};static ConfigDriver chain_cf_gen;static ConfigCfAdd chain_cfadd;static ConfigLDAPadd chain_ldadd;static ConfigTable chaincfg[] = {#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR	{ "chain-chaining", "args",		2, 4, 0, ARG_MAGIC|ARG_BERVAL|CH_CHAINING, chain_cf_gen,		"( OLcfgOvAt:3.1 NAME 'olcChainingBehavior' "			"DESC 'Chaining behavior control parameters (draft-sermersheim-ldap-chaining)' "			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */	{ "chain-cache-uri", "TRUE/FALSE",		2, 2, 0, ARG_MAGIC|ARG_ON_OFF|CH_CACHE_URI, chain_cf_gen,		"( OLcfgOvAt:3.2 NAME 'olcChainCacheURI' "			"DESC 'Enables caching of URIs not present in configuration' "			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ "chain-max-depth", "args",		2, 2, 0, ARG_MAGIC|ARG_INT|CH_MAX_DEPTH, chain_cf_gen,		"( OLcfgOvAt:3.3 NAME 'olcChainMaxReferralDepth' "			"DESC 'max referral depth' "			"SYNTAX OMsInteger "			"EQUALITY integerMatch "			"SINGLE-VALUE )", NULL, NULL },	{ "chain-return-error", "TRUE/FALSE",		2, 2, 0, ARG_MAGIC|ARG_ON_OFF|CH_RETURN_ERR, chain_cf_gen,		"( OLcfgOvAt:3.4 NAME 'olcChainReturnError' "			"DESC 'Errors are returned instead of the original referral' "			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }};static ConfigOCs chainocs[] = {	{ "( OLcfgOvOc:3.1 "		"NAME 'olcChainConfig' "		"DESC 'Chain configuration' "		"SUP olcOverlayConfig "		"MAY ( "#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR			"olcChainingBehavior $ "#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */			"olcChainCacheURI $ "			"olcChainMaxReferralDepth $ "			"olcChainReturnError "			") )",		Cft_Overlay, chaincfg, NULL, chain_cfadd },	{ "( OLcfgOvOc:3.2 "		"NAME 'olcChainDatabase' "		"DESC 'Chain remote server configuration' "		"AUXILIARY )",		Cft_Misc, chaincfg, chain_ldadd },	{ NULL, 0, NULL }};static intchain_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ){	slap_overinst		*on;	ldap_chain_t		*lc;	ldapinfo_t		*li;	AttributeDescription	*ad = NULL;	Attribute		*at;	const char		*text;	int			rc;	if ( p->ce_type != Cft_Overlay		|| !p->ce_bi		|| p->ce_bi->bi_cf_ocs != chainocs )	{		return LDAP_CONSTRAINT_VIOLATION;	}	on = (slap_overinst *)p->ce_bi;	lc = (ldap_chain_t *)on->on_bi.bi_private;	assert( ca->be == NULL );	ca->be = (BackendDB *)ch_calloc( 1, sizeof( BackendDB ) );	ca->be->bd_info = (BackendInfo *)on;	rc = slap_str2ad( "olcDbURI", &ad, &text );	assert( rc == LDAP_SUCCESS );	at = attr_find( e->e_attrs, ad );	if ( lc->lc_common_li == NULL && at != NULL ) {		/* FIXME: we should generate an empty default entry		 * if none is supplied */		Debug( LDAP_DEBUG_ANY, "slapd-chain: "			"first underlying database \"%s\" "			"cannot contain attribute \"%s\".\n",			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );		rc = LDAP_CONSTRAINT_VIOLATION;		goto done;	} else if ( lc->lc_common_li != NULL && at == NULL ) {		/* FIXME: we should generate an empty default entry		 * if none is supplied */		Debug( LDAP_DEBUG_ANY, "slapd-chain: "			"subsequent underlying database \"%s\" "			"must contain attribute \"%s\".\n",			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );		rc = LDAP_CONSTRAINT_VIOLATION;		goto done;	}	if ( lc->lc_common_li == NULL ) {		rc = ldap_chain_db_init_common( ca->be );	} else {		rc = ldap_chain_db_init_one( ca->be );	}	if ( rc != 0 ) {		Debug( LDAP_DEBUG_ANY, "slapd-chain: "			"unable to init %sunderlying database \"%s\".\n",			lc->lc_common_li == NULL ? "common " : "", e->e_name.bv_val, 0 );		return LDAP_CONSTRAINT_VIOLATION;	}	li = ca->be->be_private;	if ( lc->lc_common_li == NULL ) {		lc->lc_common_li = li;	} else {		li->li_uri = ch_strdup( at->a_vals[ 0 ].bv_val );		value_add_one( &li->li_bvuri, &at->a_vals[ 0 ] );		if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li,			ldap_chain_uri_cmp, ldap_chain_uri_dup ) )		{			Debug( LDAP_DEBUG_ANY, "slapd-chain: "				"database \"%s\" insert failed.\n",				e->e_name.bv_val, 0, 0 );			rc = LDAP_CONSTRAINT_VIOLATION;			goto done;		}	}done:;	if ( rc != LDAP_SUCCESS ) {		(void)ldap_chain_db_destroy_one( ca->be );		ch_free( ca->be );		ca->be = NULL;	}	return rc;}typedef struct ldap_chain_cfadd_apply_t {	Operation	*op;	SlapReply	*rs;	Entry		*p;	ConfigArgs	*ca;	int		count;} ldap_chain_cfadd_apply_t;static intldap_chain_cfadd_apply( void *datum, void *arg ){	ldapinfo_t			*li = (ldapinfo_t *)datum;	ldap_chain_cfadd_apply_t	*lca = (ldap_chain_cfadd_apply_t *)arg;	struct berval			bv;	/* FIXME: should not hardcode "olcDatabase" here */	bv.bv_len = snprintf( lca->ca->msg, sizeof( lca->ca->msg ),		"olcDatabase={%d}%s", lca->count, lback->bi_type );	bv.bv_val = lca->ca->msg;	lca->ca->be->be_private = (void *)li;	config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca,		&bv, lback->bi_cf_ocs, &chainocs[1] );	lca->count++;	return 0;}static intchain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ){	CfEntryInfo	*pe = p->e_private;	slap_overinst	*on = (slap_overinst *)pe->ce_bi;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	void		*priv = (void *)ca->be->be_private;	if ( lback->bi_cf_ocs ) {		ldap_chain_cfadd_apply_t	lca = { 0 };		lca.op = op;		lca.rs = rs;		lca.p = p;		lca.ca = ca;		lca.count = 0;		(void)ldap_chain_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca );		(void)avl_apply( lc->lc_lai.lai_tree, ldap_chain_cfadd_apply,			&lca, 1, AVL_INORDER );		ca->be->be_private = priv;	}	return 0;}#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIORstatic slap_verbmasks chaining_mode[] = {	{ BER_BVC("referralsRequired"),		LDAP_REFERRALS_REQUIRED },	{ BER_BVC("referralsPreferred"),	LDAP_REFERRALS_PREFERRED },	{ BER_BVC("chainingRequired"),		LDAP_CHAINING_REQUIRED },	{ BER_BVC("chainingPreferred"),		LDAP_CHAINING_PREFERRED },	{ BER_BVNULL,				0 }};#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */static intchain_cf_gen( ConfigArgs *c ){	slap_overinst	*on = (slap_overinst *)c->bi;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	int		rc = 0;	if ( c->op == SLAP_CONFIG_EMIT ) {		switch( c->type ) {#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR		case CH_CHAINING: {			struct berval	resolve = BER_BVNULL,					continuation = BER_BVNULL;			if ( !LDAP_CHAIN_CHAINING( lc ) ) {				return 1;			}			enum_to_verb( chaining_mode, ( ( lc->lc_chaining_ctrlflag & SLAP_CH_RESOLVE_MASK ) >> SLAP_CH_RESOLVE_SHIFT ), &resolve );			enum_to_verb( chaining_mode, ( ( lc->lc_chaining_ctrlflag & SLAP_CH_CONTINUATION_MASK ) >> SLAP_CH_CONTINUATION_SHIFT ), &continuation );			c->value_bv.bv_len = STRLENOF( "resolve=" ) + resolve.bv_len				+ STRLENOF( " " )				+ STRLENOF( "continuation=" ) + continuation.bv_len;			c->value_bv.bv_val = ch_malloc( c->value_bv.bv_len + 1 );			snprintf( c->value_bv.bv_val, c->value_bv.bv_len + 1,				"resolve=%s continuation=%s",				resolve.bv_val, continuation.bv_val );			if ( lc->lc_chaining_ctrl.ldctl_iscritical ) {				c->value_bv.bv_val = ch_realloc( c->value_bv.bv_val,					c->value_bv.bv_len + STRLENOF( " critical" ) + 1 );				AC_MEMCPY( &c->value_bv.bv_val[ c->value_bv.bv_len ],					" critical", STRLENOF( " critical" ) + 1 );				c->value_bv.bv_len += STRLENOF( " critical" );			}			break;		}#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */		case CH_CACHE_URI:			c->value_int = LDAP_CHAIN_CACHE_URI( lc );			break;		case CH_MAX_DEPTH:			c->value_int = lc->lc_max_depth;			break;		case CH_RETURN_ERR:			c->value_int = LDAP_CHAIN_RETURN_ERR( lc );			break;		default:			assert( 0 );			rc = 1;		}		return rc;	} else if ( c->op == LDAP_MOD_DELETE ) {		switch( c->type ) {		case CH_CHAINING:			return 1;		case CH_CACHE_URI:			lc->lc_flags &= ~LDAP_CHAIN_F_CACHE_URI;			break;		case CH_MAX_DEPTH:			c->value_int = 0;			break;		case CH_RETURN_ERR:			lc->lc_flags &= ~LDAP_CHAIN_F_RETURN_ERR;			break;		default:			return 1;		}		return rc;	}	switch( c->type ) {	case CH_CHAINING: {#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR		char			**argv = c->argv;		int			argc = c->argc;		BerElementBuffer	berbuf;		BerElement		*ber = (BerElement *)&berbuf;		int			resolve = -1,					continuation = -1,					iscritical = 0;		Operation		op = { 0 };		SlapReply		rs = { 0 };		lc->lc_chaining_ctrlflag = 0;		for ( argc--, argv++; argc > 0; argc--, argv++ ) {			if ( strncasecmp( argv[ 0 ], "resolve=", STRLENOF( "resolve=" ) ) == 0 ) {				resolve = str2chain( argv[ 0 ] + STRLENOF( "resolve=" ) );				if ( resolve == -1 ) {					Debug( LDAP_DEBUG_ANY, "%s: "						"illegal <resolve> value %s "						"in \"chain-chaining>\".\n",						c->log, argv[ 0 ], 0 );					return 1;				}			} else if ( strncasecmp( argv[ 0 ], "continuation=", STRLENOF( "continuation=" ) ) == 0 ) {				continuation = str2chain( argv[ 0 ] + STRLENOF( "continuation=" ) );				if ( continuation == -1 ) {					Debug( LDAP_DEBUG_ANY, "%s: "						"illegal <continuation> value %s "						"in \"chain-chaining\".\n",						c->log, argv[ 0 ], 0 );					return 1;				}			} else if ( strcasecmp( argv[ 0 ], "critical" ) == 0 ) {				iscritical = 1;			} else {				Debug( LDAP_DEBUG_ANY, "%s: "					"unknown option in \"chain-chaining\".\n",					c->log, 0, 0 );				return 1;			}		}		if ( resolve != -1 || continuation != -1 ) {			int	err;			if ( resolve == -1 ) {				/* default */				resolve = SLAP_CHAINING_DEFAULT;			}			ber_init2( ber, NULL, LBER_USE_DER );			err = ber_printf( ber, "{e" /* } */, resolve );	    		if ( err == -1 ) {				ber_free( ber, 1 );				Debug( LDAP_DEBUG_ANY, "%s: "					"chaining behavior control encoding error!\n",					c->log, 0, 0 );				return 1;			}			if ( continuation > -1 ) {				err = ber_printf( ber, "e", continuation );	    			if ( err == -1 ) {					ber_free( ber, 1 );					Debug( LDAP_DEBUG_ANY, "%s: "						"chaining behavior control encoding error!\n",						c->log, 0, 0 );					return 1;				}			}			err = ber_printf( ber, /* { */ "N}" );	    		if ( err == -1 ) {				ber_free( ber, 1 );				Debug( LDAP_DEBUG_ANY, "%s: "					"chaining behavior control encoding error!\n",					c->log, 0, 0 );				return 1;			}			if ( ber_flatten2( ber, &lc->lc_chaining_ctrl.ldctl_value, 0 ) == -1 ) {				exit( EXIT_FAILURE );			}		} else {			BER_BVZERO( &lc->lc_chaining_ctrl.ldctl_value );		}		lc->lc_chaining_ctrl.ldctl_oid = LDAP_CONTROL_X_CHAINING_BEHAVIOR;		lc->lc_chaining_ctrl.ldctl_iscritical = iscritical;		if ( ldap_chain_parse_ctrl( &op, &rs, &lc->lc_chaining_ctrl ) != LDAP_SUCCESS )		{			Debug( LDAP_DEBUG_ANY, "%s: "				"unable to parse chaining control%s%s.\n",				c->log, rs.sr_text ? ": " : "",				rs.sr_text ? rs.sr_text : "" );			return 1;		}		lc->lc_chaining_ctrlflag = op.o_chaining;		lc->lc_flags |= LDAP_CHAIN_F_CHAINING;		rc = 0;#else /* ! LDAP_CONTROL_X_CHAINING_BEHAVIOR */		Debug( LDAP_DEBUG_ANY, "%s: "			"\"chaining\" control unsupported (ignored).\n",			c->log, 0, 0 );#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */		} break;	case CH_CACHE_URI:		if ( c->value_int ) {			lc->lc_flags |= LDAP_CHAIN_F_CACHE_URI;		} else {			lc->lc_flags &= ~LDAP_CHAIN_F_CACHE_URI;		}		break;	case CH_MAX_DEPTH:		if ( c->value_int < 0 ) {			snprintf( c->msg, sizeof( c->msg ),				"<%s> invalid max referral depth %d",				c->argv[0], c->value_int );			Debug( LDAP_DEBUG_ANY, "%s: %s.\n",				c->log, c->msg, 0 );			rc = 1;			break;		}		lc->lc_max_depth = c->value_int;	case CH_RETURN_ERR:		if ( c->value_int ) {			lc->lc_flags |= LDAP_CHAIN_F_RETURN_ERR;		} else {			lc->lc_flags &= ~LDAP_CHAIN_F_RETURN_ERR;		}		break;	default:		assert( 0 );		return 1;	}	return rc;}static intldap_chain_db_init(	BackendDB *be ){	slap_overinst	*on = (slap_overinst *)be->bd_info;	ldap_chain_t	*lc = NULL;	if ( lback == NULL ) {		static BackendInfo	lback2;		lback = backend_info( "ldap" );		if ( lback == NULL ) {			return 1;		}		lback2 = *lback;		lback2.bi_type = ldapchain.on_bi.bi_type;		lback = &lback2;	}	lc = ch_malloc( sizeof( ldap_chain_t ) );	if ( lc == NULL ) {		return 1;	}	memset( lc, 0, sizeof( ldap_chain_t ) );	lc->lc_max_depth = 1;	ldap_pvt_thread_mutex_init( &lc->lc_lai.lai_mutex );	on->on_bi.bi_private = (void *)lc;	return 0;}static intldap_chain_db_config(	BackendDB	*be,	const char	*fname,	int		lineno,	int		argc,	char		**argv ){	slap_overinst	*on = (slap_overinst *)be->bd_info;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	int		rc = SLAP_CONF_UNKNOWN;			if ( lc->lc_common_li == NULL ) {		void	*be_private = be->be_private;		ldap_chain_db_init_common( be );		lc->lc_common_li = lc->lc_cfg_li = (ldapinfo_t *)be->be_private;		be->be_private = be_private;

⌨️ 快捷键说明

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