View | Details | Raw Unified | Return to bug 25171
Collapse All | Expand All

(-)a/lib/ldb/include/ldb_module.h (-2 / +2 lines)
Lines 85-94 void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBU Link Here
85
void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level);
85
void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level);
86
86
87
#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__)
87
#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__)
88
#define ldb_module_error(module, ecode, reason) ldb_error_at(ldb_module_get_ctx(module), ecode, reason, __FILE__, __LINE__)
88
89
89
#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory")
90
#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory")
90
#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module))
91
#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module))
91
#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error")
92
#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error")
93
#define ldb_module_operr(module) ldb_error(ldb_module_get_ctx(module), LDB_ERR_OPERATIONS_ERROR, "operations error")
92
94
93
/* The following definitions come from lib/ldb/common/ldb.c  */
95
/* The following definitions come from lib/ldb/common/ldb.c  */
94
96
95
- 
96
--
97
source4/dsdb/samdb/ldb_modules/partition.c       |  146 ++--------------------
97
source4/dsdb/samdb/ldb_modules/partition.c       |  146 ++--------------------
98
source4/dsdb/samdb/ldb_modules/simple_ldap_map.c |    7 +-
98
source4/dsdb/samdb/ldb_modules/simple_ldap_map.c |    7 +-
99
2 files changed, 13 insertions(+), 140 deletions(-)
99
2 files changed, 13 insertions(+), 140 deletions(-)
(-)a/source4/dsdb/samdb/ldb_modules/partition.c (-135 / +11 lines)
Lines 1002-1014 int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem Link Here
1002
	seqr = talloc_get_type(res->extended->data,
1002
	seqr = talloc_get_type(res->extended->data,
1003
			       struct ldb_seqnum_result);
1003
			       struct ldb_seqnum_result);
1004
	if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {
1004
	if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {
1005
		ret = LDB_ERR_OPERATIONS_ERROR;
1006
		ldb_set_errstring(ldb_module_get_ctx(module), "Primary backend in partitions module returned a timestamp based seq number (must return a normal number)");
1007
		talloc_free(res);
1005
		talloc_free(res);
1008
		return ret;
1006
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
1009
	} else {
1007
			"Primary backend in partition module returned a timestamp based seq");
1010
		*seq_number = seqr->seq_num;
1011
	}
1008
	}
1009
1010
	*seq_number = seqr->seq_num;
1012
	talloc_free(res);
1011
	talloc_free(res);
1013
	return LDB_SUCCESS;
1012
	return LDB_SUCCESS;
1014
}
1013
}
Lines 1019-1026 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1019
	int ret;
1018
	int ret;
1020
	unsigned int i;
1019
	unsigned int i;
1021
	uint64_t seq_number = 0;
1020
	uint64_t seq_number = 0;
1022
	uint64_t timestamp_sequence = 0;
1023
	uint64_t timestamp = 0;
1024
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
1021
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
1025
							      struct partition_private_data);
1022
							      struct partition_private_data);
1026
	struct ldb_seqnum_request *seq;
1023
	struct ldb_seqnum_request *seq;
Lines 1098-1211 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1098
			}
1095
			}
1099
			tseqr = talloc_get_type(res->extended->data,
1096
			tseqr = talloc_get_type(res->extended->data,
1100
						struct ldb_seqnum_result);
1097
						struct ldb_seqnum_result);
1101
			if (tseqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {
1098
			seq_number += tseqr->seq_num;
1102
				timestamp_sequence = MAX(timestamp_sequence,
1103
							 tseqr->seq_num);
1104
			} else {
1105
				seq_number += tseqr->seq_num;
1106
			}
1107
			talloc_free(res);
1108
		}
1109
		/* fall through */
1110
	case LDB_SEQ_HIGHEST_TIMESTAMP:
1111
1112
		res = talloc_zero(req, struct ldb_result);
1113
		if (res == NULL) {
1114
			return ldb_oom(ldb_module_get_ctx(module));
1115
		}
1116
1117
		tseq = talloc_zero(res, struct ldb_seqnum_request);
1118
		if (tseq == NULL) {
1119
			talloc_free(res);
1120
			return ldb_oom(ldb_module_get_ctx(module));
1121
		}
1122
		tseq->type = LDB_SEQ_HIGHEST_TIMESTAMP;
1123
1124
		ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
1125
					     LDB_EXTENDED_SEQUENCE_NUMBER,
1126
					     tseq,
1127
					     NULL,
1128
					     res,
1129
					     ldb_extended_default_callback,
1130
					     req);
1131
		LDB_REQ_SET_LOCATION(treq);
1132
		if (ret != LDB_SUCCESS) {
1133
			talloc_free(res);
1134
			return ret;
1135
		}
1136
1137
		ret = ldb_next_request(module, treq);
1138
		if (ret != LDB_SUCCESS) {
1139
			talloc_free(res);
1140
			return ret;
1141
		}
1142
		ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
1143
		if (ret != LDB_SUCCESS) {
1144
			talloc_free(res);
1145
			return ret;
1146
		}
1147
1148
		tseqr = talloc_get_type(res->extended->data,
1149
					   struct ldb_seqnum_result);
1150
		timestamp = tseqr->seq_num;
1151
1152
		talloc_free(res);
1153
1154
		/* Skip the lot if 'data' isn't here yet (initialisation) */
1155
		for (i=0; data && data->partitions && data->partitions[i]; i++) {
1156
1157
			res = talloc_zero(req, struct ldb_result);
1158
			if (res == NULL) {
1159
				return ldb_oom(ldb_module_get_ctx(module));
1160
			}
1161
1162
			tseq = talloc_zero(res, struct ldb_seqnum_request);
1163
			if (tseq == NULL) {
1164
				talloc_free(res);
1165
				return ldb_oom(ldb_module_get_ctx(module));
1166
			}
1167
			tseq->type = LDB_SEQ_HIGHEST_TIMESTAMP;
1168
1169
			ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
1170
						     LDB_EXTENDED_SEQUENCE_NUMBER,
1171
						     tseq,
1172
						     NULL,
1173
						     res,
1174
						     ldb_extended_default_callback,
1175
						     req);
1176
			LDB_REQ_SET_LOCATION(treq);
