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

📄 syncprov.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ( !so->s_res ) {		so->s_res = sr;	} else {		so->s_restail->s_next = sr;	}	so->s_restail = sr;	/* If the base of the psearch was modified, check it next time round */	if ( so->s_flags & PS_WROTE_BASE ) {		so->s_flags ^= PS_WROTE_BASE;		so->s_flags |= PS_FIND_BASE;	}	if ( so->s_flags & PS_IS_DETACHED ) {		syncprov_qstart( so );	}	ldap_pvt_thread_mutex_unlock( &so->s_mutex );	return LDAP_SUCCESS;}static intsyncprov_drop_psearch( syncops *so, int lock ){	if ( so->s_flags & PS_IS_DETACHED ) {		if ( lock )			ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex );		so->s_op->o_conn->c_n_ops_executing--;		so->s_op->o_conn->c_n_ops_completed++;		LDAP_STAILQ_REMOVE( &so->s_op->o_conn->c_ops, so->s_op, slap_op,			o_next );		if ( lock )			ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );	}	syncprov_free_syncop( so );	return 0;}static intsyncprov_ab_cleanup( Operation *op, SlapReply *rs ){	slap_callback *sc = op->o_callback;	op->o_callback = sc->sc_next;	syncprov_drop_psearch( op->o_callback->sc_private, 0 );	op->o_tmpfree( sc, op->o_tmpmemctx );	return 0;}static intsyncprov_op_abandon( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;	syncprov_info_t		*si = on->on_bi.bi_private;	syncops *so, *soprev;	ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );	for ( so=si->si_ops, soprev = (syncops *)&si->si_ops; so;		soprev=so, so=so->s_next ) {		if ( so->s_op->o_connid == op->o_connid &&			so->s_op->o_msgid == op->orn_msgid ) {				so->s_op->o_abandon = 1;				soprev->s_next = so->s_next;				break;		}	}	ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );	if ( so ) {		/* Is this really a Cancel exop? */		if ( op->o_tag != LDAP_REQ_ABANDON ) {			so->s_op->o_cancel = SLAP_CANCEL_ACK;			rs->sr_err = LDAP_CANCELLED;			send_ldap_result( so->s_op, rs );			if ( so->s_flags & PS_IS_DETACHED ) {				slap_callback *cb;				cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );				cb->sc_cleanup = syncprov_ab_cleanup;				cb->sc_next = op->o_callback;				cb->sc_private = so;				return SLAP_CB_CONTINUE;			}		}		syncprov_drop_psearch( so, 0 );	}	return SLAP_CB_CONTINUE;}/* Find which persistent searches are affected by this operation */static voidsyncprov_matchops( Operation *op, opcookie *opc, int saveit ){	slap_overinst *on = opc->son;	syncprov_info_t		*si = on->on_bi.bi_private;	fbase_cookie fc;	syncops *ss, *sprev, *snext;	Entry *e;	Attribute *a;	int rc;	struct berval newdn;	int freefdn = 0;	BackendDB *b0 = op->o_bd, db;	fc.fdn = &op->o_req_ndn;	/* compute new DN */	if ( op->o_tag == LDAP_REQ_MODRDN && !saveit ) {		struct berval pdn;		if ( op->orr_nnewSup ) pdn = *op->orr_nnewSup;		else dnParent( fc.fdn, &pdn );		build_new_dn( &newdn, &pdn, &op->orr_nnewrdn, op->o_tmpmemctx );		fc.fdn = &newdn;		freefdn = 1;	}	if ( op->o_tag != LDAP_REQ_ADD ) {		if ( !SLAP_ISOVERLAY( op->o_bd )) {			db = *op->o_bd;			op->o_bd = &db;		}		op->o_bd->bd_info = (BackendInfo *)on->on_info;		rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );		/* If we're sending responses now, make a copy and unlock the DB */		if ( e && !saveit ) {			Entry *e2 = entry_dup( e );			be_entry_release_rw( op, e, 0 );			e = e2;		}		op->o_bd->bd_info = (BackendInfo *)on;		if ( rc ) {			op->o_bd = b0;			return;		}	} else {		e = op->ora_e;	}	if ( saveit || op->o_tag == LDAP_REQ_ADD ) {		ber_dupbv_x( &opc->sdn, &e->e_name, op->o_tmpmemctx );		ber_dupbv_x( &opc->sndn, &e->e_nname, op->o_tmpmemctx );		opc->sreference = is_entry_referral( e );		a = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );		if ( a )			ber_dupbv_x( &opc->suuid, &a->a_nvals[0], op->o_tmpmemctx );	} else if ( op->o_tag == LDAP_REQ_MODRDN && !saveit ) {		op->o_tmpfree( opc->sndn.bv_val, op->o_tmpmemctx );		op->o_tmpfree( opc->sdn.bv_val, op->o_tmpmemctx );		ber_dupbv_x( &opc->sdn, &e->e_name, op->o_tmpmemctx );		ber_dupbv_x( &opc->sndn, &e->e_nname, op->o_tmpmemctx );	}	ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );	for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss;		sprev = ss, ss=snext)	{		syncmatches *sm;		int found = 0;		snext = ss->s_next;		/* validate base */		fc.fss = ss;		fc.fbase = 0;		fc.fscope = 0;		/* If the base of the search is missing, signal a refresh */		rc = syncprov_findbase( op, &fc );		if ( rc != LDAP_SUCCESS ) {			SlapReply rs = {REP_RESULT};			send_ldap_error( ss->s_op, &rs, LDAP_SYNC_REFRESH_REQUIRED,				"search base has changed" );			sprev->s_next = snext;			syncprov_drop_psearch( ss, 1 );			ss = sprev;			continue;		}		/* If we're sending results now, look for this op in old matches */		if ( !saveit ) {			syncmatches *old;			/* Did we modify the search base? */			if ( dn_match( &op->o_req_ndn, &ss->s_base )) {				ldap_pvt_thread_mutex_lock( &ss->s_mutex );				ss->s_flags |= PS_WROTE_BASE;				ldap_pvt_thread_mutex_unlock( &ss->s_mutex );			}			for ( sm=opc->smatches, old=(syncmatches *)&opc->smatches; sm;				old=sm, sm=sm->sm_next ) {				if ( sm->sm_op == ss ) {					found = 1;					old->sm_next = sm->sm_next;					op->o_tmpfree( sm, op->o_tmpmemctx );					break;				}			}		}		/* check if current o_req_dn is in scope and matches filter */		if ( fc.fscope && test_filter( op, e, ss->s_op->ors_filter ) ==			LDAP_COMPARE_TRUE ) {			if ( saveit ) {				sm = op->o_tmpalloc( sizeof(syncmatches), op->o_tmpmemctx );				sm->sm_next = opc->smatches;				sm->sm_op = ss;				ldap_pvt_thread_mutex_lock( &ss->s_mutex );				++ss->s_inuse;				ldap_pvt_thread_mutex_unlock( &ss->s_mutex );				opc->smatches = sm;			} else {				/* if found send UPDATE else send ADD */				syncprov_qresp( opc, ss,					found ? LDAP_SYNC_MODIFY : LDAP_SYNC_ADD );			}		} else if ( !saveit && found ) {			/* send DELETE */			syncprov_qresp( opc, ss, LDAP_SYNC_DELETE );		}	}	ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );	if ( op->o_tag != LDAP_REQ_ADD && e ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		be_entry_release_rw( op, e, 0 );		op->o_bd->bd_info = (BackendInfo *)on;	}	if ( freefdn ) {		op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx );	}	op->o_bd = b0;}static intsyncprov_op_cleanup( Operation *op, SlapReply *rs ){	slap_callback *cb = op->o_callback;	opcookie *opc = cb->sc_private;	slap_overinst *on = opc->son;	syncprov_info_t		*si = on->on_bi.bi_private;	syncmatches *sm, *snext;	modtarget *mt, mtdummy;	for (sm = opc->smatches; sm; sm=snext) {		snext = sm->sm_next;		syncprov_free_syncop( sm->sm_op );		op->o_tmpfree( sm, op->o_tmpmemctx );	}	/* Remove op from lock table */	mtdummy.mt_op = op;	ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );	mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );	if ( mt ) {		modinst *mi = mt->mt_mods;		/* If there are more, promote the next one */		ldap_pvt_thread_mutex_lock( &mt->mt_mutex );		if ( mi->mi_next ) {			mt->mt_mods = mi->mi_next;			mt->mt_op = mt->mt_mods->mi_op;			ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );		} else {			avl_delete( &si->si_mods, mt, sp_avl_cmp );			ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );			ldap_pvt_thread_mutex_destroy( &mt->mt_mutex );			ch_free( mt );		}	}	ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );	if ( !BER_BVISNULL( &opc->suuid ))		op->o_tmpfree( opc->suuid.bv_val, op->o_tmpmemctx );	if ( !BER_BVISNULL( &opc->sndn ))		op->o_tmpfree( opc->sndn.bv_val, op->o_tmpmemctx );	if ( !BER_BVISNULL( &opc->sdn ))		op->o_tmpfree( opc->sdn.bv_val, op->o_tmpmemctx );	op->o_callback = cb->sc_next;	op->o_tmpfree(cb, op->o_tmpmemctx);	return 0;}static voidsyncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on ){	syncprov_info_t		*si = on->on_bi.bi_private;	Modifications mod;	Operation opm;	SlapReply rsm = { 0 };	struct berval bv[2];	slap_callback cb = {0};	/* If ctxcsn is empty, delete it */	if ( BER_BVISEMPTY( &si->si_ctxcsn )) {		mod.sml_values = NULL;	} else {		mod.sml_values = bv;		bv[1].bv_val = NULL;		bv[0] = si->si_ctxcsn;	}	mod.sml_nvalues = NULL;	mod.sml_desc = slap_schema.si_ad_contextCSN;	mod.sml_op = LDAP_MOD_REPLACE;	mod.sml_flags = 0;	mod.sml_next = NULL;	cb.sc_response = slap_null_cb;	opm = *op;	opm.o_tag = LDAP_REQ_MODIFY;	opm.o_callback = &cb;	opm.orm_modlist = &mod;	opm.o_req_dn = op->o_bd->be_suffix[0];	opm.o_req_ndn = op->o_bd->be_nsuffix[0];	opm.o_bd->bd_info = on->on_info->oi_orig;	opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;	SLAP_DBFLAGS( opm.o_bd ) |= SLAP_DBFLAG_NOLASTMOD;	opm.o_bd->be_modify( &opm, &rsm );	SLAP_DBFLAGS( opm.o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;	if ( mod.sml_next != NULL ) {		slap_mods_free( mod.sml_next, 1 );	}}static voidsyncprov_add_slog( Operation *op ){	opcookie *opc = op->o_callback->sc_private;	slap_overinst *on = opc->son;	syncprov_info_t		*si = on->on_bi.bi_private;	sessionlog *sl;	slog_entry *se;	sl = si->si_logs;	{		/* Allocate a record. UUIDs are not NUL-terminated. */		se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len + 			op->o_csn.bv_len + 1 );		se->se_next = NULL;		se->se_tag = op->o_tag;		se->se_uuid.bv_val = (char *)(&se[1]);		AC_MEMCPY( se->se_uuid.bv_val, opc->suuid.bv_val, opc->suuid.bv_len );		se->se_uuid.bv_len = opc->suuid.bv_len;		se->se_csn.bv_val = se->se_uuid.bv_val + opc->suuid.bv_len;		AC_MEMCPY( se->se_csn.bv_val, op->o_csn.bv_val, op->o_csn.bv_len );		se->se_csn.bv_val[op->o_csn.bv_len] = '\0';		se->se_csn.bv_len = op->o_csn.bv_len;		ldap_pvt_thread_mutex_lock( &sl->sl_mutex );		if ( sl->sl_head ) {			sl->sl_tail->se_next = se;		} else {			sl->sl_head = se;		}		sl->sl_tail = se;		sl->sl_num++;		while ( sl->sl_num > sl->sl_size ) {			se = sl->sl_head;			sl->sl_head = se->se_next;			strcpy( sl->sl_mincsn.bv_val, se->se_csn.bv_val );			sl->sl_mincsn.bv_len = se->se_csn.bv_len;			ch_free( se );			sl->sl_num--;		}		ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );	}}/* Just set a flag if we found the matching entry */static intplaylog_cb( Operation *op, SlapReply *rs ){	if ( rs->sr_type == REP_SEARCH ) {		op->o_callback->sc_private = (void *)1;	}	return rs->sr_err;}/* enter with sl->sl_mutex locked, release before returning */static voidsyncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,	sync_control *srs, struct berval *ctxcsn ){	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;	slog_entry *se;	int i, j, ndel, num, nmods, mmods;	char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];	BerVarray uuids;	struct berval delcsn;	if ( !sl->sl_num ) {		ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );		return;	}	num = sl->sl_num;	i = 0;	nmods = 0;	uuids = op->o_tmpalloc( (num+1) * sizeof( struct berval ) +		num * UUID_LEN, op->o_tmpmemctx );	uuids[0].bv_val = (char *)(uuids + num + 1);	delcsn.bv_len = 0;	delcsn.bv_val = cbuf;	/* Make a copy of the relevant UUIDs. Put the Deletes up front	 * and everything else at the end. Do this first so we can	 * unlock the list mutex.	 */	Debug( LDAP_DEBUG_SYNC, "srs csn %s\n", srs->sr_state.ctxcsn.bv_val, 0, 0 );	for ( se=sl->sl_head; se; se=se->se_next ) {		Debug( LDAP_DEBUG_SYNC, "log csn %s\n", se->se_csn.bv_val, 0, 0 );		ndel = ber_bvcmp( &se->se_csn, &srs->sr_state.ctxcsn );		if ( ndel <= 0 ) {			Debug( LDAP_DEBUG_SYNC, "cmp %d, too old\n", ndel, 0, 0 );			continue;		}		ndel = ber_bvcmp( &se->se_csn, ctxcsn );		if ( ndel > 0 ) {			Debug( LDAP_DEBUG_SYNC, "cmp %d, too new\n", ndel, 0, 0 );			break;		}		if ( se->se_tag == LDAP_REQ_DELETE ) {			j = i;			i++;			AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len );			delcsn.bv_len = se->se_csn.bv_len;			delcsn.bv_val[delcsn.bv_len] = '\0';		} else {			nmods++;			j = num - nmods;		}		uuids[j].bv_val = uuids[0].bv_val + (j * UUID_LEN);		AC_MEMCPY(uuids[j].bv_val, se->se_uuid.bv_val, UUID_LEN);		uuids[j].bv_len = UUID_LEN;	}	ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );	ndel = i;	/* Zero out unused slots */	for ( i=ndel; i < num - nmods; i++ )		uuids[i].bv_len = 0;	/* Mods must be validated to see if they belong in this delete set.	 */	mmods = nmods;	/* Strip any duplicates */	for ( i=0; i<nmods; i++ ) {		for ( j=0; j<ndel; j++ ) {			if ( bvmatch( &uuids[j], &uuids[num - 1 - i] )) {				uuids[num - 1 - i].bv_len = 0;				mmods --;				break;			}		}		if ( uuids[num - 1 - i].bv_len == 0 ) continue;		for ( j=0; j<i; j++ ) {			if ( bvmatch( &uuids[num - 1 - j], &uuids[num - 1 - i] )) {				uuids[num - 1 - i].bv_len = 0;				mmods --;				break;			}		}	}	if ( mmods ) {		Operation fop;		SlapReply frs = { REP_RESULT };		int rc;		Filter mf, af;#ifdef LDAP_COMP_MATCH		AttributeAssertion eq = { NULL, BER_BVNULL, NULL };#else		AttributeAssertion eq;#endif		slap_callback cb = {0};		fop = *op;		fop.o_sync_mode = 0;		fop.o_callback = &cb;		fop.ors_limit = NULL;		fop.ors_tlimit = SLAP_NO_LIMIT;		fop.ors_attrs = slap_anlist_all_attributes;

⌨️ 快捷键说明

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