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

📄 syncprov.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
syncprov_op_search( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;	syncprov_info_t		*si = (syncprov_info_t *)on->on_bi.bi_private;	slap_callback	*cb;	int gotstate = 0, nochange = 0, do_present;	syncops *sop = NULL;	searchstate *ss;	sync_control *srs;	struct berval ctxcsn;	char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];	if ( !(op->o_sync_mode & SLAP_SYNC_REFRESH) ) return SLAP_CB_CONTINUE;	if ( op->ors_deref & LDAP_DEREF_SEARCHING ) {		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "illegal value for derefAliases" );		return rs->sr_err;	}	do_present = si->si_nopres ? 0 : 1;	srs = op->o_controls[slap_cids.sc_LDAPsync];	op->o_managedsait = SLAP_CONTROL_NONCRITICAL;	/* If this is a persistent search, set it up right away */	if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {		syncops so = {0};		fbase_cookie fc;		opcookie opc;		slap_callback sc;		fc.fss = &so;		fc.fbase = 0;		so.s_eid = NOID;		so.s_op = op;		so.s_flags = PS_IS_REFRESHING | PS_FIND_BASE;		/* syncprov_findbase expects to be called as a callback... */		sc.sc_private = &opc;		opc.son = on;		ldap_pvt_thread_mutex_init( &so.s_mutex );		cb = op->o_callback;		op->o_callback = &sc;		rs->sr_err = syncprov_findbase( op, &fc );		op->o_callback = cb;		ldap_pvt_thread_mutex_destroy( &so.s_mutex );		if ( rs->sr_err != LDAP_SUCCESS ) {			send_ldap_result( op, rs );			return rs->sr_err;		}		sop = ch_malloc( sizeof( syncops ));		*sop = so;		ldap_pvt_thread_mutex_init( &sop->s_mutex );		sop->s_rid = srs->sr_state.rid;		sop->s_inuse = 1;		ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );		sop->s_next = si->si_ops;		si->si_ops = sop;		ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );	}	/* snapshot the ctxcsn */	ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock );	strcpy( csnbuf, si->si_ctxcsnbuf );	ctxcsn.bv_len = si->si_ctxcsn.bv_len;	ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock );	ctxcsn.bv_val = csnbuf;		/* If we have a cookie, handle the PRESENT lookups */	if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {		sessionlog *sl;		/* The cookie was validated when it was parsed, just use it */		/* If just Refreshing and nothing has changed, shortcut it */		if ( bvmatch( &srs->sr_state.ctxcsn, &ctxcsn )) {			nochange = 1;			if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {				LDAPControl	*ctrls[2];				ctrls[0] = NULL;				ctrls[1] = NULL;				syncprov_done_ctrl( op, rs, ctrls, 0, 0,					NULL, LDAP_SYNC_REFRESH_DELETES );				rs->sr_ctrls = ctrls;				rs->sr_err = LDAP_SUCCESS;				send_ldap_result( op, rs );				rs->sr_ctrls = NULL;				return rs->sr_err;			}			goto shortcut;		}		/* Do we have a sessionlog for this search? */		sl=si->si_logs;		if ( sl ) {			ldap_pvt_thread_mutex_lock( &sl->sl_mutex );			/* Are there any log entries, and is the consumer state			 * present in the session log?			 */			if ( sl->sl_num > 0 && ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {				do_present = 0;				/* mutex is unlocked in playlog */				syncprov_playlog( op, rs, sl, srs, &ctxcsn );			} else {				ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );			}		}		/* Is the CSN still present in the database? */		if ( syncprov_findcsn( op, FIND_CSN ) != LDAP_SUCCESS ) {			/* No, so a reload is required */			/* the 2.2 consumer doesn't send this hint */			if ( si->si_usehint && srs->sr_rhint == 0 ) {				send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" );				return rs->sr_err;			}		} else {			gotstate = 1;			/* If changed and doing Present lookup, send Present UUIDs */			if ( do_present && syncprov_findcsn( op, FIND_PRESENT ) !=				LDAP_SUCCESS ) {				send_ldap_result( op, rs );				return rs->sr_err;			}		}	}shortcut:	/* Append CSN range to search filter, save original filter	 * for persistent search evaluation	 */	if ( sop ) {		sop->s_filterstr= op->ors_filterstr;	}	/* If something changed, find the changes */	if ( gotstate && !nochange ) {		Filter *fand, *fava;		fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );		fand->f_choice = LDAP_FILTER_AND;		fand->f_next = NULL;		fava = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );		fand->f_and = fava;		fava->f_choice = LDAP_FILTER_GE;		fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );		fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;#ifdef LDAP_COMP_MATCH		fava->f_ava->aa_cf = NULL;#endif		ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );		fava->f_next = op->ors_filter;		op->ors_filter = fand;		filter2bv_x( op, op->ors_filter, &op->ors_filterstr );		if ( sop )			sop->s_flags |= PS_FIX_FILTER;	}	/* Let our callback add needed info to returned entries */	cb = op->o_tmpcalloc(1, sizeof(slap_callback)+sizeof(searchstate), op->o_tmpmemctx);	ss = (searchstate *)(cb+1);	ss->ss_on = on;	ss->ss_so = sop;	ss->ss_present = do_present;	ss->ss_ctxcsn.bv_len = ctxcsn.bv_len;	ss->ss_ctxcsn.bv_val = ss->ss_csnbuf;	strcpy( ss->ss_ctxcsn.bv_val, ctxcsn.bv_val );	cb->sc_response = syncprov_search_response;	cb->sc_cleanup = syncprov_search_cleanup;	cb->sc_private = ss;	cb->sc_next = op->o_callback;	op->o_callback = cb;#if 0	/* I don't think we need to shortcircuit back-bdb any more */	op->o_sync_mode &= SLAP_CONTROL_MASK;#endif	/* If this is a persistent search and no changes were reported during	 * the refresh phase, just invoke the response callback to transition	 * us into persist phase	 */	if ( nochange ) {		rs->sr_err = LDAP_SUCCESS;		rs->sr_nentries = 0;		send_ldap_result( op, rs );		return rs->sr_err;	}	return SLAP_CB_CONTINUE;}static intsyncprov_operational(	Operation *op,	SlapReply *rs ){	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;	syncprov_info_t		*si = (syncprov_info_t *)on->on_bi.bi_private;	if ( rs->sr_entry &&		dn_match( &rs->sr_entry->e_nname, op->o_bd->be_nsuffix )) {		if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||			ad_inlist( slap_schema.si_ad_contextCSN, rs->sr_attrs )) {			Attribute *a, **ap = NULL;			for ( a=rs->sr_entry->e_attrs; a; a=a->a_next ) {				if ( a->a_desc == slap_schema.si_ad_contextCSN )					break;			}			if ( !a ) {				for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next );				a = ch_malloc( sizeof(Attribute));				a->a_desc = slap_schema.si_ad_contextCSN;				a->a_vals = ch_malloc( 2 * sizeof(struct berval));				a->a_vals[1].bv_val = NULL;				a->a_nvals = a->a_vals;				a->a_next = NULL;				a->a_flags = 0;				*ap = a;			}			ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock );			if ( !ap ) {				strcpy( a->a_vals[0].bv_val, si->si_ctxcsnbuf );			} else {				ber_dupbv( &a->a_vals[0], &si->si_ctxcsn );			}			ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock );		}	}	return SLAP_CB_CONTINUE;}enum {	SP_CHKPT = 1,	SP_SESSL,	SP_NOPRES,	SP_USEHINT};static ConfigDriver sp_cf_gen;static ConfigTable spcfg[] = {	{ "syncprov-checkpoint", "ops> <minutes", 3, 3, 0, ARG_MAGIC|SP_CHKPT,		sp_cf_gen, "( OLcfgOvAt:1.1 NAME 'olcSpCheckpoint' "			"DESC 'ContextCSN checkpoint interval in ops and minutes' "			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },	{ "syncprov-sessionlog", "ops", 2, 2, 0, ARG_INT|ARG_MAGIC|SP_SESSL,		sp_cf_gen, "( OLcfgOvAt:1.2 NAME 'olcSpSessionlog' "			"DESC 'Session log size in ops' "			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },	{ "syncprov-nopresent", NULL, 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|SP_NOPRES,		sp_cf_gen, "( OLcfgOvAt:1.3 NAME 'olcSpNoPresent' "			"DESC 'Omit Present phase processing' "			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ "syncprov-reloadhint", NULL, 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|SP_USEHINT,		sp_cf_gen, "( OLcfgOvAt:1.4 NAME 'olcSpReloadHint' "			"DESC 'Observe Reload Hint in Request control' "			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }};static ConfigOCs spocs[] = {	{ "( OLcfgOvOc:1.1 "		"NAME 'olcSyncProvConfig' "		"DESC 'SyncRepl Provider configuration' "		"SUP olcOverlayConfig "		"MAY ( olcSpCheckpoint $ olcSpSessionlog $ olcSpNoPresent ) )",			Cft_Overlay, spcfg },	{ NULL, 0, NULL }};static intsp_cf_gen(ConfigArgs *c){	slap_overinst		*on = (slap_overinst *)c->bi;	syncprov_info_t		*si = (syncprov_info_t *)on->on_bi.bi_private;	int rc = 0;	if ( c->op == SLAP_CONFIG_EMIT ) {		switch ( c->type ) {		case SP_CHKPT:			if ( si->si_chkops || si->si_chktime ) {				struct berval bv;				bv.bv_len = sprintf( c->msg, "%d %d",					si->si_chkops, si->si_chktime );				bv.bv_val = c->msg;				value_add_one( &c->rvalue_vals, &bv );			} else {				rc = 1;			}			break;		case SP_SESSL:			if ( si->si_logs ) {				c->value_int = si->si_logs->sl_size;			} else {				rc = 1;			}			break;		case SP_NOPRES:			if ( si->si_nopres ) {				c->value_int = 1;			} else {				rc = 1;			}			break;		case SP_USEHINT:			if ( si->si_usehint ) {				c->value_int = 1;			} else {				rc = 1;			}			break;		}		return rc;	} else if ( c->op == LDAP_MOD_DELETE ) {		switch ( c->type ) {		case SP_CHKPT:			si->si_chkops = 0;			si->si_chktime = 0;			break;		case SP_SESSL:			if ( si->si_logs )				si->si_logs->sl_size = 0;			else				rc = LDAP_NO_SUCH_ATTRIBUTE;			break;		case SP_NOPRES:			if ( si->si_nopres )				si->si_nopres = 0;			else				rc = LDAP_NO_SUCH_ATTRIBUTE;			break;		case SP_USEHINT:			if ( si->si_usehint )				si->si_usehint = 0;			else				rc = LDAP_NO_SUCH_ATTRIBUTE;			break;		}		return rc;	}	switch ( c->type ) {	case SP_CHKPT:		if ( lutil_atoi( &si->si_chkops, c->argv[1] ) != 0 ) {			snprintf( c->msg, sizeof( c->msg ), "%s unable to parse checkpoint ops # \"%s\"",				c->argv[0], c->argv[1] );			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,				"%s: %s\n", c->log, c->msg, 0 );			return ARG_BAD_CONF;		}		if ( si->si_chkops <= 0 ) {			snprintf( c->msg, sizeof( c->msg ), "%s invalid checkpoint ops # \"%d\"",				c->argv[0], si->si_chkops );			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,				"%s: %s\n", c->log, c->msg, 0 );			return ARG_BAD_CONF;		}		if ( lutil_atoi( &si->si_chktime, c->argv[2] ) != 0 ) {			snprintf( c->msg, sizeof( c->msg ), "%s unable to parse checkpoint time \"%s\"",				c->argv[0], c->argv[1] );			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,				"%s: %s\n", c->log, c->msg, 0 );			return ARG_BAD_CONF;		}		if ( si->si_chktime <= 0 ) {			snprintf( c->msg, sizeof( c->msg ), "%s invalid checkpoint time \"%d\"",				c->argv[0], si->si_chkops );			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,				"%s: %s\n", c->log, c->msg, 0 );			return ARG_BAD_CONF;		}		si->si_chktime *= 60;		break;	case SP_SESSL: {		sessionlog *sl;		int size = c->value_int;		if ( size < 0 ) {			snprintf( c->msg, sizeof( c->msg ), "%s size %d is negative",				c->argv[0], size );			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,				"%s: %s\n", c->log, c->msg, 0 );			return ARG_BAD_CONF;		}		sl = si->si_logs;		if ( !sl ) {			sl = ch_malloc( sizeof( sessionlog ) + LDAP_LUTIL_CSNSTR_BUFSIZE );			sl->sl_mincsn.bv_val = (char *)(sl+1);			sl->sl_mincsn.bv_len = 0;			sl->sl_num = 0;			sl->sl_head = sl->sl_tail = NULL;			ldap_pvt_thread_mutex_init( &sl->sl_mutex );			si->si_logs = sl;		}		sl->sl_size = size;		}		break;	case SP_NOPRES:		si->si_nopres = c->value_int;		break;	case SP_USEHINT:		si->si_usehint = c->value_int;		break;	}	return rc;}/* ITS#3456 we cannot run this search on the main thread, must use a * child thread in order to insure we have a big enough stack. */static void *syncprov_db_otask(	void *ptr){	syncprov_findcsn( ptr, FIND_MAXCSN );	return NULL;}/* Read any existing contextCSN from the underlying db. * Then search for any entries newer than that. If no value exists, * just generate it. Cache whatever result. */static intsyncprov_db_open(    BackendDB *be){	slap_overinst   *on = (slap_overinst *) be->bd_info;	syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;	Connection conn = { 0 };	OperationBuffer opbuf = { 0 };	char ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];	Operation *op = (Operation *) &opbuf;	Entry *e;	Attribute *a;	int rc;	void *thrctx = NULL;	if ( !SLAP_LASTMOD( be )) {		Debug( LDAP_DEBUG_ANY,			"syncprov_db_open: invalid config, lastmod must be enabled\n", 0, 0, 0 );		return -1;	}	if ( slapMode & SLAP_TOOL_MODE ) {		return 0;	}	rc = overlay_register_control( be, LDAP_CONTROL_SYNC );	if ( rc ) {		return rc;	}	thrctx = ldap_pvt_thread_pool_context();	connection_fake_init( &conn, op, thrctx );	op->o_bd = be;	op->o_dn = be->be_rootdn;	op->o_ndn = be->be_rootndn;	ctxcsnbuf[0] = '\0';	op->o_bd->bd_info = on->on_info->oi_orig;	rc = be_entry_get_rw( op, be->be_nsuffix, NULL,		slap_schema.si_ad_contextCSN, 0, &e );	if ( e ) {		ldap_pvt_thread_t tid;		a = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );		if ( a ) {			si->si_ctxcsn.bv_len = a->a_nvals[0].bv_len;			if ( si->si_ctxcsn.bv_len >= sizeof(si->si_ctxcsnbuf ))				si->si_ctxcsn.bv_len = sizeof(si->si_ctxcsnbuf)-1;			strncpy( si->si_ctxcsnbuf, a->a_nvals[0].bv_val,				si->si_ctxcsn.bv_len );			si->si_ctxcsnbuf[si->si_ctxcsn.bv_len] = '\0';			strcpy( ctxcsnbuf, si->si_

⌨️ 快捷键说明

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