1177
			if (ret != LDB_SUCCESS) {
1178
				talloc_free(res);
1179
				return ret;
1180
			}
1181
1182
			ret = ldb_request_add_control(treq,
1183
						      DSDB_CONTROL_CURRENT_PARTITION_OID,
1184
						      false, data->partitions[i]->ctrl);
1185
			if (ret != LDB_SUCCESS) {
1186
				talloc_free(res);
1187
				return ret;
1188
			}
1189
1190
			ret = partition_request(data->partitions[i]->module, treq);
1191
			if (ret != LDB_SUCCESS) {
1192
				talloc_free(res);
1193
				return ret;
1194
			}
1195
			ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
1196
			if (ret != LDB_SUCCESS) {
1197
				talloc_free(res);
1198
				return ret;
1199
			}
1200
1201
			tseqr = talloc_get_type(res->extended->data,
1202
						  struct ldb_seqnum_result);
1203
			timestamp = MAX(timestamp, tseqr->seq_num);
1204
1205
			talloc_free(res);
1099
			talloc_free(res);
1206
		}
1100
		}
1207
1208
		break;
1101
		break;
1102
1103
	case LDB_SEQ_HIGHEST_TIMESTAMP:
1104
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR, "LDB_SEQ_HIGHEST_TIMESTAMP not supported");
1209
	}
1105
	}
1210
1106
1211
	ext = talloc_zero(req, struct ldb_extended);
1107
	ext = talloc_zero(req, struct ldb_extended);
Lines 1220-1252 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1220
	ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1116
	ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1221
	ext->data = seqr;
1117
	ext->data = seqr;
1222
1118
1223
	switch (seq->type) {
1119
	seqr->seq_num = seq_number;
1224
	case LDB_SEQ_NEXT:
1225
	case LDB_SEQ_HIGHEST_SEQ:
1226
1227
		/* Has someone above set a timebase sequence? */
1228
		if (timestamp_sequence) {
1229
			seqr->seq_num = (((unsigned long long)timestamp << 24) | (seq_number & 0xFFFFFF));
1230
		} else {
1231
			seqr->seq_num = seq_number;
1232
		}
1233
1234
		if (timestamp_sequence > seqr->seq_num) {
1235
			seqr->seq_num = timestamp_sequence;
1236
			seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE;
1237
		}
1238
1239
		seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
1240
		break;
1241
	case LDB_SEQ_HIGHEST_TIMESTAMP:
1242
		seqr->seq_num = timestamp;
1243
		break;
1244
	}
1245
1246
	if (seq->type == LDB_SEQ_NEXT) {
1120
	if (seq->type == LDB_SEQ_NEXT) {
1247
		seqr->seq_num++;
1121
		seqr->seq_num++;
1248
	}
1122
	}
1249
1123
1124
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
1125
1250
	/* send request done */
1126
	/* send request done */
1251
	return ldb_module_done(req, NULL, ext, LDB_SUCCESS);
1127
	return ldb_module_done(req, NULL, ext, LDB_SUCCESS);
1252
}
1128
}
(-)a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c (-7 / +2 lines)
Lines 902-914 static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
902
		seqr->seq_num++;
902
		seqr->seq_num++;
903
		break;
903
		break;
904
	case LDB_SEQ_HIGHEST_TIMESTAMP:
904
	case LDB_SEQ_HIGHEST_TIMESTAMP:
905
	{
905
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR, "LDB_SEQ_HIGHEST_TIMESTAMP not supported");
906
		seqr->seq_num = (seq_num >> 24);
907
		break;
908
	}
909
	}
906
	}
907
910
	seqr->flags = 0;
908
	seqr->flags = 0;
911
	seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE;
912
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
909
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
913
910
914
	/* send request done */
911
	/* send request done */
915
- 
916
--
917
source4/dsdb/samdb/ldb_modules/util.c |   23 ++++++++++++++++++++---
912
source4/dsdb/samdb/ldb_modules/util.c |   23 ++++++++++++++++++++---
918
1 files changed, 20 insertions(+), 3 deletions(-)
913
1 files changed, 20 insertions(+), 3 deletions(-)
(-)a/source4/dsdb/samdb/ldb_modules/util.c (-5 / +20 lines)
Lines 314-327 int dsdb_module_guid_by_dn(struct ldb_module *module, struct ldb_dn *dn, struct Link Here
314
	talloc_free(tmp_ctx);
314
	talloc_free(tmp_ctx);
315
	return LDB_SUCCESS;
315
	return LDB_SUCCESS;
316
}
316
}
317
318
317
/*
319
/*
318
  a ldb_extended request operating on modules below the
320
  a ldb_extended request operating on modules below the
319
  current module
321
  current module
322
323
  Note that this does not automatically start a transaction. If you
324
  need a transaction the caller needs to start it as needed.
320
 */
325
 */
321
int dsdb_module_extended(struct ldb_module *module,
326
int dsdb_module_extended(struct ldb_module *module,
322
		       const char* oid, void* data,
327
			 TALLOC_CTX *mem_ctx,
323
		       uint32_t dsdb_flags,
328
			 struct ldb_result **_res,
324
		       struct ldb_request *parent)
329
			 const char* oid, void* data,
330
			 uint32_t dsdb_flags,
331
			 struct ldb_request *parent)
