summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-11-23 11:34:46 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:46:39 -0500
commit5257693496ea430263958a16b81b6df4043b1797 (patch)
tree1de4294681570d9d251e13e6b05627d326d325da /source4
parent4725c3a83d0ba72a0a764710a9810e49ac18436d (diff)
downloadsamba-5257693496ea430263958a16b81b6df4043b1797.tar.gz
samba-5257693496ea430263958a16b81b6df4043b1797.tar.bz2
samba-5257693496ea430263958a16b81b6df4043b1797.zip
r11877: - give winsdb_add/modify/delete() ldb_context as first argument
and add a flags argument to add and modify,the current flags are: WINSDB_FLAG_ALLOC_VERSION to allocate a new version id for the record WINSDB_FLAG_TAKE_OWNERSHIP to take the become the wins owner of the record - fix handling of records with no addresses, this is valid for MHOMED and SGROUP records when they're not in ACTIVE state metze (This used to be commit 0ffea2a7b898b1807e4cdcfbbeba9bd0c6792231)
Diffstat (limited to 'source4')
-rw-r--r--source4/nbt_server/wins/winsdb.c107
-rw-r--r--source4/nbt_server/wins/winsdb.h3
-rw-r--r--source4/nbt_server/wins/winsserver.c11
-rw-r--r--source4/nbt_server/wins/winswack.c2
4 files changed, 70 insertions, 53 deletions
diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c
index c734c5b51e..94e47b00b1 100644
--- a/source4/nbt_server/wins/winsdb.c
+++ b/source4/nbt_server/wins/winsdb.c
@@ -31,25 +31,24 @@
/*
return the new maxVersion and save it
*/
-static uint64_t winsdb_allocate_version(struct wins_server *winssrv)
+static uint64_t winsdb_allocate_version(struct ldb_context *wins_db)
{
int trans;
int ret;
- struct ldb_context *ldb = winssrv->wins_db;
struct ldb_dn *dn;
struct ldb_result *res = NULL;
struct ldb_message *msg = NULL;
- TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
+ TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
uint64_t maxVersion = 0;
- trans = ldb_transaction_start(ldb);
+ trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
dn = ldb_dn_explode(tmp_ctx, "CN=VERSION");
if (!dn) goto failed;
/* find the record in the WINS database */
- ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
+ ret = ldb_search(wins_db, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
if (ret != LDB_SUCCESS) goto failed;
if (res->count > 1) goto failed;
@@ -75,18 +74,18 @@ static uint64_t winsdb_allocate_version(struct wins_server *winssrv)
ret = ldb_msg_add_fmt(msg, "maxVersion", "%llu", maxVersion);
if (ret != 0) goto failed;
- ret = ldb_modify(ldb, msg);
- if (ret != 0) ret = ldb_add(ldb, msg);
+ ret = ldb_modify(wins_db, msg);
+ if (ret != 0) ret = ldb_add(wins_db, msg);
if (ret != 0) goto failed;
- trans = ldb_transaction_commit(ldb);
+ trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
talloc_free(tmp_ctx);
return maxVersion;
failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
talloc_free(tmp_ctx);
return 0;
}
@@ -422,7 +421,7 @@ NTSTATUS winsdb_record(struct ldb_message *msg, struct nbt_name *name, TALLOC_CT
NTSTATUS status;
struct winsdb_record *rec;
struct ldb_message_element *el;
- uint32_t i;
+ uint32_t i, num_values;
rec = talloc(mem_ctx, struct winsdb_record);
if (rec == NULL) {
@@ -466,25 +465,32 @@ NTSTATUS winsdb_record(struct ldb_message *msg, struct nbt_name *name, TALLOC_CT
}
el = ldb_msg_find_element(msg, "address");
- if (el == NULL) {
- status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto failed;
+ if (el) {
+ num_values = el->num_values;
+ } else {
+ num_values = 0;
}
if (rec->type == WREPL_TYPE_UNIQUE || rec->type == WREPL_TYPE_GROUP) {
- if (el->num_values != 1) {
+ if (num_values != 1) {
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto failed;
+ }
+ }
+ if (rec->state == WREPL_STATE_ACTIVE) {
+ if (num_values < 1) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto failed;
}
}
- rec->addresses = talloc_array(rec, struct winsdb_addr *, el->num_values+1);
+ rec->addresses = talloc_array(rec, struct winsdb_addr *, num_values+1);
if (rec->addresses == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
- for (i=0;i<el->num_values;i++) {
+ for (i=0;i<num_values;i++) {
status = winsdb_addr_decode(rec, &el->values[i], rec->addresses, &rec->addresses[i]);
if (!NT_STATUS_IS_OK(status)) goto failed;
}
@@ -531,8 +537,10 @@ struct ldb_message *winsdb_message(struct ldb_context *ldb,
for (i=0;rec->addresses[i];i++) {
ret |= ldb_msg_add_winsdb_addr(msg, "address", rec->addresses[i]);
}
- ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by);
- if (ret != 0) goto failed;
+ if (rec->registered_by) {
+ ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by);
+ if (ret != 0) goto failed;
+ }
return msg;
failed:
@@ -543,34 +551,37 @@ failed:
/*
save a WINS record into the database
*/
-uint8_t winsdb_add(struct wins_server *winssrv, struct winsdb_record *rec)
+uint8_t winsdb_add(struct ldb_context *wins_db, struct winsdb_record *rec, uint32_t flags)
{
- struct ldb_context *ldb = winssrv->wins_db;
struct ldb_message *msg;
- TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
+ TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
int trans = -1;
int ret = 0;
- trans = ldb_transaction_start(ldb);
+ trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- rec->version = winsdb_allocate_version(winssrv);
- if (rec->version == 0) goto failed;
- rec->wins_owner = WINSDB_OWNER_LOCAL;
+ if (flags & WINSDB_FLAG_ALLOC_VERSION) {
+ rec->version = winsdb_allocate_version(wins_db);
+ if (rec->version == 0) goto failed;
+ }
+ if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {
+ rec->wins_owner = WINSDB_OWNER_LOCAL;
+ }
- msg = winsdb_message(winssrv->wins_db, rec, tmp_ctx);
+ msg = winsdb_message(wins_db, rec, tmp_ctx);
if (msg == NULL) goto failed;
- ret = ldb_add(ldb, msg);
+ ret = ldb_add(wins_db, msg);
if (ret != 0) goto failed;
- trans = ldb_transaction_commit(ldb);
+ trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}
@@ -579,40 +590,43 @@ failed:
/*
modify a WINS record in the database
*/
-uint8_t winsdb_modify(struct wins_server *winssrv, struct winsdb_record *rec)
+uint8_t winsdb_modify(struct ldb_context *wins_db, struct winsdb_record *rec, uint32_t flags)
{
- struct ldb_context *ldb = winssrv->wins_db;
struct ldb_message *msg;
- TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
+ TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
int trans;
int ret;
int i;
- trans = ldb_transaction_start(ldb);
+ trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- rec->version = winsdb_allocate_version(winssrv);
- if (rec->version == 0) goto failed;
- rec->wins_owner = WINSDB_OWNER_LOCAL;
+ if (flags & WINSDB_FLAG_ALLOC_VERSION) {
+ rec->version = winsdb_allocate_version(wins_db);
+ if (rec->version == 0) goto failed;
+ }
+ if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {
+ rec->wins_owner = WINSDB_OWNER_LOCAL;
+ }
- msg = winsdb_message(winssrv->wins_db, rec, tmp_ctx);
+ msg = winsdb_message(wins_db, rec, tmp_ctx);
if (msg == NULL) goto failed;
for (i=0;i<msg->num_elements;i++) {
msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
}
- ret = ldb_modify(ldb, msg);
+ ret = ldb_modify(wins_db, msg);
if (ret != 0) goto failed;
- trans = ldb_transaction_commit(ldb);
+ trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}
@@ -621,31 +635,30 @@ failed:
/*
delete a WINS record from the database
*/
-uint8_t winsdb_delete(struct wins_server *winssrv, struct winsdb_record *rec)
+uint8_t winsdb_delete(struct ldb_context *wins_db, struct winsdb_record *rec)
{
- struct ldb_context *ldb = winssrv->wins_db;
- TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
+ TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
const struct ldb_dn *dn;
int trans;
int ret;
- trans = ldb_transaction_start(ldb);
+ trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
dn = winsdb_dn(tmp_ctx, rec->name);
if (dn == NULL) goto failed;
- ret = ldb_delete(ldb, dn);
+ ret = ldb_delete(wins_db, dn);
if (ret != 0) goto failed;
- trans = ldb_transaction_commit(ldb);
+ trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}
diff --git a/source4/nbt_server/wins/winsdb.h b/source4/nbt_server/wins/winsdb.h
index d93d50bdf7..8661baa3dc 100644
--- a/source4/nbt_server/wins/winsdb.h
+++ b/source4/nbt_server/wins/winsdb.h
@@ -23,6 +23,9 @@
#define WINSDB_OWNER_LOCAL "0.0.0.0"
#define WINSDB_GROUP_ADDRESS "255.255.255.255"
+#define WINSDB_FLAG_ALLOC_VERSION (1<<0)
+#define WINSDB_FLAG_TAKE_OWNERSHIP (1<<1)
+
struct winsdb_addr {
const char *address;
const char *wins_owner;
diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c
index 8a42e0a589..19b9c6c47f 100644
--- a/source4/nbt_server/wins/winsserver.c
+++ b/source4/nbt_server/wins/winsserver.c
@@ -83,7 +83,7 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
rec.is_static = False;
rec.expire_time = time(NULL) + ttl;
rec.version = 0; /* will allocated later */
- rec.wins_owner = WINSDB_OWNER_LOCAL;
+ rec.wins_owner = NULL; /* will be set later */
rec.registered_by = src->addr;
rec.addresses = winsdb_addr_list_make(packet);
if (rec.addresses == NULL) return NBT_RCODE_SVR;
@@ -97,7 +97,7 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
DEBUG(4,("WINS: accepted registration of %s with address %s\n",
nbt_name_string(packet, name), rec.addresses[0]->address));
- return winsdb_add(winssrv, &rec);
+ return winsdb_add(winssrv->wins_db, &rec, WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP);
}
@@ -124,7 +124,7 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock,
DEBUG(5,("WINS: refreshed registration of %s at %s\n",
nbt_name_string(packet, rec->name), address));
- return winsdb_modify(winssrv, rec);
+ return winsdb_modify(winssrv->wins_db, rec, 0);
}
/*
@@ -164,7 +164,8 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
rcode = NBT_RCODE_SVR;
goto done;
} else if (rec->state != WREPL_STATE_ACTIVE) {
- winsdb_delete(winssrv, rec);
+/* TODO: this is not always correct!!!*/
+ winsdb_delete(winssrv->wins_db, rec);
rcode = wins_register_new(nbtsock, packet, src);
goto done;
}
@@ -291,7 +292,7 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
if (rec->addresses[0] == NULL) {
rec->state = WREPL_STATE_RELEASED;
}
- winsdb_modify(winssrv, rec);
+ winsdb_modify(winssrv->wins_db, rec, 0);
}
done:
diff --git a/source4/nbt_server/wins/winswack.c b/source4/nbt_server/wins/winswack.c
index 64336992f6..e8c5dd6780 100644
--- a/source4/nbt_server/wins/winswack.c
+++ b/source4/nbt_server/wins/winswack.c
@@ -82,7 +82,7 @@ static void wins_wack_allow(struct wack_state *state)
rec->registered_by = state->src.addr;
- winsdb_modify(state->winssrv, rec);
+ winsdb_modify(state->winssrv->wins_db, rec, WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP);
DEBUG(4,("WINS: accepted registration of %s with address %s\n",
nbt_name_string(state, rec->name), state->reg_address));