mirror of
https://git.FreeBSD.org/ports.git
synced 2024-11-26 00:55:14 +00:00
Update Samba ports to versions 4.2.11 and 4.3.8 respectivelly, to address BadLock vulnerability(http://badlock.org).
Security: CVE-2016-2118
This commit is contained in:
parent
0e46db7805
commit
58f656ae56
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=413163
@ -3,7 +3,7 @@
|
||||
|
||||
PORTNAME?= ${SAMBA4_BASENAME}42
|
||||
PORTVERSION?= ${SAMBA4_VERSION}
|
||||
PORTREVISION?= 2
|
||||
PORTREVISION?= 0
|
||||
CATEGORIES?= net
|
||||
MASTER_SITES= SAMBA/samba/stable SAMBA/samba/rc
|
||||
DISTNAME= ${SAMBA4_DISTNAME}
|
||||
@ -15,11 +15,11 @@ LICENSE= GPLv3
|
||||
|
||||
CONFLICTS?= *samba3[2-6]-3.* samba4-4.0.* samba41-4.1.* samba43-4.3.*
|
||||
|
||||
EXTRA_PATCHES= ${PATCHDIR}/extra-patch-security:-p1
|
||||
#EXTRA_PATCHES= ${PATCHDIR}/extra-patch-security:-p1
|
||||
|
||||
SAMBA4_BASENAME= samba
|
||||
SAMBA4_PORTNAME= ${SAMBA4_BASENAME}4
|
||||
SAMBA4_VERSION= 4.2.7
|
||||
SAMBA4_VERSION= 4.2.11
|
||||
SAMBA4_DISTNAME= ${SAMBA4_BASENAME}-${SAMBA4_VERSION:S|.p|pre|:S|.r|rc|:S|.t|tp|:S|.a|alpha|}
|
||||
|
||||
WRKSRC?= ${WRKDIR}/${DISTNAME}
|
||||
|
@ -1,2 +1,2 @@
|
||||
SHA256 (samba-4.2.7.tar.gz) = f586ab3166ce4c663360f15b1de24ef083816a5471856e3ad49bc26b35f0104a
|
||||
SIZE (samba-4.2.7.tar.gz) = 20741971
|
||||
SHA256 (samba-4.2.11.tar.gz) = 75bce53c922e51352933c9846f2c4b1e251fabb80927adb426a773a321ee01f8
|
||||
SIZE (samba-4.2.11.tar.gz) = 20875348
|
||||
|
@ -1,647 +0,0 @@
|
||||
From 6a25f2a8c651523a272c0019895e1d2b1e83b022 Mon Sep 17 00:00:00 2001
|
||||
From: Volker Lendecke <vl@samba.org>
|
||||
Date: Sat, 18 Jul 2015 21:50:55 +0200
|
||||
Subject: [PATCH 1/5] dbwrap_rbt: Make "key" and "value" aligned to 16 byte
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reported by Uri Simchoni <urisimchoni@gmail.com>. Thanks!
|
||||
|
||||
Signed-off-by: Volker Lendecke <vl@samba.org>
|
||||
Reviewed-by: Ralph Boehme <slow@samba.org>
|
||||
|
||||
Autobuild-User(master): Ralph Böhme <slow@samba.org>
|
||||
Autobuild-Date(master): Mon Jul 20 23:18:23 CEST 2015 on sn-devel-104
|
||||
|
||||
(cherry picked from commit 64a88f74ca5309dce1d3ec0755ceba4af5144dbd)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 51 +++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 39 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index 3f97086..03f2f57 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -38,13 +38,6 @@ struct db_rbt_rec {
|
||||
struct db_rbt_node {
|
||||
struct rb_node rb_node;
|
||||
size_t keysize, valuesize;
|
||||
-
|
||||
- /*
|
||||
- * key and value are appended implicitly, "data" is only here as a
|
||||
- * target for offsetof()
|
||||
- */
|
||||
-
|
||||
- char data[1];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -83,12 +76,43 @@ static int db_rbt_compare(TDB_DATA a, TDB_DATA b)
|
||||
static void db_rbt_parse_node(struct db_rbt_node *node,
|
||||
TDB_DATA *key, TDB_DATA *value)
|
||||
{
|
||||
- key->dptr = ((uint8_t *)node) + offsetof(struct db_rbt_node, data);
|
||||
+ size_t key_offset, value_offset;
|
||||
+
|
||||
+ key_offset = DBWRAP_RBT_ALIGN(sizeof(struct db_rbt_node));
|
||||
+ key->dptr = ((uint8_t *)node) + key_offset;
|
||||
key->dsize = node->keysize;
|
||||
- value->dptr = key->dptr + node->keysize;
|
||||
+
|
||||
+ value_offset = DBWRAP_RBT_ALIGN(node->keysize);
|
||||
+ value->dptr = key->dptr + value_offset;
|
||||
value->dsize = node->valuesize;
|
||||
}
|
||||
|
||||
+static ssize_t db_rbt_reclen(size_t keylen, size_t valuelen)
|
||||
+{
|
||||
+ size_t len, tmp;
|
||||
+
|
||||
+ len = DBWRAP_RBT_ALIGN(sizeof(struct db_rbt_node));
|
||||
+
|
||||
+ tmp = DBWRAP_RBT_ALIGN(keylen);
|
||||
+ if (tmp < keylen) {
|
||||
+ goto overflow;
|
||||
+ }
|
||||
+
|
||||
+ len += tmp;
|
||||
+ if (len < tmp) {
|
||||
+ goto overflow;
|
||||
+ }
|
||||
+
|
||||
+ len += valuelen;
|
||||
+ if (len < valuelen) {
|
||||
+ goto overflow;
|
||||
+ }
|
||||
+
|
||||
+ return len;
|
||||
+overflow:
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
{
|
||||
struct db_rbt_ctx *db_ctx = talloc_get_type_abort(
|
||||
@@ -99,6 +123,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
struct rb_node ** p;
|
||||
struct rb_node * parent;
|
||||
|
||||
+ ssize_t reclen;
|
||||
TDB_DATA this_key, this_val;
|
||||
|
||||
if (rec_priv->node != NULL) {
|
||||
@@ -123,10 +148,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
}
|
||||
}
|
||||
|
||||
- node = (struct db_rbt_node *)talloc_size(db_ctx,
|
||||
- offsetof(struct db_rbt_node, data) + rec->key.dsize
|
||||
- + data.dsize);
|
||||
+ reclen = db_rbt_reclen(rec->key.dsize, data.dsize);
|
||||
+ if (reclen == -1) {
|
||||
+ return NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
+ }
|
||||
|
||||
+ node = talloc_size(db_ctx, reclen);
|
||||
if (node == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From b4d52184a113851954b1b901f478db200e9fd7a8 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 10:17:34 +0100
|
||||
Subject: [PATCH 2/5] dbwrap_rbt: use talloc_zero_size() instead of a partial
|
||||
ZERO_STRUCT()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit f3d1fc1d06822a951a2a3eeb5aa53748b9b5b299)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index 03f2f57..2d65647 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -153,7 +153,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
return NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
- node = talloc_size(db_ctx, reclen);
|
||||
+ node = talloc_zero_size(db_ctx, reclen);
|
||||
if (node == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@@ -172,8 +172,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
*/
|
||||
}
|
||||
|
||||
- ZERO_STRUCT(node->rb_node);
|
||||
-
|
||||
node->keysize = rec->key.dsize;
|
||||
node->valuesize = data.dsize;
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From 10abdaf5c7f99eca742c84a7d55b7bb9c324aeab Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 09:22:08 +0100
|
||||
Subject: [PATCH 3/5] dbwrap_rbt: add nested traverse protection
|
||||
|
||||
Multiple dbwrap_traverse_read() calls are possible.
|
||||
|
||||
store() and delete() on a fetch locked record
|
||||
are rejected during dbwrap_traverse_read().
|
||||
|
||||
A dbwrap_traverse() within a dbwrap_traverse_read()
|
||||
behaves like a dbwrap_traverse_read().
|
||||
|
||||
Nested dbwrap_traverse() calls are not possible.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit 590507951fc514a679f44b8bfdd03c721189c3fa)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 71 ++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 40 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index 2d65647..d4cb40d 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
struct db_rbt_ctx {
|
||||
struct rb_root tree;
|
||||
+ size_t traverse_read;
|
||||
+ bool traverse_write;
|
||||
};
|
||||
|
||||
struct db_rbt_rec {
|
||||
@@ -126,6 +128,10 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
ssize_t reclen;
|
||||
TDB_DATA this_key, this_val;
|
||||
|
||||
+ if (db_ctx->traverse_read > 0) {
|
||||
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
+ }
|
||||
+
|
||||
if (rec_priv->node != NULL) {
|
||||
|
||||
/*
|
||||
@@ -222,6 +228,10 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
rec->db->private_data, struct db_rbt_ctx);
|
||||
struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
|
||||
|
||||
+ if (db_ctx->traverse_read > 0) {
|
||||
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
+ }
|
||||
+
|
||||
if (rec_priv->node == NULL) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -232,16 +242,6 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
-static NTSTATUS db_rbt_store_deny(struct db_record *rec, TDB_DATA data, int flag)
|
||||
-{
|
||||
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS db_rbt_delete_deny(struct db_record *rec)
|
||||
-{
|
||||
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
-}
|
||||
-
|
||||
struct db_rbt_search_result {
|
||||
TDB_DATA key;
|
||||
TDB_DATA val;
|
||||
@@ -414,13 +414,8 @@ static int db_rbt_traverse_internal(struct db_context *db,
|
||||
ZERO_STRUCT(rec);
|
||||
rec.db = db;
|
||||
rec.private_data = &rec_priv;
|
||||
- if (rw) {
|
||||
- rec.store = db_rbt_store;
|
||||
- rec.delete_rec = db_rbt_delete;
|
||||
- } else {
|
||||
- rec.store = db_rbt_store_deny;
|
||||
- rec.delete_rec = db_rbt_delete_deny;
|
||||
- }
|
||||
+ rec.store = db_rbt_store;
|
||||
+ rec.delete_rec = db_rbt_delete;
|
||||
db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
|
||||
ret = f(&rec, private_data);
|
||||
@@ -440,18 +435,21 @@ static int db_rbt_traverse_internal(struct db_context *db,
|
||||
return db_rbt_traverse_internal(db, rb_right, f, private_data, count, rw);
|
||||
}
|
||||
|
||||
-static int db_rbt_traverse(struct db_context *db,
|
||||
- int (*f)(struct db_record *db,
|
||||
- void *private_data),
|
||||
- void *private_data)
|
||||
+static int db_rbt_traverse_read(struct db_context *db,
|
||||
+ int (*f)(struct db_record *db,
|
||||
+ void *private_data),
|
||||
+ void *private_data)
|
||||
{
|
||||
struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
db->private_data, struct db_rbt_ctx);
|
||||
uint32_t count = 0;
|
||||
+ int ret;
|
||||
|
||||
- int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
- f, private_data, &count,
|
||||
- true /* rw */);
|
||||
+ ctx->traverse_read++;
|
||||
+ ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ f, private_data, &count,
|
||||
+ false /* rw */);
|
||||
+ ctx->traverse_read--;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -461,18 +459,29 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
return count;
|
||||
}
|
||||
|
||||
-static int db_rbt_traverse_read(struct db_context *db,
|
||||
- int (*f)(struct db_record *db,
|
||||
- void *private_data),
|
||||
- void *private_data)
|
||||
+static int db_rbt_traverse(struct db_context *db,
|
||||
+ int (*f)(struct db_record *db,
|
||||
+ void *private_data),
|
||||
+ void *private_data)
|
||||
{
|
||||
struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
db->private_data, struct db_rbt_ctx);
|
||||
uint32_t count = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (ctx->traverse_write) {
|
||||
+ return -1;
|
||||
+ };
|
||||
+
|
||||
+ if (ctx->traverse_read > 0) {
|
||||
+ return db_rbt_traverse_read(db, f, private_data);
|
||||
+ }
|
||||
|
||||
- int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
- f, private_data, &count,
|
||||
- false /* rw */);
|
||||
+ ctx->traverse_write = true;
|
||||
+ ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ f, private_data, &count,
|
||||
+ true /* rw */);
|
||||
+ ctx->traverse_write = false;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From fd6bcd4cb3752554dd1041f0a41fd7e9edac602d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 09:22:08 +0100
|
||||
Subject: [PATCH 4/5] dbwrap_rbt: fix modifying the db during traverse
|
||||
|
||||
We delete and add of records rebalace the tree, but our
|
||||
traverse code doesn't handle that and skips records
|
||||
randomly.
|
||||
|
||||
We maintain records in a linked list for now
|
||||
in addition to the rbtree and use that list during
|
||||
traverse.
|
||||
|
||||
This add a bit overhead, but at least it works reliable.
|
||||
If someone finds a way to do reliable traverse with the
|
||||
rebalanced tree, we can replace this commit.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit 0f46da08e160e6712e5282af14e1ec4012614fc7)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 104 ++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 57 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index d4cb40d..a9cc641 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -22,13 +22,15 @@
|
||||
#include "dbwrap/dbwrap_private.h"
|
||||
#include "dbwrap/dbwrap_rbt.h"
|
||||
#include "../lib/util/rbtree.h"
|
||||
+#include "../lib/util/dlinklist.h"
|
||||
|
||||
#define DBWRAP_RBT_ALIGN(_size_) (((_size_)+15)&~15)
|
||||
|
||||
struct db_rbt_ctx {
|
||||
struct rb_root tree;
|
||||
+ struct db_rbt_node *nodes;
|
||||
size_t traverse_read;
|
||||
- bool traverse_write;
|
||||
+ struct db_rbt_node **traverse_nextp;
|
||||
};
|
||||
|
||||
struct db_rbt_rec {
|
||||
@@ -40,6 +42,7 @@ struct db_rbt_rec {
|
||||
struct db_rbt_node {
|
||||
struct rb_node rb_node;
|
||||
size_t keysize, valuesize;
|
||||
+ struct db_rbt_node *prev, *next;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -123,7 +126,8 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
struct db_rbt_node *node;
|
||||
|
||||
struct rb_node ** p;
|
||||
- struct rb_node * parent;
|
||||
+ struct rb_node *parent = NULL;
|
||||
+ struct db_rbt_node *parent_node = NULL;
|
||||
|
||||
ssize_t reclen;
|
||||
TDB_DATA this_key, this_val;
|
||||
@@ -165,12 +169,19 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
}
|
||||
|
||||
if (rec_priv->node != NULL) {
|
||||
+ if (db_ctx->traverse_nextp != NULL) {
|
||||
+ if (*db_ctx->traverse_nextp == rec_priv->node) {
|
||||
+ *db_ctx->traverse_nextp = node;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* We need to delete the key from the tree and start fresh,
|
||||
* there's not enough space in the existing record
|
||||
*/
|
||||
|
||||
rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
|
||||
+ DLIST_REMOVE(db_ctx->nodes, rec_priv->node);
|
||||
|
||||
/*
|
||||
* Keep the existing node around for a while: If the record
|
||||
@@ -197,10 +208,11 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
TDB_DATA search_key, search_val;
|
||||
int res;
|
||||
|
||||
- parent = (*p);
|
||||
-
|
||||
r = db_rbt2node(*p);
|
||||
|
||||
+ parent = (*p);
|
||||
+ parent_node = r;
|
||||
+
|
||||
db_rbt_parse_node(r, &search_key, &search_val);
|
||||
|
||||
res = db_rbt_compare(this_key, search_key);
|
||||
@@ -217,6 +229,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
}
|
||||
|
||||
rb_link_node(&node->rb_node, parent, p);
|
||||
+ DLIST_ADD_AFTER(db_ctx->nodes, node, parent_node);
|
||||
rb_insert_color(&node->rb_node, &db_ctx->tree);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@@ -236,7 +249,14 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
+ if (db_ctx->traverse_nextp != NULL) {
|
||||
+ if (*db_ctx->traverse_nextp == rec_priv->node) {
|
||||
+ *db_ctx->traverse_nextp = rec_priv->node->next;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
|
||||
+ DLIST_REMOVE(db_ctx->nodes, rec_priv->node);
|
||||
TALLOC_FREE(rec_priv->node);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@@ -383,56 +403,48 @@ static NTSTATUS db_rbt_parse_record(struct db_context *db, TDB_DATA key,
|
||||
}
|
||||
|
||||
static int db_rbt_traverse_internal(struct db_context *db,
|
||||
- struct rb_node *n,
|
||||
int (*f)(struct db_record *db,
|
||||
void *private_data),
|
||||
void *private_data, uint32_t* count,
|
||||
bool rw)
|
||||
{
|
||||
- struct rb_node *rb_right;
|
||||
- struct rb_node *rb_left;
|
||||
- struct db_record rec;
|
||||
- struct db_rbt_rec rec_priv;
|
||||
+ struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
+ db->private_data, struct db_rbt_ctx);
|
||||
+ struct db_rbt_node *cur = NULL;
|
||||
+ struct db_rbt_node *next = NULL;
|
||||
int ret;
|
||||
|
||||
- if (n == NULL) {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- rb_left = n->rb_left;
|
||||
- rb_right = n->rb_right;
|
||||
+ for (cur = ctx->nodes; cur != NULL; cur = next) {
|
||||
+ struct db_record rec;
|
||||
+ struct db_rbt_rec rec_priv;
|
||||
|
||||
- ret = db_rbt_traverse_internal(db, rb_left, f, private_data, count, rw);
|
||||
- if (ret != 0) {
|
||||
- return ret;
|
||||
- }
|
||||
+ rec_priv.node = cur;
|
||||
+ next = rec_priv.node->next;
|
||||
|
||||
- rec_priv.node = db_rbt2node(n);
|
||||
- /* n might be altered by the callback function */
|
||||
- n = NULL;
|
||||
+ ZERO_STRUCT(rec);
|
||||
+ rec.db = db;
|
||||
+ rec.private_data = &rec_priv;
|
||||
+ rec.store = db_rbt_store;
|
||||
+ rec.delete_rec = db_rbt_delete;
|
||||
+ db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
|
||||
- ZERO_STRUCT(rec);
|
||||
- rec.db = db;
|
||||
- rec.private_data = &rec_priv;
|
||||
- rec.store = db_rbt_store;
|
||||
- rec.delete_rec = db_rbt_delete;
|
||||
- db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
-
|
||||
- ret = f(&rec, private_data);
|
||||
- (*count) ++;
|
||||
- if (ret != 0) {
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (rec_priv.node != NULL) {
|
||||
- /*
|
||||
- * If the current record is still there
|
||||
- * we should take the current rb_right.
|
||||
- */
|
||||
- rb_right = rec_priv.node->rb_node.rb_right;
|
||||
+ if (rw) {
|
||||
+ ctx->traverse_nextp = &next;
|
||||
+ }
|
||||
+ ret = f(&rec, private_data);
|
||||
+ (*count) ++;
|
||||
+ if (rw) {
|
||||
+ ctx->traverse_nextp = NULL;
|
||||
+ }
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (rec_priv.node != NULL) {
|
||||
+ next = rec_priv.node->next;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return db_rbt_traverse_internal(db, rb_right, f, private_data, count, rw);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int db_rbt_traverse_read(struct db_context *db,
|
||||
@@ -446,7 +458,7 @@ static int db_rbt_traverse_read(struct db_context *db,
|
||||
int ret;
|
||||
|
||||
ctx->traverse_read++;
|
||||
- ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ ret = db_rbt_traverse_internal(db,
|
||||
f, private_data, &count,
|
||||
false /* rw */);
|
||||
ctx->traverse_read--;
|
||||
@@ -469,7 +481,7 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
uint32_t count = 0;
|
||||
int ret;
|
||||
|
||||
- if (ctx->traverse_write) {
|
||||
+ if (ctx->traverse_nextp != NULL) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
@@ -477,11 +489,9 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
return db_rbt_traverse_read(db, f, private_data);
|
||||
}
|
||||
|
||||
- ctx->traverse_write = true;
|
||||
- ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ ret = db_rbt_traverse_internal(db,
|
||||
f, private_data, &count,
|
||||
true /* rw */);
|
||||
- ctx->traverse_write = false;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From 5b555ac802ce714c26411b48a375d1cc6699b22c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 00:13:17 +0100
|
||||
Subject: [PATCH 5/5] s3:torture: add traverse testing to LOCAL-RBTREE
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
|
||||
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
|
||||
Autobuild-Date(master): Fri Nov 27 13:16:59 CET 2015 on sn-devel-104
|
||||
|
||||
(cherry picked from commit bb9f13ab4165f150e01a88ddcc51605a7c176f5d)
|
||||
---
|
||||
source3/torture/torture.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
|
||||
index 594d28f..0b37e5c 100644
|
||||
--- a/source3/torture/torture.c
|
||||
+++ b/source3/torture/torture.c
|
||||
@@ -8352,11 +8352,29 @@ static bool rbt_testval(struct db_context *db, const char *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
|
||||
+{
|
||||
+ int *count2 = (int *)private_data;
|
||||
+ (*count2)++;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
|
||||
+{
|
||||
+ int *count2 = (int *)private_data;
|
||||
+ (*count2)++;
|
||||
+ dbwrap_record_delete(rec);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool run_local_rbtree(int dummy)
|
||||
{
|
||||
struct db_context *db;
|
||||
bool ret = false;
|
||||
int i;
|
||||
+ NTSTATUS status;
|
||||
+ int count = 0;
|
||||
+ int count2 = 0;
|
||||
|
||||
db = db_open_rbt(NULL);
|
||||
|
||||
@@ -8399,6 +8417,27 @@ static bool run_local_rbtree(int dummy)
|
||||
}
|
||||
|
||||
ret = true;
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 1000)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse(db, local_rbtree_traverse_delete,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 1000)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 0)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
|
||||
done:
|
||||
TALLOC_FREE(db);
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1,4 +1,3 @@
|
||||
bin/async_connect_send_test
|
||||
bin/cifsdd
|
||||
bin/dbwrap_tool
|
||||
bin/eventlogadm
|
||||
@ -672,6 +671,7 @@ lib/shared-modules/vfs/zfsacl.so
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/bare.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/dnsserver.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/misc.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/raw_protocol.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/registry.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/rpc_talloc.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/rpcecho.py
|
||||
@ -683,7 +683,7 @@ lib/shared-modules/vfs/zfsacl.so
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/docs.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dsdb.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/gensec.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/getopt.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/get_opt.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/hostconfig.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/libsmb_samba_internal.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/messaging.py
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
PORTNAME?= ${SAMBA4_BASENAME}43
|
||||
PORTVERSION?= ${SAMBA4_VERSION}
|
||||
PORTREVISION?= 2
|
||||
PORTREVISION?= 0
|
||||
CATEGORIES?= net
|
||||
MASTER_SITES= SAMBA/samba/stable SAMBA/samba/rc
|
||||
DISTNAME= ${SAMBA4_DISTNAME}
|
||||
@ -15,11 +15,11 @@ LICENSE= GPLv3
|
||||
|
||||
CONFLICTS?= *samba3[2-6]-3.* samba4-4.0.* samba41-4.1.* samba42-4.2.*
|
||||
|
||||
EXTRA_PATCHES= ${PATCHDIR}/extra-patch-security:-p1
|
||||
EXTRA_PATCHES= ${PATCHDIR}/extra-patch-progress:-p1
|
||||
|
||||
SAMBA4_BASENAME= samba
|
||||
SAMBA4_PORTNAME= ${SAMBA4_BASENAME}4
|
||||
SAMBA4_VERSION= 4.3.3
|
||||
SAMBA4_VERSION= 4.3.8
|
||||
SAMBA4_DISTNAME= ${SAMBA4_BASENAME}-${SAMBA4_VERSION:S|.p|pre|:S|.r|rc|:S|.t|tp|:S|.a|alpha|}
|
||||
|
||||
WRKSRC?= ${WRKDIR}/${DISTNAME}
|
||||
@ -430,7 +430,7 @@ SAMBA_MAN7+= samba.7 winbind_krb5_locator.7
|
||||
SAMBA_MAN8+= eventlogadm.8 idmap_ad.8 idmap_autorid.8 idmap_hash.8 \
|
||||
idmap_ldap.8 idmap_nss.8 idmap_rfc2307.8 idmap_rid.8 \
|
||||
idmap_tdb.8 idmap_tdb2.8 net.8 nmbd.8 pam_winbind.8 pdbedit.8 \
|
||||
samba-regedit.8 samba-tool.8 samba.8 smbd.8 smbpasswd.8 \
|
||||
samba-regedit.8 samba-tool.8 samba.8 smbd.8 smbpasswd.8 smbspool_krb5_wrapper.8 \
|
||||
smbspool.8 smbta-util.8 vfs_acl_tdb.8 vfs_acl_xattr.8 \
|
||||
vfs_aio_fork.8 vfs_aio_linux.8 vfs_aio_pthread.8 \
|
||||
vfs_audit.8 vfs_cacheprime.8 vfs_cap.8 vfs_catia.8 vfs_ceph.8 \
|
||||
|
@ -1,2 +1,2 @@
|
||||
SHA256 (samba-4.3.3.tar.gz) = e62d21313acbb29e24b0b80aaf2b63fdd1ccce4cfb741f333deca95a1a3a70df
|
||||
SIZE (samba-4.3.3.tar.gz) = 20427281
|
||||
SHA256 (samba-4.3.8.tar.gz) = 379dc66c3a0a483bf5bed37be6e5d182934db7c4102b21929a6c4602b32b2b10
|
||||
SIZE (samba-4.3.8.tar.gz) = 20568773
|
||||
|
31
net/samba43/files/extra-patch-progress
Normal file
31
net/samba43/files/extra-patch-progress
Normal file
@ -0,0 +1,31 @@
|
||||
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
|
||||
index c65fb08..13713fc 100644
|
||||
--- a/source3/passdb/pdb_ldap.c
|
||||
+++ b/source3/passdb/pdb_ldap.c
|
||||
@@ -1005,7 +1005,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
|
||||
entry,
|
||||
"gecos",
|
||||
ctx);
|
||||
- if (unix_pw.pw_gecos) {
|
||||
+ if (unix_pw.pw_gecos==NULL) {
|
||||
unix_pw.pw_gecos = fullname;
|
||||
}
|
||||
unix_pw.pw_dir = smbldap_talloc_single_attribute(
|
||||
@@ -1013,7 +1013,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
|
||||
entry,
|
||||
"homeDirectory",
|
||||
ctx);
|
||||
- if (unix_pw.pw_dir) {
|
||||
+ if (unix_pw.pw_dir==NULL) {
|
||||
unix_pw.pw_dir = discard_const_p(char, "");
|
||||
}
|
||||
unix_pw.pw_shell = smbldap_talloc_single_attribute(
|
||||
@@ -1021,7 +1021,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
|
||||
entry,
|
||||
"loginShell",
|
||||
ctx);
|
||||
- if (unix_pw.pw_shell) {
|
||||
+ if (unix_pw.pw_shell==NULL) {
|
||||
unix_pw.pw_shell = discard_const_p(char, "");
|
||||
}
|
||||
|
@ -1,534 +0,0 @@
|
||||
From a4e75bba5d2b799c11aac9eb1c345b8e58563089 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 10:17:34 +0100
|
||||
Subject: [PATCH 1/4] dbwrap_rbt: use talloc_zero_size() instead of a partial
|
||||
ZERO_STRUCT()
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit f3d1fc1d06822a951a2a3eeb5aa53748b9b5b299)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index 03f2f57..2d65647 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -153,7 +153,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
return NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
- node = talloc_size(db_ctx, reclen);
|
||||
+ node = talloc_zero_size(db_ctx, reclen);
|
||||
if (node == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@@ -172,8 +172,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
*/
|
||||
}
|
||||
|
||||
- ZERO_STRUCT(node->rb_node);
|
||||
-
|
||||
node->keysize = rec->key.dsize;
|
||||
node->valuesize = data.dsize;
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From 3f448c47a8567b0e4794e787399202f050002819 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 09:22:08 +0100
|
||||
Subject: [PATCH 2/4] dbwrap_rbt: add nested traverse protection
|
||||
|
||||
Multiple dbwrap_traverse_read() calls are possible.
|
||||
|
||||
store() and delete() on a fetch locked record
|
||||
are rejected during dbwrap_traverse_read().
|
||||
|
||||
A dbwrap_traverse() within a dbwrap_traverse_read()
|
||||
behaves like a dbwrap_traverse_read().
|
||||
|
||||
Nested dbwrap_traverse() calls are not possible.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit 590507951fc514a679f44b8bfdd03c721189c3fa)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 71 ++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 40 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index 2d65647..d4cb40d 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
struct db_rbt_ctx {
|
||||
struct rb_root tree;
|
||||
+ size_t traverse_read;
|
||||
+ bool traverse_write;
|
||||
};
|
||||
|
||||
struct db_rbt_rec {
|
||||
@@ -126,6 +128,10 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
ssize_t reclen;
|
||||
TDB_DATA this_key, this_val;
|
||||
|
||||
+ if (db_ctx->traverse_read > 0) {
|
||||
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
+ }
|
||||
+
|
||||
if (rec_priv->node != NULL) {
|
||||
|
||||
/*
|
||||
@@ -222,6 +228,10 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
rec->db->private_data, struct db_rbt_ctx);
|
||||
struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
|
||||
|
||||
+ if (db_ctx->traverse_read > 0) {
|
||||
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
+ }
|
||||
+
|
||||
if (rec_priv->node == NULL) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -232,16 +242,6 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
-static NTSTATUS db_rbt_store_deny(struct db_record *rec, TDB_DATA data, int flag)
|
||||
-{
|
||||
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS db_rbt_delete_deny(struct db_record *rec)
|
||||
-{
|
||||
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
-}
|
||||
-
|
||||
struct db_rbt_search_result {
|
||||
TDB_DATA key;
|
||||
TDB_DATA val;
|
||||
@@ -414,13 +414,8 @@ static int db_rbt_traverse_internal(struct db_context *db,
|
||||
ZERO_STRUCT(rec);
|
||||
rec.db = db;
|
||||
rec.private_data = &rec_priv;
|
||||
- if (rw) {
|
||||
- rec.store = db_rbt_store;
|
||||
- rec.delete_rec = db_rbt_delete;
|
||||
- } else {
|
||||
- rec.store = db_rbt_store_deny;
|
||||
- rec.delete_rec = db_rbt_delete_deny;
|
||||
- }
|
||||
+ rec.store = db_rbt_store;
|
||||
+ rec.delete_rec = db_rbt_delete;
|
||||
db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
|
||||
ret = f(&rec, private_data);
|
||||
@@ -440,18 +435,21 @@ static int db_rbt_traverse_internal(struct db_context *db,
|
||||
return db_rbt_traverse_internal(db, rb_right, f, private_data, count, rw);
|
||||
}
|
||||
|
||||
-static int db_rbt_traverse(struct db_context *db,
|
||||
- int (*f)(struct db_record *db,
|
||||
- void *private_data),
|
||||
- void *private_data)
|
||||
+static int db_rbt_traverse_read(struct db_context *db,
|
||||
+ int (*f)(struct db_record *db,
|
||||
+ void *private_data),
|
||||
+ void *private_data)
|
||||
{
|
||||
struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
db->private_data, struct db_rbt_ctx);
|
||||
uint32_t count = 0;
|
||||
+ int ret;
|
||||
|
||||
- int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
- f, private_data, &count,
|
||||
- true /* rw */);
|
||||
+ ctx->traverse_read++;
|
||||
+ ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ f, private_data, &count,
|
||||
+ false /* rw */);
|
||||
+ ctx->traverse_read--;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -461,18 +459,29 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
return count;
|
||||
}
|
||||
|
||||
-static int db_rbt_traverse_read(struct db_context *db,
|
||||
- int (*f)(struct db_record *db,
|
||||
- void *private_data),
|
||||
- void *private_data)
|
||||
+static int db_rbt_traverse(struct db_context *db,
|
||||
+ int (*f)(struct db_record *db,
|
||||
+ void *private_data),
|
||||
+ void *private_data)
|
||||
{
|
||||
struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
db->private_data, struct db_rbt_ctx);
|
||||
uint32_t count = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (ctx->traverse_write) {
|
||||
+ return -1;
|
||||
+ };
|
||||
+
|
||||
+ if (ctx->traverse_read > 0) {
|
||||
+ return db_rbt_traverse_read(db, f, private_data);
|
||||
+ }
|
||||
|
||||
- int ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
- f, private_data, &count,
|
||||
- false /* rw */);
|
||||
+ ctx->traverse_write = true;
|
||||
+ ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ f, private_data, &count,
|
||||
+ true /* rw */);
|
||||
+ ctx->traverse_write = false;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From a2e7deb101d4aee633015fdd22df6255ee03c00e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 09:22:08 +0100
|
||||
Subject: [PATCH 3/4] dbwrap_rbt: fix modifying the db during traverse
|
||||
|
||||
We delete and add of records rebalace the tree, but our
|
||||
traverse code doesn't handle that and skips records
|
||||
randomly.
|
||||
|
||||
We maintain records in a linked list for now
|
||||
in addition to the rbtree and use that list during
|
||||
traverse.
|
||||
|
||||
This add a bit overhead, but at least it works reliable.
|
||||
If someone finds a way to do reliable traverse with the
|
||||
rebalanced tree, we can replace this commit.
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
(cherry picked from commit 0f46da08e160e6712e5282af14e1ec4012614fc7)
|
||||
---
|
||||
lib/dbwrap/dbwrap_rbt.c | 104 ++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 57 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
|
||||
index d4cb40d..a9cc641 100644
|
||||
--- a/lib/dbwrap/dbwrap_rbt.c
|
||||
+++ b/lib/dbwrap/dbwrap_rbt.c
|
||||
@@ -22,13 +22,15 @@
|
||||
#include "dbwrap/dbwrap_private.h"
|
||||
#include "dbwrap/dbwrap_rbt.h"
|
||||
#include "../lib/util/rbtree.h"
|
||||
+#include "../lib/util/dlinklist.h"
|
||||
|
||||
#define DBWRAP_RBT_ALIGN(_size_) (((_size_)+15)&~15)
|
||||
|
||||
struct db_rbt_ctx {
|
||||
struct rb_root tree;
|
||||
+ struct db_rbt_node *nodes;
|
||||
size_t traverse_read;
|
||||
- bool traverse_write;
|
||||
+ struct db_rbt_node **traverse_nextp;
|
||||
};
|
||||
|
||||
struct db_rbt_rec {
|
||||
@@ -40,6 +42,7 @@ struct db_rbt_rec {
|
||||
struct db_rbt_node {
|
||||
struct rb_node rb_node;
|
||||
size_t keysize, valuesize;
|
||||
+ struct db_rbt_node *prev, *next;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -123,7 +126,8 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
struct db_rbt_node *node;
|
||||
|
||||
struct rb_node ** p;
|
||||
- struct rb_node * parent;
|
||||
+ struct rb_node *parent = NULL;
|
||||
+ struct db_rbt_node *parent_node = NULL;
|
||||
|
||||
ssize_t reclen;
|
||||
TDB_DATA this_key, this_val;
|
||||
@@ -165,12 +169,19 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
}
|
||||
|
||||
if (rec_priv->node != NULL) {
|
||||
+ if (db_ctx->traverse_nextp != NULL) {
|
||||
+ if (*db_ctx->traverse_nextp == rec_priv->node) {
|
||||
+ *db_ctx->traverse_nextp = node;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* We need to delete the key from the tree and start fresh,
|
||||
* there's not enough space in the existing record
|
||||
*/
|
||||
|
||||
rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
|
||||
+ DLIST_REMOVE(db_ctx->nodes, rec_priv->node);
|
||||
|
||||
/*
|
||||
* Keep the existing node around for a while: If the record
|
||||
@@ -197,10 +208,11 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
TDB_DATA search_key, search_val;
|
||||
int res;
|
||||
|
||||
- parent = (*p);
|
||||
-
|
||||
r = db_rbt2node(*p);
|
||||
|
||||
+ parent = (*p);
|
||||
+ parent_node = r;
|
||||
+
|
||||
db_rbt_parse_node(r, &search_key, &search_val);
|
||||
|
||||
res = db_rbt_compare(this_key, search_key);
|
||||
@@ -217,6 +229,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
|
||||
}
|
||||
|
||||
rb_link_node(&node->rb_node, parent, p);
|
||||
+ DLIST_ADD_AFTER(db_ctx->nodes, node, parent_node);
|
||||
rb_insert_color(&node->rb_node, &db_ctx->tree);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@@ -236,7 +249,14 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
+ if (db_ctx->traverse_nextp != NULL) {
|
||||
+ if (*db_ctx->traverse_nextp == rec_priv->node) {
|
||||
+ *db_ctx->traverse_nextp = rec_priv->node->next;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
rb_erase(&rec_priv->node->rb_node, &db_ctx->tree);
|
||||
+ DLIST_REMOVE(db_ctx->nodes, rec_priv->node);
|
||||
TALLOC_FREE(rec_priv->node);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@@ -383,56 +403,48 @@ static NTSTATUS db_rbt_parse_record(struct db_context *db, TDB_DATA key,
|
||||
}
|
||||
|
||||
static int db_rbt_traverse_internal(struct db_context *db,
|
||||
- struct rb_node *n,
|
||||
int (*f)(struct db_record *db,
|
||||
void *private_data),
|
||||
void *private_data, uint32_t* count,
|
||||
bool rw)
|
||||
{
|
||||
- struct rb_node *rb_right;
|
||||
- struct rb_node *rb_left;
|
||||
- struct db_record rec;
|
||||
- struct db_rbt_rec rec_priv;
|
||||
+ struct db_rbt_ctx *ctx = talloc_get_type_abort(
|
||||
+ db->private_data, struct db_rbt_ctx);
|
||||
+ struct db_rbt_node *cur = NULL;
|
||||
+ struct db_rbt_node *next = NULL;
|
||||
int ret;
|
||||
|
||||
- if (n == NULL) {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- rb_left = n->rb_left;
|
||||
- rb_right = n->rb_right;
|
||||
+ for (cur = ctx->nodes; cur != NULL; cur = next) {
|
||||
+ struct db_record rec;
|
||||
+ struct db_rbt_rec rec_priv;
|
||||
|
||||
- ret = db_rbt_traverse_internal(db, rb_left, f, private_data, count, rw);
|
||||
- if (ret != 0) {
|
||||
- return ret;
|
||||
- }
|
||||
+ rec_priv.node = cur;
|
||||
+ next = rec_priv.node->next;
|
||||
|
||||
- rec_priv.node = db_rbt2node(n);
|
||||
- /* n might be altered by the callback function */
|
||||
- n = NULL;
|
||||
+ ZERO_STRUCT(rec);
|
||||
+ rec.db = db;
|
||||
+ rec.private_data = &rec_priv;
|
||||
+ rec.store = db_rbt_store;
|
||||
+ rec.delete_rec = db_rbt_delete;
|
||||
+ db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
|
||||
- ZERO_STRUCT(rec);
|
||||
- rec.db = db;
|
||||
- rec.private_data = &rec_priv;
|
||||
- rec.store = db_rbt_store;
|
||||
- rec.delete_rec = db_rbt_delete;
|
||||
- db_rbt_parse_node(rec_priv.node, &rec.key, &rec.value);
|
||||
-
|
||||
- ret = f(&rec, private_data);
|
||||
- (*count) ++;
|
||||
- if (ret != 0) {
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (rec_priv.node != NULL) {
|
||||
- /*
|
||||
- * If the current record is still there
|
||||
- * we should take the current rb_right.
|
||||
- */
|
||||
- rb_right = rec_priv.node->rb_node.rb_right;
|
||||
+ if (rw) {
|
||||
+ ctx->traverse_nextp = &next;
|
||||
+ }
|
||||
+ ret = f(&rec, private_data);
|
||||
+ (*count) ++;
|
||||
+ if (rw) {
|
||||
+ ctx->traverse_nextp = NULL;
|
||||
+ }
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (rec_priv.node != NULL) {
|
||||
+ next = rec_priv.node->next;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return db_rbt_traverse_internal(db, rb_right, f, private_data, count, rw);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int db_rbt_traverse_read(struct db_context *db,
|
||||
@@ -446,7 +458,7 @@ static int db_rbt_traverse_read(struct db_context *db,
|
||||
int ret;
|
||||
|
||||
ctx->traverse_read++;
|
||||
- ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ ret = db_rbt_traverse_internal(db,
|
||||
f, private_data, &count,
|
||||
false /* rw */);
|
||||
ctx->traverse_read--;
|
||||
@@ -469,7 +481,7 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
uint32_t count = 0;
|
||||
int ret;
|
||||
|
||||
- if (ctx->traverse_write) {
|
||||
+ if (ctx->traverse_nextp != NULL) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
@@ -477,11 +489,9 @@ static int db_rbt_traverse(struct db_context *db,
|
||||
return db_rbt_traverse_read(db, f, private_data);
|
||||
}
|
||||
|
||||
- ctx->traverse_write = true;
|
||||
- ret = db_rbt_traverse_internal(db, ctx->tree.rb_node,
|
||||
+ ret = db_rbt_traverse_internal(db,
|
||||
f, private_data, &count,
|
||||
true /* rw */);
|
||||
- ctx->traverse_write = false;
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
1.9.1
|
||||
|
||||
|
||||
From 88752f5f769bae1edf6f395303b9daf9d13131f1 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Metzmacher <metze@samba.org>
|
||||
Date: Wed, 25 Nov 2015 00:13:17 +0100
|
||||
Subject: [PATCH 4/4] s3:torture: add traverse testing to LOCAL-RBTREE
|
||||
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11375
|
||||
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11394
|
||||
|
||||
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||
Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||
|
||||
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
|
||||
Autobuild-Date(master): Fri Nov 27 13:16:59 CET 2015 on sn-devel-104
|
||||
|
||||
(cherry picked from commit bb9f13ab4165f150e01a88ddcc51605a7c176f5d)
|
||||
---
|
||||
source3/torture/torture.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
|
||||
index 7bb776f..505920f 100644
|
||||
--- a/source3/torture/torture.c
|
||||
+++ b/source3/torture/torture.c
|
||||
@@ -8348,11 +8348,29 @@ static bool rbt_testval(struct db_context *db, const char *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
|
||||
+{
|
||||
+ int *count2 = (int *)private_data;
|
||||
+ (*count2)++;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
|
||||
+{
|
||||
+ int *count2 = (int *)private_data;
|
||||
+ (*count2)++;
|
||||
+ dbwrap_record_delete(rec);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool run_local_rbtree(int dummy)
|
||||
{
|
||||
struct db_context *db;
|
||||
bool ret = false;
|
||||
int i;
|
||||
+ NTSTATUS status;
|
||||
+ int count = 0;
|
||||
+ int count2 = 0;
|
||||
|
||||
db = db_open_rbt(NULL);
|
||||
|
||||
@@ -8395,6 +8413,27 @@ static bool run_local_rbtree(int dummy)
|
||||
}
|
||||
|
||||
ret = true;
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 1000)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse(db, local_rbtree_traverse_delete,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 1000)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
+ count = 0; count2 = 0;
|
||||
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
|
||||
+ &count2, &count);
|
||||
+ printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
|
||||
+ if ((count != count2) || (count != 0)) {
|
||||
+ ret = false;
|
||||
+ }
|
||||
|
||||
done:
|
||||
TALLOC_FREE(db);
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1,4 +1,3 @@
|
||||
bin/async_connect_send_test
|
||||
bin/cifsdd
|
||||
bin/dbwrap_tool
|
||||
bin/eventlogadm
|
||||
@ -625,6 +624,7 @@ lib/shared-modules/vfs/zfsacl.so
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/dnsserver.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/integer.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/misc.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/raw_protocol.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/registry.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/rpc_talloc.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dcerpc/rpcecho.py
|
||||
@ -636,7 +636,7 @@ lib/shared-modules/vfs/zfsacl.so
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/docs.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/dsdb.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/gensec.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/getopt.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/get_opt.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/hostconfig.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/kcc/__init__.py
|
||||
%%PYTHON_SITELIBDIR%%/samba/tests/kcc/graph.py
|
||||
@ -839,8 +839,9 @@ man/man8/samba-tool.8.gz
|
||||
man/man8/samba.8.gz
|
||||
man/man8/smbd.8.gz
|
||||
man/man8/smbpasswd.8.gz
|
||||
man/man8/smbspool.8.gz
|
||||
man/man8/smbta-util.8.gz
|
||||
man/man8/smbspool_krb5_wrapper.8.gz
|
||||
man/man8/smbspool.8.gz
|
||||
man/man8/vfs_acl_tdb.8.gz
|
||||
man/man8/vfs_acl_xattr.8.gz
|
||||
man/man8/vfs_aio_fork.8.gz
|
||||
|
Loading…
Reference in New Issue
Block a user