325
{
332
{
326
	struct ldb_request *req;
333
	struct ldb_request *req;
327
	int ret;
334
	int ret;
Lines 329-334 int dsdb_module_extended(struct ldb_module *module, Link Here
329
	TALLOC_CTX *tmp_ctx = talloc_new(module);
336
	TALLOC_CTX *tmp_ctx = talloc_new(module);
330
	struct ldb_result *res;
337
	struct ldb_result *res;
331
338
339
	if (_res != NULL) {
340
		(*_res) = NULL;
341
	}
342
332
	res = talloc_zero(tmp_ctx, struct ldb_result);
343
	res = talloc_zero(tmp_ctx, struct ldb_result);
333
	if (!res) {
344
	if (!res) {
334
		talloc_free(tmp_ctx);
345
		talloc_free(tmp_ctx);
Lines 373-381 int dsdb_module_extended(struct ldb_module *module, Link Here
373
		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
384
		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
374
	}
385
	}
375
386
387
	if (_res != NULL && ret == LDB_SUCCESS) {
388
		(*_res) = talloc_steal(mem_ctx, res);
389
	}
390
376
	talloc_free(tmp_ctx);
391
	talloc_free(tmp_ctx);
377
	return ret;
392
	return ret;
378
}
393
}
394
395
379
/*
396
/*
380
  a ldb_modify request operating on modules below the
397
  a ldb_modify request operating on modules below the
381
  current module
398
  current module
382
- 
383
--
384
source4/dsdb/samdb/ldb_modules/partition.c      |   42 ++++++----------------
399
source4/dsdb/samdb/ldb_modules/partition.c      |   42 ++++++----------------
385
source4/dsdb/samdb/ldb_modules/partition_init.c |    2 +-
400
source4/dsdb/samdb/ldb_modules/partition_init.c |    2 +-
386
2 files changed, 13 insertions(+), 31 deletions(-)
401
2 files changed, 13 insertions(+), 31 deletions(-)
(-)a/source4/dsdb/samdb/ldb_modules/partition.c (-30 / +12 lines)
Lines 957-1001 static int partition_del_trans(struct ldb_module *module) Link Here
957
}
957
}
958
958
959
int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem_ctx, 
959
int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem_ctx, 
960
				     enum ldb_sequence_type type, uint64_t *seq_number) 
960
				     enum ldb_sequence_type type, uint64_t *seq_number,
961
				     struct ldb_request *parent)
961
{
962
{
962
	int ret;
963
	int ret;
963
	struct ldb_result *res;
964
	struct ldb_result *res;
964
	struct ldb_seqnum_request *tseq;
965
	struct ldb_seqnum_request *tseq;
965
	struct ldb_request *treq;
966
	struct ldb_seqnum_result *seqr;
966
	struct ldb_seqnum_result *seqr;
967
	res = talloc_zero(mem_ctx, struct ldb_result);
967
968
	if (res == NULL) {
968
	tseq = talloc_zero(mem_ctx, struct ldb_seqnum_request);
969
		return ldb_oom(ldb_module_get_ctx(module));
970
	}
971
	tseq = talloc_zero(res, struct ldb_seqnum_request);
972
	if (tseq == NULL) {
969
	if (tseq == NULL) {
973
		talloc_free(res);
974
		return ldb_oom(ldb_module_get_ctx(module));
970
		return ldb_oom(ldb_module_get_ctx(module));
975
	}
971
	}
976
	tseq->type = type;
972
	tseq->type = type;
977
	
973
	
978
	ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
974
	ret = dsdb_module_extended(module, tseq, &res,
979
				     LDB_EXTENDED_SEQUENCE_NUMBER,
975
				   LDB_EXTENDED_SEQUENCE_NUMBER,
980
				     tseq,
976
				   tseq,
981
				     NULL,
977
				   DSDB_FLAG_NEXT_MODULE,
982
				     res,
978
				   parent);
983
				     ldb_extended_default_callback,
984
				     NULL);
985
	LDB_REQ_SET_LOCATION(treq);
986
	if (ret != LDB_SUCCESS) {
979
	if (ret != LDB_SUCCESS) {
987
		talloc_free(res);
980
		talloc_free(tseq);
988
		return ret;
989
	}
990
	
991
	ret = ldb_next_request(module, treq);
992
	if (ret != LDB_SUCCESS) {
993
		talloc_free(res);
994
		return ret;
995
	}
996
	ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
997
	if (ret != LDB_SUCCESS) {
998
		talloc_free(res);
999
		return ret;
981
		return ret;
1000
	}
982
	}
1001
	
983
	
Lines 1008-1014 int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem Link Here
1008
	}
990
	}
1009
991
1010
	*seq_number = seqr->seq_num;
992
	*seq_number = seqr->seq_num;
1011
	talloc_free(res);
993
	talloc_free(tseq);
1012
	return LDB_SUCCESS;
994
	return LDB_SUCCESS;
1013
}
995
}
1014
996
Lines 1043-1049 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1043
	case LDB_SEQ_NEXT:
1025
	case LDB_SEQ_NEXT:
1044
	case LDB_SEQ_HIGHEST_SEQ:
1026
	case LDB_SEQ_HIGHEST_SEQ:
1045
1027
1046
		ret = partition_primary_sequence_number(module, req, seq->type, &seq_number);
1028
		ret = partition_primary_sequence_number(module, req, seq->type, &seq_number, req);
1047
		if (ret != LDB_SUCCESS) {
1029
		if (ret != LDB_SUCCESS) {
1048
			return ret;
1030
			return ret;
1049
		}
1031
		}
(-)a/source4/dsdb/samdb/ldb_modules/partition_init.c (-3 / +1 lines)
Lines 397-403 int partition_reload_if_required(struct ldb_module *module, Link Here
397
		return ldb_oom(ldb);
397
		return ldb_oom(ldb);
398
	}
398
	}
399
399
400
	ret = partition_primary_sequence_number(module, mem_ctx, LDB_SEQ_HIGHEST_SEQ, &seq);
400
	ret = partition_primary_sequence_number(module, mem_ctx, LDB_SEQ_HIGHEST_SEQ, &seq, parent);
401
	if (ret != LDB_SUCCESS) {
401
	if (ret != LDB_SUCCESS) {
402
		talloc_free(mem_ctx);
402
		talloc_free(mem_ctx);
403
		return ret;
403
		return ret;
404
- 
405
--
406
source4/dsdb/samdb/ldb_modules/partition.c         |  122 +++++-
404
source4/dsdb/samdb/ldb_modules/partition.c         |  122 +++++-
407
source4/dsdb/samdb/ldb_modules/partition.h         |    7 +
405
source4/dsdb/samdb/ldb_modules/partition.h         |    7 +
408
source4/dsdb/samdb/ldb_modules/partition_init.c    |    6 +
406
source4/dsdb/samdb/ldb_modules/partition_init.c    |    6 +
409
.../dsdb/samdb/ldb_modules/partition_metadata.c    |  492 ++++++++++++++++++++
407
.../dsdb/samdb/ldb_modules/partition_metadata.c    |  492 ++++++++++++++++++++
410
source4/dsdb/samdb/ldb_modules/wscript_build       |    2 +-
408
source4/dsdb/samdb/ldb_modules/wscript_build       |    2 +-
411
5 files changed, 612 insertions(+), 17 deletions(-)
409
5 files changed, 612 insertions(+), 17 deletions(-)
412
create mode 100644 source4/dsdb/samdb/ldb_modules/partition_metadata.c
410
create mode 100644 source4/dsdb/samdb/ldb_modules/partition_metadata.c
(-)a/source4/dsdb/samdb/ldb_modules/partition.c (-16 / +106 lines)
Lines 824-829 static int partition_start_trans(struct ldb_module *module) Link Here
824
824
825
	ret = partition_reload_if_required(module, data, NULL);
825
	ret = partition_reload_if_required(module, data, NULL);
826
	if (ret != LDB_SUCCESS) {
826
	if (ret != LDB_SUCCESS) {
827
		ldb_next_del_trans(module);
828
		return ret;
829
	}
830
831
	ret = partition_metadata_start_trans(module);
832
	if (ret != LDB_SUCCESS) {
833
		ldb_next_del_trans(module);
827
		return ret;
834
		return ret;
828
	}
835
	}
829
836
Lines 839-844 static int partition_start_trans(struct ldb_module *module) Link Here
839
				ldb_next_del_trans(data->partitions[i]->module);
846
				ldb_next_del_trans(data->partitions[i]->module);
840
			}
847
			}
841
			ldb_next_del_trans(module);
848
			ldb_next_del_trans(module);
849
			partition_metadata_del_trans(module);
842
			return ret;
850
			return ret;
843
		}
851
		}
844
	}
852
	}
Lines 854-863 static int partition_prepare_commit(struct ldb_module *module) Link Here
854
	unsigned int i;
862
	unsigned int i;
855
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
863
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
856
							      struct partition_private_data);
864
							      struct partition_private_data);
865
	int ret;
857
866
858
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
867
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
859
		int ret;
860
861
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
868
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
862
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> %s",
869
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> %s",
863
				  ldb_dn_get_linearized(data->partitions[i]->ctrl->dn));
870
				  ldb_dn_get_linearized(data->partitions[i]->ctrl->dn));
Lines 874-880 static int partition_prepare_commit(struct ldb_module *module) Link Here
874
	if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
881
	if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
875
		ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> (metadata partition)");
882
		ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> (metadata partition)");
876
	}
883
	}
877
	return ldb_next_prepare_commit(module);
884
885
	ret = ldb_next_prepare_commit(module);
886
	if (ret != LDB_SUCCESS) {
887
		return ret;
888
	}
889
890
	/* metadata prepare commit must come last, as other partitions could modify
891
	 * the database inside the prepare commit method of a module */
892
	return partition_metadata_prepare_commit(module);
878
}
893
}
879
894
880
895
Lines 895-900 static int partition_end_trans(struct ldb_module *module) Link Here
895
		data->in_transaction--;
