ctxcsn.c 5.15 KB
Newer Older
Kurt Zeilenga's avatar
Kurt Zeilenga committed
1
/* ctxcsn.c -- Context CSN Management Routines */
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
2
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
4
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
5
 * Copyright 2003-2020 The OpenLDAP Foundation.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
 * Portions Copyright 2003 IBM Corporation.
 * All rights reserved.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
8
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
9
10
11
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
12
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
13
14
15
 * 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>.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
16
17
18
19
20
21
22
23
24
25
26
27
28
 */

#include "portable.h"

#include <stdio.h>

#include <ac/string.h>
#include <ac/socket.h>

#include "lutil.h"
#include "slap.h"
#include "lutil_ldap.h"

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
29
30
const struct berval slap_ldapsync_bv = BER_BVC("ldapsync");
const struct berval slap_ldapsync_cn_bv = BER_BVC("cn=ldapsync");
31
int slap_serverID;
Howard Chu's avatar
Howard Chu committed
32

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
33
/* maxcsn->bv_val must point to a char buf[LDAP_PVT_CSNSTR_BUFSIZE] */
Howard Chu's avatar
Howard Chu committed
34
void
35
36
slap_get_commit_csn(
	Operation *op,
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
37
38
	struct berval *maxcsn,
	int *foundit
39
)
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
40
{
41
	struct slap_csn_entry *csne, *committed_csne = NULL;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
42
	BackendDB *be = op->o_bd->bd_self;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
43
	int sid = -1;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
44

45
	if ( maxcsn ) {
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
46
		assert( maxcsn->bv_val != NULL );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
47
		assert( maxcsn->bv_len >= LDAP_PVT_CSNSTR_BUFSIZE );
48
	}
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
49
50
51
	if ( foundit ) {
		*foundit = 0;
	}
Howard Chu's avatar
Howard Chu committed
52

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
53
	ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
54

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
55
56
57
58
	if ( !BER_BVISEMPTY( &op->o_csn )) {
		sid = slap_parse_csn_sid( &op->o_csn );
	}

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
59
	LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
Howard Chu's avatar
Howard Chu committed
60
		if ( csne->ce_op == op ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
61
			csne->ce_state = SLAP_CSN_COMMIT;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
62
			if ( foundit ) *foundit = 1;
63
64
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
65
66
	}

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
67
	LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
68
69
70
71
		if ( sid != -1 && sid == csne->ce_sid ) {
			if ( csne->ce_state == SLAP_CSN_COMMIT ) committed_csne = csne;
			if ( csne->ce_state == SLAP_CSN_PENDING ) break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
72
	}
73

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
74
75
76
77
78
79
80
81
82
83
84
	if ( maxcsn ) {
		if ( committed_csne ) {
			if ( committed_csne->ce_csn.bv_len < maxcsn->bv_len )
				maxcsn->bv_len = committed_csne->ce_csn.bv_len;
			AC_MEMCPY( maxcsn->bv_val, committed_csne->ce_csn.bv_val,
				maxcsn->bv_len+1 );
		} else {
			maxcsn->bv_len = 0;
			maxcsn->bv_val[0] = 0;
		}
	}
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
85
	ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
86
87
88
}

void
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
89
slap_rewind_commit_csn( Operation *op )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
90
{
91
	struct slap_csn_entry *csne;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
92
	BackendDB *be = op->o_bd->bd_self;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
93

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
94
	ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
95

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
96
	LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
Howard Chu's avatar
Howard Chu committed
97
		if ( csne->ce_op == op ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
98
			csne->ce_state = SLAP_CSN_PENDING;
99
100
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
101
102
	}

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
103
	ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
104
105
106
}

