1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

r11026: r10318@SERNOX: metze | 2005-09-19 16:38:15 +0200

move to struct winsdb_addr, (I'll add expiry_time and the wins_owner later

 tridge: can you please review the new winsdb_addr_* functions carefull, look for off-by-one bugs, etc.

 metze
(This used to be commit 72eba90465)
This commit is contained in:
Stefan Metzmacher 2005-10-14 12:49:55 +00:00 committed by Gerald (Jerry) Carter
parent 1d55354663
commit 4c297bac9d
4 changed files with 135 additions and 23 deletions

View File

@ -119,24 +119,124 @@ static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct nbt_name *name)
return dn;
}
static const char *winsdb_addr_decode(TALLOC_CTX *mem_ctx, struct ldb_val *val)
static struct winsdb_addr *winsdb_addr_decode(TALLOC_CTX *mem_ctx, struct ldb_val *val)
{
const char *addr;
addr = talloc_steal(mem_ctx, val->data);
struct winsdb_addr *addr;
addr = talloc(mem_ctx, struct winsdb_addr);
if (!addr) return NULL;
addr->address = talloc_steal(addr, val->data);
return addr;
}
static int ldb_msg_add_winsdb_addr(struct ldb_context *ldb, struct ldb_message *msg,
const char *attr_name, const char *addr)
const char *attr_name, struct winsdb_addr *addr)
{
struct ldb_val val;
val.data = discard_const_p(uint8_t, addr);
val.length = strlen(addr);
val.data = discard_const_p(uint8_t, addr->address);
val.length = strlen(addr->address);
return ldb_msg_add_value(ldb, msg, attr_name, &val);
}
struct winsdb_addr **winsdb_addr_list_make(TALLOC_CTX *mem_ctx)
{
struct winsdb_addr **addresses;
addresses = talloc_array(mem_ctx, struct winsdb_addr *, 1);
if (!addresses) return NULL;
addresses[0] = NULL;
return addresses;
}
struct winsdb_addr **winsdb_addr_list_add(struct winsdb_addr **addresses, const char *address)
{
size_t len = winsdb_addr_list_length(addresses);
addresses = talloc_realloc(addresses, addresses, struct winsdb_addr *, len + 2);
if (!addresses) return NULL;
addresses[len] = talloc(addresses, struct winsdb_addr);
if (!addresses[len]) {
talloc_free(addresses);
return NULL;
}
addresses[len]->address = talloc_strdup(addresses[len], address);
if (!addresses[len]->address) {
talloc_free(addresses);
return NULL;
}
addresses[len+1] = NULL;
return addresses;
}
void winsdb_addr_list_remove(struct winsdb_addr **addresses, const char *address)
{
size_t i;
for (i=0; addresses[i]; i++) {
if (strcmp(addresses[i]->address, address) == 0) {
break;
}
}
if (!addresses[i]) return;
for (; addresses[i]; i++) {
addresses[i] = addresses[i+1];
}
return;
}
struct winsdb_addr *winsdb_addr_list_check(struct winsdb_addr **addresses, const char *address)
{
size_t i;
for (i=0; addresses[i]; i++) {
if (strcmp(addresses[i]->address, address) == 0) {
return addresses[i];
}
}
return NULL;
}
size_t winsdb_addr_list_length(struct winsdb_addr **addresses)
{
size_t i;
for (i=0; addresses[i]; i++);
return i;
}
const char **winsdb_addr_string_list(TALLOC_CTX *mem_ctx, struct winsdb_addr **addresses)
{
size_t len = winsdb_addr_list_length(addresses);
const char **str_list;
size_t i;
str_list = talloc_array(mem_ctx, const char *, len + 1);
if (!str_list) return NULL;
for (i=0; i < len; i++) {
str_list[i] = talloc_strdup(str_list, addresses[i]->address);
if (!str_list[i]) {
talloc_free(str_list);
return NULL;
}
}
str_list[len] = NULL;
return str_list;
}
/*
load a WINS entry from the database
*/
@ -173,7 +273,7 @@ struct winsdb_record *winsdb_load(struct wins_server *winssrv,
el = ldb_msg_find_element(res[0], "address");
if (el == NULL) goto failed;
rec->addresses = talloc_array(rec, const char *, el->num_values+1);
rec->addresses = talloc_array(rec, struct winsdb_addr *, el->num_values+1);
if (rec->addresses == NULL) goto failed;
for (i=0;i<el->num_values;i++) {

View File

@ -25,6 +25,10 @@ enum wins_record_state {
WINS_REC_ACTIVE =1
};
struct winsdb_addr {
const char *address;
};
/*
each record in the database contains the following information
*/
@ -34,7 +38,7 @@ struct winsdb_record {
enum wins_record_state state;
time_t expire_time;
const char *registered_by;
const char **addresses;
struct winsdb_addr **addresses;
uint64_t version;
};

View File

@ -57,15 +57,17 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
rec.state = WINS_REC_ACTIVE;
rec.expire_time = time(NULL) + ttl;
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 = str_list_make(packet, "255.255.255.255", NULL);
rec.addresses = winsdb_addr_list_add(rec.addresses, "255.255.255.255");
} else {
rec.addresses = str_list_make(packet, address, NULL);
rec.addresses = winsdb_addr_list_add(rec.addresses, address);
}
if (rec.addresses == NULL) return NBT_RCODE_SVR;
DEBUG(4,("WINS: accepted registration of %s with address %s\n",
nbt_name_string(packet, name), rec.addresses[0]));
nbt_name_string(packet, name), rec.addresses[0]->address));
return winsdb_add(winssrv, &rec);
}
@ -153,7 +155,7 @@ 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 */
if (str_list_check(rec->addresses, address)) {
if (winsdb_addr_list_check(rec->addresses, address)) {
wins_update_ttl(nbtsock, packet, rec, src);
goto done;
}
@ -181,6 +183,7 @@ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock,
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
struct winsdb_record *rec;
const char **addresses;
rec = winsdb_load(winssrv, name, packet);
if (rec == NULL || rec->state != WINS_REC_ACTIVE) {
@ -188,8 +191,14 @@ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock,
return;
}
addresses = winsdb_addr_string_list(packet, rec->addresses);
if (addresses == NULL) {
nbtd_negative_name_query_reply(nbtsock, packet, src);
return;
}
nbtd_name_query_reply(nbtsock, packet, src, name,
0, rec->nb_flags, rec->addresses);
0, rec->nb_flags, addresses);
}
/*
@ -214,11 +223,11 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
/* we only allow releases from an owner - other releases are
silently ignored */
if (str_list_check(rec->addresses, src->addr)) {
if (winsdb_addr_list_check(rec->addresses, src->addr)) {
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);
winsdb_addr_list_remove(rec->addresses, address);
if (rec->addresses[0] == NULL) {
rec->state = WINS_REC_RELEASED;
}

View File

@ -69,7 +69,7 @@ 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 = str_list_add(rec->addresses, state->reg_address);
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);
@ -133,11 +133,9 @@ static void wins_wack_handler(struct nbt_name_request *req)
/* we are going to allow the registration, but first remove any addresses
from the record that aren't in the reply from the client */
for (i=0;rec->addresses[i];) {
if (!str_list_check(state->query.out.reply_addrs, rec->addresses[i])) {
str_list_remove(rec->addresses, rec->addresses[i]);
} else {
i++;
for (i=0; state->query.out.reply_addrs[i]; i++) {
if (!winsdb_addr_list_check(rec->addresses, state->query.out.reply_addrs[i])) {
winsdb_addr_list_remove(rec->addresses, state->query.out.reply_addrs[i]);
}
}
@ -174,7 +172,8 @@ void wins_register_wack(struct nbt_name_socket *nbtsock,
state->nbtsock = nbtsock;
state->request_packet = talloc_steal(state, packet);
state->rec = talloc_steal(state, rec);
state->owner_addresses = rec->addresses;
state->owner_addresses = winsdb_addr_string_list(state, rec->addresses);
if (state->owner_addresses == NULL) goto failed;
state->reg_address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
state->src.port = src->port;
state->src.addr = talloc_strdup(state, src->addr);
@ -196,7 +195,7 @@ void wins_register_wack(struct nbt_name_socket *nbtsock,
/* send a WACK to the client, specifying the maximum time it could
take to check with the owner, plus some slack */
ttl = 5 + 4 * str_list_length(rec->addresses);
ttl = 5 + 4 * winsdb_addr_list_length(rec->addresses);
nbtd_wack_reply(nbtsock, packet, src, ttl);
req = nbt_name_query_send(nbtsock, &state->query);