910
		data->in_transaction--;
896
	}
911
	}
897
912
913
	ret2 = partition_metadata_end_trans(module);
914
	if (ret2 != LDB_SUCCESS) {
915
		ret = ret2;
916
	}
917
898
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
918
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
899
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
919
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
900
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> %s",
920
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> %s",
Lines 926-931 static int partition_del_trans(struct ldb_module *module) Link Here
926
	unsigned int i;
946
	unsigned int i;
927
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
947
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
928
							      struct partition_private_data);
948
							      struct partition_private_data);
949
	ret = partition_metadata_del_trans(module);
950
	if (ret != LDB_SUCCESS) {
951
		final_ret = ret;
952
	}
953
929
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
954
	for (i=0; data && data->partitions && data->partitions[i]; i++) {
930
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
955
		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
931
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_del_trans() -> %s",
956
			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_del_trans() -> %s",
Lines 957-964 static int partition_del_trans(struct ldb_module *module) Link Here
957
}
982
}
958
983
959
int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem_ctx, 
984
int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem_ctx, 
960
				     enum ldb_sequence_type type, uint64_t *seq_number,
985
				      enum ldb_sequence_type type, uint64_t *seq_number,
961
				     struct ldb_request *parent)
986
				      struct ldb_request *parent)
962
{
987
{
963
	int ret;
988
	int ret;
964
	struct ldb_result *res;
989
	struct ldb_result *res;
Lines 981-988 int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem Link Here
981
		return ret;
1006
		return ret;
982
	}
1007
	}
983
	
1008
	
984
	seqr = talloc_get_type(res->extended->data,
1009
	seqr = talloc_get_type_abort(res->extended->data,
985
			       struct ldb_seqnum_result);
1010
				     struct ldb_seqnum_result);
986
	if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {
1011
	if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {
987
		talloc_free(res);
1012
		talloc_free(res);
988
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
1013
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
Lines 994-1001 int partition_primary_sequence_number(struct ldb_module *module, TALLOC_CTX *mem Link Here
994
	return LDB_SUCCESS;
1019
	return LDB_SUCCESS;
995
}
1020
}
996
1021
997
/* FIXME: This function is still semi-async */
1022
998
static int partition_sequence_number(struct ldb_module *module, struct ldb_request *req)
1023
/*
1024
 * Older version of sequence number as sum of sequence numbers for each partition
1025
 */
1026
int partition_sequence_number_from_partitions(struct ldb_module *module,
1027
					      struct ldb_request *req,
1028
					      struct ldb_extended **ext)
999
{
1029
{
1000
	int ret;
1030
	int ret;
1001
	unsigned int i;
1031
	unsigned int i;
Lines 1007-1013 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1007
	struct ldb_request *treq;
1037
	struct ldb_request *treq;
1008
	struct ldb_seqnum_request *tseq;
1038
	struct ldb_seqnum_request *tseq;
1009
	struct ldb_seqnum_result *tseqr;
1039
	struct ldb_seqnum_result *tseqr;
1010
	struct ldb_extended *ext;
1011
	struct ldb_result *res;
1040
	struct ldb_result *res;
1012
	struct dsdb_partition *p;
1041
	struct dsdb_partition *p;
1013
1042
Lines 1086-1102 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1086
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR, "LDB_SEQ_HIGHEST_TIMESTAMP not supported");
1115
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR, "LDB_SEQ_HIGHEST_TIMESTAMP not supported");
1087
	}
