From 6f0f39cab1e39467bd02ebc04cab24bea5feef33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:50:11 +0000 Subject: r11027: r10319@SERNOX: metze | 2005-09-19 18:31:23 +0200 - store the wins owner on the record and the wins owner and expire time on each address - we use "0.0.0.0" to mark entries which are registered at the local wins server - we use this ldif-format: address: 172.31.9.1;winsOwner:0.0.0.0;expireTime:20050923032337.0Z address: 172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z metze (This used to be commit 752025a0e10bfea646784087b5128841ec127a65) --- source4/nbt_server/wins/winsdb.c | 93 +++++++++++++++++++++++++++++++++--- source4/nbt_server/wins/winsdb.h | 6 +++ source4/nbt_server/wins/winsserver.c | 9 ++-- source4/nbt_server/wins/winswack.c | 9 ++-- 4 files changed, 104 insertions(+), 13 deletions(-) diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index a1af256eb5..ff6dc70226 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -119,25 +119,91 @@ static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct nbt_name *name) return dn; } -static struct winsdb_addr *winsdb_addr_decode(TALLOC_CTX *mem_ctx, struct ldb_val *val) +/* + decode the winsdb_addr("address") attribute: + "172.31.1.1" or + "172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z" + are valid records +*/ +static struct winsdb_addr *winsdb_addr_decode(struct winsdb_record *rec, TALLOC_CTX *mem_ctx, struct ldb_val *val) { struct winsdb_addr *addr; + char *address; + char *wins_owner; + char *expire_time; + char *p; addr = talloc(mem_ctx, struct winsdb_addr); if (!addr) return NULL; - addr->address = talloc_steal(addr, val->data); + address = (char *)val->data; + + p = strchr(address, ';'); + if (!p) { + /* support old entries, with only the address */ + addr->address = talloc_steal(addr, val->data); + addr->wins_owner = rec->wins_owner; + addr->expire_time = rec->expire_time; + return addr; + } + + *p = '\0';p++; + addr->address = talloc_strdup(addr, address); + if (!addr->address) { + talloc_free(addr); + return NULL; + } + + if (strncmp("winsOwner:", p, 10) != 0) { + /* invalid record */ + talloc_free(addr); + return NULL; + } + wins_owner = p + 10; + p = strchr(wins_owner, ';'); + if (!p) { + /* invalid record */ + talloc_free(addr); + return NULL; + } + + *p = '\0';p++; + addr->wins_owner = talloc_strdup(addr, wins_owner); + if (!addr->wins_owner) { + talloc_free(addr); + return NULL; + } + + if (strncmp("expireTime:", p, 11) != 0) { + /* invalid record */ + talloc_free(addr); + return NULL; + } + + expire_time = p + 11; + + addr->expire_time = ldap_string_to_time(expire_time); return addr; } +/* + encode the winsdb_addr("address") attribute like this: + "172.31.1.1;winsOwner:172.31.9.202;expireTime:20050923032330.0Z" +*/ static int ldb_msg_add_winsdb_addr(struct ldb_context *ldb, struct ldb_message *msg, const char *attr_name, struct winsdb_addr *addr) { struct ldb_val val; + const char *str; + + str = talloc_asprintf(msg, "%s;winsOwner:%s;expireTime:%s", + addr->address, addr->wins_owner, + ldap_timestring(msg, addr->expire_time)); + if (!str) return -1; - val.data = discard_const_p(uint8_t, addr->address); - val.length = strlen(addr->address); + val.data = discard_const_p(uint8_t, str); + val.length = strlen(str); return ldb_msg_add_value(ldb, msg, attr_name, &val); } @@ -154,7 +220,8 @@ struct winsdb_addr **winsdb_addr_list_make(TALLOC_CTX *mem_ctx) return addresses; } -struct winsdb_addr **winsdb_addr_list_add(struct winsdb_addr **addresses, const char *address) +struct winsdb_addr **winsdb_addr_list_add(struct winsdb_addr **addresses, const char *address, + const char *wins_owner, time_t expire_time) { size_t len = winsdb_addr_list_length(addresses); @@ -170,9 +237,17 @@ struct winsdb_addr **winsdb_addr_list_add(struct winsdb_addr **addresses, const addresses[len]->address = talloc_strdup(addresses[len], address); if (!addresses[len]->address) { talloc_free(addresses); - return NULL; + return NULL; } + addresses[len]->wins_owner = talloc_strdup(addresses[len], wins_owner); + if (!addresses[len]->wins_owner) { + talloc_free(addresses); + return NULL; + } + + addresses[len]->expire_time = expire_time; + addresses[len+1] = NULL; return addresses; @@ -268,8 +343,11 @@ struct winsdb_record *winsdb_load(struct wins_server *winssrv, rec->expire_time = ldb_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->wins_owner); talloc_steal(rec, rec->registered_by); + if (!rec->wins_owner) rec->wins_owner = WINSDB_OWNER_LOCAL; + el = ldb_msg_find_element(res[0], "address"); if (el == NULL) goto failed; @@ -277,7 +355,7 @@ struct winsdb_record *winsdb_load(struct wins_server *winssrv, if (rec->addresses == NULL) goto failed; for (i=0;inum_values;i++) { - rec->addresses[i] = winsdb_addr_decode(rec->addresses, &el->values[i]); + rec->addresses[i] = winsdb_addr_decode(rec, rec->addresses, &el->values[i]); if (rec->addresses[i] == NULL) goto failed; } rec->addresses[i] = NULL; @@ -383,6 +461,7 @@ uint8_t winsdb_modify(struct wins_server *winssrv, struct winsdb_record *rec) rec->version = winsdb_allocate_version(winssrv); if (rec->version == 0) goto failed; + rec->wins_owner = WINSDB_OWNER_LOCAL; msg = winsdb_message(winssrv, rec, tmp_ctx); if (msg == NULL) goto failed; diff --git a/source4/nbt_server/wins/winsdb.h b/source4/nbt_server/wins/winsdb.h index 44d4003acc..c775159a18 100644 --- a/source4/nbt_server/wins/winsdb.h +++ b/source4/nbt_server/wins/winsdb.h @@ -25,8 +25,13 @@ enum wins_record_state { WINS_REC_ACTIVE =1 }; +#define WINSDB_OWNER_LOCAL "0.0.0.0" +#define WINSDB_GROUP_ADDRESS "255.255.255.255" + struct winsdb_addr { const char *address; + const char *wins_owner; + time_t expire_time; }; /* @@ -36,6 +41,7 @@ struct winsdb_record { struct nbt_name *name; uint16_t nb_flags; enum wins_record_state state; + const char *wins_owner; time_t expire_time; const char *registered_by; struct winsdb_addr **addresses; diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c index eba85ecb84..ddb4c6cc6c 100644 --- a/source4/nbt_server/wins/winsserver.c +++ b/source4/nbt_server/wins/winsserver.c @@ -59,11 +59,14 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock, rec.registered_by = src->addr; rec.addresses = winsdb_addr_list_make(packet); if (rec.addresses == NULL) return NBT_RCODE_SVR; + if (IS_GROUP_NAME(name, nb_flags)) { - rec.addresses = winsdb_addr_list_add(rec.addresses, "255.255.255.255"); - } else { - rec.addresses = winsdb_addr_list_add(rec.addresses, address); + address = WINSDB_GROUP_ADDRESS; } + rec.addresses = winsdb_addr_list_add(rec.addresses, + address, + WINSDB_OWNER_LOCAL, + rec.expire_time); if (rec.addresses == NULL) return NBT_RCODE_SVR; DEBUG(4,("WINS: accepted registration of %s with address %s\n", diff --git a/source4/nbt_server/wins/winswack.c b/source4/nbt_server/wins/winswack.c index 461acad981..defa3ad09a 100644 --- a/source4/nbt_server/wins/winswack.c +++ b/source4/nbt_server/wins/winswack.c @@ -69,13 +69,16 @@ static void wins_wack_allow(struct wack_state *state) nbtd_name_registration_reply(state->nbtsock, state->request_packet, &state->src, NBT_RCODE_OK); - rec->addresses = winsdb_addr_list_add(rec->addresses, state->reg_address); - if (rec->addresses == NULL) goto failed; - ttl = wins_server_ttl(state->winssrv, state->request_packet->additional[0].ttl); if (now + ttl > rec->expire_time) { rec->expire_time = now + ttl; } + rec->addresses = winsdb_addr_list_add(rec->addresses, + state->reg_address, + WINSDB_OWNER_LOCAL, + rec->expire_time); + if (rec->addresses == NULL) goto failed; + rec->registered_by = state->src.addr; winsdb_modify(state->winssrv, rec); -- cgit