From 5257693496ea430263958a16b81b6df4043b1797 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Nov 2005 11:34:46 +0000 Subject: 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) --- source4/nbt_server/wins/winsdb.c | 107 ++++++++++++++++++++--------------- source4/nbt_server/wins/winsdb.h | 3 + source4/nbt_server/wins/winsserver.c | 11 ++-- source4/nbt_server/wins/winswack.c | 2 +- 4 files changed, 70 insertions(+), 53 deletions(-) (limited to 'source4/nbt_server') 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;inum_values;i++) { + for (i=0;ivalues[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;inum_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)); -- cgit