1116
	}
1088
1117
1089
	ext = talloc_zero(req, struct ldb_extended);
1118
	*ext = talloc_zero(req, struct ldb_extended);
1090
	if (!ext) {
1119
	if (!*ext) {
1091
		return ldb_oom(ldb_module_get_ctx(module));
1120
		return ldb_oom(ldb_module_get_ctx(module));
1092
	}
1121
	}
1093
	seqr = talloc_zero(ext, struct ldb_seqnum_result);
1122
	seqr = talloc_zero(*ext, struct ldb_seqnum_result);
1094
	if (seqr == NULL) {
1123
	if (seqr == NULL) {
1095
		talloc_free(ext);
1124
		talloc_free(*ext);
1096
		return ldb_oom(ldb_module_get_ctx(module));
1125
		return ldb_oom(ldb_module_get_ctx(module));
1097
	}
1126
	}
1098
	ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1127
	(*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1099
	ext->data = seqr;
1128
	(*ext)->data = seqr;
1100
1129
1101
	seqr->seq_num = seq_number;
1130
	seqr->seq_num = seq_number;
1102
	if (seq->type == LDB_SEQ_NEXT) {
1131
	if (seq->type == LDB_SEQ_NEXT) {
Lines 1104-1109 static int partition_sequence_number(struct ldb_module *module, struct ldb_reque Link Here
1104
	}
1133
	}
1105
1134
1106
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
1135
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
1136
	return LDB_SUCCESS;
1137
}
1138
1139
1140
/*
1141
 * Newer version of sequence number using metadata tdb
1142
 */
1143
static int partition_sequence_number(struct ldb_module *module, struct ldb_request *req)
1144
{
1145
	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
1146
							      struct partition_private_data);
1147
	struct ldb_extended *ext;
1148
	struct ldb_seqnum_request *seq;
1149
	struct ldb_seqnum_result *seqr;
1150
	uint64_t seq_number;
1151
	struct dsdb_partition *p;
1152
	int ret;
1153
1154
	p = find_partition(data, NULL, req);
1155
	if (p != NULL) {
1156
		/* the caller specified what partition they want the
1157
		 * sequence number operation on - just pass it on
1158
		 */
1159
		return ldb_next_request(p->module, req);
1160
	}
1161
1162
	seq = talloc_get_type_abort(req->op.extended.data, struct ldb_seqnum_request);
1163
	switch (seq->type) {
1164
	case LDB_SEQ_NEXT:
1165
		ret = partition_metadata_sequence_number_increment(module, &seq_number);
1166
		if (ret != LDB_SUCCESS) {
1167
			return ret;
1168
		}
1169
		break;
1170
1171
	case LDB_SEQ_HIGHEST_SEQ:
1172
		ret = partition_metadata_sequence_number(module, &seq_number);
1173
		if (ret != LDB_SUCCESS) {
1174
			return ret;
1175
		}
1176
		break;
1177
1178
	case LDB_SEQ_HIGHEST_TIMESTAMP:
1179
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
1180
					"LDB_SEQ_HIGHEST_TIMESTAMP not supported");
1181
	}
1182
1183
	ext = talloc_zero(req, struct ldb_extended);
1184
	if (!ext) {
1185
		return ldb_module_oom(module);
1186
	}
1187
	seqr = talloc_zero(ext, struct ldb_seqnum_result);
1188
	if (seqr == NULL) {
1189
		talloc_free(ext);
1190
		return ldb_module_oom(module);
1191
	}
1192
	ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1193
	ext->data = seqr;
1194
1195
	seqr->seq_num = seq_number;
1196
	seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
1107
1197
1108
	/* send request done */
1198
	/* send request done */
1109
	return ldb_module_done(req, NULL, ext, LDB_SUCCESS);
1199
	return ldb_module_done(req, NULL, ext, LDB_SUCCESS);
(-)a/source4/dsdb/samdb/ldb_modules/partition.h (+7 lines)
Lines 21-26 Link Here
21
#include <ldb.h>
21
#include <ldb.h>
22
#include <ldb_errors.h>
22
#include <ldb_errors.h>
23
#include <ldb_module.h>
23
#include <ldb_module.h>
24
#include "lib/util/tdb_wrap.h"
24
#include "dsdb/samdb/samdb.h"
25
#include "dsdb/samdb/samdb.h"
25
#include "dsdb/samdb/ldb_modules/util.h"
26
#include "dsdb/samdb/ldb_modules/util.h"
26
#include "system/locale.h"
27
#include "system/locale.h"
Lines 39-47 struct partition_module { Link Here
39
	struct ldb_dn *dn;
40
	struct ldb_dn *dn;
40
};
41
};
41
42
43
struct partition_metadata {
44
	struct tdb_wrap *db;
45
	int in_transaction;
46
};
47
42
struct partition_private_data {
48
struct partition_private_data {
43
	struct dsdb_partition **partitions;
49
	struct dsdb_partition **partitions;
44
	struct ldb_dn **replicate;
50
	struct ldb_dn **replicate;
51
	struct partition_metadata *metadata;
45
	
52
	
46
	struct partition_module **modules;
53
	struct partition_module **modules;
47
	const char *ldapBackend;
54
	const char *ldapBackend;
(-)a/source4/dsdb/samdb/ldb_modules/partition_init.c (+6 lines)
Lines 875-879 int partition_init(struct ldb_module *module) Link Here
875
		return ldb_operr(ldb);
875
		return ldb_operr(ldb);
876
	}
876
	}
877
877
878
	/* This loads metadata tdb. If it's missing, creates it */
879
	ret = partition_metadata_init(module);
880
	if (ret != LDB_SUCCESS) {
881
		return ret;
882
	}
883
878
	return ldb_next_init(module);
884
	return ldb_next_init(module);
879
}
885
}
(-)a/source4/dsdb/samdb/ldb_modules/partition_metadata.c (+492 lines)
Line 0 Link Here
1
/*
2
   Partitions ldb module - management of metadata.tdb for sequence number
3
4
   Copyright (C) Amitay Isaacs <amitay@samba.org> 2011
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "dsdb/samdb/ldb_modules/partition.h"
21
#include "system/filesys.h"
22
23
#define LDB_METADATA_SEQ_NUM	"SEQ_NUM"
24
25
26
/*
27
 * Read a key with uint64 value
28
 */
