summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-08-23 01:59:14 +0000
committerJeremy Allison <jra@samba.org>2003-08-23 01:59:14 +0000
commitdac11b890b3e81f8849340e582b7f397a612baba (patch)
tree91c9b21264d90486a81696f3a03ef0842abd00db /source3
parente745d4e602698e0a49a9e90c918049b4096fbba8 (diff)
downloadsamba-dac11b890b3e81f8849340e582b7f397a612baba.tar.gz
samba-dac11b890b3e81f8849340e582b7f397a612baba.tar.bz2
samba-dac11b890b3e81f8849340e582b7f397a612baba.zip
Half-way though the big conversion of all nmbd access to wire elements being
converted to pull/push_ascii. This will not work right at the moment for non English codepages, but compiles - I will finish the work over the weekend. Then nmbd should be completely codepage correct. Jeremy. (This used to be commit 236d6adadf32397b28028ea82ae2ec027366f7c8)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/nameserv.h367
-rw-r--r--source3/include/safe_string.h1
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/lib/charcnv.c10
-rw-r--r--source3/nmbd/nmbd.c205
-rw-r--r--source3/nmbd/nmbd_become_dmb.c522
-rw-r--r--source3/nmbd/nmbd_become_lmb.c688
-rw-r--r--source3/nmbd/nmbd_browserdb.c6
-rw-r--r--source3/nmbd/nmbd_browsesync.c841
-rw-r--r--source3/nmbd/nmbd_elections.c527
-rw-r--r--source3/nmbd/nmbd_incomingdgrams.c1087
-rw-r--r--source3/nmbd/nmbd_namequery.c4
12 files changed, 2088 insertions, 2176 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 14561cf44d..10e1295fb6 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -176,124 +176,116 @@ enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME,
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET};
-enum master_state
-{
- MST_NONE,
- MST_POTENTIAL,
- MST_BACKUP,
- MST_MSB,
- MST_BROWSER,
- MST_UNBECOMING_MASTER
+enum master_state {
+ MST_NONE,
+ MST_POTENTIAL,
+ MST_BACKUP,
+ MST_MSB,
+ MST_BROWSER,
+ MST_UNBECOMING_MASTER
};
-enum domain_state
-{
- DOMAIN_NONE,
- DOMAIN_WAIT,
- DOMAIN_MST
+enum domain_state {
+ DOMAIN_NONE,
+ DOMAIN_WAIT,
+ DOMAIN_MST
};
-enum logon_state
-{
- LOGON_NONE,
- LOGON_WAIT,
- LOGON_SRV
+enum logon_state {
+ LOGON_NONE,
+ LOGON_WAIT,
+ LOGON_SRV
};
struct subnet_record;
-struct nmb_data
-{
- uint16 nb_flags; /* Netbios flags. */
- int num_ips; /* Number of ip entries. */
- struct in_addr *ip; /* The ip list for this name. */
+struct nmb_data {
+ uint16 nb_flags; /* Netbios flags. */
+ int num_ips; /* Number of ip entries. */
+ struct in_addr *ip; /* The ip list for this name. */
- enum name_source source; /* Where the name came from. */
+ enum name_source source; /* Where the name came from. */
- time_t death_time; /* The time the record must be removed (do not remove if 0). */
- time_t refresh_time; /* The time the record should be refreshed. */
+ time_t death_time; /* The time the record must be removed (do not remove if 0). */
+ time_t refresh_time; /* The time the record should be refreshed. */
- SMB_BIG_UINT id; /* unique id */
- struct in_addr wins_ip; /* the adress of the wins server this record comes from */
+ SMB_BIG_UINT id; /* unique id */
+ struct in_addr wins_ip; /* the adress of the wins server this record comes from */
- int wins_flags; /* similar to the netbios flags but different ! */
+ int wins_flags; /* similar to the netbios flags but different ! */
};
/* This structure represents an entry in a local netbios name list. */
-struct name_record
- {
- ubi_trNode node[1];
- struct subnet_record *subnet;
- struct nmb_name name; /* The netbios name. */
- struct nmb_data data; /* The netbios data. */
- };
+struct name_record {
+ ubi_trNode node[1];
+ struct subnet_record *subnet;
+ struct nmb_name name; /* The netbios name. */
+ struct nmb_data data; /* The netbios data. */
+};
/* Browser cache for synchronising browse lists. */
-struct browse_cache_record
- {
- ubi_dlNode node[1];
- pstring lmb_name;
- pstring work_group;
- struct in_addr ip;
- time_t sync_time;
- time_t death_time; /* The time the record must be removed. */
- };
+struct browse_cache_record {
+ ubi_dlNode node[1];
+ pstring lmb_name;
+ pstring work_group;
+ struct in_addr ip;
+ time_t sync_time;
+ time_t death_time; /* The time the record must be removed. */
+};
/* This is used to hold the list of servers in my domain, and is
contained within lists of domains. */
-struct server_record
-{
- struct server_record *next;
- struct server_record *prev;
+struct server_record {
+ struct server_record *next;
+ struct server_record *prev;
- struct subnet_record *subnet;
+ struct subnet_record *subnet;
- struct server_info_struct serv;
- time_t death_time;
+ struct server_info_struct serv;
+ time_t death_time;
};
/* A workgroup structure. It contains a list of servers. */
-struct work_record
-{
- struct work_record *next;
- struct work_record *prev;
+struct work_record {
+ struct work_record *next;
+ struct work_record *prev;
- struct subnet_record *subnet;
+ struct subnet_record *subnet;
- struct server_record *serverlist;
+ struct server_record *serverlist;
- /* Stage of development from non-local-master up to local-master browser. */
- enum master_state mst_state;
+ /* Stage of development from non-local-master up to local-master browser. */
+ enum master_state mst_state;
- /* Stage of development from non-domain-master to domain-master browser. */
- enum domain_state dom_state;
+ /* Stage of development from non-domain-master to domain-master browser. */
+ enum domain_state dom_state;
- /* Stage of development from non-logon-server to logon server. */
- enum logon_state log_state;
+ /* Stage of development from non-logon-server to logon server. */
+ enum logon_state log_state;
- /* Work group info. */
- fstring work_group;
- int token; /* Used when communicating with backup browsers. */
- fstring local_master_browser_name; /* Current local master browser. */
+ /* Work group info. */
+ fstring work_group;
+ int token; /* Used when communicating with backup browsers. */
+ fstring local_master_browser_name; /* Current local master browser. */
- /* Announce info. */
- time_t lastannounce_time;
- int announce_interval;
- BOOL needannounce;
+ /* Announce info. */
+ time_t lastannounce_time;
+ int announce_interval;
+ BOOL needannounce;
- /* Timeout time for this workgroup. 0 means permanent. */
- time_t death_time;
+ /* Timeout time for this workgroup. 0 means permanent. */
+ time_t death_time;
- /* Election info */
- BOOL RunningElection;
- BOOL needelection;
- int ElectionCount;
- uint32 ElectionCriterion;
+ /* Election info */
+ BOOL RunningElection;
+ BOOL needelection;
+ int ElectionCount;
+ uint32 ElectionCriterion;
- /* Domain master browser info. Used for efficient syncs. */
- struct nmb_name dmb_name;
- struct in_addr dmb_addr;
+ /* Domain master browser info. Used for efficient syncs. */
+ struct nmb_name dmb_name;
+ struct in_addr dmb_addr;
};
/* typedefs needed to define copy & free functions for userdata. */
@@ -305,10 +297,10 @@ typedef void (*userdata_free_fn)(struct userdata_struct *);
/* Structure to define any userdata passed around. */
struct userdata_struct {
- userdata_copy_fn copy_fn;
- userdata_free_fn free_fn;
- unsigned int userdata_len;
- char data[16]; /* 16 is to ensure alignment/padding on all systems */
+ userdata_copy_fn copy_fn;
+ userdata_free_fn free_fn;
+ unsigned int userdata_len;
+ char data[16]; /* 16 is to ensure alignment/padding on all systems */
};
struct response_record;
@@ -382,33 +374,32 @@ typedef void (*node_status_fail_function)( struct subnet_record *,
/* Initiated name queries are recorded in this list to track any responses. */
-struct response_record
-{
- struct response_record *next;
- struct response_record *prev;
+struct response_record {
+ struct response_record *next;
+ struct response_record *prev;
- uint16 response_id;
+ uint16 response_id;
- /* Callbacks for packets received or not. */
- response_function resp_fn;
- timeout_response_function timeout_fn;
+ /* Callbacks for packets received or not. */
+ response_function resp_fn;
+ timeout_response_function timeout_fn;
- /* Callbacks for the request succeeding or not. */
- success_function success_fn;
- fail_function fail_fn;
+ /* Callbacks for the request succeeding or not. */
+ success_function success_fn;
+ fail_function fail_fn;
- struct packet_struct *packet;
+ struct packet_struct *packet;
- struct userdata_struct *userdata;
+ struct userdata_struct *userdata;
- int num_msgs;
+ int num_msgs;
- time_t repeat_time;
- time_t repeat_interval;
- int repeat_count;
+ time_t repeat_time;
+ time_t repeat_interval;
+ int repeat_count;
- /* Recursion protection. */
- BOOL in_expiration_processing;
+ /* Recursion protection. */
+ BOOL in_expiration_processing;
};
/* A subnet structure. It contains a list of workgroups and netbios names. */
@@ -420,42 +411,41 @@ struct response_record
*/
enum subnet_type {
- NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */
- UNICAST_SUBNET = 1, /* Subnet for unicast packets. */
- REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */
- WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */
+ NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */
+ UNICAST_SUBNET = 1, /* Subnet for unicast packets. */
+ REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */
+ WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */
};
-struct subnet_record
-{
- struct subnet_record *next;
- struct subnet_record *prev;
+struct subnet_record {
+ struct subnet_record *next;
+ struct subnet_record *prev;
- char *subnet_name; /* For Debug identification. */
- enum subnet_type type; /* To catagorize the subnet. */
+ char *subnet_name; /* For Debug identification. */
+ enum subnet_type type; /* To catagorize the subnet. */
- struct work_record *workgrouplist; /* List of workgroups. */
- ubi_trRoot namelist[1]; /* List of netbios names. */
- struct response_record *responselist; /* List of responses expected. */
+ struct work_record *workgrouplist; /* List of workgroups. */
+ ubi_trRoot namelist[1]; /* List of netbios names. */
+ struct response_record *responselist; /* List of responses expected. */
- BOOL namelist_changed;
- BOOL work_changed;
+ BOOL namelist_changed;
+ BOOL work_changed;
- struct in_addr bcast_ip;
- struct in_addr mask_ip;
- struct in_addr myip;
- int nmb_sock; /* socket to listen for unicast 137. */
- int dgram_sock; /* socket to listen for unicast 138. */
+ struct in_addr bcast_ip;
+ struct in_addr mask_ip;
+ struct in_addr myip;
+ int nmb_sock; /* socket to listen for unicast 137. */
+ int dgram_sock; /* socket to listen for unicast 138. */
};
/* A resource record. */
struct res_rec {
- struct nmb_name rr_name;
- int rr_type;
- int rr_class;
- int ttl;
- int rdlength;
- char rdata[MAX_DGRAM_SIZE];
+ struct nmb_name rr_name;
+ int rr_type;
+ int rr_class;
+ int ttl;
+ int rdlength;
+ char rdata[MAX_DGRAM_SIZE];
};
/* Define these so we can pass info back to caller of name_query */
@@ -467,35 +457,34 @@ struct res_rec {
#define NM_FLAGS_B 0x01 /* Broadcast */
/* An nmb packet. */
-struct nmb_packet
-{
- struct {
- int name_trn_id;
- int opcode;
- BOOL response;
- struct {
- BOOL bcast;
- BOOL recursion_available;
- BOOL recursion_desired;
- BOOL trunc;
- BOOL authoritative;
- } nm_flags;
- int rcode;
- int qdcount;
- int ancount;
- int nscount;
- int arcount;
- } header;
-
- struct {
- struct nmb_name question_name;
- int question_type;
- int question_class;
- } question;
-
- struct res_rec *answers;
- struct res_rec *nsrecs;
- struct res_rec *additional;
+struct nmb_packet {
+ struct {
+ int name_trn_id;
+ int opcode;
+ BOOL response;
+ struct {
+ BOOL bcast;
+ BOOL recursion_available;
+ BOOL recursion_desired;
+ BOOL trunc;
+ BOOL authoritative;
+ } nm_flags;
+ int rcode;
+ int qdcount;
+ int ancount;
+ int nscount;
+ int arcount;
+ } header;
+
+ struct {
+ struct nmb_name question_name;
+ int question_type;
+ int question_class;
+ } question;
+
+ struct res_rec *answers;
+ struct res_rec *nsrecs;
+ struct res_rec *additional;
};
/* msg_type field options - from rfc1002. */
@@ -511,23 +500,23 @@ struct nmb_packet
/* A datagram - this normally contains SMB data in the data[] array. */
struct dgram_packet {
- struct {
- int msg_type;
- struct {
- enum node_type node_type;
- BOOL first;
- BOOL more;
- } flags;
- int dgm_id;
- struct in_addr source_ip;
- int source_port;
- int dgm_length;
- int packet_offset;
- } header;
- struct nmb_name source_name;
- struct nmb_name dest_name;
- int datasize;
- char data[MAX_DGRAM_SIZE];
+ struct {
+ int msg_type;
+ struct {
+ enum node_type node_type;
+ BOOL first;
+ BOOL more;
+ } flags;
+ int dgm_id;
+ struct in_addr source_ip;
+ int source_port;
+ int dgm_length;
+ int packet_offset;
+ } header;
+ struct nmb_name source_name;
+ struct nmb_name dest_name;
+ int datasize;
+ char data[MAX_DGRAM_SIZE];
};
/* Define a structure used to queue packets. This will be a linked
@@ -535,18 +524,18 @@ struct dgram_packet {
struct packet_struct
{
- struct packet_struct *next;
- struct packet_struct *prev;
- BOOL locked;
- struct in_addr ip;
- int port;
- int fd;
- time_t timestamp;
- enum packet_type packet_type;
- union {
- struct nmb_packet nmb;
- struct dgram_packet dgram;
- } packet;
+ struct packet_struct *next;
+ struct packet_struct *prev;
+ BOOL locked;
+ struct in_addr ip;
+ int port;
+ int fd;
+ time_t timestamp;
+ enum packet_type packet_type;
+ union {
+ struct nmb_packet nmb;
+ struct dgram_packet dgram;
+ } packet;
};
/* NETLOGON opcodes */
diff --git a/source3/include/safe_string.h b/source3/include/safe_string.h
index 6656f4f6bb..07578b2424 100644
--- a/source3/include/safe_string.h
+++ b/source3/include/safe_string.h
@@ -124,6 +124,7 @@ size_t __unsafe_string_function_usage_here_char__(void);
#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
+#define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1)
/* the addition of the DEVELOPER checks in safe_strcpy means we must
* update a lot of code. To make this a little easier here are some
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 36c53065bc..8c6f47f23f 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1484,9 +1484,11 @@ struct cnotify_fns {
#include "smb_macros.h"
+typedef char nstring[16];
+
/* A netbios name structure. */
struct nmb_name {
- char name[16];
+ nstring name;
char scope[64];
unsigned int name_type;
};
@@ -1494,7 +1496,7 @@ struct nmb_name {
/* A netbios node status array element. */
struct node_status {
- char name[16];
+ nstring name;
unsigned char type;
unsigned char flags;
};
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 02d94582fb..7f372b358f 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -529,6 +529,11 @@ size_t push_ascii_pstring(void *dest, const char *src)
return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
}
+size_t push_ascii_nstring(void *dest, const char *src)
+{
+ return push_ascii(dest, src, sizeof(nstring), STR_TERMINATE);
+}
+
/**
* Copy a string from a dos codepage source to a unix char* destination.
*
@@ -582,6 +587,11 @@ size_t pull_ascii_fstring(char *dest, const void *src)
return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
}
+size_t pull_ascii_nstring(char *dest, const void *src)
+{
+ return pull_ascii(dest, src, sizeof(nstring), sizeof(nstring), STR_TERMINATE);
+}
+
/**
* Copy a string from a char* src to a unicode destination.
*
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index fd648a4a27..c33011a417 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -303,6 +303,7 @@ static BOOL reload_nmbd_services(BOOL test)
* We use buf here to return BOOL result to process() when reload_interfaces()
* detects that there are no subnets.
**************************************************************************** */
+
static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len)
{
write_browse_list( 0, True );
@@ -650,126 +651,120 @@ static BOOL open_sockets(BOOL isdaemon, int port)
log_stdout = True;
}
- if ( log_stdout && Fork ) {
- DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
- exit(1);
- }
+ if ( log_stdout && Fork ) {
+ DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
+ exit(1);
+ }
- setup_logging( argv[0], log_stdout );
+ setup_logging( argv[0], log_stdout );
- reopen_logs();
+ reopen_logs();
- DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
- DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) );
+ DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
+ DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) );
- if ( !reload_nmbd_services(False) )
- return(-1);
+ if ( !reload_nmbd_services(False) )
+ return(-1);
- if(!init_names())
- return -1;
+ if(!init_names())
+ return -1;
- reload_nmbd_services( True );
+ reload_nmbd_services( True );
- if (strequal(lp_workgroup(),"*"))
- {
- DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
- exit(1);
- }
+ if (strequal(lp_workgroup(),"*")) {
+ DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
+ exit(1);
+ }
- set_samba_nb_type();
+ set_samba_nb_type();
- if (!is_daemon && !is_a_socket(0))
- {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
+ if (!is_daemon && !is_a_socket(0)) {
+ DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+ is_daemon = True;
+ }
- if (is_daemon && !opt_interactive)
- {
- DEBUG( 2, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
- }
+ if (is_daemon && !opt_interactive) {
+ DEBUG( 2, ( "Becoming a daemon.\n" ) );
+ become_daemon(Fork);
+ }
#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (opt_interactive)
- setpgid( (pid_t)0, (pid_t)0 );
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (opt_interactive)
+ setpgid( (pid_t)0, (pid_t)0 );
#endif
#ifndef SYNC_DNS
- /* Setup the async dns. We do it here so it doesn't have all the other
- stuff initialised and thus chewing memory and sockets */
- if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
- start_async_dns();
- }
+ /* Setup the async dns. We do it here so it doesn't have all the other
+ stuff initialised and thus chewing memory and sockets */
+ if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
+ start_async_dns();
+ }
#endif
- if (!directory_exist(lp_lockdir(), NULL)) {
- mkdir(lp_lockdir(), 0755);
- }
-
- pidfile_create("nmbd");
- message_init();
- message_register(MSG_FORCE_ELECTION, nmbd_message_election);
- message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
- message_register(MSG_SHUTDOWN, nmbd_terminate);
- message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
-
- DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
-
- if ( !open_sockets( is_daemon, global_nmb_port ) ) {
- kill_async_dns_child();
- return 1;
- }
-
- /* Determine all the IP addresses we have. */
- load_interfaces();
-
- /* Create an nmbd subnet record for each of the above. */
- if( False == create_subnets() )
- {
- DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* Load in any static local names. */
- load_lmhosts_file(dyn_LMHOSTSFILE);
- DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
-
- /* If we are acting as a WINS server, initialise data structures. */
- if( !initialise_wins() )
- {
- DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
- kill_async_dns_child();
- exit(1);
- }
-
- /*
- * Register nmbd primary workgroup and nmbd names on all
- * the broadcast subnets, and on the WINS server (if specified).
- * Also initiate the startup of our primary workgroup (start
- * elections if we are setup as being able to be a local
- * master browser.
- */
-
- if( False == register_my_workgroup_and_names() )
- {
- DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
- process();
-
- if (dbf)
- x_fclose(dbf);
- kill_async_dns_child();
- return(0);
+ if (!directory_exist(lp_lockdir(), NULL)) {
+ mkdir(lp_lockdir(), 0755);
+ }
+
+ pidfile_create("nmbd");
+ message_init();
+ message_register(MSG_FORCE_ELECTION, nmbd_message_election);
+ message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
+ message_register(MSG_SHUTDOWN, nmbd_terminate);
+ message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
+
+ DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
+
+ if ( !open_sockets( is_daemon, global_nmb_port ) ) {
+ kill_async_dns_child();
+ return 1;
+ }
+
+ /* Determine all the IP addresses we have. */
+ load_interfaces();
+
+ /* Create an nmbd subnet record for each of the above. */
+ if( False == create_subnets() ) {
+ DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
+ kill_async_dns_child();
+ exit(1);
+ }
+
+ /* Load in any static local names. */
+ load_lmhosts_file(dyn_LMHOSTSFILE);
+ DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
+
+ /* If we are acting as a WINS server, initialise data structures. */
+ if( !initialise_wins() ) {
+ DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
+ kill_async_dns_child();
+ exit(1);
+ }
+
+ /*
+ * Register nmbd primary workgroup and nmbd names on all
+ * the broadcast subnets, and on the WINS server (if specified).
+ * Also initiate the startup of our primary workgroup (start
+ * elections if we are setup as being able to be a local
+ * master browser.
+ */
+
+ if( False == register_my_workgroup_and_names() ) {
+ DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
+ kill_async_dns_child();
+ exit(1);
+ }
+
+ /* We can only take signals in the select. */
+ BlockSignals( True, SIGTERM );
+
+ process();
+
+ if (dbf)
+ x_fclose(dbf);
+ kill_async_dns_child();
+ return(0);
}
diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c
index 2e76e51f45..46d37fbb81 100644
--- a/source3/nmbd/nmbd_become_dmb.c
+++ b/source3/nmbd/nmbd_become_dmb.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-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
@@ -37,36 +37,37 @@ static void become_domain_master_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_domain_master_fail: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
-
- /* Set the state back to DOMAIN_NONE. */
- work->dom_state = DOMAIN_NONE;
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
+ nstring failname;
+ struct work_record *work;
+ struct server_record *servrec;
+
+ pull_ascii_nstring(failname, fail_name->name);
+ work = find_workgroup_on_subnet(subrec, failname);
+ if(!work) {
+ DEBUG(0,("become_domain_master_fail: Error - cannot find \
+workgroup %s on subnet %s\n", failname, subrec->subnet_name));
+ return;
+ }
+
+ /* Set the state back to DOMAIN_NONE. */
+ work->dom_state = DOMAIN_NONE;
+
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname(), work->work_group, subrec->subnet_name));
+ return;
+ }
- /* Update our server status. */
- servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
+ /* Update our server status. */
+ servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
+ DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
/****************************************************************************
@@ -79,115 +80,112 @@ static void become_domain_master_stage2(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
+ nstring regname;
+ struct work_record *work;
+ struct server_record *servrec;
+
+ pull_ascii_nstring(regname, registered_name->name);
+ work = find_workgroup_on_subnet( subrec, regname);
+
+ if(!work) {
+ DEBUG(0,("become_domain_master_stage2: Error - cannot find \
+workgroup %s on subnet %s\n", regname, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), registered_name->name, subrec->subnet_name));
- work->dom_state = DOMAIN_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->dom_state = DOMAIN_MST; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\nSamba server %s ", global_myname() );
- dbgtext( "is now a domain master browser for " );
- dbgtext( "workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
- if( subrec == unicast_subnet )
- {
- struct nmb_name nmbname;
- struct in_addr my_first_ip;
-
- /* Put our name and first IP address into the
- workgroup struct as domain master browser. This
- will stop us syncing with ourself if we are also
- a local master browser. */
-
- make_nmb_name(&nmbname, global_myname(), 0x20);
-
- work->dmb_name = nmbname;
- /* Pick the first interface ip address as the domain master browser ip. */
- my_first_ip = *iface_n_ip(0);
-
- putip((char *)&work->dmb_addr, &my_first_ip);
-
- /* We successfully registered by unicast with the
- WINS server. We now expect to become the domain
- master on the local subnets. If this fails, it's
- probably a 1.9.16p2 to 1.9.16p11 server's fault.
-
- This is a configuration issue that should be addressed
- by the network administrator - you shouldn't have
- several machines configured as a domain master browser
- for the same WINS scope (except if they are 1.9.17 or
- greater, and you know what you're doing.
-
- see docs/DOMAIN.txt.
-
- */
- become_domain_master_browser_bcast(work->work_group);
- }
- else
- {
- /*
- * Now we are a domain master on a broadcast subnet, we need to add
- * the WORKGROUP<1b> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. This bug wasn't found for a while
- * as it is strange to have a DMB without using WINS. JRA.
- */
- insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
- }
+ global_myname(), regname, subrec->subnet_name));
+ work->dom_state = DOMAIN_NONE;
+ return;
+ }
+
+ /* Set the state in the workgroup structure. */
+ work->dom_state = DOMAIN_MST; /* Become domain master. */
+
+ /* Update our server status. */
+ servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "*****\n\nSamba server %s ", global_myname() );
+ dbgtext( "is now a domain master browser for " );
+ dbgtext( "workgroup %s ", work->work_group );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
+
+ if( subrec == unicast_subnet ) {
+ struct nmb_name nmbname;
+ struct in_addr my_first_ip;
+
+ /* Put our name and first IP address into the
+ workgroup struct as domain master browser. This
+ will stop us syncing with ourself if we are also
+ a local master browser. */
+
+ make_nmb_name(&nmbname, global_myname(), 0x20);
+
+ work->dmb_name = nmbname;
+ /* Pick the first interface ip address as the domain master browser ip. */
+ my_first_ip = *iface_n_ip(0);
+
+ putip((char *)&work->dmb_addr, &my_first_ip);
+
+ /* We successfully registered by unicast with the
+ WINS server. We now expect to become the domain
+ master on the local subnets. If this fails, it's
+ probably a 1.9.16p2 to 1.9.16p11 server's fault.
+
+ This is a configuration issue that should be addressed
+ by the network administrator - you shouldn't have
+ several machines configured as a domain master browser
+ for the same WINS scope (except if they are 1.9.17 or
+ greater, and you know what you're doing.
+
+ see docs/DOMAIN.txt.
+
+ */
+ become_domain_master_browser_bcast(work->work_group);
+ } else {
+ /*
+ * Now we are a domain master on a broadcast subnet, we need to add
+ * the WORKGROUP<1b> name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. This bug wasn't found for a while
+ * as it is strange to have a DMB without using WINS. JRA.
+ */
+ insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
+ }
}
/****************************************************************************
Start the name registration process when becoming a Domain Master Browser
on a subnet.
- ****************************************************************************/
+****************************************************************************/
-static void become_domain_master_stage1(struct subnet_record *subrec, char *wg_name)
+static void become_domain_master_stage1(struct subnet_record *subrec, const char *wg_name)
{
- struct work_record *work;
+ struct work_record *work;
- DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
+ DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
workgroup %s on subnet %s\n", wg_name, subrec->subnet_name));
- /* First, find the workgroup on the subnet. */
- if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL)
- {
- DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
- wg_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
- work->dom_state = DOMAIN_WAIT;
-
- /* WORKGROUP<1b> is the domain master browser name. */
- register_name(subrec, work->work_group,0x1b,samba_nb_type,
- become_domain_master_stage2,
- become_domain_master_fail, NULL);
+ /* First, find the workgroup on the subnet. */
+ if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL) {
+ DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
+ wg_name, subrec->subnet_name));
+ return;
+ }
+
+ DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
+ work->dom_state = DOMAIN_WAIT;
+
+ /* WORKGROUP<1b> is the domain master browser name. */
+ register_name(subrec, work->work_group,0x1b,samba_nb_type,
+ become_domain_master_stage2,
+ become_domain_master_fail, NULL);
}
/****************************************************************************
@@ -202,37 +200,35 @@ static void become_domain_master_query_success(struct subnet_record *subrec,
struct nmb_name *nmbname, struct in_addr ip,
struct res_rec *rrec)
{
- /* If the given ip is not ours, then we can't become a domain
- controler as the name is already registered.
- */
-
- /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
- address or zero ip for this query. Pretend this is ok. */
-
- if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip))
- {
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "become_domain_master_query_success():\n" );
- dbgtext( "Our address (%s) ", inet_ntoa(ip) );
- dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
- dbgtext( "(domain master browser name) " );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- dbgtext( "Continuing with domain master code.\n" );
- }
-
- become_domain_master_stage1(subrec, nmbname->name);
- }
- else
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_query_success:\n" );
- dbgtext( "There is already a domain master browser at " );
- dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), nmbname->name );
- dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
- }
- }
+ nstring name;
+ pull_ascii_nstring(name, nmbname->name);
+
+ /* If the given ip is not ours, then we can't become a domain
+ controler as the name is already registered.
+ */
+
+ /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
+ address or zero ip for this query. Pretend this is ok. */
+
+ if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip)) {
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "become_domain_master_query_success():\n" );
+ dbgtext( "Our address (%s) ", inet_ntoa(ip) );
+ dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
+ dbgtext( "(domain master browser name) " );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ dbgtext( "Continuing with domain master code.\n" );
+ }
+
+ become_domain_master_stage1(subrec, name);
+ } else {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "become_domain_master_query_success:\n" );
+ dbgtext( "There is already a domain master browser at " );
+ dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), name );
+ dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
+ }
+ }
}
/****************************************************************************
@@ -245,18 +241,21 @@ static void become_domain_master_query_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- /* If the query was unicast, and the error is not NAM_ERR (name didn't exist),
- then this is a failure. Otherwise, not finding the name is what we want. */
- if((subrec == unicast_subnet) && (fail_code != NAM_ERR))
- {
- DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
+ nstring name;
+
+ /* If the query was unicast, and the error is not NAM_ERR (name didn't exist),
+ then this is a failure. Otherwise, not finding the name is what we want. */
+
+ if((subrec == unicast_subnet) && (fail_code != NAM_ERR)) {
+ DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
querying WINS server for name %s.\n",
- fail_code, nmb_namestr(question_name)));
- return;
- }
+ fail_code, nmb_namestr(question_name)));
+ return;
+ }
- /* Otherwise - not having the name allows us to register it. */
- become_domain_master_stage1(subrec, question_name->name);
+ /* Otherwise - not having the name allows us to register it. */
+ pull_ascii_nstring(name, question_name->name);
+ become_domain_master_stage1(subrec, name);
}
/****************************************************************************
@@ -265,47 +264,43 @@ querying WINS server for name %s.\n",
static void become_domain_master_browser_bcast(const char *workgroup_name)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
-
- if (work && (work->dom_state == DOMAIN_NONE))
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
-
- /*
- * Check for our name on the given broadcast subnet first, only initiate
- * further processing if we cannot find it.
- */
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_browser_bcast:\n" );
- dbgtext( "Attempting to become domain master browser on " );
- dbgtext( "workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name );
- }
-
- /* Send out a query to establish whether there's a
- domain controller on the local subnet. If not,
- we can become a domain controller.
- */
-
- DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
+
+ if (work && (work->dom_state == DOMAIN_NONE)) {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,workgroup_name,0x1b);
+
+ /*
+ * Check for our name on the given broadcast subnet first, only initiate
+ * further processing if we cannot find it.
+ */
+
+ if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "become_domain_master_browser_bcast:\n" );
+ dbgtext( "Attempting to become domain master browser on " );
+ dbgtext( "workgroup %s on subnet %s\n",
+ workgroup_name, subrec->subnet_name );
+ }
+
+ /* Send out a query to establish whether there's a
+ domain controller on the local subnet. If not,
+ we can become a domain controller.
+ */
+
+ DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
for domain master browser on workgroup %s\n", subrec->subnet_name, workgroup_name));
- query_name(subrec, nmbname.name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
- }
+ query_name(subrec, workgroup_name, nmbname.name_type,
+ become_domain_master_query_success,
+ become_domain_master_query_fail,
+ NULL);
+ }
+ }
+ }
}
/****************************************************************************
@@ -314,46 +309,43 @@ for domain master browser on workgroup %s\n", subrec->subnet_name, workgroup_nam
static void become_domain_master_browser_wins(const char *workgroup_name)
{
- struct work_record *work;
+ struct work_record *work;
- work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
+ work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
- if (work && (work->dom_state == DOMAIN_NONE))
- {
- struct nmb_name nmbname;
+ if (work && (work->dom_state == DOMAIN_NONE)) {
+ struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
+ make_nmb_name(&nmbname,workgroup_name,0x1b);
- /*
- * Check for our name on the unicast subnet first, only initiate
- * further processing if we cannot find it.
- */
+ /*
+ * Check for our name on the unicast subnet first, only initiate
+ * further processing if we cannot find it.
+ */
- if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_browser_wins:\n" );
- dbgtext( "Attempting to become domain master browser " );
- dbgtext( "on workgroup %s, subnet %s.\n",
- workgroup_name, unicast_subnet->subnet_name );
- }
+ if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "become_domain_master_browser_wins:\n" );
+ dbgtext( "Attempting to become domain master browser " );
+ dbgtext( "on workgroup %s, subnet %s.\n",
+ workgroup_name, unicast_subnet->subnet_name );
+ }
- /* Send out a query to establish whether there's a
- domain master broswer registered with WINS. If not,
- we can become a domain master browser.
- */
+ /* Send out a query to establish whether there's a
+ domain master broswer registered with WINS. If not,
+ we can become a domain master browser.
+ */
- DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
+ DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
for domain master browser name %s on workgroup %s\n",
- inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
-
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
+ inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
+
+ query_name(unicast_subnet, workgroup_name, nmbname.name_type,
+ become_domain_master_query_success,
+ become_domain_master_query_fail,
+ NULL);
+ }
+ }
}
/****************************************************************************
@@ -363,34 +355,32 @@ for domain master browser name %s on workgroup %s\n",
void add_domain_names(time_t t)
{
- static time_t lastrun = 0;
-
- if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
- return;
-
- lastrun = t;
-
- /* Do the "internet group" - <1c> names. */
- if (lp_domain_logons())
- add_logon_names();
-
- /* Do the domain master names. */
- if(lp_domain_master())
- {
- if(we_are_a_wins_client())
- {
- /* We register the WORKGROUP<1b> name with the WINS
- server first, and call add_domain_master_bcast()
- only if this is successful.
-
- This results in domain logon services being gracefully provided,
- as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
- 1.9.16p2 to 1.9.16p11 - due to a bug in namelogon.c,
- cannot provide domain master / domain logon services.
- */
- become_domain_master_browser_wins(lp_workgroup());
- }
- else
- become_domain_master_browser_bcast(lp_workgroup());
- }
+ static time_t lastrun = 0;
+
+ if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
+ return;
+
+ lastrun = t;
+
+ /* Do the "internet group" - <1c> names. */
+ if (lp_domain_logons())
+ add_logon_names();
+
+ /* Do the domain master names. */
+ if(lp_domain_master()) {
+ if(we_are_a_wins_client()) {
+ /* We register the WORKGROUP<1b> name with the WINS
+ server first, and call add_domain_master_bcast()
+ only if this is successful.
+
+ This results in domain logon services being gracefully provided,
+ as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
+ 1.9.16p2 to 1.9.16p11 - due to a bug in namelogon.c,
+ cannot provide domain master / domain logon services.
+ */
+ become_domain_master_browser_wins(lp_workgroup());
+ } else {
+ become_domain_master_browser_bcast(lp_workgroup());
+ }
+ }
}
diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c
index d390bf72e9..a6ae1ce42e 100644
--- a/source3/nmbd/nmbd_become_lmb.c
+++ b/source3/nmbd/nmbd_become_lmb.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-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
@@ -33,21 +33,20 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
void insert_permanent_name_into_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_type )
{
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
- {
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, nmbname->name,
- nmbname->name_type, nb_type,
- PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
- }
- else
- {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
+ nstring name;
+ struct name_record *namerec;
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
+ pull_ascii_nstring(name, nmbname->name);
+ /* The name needs to be created on the unicast subnet. */
+ (void)add_name_to_subnet( unicast_subnet, name,
+ nmbname->name_type, nb_type,
+ PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
+ } else {
+ /* The name already exists on the unicast subnet. Add our local
+ IP for the given broadcast subnet to the name. */
+ add_ip_to_name_record( namerec, subrec->myip);
+ }
}
/*******************************************************************
@@ -57,15 +56,14 @@ void insert_permanent_name_into_unicast( struct subnet_record *subrec,
static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname )
{
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
- {
- /* Remove this broadcast subnet IP address from the name. */
- remove_ip_from_name_record( namerec, subrec->myip);
- if(namerec->data.num_ips == 0)
- remove_name_from_namelist( unicast_subnet, namerec);
- }
+ struct name_record *namerec;
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL) {
+ /* Remove this broadcast subnet IP address from the name. */
+ remove_ip_from_name_record( namerec, subrec->myip);
+ if(namerec->data.num_ips == 0)
+ remove_name_from_namelist( unicast_subnet, namerec);
+ }
}
/*******************************************************************
@@ -73,60 +71,58 @@ static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
state back to potential browser, or none.
******************************************************************/
-static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
+static void reset_workgroup_state( struct subnet_record *subrec, const char *workgroup_name,
BOOL force_new_election )
{
- struct work_record *work;
- struct server_record *servrec;
- struct nmb_name nmbname;
+ struct work_record *work;
+ struct server_record *servrec;
+ struct nmb_name nmbname;
- if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
+ if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL) {
+ DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
subnet %s.\n", workgroup_name, subrec->subnet_name ));
- return;
- }
+ return;
+ }
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname(), work->work_group, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- /* Update our server status - remove any master flag and replace
- it with the potential browser flag. */
- servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
- servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
+ /* Update our server status - remove any master flag and replace
+ it with the potential browser flag. */
+ servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
+ servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- /* Reset our election flags. */
- work->ElectionCriterion &= ~0x4;
+ /* Reset our election flags. */
+ work->ElectionCriterion &= ~0x4;
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- /* Forget who the local master browser was for
- this workgroup. */
+ /* Forget who the local master browser was for
+ this workgroup. */
- set_workgroup_local_master_browser_name( work, "");
+ set_workgroup_local_master_browser_name( work, "");
- /*
- * Ensure the IP address of this subnet is not registered as one
- * of the IP addresses of the WORKGROUP<1d> name on the unicast
- * subnet. This undoes what we did below when we became a local
- * master browser.
- */
+ /*
+ * Ensure the IP address of this subnet is not registered as one
+ * of the IP addresses of the WORKGROUP<1d> name on the unicast
+ * subnet. This undoes what we did below when we became a local
+ * master browser.
+ */
- make_nmb_name(&nmbname, work->work_group, 0x1d);
+ make_nmb_name(&nmbname, work->work_group, 0x1d);
- remove_permanent_name_from_unicast( subrec, &nmbname);
+ remove_permanent_name_from_unicast( subrec, &nmbname);
- if(force_new_election)
- work->needelection = True;
+ if(force_new_election)
+ work->needelection = True;
}
/*******************************************************************
@@ -138,24 +134,25 @@ static void unbecome_local_master_success(struct subnet_record *subrec,
struct nmb_name *released_name,
struct in_addr released_ip)
{
- BOOL force_new_election = False;
+ BOOL force_new_election = False;
+ nstring relname;
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
+ memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
- DEBUG(3,("unbecome_local_master_success: released name %s.\n",
- nmb_namestr(released_name)));
+ DEBUG(3,("unbecome_local_master_success: released name %s.\n",
+ nmb_namestr(released_name)));
- /* Now reset the workgroup and server state. */
- reset_workgroup_state( subrec, released_name->name, force_new_election );
+ /* Now reset the workgroup and server state. */
+ pull_ascii_nstring(relname, released_name->name);
+ reset_workgroup_state( subrec, relname, force_new_election );
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", released_name->name );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname() );
+ dbgtext( "has stopped being a local master browser " );
+ dbgtext( "for workgroup %s ", relname );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
}
@@ -166,67 +163,66 @@ static void unbecome_local_master_success(struct subnet_record *subrec,
static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct name_record *namerec;
- struct userdata_struct *userdata = rrec->userdata;
- BOOL force_new_election = False;
+ struct name_record *namerec;
+ struct userdata_struct *userdata = rrec->userdata;
+ BOOL force_new_election = False;
+ nstring failname;
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
+ memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
- DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
+ DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
Removing from namelist anyway.\n", nmb_namestr(fail_name)));
- /* Do it anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
-
- /* Now reset the workgroup and server state. */
- reset_workgroup_state( subrec, fail_name->name, force_new_election );
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", fail_name->name );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
+ /* Do it anyway. */
+ namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
+ if(namerec)
+ remove_name_from_namelist(subrec, namerec);
+
+ /* Now reset the workgroup and server state. */
+ pull_ascii_nstring(failname, fail_name->name);
+ reset_workgroup_state( subrec, failname, force_new_election );
+
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname() );
+ dbgtext( "has stopped being a local master browser " );
+ dbgtext( "for workgroup %s ", failname );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
}
/*******************************************************************
Utility function to remove the WORKGROUP<1d> name.
******************************************************************/
-static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
+static void release_1d_name( struct subnet_record *subrec, const char *workgroup_name,
BOOL force_new_election)
{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, workgroup_name, 0x1d);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
- {
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(BOOL);
-
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0,("release_1d_name: malloc fail.\n"));
- return;
- }
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(BOOL);
- memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
-
- release_name(subrec, namerec,
- unbecome_local_master_success,
- unbecome_local_master_fail,
- userdata);
-
- zero_free(userdata, size);
- }
+ struct nmb_name nmbname;
+ struct name_record *namerec;
+
+ make_nmb_name(&nmbname, workgroup_name, 0x1d);
+ if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
+ struct userdata_struct *userdata;
+ size_t size = sizeof(struct userdata_struct) + sizeof(BOOL);
+
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
+ DEBUG(0,("release_1d_name: malloc fail.\n"));
+ return;
+ }
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(BOOL);
+ memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
+
+ release_name(subrec, namerec,
+ unbecome_local_master_success,
+ unbecome_local_master_fail,
+ userdata);
+
+ zero_free(userdata, size);
+ }
}
/*******************************************************************
@@ -238,11 +234,11 @@ static void release_msbrowse_name_success(struct subnet_record *subrec,
struct nmb_name *released_name,
struct in_addr released_ip)
{
- DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
- nmb_namestr(released_name), subrec->subnet_name ));
+ DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
+ nmb_namestr(released_name), subrec->subnet_name ));
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, released_name);
+ /* Remove the permanent MSBROWSE name added into the unicast subnet. */
+ remove_permanent_name_from_unicast( subrec, released_name);
}
/*******************************************************************
@@ -253,18 +249,18 @@ static void release_msbrowse_name_fail( struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
- nmb_namestr(fail_name), subrec->subnet_name ));
+ DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
+ nmb_namestr(fail_name), subrec->subnet_name ));
- /* Release the name anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
+ /* Release the name anyway. */
+ namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
+ if(namerec)
+ remove_name_from_namelist(subrec, namerec);
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, fail_name);
+ /* Remove the permanent MSBROWSE name added into the unicast subnet. */
+ remove_permanent_name_from_unicast( subrec, fail_name);
}
/*******************************************************************
@@ -275,50 +271,48 @@ static void release_msbrowse_name_fail( struct subnet_record *subrec,
void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
BOOL force_new_election)
{
- struct name_record *namerec;
- struct nmb_name nmbname;
+ struct name_record *namerec;
+ struct nmb_name nmbname;
/* Sanity check. */
- DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
+ DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
on subnet %s\n",work->work_group, subrec->subnet_name));
- if(find_server_in_workgroup( work, global_myname()) == NULL)
- {
- DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
+ if(find_server_in_workgroup( work, global_myname()) == NULL) {
+ DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname(), work->work_group, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- /* Set the state to unbecoming. */
- work->mst_state = MST_UNBECOMING_MASTER;
-
- /*
- * Release the WORKGROUP<1d> name asap to allow another machine to
- * claim it.
- */
-
- release_1d_name( subrec, work->work_group, force_new_election);
-
- /* Deregister any browser names we may have. */
- make_nmb_name(&nmbname, MSBROWSE, 0x1);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
- {
- release_name(subrec, namerec,
- release_msbrowse_name_success,
- release_msbrowse_name_fail,
- NULL);
- }
-
- /*
- * Ensure we have sent and processed these release packets
- * before returning - we don't want to process any election
- * packets before dealing with the 1d release.
- */
-
- retransmit_or_expire_response_records(time(NULL));
+ /* Set the state to unbecoming. */
+ work->mst_state = MST_UNBECOMING_MASTER;
+
+ /*
+ * Release the WORKGROUP<1d> name asap to allow another machine to
+ * claim it.
+ */
+
+ release_1d_name( subrec, work->work_group, force_new_election);
+
+ /* Deregister any browser names we may have. */
+ make_nmb_name(&nmbname, MSBROWSE, 0x1);
+ if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
+ release_name(subrec, namerec,
+ release_msbrowse_name_success,
+ release_msbrowse_name_fail,
+ NULL);
+ }
+
+ /*
+ * Ensure we have sent and processed these release packets
+ * before returning - we don't want to process any election
+ * packets before dealing with the 1d release.
+ */
+
+ retransmit_or_expire_response_records(time(NULL));
}
/****************************************************************************
@@ -332,104 +326,107 @@ static void become_local_master_stage2(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- int i = 0;
- struct server_record *sl;
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_local_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
+ int i = 0;
+ struct server_record *sl;
+ struct work_record *work;
+ struct server_record *servrec;
+ nstring regname;
+
+ pull_ascii_nstring(regname, registered_name->name);
+ work = find_workgroup_on_subnet( subrec, regname);
+
+ if(!work) {
+ DEBUG(0,("become_local_master_stage2: Error - cannot find \
+workgroup %s on subnet %s\n", regname, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), registered_name->name, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname(), regname, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
+ DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
on subnet %s\n", work->work_group, subrec->subnet_name));
- work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
-
- /* update our server status */
- servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
- servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /* Add this name to the workgroup as local master browser. */
- set_workgroup_local_master_browser_name( work, global_myname());
-
- /* Count the number of servers we have on our list. If it's
- less than 10 (just a heuristic) request the servers
- to announce themselves.
- */
- for( sl = work->serverlist; sl != NULL; sl = sl->next)
- i++;
-
- if (i < 10)
- {
- /* Ask all servers on our local net to announce to us. */
- broadcast_announce_request(subrec, work);
- }
-
- /*
- * Now we are a local master on a broadcast subnet, we need to add
- * the WORKGROUP<1d> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We can create this name directly on
- * the unicast subnet as a WINS server always returns true when registering
- * this name, and discards the registration. We use the number of IP
- * addresses registered to this name as a reference count, as we
- * remove this broadcast subnet IP address from it when we stop becoming a local
- * master browser for this broadcast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Reset the announce master browser timer so that we try and tell a domain
- master browser as soon as possible that we are a local master browser. */
- reset_announce_timer();
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "is now a local master browser " );
- dbgtext( "for workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
+ work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
+
+ /* update our server status */
+ servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
+ servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ /* Add this name to the workgroup as local master browser. */
+ set_workgroup_local_master_browser_name( work, global_myname());
+
+ /* Count the number of servers we have on our list. If it's
+ less than 10 (just a heuristic) request the servers
+ to announce themselves.
+ */
+ for( sl = work->serverlist; sl != NULL; sl = sl->next)
+ i++;
+
+ if (i < 10) {
+ /* Ask all servers on our local net to announce to us. */
+ broadcast_announce_request(subrec, work);
+ }
+
+ /*
+ * Now we are a local master on a broadcast subnet, we need to add
+ * the WORKGROUP<1d> name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. We can create this name directly on
+ * the unicast subnet as a WINS server always returns true when registering
+ * this name, and discards the registration. We use the number of IP
+ * addresses registered to this name as a reference count, as we
+ * remove this broadcast subnet IP address from it when we stop becoming a local
+ * master browser for this broadcast subnet.
+ */
+
+ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
+
+ /* Reset the announce master browser timer so that we try and tell a domain
+ master browser as soon as possible that we are a local master browser. */
+ reset_announce_timer();
+
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname() );
+ dbgtext( "is now a local master browser " );
+ dbgtext( "for workgroup %s ", work->work_group );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
}
/****************************************************************************
Failed to register the WORKGROUP<1d> name.
****************************************************************************/
+
static void become_local_master_fail2(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
+ nstring failname;
+ struct work_record *work;
- DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
+ DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
- if(!work)
- {
- DEBUG(0,("become_local_master_fail2: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
+ pull_ascii_nstring(failname, fail_name->name);
+ work = find_workgroup_on_subnet( subrec, failname);
- /* Roll back all the way by calling unbecome_local_master_browser(). */
- unbecome_local_master_browser(subrec, work, False);
+ if(!work) {
+ DEBUG(0,("become_local_master_fail2: Error - cannot find \
+workgroup %s on subnet %s\n", failname, subrec->subnet_name));
+ return;
+ }
+
+ /* Roll back all the way by calling unbecome_local_master_browser(). */
+ unbecome_local_master_browser(subrec, work, False);
}
/****************************************************************************
@@ -442,35 +439,34 @@ static void become_local_master_stage1(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- char *work_name = userdata->data;
- struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
-
- if(!work)
- {
- DEBUG(0,("become_local_master_stage1: Error - cannot find \
-workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
- work->work_group));
-
- work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
-
- /*
- * We registered the MSBROWSE name on a broadcast subnet, now need to add
- * the MSBROWSE name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We create this name directly on
- * the unicast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Attempt to register the WORKGROUP<1d> name. */
- register_name(subrec, work->work_group,0x1d,samba_nb_type,
- become_local_master_stage2,
- become_local_master_fail2,
- NULL);
+ char *work_name = userdata->data;
+ struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
+
+ if(!work) {
+ DEBUG(0,("become_local_master_stage1: Error - cannot find \
+ %s on subnet %s\n", work_name, subrec->subnet_name));
+ return;
+ }
+
+ DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
+ work->work_group));
+
+ work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
+
+ /*
+ * We registered the MSBROWSE name on a broadcast subnet, now need to add
+ * the MSBROWSE name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. We create this name directly on
+ * the unicast subnet.
+ */
+
+ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
+
+ /* Attempt to register the WORKGROUP<1d> name. */
+ register_name(subrec, work->work_group,0x1d,samba_nb_type,
+ become_local_master_stage2,
+ become_local_master_fail2,
+ NULL);
}
/****************************************************************************
@@ -481,29 +477,27 @@ static void become_local_master_fail1(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- char *work_name = rrec->userdata->data;
- struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
+ char *work_name = rrec->userdata->data;
+ struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
- if(!work)
- {
- DEBUG(0,("become_local_master_fail1: Error - cannot find \
+ if(!work) {
+ DEBUG(0,("become_local_master_fail1: Error - cannot find \
workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
+ return;
+ }
- if(find_server_in_workgroup(work, global_myname()) == NULL)
- {
- DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
+ if(find_server_in_workgroup(work, global_myname()) == NULL) {
+ DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname(), work->work_group, subrec->subnet_name));
+ return;
+ }
- reset_workgroup_state( subrec, work->work_group, False );
+ reset_workgroup_state( subrec, work->work_group, False );
- DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
+ DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
/******************************************************************
@@ -517,61 +511,57 @@ workgroup %s on subnet %s. Couldn't register name %s.\n",
void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
{
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
-
- /* Sanity check. */
- if (!lp_local_master())
- {
- DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
- return;
- }
-
- if(!AM_POTENTIAL_MASTER_BROWSER(work))
- {
- DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
- work->mst_state ));
- return;
- }
-
- if(find_server_in_workgroup( work, global_myname()) == NULL)
- {
- DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
+ struct userdata_struct *userdata;
+ size_t size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
+
+ /* Sanity check. */
+ if (!lp_local_master()) {
+ DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
+ return;
+ }
+
+ if(!AM_POTENTIAL_MASTER_BROWSER(work)) {
+ DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
+ work->mst_state ));
+ return;
+ }
+
+ if(find_server_in_workgroup( work, global_myname()) == NULL) {
+ DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname(), work->work_group, subrec->subnet_name));
+ return;
+ }
- DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
+ DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
%s on subnet %s\n", work->work_group, subrec->subnet_name));
- DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
- work->mst_state = MST_BACKUP; /* an election win was successful */
+ DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
+ work->mst_state = MST_BACKUP; /* an election win was successful */
- work->ElectionCriterion |= 0x5;
+ work->ElectionCriterion |= 0x5;
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- /* Setup the userdata_struct. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0,("become_local_master_browser: malloc fail.\n"));
- return;
- }
+ /* Setup the userdata_struct. */
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
+ DEBUG(0,("become_local_master_browser: malloc fail.\n"));
+ return;
+ }
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = strlen(work->work_group)+1;
+ overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
- /* Register the special browser group name. */
- register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
- become_local_master_stage1,
- become_local_master_fail1,
- userdata);
+ /* Register the special browser group name. */
+ register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
+ become_local_master_stage1,
+ become_local_master_fail1,
+ userdata);
- zero_free(userdata, size);
+ zero_free(userdata, size);
}
/***************************************************************
@@ -583,7 +573,7 @@ in workgroup %s on subnet %s\n",
void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname)
{
- DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
+ DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
for workgroup %s.\n", newname, work->work_group ));
#if 0
@@ -600,5 +590,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n",
}
#endif
- fstrcpy(work->local_master_browser_name, newname);
+ fstrcpy(work->local_master_browser_name, newname);
}
diff --git a/source3/nmbd/nmbd_browserdb.c b/source3/nmbd/nmbd_browserdb.c
index 4a302ddfd4..83dfba66e9 100644
--- a/source3/nmbd/nmbd_browserdb.c
+++ b/source3/nmbd/nmbd_browserdb.c
@@ -80,8 +80,8 @@ void update_browser_death_time( struct browse_cache_record *browc )
*
* ************************************************************************** **
*/
-struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
- char *browser_name,
+struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name,
+ const char *browser_name,
struct in_addr ip )
{
struct browse_cache_record *browc;
@@ -134,7 +134,7 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
*
* ************************************************************************** **
*/
-struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name )
+struct browse_cache_record *find_browser_in_lmb_cache( const char *browser_name )
{
struct browse_cache_record *browc;
diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c
index 26d4735744..95e542354f 100644
--- a/source3/nmbd/nmbd_browsesync.c
+++ b/source3/nmbd/nmbd_browsesync.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-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
@@ -29,74 +29,70 @@ extern ubi_dlList lmb_browserlist[];
/****************************************************************************
As a domain master browser, do a sync with a local master browser.
**************************************************************************/
+
static void sync_with_lmb(struct browse_cache_record *browc)
{
- struct work_record *work;
-
- if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Failed to get a workgroup for a local master browser " );
- dbgtext( "cache entry workgroup " );
- dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
- }
- return;
- }
+ struct work_record *work;
- /* We should only be doing this if we are a domain master browser for
- the given workgroup. Ensure this is so. */
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "We are trying to sync with a local master browser " );
- dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
- dbgtext( "and we are not a domain master browser on this workgroup.\n" );
- dbgtext( "Error!\n" );
- }
- return;
- }
+ if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) ) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "Failed to get a workgroup for a local master browser " );
+ dbgtext( "cache entry workgroup " );
+ dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
+ }
+ return;
+ }
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Initiating sync with local master browser " );
- dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
- dbgtext( "for workgroup %s\n", browc->work_group );
- }
+ /* We should only be doing this if we are a domain master browser for
+ the given workgroup. Ensure this is so. */
- sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
+ if(!AM_DOMAIN_MASTER_BROWSER(work)) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "We are trying to sync with a local master browser " );
+ dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
+ dbgtext( "and we are not a domain master browser on this workgroup.\n" );
+ dbgtext( "Error!\n" );
+ }
+ return;
+ }
+
+ if( DEBUGLVL( 2 ) ) {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "Initiating sync with local master browser " );
+ dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
+ dbgtext( "for workgroup %s\n", browc->work_group );
+ }
+
+ sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
- browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
+ browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
}
/****************************************************************************
Sync or expire any local master browsers.
**************************************************************************/
+
void dmb_expire_and_sync_browser_lists(time_t t)
{
- static time_t last_run = 0;
- struct browse_cache_record *browc;
+ static time_t last_run = 0;
+ struct browse_cache_record *browc;
- /* Only do this every 20 seconds. */
- if (t - last_run < 20)
- return;
+ /* Only do this every 20 seconds. */
+ if (t - last_run < 20)
+ return;
- last_run = t;
+ last_run = t;
- expire_lmb_browsers(t);
+ expire_lmb_browsers(t);
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
- {
- if (browc->sync_time < t)
- sync_with_lmb(browc);
- }
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc;
+ browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) {
+ if (browc->sync_time < t)
+ sync_with_lmb(browc);
+ }
}
/****************************************************************************
@@ -105,46 +101,43 @@ As a local master browser, send an announce packet to the domain master browser.
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
{
- pstring outbuf;
- fstring myname;
- char *p;
-
- if(ismyip(work->dmb_addr))
- {
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "We are both a domain and a local master browser for " );
- dbgtext( "workgroup %s. ", work->work_group );
- dbgtext( "Do not announce to ourselves.\n" );
- }
- return;
- }
+ pstring outbuf;
+ fstring myname;
+ char *p;
+
+ if(ismyip(work->dmb_addr)) {
+ if( DEBUGLVL( 2 ) ) {
+ dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
+ dbgtext( "We are both a domain and a local master browser for " );
+ dbgtext( "workgroup %s. ", work->work_group );
+ dbgtext( "Do not announce to ourselves.\n" );
+ }
+ return;
+ }
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_MasterAnnouncement);
+ p++;
- fstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ /* The call below does CH_UNIX -> CH_DOS conversion. JRA */
+ push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(p,1);
- if( DEBUGLVL( 4 ) )
- {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "Sending local master announce to " );
- dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
- work->work_group );
- }
+ if( DEBUGLVL( 4 ) ) {
+ dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
+ dbgtext( "Sending local master announce to " );
+ dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
+ work->work_group );
+ }
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
global_myname(), 0x0, work->dmb_name.name, 0x0,
work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
-
}
/****************************************************************************
@@ -153,17 +146,19 @@ As a local master browser, do a sync with a domain master browser.
static void sync_with_dmb(struct work_record *work)
{
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "sync_with_dmb:\n" );
- dbgtext( "Initiating sync with domain master browser " );
- dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
- dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
- dbgtext( "for workgroup %s\n", work->work_group );
- }
+ nstring dmb_name;
+
+ if( DEBUGLVL( 2 ) ) {
+ dbgtext( "sync_with_dmb:\n" );
+ dbgtext( "Initiating sync with domain master browser " );
+ dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
+ dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
+ dbgtext( "for workgroup %s\n", work->work_group );
+ }
- sync_browse_lists(work, work->dmb_name.name, work->dmb_name.name_type,
- work->dmb_addr, False, True);
+ pull_ascii_nstring(dmb_name, work->dmb_name.name);
+ sync_browse_lists(work, dmb_name, work->dmb_name.name_type,
+ work->dmb_addr, False, True);
}
/****************************************************************************
@@ -175,78 +170,69 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
struct res_rec *answers,
struct in_addr from_ip)
{
- struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
-
- if( work == NULL )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Unable to find workgroup " );
- dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
- }
- return;
- }
+ struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Success in node status for workgroup " );
- dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
- }
+ if( work == NULL ) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Unable to find workgroup " );
+ dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
+ }
+ return;
+ }
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Success in node status for workgroup " );
+ dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
+ }
/* Go through the list of names found at answers->rdata and look for
the first SERVER<0x20> name. */
- if(answers->rdata != NULL)
- {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
+ if(answers->rdata != NULL) {
+ char *p = answers->rdata;
+ int numnames = CVAL(p, 0);
- p += 1;
+ p += 1;
- while (numnames--)
- {
- char qname[17];
- uint16 nb_flags;
- int name_type;
+ while (numnames--) {
+ nstring qname;
+ uint16 nb_flags;
+ int name_type;
- StrnCpy(qname,p,15);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_string(qname,NULL," ");
+ pull_ascii_nstring(qname, p);
+ name_type = CVAL(p,15);
+ nb_flags = get_nb_flags(&p[16]);
+ trim_string(qname,NULL," ");
- p += 18;
+ p += 18;
- if(!(nb_flags & NB_GROUP) && (name_type == 0x20))
- {
- struct nmb_name nmbname;
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) {
+ struct nmb_name nmbname;
- make_nmb_name(&nmbname, qname, name_type);
+ make_nmb_name(&nmbname, qname, name_type);
- /* Copy the dmb name and IP address
- into the workgroup struct. */
+ /* Copy the dmb name and IP address
+ into the workgroup struct. */
- work->dmb_name = nmbname;
- putip((char *)&work->dmb_addr, &from_ip);
+ work->dmb_name = nmbname;
+ putip((char *)&work->dmb_addr, &from_ip);
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
+ /* Do the local master browser announcement to the domain
+ master browser name and IP. */
+ announce_local_master_browser_to_domain_master_browser( work );
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- break;
- }
- }
- }
- else
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
+ /* Now synchronise lists with the domain master browser. */
+ sync_with_dmb(work);
+ break;
+ }
+ }
+ } else if( DEBUGLVL( 0 ) ) {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
+ dbgtext( "%s.\n", inet_ntoa(from_ip) );
+ }
}
/****************************************************************************
@@ -256,16 +242,15 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
static void domain_master_node_status_fail(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct userdata_struct *userdata = rrec->userdata;
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser\n" );
- dbgtext( "for workgroup %s ", userdata ? userdata->data : "NULL" );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot sync browser lists.\n" );
- }
+ struct userdata_struct *userdata = rrec->userdata;
+
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "domain_master_node_status_fail:\n" );
+ dbgtext( "Doing a node status request to the domain master browser\n" );
+ dbgtext( "for workgroup %s ", userdata ? userdata->data : "NULL" );
+ dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
+ dbgtext( "Cannot sync browser lists.\n" );
+ }
}
/****************************************************************************
@@ -276,100 +261,99 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
struct userdata_struct *userdata_in,
struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
{
- /*
- * Unfortunately, finding the IP address of the Domain Master Browser,
- * as we have here, is not enough. We need to now do a sync to the
- * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
- * respond to the SMBSERVER name. To get this name from IP
- * address we do a Node status request, and look for the first
- * NAME<0x20> in the response, and take that as the server name.
- * We also keep a cache of the Domain Master Browser name for this
- * workgroup in the Workgroup struct, so that if the same IP addess
- * is returned every time, we don't need to do the node status
- * request.
- */
-
- struct work_record *work;
- struct nmb_name nmbname;
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
-
- if( !(work = find_workgroup_on_subnet(subrec, q_name->name)) )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "find_domain_master_name_query_success:\n" );
- dbgtext( "Failed to find workgroup %s\n", q_name->name );
- }
- return;
+ /*
+ * Unfortunately, finding the IP address of the Domain Master Browser,
+ * as we have here, is not enough. We need to now do a sync to the
+ * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
+ * respond to the SMBSERVER name. To get this name from IP
+ * address we do a Node status request, and look for the first
+ * NAME<0x20> in the response, and take that as the server name.
+ * We also keep a cache of the Domain Master Browser name for this
+ * workgroup in the Workgroup struct, so that if the same IP addess
+ * is returned every time, we don't need to do the node status
+ * request.
+ */
+
+ struct work_record *work;
+ struct nmb_name nmbname;
+ struct userdata_struct *userdata;
+ size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
+ nstring qname;
+
+ pull_ascii_nstring(qname, q_name->name);
+ if( !(work = find_workgroup_on_subnet(subrec, qname)) ) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "find_domain_master_name_query_success:\n" );
+ dbgtext( "Failed to find workgroup %s\n", qname);
+ }
+ return;
}
/* First check if we already have a dmb for this workgroup. */
- if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip))
- {
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
+ if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+ /* Do the local master browser announcement to the domain
+ master browser name and IP. */
+ announce_local_master_browser_to_domain_master_browser( work );
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- return;
- }
- else
- zero_ip(&work->dmb_addr);
-
- /* Now initiate the node status request. */
-
- /* We used to use the name "*",0x0 here, but some Windows
- * servers don't answer that name. However we *know* they
- * have the name workgroup#1b (as we just looked it up).
- * So do the node status request on this name instead.
- * Found at LBL labs. JRA.
- */
-
- make_nmb_name(&nmbname,work->work_group,0x1b);
-
- /* Put the workgroup name into the userdata so we know
- what workgroup we're talking to when the reply comes
- back. */
-
- /* Setup the userdata_struct - this is copied so we can use
- a stack variable for this. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
- return;
- }
+ /* Now synchronise lists with the domain master browser. */
+ sync_with_dmb(work);
+ return;
+ } else {
+ zero_ip(&work->dmb_addr);
+ }
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ /* Now initiate the node status request. */
- node_status( subrec, &nmbname, answer_ip,
- domain_master_node_status_success,
- domain_master_node_status_fail,
- userdata);
+ /* We used to use the name "*",0x0 here, but some Windows
+ * servers don't answer that name. However we *know* they
+ * have the name workgroup#1b (as we just looked it up).
+ * So do the node status request on this name instead.
+ * Found at LBL labs. JRA.
+ */
- zero_free(userdata, size);
+ make_nmb_name(&nmbname,work->work_group,0x1b);
+
+ /* Put the workgroup name into the userdata so we know
+ what workgroup we're talking to when the reply comes
+ back. */
+
+ /* Setup the userdata_struct - this is copied so we can use
+ a stack variable for this. */
+
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
+ DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
+ return;
+ }
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = strlen(work->work_group)+1;
+ overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+
+ node_status( subrec, &nmbname, answer_ip,
+ domain_master_node_status_success,
+ domain_master_node_status_fail,
+ userdata);
+
+ zero_free(userdata, size);
}
/****************************************************************************
Function called when a query for a WORKGROUP<1b> name fails.
****************************************************************************/
+
static void find_domain_master_name_query_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "Unable to find the Domain Master Browser name " );
- dbgtext( "%s for the workgroup %s.\n",
- nmb_namestr(question_name), question_name->name );
- dbgtext( "Unable to sync browse lists in this workgroup.\n" );
- }
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "find_domain_master_name_query_fail:\n" );
+ dbgtext( "Unable to find the Domain Master Browser name " );
+ dbgtext( "%s for the workgroup %s.\n",
+ nmb_namestr(question_name), question_name->name );
+ dbgtext( "Unable to sync browse lists in this workgroup.\n" );
+ }
}
/****************************************************************************
@@ -381,27 +365,20 @@ full domain browse lists from it onto the given subnet.
void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
struct work_record *work)
{
- struct nmb_name nmbname;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- {
- if( DEBUGLVL( 10 ) )
- {
- dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
- dbgtext( "Ignoring, as we are not a WINS client.\n" );
- }
- return;
- }
-
- make_nmb_name(&nmbname,work->work_group,0x1b);
+ /* Only do this if we are using a WINS server. */
+ if(we_are_a_wins_client() == False) {
+ if( DEBUGLVL( 10 ) ) {
+ dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
+ dbgtext( "Ignoring, as we are not a WINS client.\n" );
+ }
+ return;
+ }
- /* First, query for the WORKGROUP<1b> name from the WINS server. */
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
+ /* First, query for the WORKGROUP<1b> name from the WINS server. */
+ query_name(unicast_subnet, work->work_group, 0x1b,
find_domain_master_name_query_success,
find_domain_master_name_query_fail,
NULL);
-
}
/****************************************************************************
@@ -421,89 +398,81 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
struct res_rec *answers,
struct in_addr from_ip)
{
- struct work_record *work;
- fstring server_name;
+ struct work_record *work;
+ fstring server_name;
- server_name[0] = 0;
+ server_name[0] = 0;
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
- }
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
+ }
- /*
- * Go through the list of names found at answers->rdata and look for
- * the first WORKGROUP<0x1b> name.
- */
-
- if(answers->rdata != NULL)
- {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
-
- p += 1;
-
- while (numnames--)
- {
- char qname[17];
- uint16 nb_flags;
- int name_type;
-
- StrnCpy(qname,p,15);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_string(qname,NULL," ");
-
- p += 18;
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
- server_name[0] == 0) {
- /* this is almost certainly the server netbios name */
- fstrcpy(server_name, qname);
- continue;
- }
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x1b))
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
- dbgtext( "is a domain master browser for workgroup " );
- dbgtext( "%s. Adding this name.\n", qname );
- }
-
- /*
- * If we don't already know about this workgroup, add it
- * to the workgroup list on the unicast_subnet.
- */
- if((work = find_workgroup_on_subnet( subrec, qname)) == NULL)
- {
- struct nmb_name nmbname;
- /*
- * Add it - with an hour in the cache.
- */
- if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
- return;
-
- /* remember who the master is */
- fstrcpy(work->local_master_browser_name, server_name);
- make_nmb_name(&nmbname, server_name, 0x20);
- work->dmb_name = nmbname;
- work->dmb_addr = from_ip;
- }
- break;
- }
- }
- }
- else
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
+ /*
+ * Go through the list of names found at answers->rdata and look for
+ * the first WORKGROUP<0x1b> name.
+ */
+
+ if(answers->rdata != NULL) {
+ char *p = answers->rdata;
+ int numnames = CVAL(p, 0);
+
+ p += 1;
+
+ while (numnames--) {
+ nstring qname;
+ uint16 nb_flags;
+ int name_type;
+
+ pull_ascii_nstring(qname, p);
+ name_type = CVAL(p,15);
+ nb_flags = get_nb_flags(&p[16]);
+ trim_string(qname,NULL," ");
+
+ p += 18;
+
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
+ server_name[0] == 0) {
+ /* this is almost certainly the server netbios name */
+ fstrcpy(server_name, qname);
+ continue;
+ }
+
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) {
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
+ dbgtext( "is a domain master browser for workgroup " );
+ dbgtext( "%s. Adding this name.\n", qname );
+ }
+
+ /*
+ * If we don't already know about this workgroup, add it
+ * to the workgroup list on the unicast_subnet.
+ */
+
+ if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) {
+ struct nmb_name nmbname;
+ /*
+ * Add it - with an hour in the cache.
+ */
+ if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
+ return;
+
+ /* remember who the master is */
+ fstrcpy(work->local_master_browser_name, server_name);
+ make_nmb_name(&nmbname, server_name, 0x20);
+ work->dmb_name = nmbname;
+ work->dmb_addr = from_ip;
+ }
+ break;
+ }
+ }
+ } else if( DEBUGLVL( 0 ) ) {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
+ dbgtext( "%s.\n", inet_ntoa(from_ip) );
+ }
}
/****************************************************************************
@@ -513,13 +482,12 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
struct response_record *rrec)
{
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "get_domain_master_name_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser " );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot get workgroup name.\n" );
- }
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "get_domain_master_name_node_status_fail:\n" );
+ dbgtext( "Doing a node status request to the domain master browser " );
+ dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
+ dbgtext( "Cannot get workgroup name.\n" );
+ }
}
/****************************************************************************
@@ -530,58 +498,53 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
struct userdata_struct *userdata_in,
struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
{
- /*
- * We now have a list of all the domain master browsers for all workgroups
- * that have registered with the WINS server. Now do a node status request
- * to each one and look for the first 1b name in the reply. This will be
- * the workgroup name that we will add to the unicast subnet as a 'non-local'
- * workgroup.
- */
-
- struct nmb_name nmbname;
- struct in_addr send_ip;
- int i;
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
- dbgtext( "IP addresses for Domain Master Browsers.\n" );
- }
+ /*
+ * We now have a list of all the domain master browsers for all workgroups
+ * that have registered with the WINS server. Now do a node status request
+ * to each one and look for the first 1b name in the reply. This will be
+ * the workgroup name that we will add to the unicast subnet as a 'non-local'
+ * workgroup.
+ */
+
+ struct nmb_name nmbname;
+ struct in_addr send_ip;
+ int i;
+
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "find_all_domain_master_names_query_succes:\n" );
+ dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
+ dbgtext( "IP addresses for Domain Master Browsers.\n" );
+ }
- for(i = 0; i < rrec->rdlength / 6; i++)
- {
- /* Initiate the node status requests. */
- make_nmb_name(&nmbname, "*", 0);
-
- putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
-
- /*
- * Don't send node status requests to ourself.
- */
-
- if(ismyip( send_ip ))
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Not sending node status to our own IP " );
- dbgtext( "%s.\n", inet_ntoa(send_ip) );
- }
- continue;
- }
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_success:\n" );
- dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
- }
-
- node_status( subrec, &nmbname, send_ip,
- get_domain_master_name_node_status_success,
- get_domain_master_name_node_status_fail,
- NULL);
- }
+ for(i = 0; i < rrec->rdlength / 6; i++) {
+ /* Initiate the node status requests. */
+ make_nmb_name(&nmbname, "*", 0);
+
+ putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
+
+ /*
+ * Don't send node status requests to ourself.
+ */
+
+ if(ismyip( send_ip )) {
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "find_all_domain_master_names_query_succes:\n" );
+ dbgtext( "Not sending node status to our own IP " );
+ dbgtext( "%s.\n", inet_ntoa(send_ip) );
+ }
+ continue;
+ }
+
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "find_all_domain_master_names_query_success:\n" );
+ dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
+ }
+
+ node_status( subrec, &nmbname, send_ip,
+ get_domain_master_name_node_status_success,
+ get_domain_master_name_node_status_fail,
+ NULL);
+ }
}
/****************************************************************************
@@ -591,13 +554,12 @@ static void find_all_domain_master_names_query_fail(struct subnet_record *subrec
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- if( DEBUGLVL( 10 ) )
- {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "WINS server did not reply to a query for name " );
- dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
- dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
- }
+ if( DEBUGLVL( 10 ) ) {
+ dbgtext( "find_domain_master_name_query_fail:\n" );
+ dbgtext( "WINS server did not reply to a query for name " );
+ dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
+ dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
+ }
}
/****************************************************************************
@@ -608,43 +570,39 @@ static void find_all_domain_master_names_query_fail(struct subnet_record *subrec
<1b> name in the reply - this is the workgroup name. Add this to the unicast
subnet. This is expensive, so we only do this every 15 minutes.
**************************************************************************/
+
void collect_all_workgroup_names_from_wins_server(time_t t)
{
- static time_t lastrun = 0;
- struct work_record *work;
- struct nmb_name nmbname;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- return;
-
- /* Check to see if we are a domain master browser on the unicast subnet. */
- if((work = find_workgroup_on_subnet( unicast_subnet, lp_workgroup())) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
- dbgtext( "Cannot find my workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
- }
- return;
- }
+ static time_t lastrun = 0;
+ struct work_record *work;
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- return;
+ /* Only do this if we are using a WINS server. */
+ if(we_are_a_wins_client() == False)
+ return;
- if ((lastrun != 0) && (t < lastrun + (15 * 60)))
- return;
-
- lastrun = t;
+ /* Check to see if we are a domain master browser on the unicast subnet. */
+ if((work = find_workgroup_on_subnet( unicast_subnet, lp_workgroup())) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
+ dbgtext( "Cannot find my workgroup %s ", lp_workgroup() );
+ dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
+ }
+ return;
+ }
+
+ if(!AM_DOMAIN_MASTER_BROWSER(work))
+ return;
- make_nmb_name(&nmbname,"*",0x1b);
+ if ((lastrun != 0) && (t < lastrun + (15 * 60)))
+ return;
+
+ lastrun = t;
- /* First, query for the *<1b> name from the WINS server. */
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
- find_all_domain_master_names_query_success,
- find_all_domain_master_names_query_fail,
- NULL);
+ /* First, query for the *<1b> name from the WINS server. */
+ query_name(unicast_subnet, "*", 0x1b,
+ find_all_domain_master_names_query_success,
+ find_all_domain_master_names_query_fail,
+ NULL);
}
@@ -656,6 +614,7 @@ To prevent exponential network traffic with large numbers of workgroups
we use a randomised system where sync probability is inversely proportional
to the number of known workgroups
**************************************************************************/
+
void sync_all_dmbs(time_t t)
{
static time_t lastrun = 0;
@@ -669,7 +628,8 @@ void sync_all_dmbs(time_t t)
/* Check to see if we are a domain master browser on the
unicast subnet. */
work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup());
- if (!work) return;
+ if (!work)
+ return;
if (!AM_DOMAIN_MASTER_BROWSER(work))
return;
@@ -687,7 +647,10 @@ void sync_all_dmbs(time_t t)
/* sync with a probability of 1/count */
for (work=unicast_subnet->workgrouplist; work; work = work->next) {
if (strcmp(lp_workgroup(), work->work_group)) {
- if (((unsigned)sys_random()) % count != 0) continue;
+ nstring dmb_name;
+
+ if (((unsigned)sys_random()) % count != 0)
+ continue;
lastrun = t;
@@ -699,13 +662,15 @@ void sync_all_dmbs(time_t t)
0x20);
}
+ pull_ascii_nstring(dmb_name, work->dmb_name.name);
+
DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
- work->dmb_name.name,
- inet_ntoa(work->dmb_addr)));
+ dmb_name, inet_ntoa(work->dmb_addr)));
+
sync_browse_lists(work,
- work->dmb_name.name,
+ dmb_name,
work->dmb_name.name_type,
work->dmb_addr, False, False);
}
}
-}
+}
diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c
index b948eb9d04..09ab9ee783 100644
--- a/source3/nmbd/nmbd_elections.c
+++ b/source3/nmbd/nmbd_elections.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-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
@@ -29,32 +29,35 @@ extern time_t StartupTime;
/****************************************************************************
Send an election datagram packet.
**************************************************************************/
+
static void send_election_dgram(struct subnet_record *subrec, const char *workgroup_name,
uint32 criterion, int timeup,const char *server_name)
{
- pstring outbuf;
- char *p;
-
- DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name ));
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_Election); /* Election opcode. */
- p++;
-
- SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
- SIVAL(p,1,criterion);
- SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
- p += 13;
- pstrcpy_base(p, server_name, outbuf);
- strupper_m(p);
- p = skip_string(p,1);
+ pstring outbuf;
+ fstring srv_name;
+ char *p;
+
+ DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
+ workgroup_name, subrec->subnet_name ));
+
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_Election); /* Election opcode. */
+ p++;
+
+ SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
+ SIVAL(p,1,criterion);
+ SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
+ p += 13;
+ fstrcpy(srv_name, server_name);
+ strupper_m(srv_name);
+ pstrcpy_base(p, srv_name, outbuf);
+ p = skip_string(p,1);
- send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- global_myname(), 0,
- workgroup_name, 0x1e,
- subrec->bcast_ip, subrec->myip, DGRAM_PORT);
+ send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ global_myname(), 0,
+ workgroup_name, 0x1e,
+ subrec->bcast_ip, subrec->myip, DGRAM_PORT);
}
/*******************************************************************
@@ -66,8 +69,10 @@ static void check_for_master_browser_success(struct subnet_record *subrec,
struct nmb_name *answer_name,
struct in_addr answer_ip, struct res_rec *rrec)
{
- DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
-IP %s (just checking).\n", answer_name->name, inet_ntoa(answer_ip) ));
+ nstring aname;
+ pull_ascii_nstring(aname, answer_name->name);
+ DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
+IP %s (just checking).\n", aname, inet_ntoa(answer_ip) ));
}
/*******************************************************************
@@ -79,41 +84,39 @@ static void check_for_master_browser_fail( struct subnet_record *subrec,
struct nmb_name *question_name,
int fail_code)
{
- char *workgroup_name = question_name->name;
- struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
-
- if(work == NULL)
- {
- DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
- workgroup_name, subrec->subnet_name ));
- return;
- }
-
- if (strequal(work->work_group, lp_workgroup()))
- {
-
- if (lp_local_master())
- {
- /* We have discovered that there is no local master
- browser, and we are configured to initiate
- an election that we will participate in.
- */
- DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
- work->work_group, subrec->subnet_name ));
-
- /* Setting this means we will participate when the
- election is run in run_elections(). */
- work->needelection = True;
- }
- else
- {
- /* We need to force an election, because we are configured
- not to become the local master, but we still need one,
- having detected that one doesn't exist.
- */
- send_election_dgram(subrec, work->work_group, 0, 0, "");
- }
- }
+ nstring workgroup_name;
+ struct work_record *work;
+
+ pull_ascii_nstring(workgroup_name,question_name->name);
+
+ work = find_workgroup_on_subnet(subrec, workgroup_name);
+ if(work == NULL) {
+ DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
+ workgroup_name, subrec->subnet_name ));
+ return;
+ }
+
+ if (strequal(work->work_group, lp_workgroup())) {
+
+ if (lp_local_master()) {
+ /* We have discovered that there is no local master
+ browser, and we are configured to initiate
+ an election that we will participate in.
+ */
+ DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
+ work->work_group, subrec->subnet_name ));
+
+ /* Setting this means we will participate when the
+ election is run in run_elections(). */
+ work->needelection = True;
+ } else {
+ /* We need to force an election, because we are configured
+ not to become the local master, but we still need one,
+ having detected that one doesn't exist.
+ */
+ send_election_dgram(subrec, work->work_group, 0, 0, "");
+ }
+ }
}
/*******************************************************************
@@ -123,36 +126,33 @@ static void check_for_master_browser_fail( struct subnet_record *subrec,
void check_master_browser_exists(time_t t)
{
- static time_t lastrun=0;
- struct subnet_record *subrec;
- const char *workgroup_name = lp_workgroup();
-
- if (!lastrun)
- lastrun = t;
-
- if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
- return;
-
- lastrun = t;
-
- dump_workgroups(False);
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work))
- {
- /* Do a name query for the local master browser on this net. */
- query_name( subrec, work->work_group, 0x1d,
- check_for_master_browser_success,
- check_for_master_browser_fail,
- NULL);
- }
- }
- }
+ static time_t lastrun=0;
+ struct subnet_record *subrec;
+ const char *workgroup_name = lp_workgroup();
+
+ if (!lastrun)
+ lastrun = t;
+
+ if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
+ return;
+
+ lastrun = t;
+
+ dump_workgroups(False);
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work;
+
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) {
+ /* Do a name query for the local master browser on this net. */
+ query_name( subrec, work->work_group, 0x1d,
+ check_for_master_browser_success,
+ check_for_master_browser_fail,
+ NULL);
+ }
+ }
+ }
}
/*******************************************************************
@@ -161,56 +161,52 @@ void check_master_browser_exists(time_t t)
void run_elections(time_t t)
{
- static time_t lastime = 0;
+ static time_t lastime = 0;
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- /* Send election packets once every 2 seconds - note */
- if (lastime && (t - lastime < 2))
- return;
+ /* Send election packets once every 2 seconds - note */
+ if (lastime && (t - lastime < 2))
+ return;
- lastime = t;
+ lastime = t;
- START_PROFILE(run_elections);
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (work->RunningElection)
- {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
+ START_PROFILE(run_elections);
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work;
+
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ if (work->RunningElection) {
+ /*
+ * We can only run an election for a workgroup if we have
+ * registered the WORKGROUP<1e> name, as that's the name
+ * we must listen to.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, work->work_group, 0x1e);
+ if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
+ DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
+ continue;
+ }
- send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
- t - StartupTime, global_myname());
+ send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
+ t - StartupTime, global_myname());
- if (work->ElectionCount++ >= 4)
- {
- /* Won election (4 packets were sent out uncontested. */
- DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
-
- work->RunningElection = False;
-
- become_local_master_browser(subrec, work);
- }
- }
- }
- }
- END_PROFILE(run_elections);
+ if (work->ElectionCount++ >= 4) {
+ /* Won election (4 packets were sent out uncontested. */
+ DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+
+ work->RunningElection = False;
+
+ become_local_master_browser(subrec, work);
+ }
+ }
+ }
+ }
+ END_PROFILE(run_elections);
}
/*******************************************************************
@@ -218,44 +214,42 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
******************************************************************/
static BOOL win_election(struct work_record *work, int version,
- uint32 criterion, int timeup, char *server_name)
+ uint32 criterion, int timeup, const char *server_name)
{
- int mytimeup = time(NULL) - StartupTime;
- uint32 mycriterion = work->ElectionCriterion;
-
- /* If local master is false then never win
- in election broadcasts. */
- if(!lp_local_master())
- {
- DEBUG(3,("win_election: Losing election as local master == False\n"));
- return False;
- }
+ int mytimeup = time(NULL) - StartupTime;
+ uint32 mycriterion = work->ElectionCriterion;
+
+ /* If local master is false then never win in election broadcasts. */
+ if(!lp_local_master()) {
+ DEBUG(3,("win_election: Losing election as local master == False\n"));
+ return False;
+ }
- DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
- version, ELECTION_VERSION,
- criterion, mycriterion,
- timeup, mytimeup,
- server_name, global_myname()));
-
- if (version > ELECTION_VERSION)
- return(False);
- if (version < ELECTION_VERSION)
- return(True);
+ DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
+ version, ELECTION_VERSION,
+ criterion, mycriterion,
+ timeup, mytimeup,
+ server_name, global_myname()));
+
+ if (version > ELECTION_VERSION)
+ return(False);
+ if (version < ELECTION_VERSION)
+ return(True);
- if (criterion > mycriterion)
- return(False);
- if (criterion < mycriterion)
- return(True);
-
- if (timeup > mytimeup)
- return(False);
- if (timeup < mytimeup)
- return(True);
-
- if (strcasecmp(global_myname(), server_name) > 0)
- return(False);
+ if (criterion > mycriterion)
+ return(False);
+ if (criterion < mycriterion)
+ return(True);
+
+ if (timeup > mytimeup)
+ return(False);
+ if (timeup < mytimeup)
+ return(True);
+
+ if (strcasecmp(global_myname(), server_name) > 0)
+ return(False);
- return(True);
+ return(True);
}
/*******************************************************************
@@ -264,66 +258,63 @@ static BOOL win_election(struct work_record *work, int version,
void process_election(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int version = CVAL(buf,0);
- uint32 criterion = IVAL(buf,1);
- int timeup = IVAL(buf,5)/1000;
- char *server_name = buf+13;
- struct work_record *work;
- char *workgroup_name = dgram->dest_name.name;
-
- START_PROFILE(election);
- server_name[15] = 0;
-
- DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
- server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
-
- DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
-
- if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
- workgroup_name, subrec->subnet_name ));
- goto done;
- }
-
- if (!strequal(work->work_group, lp_workgroup()))
- {
- DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int version = CVAL(buf,0);
+ uint32 criterion = IVAL(buf,1);
+ int timeup = IVAL(buf,5)/1000;
+ nstring server_name;
+ struct work_record *work;
+ nstring workgroup_name;
+
+ pull_ascii_nstring(server_name, buf+13);
+ pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+
+ START_PROFILE(election);
+ server_name[15] = 0;
+
+ DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
+ server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
+
+ DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
+
+ if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) {
+ DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
+ workgroup_name, subrec->subnet_name ));
+ goto done;
+ }
+
+ if (!strequal(work->work_group, lp_workgroup())) {
+ DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
is not my workgroup.\n", work->work_group, subrec->subnet_name ));
- goto done;
- }
-
- if (win_election(work, version,criterion,timeup,server_name))
- {
- /* We take precedence over the requesting server. */
- if (!work->RunningElection)
- {
- /* We weren't running an election - start running one. */
-
- work->needelection = True;
- work->ElectionCount=0;
- }
-
- /* Note that if we were running an election for this workgroup on this
- subnet already, we just ignore the server we take precedence over. */
- }
- else
- {
- /* We lost. Stop participating. */
- work->needelection = False;
-
- if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work))
- {
- work->RunningElection = False;
- DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(subrec, work, False);
- }
- }
+ goto done;
+ }
+
+ if (win_election(work, version,criterion,timeup,server_name)) {
+ /* We take precedence over the requesting server. */
+ if (!work->RunningElection) {
+ /* We weren't running an election - start running one. */
+
+ work->needelection = True;
+ work->ElectionCount=0;
+ }
+
+ /* Note that if we were running an election for this workgroup on this
+ subnet already, we just ignore the server we take precedence over. */
+ } else {
+ /* We lost. Stop participating. */
+ work->needelection = False;
+
+ if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) {
+ work->RunningElection = False;
+ DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+ if (AM_LOCAL_MASTER_BROWSER(work))
+ unbecome_local_master_browser(subrec, work, False);
+ }
+ }
done:
- END_PROFILE(election);
+
+ END_PROFILE(election);
}
/****************************************************************************
@@ -335,57 +326,53 @@ done:
BOOL check_elections(void)
{
- struct subnet_record *subrec;
- BOOL run_any_election = False;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- run_any_election |= work->RunningElection;
-
- /*
- * Start an election if we have any chance of winning.
- * Note this is a change to the previous code, that would
- * only run an election if nmbd was in the potential browser
- * state. We need to run elections in any state if we're told
- * to. JRA.
- */
-
- if (work->needelection && !work->RunningElection && lp_local_master())
- {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
+ struct subnet_record *subrec;
+ BOOL run_any_election = False;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work;
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ run_any_election |= work->RunningElection;
+
+ /*
+ * Start an election if we have any chance of winning.
+ * Note this is a change to the previous code, that would
+ * only run an election if nmbd was in the potential browser
+ * state. We need to run elections in any state if we're told
+ * to. JRA.
+ */
+
+ if (work->needelection && !work->RunningElection && lp_local_master()) {
+ /*
+ * We can only run an election for a workgroup if we have
+ * registered the WORKGROUP<1e> name, as that's the name
+ * we must listen to.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, work->work_group, 0x1e);
+ if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
+ DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
-
- DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
-
- work->ElectionCount = 0;
- work->RunningElection = True;
- work->needelection = False;
- }
- }
- }
- return run_any_election;
-}
+ continue;
+ }
+ DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+ work->ElectionCount = 0;
+ work->RunningElection = True;
+ work->needelection = False;
+ }
+ }
+ }
+ return run_any_election;
+}
/****************************************************************************
-process a internal Samba message forcing an election
+ Process a internal Samba message forcing an election.
***************************************************************************/
+
void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
{
struct subnet_record *subrec;
diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c
index 80465ada0d..49fad8e867 100644
--- a/source3/nmbd/nmbd_incomingdgrams.c
+++ b/source3/nmbd/nmbd_incomingdgrams.c
@@ -95,102 +95,99 @@ void tell_become_backup(void)
void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *announce_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *comment = buf+31;
- struct work_record *work;
- struct server_record *servrec;
- const char *work_name;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(host_announce);
- comment[43] = 0;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ nstring announce_name;
+ uint32 servertype = IVAL(buf,23);
+ fstring comment;
+ struct work_record *work;
+ struct server_record *servrec;
+ nstring work_name;
+ nstring source_name;
+
+ START_PROFILE(host_announce);
+
+ pull_ascii_fstring(comment, buf+31);
+ comment[12] = 0;
- DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
+ pull_ascii_nstring(announce_name, buf+5);
+ pull_ascii_nstring(source_name, dgram->source_name.name);
+
+ DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
+ nmb_namestr(&dgram->dest_name),announce_name));
- DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype,comment));
+ DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
+ ttl, servertype,comment));
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
- /* A host announcement must be sent to the name WORKGROUP<1d>. */
- if(dgram->dest_name.name_type != 0x1d)
- {
- DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
+ /* A host announcement must be sent to the name WORKGROUP<1d>. */
+ if(dgram->dest_name.name_type != 0x1d) {
+ DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1d. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x1d;
- }
-
- /* For a host announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name.
- */
-
- if(strequal(work_name, global_myname()))
- work_name = lp_workgroup();
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
-
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0)
- {
- if (work ==NULL )
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ /* Change it so it was. */
+ dgram->dest_name.name_type = 0x1d;
+ }
+
+ /* For a host announce the workgroup name is the destination name. */
+ pull_ascii_nstring(work_name, dgram->dest_name.name);
+
+ /*
+ * Syntax servers version 5.1 send HostAnnounce packets to
+ * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
+ * instead of WORKGROUP<1d> name. So to fix this we check if
+ * the workgroup name is our own name, and if so change it
+ * to be our primary workgroup name.
+ */
+
+ if(strequal(work_name, global_myname()))
+ nstrcpy(work_name,lp_workgroup());
+
+ /*
+ * We are being very agressive here in adding a workgroup
+ * name on the basis of a host announcing itself as being
+ * in that workgroup. Maybe we should wait for the workgroup
+ * announce instead ? JRA.
+ */
+
+ work = find_workgroup_on_subnet(subrec, work_name);
+
+ if(servertype != 0) {
+ if (work ==NULL ) {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
- subrec->work_changed = True;
+ if((servrec = find_server_in_workgroup( work, announce_name))==NULL) {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, announce_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ } else {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl( servrec, ttl);
+ fstrcpy(servrec->serv.comment,comment);
+ }
+ } else {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(announce_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+
+ subrec->work_changed = True;
done:
- END_PROFILE(host_announce);
+
+ END_PROFILE(host_announce);
}
/*******************************************************************
@@ -199,53 +196,56 @@ done:
void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *workgroup_announce_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *master_name = buf+31;
- struct work_record *work;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(workgroup_announce);
- master_name[43] = 0;
-
- DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ nstring workgroup_announce_name;
+ nstring master_name;
+ uint32 servertype = IVAL(buf,23);
+ struct work_record *work;
+ nstring source_name;
+ nstring dest_name;
+
+ START_PROFILE(workgroup_announce);
+
+ pull_ascii_nstring(workgroup_announce_name,buf+5);
+ pull_ascii_nstring(master_name,buf+31);
+ master_name[12] = 0;
+ pull_ascii_nstring(source_name,dgram->source_name.name);
+ pull_ascii_nstring(dest_name,dgram->dest_name.name);
+
+ DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
%s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),workgroup_announce_name));
-
- DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
- ttl, servertype, master_name));
-
- /* Workgroup announcements must only go to the MSBROWSE name. */
- if (!strequal(dgram->dest_name.name, MSBROWSE) || (dgram->dest_name.name_type != 0x1))
- {
- DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- goto done;
- }
+ nmb_namestr(&dgram->dest_name),workgroup_announce_name));
+
+ DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
+ ttl, servertype, master_name));
+
+ /* Workgroup announcements must only go to the MSBROWSE name. */
+ if (!strequal(dest_name, MSBROWSE) || (dgram->dest_name.name_type != 0x1)) {
+ DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ goto done;
+ }
+
+ if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL) {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
+ goto done;
+ } else {
+ /* Update the workgroup death_time. */
+ update_workgroup_ttl(work, ttl);
+ }
+
+ if(*work->local_master_browser_name == '\0') {
+ /* Set the master browser name. */
+ set_workgroup_local_master_browser_name( work, master_name );
+ }
+
+ subrec->work_changed = True;
- if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL)
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
- goto done;
- }
- else
- {
- /* Update the workgroup death_time. */
- update_workgroup_ttl(work, ttl);
- }
-
- if(*work->local_master_browser_name == '\0')
- {
- /* Set the master browser name. */
- set_workgroup_local_master_browser_name( work, master_name );
- }
-
- subrec->work_changed = True;
done:
- END_PROFILE(workgroup_announce);
+
+ END_PROFILE(workgroup_announce);
}
/*******************************************************************
@@ -254,117 +254,110 @@ done:
void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *server_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *comment = buf+31;
- char *work_name;
- struct work_record *work;
- struct server_record *servrec;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(local_master_announce);
- comment[43] = 0;
-
- DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ nstring server_name;
+ uint32 servertype = IVAL(buf,23);
+ fstring comment;
+ nstring work_name;
+ struct work_record *work;
+ struct server_record *servrec;
+ nstring source_name;
+
+ START_PROFILE(local_master_announce);
+
+ pull_ascii_nstring(server_name,buf+5);
+ pull_ascii_fstring(comment, buf+31);
+ comment[12] = 0;
+ pull_ascii_nstring(source_name, dgram->source_name.name);
+ pull_ascii_nstring(work_name, dgram->dest_name.name);
+
+ DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),server_name));
+ nmb_namestr(&dgram->dest_name),server_name));
- DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype, comment));
+ DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
+ ttl, servertype, comment));
- /* A local master announcement must be sent to the name WORKGROUP<1e>. */
- if(dgram->dest_name.name_type != 0x1e)
- {
- DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
+ /* A local master announcement must be sent to the name WORKGROUP<1e>. */
+ if(dgram->dest_name.name_type != 0x1e) {
+ DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1e. Ignoring packet.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- goto done;
- }
-
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
-
- /* For a local master announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL)
- {
- /* Don't bother adding if it's a local master release announce. */
- if(servertype == 0)
- goto done;
-
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- /* If we think we're the local master browser for this workgroup,
- we should never have got this packet. We don't see our own
- packets.
- */
- if(AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ goto done;
+ }
+
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+
+ /* For a local master announce the workgroup name is the destination name. */
+
+ if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL) {
+ /* Don't bother adding if it's a local master release announce. */
+ if(servertype == 0)
+ goto done;
+
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
+
+ /* If we think we're the local master browser for this workgroup,
+ we should never have got this packet. We don't see our own
+ packets.
+ */
+ if(AM_LOCAL_MASTER_BROWSER(work)) {
+ DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
a local master browser for workgroup %s and we think we are master. Forcing election.\n",
- server_name, inet_ntoa(p->ip), work_name));
+ server_name, inet_ntoa(p->ip), work_name));
- /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
- they have become a local master browser once, they will never
- stop sending local master announcements. To fix this we send
- them a reset browser packet, with level 0x2 on the __SAMBA__
- name that only they should be listening to. */
+ /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
+ they have become a local master browser once, they will never
+ stop sending local master announcements. To fix this we send
+ them a reset browser packet, with level 0x2 on the __SAMBA__
+ name that only they should be listening to. */
- send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);
-
- /* We should demote ourself and force an election. */
-
- unbecome_local_master_browser( subrec, work, True);
-
- /* The actual election requests are handled in
- nmbd_election.c */
- goto done;
- }
-
- /* Find the server record on this workgroup. If it doesn't exist, add it. */
-
- if(servertype != 0)
- {
- if((servrec = find_server_in_workgroup( work, server_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, server_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl(servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
-
- set_workgroup_local_master_browser_name( work, server_name );
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(server_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, server_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
+ send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);
+
+ /* We should demote ourself and force an election. */
+
+ unbecome_local_master_browser( subrec, work, True);
+
+ /* The actual election requests are handled in nmbd_election.c */
+ goto done;
+ }
+
+ /* Find the server record on this workgroup. If it doesn't exist, add it. */
+
+ if(servertype != 0) {
+ if((servrec = find_server_in_workgroup( work, server_name))==NULL) {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, server_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ } else {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl(servrec, ttl);
+ fstrcpy(servrec->serv.comment,comment);
+ }
+
+ set_workgroup_local_master_browser_name( work, server_name );
+ } else {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(server_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, server_name))!=NULL)) {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+
+ subrec->work_changed = True;
done:
- END_PROFILE(local_master_announce);
+
+ END_PROFILE(local_master_announce);
}
/*******************************************************************
@@ -377,50 +370,49 @@ done:
void process_master_browser_announce(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- char *local_master_name = buf;
- struct work_record *work;
- struct browse_cache_record *browrec;
+ nstring local_master_name;
+ struct work_record *work;
+ struct browse_cache_record *browrec;
- START_PROFILE(master_browser_announce);
- local_master_name[15] = 0;
+ START_PROFILE(master_browser_announce);
+
+ pull_ascii_nstring(local_master_name,buf);
- DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
- local_master_name, inet_ntoa(p->ip)));
+ DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
+ local_master_name, inet_ntoa(p->ip)));
- if (!lp_domain_master())
- {
- DEBUG(0,("process_master_browser_announce: Not configured as domain \
+ if (!lp_domain_master()) {
+ DEBUG(0,("process_master_browser_announce: Not configured as domain \
master - ignoring master announce.\n"));
- goto done;
- }
+ goto done;
+ }
- if((work = find_workgroup_on_subnet(subrec, lp_workgroup())) == NULL)
- {
- DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), subrec->subnet_name));
- goto done;
- }
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
+ if((work = find_workgroup_on_subnet(subrec, lp_workgroup())) == NULL) {
+ DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
+ lp_workgroup(), subrec->subnet_name));
+ goto done;
+ }
+
+ if(!AM_DOMAIN_MASTER_BROWSER(work)) {
+ DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip)));
- goto done;
- }
+ goto done;
+ }
- /* Add this host as a local master browser entry on the browse lists.
- This causes a sync request to be made to it at a later date.
- */
+ /* Add this host as a local master browser entry on the browse lists.
+ This causes a sync request to be made to it at a later date.
+ */
+
+ if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL) {
+ /* Add it. */
+ create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip);
+ } else {
+ update_browser_death_time(browrec);
+ }
- if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL)
- {
- /* Add it. */
- create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip);
- }
- else
- update_browser_death_time(browrec);
done:
- END_PROFILE(master_browser_announce);
+
+ END_PROFILE(master_browser_announce);
}
/*******************************************************************
@@ -429,123 +421,117 @@ done:
void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- uint32 servertype = IVAL(buf,1);
- int osmajor=CVAL(buf,5); /* major version of node software */
- int osminor=CVAL(buf,6); /* minor version of node software */
- int ttl = SVAL(buf,7);
- char *announce_name = buf+9;
- struct work_record *work;
- struct server_record *servrec;
- const char *work_name;
- char *source_name = dgram->source_name.name;
- pstring comment;
- char *s = buf+9;
-
- START_PROFILE(lm_host_announce);
- s = skip_string(s,1);
- StrnCpy(comment, s, 43);
-
- DEBUG(3,("process_lm_host_announce: LM Announcement from %s<%02x> IP %s to \
-%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
-
- DEBUG(5,("process_lm_host_announce: os=(%d,%d) ttl=%d server type=%08x comment=%s\n",
- osmajor, osminor, ttl, servertype,comment));
-
- if ((osmajor < 36) || (osmajor > 38) || (osminor !=0))
- {
- DEBUG(5,("process_lm_host_announce: LM Announcement packet does not \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ uint32 servertype = IVAL(buf,1);
+ int osmajor=CVAL(buf,5); /* major version of node software */
+ int osminor=CVAL(buf,6); /* minor version of node software */
+ int ttl = SVAL(buf,7);
+ nstring announce_name;
+ struct work_record *work;
+ struct server_record *servrec;
+ nstring work_name;
+ nstring source_name;
+ fstring comment;
+ char *s = buf+9;
+
+ START_PROFILE(lm_host_announce);
+ s = skip_string(s,1);
+ pull_ascii(comment, s, sizeof(fstring), 43, STR_TERMINATE);
+
+ pull_ascii_nstring(announce_name,buf+9);
+ pull_ascii_nstring(source_name,dgram->source_name.name);
+ /* For a LanMan host announce the workgroup name is the destination name. */
+ pull_ascii_nstring(work_name,dgram->dest_name.name);
+
+ DEBUG(3,("process_lm_host_announce: LM Announcement from %s IP %s to \
+%s for server %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name),announce_name));
+
+ DEBUG(5,("process_lm_host_announce: os=(%d,%d) ttl=%d server type=%08x comment=%s\n",
+ osmajor, osminor, ttl, servertype,comment));
+
+ if ((osmajor < 36) || (osmajor > 38) || (osminor !=0)) {
+ DEBUG(5,("process_lm_host_announce: LM Announcement packet does not \
originate from OS/2 Warp client. Ignoring packet.\n"));
- /* Could have been from a Windows machine (with its LM Announce enabled),
- or a Samba server. Then don't disrupt the current browse list. */
- goto done;
- }
+ /* Could have been from a Windows machine (with its LM Announce enabled),
+ or a Samba server. Then don't disrupt the current browse list. */
+ goto done;
+ }
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
- /* A LanMan host announcement must be sent to the name WORKGROUP<00>. */
- if(dgram->dest_name.name_type != 0x00)
- {
- DEBUG(2,("process_lm_host_announce: incorrect name type for destination from IP %s \
+ /* A LanMan host announcement must be sent to the name WORKGROUP<00>. */
+ if(dgram->dest_name.name_type != 0x00) {
+ DEBUG(2,("process_lm_host_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x00. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x00;
- }
-
- /* For a LanMan host announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name. This code is probably
- * not needed in the LanMan announce code, but it won't hurt.
- */
-
- if(strequal(work_name, global_myname()))
- work_name = lp_workgroup();
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ /* Change it so it was. */
+ dgram->dest_name.name_type = 0x00;
+ }
+
+ /*
+ * Syntax servers version 5.1 send HostAnnounce packets to
+ * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
+ * instead of WORKGROUP<1d> name. So to fix this we check if
+ * the workgroup name is our own name, and if so change it
+ * to be our primary workgroup name. This code is probably
+ * not needed in the LanMan announce code, but it won't hurt.
+ */
+
+ if(strequal(work_name, global_myname()))
+ nstrcpy(work_name,lp_workgroup());
+
+ /*
+ * We are being very agressive here in adding a workgroup
+ * name on the basis of a host announcing itself as being
+ * in that workgroup. Maybe we should wait for the workgroup
+ * announce instead ? JRA.
+ */
+
+ work = find_workgroup_on_subnet(subrec, work_name);
+
+ if(servertype != 0) {
+ if (work == NULL) {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
+
+ if((servrec = find_server_in_workgroup( work, announce_name))==NULL) {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, announce_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ } else {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl( servrec, ttl);
+ fstrcpy(servrec->serv.comment,comment);
+ }
+ } else {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(announce_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+
+ subrec->work_changed = True;
+ found_lm_clients = True;
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0)
- {
- if (work == NULL)
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
- found_lm_clients = True;
done:
- END_PROFILE(lm_host_announce);
+
+ END_PROFILE(lm_host_announce);
}
/****************************************************************************
Send a backup list response.
*****************************************************************************/
+
static void send_backup_list_response(struct subnet_record *subrec,
struct work_record *work,
struct nmb_name *send_to_name,
@@ -553,40 +539,41 @@ static void send_backup_list_response(struct subnet_record *subrec,
uint32 token, struct in_addr sendto_ip,
int port)
{
- char outbuf[1024];
- char *p, *countptr;
- unsigned int count = 0;
+ char outbuf[1024];
+ char *p, *countptr;
+ unsigned int count = 0;
+ nstring send_to_namestr;
#if 0
struct server_record *servrec;
#endif
- fstring myname;
+ fstring myname;
- memset(outbuf,'\0',sizeof(outbuf));
+ memset(outbuf,'\0',sizeof(outbuf));
- DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
- work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
+ DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
+ work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
- p = outbuf;
+ p = outbuf;
- SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
- p++;
+ SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
+ p++;
- countptr = p;
- p++;
+ countptr = p;
+ p++;
- SIVAL(p,0,token); /* The sender's unique info. */
- p += 4;
+ SIVAL(p,0,token); /* The sender's unique info. */
+ p += 4;
- /* We always return at least one name - our own. */
- count = 1;
- fstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
+ /* We always return at least one name - our own. */
+ count = 1;
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(p,1);
- /* Look for backup browsers in this workgroup. */
+ /* Look for backup browsers in this workgroup. */
#if 0
/* we don't currently send become_backup requests so we should never
@@ -624,16 +611,18 @@ static void send_backup_list_response(struct subnet_record *subrec,
}
#endif
- SCVAL(countptr, 0, count);
+ SCVAL(countptr, 0, count);
+
+ pull_ascii_nstring(send_to_namestr, send_to_name->name);
- DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
- send_to_name->name, inet_ntoa(sendto_ip), count));
+ DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
+ send_to_namestr, inet_ntoa(sendto_ip), count));
- send_mailslot(True, BROWSE_MAILSLOT,
- outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0,
- send_to_name->name,0,
- sendto_ip, subrec->myip, port);
+ send_mailslot(True, BROWSE_MAILSLOT,
+ outbuf,PTR_DIFF(p,outbuf),
+ global_myname(), 0,
+ send_to_namestr,0,
+ sendto_ip, subrec->myip, port);
}
/*******************************************************************
@@ -649,80 +638,74 @@ static void send_backup_list_response(struct subnet_record *subrec,
void process_get_backup_list_request(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- unsigned char max_number_requested = CVAL(buf,0);
- uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
- int name_type = dgram->dest_name.name_type;
- char *workgroup_name = dgram->dest_name.name;
- struct subnet_record *search_subrec = subrec;
-
- START_PROFILE(get_backup_list);
- DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct work_record *work;
+ unsigned char max_number_requested = CVAL(buf,0);
+ uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
+ int name_type = dgram->dest_name.name_type;
+ nstring workgroup_name;
+ struct subnet_record *search_subrec = subrec;
+
+ START_PROFILE(get_backup_list);
+ pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+
+ DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
- /* We have to be a master browser, or a domain master browser
- for the requested workgroup. That means it must be our
- workgroup. */
-
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
+ /* We have to be a master browser, or a domain master browser
+ for the requested workgroup. That means it must be our
+ workgroup. */
+
+ if(strequal(workgroup_name, lp_workgroup()) == False) {
+ DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
+
+ if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL) {
+ DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
subnet %s.\n", workgroup_name, search_subrec->subnet_name));
- goto done;
- }
+ goto done;
+ }
- /*
- * If the packet was sent to WORKGROUP<1b> instead
- * of WORKGROUP<1d> then it was unicast to us a domain master
- * browser. Change search subrec to unicast.
- */
+ /*
+ * If the packet was sent to WORKGROUP<1b> instead
+ * of WORKGROUP<1d> then it was unicast to us a domain master
+ * browser. Change search subrec to unicast.
+ */
- if(name_type == 0x1b)
- {
- /* We must be a domain master browser in order to
- process this packet. */
+ if(name_type == 0x1b) {
+ /* We must be a domain master browser in order to
+ process this packet. */
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
+ if(!AM_DOMAIN_MASTER_BROWSER(work)) {
+ DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a domain master browser.\n", workgroup_name));
- goto done;
- }
+ goto done;
+ }
- search_subrec = unicast_subnet;
- }
- else if (name_type == 0x1d)
- {
- /* We must be a local master browser in order to
- process this packet. */
+ search_subrec = unicast_subnet;
+ } else if (name_type == 0x1d) {
+ /* We must be a local master browser in order to process this packet. */
- if(!AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
+ if(!AM_LOCAL_MASTER_BROWSER(work)) {
+ DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a local master browser.\n", workgroup_name));
- goto done;
- }
- }
- else
- {
- DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
- name_type));
- goto done;
- }
+ goto done;
+ }
+ } else {
+ DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
+ name_type));
+ goto done;
+ }
+
+ send_backup_list_response(subrec, work, &dgram->source_name,
+ max_number_requested, token, p->ip, p->port);
- send_backup_list_response(subrec, work, &dgram->source_name,
- max_number_requested, token, p->ip, p->port);
done:
- END_PROFILE(get_backup_list);
+
+ END_PROFILE(get_backup_list);
}
/*******************************************************************
@@ -738,49 +721,46 @@ done:
void process_reset_browser(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int state = CVAL(buf,0);
- struct subnet_record *sr;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int state = CVAL(buf,0);
+ struct subnet_record *sr;
- START_PROFILE(reset_browser);
- DEBUG(1,("process_reset_browser: received diagnostic browser reset \
-request from %s IP %s state=0x%X\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
+ START_PROFILE(reset_browser);
- /* Stop being a local master browser on all our broadcast subnets. */
- if (state & 0x1)
- {
- for (sr = FIRST_SUBNET; sr; sr = NEXT_SUBNET_EXCLUDING_UNICAST(sr))
- {
- struct work_record *work;
- for (work = sr->workgrouplist; work; work = work->next)
- {
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(sr, work, True);
- }
- }
- }
+ DEBUG(1,("process_reset_browser: received diagnostic browser reset \
+request from %s IP %s state=0x%X\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
+
+ /* Stop being a local master browser on all our broadcast subnets. */
+ if (state & 0x1) {
+ for (sr = FIRST_SUBNET; sr; sr = NEXT_SUBNET_EXCLUDING_UNICAST(sr)) {
+ struct work_record *work;
+ for (work = sr->workgrouplist; work; work = work->next) {
+ if (AM_LOCAL_MASTER_BROWSER(work))
+ unbecome_local_master_browser(sr, work, True);
+ }
+ }
+ }
- /* Discard our browse lists. */
- if (state & 0x2)
- {
- /*
- * Calling expire_workgroups_and_servers with a -1
- * time causes all servers not marked with a PERMANENT_TTL
- * on the workgroup lists to be discarded, and all
- * workgroups with empty server lists to be discarded.
- * This means we keep our own server names and workgroup
- * as these have a PERMANENT_TTL.
- */
-
- expire_workgroups_and_servers(-1);
- }
+ /* Discard our browse lists. */
+ if (state & 0x2) {
+ /*
+ * Calling expire_workgroups_and_servers with a -1
+ * time causes all servers not marked with a PERMANENT_TTL
+ * on the workgroup lists to be discarded, and all
+ * workgroups with empty server lists to be discarded.
+ * This means we keep our own server names and workgroup
+ * as these have a PERMANENT_TTL.
+ */
+
+ expire_workgroups_and_servers(-1);
+ }
- /* Request to stop browsing altogether. */
- if (state & 0x4)
- DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
+ /* Request to stop browsing altogether. */
+ if (state & 0x4)
+ DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
- END_PROFILE(reset_browser);
+ END_PROFILE(reset_browser);
}
/*******************************************************************
@@ -793,33 +773,34 @@ request from %s IP %s state=0x%X\n",
void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- char *workgroup_name = dgram->dest_name.name;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct work_record *work;
+ nstring workgroup_name;
- START_PROFILE(announce_request);
- DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
-
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
+ START_PROFILE(announce_request);
- work->needannounce = True;
+ pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+ DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
+
+ /* We only send announcement requests on our workgroup. */
+ if(strequal(workgroup_name, lp_workgroup()) == False) {
+ DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
+
+ if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) {
+ DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
+ workgroup_name));
+ goto done;
+ }
+
+ work->needannounce = True;
done:
- END_PROFILE(lm_host_announce);
+
+ END_PROFILE(lm_host_announce);
}
/*******************************************************************
@@ -833,30 +814,32 @@ done:
void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- char *workgroup_name = dgram->dest_name.name;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ nstring workgroup_name;
- START_PROFILE(lm_announce_request);
- DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
+ START_PROFILE(lm_announce_request);
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
+ pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+ DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
- if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL)
- {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
+ /* We only send announcement requests on our workgroup. */
+ if(strequal(workgroup_name, lp_workgroup()) == False) {
+ DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
+
+ if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL) {
+ DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
+ workgroup_name));
+ goto done;
+ }
+
+ found_lm_clients = True;
- found_lm_clients = True;
done:
- END_PROFILE(lm_host_announce);
+
+ END_PROFILE(lm_host_announce);
}
diff --git a/source3/nmbd/nmbd_namequery.c b/source3/nmbd/nmbd_namequery.c
index 8995e9ac52..2a200713b9 100644
--- a/source3/nmbd/nmbd_namequery.c
+++ b/source3/nmbd/nmbd_namequery.c
@@ -201,7 +201,7 @@ static BOOL query_local_namelists(struct subnet_record *subrec, struct nmb_name
Try and query for a name.
****************************************************************************/
-BOOL query_name(struct subnet_record *subrec, char *name, int type,
+BOOL query_name(struct subnet_record *subrec, const char *name, int type,
query_name_success_function success_fn,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)
@@ -276,7 +276,7 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
****************************************************************************/
BOOL query_name_from_wins_server(struct in_addr ip_to,
- char *name, int type,
+ const char *name, int type,
query_name_success_function success_fn,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)