r11877: - give winsdb_add/modify/delete() ldb_context as first argument
authorStefan Metzmacher <metze@samba.org>
Wed, 23 Nov 2005 11:34:46 +0000 (11:34 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:39 +0000 (13:46 -0500)
  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

source/nbt_server/wins/winsdb.c
source/nbt_server/wins/winsdb.h
source/nbt_server/wins/winsserver.c
source/nbt_server/wins/winswack.c

index c734c5b51ec5f9d8c50dd64bbaa2cda13af82d08..94e47b00b1a805656b5298cd6ddcdcc758a98908 100644 (file)
 /*
   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;
 }
index d93d50bdf7674f0066bd4ec18de82450fab6b888..8661baa3dc5848ebf5dc5533d0b5859c3dad26ea 100644 (file)
@@ -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;
index 8a42e0a589a3dfb3c81856191212bf381078dba4..19b9c6c47ff50955a33e75cf6fb528730ec46cd7 100644 (file)
@@ -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:
index 64336992f6d870aa6772b0a98a3c73b5f3c50582..e8c5dd6780b05ff47ab775ae9a9854272edb8c2a 100644 (file)
@@ -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));