29
static int partition_metadata_get_uint64(struct ldb_module *module,
30
					 const char *key, uint64_t *value,
31
					 uint64_t default_value)
32
{
33
	struct partition_private_data *data;
34
	struct tdb_context *tdb;
35
	TDB_DATA tdb_key, tdb_data;
36
	char *value_str;
37
	TALLOC_CTX *tmp_ctx;
38
39
	data = talloc_get_type_abort(ldb_module_get_private(module),
40
				     struct partition_private_data);
41
42
	if (!data && !data->metadata && !data->metadata->db) {
43
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
44
					"partition_metadata: metadata tdb not initialized");
45
	}
46
47
	tmp_ctx = talloc_new(NULL);
48
	if (tmp_ctx == NULL) {
49
		return ldb_module_oom(module);
50
	}
51
52
	tdb = data->metadata->db->tdb;
53
54
	tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
55
	tdb_key.dsize = strlen(key);
56
57
	tdb_data = tdb_fetch(tdb, tdb_key);
58
	if (!tdb_data.dptr) {
59
		if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
60
			*value = default_value;
61
			return LDB_SUCCESS;
62
		} else {
63
			return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
64
						tdb_errorstr(tdb));
65
		}
66
	}
67
68
	value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
69
	if (value_str == NULL) {
70
		SAFE_FREE(tdb_data.dptr);
71
		talloc_free(tmp_ctx);
72
		return ldb_module_oom(module);
73
	}
74
75
	*value = strtoull(value_str, NULL, 10);
76
77
	SAFE_FREE(tdb_data.dptr);
78
	talloc_free(tmp_ctx);
79
80
	return LDB_SUCCESS;
81
}
82
83
84
/*
85
 * Write a key with uin64 value
86
 */
87
static int partition_metadata_set_uint64(struct ldb_module *module,
88
					 const char *key, uint64_t value,
89
					 bool insert)
90
{
91
	struct partition_private_data *data;
92
	struct tdb_context *tdb;
93
	TDB_DATA tdb_key, tdb_data;
94
	int tdb_flag;
95
	char *value_str;
96
	TALLOC_CTX *tmp_ctx;
97
98
	data = talloc_get_type_abort(ldb_module_get_private(module),
99
				     struct partition_private_data);
100
101
	if (!data && !data->metadata && !data->metadata->db) {
102
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
103
					"partition_metadata: metadata tdb not initialized");
104
	}
105
106
	tmp_ctx = talloc_new(NULL);
107
	if (tmp_ctx == NULL) {
108
		return ldb_module_oom(module);
109
	}
110
111
	tdb = data->metadata->db->tdb;
112
113
	value_str = talloc_asprintf(tmp_ctx, "%llu", (unsigned long long)value);
114
	if (value_str == NULL) {
115
		talloc_free(tmp_ctx);
116
		return ldb_module_oom(module);
117
	}
118
119
	tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
120
	tdb_key.dsize = strlen(key);
121
122
	tdb_data.dptr = (uint8_t *)value_str;
123
	tdb_data.dsize = strlen(value_str);
124
125
	if (insert) {
126
		tdb_flag = TDB_INSERT;
127
	} else {
128
		tdb_flag = TDB_MODIFY;
129
	}
130
131
	if (tdb_store(tdb, tdb_key, tdb_data, tdb_flag) != 0) {
132
		talloc_free(tmp_ctx);
133
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
134
					tdb_errorstr(tdb));
135
	}
136
137
	talloc_free(tmp_ctx);
138
139
	return LDB_SUCCESS;
140
}
141
142
143
/*
144
 * Open sam.ldb.d/metadata.tdb.
145
 */
146
static int partition_metadata_open(struct ldb_module *module, bool create)
147
{
148
	struct ldb_context *ldb = ldb_module_get_ctx(module);
149
	TALLOC_CTX *tmp_ctx;
150
	struct partition_private_data *data;
151
	struct loadparm_context *lp_ctx;
152
	const char *sam_name;
153
	char *filename, *dirname;
154
	int open_flags;
155
156
	data = talloc_get_type_abort(ldb_module_get_private(module),
157
				     struct partition_private_data);
158
	if (!data || !data->metadata) {
159
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
160
					"partition_metadata: metadata not initialized");
161
	}
162
163
	tmp_ctx = talloc_new(NULL);
164
	if (tmp_ctx == NULL) {
165
		return ldb_module_oom(module);
166
	}
167
168
	sam_name = (const char *)ldb_get_opaque(ldb, "ldb_url");
169
	if (strncmp("tdb://", sam_name, 6) == 0) {
170
		sam_name += 6;
171
	}
172
	if (!sam_name) {
173
		talloc_free(tmp_ctx);
174
		return ldb_operr(ldb);
175
	}
176
	filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name);
177
	if (!filename) {
178
		talloc_free(tmp_ctx);
179
		return ldb_oom(ldb);
180
	}
181
182
	open_flags = O_RDWR;
183
	if (create) {
184
		open_flags |= O_CREAT;
185
186
		/* While provisioning, sam.ldb.d directory may not exist,
187
		 * so create it. Ignore errors, if it already exists. */
188
		dirname = talloc_asprintf(tmp_ctx, "%s.d", sam_name);
189
		if (!dirname) {
190
			talloc_free(tmp_ctx);
191
			return ldb_oom(ldb);
192
		}
193
194
		mkdir(dirname, 0700);
195
		talloc_free(dirname);
196
	}
197
198
	lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
199
				       struct loadparm_context);
200
201
	data->metadata->db = tdb_wrap_open(data->metadata, filename, 10,
202
					      TDB_DEFAULT, open_flags, 0660,
203
					      lp_ctx);
204
	if (data->metadata->db == NULL) {
205
		talloc_free(tmp_ctx);
206
		if (create) {
207
			ldb_debug(ldb, LDB_DEBUG_ERROR,
208
				  "partition_metadata: Unable to create %s",
209
				  filename);
210
		}
211
		return LDB_ERR_OPERATIONS_ERROR;
212
	}
213
214
	talloc_free(tmp_ctx);
