diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-02-12 11:33:42 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:09:45 -0500 |
commit | e199f4cef2bac3b244d08d445421975313229283 (patch) | |
tree | acc368908e18aef24c8093cf7a28044e61754ee3 /source4/nbt_server/winsserver.c | |
parent | ff4797a9e4b01fe8cc9421e911371677433d070c (diff) | |
download | samba-e199f4cef2bac3b244d08d445421975313229283.tar.gz samba-e199f4cef2bac3b244d08d445421975313229283.tar.bz2 samba-e199f4cef2bac3b244d08d445421975313229283.zip |
r5358: - added initial WINS server code. It passes most of the NBT-WINS test, but doesn't yet
do secure server WACK responses
- added a ldap_string_to_time() function, for converting a LDAP
formatted time to a time_t
(This used to be commit 9aa3313b3f93e47e3f93028e072f6a23b3c22385)
Diffstat (limited to 'source4/nbt_server/winsserver.c')
-rw-r--r-- | source4/nbt_server/winsserver.c | 127 |
1 files changed, 112 insertions, 15 deletions
diff --git a/source4/nbt_server/winsserver.c b/source4/nbt_server/winsserver.c index 22cfee415c..b59a1c9fa3 100644 --- a/source4/nbt_server/winsserver.c +++ b/source4/nbt_server/winsserver.c @@ -22,28 +22,121 @@ #include "includes.h" #include "nbt_server/nbt_server.h" +#include "nbt_server/winsdb.h" +#include "system/time.h" +/* + register a new name with WINS +*/ +static uint8_t wins_register_new(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *packet, + 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; + struct nbt_name *name = &packet->questions[0].name; + uint32_t ttl = packet->additional[0].ttl; + struct winsdb_record rec; + + ttl = MIN(ttl, winssrv->max_ttl); + ttl = MAX(ttl, winssrv->min_ttl); + + rec.name = name; + rec.nb_flags = packet->additional[0].rdata.netbios.addresses[0].nb_flags; + rec.state = WINS_REC_ACTIVE; + rec.expire_time = time(NULL) + ttl; + rec.registered_by = src_address; + rec.addresses = str_list_make(packet, + packet->additional[0].rdata.netbios.addresses[0].ipaddr, + NULL); + + return winsdb_add(winssrv, &rec); +} +/* + register a name +*/ +static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *packet, + 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; + struct nbt_name *name = &packet->questions[0].name; + struct winsdb_record *rec; + uint8_t rcode = 0; + + rec = winsdb_load(winssrv, name, packet); + if (rec == NULL) { + rcode = wins_register_new(nbtsock, packet, src_address, src_port); + } else if (rec->state != WINS_REC_ACTIVE) { + uint32_t ttl = packet->additional[0].ttl; + ttl = MIN(ttl, winssrv->max_ttl); + ttl = MAX(ttl, winssrv->min_ttl); + rec->nb_flags = packet->additional[0].rdata.netbios.addresses[0].nb_flags; + rec->state = WINS_REC_ACTIVE; + rec->expire_time = time(NULL) + ttl; + rec->registered_by = src_address; + rec->addresses = str_list_make(packet, + packet->additional[0].rdata.netbios.addresses[0].ipaddr, + NULL); + winsdb_modify(winssrv, rec); + } else { + rcode = NBT_RCODE_ACT; + } + + nbtd_name_registration_reply(nbtsock, packet, src_address, src_port, rcode); +} + + + +/* + query a name +*/ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, const char *src_address, int src_port) { - nbtd_negative_name_query_reply(nbtsock, packet, src_address, src_port); -} + struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, + struct nbtd_interface); + struct wins_server *winssrv = iface->nbtsrv->winssrv; + struct nbt_name *name = &packet->questions[0].name; + struct winsdb_record *rec; + + rec = winsdb_load(winssrv, name, packet); + if (rec == NULL || rec->state != WINS_REC_ACTIVE) { + nbtd_negative_name_query_reply(nbtsock, packet, src_address, src_port); + return; + } -static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock, - struct nbt_name_packet *packet, - const char *src_address, int src_port) -{ - nbtd_negative_name_registration_reply(nbtsock, packet, src_address, src_port); + nbtd_name_query_reply(nbtsock, packet, src_address, src_port, name, + 0, rec->nb_flags, rec->addresses); } - +/* + release a name +*/ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, 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; + struct nbt_name *name = &packet->questions[0].name; + struct winsdb_record *rec; + + rec = winsdb_load(winssrv, name, packet); + if (rec != NULL && rec->state == WINS_REC_ACTIVE) { + rec->state = WINS_REC_RELEASED; + winsdb_modify(winssrv, rec); + } + + /* 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); } @@ -54,7 +147,10 @@ void nbtd_winsserver_request(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, const char *src_address, int src_port) { - if (packet->operation & NBT_FLAG_BROADCAST) { + struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, + struct nbtd_interface); + struct wins_server *winssrv = iface->nbtsrv->winssrv; + if ((packet->operation & NBT_FLAG_BROADCAST) || winssrv == NULL) { return; } @@ -83,14 +179,15 @@ void nbtd_winsserver_request(struct nbt_name_socket *nbtsock, NTSTATUS nbtd_winsserver_init(struct nbtd_server *nbtsrv) { if (!lp_wins_support()) { - nbtsrv->wins_db = NULL; + nbtsrv->winssrv = NULL; return NT_STATUS_OK; } - nbtsrv->wins_db = ldb_wrap_connect(nbtsrv, lp_wins_url(), 0, NULL); - if (nbtsrv->wins_db == NULL) { - return NT_STATUS_INTERNAL_DB_ERROR; - } + nbtsrv->winssrv = talloc(nbtsrv, struct wins_server); + NT_STATUS_HAVE_NO_MEMORY(nbtsrv->winssrv); + + nbtsrv->winssrv->max_ttl = lp_max_wins_ttl(); + nbtsrv->winssrv->min_ttl = lp_min_wins_ttl(); - return NT_STATUS_OK; + return winsdb_init(nbtsrv->winssrv); } |