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:
parent
1d55354663
commit
4c297bac9d
@ -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++) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user