summaryrefslogtreecommitdiff
path: root/source4/lib/wins_srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/wins_srv.c')
-rw-r--r--source4/lib/wins_srv.c362
1 files changed, 0 insertions, 362 deletions
diff --git a/source4/lib/wins_srv.c b/source4/lib/wins_srv.c
deleted file mode 100644
index 0338db8b3d..0000000000
--- a/source4/lib/wins_srv.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba wins server helper functions
- Copyright (C) Andrew Tridgell 1992-2002
- Copyright (C) Christopher R. Hertel 2000
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "system/time.h"
-
-/*
- This is pretty much a complete rewrite of the earlier code. The main
- aim of the rewrite is to add support for having multiple wins server
- lists, so Samba can register with multiple groups of wins servers
- and each group has a failover list of wins servers.
-
- Central to the way it all works is the idea of a wins server
- 'tag'. A wins tag is a label for a group of wins servers. For
- example if you use
-
- wins server = fred:192.168.2.10 mary:192.168.3.199 fred:192.168.2.61
-
- then you would have two groups of wins servers, one tagged with the
- name 'fred' and the other with the name 'mary'. I would usually
- recommend using interface names instead of 'fred' and 'mary' but
- they can be any alpha string.
-
- Now, how does it all work. Well, nmbd needs to register each of its
- IPs with each of its names once with each group of wins servers. So
- it tries registering with the first one mentioned in the list, then
- if that fails it marks that WINS server dead and moves onto the next
- one.
-
- In the client code things are a bit different. As each of the groups
- of wins servers is a separate name space we need to try each of the
- groups until we either succeed or we run out of wins servers to
- try. If we get a negative response from a wins server then that
- means the name doesn't exist in that group, so we give up on that
- group and move to the next group. If we don't get a response at all
- then maybe the wins server is down, in which case we need to
- failover to the next one for that group.
-
- confused yet? (tridge)
-*/
-
-/* how long a server is marked dead for */
-#define DEATH_TIME 600
-
-/* The list of dead wins servers is stored in gencache.tdb. Each server is
- marked dead from the point of view of a given source address. We keep a
- separate dead list for each src address to cope with multiple interfaces
- that are not routable to each other.
- */
-
-#define WINS_SRV_FMT "WINS_SRV_DEAD/%s,%s" /* wins_ip,src_ip */
-
-static char *wins_srv_keystr(struct ipv4_addr wins_ip, struct ipv4_addr src_ip)
-{
- char *keystr;
-
- if (asprintf(&keystr, WINS_SRV_FMT, sys_inet_ntoa(wins_ip),
- sys_inet_ntoa(src_ip)) == -1) {
- DEBUG(0, ("wins_srv_is_dead: malloc error\n"));
- return NULL;
- }
-
- return keystr;
-}
-
-/*
- see if an ip is on the dead list
-*/
-
-BOOL wins_srv_is_dead(struct ipv4_addr wins_ip, struct ipv4_addr src_ip)
-{
- char *keystr = wins_srv_keystr(wins_ip, src_ip);
- BOOL result;
-
- /* If the key exists then the WINS server has been marked as dead */
-
- result = gencache_get(keystr, NULL, NULL);
- SAFE_FREE(keystr);
-
- DEBUG(4, ("wins_srv_is_dead: %s is %s\n", sys_inet_ntoa(wins_ip),
- result ? "dead" : "alive"));
-
- return result;
-}
-
-
-/*
- mark a wins server as being alive (for the moment)
-*/
-void wins_srv_alive(struct ipv4_addr wins_ip, struct ipv4_addr src_ip)
-{
- char *keystr = wins_srv_keystr(wins_ip, src_ip);
-
- gencache_del(keystr);
- SAFE_FREE(keystr);
-
- DEBUG(4, ("wins_srv_alive: marking wins server %s alive\n",
- sys_inet_ntoa(wins_ip)));
-}
-
-/*
- mark a wins server as temporarily dead
-*/
-void wins_srv_died(struct ipv4_addr wins_ip, struct ipv4_addr src_ip)
-{
- char *keystr;
-
- if (is_zero_ip(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
- return;
-
- keystr = wins_srv_keystr(wins_ip, src_ip);
-
- gencache_set(keystr, "DOWN", time(NULL) + DEATH_TIME);
-
- SAFE_FREE(keystr);
-
- DEBUG(4,("Marking wins server %s dead for %u seconds from source %s\n",
- sys_inet_ntoa(wins_ip), DEATH_TIME, sys_inet_ntoa(src_ip)));
-}
-
-/*
- return the total number of wins servers, dead or not
-*/
-uint_t wins_srv_count(void)
-{
- const char **list;
- int count = 0;
-
- if (lp_wins_support()) {
- /* simple - just talk to ourselves */
- return 1;
- }
-
- list = lp_wins_server_list();
- for (count=0; list && list[count]; count++)
- /* nop */ ;
-
- return count;
-}
-
-/* an internal convenience structure for an IP with a short string tag
- attached */
-struct tagged_ip {
- fstring tag;
- struct ipv4_addr ip;
-};
-
-/*
- parse an IP string that might be in tagged format
- the result is a tagged_ip structure containing the tag
- and the ip in in_addr format. If there is no tag then
- use the tag '*'
-*/
-static void parse_ip(TALLOC_CTX *mem_ctx, struct tagged_ip *ip, const char *str)
-{
- char *s = strchr(str, ':');
- if (!s) {
- fstrcpy(ip->tag, "*");
- ip->ip = interpret_addr2(str);
- return;
- }
-
- ip->ip = interpret_addr2(s+1);
- fstrcpy(ip->tag, str);
- s = strchr(ip->tag, ':');
- if (s) *s = 0;
-}
-
-
-
-/*
- return the list of wins server tags. A 'tag' is used to distinguish
- wins server as either belonging to the same name space or a separate
- name space. Usually you would setup your 'wins server' option to
- list one or more wins server per interface and use the interface
- name as your tag, but you are free to use any tag you like.
-*/
-char **wins_srv_tags(void)
-{
- char **ret = NULL;
- int count=0, i, j;
- const char **list;
- TALLOC_CTX *mem_ctx;
-
- if (lp_wins_support()) {
- /* give the caller something to chew on. This makes
- the rest of the logic simpler (ie. less special cases) */
- ret = malloc_array_p(char *, 2);
- if (!ret) return NULL;
- ret[0] = strdup("*");
- ret[1] = NULL;
- return ret;
- }
-
- list = lp_wins_server_list();
- if (!list)
- return NULL;
-
- mem_ctx = talloc_init("wins_ssrv_tags");
- if (!mem_ctx) {
- return NULL;
- }
- /* yes, this is O(n^2) but n is very small */
- for (i=0;list[i];i++) {
- struct tagged_ip t_ip;
-
- parse_ip(mem_ctx, &t_ip, list[i]);
-
- /* see if we already have it */
- for (j=0;j<count;j++) {
- if (strcmp(ret[j], t_ip.tag) == 0) {
- break;
- }
- }
-
- if (j != count) {
- /* we already have it. Move along */
- continue;
- }
-
- /* add it to the list */
- ret = realloc_p(ret, char *, count+2);
- ret[count] = strdup(t_ip.tag);
- if (!ret[count]) break;
- count++;
- }
-
- if (count) {
- /* make sure we null terminate */
- ret[count] = NULL;
- }
-
- return ret;
-}
-
-/* free a list of wins server tags given by wins_srv_tags */
-void wins_srv_tags_free(char **list)
-{
- int i;
- if (!list) return;
- for (i=0; list[i]; i++) {
- free(list[i]);
- }
- free(list);
-}
-
-
-/*
- return the IP of the currently active wins server for the given tag,
- or the zero IP otherwise
-*/
-struct ipv4_addr wins_srv_ip_tag(const char *tag, struct ipv4_addr src_ip)
-{
- const char **list;
- int i;
- struct tagged_ip t_ip;
- TALLOC_CTX *mem_ctx;
-
- /* if we are a wins server then we always just talk to ourselves */
- if (lp_wins_support()) {
- extern struct ipv4_addr loopback_ip;
- return loopback_ip;
- }
-
- list = lp_wins_server_list();
- if (!list || !list[0]) {
- struct ipv4_addr ip;
- zero_ip(&ip);
- return ip;
- }
-
- mem_ctx = talloc_init("wins_srv_ip_tag");
- /* find the first live one for this tag */
- for (i=0; list[i]; i++) {
- parse_ip(mem_ctx, &t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) != 0) {
- /* not for the right tag. Move along */
- continue;
- }
- if (!wins_srv_is_dead(t_ip.ip, src_ip)) {
- char *src_name;
- src_name = talloc_strdup(mem_ctx, sys_inet_ntoa(src_ip));
- DEBUG(6,("Current wins server for tag '%s' with source %s is %s\n",
- tag,
- src_name,
- sys_inet_ntoa(t_ip.ip)));
- goto exit;
- }
- }
-
- /* they're all dead - try the first one until they revive */
- for (i=0; list[i]; i++) {
- parse_ip(mem_ctx, &t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) != 0) {
- continue;
- }
- goto exit;
- }
-
- /* this can't happen?? */
- zero_ip(&t_ip.ip);
-exit:
- talloc_destroy(mem_ctx);
- return t_ip.ip;
-}
-
-
-/*
- return a count of the number of IPs for a particular tag, including
- dead ones
-*/
-uint_t wins_srv_count_tag(const char *tag)
-{
- const char **list;
- int i, count=0;
- TALLOC_CTX *mem_ctx;
-
- /* if we are a wins server then we always just talk to ourselves */
- if (lp_wins_support()) {
- return 1;
- }
-
- list = lp_wins_server_list();
- if (!list || !list[0]) {
- return 0;
- }
-
- /* find the first live one for this tag */
- mem_ctx = talloc_init("wins_srv_count_tag");
- if (!mem_ctx) {
- return 0;
- }
- for (i=0; list[i]; i++) {
- struct tagged_ip t_ip;
- parse_ip(mem_ctx, &t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) == 0) {
- count++;
- }
- }
- talloc_destroy(mem_ctx);
-
- return count;
-}