215
	return LDB_SUCCESS;
216
}
217
218
219
/*
220
 * Set the sequence number calculated from older logic (sum of primary sequence
221
 * numbers for each partition) as LDB_METADATA_SEQ_NUM key.
222
 */
223
static int partition_metadata_set_sequence_number(struct ldb_module *module)
224
{
225
	struct partition_private_data *data;
226
	struct ldb_result *res;
227
	struct ldb_request *req;
228
	struct ldb_seqnum_request *seq;
229
	struct ldb_seqnum_result *seqr;
230
	struct ldb_extended *ext;
231
	TALLOC_CTX *tmp_ctx;
232
	int ret;
233
	uint64_t seq_number;
234
235
	data = talloc_get_type_abort(ldb_module_get_private(module),
236
				    struct partition_private_data);
237
	if (!data || !data->metadata) {
238
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
239
					"partition_metadata: metadata not initialized");
240
	}
241
242
	tmp_ctx = talloc_new(data->metadata);
243
	if (tmp_ctx == NULL) {
244
		return ldb_module_oom(module);
245
	}
246
247
	res = talloc_zero(tmp_ctx, struct ldb_result);
248
	if (res == NULL) {
249
		talloc_free(tmp_ctx);
250
		return ldb_module_oom(module);
251
	}
252
253
	seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request);
254
	if (seq == NULL) {
255
		talloc_free(tmp_ctx);
256
		return ldb_module_oom(module);
257
	}
258
	seq->type = LDB_SEQ_HIGHEST_SEQ;
259
260
	/* Build an extended request, so it can be passed to each partition in
261
	   partition_sequence_number_from_partitions() */
262
	ret = ldb_build_extended_req(&req,
263
				     ldb_module_get_ctx(module),
264
				     tmp_ctx,
265
				     LDB_EXTENDED_SEQUENCE_NUMBER,
266
				     seq,
267
				     NULL,
268
				     res,
269
				     ldb_extended_default_callback,
270
				     NULL);
271
	LDB_REQ_SET_LOCATION(req);
272
	if (ret != LDB_SUCCESS) {
273
		talloc_free(tmp_ctx);
274
		return ret;
275
	}
276
277
	ret = partition_sequence_number_from_partitions(module, req, &ext);
278
	if (ret != LDB_SUCCESS) {
279
		talloc_free(tmp_ctx);
280
		return ret;
281
	}
282
283
	seqr = talloc_get_type_abort(ext->data, struct ldb_seqnum_result);
284
	seq_number = seqr->seq_num;
285
286
	talloc_free(tmp_ctx);
287
288
	return partition_metadata_set_uint64(module, LDB_METADATA_SEQ_NUM, seq_number, true);
289
}
290
291
292
/*
293
 * Initialize metadata. Load metadata.tdb.
294
 * If missing, create it and fill in sequence number
295
 */
296
int partition_metadata_init(struct ldb_module *module)
297
{
298
	struct partition_private_data *data;
299
	int ret;
300
301
	data = talloc_get_type_abort(ldb_module_get_private(module),
302
				     struct partition_private_data);
303
304
	data->metadata = talloc_zero(data, struct partition_metadata);
305
	if (data->metadata == NULL) {
306
		return ldb_module_oom(module);
307
	}
308
309
	ret = partition_metadata_open(module, false);
310
	if (ret == LDB_SUCCESS) {
311
		goto end;
312
	}
313
314
	/* metadata.tdb does not exist, create it */
315
	DEBUG(2, ("partition_metadata: Migrating partition metadata\n"));
316
	ret = partition_metadata_open(module, true);
317
	if (ret != LDB_SUCCESS) {
318
		talloc_free(data->metadata);
319
		data->metadata = NULL;
320
		goto end;
321
	}
322
323
	ret = partition_metadata_set_sequence_number(module);
324
	if (ret != LDB_SUCCESS) {
325
		talloc_free(data->metadata);
326
		data->metadata = NULL;
327
	}
328
329
end:
330
	return ret;
331
}
332
333
334
/*
335
 * Read the sequence number, default to 0 if LDB_METADATA_SEQ_NUM key is missing
336
 */
337
int partition_metadata_sequence_number(struct ldb_module *module, uint64_t *value)
338
{
339
	return partition_metadata_get_uint64(module,
340
					     LDB_METADATA_SEQ_NUM,
341
					     value,
342
					     0);
343
}
344
345
346
/*
347
 * Increment the sequence number, returning the new sequence number
348
 */
349
int partition_metadata_sequence_number_increment(struct ldb_module *module, uint64_t *value)
350
{
351
	struct partition_private_data *data;
352
	int ret;
353
354
	data = talloc_get_type_abort(ldb_module_get_private(module),
355
				    struct partition_private_data);
356
	if (!data && !data->metadata) {
357
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
358
					"partition_metadata: metadata not initialized");
359
	}
360
361
	if (data->metadata->in_transaction == 0) {
362
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
363
					"partition_metadata: increment sequence number without transaction");
364
	}
365
366
	ret = partition_metadata_get_uint64(module, LDB_METADATA_SEQ_NUM, value, 0);
367
	if (ret != LDB_SUCCESS) {
368
		return ret;
369
	}
370
371
	(*value)++;
372
	ret = partition_metadata_set_uint64(module, LDB_METADATA_SEQ_NUM, *value, false);
373
	return ret;
374
}
375
376
377
/*
378
 * Transaction start
379
 */
380
int partition_metadata_start_trans(struct ldb_module *module)
381
{
382
	struct partition_private_data *data;
383
	struct tdb_context *tdb;
384
385
	data = talloc_get_type_abort(ldb_module_get_private(module),
386
				     struct partition_private_data);
387
	if (!data && !data->metadata && !data->metadata->db) {
388
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
389
					"partition_metadata: metadata not initialized");
390
	}
391
	tdb = data->metadata->db->tdb;
392
393
	if (tdb_transaction_start(tdb) != 0) {
394
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
395
					tdb_errorstr(tdb));
396
	}
397
398
	data->metadata->in_transaction++;
399
400
	return LDB_SUCCESS;
401
}
402
403
404
/*
405
 * Transaction prepare commit
406
 */
