summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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));