1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +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 72eba90465c478ac9d363ed0c88efea27afd158e)
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; 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; struct winsdb_addr *addr;
addr = talloc_steal(mem_ctx, val->data);
addr = talloc(mem_ctx, struct winsdb_addr);
if (!addr) return NULL;
addr->address = talloc_steal(addr, val->data);
return addr; return addr;
} }
static int ldb_msg_add_winsdb_addr(struct ldb_context *ldb, struct ldb_message *msg, 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; struct ldb_val val;
val.data = discard_const_p(uint8_t, addr); val.data = discard_const_p(uint8_t, addr->address);
val.length = strlen(addr); val.length = strlen(addr->address);
return ldb_msg_add_value(ldb, msg, attr_name, &val); 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 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"); el = ldb_msg_find_element(res[0], "address");
if (el == NULL) goto failed; 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; if (rec->addresses == NULL) goto failed;
for (i=0;i<el->num_values;i++) { for (i=0;i<el->num_values;i++) {

View File

@ -25,6 +25,10 @@ enum wins_record_state {
WINS_REC_ACTIVE =1 WINS_REC_ACTIVE =1
}; };
struct winsdb_addr {
const char *address;
};
/* /*
each record in the database contains the following information each record in the database contains the following information
*/ */
@ -34,7 +38,7 @@ struct winsdb_record {
enum wins_record_state state; enum wins_record_state state;
time_t expire_time; time_t expire_time;
const char *registered_by; const char *registered_by;
const char **addresses; struct winsdb_addr **addresses;
uint64_t version; 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.state = WINS_REC_ACTIVE;
rec.expire_time = time(NULL) + ttl; rec.expire_time = time(NULL) + ttl;
rec.registered_by = src->addr; 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)) { 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 { } 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; if (rec.addresses == NULL) return NBT_RCODE_SVR;
DEBUG(4,("WINS: accepted registration of %s with address %s\n", 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); 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 /* if the registration is for an address that is currently active, then
just update the expiry time */ 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); wins_update_ttl(nbtsock, packet, rec, src);
goto done; goto done;
} }
@ -181,6 +183,7 @@ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock,
struct wins_server *winssrv = iface->nbtsrv->winssrv; struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name; struct nbt_name *name = &packet->questions[0].name;
struct winsdb_record *rec; struct winsdb_record *rec;
const char **addresses;
rec = winsdb_load(winssrv, name, packet); rec = winsdb_load(winssrv, name, packet);
if (rec == NULL || rec->state != WINS_REC_ACTIVE) { if (rec == NULL || rec->state != WINS_REC_ACTIVE) {
@ -188,8 +191,14 @@ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock,
return; 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, 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 /* we only allow releases from an owner - other releases are
silently ignored */ 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; 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)); 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) { if (rec->addresses[0] == NULL) {
rec->state = WINS_REC_RELEASED; 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, nbtd_name_registration_reply(state->nbtsock, state->request_packet,
&state->src, NBT_RCODE_OK); &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; if (rec->addresses == NULL) goto failed;
ttl = wins_server_ttl(state->winssrv, state->request_packet->additional[0].ttl); 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 /* we are going to allow the registration, but first remove any addresses
from the record that aren't in the reply from the client */ from the record that aren't in the reply from the client */
for (i=0;rec->addresses[i];) { for (i=0; state->query.out.reply_addrs[i]; i++) {
if (!str_list_check(state->query.out.reply_addrs, rec->addresses[i])) { if (!winsdb_addr_list_check(rec->addresses, state->query.out.reply_addrs[i])) {
str_list_remove(rec->addresses, rec->addresses[i]); winsdb_addr_list_remove(rec->addresses, state->query.out.reply_addrs[i]);
} else {
i++;
} }
} }
@ -174,7 +172,8 @@ void wins_register_wack(struct nbt_name_socket *nbtsock,
state->nbtsock = nbtsock; state->nbtsock = nbtsock;
state->request_packet = talloc_steal(state, packet); state->request_packet = talloc_steal(state, packet);
state->rec = talloc_steal(state, rec); 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->reg_address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
state->src.port = src->port; state->src.port = src->port;
state->src.addr = talloc_strdup(state, src->addr); 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 /* send a WACK to the client, specifying the maximum time it could
take to check with the owner, plus some slack */ 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); nbtd_wack_reply(nbtsock, packet, src, ttl);
req = nbt_name_query_send(nbtsock, &state->query); req = nbt_name_query_send(nbtsock, &state->query);