407
int partition_metadata_prepare_commit(struct ldb_module *module)
408
{
409
	struct partition_private_data *data;
410
	struct tdb_context *tdb;
411
412
	data = talloc_get_type_abort(ldb_module_get_private(module),
413
				     struct partition_private_data);
414
	if (!data && !data->metadata && !data->metadata->db) {
415
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
416
					"partition_metadata: metadata not initialized");
417
	}
418
	tdb = data->metadata->db->tdb;
419
420
	if (data->metadata->in_transaction == 0) {
421
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
422
					"partition_metadata: not in transaction");
423
	}
424
425
	if (tdb_transaction_prepare_commit(tdb) != 0) {
426
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
427
					tdb_errorstr(tdb));
428
	}
429
430
	return LDB_SUCCESS;
431
}
432
433
434
/*
435
 * Transaction end
436
 */
437
int partition_metadata_end_trans(struct ldb_module *module)
438
{
439
	struct partition_private_data *data;
440
	struct tdb_context *tdb;
441
442
	data = talloc_get_type_abort(ldb_module_get_private(module),
443
				     struct partition_private_data);
444
	if (!data && !data->metadata && !data->metadata->db) {
445
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
446
					"partition_metadata: metadata not initialized");
447
	}
448
	tdb = data->metadata->db->tdb;
449
450
	if (data->metadata->in_transaction == 0) {
451
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
452
					"partition_metadata: not in transaction");
453
	}
454
455
	data->metadata->in_transaction--;
456
457
	if (tdb_transaction_commit(tdb) != 0) {
458
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
459
					tdb_errorstr(tdb));
460
	}
461
462
	return LDB_SUCCESS;
463
}
464
465
466
/*
467
 * Transaction delete
468
 */
469
int partition_metadata_del_trans(struct ldb_module *module)
470
{
471
	struct partition_private_data *data;
472
	struct tdb_context *tdb;
473
474
	data = talloc_get_type_abort(ldb_module_get_private(module),
475
				     struct partition_private_data);
476
	if (!data && !data->metadata && !data->metadata->db) {
477
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
478
					"partition_metadata: metadata not initialized");
479
	}
480
	tdb = data->metadata->db->tdb;
481
482
	if (data->metadata->in_transaction == 0) {
483
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
484
					"partition_metadata: not in transaction");
485
	}
486
487
	data->metadata->in_transaction--;
488
489
	tdb_transaction_cancel(tdb);
490
491
	return LDB_SUCCESS;
492
}
(-)a/source4/dsdb/samdb/ldb_modules/wscript_build (-3 / +1 lines)
Lines 194-200 bld.SAMBA_MODULE('ldb_show_deleted', Link Here
194
194
195
195
196
bld.SAMBA_MODULE('ldb_partition',
196
bld.SAMBA_MODULE('ldb_partition',
197
	source='partition.c partition_init.c',
197
	source='partition.c partition_init.c partition_metadata.c',
198
	autoproto='partition_proto.h',
198
	autoproto='partition_proto.h',
199
	subsystem='ldb',
199
	subsystem='ldb',
200
	init_function='ldb_partition_module_init',
200
	init_function='ldb_partition_module_init',
201
- 
Line 01 Link Here
01
   lib/util: Add back control of mmap and hash size in tdb for top level build
934
   lib/util: Add back control of mmap and hash size in tdb for top level build
2
   This passes down a struct loadparm_context to allow these
935
   This passes down a struct loadparm_context to allow these
3
   parameters to be checked.  This may be s3 or s4 context, allowing the
936
   parameters to be checked.  This may be s3 or s4 context, allowing the
4
   #if _SAMBA_BUILD_ macro to go away safely.
937
   #if _SAMBA_BUILD_ macro to go away safely.
5
   Andrew Bartlett
938
   Andrew Bartlett
6
--
7
.../dsdb/samdb/ldb_modules/partition_metadata.c    |    3 +--
939
.../dsdb/samdb/ldb_modules/partition_metadata.c    |    3 +--
8
1 files changed, 1 insertions(+), 2 deletions(-)
940
1 files changed, 1 insertions(+), 2 deletions(-)
(-)a/source4/dsdb/samdb/ldb_modules/partition_metadata.c (-4 / +1 lines)
Lines 199-206 static int partition_metadata_open(struct ldb_module *module, bool create) Link Here
199
				       struct loadparm_context);
199
				       struct loadparm_context);
200
200
201
	data->metadata->db = tdb_wrap_open(data->metadata, filename, 10,
201
	data->metadata->db = tdb_wrap_open(data->metadata, filename, 10,
202
					      TDB_DEFAULT, open_flags, 0660,
202
					      TDB_DEFAULT, open_flags, 0660);
203
					      lp_ctx);
204
	if (data->metadata->db == NULL) {
203
	if (data->metadata->db == NULL) {
205
		talloc_free(tmp_ctx);
204
		talloc_free(tmp_ctx);
206
		if (create) {
205
		if (create) {
207
- 
208
(cherry picked from commit 13545d781b257afe3c3a107a669851c38cdfefbd)
206
(cherry picked from commit 13545d781b257afe3c3a107a669851c38cdfefbd)
209
--
210
source4/scripting/python/samba/samdb.py |   14 ++++++++++++++
207
source4/scripting/python/samba/samdb.py |   14 ++++++++++++++
211
1 files changed, 14 insertions(+), 0 deletions(-)
208
1 files changed, 14 insertions(+), 0 deletions(-)
(-)a/source4/scripting/python/samba/samdb.py (-1 / +14 lines)
Lines 817-819 accountExpires: %u Link Here
817
        if sd:
817
        if sd:
818
            m["nTSecurityDescriptor"] = ndr_pack(sd)
818
            m["nTSecurityDescriptor"] = ndr_pack(sd)
819
        self.add(m)
819
        self.add(m)
820
- 
820
821
    def sequence_number(self, seq_type):
822
        """Returns the value of the sequence number according to the requested type
823
        :param seq_type: type of sequence number
824
         """
825
        self.transaction_start()
826
        try:
827
            seq = super(SamDB, self).sequence_number(seq_type)
828
        except Exception:
829
             self.transaction_cancel()
830
             raise
831
        else:
832
            self.transaction_commit()
833
        return seq

Return to bug 25171