diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-02-16 15:19:49 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:10:44 -0500 |
commit | 12d4b8a95131695724ad3b20c5384a5b2f76f583 (patch) | |
tree | 020eaec246feface50ae95fa48fb38d248aa9477 /source4/nbt_server/winsdb.c | |
parent | a0667e11ae2c92850919a1568ca47fa83d29af6f (diff) | |
download | samba-12d4b8a95131695724ad3b20c5384a5b2f76f583.tar.gz samba-12d4b8a95131695724ad3b20c5384a5b2f76f583.tar.bz2 samba-12d4b8a95131695724ad3b20c5384a5b2f76f583.zip |
r5418: - added version numbers to WINS database records in preparation for adding server side
replication support
- on a WACK registration success, check that the database record
hasn't changed during the WACK processing. If it has, then fail
the registration
(This used to be commit 2acd79b95931b57efae9f7c239bc08dc143f5225)
Diffstat (limited to 'source4/nbt_server/winsdb.c')
-rw-r--r-- | source4/nbt_server/winsdb.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/source4/nbt_server/winsdb.c b/source4/nbt_server/winsdb.c index 4eff12901f..66e84c668b 100644 --- a/source4/nbt_server/winsdb.c +++ b/source4/nbt_server/winsdb.c @@ -28,6 +28,62 @@ #include "system/time.h" /* + save the min/max version IDs for the database +*/ +static BOOL winsdb_save_version(struct wins_server *winssrv) +{ + int i, ret = 0; + struct ldb_context *ldb = winssrv->wins_db->ldb; + struct ldb_message *msg = ldb_msg_new(winssrv); + if (msg == NULL) goto failed; + + msg->dn = talloc_strdup(msg, "CN=VERSION"); + if (msg->dn == NULL) goto failed; + + ret |= ldb_msg_add_fmt(ldb, msg, "minVersion", "%llu", winssrv->min_version); + ret |= ldb_msg_add_fmt(ldb, msg, "maxVersion", "%llu", winssrv->max_version); + if (ret != 0) goto failed; + + for (i=0;i<msg->num_elements;i++) { + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; + } + + ret = ldb_modify(ldb, msg); + if (ret != 0) ret = ldb_add(ldb, msg); + if (ret != 0) goto failed; + + talloc_free(msg); + return True; + +failed: + talloc_free(msg); + return False; +} + +/* + allocate a new version id for a record +*/ +static uint64_t winsdb_allocate_version(struct wins_server *winssrv) +{ + winssrv->max_version++; + if (!winsdb_save_version(winssrv)) { + return 0; + } + return winssrv->max_version; +} + +/* + allocate a new version id for a record +*/ +static void winsdb_remove_version(struct wins_server *winssrv, uint64_t version) +{ + if (version == winssrv->min_version) { + winssrv->min_version++; + winsdb_save_version(winssrv); + } +} + +/* load a WINS entry from the database */ struct winsdb_record *winsdb_load(struct wins_server *winssrv, @@ -60,6 +116,7 @@ struct winsdb_record *winsdb_load(struct wins_server *winssrv, rec->nb_flags = ldb_msg_find_int(res[0], "nbFlags", 0); rec->expire_time = ldap_string_to_time(ldb_msg_find_string(res[0], "expires", NULL)); rec->registered_by = ldb_msg_find_string(res[0], "registeredBy", NULL); + rec->version = ldb_msg_find_uint64(res[0], "version", 0); talloc_steal(rec, rec->registered_by); el = ldb_msg_find_element(res[0], "address"); @@ -109,6 +166,7 @@ static struct ldb_message *winsdb_message(struct wins_server *winssrv, ret |= ldb_msg_add_string(ldb, msg, "registeredBy", rec->registered_by); ret |= ldb_msg_add_string(ldb, msg, "expires", ldap_timestring(msg, rec->expire_time)); + ret |= ldb_msg_add_fmt(ldb, msg, "version", "%llu", rec->version); for (i=0;rec->addresses[i];i++) { ret |= ldb_msg_add_string(ldb, msg, "address", rec->addresses[i]); } @@ -130,6 +188,9 @@ uint8_t winsdb_add(struct wins_server *winssrv, struct winsdb_record *rec) TALLOC_CTX *tmp_ctx = talloc_new(winssrv); int ret; + rec->version = winsdb_allocate_version(winssrv); + if (rec->version == 0) goto failed; + msg = winsdb_message(winssrv, rec, tmp_ctx); if (msg == NULL) goto failed; ret = ldb_add(ldb, msg); @@ -155,6 +216,9 @@ uint8_t winsdb_modify(struct wins_server *winssrv, struct winsdb_record *rec) int ret; int i; + rec->version = winsdb_allocate_version(winssrv); + if (rec->version == 0) goto failed; + msg = winsdb_message(winssrv, rec, tmp_ctx); if (msg == NULL) goto failed; @@ -177,14 +241,16 @@ failed: /* delete a WINS record from the database */ -uint8_t winsdb_delete(struct wins_server *winssrv, struct nbt_name *name) +uint8_t winsdb_delete(struct wins_server *winssrv, struct winsdb_record *rec) { struct ldb_context *ldb = winssrv->wins_db->ldb; TALLOC_CTX *tmp_ctx = talloc_new(winssrv); int ret; const char *dn; - dn = talloc_asprintf(tmp_ctx, "NAME=%s", nbt_name_string(tmp_ctx, name)); + winsdb_remove_version(winssrv, rec->version); + + dn = talloc_asprintf(tmp_ctx, "NAME=%s", nbt_name_string(tmp_ctx, rec->name)); if (dn == NULL) goto failed; ret = ldb_delete(ldb, dn); |