void
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
107
slap_graduate_commit_csn( Operation *op )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
108
{
109
	struct slap_csn_entry *csne;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
110
	BackendDB *be;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
111

Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
112
113
	if ( op == NULL ) return;
	if ( op->o_bd == NULL ) return;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
114
	be = op->o_bd->bd_self;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
115

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
116
	ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
117

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
118
	LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
Howard Chu's avatar
Howard Chu committed
119
		if ( csne->ce_op == op ) {
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
120
			LDAP_TAILQ_REMOVE( be->be_pending_csn_list,
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
121
				csne, ce_csn_link );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
122
			Debug( LDAP_DEBUG_SYNC, "slap_graduate_commit_csn: removing %p %s\n",
Howard Chu's avatar
Cleanup    
Howard Chu committed
123
				csne, csne->ce_csn.bv_val, 0 );
Howard Chu's avatar
Howard Chu committed
124
125
126
			if ( op->o_csn.bv_val == csne->ce_csn.bv_val ) {
				BER_BVZERO( &op->o_csn );
			}
127
			ch_free( csne->ce_csn.bv_val );
128
129
130
			ch_free( csne );
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
131
132
	}

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
133
	ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
134
135
136
137

	return;
}

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
static struct berval ocbva[] = {
	BER_BVC("top"),
	BER_BVC("subentry"),
	BER_BVC("syncProviderSubentry"),
	BER_BVNULL
};

Entry *
slap_create_context_csn_entry(
	Backend *be,
	struct berval *context_csn )
{
	Entry* e;

	struct berval bv;

	e = entry_alloc();

	attr_merge( e, slap_schema.si_ad_objectClass,
		ocbva, NULL );
	attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
		&ocbva[1], NULL );
	attr_merge_one( e, slap_schema.si_ad_cn,
		(struct berval *)&slap_ldapsync_bv, NULL );

	if ( context_csn ) {
		attr_merge_one( e, slap_schema.si_ad_contextCSN,
			context_csn, NULL );
	}

	BER_BVSTR( &bv, "{}" );
	attr_merge_one( e, slap_schema.si_ad_subtreeSpecification, &bv, NULL );

	build_new_dn( &e->e_name, &be->be_nsuffix[0],
		(struct berval *)&slap_ldapsync_cn_bv, NULL );
	ber_dupbv( &e->e_nname, &e->e_name );

	return e;
}

178
179
180
181
182
183
void
slap_queue_csn(
	Operation *op,
	struct berval *csn )
{
	struct slap_csn_entry *pending;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
184
	BackendDB *be = op->o_bd->bd_self;
185
186
187

	pending = (struct slap_csn_entry *) ch_calloc( 1,
			sizeof( struct slap_csn_entry ));
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
188

Howard Chu's avatar
Cleanup    
Howard Chu committed
189
	Debug( LDAP_DEBUG_SYNC, "slap_queue_csn: queueing %p %s\n", pending, csn->bv_val, 0 );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
190

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
191
	ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
192

193
	ber_dupbv( &pending->ce_csn, csn );
194
	ber_bvreplace_x( &op->o_csn, &pending->ce_csn, op->o_tmpmemctx );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
195
	pending->ce_sid = slap_parse_csn_sid( csn );
Howard Chu's avatar
Howard Chu committed
196
	pending->ce_op = op;
197
	pending->ce_state = SLAP_CSN_PENDING;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
198
	LDAP_TAILQ_INSERT_TAIL( be->be_pending_csn_list,
199
		pending, ce_csn_link );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
200
	ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
201
202
}

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
203
204
205
206
int
slap_get_csn(
	Operation *op,
	struct berval *csn,
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
207
	int manage_ctxcsn )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
208
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
209
	if ( csn == NULL ) return LDAP_OTHER;
210

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
211
	csn->bv_len = ldap_pvt_csnstr( csn->bv_val, csn->bv_len, slap_serverID, 0 );
212
213
	Debug( LDAP_DEBUG_SYNC, "slap_get_csn: %s generated new csn=%s manage=%d\n",
		op->o_log_prefix, csn->bv_val, manage_ctxcsn );
214
215
	if ( manage_ctxcsn )
		slap_queue_csn( op, csn );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
216
217
218

	return LDAP_SUCCESS;
}