summaryrefslogtreecommitdiff
path: root/source4/nbt_server/winsserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/nbt_server/winsserver.c')
-rw-r--r--source4/nbt_server/winsserver.c77
1 files changed, 34 insertions, 43 deletions
diff --git a/source4/nbt_server/winsserver.c b/source4/nbt_server/winsserver.c
index ad5ccdc16e..38f874a196 100644
--- a/source4/nbt_server/winsserver.c
+++ b/source4/nbt_server/winsserver.c
@@ -26,6 +26,16 @@
#include "system/time.h"
/*
+ work out the ttl we will use given a client requested ttl
+*/
+uint32_t wins_server_ttl(struct wins_server *winssrv, uint32_t ttl)
+{
+ ttl = MIN(ttl, winssrv->max_ttl);
+ ttl = MAX(ttl, winssrv->min_ttl);
+ return ttl;
+}
+
+/*
register a new name with WINS
*/
static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
@@ -36,14 +46,11 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
- uint32_t ttl = packet->additional[0].ttl;
+ uint32_t ttl = wins_server_ttl(winssrv, packet->additional[0].ttl);
uint16_t nb_flags = packet->additional[0].rdata.netbios.addresses[0].nb_flags;
const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
struct winsdb_record rec;
- ttl = MIN(ttl, winssrv->max_ttl);
- ttl = MAX(ttl, winssrv->min_ttl);
-
rec.name = name;
rec.nb_flags = nb_flags;
rec.state = WINS_REC_ACTIVE;
@@ -74,13 +81,10 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock,
struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
- uint32_t ttl = packet->additional[0].ttl;
+ uint32_t ttl = wins_server_ttl(winssrv, packet->additional[0].ttl);
const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
time_t now = time(NULL);
- ttl = MIN(ttl, winssrv->max_ttl);
- ttl = MAX(ttl, winssrv->min_ttl);
-
if (now + ttl > rec->expire_time) {
rec->expire_time = now + ttl;
}
@@ -92,28 +96,6 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock,
return winsdb_modify(winssrv, rec);
}
-
-/*
- send a WACK reply, then check if the current owners want to keep the name
-*/
-static uint8_t wins_register_wack(struct nbt_name_socket *nbtsock,
- struct nbt_name_packet *packet,
- struct winsdb_record *rec,
- const char *src_address, int src_port)
-{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
- struct nbtd_interface);
- struct wins_server *winssrv = iface->nbtsrv->winssrv;
- uint32_t ttl = packet->additional[0].ttl;
- const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
- time_t now = time(NULL);
-
- DEBUG(0,("TODO: WACK\n"));
-
- return NBT_RCODE_SVR;
-}
-
-
/*
register a name
*/
@@ -129,7 +111,6 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
uint8_t rcode = NBT_RCODE_OK;
uint16_t nb_flags = packet->additional[0].rdata.netbios.addresses[0].nb_flags;
const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
- int i;
rec = winsdb_load(winssrv, name, packet);
if (rec == NULL) {
@@ -165,15 +146,13 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
/* if the registration is for an address that is currently active, then
just update the expiry time */
- for (i=0;rec->addresses[i];i++) {
- if (strcmp(address, rec->addresses[i]) == 0) {
- wins_update_ttl(nbtsock, packet, rec, src_address, src_port);
- goto done;
- }
+ if (str_list_check(rec->addresses, address)) {
+ wins_update_ttl(nbtsock, packet, rec, src_address, src_port);
+ goto done;
}
- /* we have to do a WACK to see if the current owners are willing to give
- up their claim */
+ /* we have to do a WACK to see if the current owner is willing
+ to give up its claim */
wins_register_wack(nbtsock, packet, rec, src_address, src_port);
return;
@@ -220,14 +199,26 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
struct winsdb_record *rec;
rec = winsdb_load(winssrv, name, packet);
- if (rec != NULL &&
- rec->state == WINS_REC_ACTIVE &&
- !(rec->nb_flags & NBT_NM_GROUP)) {
- /* should we release all, or only some of the addresses? */
- rec->state = WINS_REC_RELEASED;
+ if (rec == NULL ||
+ rec->state != WINS_REC_ACTIVE ||
+ (rec->nb_flags & NBT_NM_GROUP)) {
+ goto done;
+ }
+
+ /* we only allow releases from an owner - other releases are
+ silently ignored */
+ if (str_list_check(rec->addresses, src_address)) {
+ const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
+
+ DEBUG(4,("WINS: released name %s at %s\n", nbt_name_string(rec, rec->name), address));
+ str_list_remove(rec->addresses, address);
+ if (rec->addresses[0] == NULL) {
+ rec->state = WINS_REC_RELEASED;
+ }
winsdb_modify(winssrv, rec);
}
+done:
/* we match w2k3 by always giving a positive reply to name releases. */
nbtd_name_release_reply(nbtsock, packet, src_address, src_port, NBT_RCODE_OK);
}