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

📄 chain.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Something for the chain database? */	if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) {		char		*save_argv0 = argv[ 0 ];		BackendInfo	*bd_info = be->bd_info;		void		*be_private = be->be_private;		ConfigOCs	*be_cf_ocs = be->be_cf_ocs;		static char	*allowed_argv[] = {			/* special: put URI here, so in the meanwhile			 * it detects whether a new URI is being provided */			"uri",			"nretries",			"timeout",			/* flags */			"tls",			/* FIXME: maybe rebind-as-user should be allowed			 * only within known URIs... */			"rebind-as-user",			"chase-referrals",			"t-f-support",			"proxy-whoami",			NULL		};		int		which_argv = -1;		argv[ 0 ] += STRLENOF( "chain-" );		for ( which_argv = 0; allowed_argv[ which_argv ]; which_argv++ ) {			if ( strcasecmp( argv[ 0 ], allowed_argv[ which_argv ] ) == 0 ) {				break;			}		}		if ( allowed_argv[ which_argv ] == NULL ) {			which_argv = -1;			if ( lc->lc_cfg_li == lc->lc_common_li ) {				Debug( LDAP_DEBUG_ANY, "%s: line %d: "					"\"%s\" only allowed within a URI directive.\n.",					fname, lineno, argv[ 0 ] );				return 1;			}		}		if ( which_argv == 0 ) {			rc = ldap_chain_db_init_one( be );			if ( rc != 0 ) {				Debug( LDAP_DEBUG_ANY, "%s: line %d: "					"underlying slapd-ldap initialization failed.\n.",					fname, lineno, 0 );				return 1;			}			lc->lc_cfg_li = be->be_private;		}		/* TODO: add checks on what other slapd-ldap(5) args		 * should be put in the template; this is not quite		 * harmful, because attributes that shouldn't don't		 * get actually used, but the user should at least		 * be warned.		 */		be->bd_info = lback;		be->be_private = (void *)lc->lc_cfg_li;		be->be_cf_ocs = lback->bi_cf_ocs;		rc = config_generic_wrapper( be, fname, lineno, argc, argv );		argv[ 0 ] = save_argv0;		be->be_cf_ocs = be_cf_ocs;		be->be_private = be_private;		be->bd_info = bd_info;		if ( which_argv == 0 ) {private_destroy:;			if ( rc != 0 ) {				BackendDB		db = *be;				db.bd_info = lback;				db.be_private = (void *)lc->lc_cfg_li;				ldap_chain_db_destroy_one( &db );				lc->lc_cfg_li = NULL;			} else {				if ( lc->lc_cfg_li->li_bvuri == NULL					|| BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 0 ] )					|| !BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 1 ] ) )				{					Debug( LDAP_DEBUG_ANY, "%s: line %d: "						"no URI list allowed in slapo-chain.\n",						fname, lineno, 0 );					rc = 1;					goto private_destroy;				}				if ( avl_insert( &lc->lc_lai.lai_tree,					(caddr_t)lc->lc_cfg_li,					ldap_chain_uri_cmp, ldap_chain_uri_dup ) )				{					Debug( LDAP_DEBUG_ANY, "%s: line %d: "						"duplicate URI in slapo-chain.\n",						fname, lineno, 0 );					rc = 1;					goto private_destroy;				}			}		}	}		return rc;}enum db_which {	db_open = 0,	db_close,	db_destroy,	db_last};typedef struct ldap_chain_db_apply_t {	BackendDB	*be;	BI_db_func	*func;} ldap_chain_db_apply_t;static intldap_chain_db_apply( void *datum, void *arg ){	ldapinfo_t		*li = (ldapinfo_t *)datum;	ldap_chain_db_apply_t	*lca = (ldap_chain_db_apply_t *)arg;	lca->be->be_private = (void *)li;	return lca->func( lca->be );}static intldap_chain_db_func(	BackendDB *be,	enum db_which which){	slap_overinst	*on = (slap_overinst *)be->bd_info;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	int		rc = 0;	if ( lc ) {		BI_db_func	*func = (&lback->bi_db_open)[ which ];		if ( func != NULL && lc->lc_common_li != NULL ) {			BackendDB		db = *be;			db.bd_info = lback;			db.be_private = lc->lc_common_li;			rc = func( &db );			if ( rc != 0 ) {				return rc;			}			if ( lc->lc_lai.lai_tree != NULL ) {				ldap_chain_db_apply_t	lca;				lca.be = &db;				lca.func = func;				rc = avl_apply( lc->lc_lai.lai_tree,					ldap_chain_db_apply, (void *)&lca,					1, AVL_INORDER ) != AVL_NOMORE;			}		}	}	return rc;}static intldap_chain_db_open(	BackendDB	*be ){	slap_overinst	*on = (slap_overinst *) be->bd_info;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	int		rc = 0;#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR	rc = overlay_register_control( be, LDAP_CONTROL_X_CHAINING_BEHAVIOR );	if ( rc != 0 ) {		return rc;	}#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */	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;	}	/* filter out and restore monitoring */	rc = ldap_chain_db_func( be, db_open );	return rc;}static intldap_chain_db_close(	BackendDB	*be ){	return ldap_chain_db_func( be, db_close );}static intldap_chain_db_destroy(	BackendDB	*be ){	slap_overinst	*on = (slap_overinst *) be->bd_info;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	int		rc;	rc = ldap_chain_db_func( be, db_destroy );	if ( lc ) {		avl_free( lc->lc_lai.lai_tree, NULL );		ldap_pvt_thread_mutex_destroy( &lc->lc_lai.lai_mutex );		ch_free( lc );	}	return rc;}/* * inits one instance of the slapd-ldap backend, and stores * the private info in be_private of the arg */static intldap_chain_db_init_common(	BackendDB	*be ){	BackendInfo	*bi = be->bd_info;	ldapinfo_t	*li;	int		rc;	be->bd_info = lback;	be->be_private = NULL;	rc = lback->bi_db_init( be );	if ( rc != 0 ) {		return rc;	}	li = (ldapinfo_t *)be->be_private;	be->bd_info = bi;	return 0;}/* * inits one instance of the slapd-ldap backend, stores * the private info in be_private of the arg and fills * selected fields with data from the template. * * NOTE: add checks about the other fields of the template, * which are ignored and SHOULD NOT be configured by the user. */static intldap_chain_db_init_one(	BackendDB	*be ){	slap_overinst	*on = (slap_overinst *)be->bd_info;	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;	BackendInfo	*bi = be->bd_info;	ldapinfo_t	*li;	slap_op_t	t;	be->bd_info = lback;	be->be_private = NULL;	t = lback->bi_db_init( be );	if ( t != 0 ) {		return t;	}	li = (ldapinfo_t *)be->be_private;	/* copy common data */	li->li_nretries = lc->lc_common_li->li_nretries;	li->li_flags = lc->lc_common_li->li_flags;	li->li_version = lc->lc_common_li->li_version;	for ( t = 0; t < SLAP_OP_LAST; t++ ) {		li->li_timeout[ t ] = lc->lc_common_li->li_timeout[ t ];	}	be->bd_info = bi;	return 0;}static intldap_chain_db_open_one(	BackendDB	*be ){	return lback->bi_db_open( be );}typedef struct ldap_chain_conn_apply_t {	BackendDB	*be;	Connection	*conn;} ldap_chain_conn_apply_t;static intldap_chain_conn_apply( void *datum, void *arg ){	ldapinfo_t		*li = (ldapinfo_t *)datum;	ldap_chain_conn_apply_t	*lca = (ldap_chain_conn_apply_t *)arg;	lca->be->be_private = (void *)li;	return lback->bi_connection_destroy( lca->be, lca->conn );}static intldap_chain_connection_destroy(	BackendDB *be,	Connection *conn){	slap_overinst		*on = (slap_overinst *) be->bd_info;	ldap_chain_t		*lc = (ldap_chain_t *)on->on_bi.bi_private;	void			*private = be->be_private;	ldap_chain_conn_apply_t	lca;	int			rc;	be->be_private = NULL;	lca.be = be;	lca.conn = conn;	ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );	rc = avl_apply( lc->lc_lai.lai_tree, ldap_chain_conn_apply,		(void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE;	ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );	be->be_private = private;	return rc;}#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIORstatic intldap_chain_parse_ctrl(	Operation	*op,	SlapReply	*rs,	LDAPControl	*ctrl ){	ber_tag_t	tag;	BerElement	*ber;	ber_int_t	mode,			behavior;	if ( get_chaining( op ) != SLAP_CONTROL_NONE ) {		rs->sr_text = "Chaining behavior control specified multiple times";		return LDAP_PROTOCOL_ERROR;	}	if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {		rs->sr_text = "Chaining behavior control specified with pagedResults control";		return LDAP_PROTOCOL_ERROR;	}	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {		mode = (SLAP_CH_RESOLVE_DEFAULT|SLAP_CH_CONTINUATION_DEFAULT);	} else {		ber_len_t	len;		/* Parse the control value		 *      ChainingBehavior ::= SEQUENCE { 		 *           resolveBehavior         Behavior OPTIONAL, 		 *           continuationBehavior    Behavior OPTIONAL } 		 *                             		 *      Behavior :: = ENUMERATED { 		 *           chainingPreferred       (0), 		 *           chainingRequired        (1), 		 *           referralsPreferred      (2), 		 *           referralsRequired       (3) } 		 */		ber = ber_init( &ctrl->ldctl_value );		if( ber == NULL ) {			rs->sr_text = "internal error";			return LDAP_OTHER;		}		tag = ber_scanf( ber, "{e" /* } */, &behavior );		/* FIXME: since the whole SEQUENCE is optional,		 * should we accept no enumerations at all? */		if ( tag != LBER_ENUMERATED ) {			rs->sr_text = "Chaining behavior control: resolveBehavior decoding error";			return LDAP_PROTOCOL_ERROR;		}		switch ( behavior ) {		case LDAP_CHAINING_PREFERRED:			mode = SLAP_CH_RESOLVE_CHAINING_PREFERRED;			break;		case LDAP_CHAINING_REQUIRED:			mode = SLAP_CH_RESOLVE_CHAINING_REQUIRED;			break;		case LDAP_REFERRALS_PREFERRED:			mode = SLAP_CH_RESOLVE_REFERRALS_PREFERRED;			break;		case LDAP_REFERRALS_REQUIRED:			mode = SLAP_CH_RESOLVE_REFERRALS_REQUIRED;			break;		default:			rs->sr_text = "Chaining behavior control: unknown resolveBehavior";			return LDAP_PROTOCOL_ERROR;		}		tag = ber_peek_tag( ber, &len );		if ( tag == LBER_ENUMERATED ) {			tag = ber_scanf( ber, "e", &behavior );			if ( tag == LBER_ERROR ) {				rs->sr_text = "Chaining behavior control: continuationBehavior decoding error";				return LDAP_PROTOCOL_ERROR;			}		}		if ( tag == LBER_DEFAULT ) {			mode |= SLAP_CH_CONTINUATION_DEFAULT;		} else {			switch ( behavior ) {			case LDAP_CHAINING_PREFERRED:				mode |= SLAP_CH_CONTINUATION_CHAINING_PREFERRED;				break;			case LDAP_CHAINING_REQUIRED:				mode |= SLAP_CH_CONTINUATION_CHAINING_REQUIRED;				break;			case LDAP_REFERRALS_PREFERRED:				mode |= SLAP_CH_CONTINUATION_REFERRALS_PREFERRED;				break;			case LDAP_REFERRALS_REQUIRED:				mode |= SLAP_CH_CONTINUATION_REFERRALS_REQUIRED;				break;			default:				rs->sr_text = "Chaining behavior control: unknown continuationBehavior";				return LDAP_PROTOCOL_ERROR;			}		}		if ( ( ber_scanf( ber, /* { */ "}") ) == LBER_ERROR ) {			rs->sr_text = "Chaining behavior control: decoding error";			return LDAP_PROTOCOL_ERROR;		}		(void) ber_free( ber, 1 );	}	op->o_chaining = mode | ( ctrl->ldctl_iscritical			? SLAP_CONTROL_CRITICAL			: SLAP_CONTROL_NONCRITICAL );	return LDAP_SUCCESS;}#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */static slap_overinst ldapchain;intchain_init( void ){	int	rc;	/* Make sure we don't exceed the bits reserved for userland */	config_check_userland( CH_LAST );#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR	rc = register_supported_control( LDAP_CONTROL_X_CHAINING_BEHAVIOR,			/* SLAP_CTRL_GLOBAL| */ SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,			ldap_chain_parse_ctrl, &sc_chainingBehavior );	if ( rc != LDAP_SUCCESS ) {		Debug( LDAP_DEBUG_ANY, "slapd-chain: "			"unable to register chaining behavior control: %d.\n",			rc, 0, 0 );		return rc;	}#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */	ldapchain.on_bi.bi_type = "chain";	ldapchain.on_bi.bi_db_init = ldap_chain_db_init;	ldapchain.on_bi.bi_db_config = ldap_chain_db_config;	ldapchain.on_bi.bi_db_open = ldap_chain_db_open;	ldapchain.on_bi.bi_db_close = ldap_chain_db_close;	ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;	ldapchain.on_bi.bi_connection_destroy = ldap_chain_connection_destroy;	ldapchain.on_response = ldap_chain_response;	ldapchain.on_bi.bi_cf_ocs = chainocs;	rc = config_register_schema( chaincfg, chainocs );	if ( rc ) {		return rc;	}	return overlay_register( &ldapchain );}

⌨️ 快捷键说明

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