- fixed bugs in nmb response packet checking.
authorSamba Release Account <samba-bugs@samba.org>
Fri, 23 Aug 1996 10:17:30 +0000 (10:17 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Fri, 23 Aug 1996 10:17:30 +0000 (10:17 +0000)
- added multiple workgroup code - samba can register under different
  (unique) NetBIOS aliases, one per workgroup it joins.

lkcl
(This used to be commit f24e341e7e4d8726b98d3a0f83b24f61817fe536)

23 files changed:
source3/include/nameserv.h
source3/include/proto.h
source3/lib/util.c
source3/nameannounce.c
source3/namebrowse.c
source3/nameconf.c [new file with mode: 0644]
source3/namedbname.c
source3/namedbresp.c
source3/namedbserver.c
source3/namedbsubnet.c
source3/namedbwork.c
source3/nameelect.c
source3/namepacket.c
source3/nameresp.c
source3/nameserv.c
source3/nameservreply.c
source3/nameservresp.c
source3/namework.c
source3/nmbd/nmbd.c
source3/nmbsync.c
source3/param/loadparm.c
source3/smbd/ipc.c
source3/smbd/server.c

index e4876bac57022d7d641556eb7ea8560ccbbb1af1..404c0531e5205aab6c405284ab07c1e10f7c3742 100644 (file)
@@ -99,19 +99,19 @@ enum master_state
 
 enum state_type
 {
-       NAME_STATUS_DOM_SRV_CHK,
-       NAME_STATUS_SRV_CHK,
-       NAME_REGISTER_CHALLENGE,
-       NAME_REGISTER,
-       NAME_RELEASE,
-       NAME_QUERY_CONFIRM,
-       NAME_QUERY_ANNOUNCE_HOST,
-       NAME_QUERY_SYNC_LOCAL,
-       NAME_QUERY_SYNC_REMOTE,
-       NAME_QUERY_DOM_SRV_CHK,
-       NAME_QUERY_SRV_CHK,
-       NAME_QUERY_FIND_MST,
-       NAME_QUERY_MST_CHK
+    NAME_STATUS_DOM_SRV_CHK,
+    NAME_STATUS_SRV_CHK,
+    NAME_REGISTER_CHALLENGE,
+    NAME_REGISTER,
+    NAME_RELEASE,
+    NAME_QUERY_CONFIRM,
+    NAME_QUERY_ANNOUNCE_HOST,
+    NAME_QUERY_SYNC_LOCAL,
+    NAME_QUERY_SYNC_REMOTE,
+    NAME_QUERY_DOM_SRV_CHK,
+    NAME_QUERY_SRV_CHK,
+    NAME_QUERY_FIND_MST,
+    NAME_QUERY_MST_CHK
 };
 
 /* a netbios name structure */
@@ -121,6 +121,14 @@ struct nmb_name {
   int name_type;
 };
 
+/* A server name and comment. */
+struct server_identity
+{
+    char *name;
+    char *comment;
+    struct server_identity *next;
+};
+
 /* a netbios flags + ip address structure */
 /* this is used for multi-homed systems and for internet group names */
 struct nmb_ip
@@ -148,16 +156,16 @@ struct name_record
 /* browse and backup server cache for synchronising browse list */
 struct browse_cache_record
 {
-       struct browse_cache_record *next;
-       struct browse_cache_record *prev;
-
-       pstring name;
-       int type;
-       pstring group;
-       struct in_addr ip;
-       time_t sync_time;
-       BOOL synced;
-       BOOL local;
+    struct browse_cache_record *next;
+    struct browse_cache_record *prev;
+
+    pstring name;
+    int type;
+    pstring group;
+    struct in_addr ip;
+    time_t sync_time;
+    BOOL synced;
+    BOOL local;
 };
 
 /* this is used to hold the list of servers in my domain, and is */
@@ -214,9 +222,10 @@ struct response_record
   int fd;
   int quest_type;
   struct nmb_name name;
-  int nb_flags;
+  struct nmb_ip reply;
   time_t ttl;
 
+  int token; /* unique workgroup token id */
   int server_type;
   fstring my_name;
   fstring my_comment;
@@ -224,7 +233,6 @@ struct response_record
   BOOL bcast;
   BOOL recurse;
   struct in_addr send_ip;
-  struct in_addr reply_to_ip;
 
   int num_msgs;
 
index e20238fee4269aa3c3373c88813c4b43602e5a60..293179d4ab0942b9fdbbaba68d427e0630c29bb5 100644 (file)
@@ -1,39 +1,24 @@
 /* This file is automatically generated with "make proto". DO NOT EDIT */
 
 
-/*The following definitions come from  access.c  */
+/*The following definitions come from  -  */
 
 BOOL check_access(int snum);
 BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
 BOOL fromhost(int sock,struct from_host *f);
-
-/*The following definitions come from  charcnv.c  */
-
 char *unix2dos_format(char *str,BOOL overwrite);
 char *dos2unix_format(char *str, BOOL overwrite);
 int interpret_character_set(char *str, int def);
-
-/*The following definitions come from  charset.c  */
-
 void charset_initialise(void);
 void add_char_string(char *s);
-
-/*The following definitions come from  chgpasswd.c  */
-
 BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
 BOOL chgpasswd(char *name,char *oldpass,char *newpass);
 BOOL chgpasswd(char *name,char *oldpass,char *newpass);
-
-/*The following definitions come from  client.c  */
-
 void setup_pkt(char *outbuf);
 void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
 void cmd_help(void);
 BOOL reopen_connection(char *inbuf,char *outbuf);
 char *smb_errstr(char *inbuf);
-
-/*The following definitions come from  clientutil.c  */
-
 void cli_setup_pkt(char *outbuf);
 BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
                                int *param_len, char **data,char **param);
@@ -48,9 +33,6 @@ BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int fl
 BOOL cli_open_sockets(int port);
 BOOL cli_reopen_connection(char *inbuf,char *outbuf);
 char *smb_errstr(char *inbuf);
-
-/*The following definitions come from  clitar.c  */
-
 int strslashcmp(const char *s1, const char *s2);
 void cmd_block(void);
 void cmd_tarmode(void);
@@ -59,9 +41,6 @@ void cmd_tar(char *inbuf, char *outbuf);
 int process_tar(char *inbuf, char *outbuf);
 int clipfind(char **aret, int ret, char *tok);
 int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
-
-/*The following definitions come from  dir.c  */
-
 void init_dptrs(void);
 char *dptr_path(int key);
 char *dptr_wcard(int key);
@@ -87,17 +66,8 @@ int TellDir(void *p);
 void DirCacheAdd(char *path,char *name,char *dname,int snum);
 char *DirCacheCheck(char *path,char *name,int snum);
 void DirCacheFlush(int snum);
-
-/*The following definitions come from  fault.c  */
-
 void fault_setup(void (*fn)());
-
-/*The following definitions come from  getsmbpass.c  */
-
 char *getsmbpass(char *prompt)    ;
-
-/*The following definitions come from  interface.c  */
-
 void load_interfaces(void);
 void iface_set_default(char *ip,char *bcast,char *nmask);
 BOOL ismyip(struct in_addr ip);
@@ -107,23 +77,15 @@ struct in_addr *iface_n_ip(int n);
 struct in_addr *iface_bcast(struct in_addr ip);
 struct in_addr *iface_nmask(struct in_addr ip);
 struct in_addr *iface_ip(struct in_addr ip);
-
-/*The following definitions come from  ipc.c  */
-
 int reply_trans(char *inbuf,char *outbuf);
-
-/*The following definitions come from  kanji.c  */
-
 int interpret_coding_system(char *str, int def);
-
-/*The following definitions come from  loadparm.c  */
-
 char *lp_string(char *s);
 char *lp_logfile(void);
 char *lp_smbrun(void);
 char *lp_configfile(void);
 char *lp_smb_passwd_file(void);
 char *lp_serverstring(void);
+char *lp_server_comment(void);
 char *lp_printcapname(void);
 char *lp_lockdir(void);
 char *lp_rootdir(void);
@@ -146,6 +108,7 @@ char *lp_interfaces(void);
 char *lp_socket_address(void);
 BOOL lp_wins_support(void);
 BOOL lp_wins_proxy(void);
+BOOL lp_local_master(void);
 BOOL lp_domain_master(void);
 BOOL lp_domain_logons(void);
 BOOL lp_preferred_master(void);
@@ -251,9 +214,6 @@ int lp_numservices(void);
 void lp_dump(void);
 int lp_servicenumber(char *pszServiceName);
 char *volume_label(int snum);
-
-/*The following definitions come from  locking.c  */
-
 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
 int file_lock(char *name,int timeout);
 void file_unlock(int fd);
@@ -268,9 +228,6 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid);
 void del_share_mode(int fnum);
 BOOL set_share_mode(int fnum,int mode);
 void clean_share_modes(void);
-
-/*The following definitions come from  mangle.c  */
-
 int str_checksum(char *s);
 BOOL is_8_3(char *fname);
 void create_mangled_stack(int size);
@@ -278,192 +235,157 @@ BOOL check_mangled_stack(char *s);
 BOOL is_mangled(char *s);
 void mangle_name_83(char *s);
 BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
-
-/*The following definitions come from  md4.c  */
-
-
-/*The following definitions come from  message.c  */
-
 int reply_sends(char *inbuf,char *outbuf);
 int reply_sendstrt(char *inbuf,char *outbuf);
 int reply_sendtxt(char *inbuf,char *outbuf);
 int reply_sendend(char *inbuf,char *outbuf);
-
-/*The following definitions come from  nameannounce.c  */
-
 void announce_request(struct work_record *work, struct in_addr ip);
-void do_announce_request(char *info, char *to_name, int announce_type, 
-                        int from,
-                        int to, struct in_addr dest_ip);
+void do_announce_request(char *info, char *from_name, char *to_name,
+             int announce_type, int from, int to, struct in_addr dest_ip);
 void sync_server(enum state_type state, char *serv_name, char *work_name, 
-                int name_type,
-                struct in_addr ip);
+         int name_type,
+         struct in_addr ip);
 void do_announce_host(int command,
-               char *from_name, int from_type, struct in_addr from_ip,
-               char *to_name  , int to_type  , struct in_addr to_ip,
-               time_t announce_interval,
-               char *server_name, int server_type, char *server_comment);
+        char *from_name, int from_type, struct in_addr from_ip,
+        char *to_name  , int to_type  , struct in_addr to_ip,
+        time_t announce_interval,
+        char *server_name, int server_type, char *server_comment);
 void remove_my_servers(void);
 void announce_server(struct subnet_record *d, struct work_record *work,
-                    char *name, char *comment, time_t ttl, int server_type);
+             char *name, char *comment, time_t ttl, int server_type);
 void announce_host(void);
 void announce_master(void);
 void announce_remote(void);
-
-/*The following definitions come from  namebrowse.c  */
-
 void expire_browse_cache(time_t t);
 struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
-                                             time_t ttl, struct in_addr ip, BOOL local);
+                          time_t ttl, struct in_addr ip, BOOL local);
 void do_browser_lists(void);
-
-/*The following definitions come from  namedbname.c  */
-
+int get_num_workgroups(void);
+int conf_workgroup_name_to_token(const char *workgroup_name,
+                                                                const char *default_name);
+char *conf_workgroup_name(int token);
+int conf_should_workgroup_member(int token);
+int conf_should_local_master(int token);
+int conf_should_domain_master(int token);
+char *conf_browsing_alias(int token);
+char *conf_browsing_alias_comment(int token);
+char *conf_alias_to_workgroup(const char *alias);
+int conf_alias_to_token(const char *alias);
+void read_smbbrowse_conf(char *default_name);
 void set_samba_nb_type(void);
 BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
 BOOL ms_browser_name(char *name, int type);
 void remove_name(struct subnet_record *d, struct name_record *n);
 struct name_record *find_name(struct name_record *n,
-                       struct nmb_name *name,
-                       int search);
+            struct nmb_name *name,
+            int search);
 struct name_record *find_name_search(struct subnet_record **d,
-                       struct nmb_name *name,
-                       int search, struct in_addr ip);
+            struct nmb_name *name,
+            int search, struct in_addr ip);
 void dump_names(void);
 void load_netbios_names(void);
 void remove_netbios_name(struct subnet_record *d,
-                       char *name,int type, enum name_source source,
-                        struct in_addr ip);
+            char *name,int type, enum name_source source,
+             struct in_addr ip);
 struct name_record *add_netbios_entry(struct subnet_record *d,
-               char *name, int type, int nb_flags, 
-               int ttl, enum name_source source, struct in_addr ip,
-               BOOL new_only,BOOL wins);
-void expire_names(time_t t);
+        char *name, int type, int nb_flags, 
+        int ttl, enum name_source source, struct in_addr ip,
+        BOOL new_only,BOOL wins);
+void check_expire_names(time_t t);
 struct name_record *search_for_name(struct subnet_record **d,
-                                       struct nmb_name *question,
-                                   struct in_addr ip, int Time, int search);
-
-/*The following definitions come from  namedbresp.c  */
-
+                    struct nmb_name *question,
+                    struct in_addr ip, int Time, int search);
 void add_response_record(struct subnet_record *d,
                                struct response_record *n);
 void remove_response_record(struct subnet_record *d,
                                struct response_record *n);
 struct response_record *make_response_queue_record(enum state_type state,
-                               int id,uint16 fd,
-                               int quest_type, char *name,int type, int nb_flags, time_t ttl,
+                               int id,uint16 fd, int quest_type,
+                int token, char *name,int type, int nb_flags, time_t ttl,
                                int server_type, char *my_name, char *my_comment,
                                BOOL bcast,BOOL recurse,
                                struct in_addr send_ip, struct in_addr reply_to_ip);
 struct response_record *find_response_record(struct subnet_record **d,
                                uint16 id);
-
-/*The following definitions come from  namedbserver.c  */
-
 void remove_old_servers(struct work_record *work, time_t t,
-                                       BOOL remove_all);
+                    BOOL remove_all);
 struct server_record *find_server(struct work_record *work, char *name);
 struct server_record *add_server_entry(struct subnet_record *d, 
-                                      struct work_record *work,
-                                      char *name,int servertype, 
-                                      int ttl,char *comment,
-                                      BOOL replace);
+                       struct work_record *work,
+                       char *name,int servertype, 
+                       int ttl,char *comment,
+                       BOOL replace);
 void expire_servers(time_t t);
-
-/*The following definitions come from  namedbsubnet.c  */
-
 struct subnet_record *find_subnet(struct in_addr bcast_ip);
 struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
 void add_subnet_interfaces(void);
 void add_my_subnets(char *group);
 struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
-                                      struct in_addr mask_ip,
-                                      char *name, BOOL add, BOOL lmhosts);
+                       struct in_addr mask_ip,
+                       char *name, BOOL add, BOOL lmhosts);
 void write_browse_list(void);
-
-/*The following definitions come from  namedbwork.c  */
-
 struct work_record *remove_workgroup(struct subnet_record *d, 
-                                    struct work_record *work,
-                                        BOOL remove_all_servers);
+                     struct work_record *work,
+                     BOOL remove_all_servers);
 struct work_record *find_workgroupstruct(struct subnet_record *d, 
-                                        fstring name, BOOL add);
+                     fstring name, BOOL add);
 void dump_workgroups(void);
-
-/*The following definitions come from  nameelect.c  */
-
 void check_master_browser(void);
 void browser_gone(char *work_name, struct in_addr ip);
 void send_election(struct subnet_record *d, char *group,uint32 criterion,
-                  int timeup,char *name);
+           int timeup,char *name);
 void name_unregister_work(struct subnet_record *d, char *name, int name_type);
-void name_register_work(struct subnet_record *d, char *name, int name_type,
-                               int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
+void name_register_work(struct subnet_record *d, int token,
+                char *name, int name_type,
+                struct nmb_ip *data, time_t ttl, struct in_addr ip, BOOL bcast);
 void become_master(struct subnet_record *d, struct work_record *work);
 void become_nonmaster(struct subnet_record *d, struct work_record *work,
-                               int remove_type);
+                int remove_type);
 void run_elections(void);
 void process_election(struct packet_struct *p,char *buf);
 BOOL check_elections(void);
-
-/*The following definitions come from  namelogon.c  */
-
 void process_logon_packet(struct packet_struct *p,char *buf,int len);
-
-/*The following definitions come from  namepacket.c  */
-
 void debug_browse_data(char *outbuf, int len);
-void initiate_netbios_packet(uint16 *id,
-                               int fd,int quest_type,char *name,int name_type,
-                           int nb_flags,BOOL bcast,BOOL recurse,
-                           struct in_addr to_ip);
+BOOL initiate_netbios_packet(uint16 id,
+                int fd,int quest_type,char *name,int name_type,
+                int nb_flags,BOOL bcast,BOOL recurse,
+                struct in_addr to_ip);
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
-                               int rcode, int rcv_code, int opcode, BOOL recurse,
-                               struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
-                               char *data,int len);
+                int rcode, int rcv_code, int opcode, BOOL recurse,
+                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
+                char *data,int len);
 void queue_packet(struct packet_struct *packet);
 void run_packet_queue();
 void listen_for_packets(BOOL run_election);
 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
-                        char *dstname,int src_type,int dest_type,
-                        struct in_addr dest_ip,struct in_addr src_ip);
-
-/*The following definitions come from  namequery.c  */
-
+             char *dstname,int src_type,int dest_type,
+             struct in_addr dest_ip,struct in_addr src_ip);
 BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
                 struct in_addr to_ip,char *master,char *rname,
                 void (*fn)());
 BOOL name_query(int fd,char *name,int name_type, 
                BOOL bcast,BOOL recurse,
                struct in_addr to_ip, struct in_addr *ip,void (*fn)());
-
-/*The following definitions come from  nameresp.c  */
-
+void update_name_trn_id(void);
 void expire_netbios_response_entries();
-struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
-                               int fd,int quest_type,enum state_type state,
-                           char *name,int name_type,int nb_flags, time_t ttl,
-                               int server_type, char *my_name, char *my_comment,
-                           BOOL bcast,BOOL recurse,
-                               struct in_addr send_ip, struct in_addr reply_to_ip);
-struct response_record *queue_netbios_packet(struct subnet_record *d,
-                       int fd,int quest_type,enum state_type state,char *name,
-                       int name_type,int nb_flags, time_t ttl,
-                       int server_type, char *my_name, char *my_comment,
-                   BOOL bcast,BOOL recurse,
-                       struct in_addr send_ip, struct in_addr reply_to_ip);
-
-/*The following definitions come from  nameserv.c  */
-
-void remove_name_entry(struct subnet_record *d, char *name,int type);
-void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
+void queue_netbios_pkt_wins(struct subnet_record *d,
+                int fd,int quest_type,enum state_type state,
+                int token, char *name,int name_type,int nb_flags, time_t ttl,
+                int server_type, char *my_name, char *my_comment,
+                BOOL bcast,BOOL recurse,
+                struct in_addr send_ip, struct in_addr reply_to_ip);
+void queue_netbios_packet(struct subnet_record *d,
+            int fd,int quest_type,enum state_type state,
+            int token, char *name, int name_type,int nb_flags, time_t ttl,
+            int server_type, char *my_name, char *my_comment,
+            BOOL bcast,BOOL recurse,
+            struct in_addr send_ip, struct in_addr reply_to_ip);
+void remove_name_entry(struct subnet_record *d, int token, char *name,int type);
+void add_my_name_entry(struct subnet_record *d, int token,
+                       char *name,int type,int nb_flags);
 void add_my_names(void);
 void remove_my_names();
-void refresh_my_names(time_t t);
 void query_refresh_names(void);
-
-/*The following definitions come from  nameservreply.c  */
-
 void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
                                uint16 response_id,
                                struct nmb_name *name,
@@ -477,25 +399,18 @@ void reply_name_release(struct packet_struct *p);
 void reply_name_reg(struct packet_struct *p);
 void reply_name_status(struct packet_struct *p);
 void reply_name_query(struct packet_struct *p);
-
-/*The following definitions come from  nameservresp.c  */
-
 void debug_state_type(int state);
+void response_process(struct in_addr ip, struct subnet_record *d,
+                struct response_record *n, 
+                int rcode, char *nmb_data, struct nmb_name *q_name,
+                time_t ttl, BOOL bcast, struct nmb_name *ans_name);
 void response_netbios_packet(struct packet_struct *p);
-
-/*The following definitions come from  namework.c  */
-
-void reset_server(char *name, int state, struct in_addr ip);
+void reset_server(struct work_record *work, char *name, int state, struct in_addr ip);
 void tell_become_backup(void);
 BOOL same_context(struct dgram_packet *dgram);
+BOOL listening_name(struct work_record *work, struct nmb_name *n);
 void process_browse_packet(struct packet_struct *p,char *buf,int len);
-
-/*The following definitions come from  nmbd.c  */
-
 BOOL reload_services(BOOL test);
-
-/*The following definitions come from  nmblib.c  */
-
 void debug_nmb_packet(struct packet_struct *p);
 char *namestr(struct nmb_name *n);
 void free_nmb_packet(struct nmb_packet *nmb);
@@ -504,23 +419,11 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type);
 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
 BOOL send_packet(struct packet_struct *p);
 struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-
-/*The following definitions come from  nmblookup.c  */
-
 int main(int argc,char *argv[]);
-
-/*The following definitions come from  nmbsync.c  */
-
 char *getsmbpass(char *pass);
 void sync_browse_lists(struct subnet_record *d, struct work_record *work,
-               char *name, int nm_type, struct in_addr ip, BOOL local);
-
-/*The following definitions come from  params.c  */
-
+        char *name, int nm_type, struct in_addr ip, BOOL local);
 BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
-
-/*The following definitions come from  password.c  */
-
 void generate_next_challenge(char *challenge);
 BOOL set_challenge(char *challenge);
 BOOL last_challenge(char *challenge);
@@ -540,14 +443,8 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
 BOOL check_hosts_equiv(char *user);
 BOOL server_cryptkey(char *buf);
 BOOL server_validate(char *buf);
-
-/*The following definitions come from  pcap.c  */
-
 BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
 void pcap_printer_fn(void (*fn)());
-
-/*The following definitions come from  pipes.c  */
-
 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize);
 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
                     int mdrcnt,int mprcnt,
@@ -557,31 +454,19 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
                     int mdrcnt,int mprcnt,
                     char **rdata,char **rparam,
                     int *rdata_len,int *rparam_len);
-
-/*The following definitions come from  predict.c  */
-
 int read_predict(int fd,int offset,char *buf,char **ptr,int num);
 void do_read_prediction();
 void invalidate_read_prediction(int fd);
-
-/*The following definitions come from  printing.c  */
-
 void lpq_reset(int snum);
 void print_file(int fnum);
 int get_printqueue(int snum,int cnum,print_queue_struct **queue,
                   print_status_struct *status);
 void del_printqueue(int cnum,int snum,int jobid);
 void status_printjob(int cnum,int snum,int jobid,int status);
-
-/*The following definitions come from  quotas.c  */
-
 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-
-/*The following definitions come from  replace.c  */
-
 char *Strstr(char *s, char *p);
 time_t Mktime(struct tm      *t);
 int InNetGr(char *group,char *host,char *user,char *dom);
@@ -589,9 +474,6 @@ void *malloc_wrapped(int size,char *file,int line);
 void *realloc_wrapped(void *ptr,int size,char *file,int line);
 void free_wrapped(void *ptr,char *file,int line);
 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
-
-/*The following definitions come from  reply.c  */
-
 int reply_special(char *inbuf,char *outbuf);
 int reply_tcon(char *inbuf,char *outbuf);
 int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
@@ -642,9 +524,6 @@ int reply_writebmpx(char *inbuf,char *outbuf);
 int reply_writebs(char *inbuf,char *outbuf);
 int reply_setattrE(char *inbuf,char *outbuf);
 int reply_getattrE(char *inbuf,char *outbuf);
-
-/*The following definitions come from  server.c  */
-
 mode_t unix_mode(int cnum,int dosmode);
 int dos_mode(int cnum,char *path,struct stat *sbuf);
 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
@@ -685,9 +564,6 @@ void standard_sub(int cnum,char *s);
 char *smb_fn_name(int type);
 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
-
-/*The following definitions come from  shmem.c  */
-
 BOOL shm_open( char *file_name, int size);
 BOOL shm_close( void );
 shm_offset_t shm_alloc(int size);
@@ -701,9 +577,6 @@ BOOL shm_unlock(void);
 BOOL shm_get_usage(int *bytes_free,
                   int *bytes_used,
                   int *bytes_overhead);
-
-/*The following definitions come from  smbencrypt.c  */
-
 void str_to_key(uchar *str,uchar *key);
 void D1(uchar *k, uchar *d, uchar *out);
 void E1(uchar *k, uchar *d, uchar *out);
@@ -712,28 +585,13 @@ void E_P24(uchar *p21, uchar *c8, uchar *p24);
 void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
 void E_md4hash(uchar *passwd, uchar *p16);
 void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-
-/*The following definitions come from  smbpass.c  */
-
 int pw_file_lock(char *name, int type, int secs);
 int pw_file_unlock(int fd);
 struct smb_passwd *get_smbpwnam(char *name);
-
-/*The following definitions come from  smbpasswd.c  */
-
-
-/*The following definitions come from  smbrun.c  */
-
-
-/*The following definitions come from  status.c  */
-
 void Ucrit_addUsername(pstring username);
 unsigned int Ucrit_checkUsername(pstring username);
 void Ucrit_addPid(int pid);
 unsigned int   Ucrit_checkPid(int pid);
-
-/*The following definitions come from  system.c  */
-
 int sys_select(fd_set *fds,struct timeval *tval);
 int sys_select(fd_set *fds,struct timeval *tval);
 int sys_unlink(char *fname);
@@ -749,16 +607,7 @@ int sys_rename(char *from, char *to);
 int sys_chmod(char *fname,int mode);
 int sys_chown(char *fname,int uid,int gid);
 int sys_chroot(char *dname);
-
-/*The following definitions come from  testparm.c  */
-
-
-/*The following definitions come from  testprns.c  */
-
 int main(int argc, char *argv[]);
-
-/*The following definitions come from  time.c  */
-
 void GetTimeOfDay(struct timeval *tval);
 void TimeInit(void);
 int TimeDiff(time_t t);
@@ -773,35 +622,22 @@ time_t make_unix_date2(void *date_ptr);
 time_t make_unix_date3(void *date_ptr);
 BOOL set_filetime(char *fname,time_t mtime);
 char *timestring(void );
-
-/*The following definitions come from  trans2.c  */
-
 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
-
-/*The following definitions come from  ufc.c  */
-
 char *ufc_crypt(char *key,char *salt);
-
-/*The following definitions come from  uid.c  */
-
 void init_uid(void);
 BOOL become_guest(void);
 BOOL become_user(int cnum, int uid);
 BOOL unbecome_user(void );
 int smbrun(char *cmd,char *outfile);
-
-/*The following definitions come from  username.c  */
-
+void write_utmp(int dologin, int connection, int pid,
+                char *from_addr, char *username);
 char *get_home_dir(char *user);
 void map_username(char *user);
 struct passwd *Get_Pwnam(char *user,BOOL allow_change);
 BOOL user_in_list(char *user,char *list);
-
-/*The following definitions come from  util.c  */
-
 void setup_logging(char *pname,BOOL interactive);
 void reopen_logs(void);
 BOOL is_a_socket(int fd);
@@ -821,9 +657,9 @@ time_t file_modtime(char *fname);
 BOOL directory_exist(char *dname,struct stat *st);
 uint32 file_size(char *file_name);
 char *attrib_string(int mode);
-int StrCaseCmp(char *s, char *t);
-int StrnCaseCmp(char *s, char *t, int n);
-BOOL strequal(char *s1,char *s2);
+int StrCaseCmp(const char *s, const char *t);
+int StrnCaseCmp(const char *s, const char *t, int n);
+BOOL strequal(const char *s1, const char *s2);
 BOOL strnequal(char *s1,char *s2,int n);
 BOOL strcsequal(char *s1,char *s2);
 void strlower(char *s);
@@ -908,9 +744,6 @@ char *gidtoname(int gid);
 void BlockSignals(BOOL block,int signum);
 void ajt_panic(void);
 char *readdirname(void *p);
-
-/*The following definitions come from  vt_mode.c  */
-
 int    VT_Check(char   *buffer);
 int VT_Start_utmp(void);
 int VT_Stop_utmp(void);
index 31ad3da31cb7c07f65bd3701f7c758a86333ac89..45fdb045060f3a8c2e18b7e4c65d087341c0c70d 100644 (file)
@@ -119,26 +119,26 @@ void reopen_logs(void)
     {
       strcpy(fname,debugf);
       if (lp_loaded() && (*lp_logfile()))
-       strcpy(fname,lp_logfile());
+    strcpy(fname,lp_logfile());
 
       if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
-       {
-         strcpy(debugf,fname);
-         if (dbf) fclose(dbf);
-         if (append_log)
-           dbf = fopen(debugf,"a");
-         else
-           dbf = fopen(debugf,"w");
-         if (dbf) setbuf(dbf,NULL);
-       }
+    {
+      strcpy(debugf,fname);
+      if (dbf) fclose(dbf);
+      if (append_log)
+        dbf = fopen(debugf,"a");
+      else
+        dbf = fopen(debugf,"w");
+      if (dbf) setbuf(dbf,NULL);
+    }
     }
   else
     {
       if (dbf)
-       {
-         fclose(dbf);
-         dbf = NULL;
-       }
+    {
+      fclose(dbf);
+      dbf = NULL;
+    }
     }
 }
 
@@ -204,13 +204,13 @@ va_dcl
 #endif  
     {
       if (!dbf) 
-       {
-         dbf = fopen(debugf,"w");
-         if (dbf)
-           setbuf(dbf,NULL);
-         else
-           return(0);
-       }
+    {
+          dbf = fopen(debugf,"w");
+      if (dbf)
+        setbuf(dbf,NULL);
+      else
+        return(0);
+    }
     }
 
 #ifdef SYSLOG
@@ -222,19 +222,19 @@ va_dcl
        * necessarily errors
        */
       static int priority_map[] = { 
-       LOG_ERR,     /* 0 */
-       LOG_WARNING, /* 1 */
-       LOG_NOTICE,  /* 2 */
-       LOG_INFO,    /* 3 */
+    LOG_ERR,     /* 0 */
+    LOG_WARNING, /* 1 */
+    LOG_NOTICE,  /* 2 */
+    LOG_INFO,    /* 3 */
       };
       int priority;
       pstring msgbuf;
       
       if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
-         syslog_level < 0)
-       priority = LOG_DEBUG;
+      syslog_level < 0)
+    priority = LOG_DEBUG;
       else
-       priority = priority_map[syslog_level];
+    priority = priority_map[syslog_level];
       
 #ifdef __STDC__
       va_start(ap, format_str);
@@ -312,9 +312,9 @@ BOOL next_token(char **ptr,char *buff,char *sep)
   for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
     {
       if (*s == '\"') 
-       quoted = !quoted;
+    quoted = !quoted;
       else
-       *buff++ = *s;
+    *buff++ = *s;
     }
 
   *ptr = (*s) ? s+1 : s;  
@@ -387,34 +387,34 @@ void *MemMove(void *dest,void *src,int size)
     {
       /* we can forward copy */
       if (s-d >= sizeof(int) && 
-         !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
-       /* do it all as words */
-       int *idest = (int *)dest;
-       int *isrc = (int *)src;
-       size /= sizeof(int);
-       for (i=0;i<size;i++) idest[i] = isrc[i];
+      !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
+    /* do it all as words */
+    int *idest = (int *)dest;
+    int *isrc = (int *)src;
+    size /= sizeof(int);
+    for (i=0;i<size;i++) idest[i] = isrc[i];
       } else {
-       /* simplest */
-       char *cdest = (char *)dest;
-       char *csrc = (char *)src;
-       for (i=0;i<size;i++) cdest[i] = csrc[i];
+    /* simplest */
+    char *cdest = (char *)dest;
+    char *csrc = (char *)src;
+    for (i=0;i<size;i++) cdest[i] = csrc[i];
       }
     }
   else
     {
       /* must backward copy */
       if (d-s >= sizeof(int) && 
-         !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
-       /* do it all as words */
-       int *idest = (int *)dest;
-       int *isrc = (int *)src;
-       size /= sizeof(int);
-       for (i=size-1;i>=0;i--) idest[i] = isrc[i];
+      !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
+    /* do it all as words */
+    int *idest = (int *)dest;
+    int *isrc = (int *)src;
+    size /= sizeof(int);
+    for (i=size-1;i>=0;i--) idest[i] = isrc[i];
       } else {
-       /* simplest */
-       char *cdest = (char *)dest;
-       char *csrc = (char *)src;
-       for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
+    /* simplest */
+    char *cdest = (char *)dest;
+    char *csrc = (char *)src;
+    for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
       }      
     }
   return(dest);
@@ -486,7 +486,7 @@ struct
 #endif
   {NULL,0,0,0,0}};
 
-       
+    
 
 /****************************************************************************
 set user socket options
@@ -503,44 +503,44 @@ void set_socket_options(int fd, char *options)
       BOOL got_value = False;
 
       if ((p = strchr(tok,'=')))
-       {
-         *p = 0;
-         value = atoi(p+1);
-         got_value = True;
-       }
+    {
+      *p = 0;
+      value = atoi(p+1);
+      got_value = True;
+    }
 
       for (i=0;socket_options[i].name;i++)
-       if (strequal(socket_options[i].name,tok))
-         break;
+    if (strequal(socket_options[i].name,tok))
+      break;
 
       if (!socket_options[i].name)
-       {
-         DEBUG(0,("Unknown socket option %s\n",tok));
-         continue;
-       }
+    {
+      DEBUG(0,("Unknown socket option %s\n",tok));
+      continue;
+    }
 
       switch (socket_options[i].opttype)
-       {
-       case OPT_BOOL:
-       case OPT_INT:
-         ret = setsockopt(fd,socket_options[i].level,
-                          socket_options[i].option,(char *)&value,sizeof(int));
-         break;
-
-       case OPT_ON:
-         if (got_value)
-           DEBUG(0,("syntax error - %s does not take a value\n",tok));
-
-         {
-           int on = socket_options[i].value;
-           ret = setsockopt(fd,socket_options[i].level,
-                            socket_options[i].option,(char *)&on,sizeof(int));
-         }
-         break;          
-       }
+    {
+    case OPT_BOOL:
+    case OPT_INT:
+      ret = setsockopt(fd,socket_options[i].level,
+               socket_options[i].option,(char *)&value,sizeof(int));
+      break;
+
+    case OPT_ON:
+      if (got_value)
+        DEBUG(0,("syntax error - %s does not take a value\n",tok));
+
+      {
+        int on = socket_options[i].value;
+        ret = setsockopt(fd,socket_options[i].level,
+                 socket_options[i].option,(char *)&on,sizeof(int));
+      }
+      break;      
+    }
       
       if (ret != 0)
-       DEBUG(0,("Failed to set socket option %s\n",tok));
+    DEBUG(0,("Failed to set socket option %s\n",tok));
     }
 }
 
@@ -636,8 +636,8 @@ static int name_interpret(char *in,char *out)
   while (len--)
     {
       if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
-       *out = 0;
-       return(0);
+    *out = 0;
+    return(0);
       }
       *out = ((in[0]-'A')<<4) + (in[1]-'A');
       in += 2;
@@ -695,7 +695,7 @@ int name_mangle(char *In,char *Out,char name_type)
     {
       p = strchr(label, '.');
       if (p == 0)
-       p = label + strlen(label);
+    p = label + strlen(label);
       *out++ = p - label;
       memcpy(out, label, p - label);
       out += p - label;
@@ -772,7 +772,7 @@ char *attrib_string(int mode)
   if (mode & aARCH) strcat(attrstr,"A");
   if (mode & aHIDDEN) strcat(attrstr,"H");
   if (mode & aSYSTEM) strcat(attrstr,"S");
-  if (mode & aRONLY) strcat(attrstr,"R");        
+  if (mode & aRONLY) strcat(attrstr,"R");     
 
   return(attrstr);
 }
@@ -781,7 +781,7 @@ char *attrib_string(int mode)
 /*******************************************************************
   case insensitive string compararison
 ********************************************************************/
-int StrCaseCmp(char *s, char *t)
+int StrCaseCmp(const char *s, const char *t)
 {
   for (; tolower(*s) == tolower(*t); ++s, ++t)
     if (!*s) return 0;
@@ -792,7 +792,7 @@ int StrCaseCmp(char *s, char *t)
 /*******************************************************************
   case insensitive string compararison, length limited
 ********************************************************************/
-int StrnCaseCmp(char *s, char *t, int n)
+int StrnCaseCmp(const char *s, const char *t, int n)
 {
   while (n-- && *s && *t) {
     if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
@@ -806,7 +806,7 @@ int StrnCaseCmp(char *s, char *t, int n)
 /*******************************************************************
   compare 2 strings 
 ********************************************************************/
-BOOL strequal(char *s1,char *s2)
+BOOL strequal(const char *s1, const char *s2)
 {
   if (s1 == s2) return(True);
   if (!s1 || !s2) return(False);
@@ -845,18 +845,18 @@ void strlower(char *s)
   while (*s)
     {
 #ifdef KANJI
-       if (is_shift_jis (*s)) {
-           s += 2;
-       } else if (is_kana (*s)) {
-           s++;
-       } else {
-           if (isupper(*s))
-               *s = tolower(*s);
-           s++;
-       }
+    if (is_shift_jis (*s)) {
+        s += 2;
+    } else if (is_kana (*s)) {
+        s++;
+    } else {
+        if (isupper(*s))
+        *s = tolower(*s);
+        s++;
+    }
 #else
       if (isupper(*s))
-         *s = tolower(*s);
+      *s = tolower(*s);
       s++;
 #endif /* KANJI */
     }
@@ -870,18 +870,18 @@ void strupper(char *s)
   while (*s)
     {
 #ifdef KANJI
-       if (is_shift_jis (*s)) {
-           s += 2;
-       } else if (is_kana (*s)) {
-           s++;
-       } else {
-           if (islower(*s))
-               *s = toupper(*s);
-           s++;
-       }
+    if (is_shift_jis (*s)) {
+        s += 2;
+    } else if (is_kana (*s)) {
+        s++;
+    } else {
+        if (islower(*s))
+        *s = toupper(*s);
+        s++;
+    }
 #else
       if (islower(*s))
-       *s = toupper(*s);
+    *s = toupper(*s);
       s++;
 #endif
     }
@@ -918,18 +918,18 @@ void string_replace(char *s,char oldc,char newc)
   while (*s)
     {
 #ifdef KANJI
-       if (is_shift_jis (*s)) {
-           s += 2;
-       } else if (is_kana (*s)) {
-           s++;
-       } else {
-           if (oldc == *s)
-               *s = newc;
-           s++;
-       }
+    if (is_shift_jis (*s)) {
+        s += 2;
+    } else if (is_kana (*s)) {
+        s++;
+    } else {
+        if (oldc == *s)
+        *s = newc;
+        s++;
+    }
 #else
       if (oldc == *s)
-       *s = newc;
+    *s = newc;
       s++;
 #endif /* KANJI */
     }
@@ -977,22 +977,22 @@ void show_msg(char *buf)
     return;
 
   DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
-         smb_len(buf),
-         (int)CVAL(buf,smb_com),
-         (int)CVAL(buf,smb_rcls),
-         (int)CVAL(buf,smb_reh),
-         (int)SVAL(buf,smb_err),
-         (int)CVAL(buf,smb_flg),
-         (int)SVAL(buf,smb_flg2)));
+      smb_len(buf),
+      (int)CVAL(buf,smb_com),
+      (int)CVAL(buf,smb_rcls),
+      (int)CVAL(buf,smb_reh),
+      (int)SVAL(buf,smb_err),
+      (int)CVAL(buf,smb_flg),
+      (int)SVAL(buf,smb_flg2)));
   DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
-         (int)SVAL(buf,smb_tid),
-         (int)SVAL(buf,smb_pid),
-         (int)SVAL(buf,smb_uid),
-         (int)SVAL(buf,smb_mid),
-         (int)CVAL(buf,smb_wct)));
+      (int)SVAL(buf,smb_tid),
+      (int)SVAL(buf,smb_pid),
+      (int)SVAL(buf,smb_uid),
+      (int)SVAL(buf,smb_mid),
+      (int)CVAL(buf,smb_wct)));
   for (i=0;i<(int)CVAL(buf,smb_wct);i++)
     DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
-         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
+      SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
   bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
   DEBUG(5,("smb_bcc=%d\n",bcc));
   if (DEBUGLEVEL < 10)
@@ -1109,14 +1109,14 @@ BOOL trim_string(char *s,char *front,char *back)
       char *p = s;
       ret = True;
       while (1)
-       {
-         if (!(*p = p[strlen(front)]))
-           break;
-         p++;
-       }
+    {
+      if (!(*p = p[strlen(front)]))
+        break;
+      p++;
+    }
     }
   while (back && *back && strlen(s) >= strlen(back) && 
-        (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
+     (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
     {
       ret = True;
       s[strlen(s)-strlen(back)] = 0;
@@ -1145,9 +1145,9 @@ void dos_clean_name(char *s)
       strcpy(s1,p+3);
 
       if ((p=strrchr(s,'\\')) != NULL)
-       *p = 0;
+    *p = 0;
       else
-       *s = 0;
+    *s = 0;
       strcat(s,s1);
     }  
 
@@ -1176,9 +1176,9 @@ void unix_clean_name(char *s)
       strcpy(s1,p+3);
 
       if ((p=strrchr(s,'/')) != NULL)
-       *p = 0;
+    *p = 0;
       else
-       *s = 0;
+    *s = 0;
       strcat(s,s1);
     }  
 
@@ -1251,10 +1251,10 @@ char *GetWd(char *str)
     {
       getwd_cache_init = True;
       for (i=0;i<MAX_GETWDCACHE;i++)
-       {
-         string_init(&ino_list[i].text,"");
-         ino_list[i].valid = False;
-       }
+    {
+      string_init(&ino_list[i].text,"");
+      ino_list[i].valid = False;
+    }
     }
 
   /*  Get the inode of the current directory, if this doesn't work we're
@@ -1271,35 +1271,35 @@ char *GetWd(char *str)
     if (ino_list[i].valid)
       {
 
-       /*  If we have found an entry with a matching inode and dev number
-           then find the inode number for the directory in the cached string.
-           If this agrees with that returned by the stat for the current
-           directory then all is o.k. (but make sure it is a directory all
-           the same...) */
+    /*  If we have found an entry with a matching inode and dev number
+        then find the inode number for the directory in the cached string.
+        If this agrees with that returned by the stat for the current
+        directory then all is o.k. (but make sure it is a directory all
+        the same...) */
       
-       if (st.st_ino == ino_list[i].inode &&
-           st.st_dev == ino_list[i].dev)
-         {
-           if (stat(ino_list[i].text,&st2) == 0)
-             {
-               if (st.st_ino == st2.st_ino &&
-                   st.st_dev == st2.st_dev &&
-                   (st2.st_mode & S_IFMT) == S_IFDIR)
-                 {
-                   strcpy (str, ino_list[i].text);
-
-                   /* promote it for future use */
-                   array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
-                   return (str);
-                 }
-               else
-                 {
-                   /*  If the inode is different then something's changed, 
-                       scrub the entry and start from scratch. */
-                   ino_list[i].valid = False;
-                 }
-             }
-         }
+    if (st.st_ino == ino_list[i].inode &&
+        st.st_dev == ino_list[i].dev)
+      {
+        if (stat(ino_list[i].text,&st2) == 0)
+          {
+        if (st.st_ino == st2.st_ino &&
+            st.st_dev == st2.st_dev &&
+            (st2.st_mode & S_IFMT) == S_IFDIR)
+          {
+            strcpy (str, ino_list[i].text);
+
+            /* promote it for future use */
+            array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
+            return (str);
+          }
+        else
+          {
+            /*  If the inode is different then something's changed, 
+            scrub the entry and start from scratch. */
+            ino_list[i].valid = False;
+          }
+          }
+      }
       }
 
 
@@ -1358,10 +1358,10 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
       unix_clean_name(s);
       /* can't have a leading .. */
       if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
-       {
-         DEBUG(3,("Illegal file name? (%s)\n",s));
-         return(False);
-       }
+    {
+      DEBUG(3,("Illegal file name? (%s)\n",s));
+      return(False);
+    }
       return(True);
     }
   
@@ -1398,11 +1398,11 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
 
     if (p && (p != basename))
       {
-       *p = 0;
-       if (strcmp(p+1,".")==0)
-         p[1]=0;
-       if (strcmp(p+1,"..")==0)
-         *p = '/';
+    *p = 0;
+    if (strcmp(p+1,".")==0)
+      p[1]=0;
+    if (strcmp(p+1,"..")==0)
+      *p = '/';
       }
 
   if (ChDir(basename) != 0)
@@ -1432,17 +1432,17 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
 
     if (strncmp(newname,dir2,l) != 0)
       {
-       ChDir(wd);
-       DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
-       return(False);
+    ChDir(wd);
+    DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
+    return(False);
       }
 
     if (relative)
       {
-       if (newname[l] == '/')
-         strcpy(s,newname + l + 1);
-       else
-         strcpy(s,newname+l);
+    if (newname[l] == '/')
+      strcpy(s,newname + l + 1);
+    else
+      strcpy(s,newname+l);
       }
     else
       strcpy(s,newname);
@@ -1471,7 +1471,7 @@ static void expand_one(char *Mask,int len)
       pstring tmp;
       strcpy(tmp,Mask);  
       memset(tmp+l1,'?',lfill);
-      strcpy(tmp + l1 + lfill,Mask + l1 + 1);  
+      strcpy(tmp + l1 + lfill,Mask + l1 + 1);   
       strcpy(Mask,tmp);      
     }
 }
@@ -1508,10 +1508,10 @@ void expand_mask(char *Mask,BOOL doext)
     {
       strcpy(mext,"");
       if (strlen(mbeg) > 8)
-       {
-         strcpy(mext,mbeg + 8);
-         mbeg[8] = 0;
-       }
+    {
+      strcpy(mext,mbeg + 8);
+      mbeg[8] = 0;
+    }
     }
 
   if (*mbeg == 0)
@@ -1545,14 +1545,14 @@ BOOL strhasupper(char *s)
   while (*s) 
     {
 #ifdef KANJI
-       if (is_shift_jis (*s)) {
-           s += 2;
-       } else if (is_kana (*s)) {
-           s++;
-       } else {
-           if (isupper(*s)) return(True);
-           s++;
-       }
+    if (is_shift_jis (*s)) {
+        s += 2;
+    } else if (is_kana (*s)) {
+        s++;
+    } else {
+        if (isupper(*s)) return(True);
+        s++;
+    }
 #else 
       if (isupper(*s)) return(True);
       s++;
@@ -1569,14 +1569,14 @@ BOOL strhaslower(char *s)
   while (*s) 
     {
 #ifdef KANJI
-       if (is_shift_jis (*s)) {
-           s += 2;
-       } else if (is_kana (*s)) {
-           s++;
-       } else {
-           if (islower(*s)) return(True);
-           s++;
-       }
+    if (is_shift_jis (*s)) {
+        s += 2;
+    } else if (is_kana (*s)) {
+        s++;
+    } else {
+        if (islower(*s)) return(True);
+        s++;
+    }
 #else 
       if (islower(*s)) return(True);
       s++;
@@ -1594,7 +1594,7 @@ int count_chars(char *s,char c)
   while (*s) 
     {
       if (*s == c)
-       count++;
+    count++;
       s++;
     }
   return(count);
@@ -1756,13 +1756,13 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
     while (nread < mincnt) {
       readret = read(fd, buf + nread, maxcnt - nread);
       if (readret == 0) {
-       smb_read_error = READ_EOF;
-       return -1;
+    smb_read_error = READ_EOF;
+    return -1;
       }
 
       if (readret == -1) {
-       smb_read_error = READ_ERROR;
-       return -1;
+    smb_read_error = READ_ERROR;
+    return -1;
       }
       nread += readret;
     }
@@ -1771,9 +1771,9 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
   
   /* Most difficult - timeout read */
   /* If this is ever called on a disk file and 
-        mincnt is greater then the filesize then
-        system performance will suffer severely as 
-        select always return true on disk files */
+     mincnt is greater then the filesize then
+     system performance will suffer severely as 
+     select always return true on disk files */
 
   /* Set initial timeout */
   timeout.tv_sec = time_out / 1000;
@@ -1788,28 +1788,28 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
 
       /* Check if error */
       if(selrtn == -1) {
-       /* something is wrong. Maybe the socket is dead? */
-       smb_read_error = READ_ERROR;
-       return -1;
+    /* something is wrong. Maybe the socket is dead? */
+    smb_read_error = READ_ERROR;
+    return -1;
       }
       
       /* Did we timeout ? */
       if (selrtn == 0) {
-       smb_read_error = READ_TIMEOUT;
-       return -1;
+    smb_read_error = READ_TIMEOUT;
+    return -1;
       }
       
       readret = read(fd, buf+nread, maxcnt-nread);
       if (readret == 0) {
-       /* we got EOF on the file descriptor */
-       smb_read_error = READ_EOF;
-       return -1;
+    /* we got EOF on the file descriptor */
+    smb_read_error = READ_EOF;
+    return -1;
       }
 
       if (readret == -1) {
-       /* the descriptor is probably dead */
-       smb_read_error = READ_ERROR;
-       return -1;
+    /* the descriptor is probably dead */
+    smb_read_error = READ_ERROR;
+    return -1;
       }
       
       nread += readret;
@@ -1853,7 +1853,7 @@ values
 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
 {
   return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
-        ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
+     ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
 }
 
 /****************************************************************************
@@ -1885,12 +1885,12 @@ int read_data(int fd,char *buffer,int N)
     {
       ret = read(fd,buffer + total,N - total);
       if (ret == 0) {
-       smb_read_error = READ_EOF;
-       return 0;
+    smb_read_error = READ_EOF;
+    return 0;
       }
       if (ret == -1) {
-       smb_read_error = READ_ERROR;
-       return -1;
+    smb_read_error = READ_ERROR;
+    return -1;
       }
       total += ret;
     }
@@ -1959,37 +1959,37 @@ int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
       ret = 0;
 
       if (header && (headlen >= MIN(s,1024))) {
-       buf1 = header;
-       s = headlen;
-       ret = headlen;
-       headlen = 0;
-       header = NULL;
+    buf1 = header;
+    s = headlen;
+    ret = headlen;
+    headlen = 0;
+    header = NULL;
       } else {
-       buf1 = abuf;
+    buf1 = abuf;
       }
 
       if (header && headlen > 0)
-       {
-         ret = MIN(headlen,size);
-         memcpy(buf1,header,ret);
-         headlen -= ret;
-         header += ret;
-         if (headlen <= 0) header = NULL;
-       }
+    {
+      ret = MIN(headlen,size);
+      memcpy(buf1,header,ret);
+      headlen -= ret;
+      header += ret;
+      if (headlen <= 0) header = NULL;
+    }
 
       if (s > ret)
-       ret += read(infd,buf1+ret,s-ret);
+    ret += read(infd,buf1+ret,s-ret);
 
       if (ret > 0)
-       {
-         ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
-         if (ret2 > 0) total += ret2;
-         /* if we can't write then dump excess data */
-         if (ret2 != ret)
-           transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
-       }
+    {
+      ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
+      if (ret2 > 0) total += ret2;
+      /* if we can't write then dump excess data */
+      if (ret2 != ret)
+        transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
+    }
       if (ret <= 0 || ret2 != ret)
-       return(total);
+    return(total);
       n -= ret;
     }
   return(total);
@@ -2015,21 +2015,21 @@ int read_smb_length(int fd,char *inbuf,int timeout)
   while (!ok)
     {
       if (timeout > 0)
-       ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
+    ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
       else 
-       ok = (read_data(fd,buffer,4) == 4);
+    ok = (read_data(fd,buffer,4) == 4);
 
       if (!ok)
-       return(-1);
+    return(-1);
 
       len = smb_len(buffer);
       msg_type = CVAL(buffer,0);
 
       if (msg_type == 0x85) 
-       {
-         DEBUG(5,("Got keepalive packet\n"));
-         ok = False;
-       }
+    {
+      DEBUG(5,("Got keepalive packet\n"));
+      ok = False;
+    }
     }
 
   DEBUG(10,("got smb length of %d\n",len));
@@ -2084,11 +2084,11 @@ BOOL send_smb(int fd,char *buffer)
     {
       ret = write_socket(fd,buffer+nwritten,len - nwritten);
       if (ret <= 0)
-       {
-         DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
+    {
+      DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
           close_sockets();
-         exit(1);
-       }
+      exit(1);
+    }
       nwritten += ret;
     }
 
@@ -2172,14 +2172,14 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
   
   if (DEBUGLEVEL > 0)
     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
-            len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
-       
+         len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
+    
   /* send it */
   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
 
   if (!ret)
     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
-            inet_ntoa(ip),port,errno));
+         inet_ntoa(ip),port,errno));
 
   close(out_fd);
   return(ret);
@@ -2223,11 +2223,11 @@ BOOL in_list(char *s,char *list,BOOL casesensitive)
   while (next_token(&p,tok,LIST_SEP))
     {
       if (casesensitive) {
-       if (strcmp(tok,s) == 0)
-         return(True);
+    if (strcmp(tok,s) == 0)
+      return(True);
       } else {
-       if (StrCaseCmp(tok,s) == 0)
-         return(True);
+    if (StrCaseCmp(tok,s) == 0)
+      return(True);
       }
     }
   return(False);
@@ -2250,7 +2250,7 @@ BOOL string_init(char **dest,char *src)
   if (l == 0)
     {
       if (!null_string)
-       null_string = (char *)malloc(1);
+    null_string = (char *)malloc(1);
 
       *null_string = 0;
       *dest = null_string;
@@ -2338,29 +2338,29 @@ BOOL do_match(char *str, char *regexp, int case_sig)
 
     case '*':
       /* Look for a character matching 
-        the one after the '*' */
+     the one after the '*' */
       p++;
       if(!*p)
-       return True; /* Automatic match */
+    return True; /* Automatic match */
       while(*str) {
-       while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
-         str++;
-       if(do_match(str,p,case_sig))
-         return True;
-       if(!*str)
-         return False;
-       else
-         str++;
+    while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
+      str++;
+    if(do_match(str,p,case_sig))
+      return True;
+    if(!*str)
+      return False;
+    else
+      str++;
       }
       return False;
 
     default:
       if(case_sig) {
-       if(*str != *p)
-         return False;
+    if(*str != *p)
+      return False;
       } else {
-       if(toupper(*str) != toupper(*p))
-         return False;
+    if(toupper(*str) != toupper(*p))
+      return False;
       }
       str++, p++;
       break;
@@ -2479,8 +2479,8 @@ void become_daemon(void)
     int i = open("/dev/tty", O_RDWR);
     if (i >= 0) 
       {
-       ioctl(i, (int) TIOCNOTTY, (char *)0);      
-       close(i);
+    ioctl(i, (int) TIOCNOTTY, (char *)0);      
+    close(i);
       }
   }
 #endif
@@ -2535,39 +2535,39 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
     {
       c = getc(f);
       switch (c)
-       {
-       case '\r':
-         break;
-       case '\n':
-         while (len > 0 && s[len-1] == ' ')
-           {
-             s[--len] = 0;
-           }
-         if (len > 0 && s[len-1] == '\\')
-           {
-             s[--len] = 0;
-             start_of_line = True;
-             break;
-           }
-         return(s);
-       case EOF:
-         if (len <= 0 && !s2) 
-           free(s);
-         return(len>0?s:NULL);
-       case ' ':
-         if (start_of_line)
-           break;
-       default:
-         start_of_line = False;
-         s[len++] = c;
-         s[len] = 0;
-       }
+    {
+    case '\r':
+      break;
+    case '\n':
+      while (len > 0 && s[len-1] == ' ')
+        {
+          s[--len] = 0;
+        }
+      if (len > 0 && s[len-1] == '\\')
+        {
+          s[--len] = 0;
+          start_of_line = True;
+          break;
+        }
+      return(s);
+    case EOF:
+      if (len <= 0 && !s2) 
+        free(s);
+      return(len>0?s:NULL);
+    case ' ':
+      if (start_of_line)
+        break;
+    default:
+      start_of_line = False;
+      s[len++] = c;
+      s[len] = 0;
+    }
       if (!s2 && len > maxlen-3)
-       {
-         maxlen *= 2;
-         s = (char *)Realloc(s,maxlen);
-         if (!s) return(NULL);
-       }
+    {
+      maxlen *= 2;
+      s = (char *)Realloc(s,maxlen);
+      if (!s) return(NULL);
+    }
     }
   return(s);
 }
@@ -2825,16 +2825,16 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
     { 
       if (port) {
-       if (port == SMB_PORT || port == NMB_PORT)
-         DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
-                       port,socket_addr,strerror(errno))); 
-       close(res); 
+    if (port == SMB_PORT || port == NMB_PORT)
+      DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
+            port,socket_addr,strerror(errno))); 
+    close(res); 
 
-       if (dlevel > 0 && port < 1000)
-         port = 7999;
+    if (dlevel > 0 && port < 1000)
+      port = 7999;
 
-       if (port >= 1000 && port < 9000)
-         return(open_socket_in(type,port+1,dlevel,socket_addr));
+    if (port >= 1000 && port < 9000)
+      return(open_socket_in(type,port+1,dlevel,socket_addr));
       }
 
       return(-1); 
@@ -3258,8 +3258,8 @@ char *readdirname(void *p)
     static BOOL broken_readdir = False;
     if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
       {
-       DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
-       broken_readdir = True;
+    DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
+    broken_readdir = True;
       }
     if (broken_readdir)
       return(dname-2);
index ff2c89df85296785105d25b5ba901eed0af402b1..84a5f2627ec9656b9d389d1f7f6dc63a13fbf168 100644 (file)
@@ -23,6 +23,9 @@
    14 jan 96: lkcl@pires.co.uk
    added multiple workgroup domain master support
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -34,8 +37,6 @@ extern BOOL CanRecurse;
 
 extern struct in_addr ipzero;
 
-extern pstring myname;
-
 extern int ClientDGRAM;
 extern int ClientNMB;
 
@@ -43,14 +44,17 @@ extern int ClientNMB;
 extern struct subnet_record *subnetlist;
 
 extern int  updatecount;
-extern int  workgroup_count;
 
-extern struct in_addr ipgrp;
+extern struct in_addr ipgrp;                          
 
+extern pstring myname;
 
 
 /****************************************************************************
-  send a announce request to the local net
+  Send a announce request to the local net.
+  
+  This is called by become_master(). This purpose of this action is to
+  encourage servers to send us host announcements right away.
   **************************************************************************/
 void announce_request(struct work_record *work, struct in_addr ip)
 {
@@ -62,7 +66,7 @@ void announce_request(struct work_record *work, struct in_addr ip)
   work->needannounce = True;
 
   DEBUG(2,("sending announce request to %s for workgroup %s\n",
-          inet_ntoa(ip),work->work_group));
+       inet_ntoa(ip),work->work_group));
 
   bzero(outbuf,sizeof(outbuf));
   p = outbuf;
@@ -71,8 +75,7 @@ void announce_request(struct work_record *work, struct in_addr ip)
 
   CVAL(p,0) = work->token; /* (local) unique workgroup token id */
   p++;
-  StrnCpy(p,myname,16);
-  strupper(p);
+  StrnCpy(p,conf_browsing_alias(work->token),16);
   p = skip_string(p,1);
   
   /* XXXX note: if we sent the announcement request to 0x1d instead
@@ -80,16 +83,17 @@ void announce_request(struct work_record *work, struct in_addr ip)
      us instead of the members of the workgroup. wha-hey! */
 
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
+              conf_browsing_alias(work->token),work->work_group,
+              0x20,                            0x1e,
+              ip,*iface_ip(ip));
 }
 
 
 /****************************************************************************
   request an announcement
   **************************************************************************/
-void do_announce_request(char *info, char *to_name, int announce_type, 
-                        int from,
-                        int to, struct in_addr dest_ip)
+void do_announce_request(char *info, char *from_name, char *to_name,
+             int announce_type, int from, int to, struct in_addr dest_ip)
 {
   pstring outbuf;
   char *p;
@@ -100,14 +104,15 @@ void do_announce_request(char *info, char *to_name, int announce_type,
   p++;
   
   DEBUG(2,("sending announce type %d: info %s to %s - server %s(%x)\n",
-          announce_type, info, inet_ntoa(dest_ip),to_name,to));
+       announce_type, info, inet_ntoa(dest_ip),to_name,to));
   
   StrnCpy(p,info,16);
   strupper(p);
   p = skip_string(p,1);
   
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
+              from_name,to_name,from,to,
+              dest_ip,*iface_ip(dest_ip));
 }
 
 
@@ -116,19 +121,23 @@ void do_announce_request(char *info, char *to_name, int announce_type,
   control ends up back here via response_name_query.
   **************************************************************************/
 void sync_server(enum state_type state, char *serv_name, char *work_name, 
-                int name_type,
-                struct in_addr ip)
-{                     
+         int name_type,
+         struct in_addr ip)
+{
+  int token = conf_workgroup_name_to_token(work_name, myname);
+
   /* with a domain master we can get the whole list (not local only list) */
   BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
 
   add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
 
-  if (state == NAME_STATUS_DOM_SRV_CHK)
+  if (state == NAME_STATUS_DOM_SRV_CHK && conf_should_local_master(token))
   {
     /* announce ourselves as a master browser to serv_name */
-    do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
-                         0x20, 0, ip);
+    do_announce_request(conf_browsing_alias(token), /* info */
+                        conf_browsing_alias(token), /* from */
+                        serv_name, /* to */
+                        ANN_MasterAnnouncement, 0x20, 0,ip);
   }
 }
 
@@ -137,46 +146,46 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
   send a host announcement packet
   **************************************************************************/
 void do_announce_host(int command,
-               char *from_name, int from_type, struct in_addr from_ip,
-               char *to_name  , int to_type  , struct in_addr to_ip,
-               time_t announce_interval,
-               char *server_name, int server_type, char *server_comment)
+        char *from_name, int from_type, struct in_addr from_ip,
+        char *to_name  , int to_type  , struct in_addr to_ip,
+        time_t announce_interval,
+        char *server_name, int server_type, char *server_comment)
 {
-       pstring outbuf;
-       char *p;
+    pstring outbuf;
+    char *p;
 
-       bzero(outbuf,sizeof(outbuf));
-       p = outbuf+1;
+    bzero(outbuf,sizeof(outbuf));
+    p = outbuf+1;
 
-       /* command type */
-       CVAL(outbuf,0) = command;
+    /* command type */
+    CVAL(outbuf,0) = command;
 
-       /* announcement parameters */
-       CVAL(p,0) = updatecount;
-       SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
+    /* announcement parameters */
+    CVAL(p,0) = updatecount;
+    SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
 
-       StrnCpy(p+5,server_name,16);
-       strupper(p+5);
+    StrnCpy(p+5,server_name,16);
+    strupper(p+5);
 
-       CVAL(p,21) = 0x02; /* major version */
-       CVAL(p,22) = 0x02; /* minor version */
+    CVAL(p,21) = 0x02; /* major version */
+    CVAL(p,22) = 0x02; /* minor version */
 
-       SIVAL(p,23,server_type);
-       SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
-       SSVAL(p,29,0xaa55); /* browse signature */
+    SIVAL(p,23,server_type);
+    SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
+    SSVAL(p,29,0xaa55); /* browse signature */
 
-       strcpy(p+31,server_comment);
-       p += 31;
-       p = skip_string(p,1);
+    strcpy(p+31,server_comment);
+    p += 31;
+    p = skip_string(p,1);
 
     debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
 
-       /* send the announcement */
-       send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
-                                         PTR_DIFF(p,outbuf),
-                                         from_name, to_name,
-                                         from_type, to_type,
-                                         to_ip, from_ip);
+    /* send the announcement */
+    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
+                      PTR_DIFF(p,outbuf),
+                      from_name, to_name,
+                      from_type, to_type,
+                      to_ip, from_ip);
 }
 
 
@@ -185,20 +194,23 @@ void do_announce_host(int command,
   ****************************************************************************/
 void remove_my_servers(void)
 {
-       struct subnet_record *d; 
-       for (d = subnetlist; d; d = d->next)
-       {
-               struct work_record *work;
-               for (work = d->workgrouplist; work; work = work->next)
-               {
-                       struct server_record *s;
-                       for (s = work->serverlist; s; s = s->next)
-                       {
-                               if (!strequal(myname,s->serv.name)) continue;
-                               announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
-                       }
-               }
-       }
+    struct subnet_record *d; 
+    for (d = subnetlist; d; d = d->next)
+    {
+        struct work_record *work;
+        for (work = d->workgrouplist; work; work = work->next)
+        {
+            struct server_record *s;
+            for (s = work->serverlist; s; s = s->next)
+            {
+                if (!strequal(conf_browsing_alias(work->token),s->serv.name))
+                {
+                   continue;
+                }
+                announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
+            }
+        }
+    }
 }
 
 
@@ -206,7 +218,7 @@ void remove_my_servers(void)
   announce a server entry
   ****************************************************************************/
 void announce_server(struct subnet_record *d, struct work_record *work,
-                    char *name, char *comment, time_t ttl, int server_type)
+             char *name, char *comment, time_t ttl, int server_type)
 {
        uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE;
        BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
@@ -223,7 +235,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
                                /* look up the domain master with the WINS server */
                                queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
                                         NAME_QUERY_ANNOUNCE_HOST,
-                                        work->work_group,0x1b,0,ttl*1000,
+                                        work->token,work->work_group,0x1b,0,ttl*1000,
                                         server_type,name,comment,
                                         False, False, ipzero, d->bcast_ip);
                        }
@@ -293,11 +305,6 @@ void announce_host(void)
   time_t t = time(NULL);
   struct subnet_record *d;
   pstring comment;
-  char *my_name;
-
-  StrnCpy(comment, lp_serverstring(), 43);
-
-  my_name = *myname ? myname : "NoName";
 
   for (d = subnetlist; d; d = d->next)
     {
@@ -306,53 +313,62 @@ void announce_host(void)
       if (ip_equal(d->bcast_ip, ipgrp)) continue;
 
       for (work = d->workgrouplist; work; work = work->next)
-       {
-         uint32 stype = work->ServerType;
-         struct server_record *s;
-         BOOL announce = False;
-         
+    {
+      uint32 stype = work->ServerType;
+      struct server_record *s;
+      BOOL announce = False;
+      
+      char *my_name    = conf_browsing_alias(work->token);
+      char *my_comment = conf_browsing_alias_comment(work->token);
+
+      my_name    = my_name    ? my_name    : myname;
+      my_comment = my_comment ? my_comment : lp_server_comment();
+
+      StrnCpy(comment, my_comment, 43);
+
       /* must work on the code that does announcements at up to
          30 seconds later if a master browser sends us a request
          announce.
        */
 
-         if (work->needannounce) {
-           /* drop back to a max 3 minute announce - this is to prevent a
-              single lost packet from stuffing things up for too long */
-           work->announce_interval = MIN(work->announce_interval,
-                                               CHECK_TIME_MIN_HOST_ANNCE*60);
-           work->lastannounce_time = t - (work->announce_interval+1);
-         }
-         
-         /* announce every minute at first then progress to every 12 mins */
-         if (work->lastannounce_time && 
-             (t - work->lastannounce_time) < work->announce_interval)
-           continue;
-         
-         if (work->announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60) 
-           work->announce_interval += 60;
-         
-         work->lastannounce_time = t;
-
-         for (s = work->serverlist; s; s = s->next) {
-           if (strequal(myname, s->serv.name)) { 
-             announce = True; 
-             break; 
-           }
-         }
-         
-         if (announce) {
-           announce_server(d,work,my_name,comment,
-                           work->announce_interval,stype);
-         }
-         
-         if (work->needannounce)
-         {
-             work->needannounce = False;
-             break;
-             /* sorry: can't do too many announces. do some more later */
-         }
-       }
+      if (work->needannounce) {
+        /* drop back to a max 3 minute announce - this is to prevent a
+           single lost packet from stuffing things up for too long */
+        work->announce_interval = MIN(work->announce_interval,
+                        CHECK_TIME_MIN_HOST_ANNCE*60);
+        work->lastannounce_time = t - (work->announce_interval+1);
+      }
+      
+      /* announce every minute at first then progress to every 12 mins */
+      if (work->lastannounce_time && 
+          (t - work->lastannounce_time) < work->announce_interval)
+        continue;
+      
+      if (work->announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60) 
+        work->announce_interval += 60;
+      
+      work->lastannounce_time = t;
+
+      for (s = work->serverlist; s; s = s->next) {
+        if (strequal(my_name, s->serv.name))
+        { 
+          announce = True; 
+          break; 
+        }
+      }
+      
+      if (announce) {
+        announce_server(d,work,my_name,comment,
+                work->announce_interval,stype);
+      }
+      
+      if (work->needannounce)
+      {
+          work->needannounce = False;
+          break;
+          /* sorry: can't do too many announces. do some more later */
+      }
+    }
   }
 }
 
@@ -373,97 +389,96 @@ void announce_master(void)
 
   if (!last) last = t;
   if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
-       return;
+    return;
 
   last = t;
 
   for (d = subnetlist; d; d = d->next)
+  {
+    struct work_record *work;
+    for (work = d->workgrouplist; work; work = work->next)
     {
-      struct work_record *work;
-      for (work = d->workgrouplist; work; work = work->next)
-       {
-         if (AM_MASTER(work))
-           {
-             am_master = True;
-           }
-       }
+      if (AM_MASTER(work))
+      {
+          am_master = True;
+      }
     }
+  }
   
   if (!am_master) return; /* only proceed if we are a master browser */
   
   for (d = subnetlist; d; d = d->next)
+  {
+    struct work_record *work;
+    for (work = d->workgrouplist; work; work = work->next)
     {
-      struct work_record *work;
-      for (work = d->workgrouplist; work; work = work->next)
-       {
-         struct server_record *s;
-         for (s = work->serverlist; s; s = s->next)
-           {
-             if (strequal(s->serv.name, myname)) continue;
-             
-             /* all DOMs (which should also be master browsers) */
-             if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
-               {
-                 /* check the existence of a pdc for this workgroup, and if
-                    one exists at the specified ip, sync with it and announce
-                    ourselves as a master browser to it */
-                 
-                 if (!*lp_domain_controller() ||
-                     !strequal(lp_domain_controller(), s->serv.name))
-                   {
-                     if (!lp_wins_support() && *lp_wins_server())
-                       {
-                         queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
-                                                NAME_QUERY_DOM_SRV_CHK,
-                                                work->work_group,0x1b,0,0,0,NULL,NULL,
-                                                False, False, ipzero, ipzero);
-                       }
-                     else
-                       {
-                         struct subnet_record *d2;
-                         for (d2 = subnetlist; d2; d2 = d2->next)
-                           {
-                             queue_netbios_packet(d,ClientNMB,NMB_QUERY,
-                                                  NAME_QUERY_DOM_SRV_CHK,
-                                                  work->work_group,0x1b,0,0,0,NULL,NULL,
-                                                  True, False, d2->bcast_ip, d2->bcast_ip);
-                           }
-                       }
-                   }
-               }
-           }
-         
-         /* now do primary domain controller - the one that's not
-            necessarily in our browse lists, although it ought to be
-            this pdc is the one that we get TOLD about through smb.conf.
-            basically, if it's on a subnet that we know about, it may end
-            up in our browse lists (which is why it's explicitly excluded
-            in the code above) */
-         
-         if (*lp_domain_controller())
-           {
-             struct in_addr ip;
-             BOOL bcast = False;
-             
-             ip = *interpret_addr2(lp_domain_controller());
-             
-             if (zero_ip(ip)) {
-               ip = d->bcast_ip;
-               bcast = True;
-             }
-
-             DEBUG(2, ("Searching for DOM %s at %s\n",
-                       lp_domain_controller(), inet_ntoa(ip)));
-             
-             /* check the existence of a pdc for this workgroup, and if
-                one exists at the specified ip, sync with it and announce
-                ourselves as a master browser to it */
-             queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
-                                    work->work_group,0x1b,0,0,0,NULL,NULL,
-                                    bcast, False, ip, ip);
-           }
-       }
+      struct server_record *s;
+      for (s = work->serverlist; s; s = s->next)
+      {
+        if (strequal(s->serv.name, conf_browsing_alias(work->token))) continue;
+          
+        /* all DOMs (which should also be master browsers) */
+        if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
+        {
+          /* check the existence of a pdc for this workgroup, and if
+             one exists at the specified ip, sync with it and announce
+             ourselves as a master browser to it */
+          
+          if (!*lp_domain_controller() ||
+              !strequal(lp_domain_controller(), s->serv.name))
+          {
+            if (!lp_wins_support() && *lp_wins_server())
+            {
+              queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
+                         NAME_QUERY_DOM_SRV_CHK,
+                         work->token, work->work_group,0x1b,0,0,0,NULL,NULL,
+                         False, False, ipzero, ipzero);
+            }
+            else
+            {
+              struct subnet_record *d2;
+              for (d2 = subnetlist; d2; d2 = d2->next)
+              {
+                  queue_netbios_packet(d,ClientNMB,NMB_QUERY,
+                           NAME_QUERY_DOM_SRV_CHK,
+                           work->token, work->work_group,0x1b,0,0,0,NULL,NULL,
+                           True, False, d2->bcast_ip, d2->bcast_ip);
+              }
+            }
+          }
+        }
+      }
+      
+      /* now do primary domain controller - the one that's not
+         necessarily in our browse lists, although it ought to be
+         this pdc is the one that we get TOLD about through smb.conf.
+         basically, if it's on a subnet that we know about, it may end
+         up in our browse lists (which is why it's explicitly excluded
+         in the code above) */
+      
+      if (*lp_domain_controller())
+      {
+        struct in_addr ip;
+          
+        ip = *interpret_addr2(lp_domain_controller());
+        
+        /* if the ip is zero, then make the query to samba as a WINS server */
+        /* XXXX later, if this also fails, we could also do a broadcast query on
+           samba's local subnets
+         */
+          
+        DEBUG(2, ("Searching for DOM %s at %s\n",
+            lp_domain_controller(), inet_ntoa(ip)));
+          
+        /* check the existence of a pdc for this workgroup, and if
+           one exists at the specified ip, sync with it and announce
+           ourselves as a master browser to it */
+                       queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
+                                                work->token, work->work_group,0x1b,0,0,0,NULL,NULL,
+                                                False, False, ip, ip);
+                 }
     }
+  }
 }
 
 
@@ -481,6 +496,7 @@ void announce_remote(void)
   pstring s2;
   struct in_addr addr;
   char *comment,*workgroup;
+  int token;
   int stype = DFLT_SERVER_TYPE;
 
   if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
@@ -491,13 +507,16 @@ void announce_remote(void)
   s = lp_remote_announce();
   if (!*s) return;
 
-  comment = lp_serverstring();
-  workgroup = lp_workgroup();
+  comment = lp_serverstring(); /* default comment */
+  workgroup = lp_workgroup();  /* default workgroup name */
 
-  for (ptr=s; next_token(&ptr,s2,NULL); ) {
+  for (ptr=s; next_token(&ptr,s2,NULL); )
+  {
     /* the entries are of the form a.b.c.d/WORKGROUP with 
        WORKGROUP being optional */
     char *wgroup;
+    char *my_name;
+    extern pstring myname; /* samba's default NetBIOS name */
 
     wgroup = strchr(s2,'/');
     if (wgroup) *wgroup++ = 0;
@@ -506,10 +525,14 @@ void announce_remote(void)
 
     addr = *interpret_addr2(s2);
     
-    do_announce_host(ANN_HostAnnouncement,myname,0x20,*iface_ip(addr),
-                    wgroup,0x1e,addr,
-                    REMOTE_ANNOUNCE_INTERVAL,
-                    myname,stype,comment);    
+    token = conf_workgroup_name_to_token(wgroup, myname);
+    my_name = conf_browsing_alias(token);
+    my_name = my_name ? my_name : myname;
+
+    do_announce_host(ANN_HostAnnouncement,
+             my_name, 0x20, *iface_ip(addr),
+             wgroup , 0x1e, addr,
+             REMOTE_ANNOUNCE_INTERVAL,
+             my_name,stype,comment);    
   }
-
 }
index b426bc7a15005404137016c35ab6664a5b1e37d1..8ebf7b8c9007091c29ce8283a9e8fc0e35a43e37 100644 (file)
@@ -23,6 +23,9 @@
    14 jan 96: lkcl@pires.co.uk
    added multiple workgroup domain master support
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -71,21 +74,21 @@ void expire_browse_cache(time_t t)
   for (b = browserlist; b; b = nextb)
     {
       if (b->synced && b->sync_time < t)
-       {
-         DEBUG(3,("Removing dead cached browser %s\n",b->name));
-         nextb = b->next;
-         
-         if (b->prev) b->prev->next = b->next;
-         if (b->next) b->next->prev = b->prev;
-         
-         if (browserlist == b) browserlist = b->next; 
-         
-         free(b);
-       }
+    {
+      DEBUG(3,("Removing dead cached browser %s\n",b->name));
+      nextb = b->next;
+      
+      if (b->prev) b->prev->next = b->next;
+      if (b->next) b->next->prev = b->prev;
+      
+      if (browserlist == b) browserlist = b->next; 
+      
+      free(b);
+    }
       else
-       {
-         nextb = b->next;
-       }
+    {
+      nextb = b->next;
+    }
     }
 }
 
@@ -94,7 +97,7 @@ void expire_browse_cache(time_t t)
   add a browser entry
   ****************************************************************************/
 struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
-                                             time_t ttl, struct in_addr ip, BOOL local)
+                          time_t ttl, struct in_addr ip, BOOL local)
 {
   BOOL newentry=False;
   
@@ -109,9 +112,9 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
   if (b && b->synced)
     {
       /* entries get left in the cache for a while. this stops sync'ing too
-        often if the network is large */
+     often if the network is large */
       DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
-               b->name, b->group, inet_ntoa(b->ip), b->sync_time));
+        b->name, b->group, inet_ntoa(b->ip), b->sync_time));
       return NULL;
     }
   
@@ -146,12 +149,12 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
       add_browse_cache(b);
       
       DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
-              wg, name, type, inet_ntoa(ip),ttl));
+           wg, name, type, inet_ntoa(ip),ttl));
     }
   else
     {
       DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
-              wg, name, type, inet_ntoa(ip),ttl));
+           wg, name, type, inet_ntoa(ip),ttl));
     }
   
   return(b);
@@ -166,23 +169,23 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
   struct subnet_record *d;
   struct work_record *work;
 
-  if (!(d = find_subnet(b->ip))) return;
-
+  if( (d = find_subnet(b->ip)) == (struct subnet_record *)NULL ) return;
+  
   if (!(work = find_workgroupstruct(d, b->group, False))) return;
-
+    
   /* only sync if we are the master */
   if (AM_MASTER(work)) {
-
+    
       /* first check whether the group we intend to sync with exists. if it
          doesn't, the server must have died. o dear. */
-
+    
       /* see response_netbios_packet() or expire_netbios_response_entries() */
       queue_netbios_packet(d,ClientNMB,NMB_QUERY,
                        b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
-                                          b->group,0x20,0,0,0,NULL,NULL,
-                                          False,False,b->ip,b->ip);
+                       work->token,b->group,0x20,0,0,0,NULL,NULL,
+                       False,False,b->ip,b->ip);
   }
-
+    
   b->synced = True;
 }
 
diff --git a/source3/nameconf.c b/source3/nameconf.c
new file mode 100644 (file)
index 0000000..79fa2ab
--- /dev/null
@@ -0,0 +1,349 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   NBT netbios routines and daemon - version 2
+   Copyright (C) David Chappell 1996
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   
+   Revision History:
+
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
+*/
+
+/*
+** nameconf.c
+** These functions dispense information from smbbrowse.conf.
+**
+**
+*/
+
+#include "includes.h"
+extern int DEBUGLEVEL;
+
+#if 0
+struct smbbrowse_parms
+    {
+    char *name;
+    BOOL (*reader)(char *string, void *toset);
+    } smbbrowse_table[] =
+{
+    {"preferred master", NULL},
+    {"local master", NULL},
+    {"domain master", NULL}
+} ;
+#endif
+
+/*
+** Structure for the list of workgroups from smbbrowse.conf.  This 
+** structure should only be manipulated thru the functions in this file.
+** That is why it is not defined in a header file.
+*/
+struct smbbrowse
+{
+    char work_name[16];               /* workgroup name */
+    char browsing_alias[16];          /* alias for our role in this workgroup */
+    struct server_identity *my_names; /* a list of server name we should appear here as */
+    BOOL should_workgroup_member;     /* should we try to become a member of this workgroup? */
+    BOOL should_local_master;         /* should we try to become a master browser? */
+    BOOL should_domain_master;        /* should we try to become the domain master browser? */
+} ;
+
+/* The whole list */
+static struct smbbrowse *smbbrowse_workgroups = (struct smbbrowse*)NULL;
+
+/* The size of the list */
+static int array_size = 0;
+
+/* The next available space in the list */
+static int nexttoken = 0;
+
+int get_num_workgroups(void)
+{
+    return nexttoken;
+}
+
+/*
+** This makes a new workgroup structure, possibly taking an 
+** old one as a model.
+*/
+static struct smbbrowse *new_workgroup(struct smbbrowse *model,
+                                const char *workgroup_name,
+                                const char *default_name)
+{
+    struct smbbrowse *new;
+
+    if( ! (array_size > nexttoken) )
+    {
+    array_size += 10;
+    smbbrowse_workgroups = (struct smbbrowse*)realloc(smbbrowse_workgroups,
+                array_size * sizeof(struct smbbrowse));
+    }
+
+    new = &smbbrowse_workgroups[nexttoken];
+
+    if(model != (struct smbbrowse *)NULL )
+    memcpy(new, model, sizeof(struct smbbrowse));
+    else
+        memset(new, 0, sizeof(struct smbbrowse));
+
+    StrnCpy(new->work_name, workgroup_name, 15);
+    strupper(new->work_name);
+        
+       if (strequal(lp_workgroup(), workgroup_name))
+      StrnCpy(new->browsing_alias, default_name, 15);
+    else
+      sprintf(new->browsing_alias, "%.14s%x", default_name, nexttoken);
+    strupper(new->browsing_alias);
+
+       DEBUG(4,("wg: %s alias: %s token: %x\n",
+               new->work_name, new->browsing_alias, nexttoken));
+
+    nexttoken++;
+    return new;
+}
+
+/*
+** If fed a workgroup name, this function returns its token number.
+** If the workgroup does not exist a new token is assigned unless
+** new workgroups are not allowed.
+*/
+int conf_workgroup_name_to_token(const char *workgroup_name,
+                                                                const char *default_name)
+{
+    int idx;
+    
+    /* Look for an existing instance. */
+    for(idx=0; idx < nexttoken; idx++)
+    {
+        if(strequal(workgroup_name, smbbrowse_workgroups[idx].work_name))
+        {
+            return idx;
+        }
+    }
+    
+    /* See if creating new ones in admissable. */
+    for(idx=0; idx < nexttoken; idx++)
+    {
+        if(strequal("*", smbbrowse_workgroups[idx].work_name))
+        {
+            struct smbbrowse *w = new_workgroup(&smbbrowse_workgroups[idx],
+                                                workgroup_name, default_name);
+            w->should_workgroup_member = False;
+
+            return (nexttoken - 1);
+        }
+    }
+
+    /* Not allowed */
+    DEBUG(4, ("refusing to allow new workgroup\n"));
+    return -1;
+}
+
+/*
+** This is a workgroups array bounds checker.
+*/
+static int range_check(int token)
+{
+    if(token < 0 || token >= nexttoken)
+    {
+    DEBUG(0, ("range_check(): failed\n"));
+        return True;
+        }
+        
+    return False;
+}
+
+/*
+** Given a token, return the name.
+*/
+char *conf_workgroup_name(int token)
+{
+    if(range_check(token))
+        return (char*)NULL;
+    
+    return smbbrowse_workgroups[token].work_name;
+}
+
+/*
+** Given a token, return True if we should try
+** to become a master browser.
+*/
+int conf_should_workgroup_member(int token)
+    {
+
+    if(range_check(token))
+        return False;
+    
+    return smbbrowse_workgroups[token].should_workgroup_member;
+    }
+
+/*
+** Given a token, return True if we should try
+** to become a master browser.
+*/
+int conf_should_local_master(int token)
+    {
+    if(range_check(token))
+        return False;
+    
+    return smbbrowse_workgroups[token].should_local_master;
+    }
+
+/*
+** Given a token, return True if we should try
+** to become a domain master browser.
+*/
+int conf_should_domain_master(int token)
+    {
+    if(range_check(token))
+        return False;
+    
+    return smbbrowse_workgroups[token].should_domain_master;
+    }
+
+/*
+** Given a token, return the name.
+*/
+char *conf_browsing_alias(int token)
+    {
+    if(range_check(token))
+        return (char*)NULL;
+
+    return smbbrowse_workgroups[token].browsing_alias;
+    }
+
+/*
+** Return the server comment which should be used with the
+** browsing alias.
+*/
+char *conf_browsing_alias_comment(int token)
+{
+    if(range_check(token))
+        return (char*) NULL;
+        
+    return "Browser";
+    }       
+
+/*
+** Given an alias name for this server, return the name of the workgroup 
+** for which it is the browsing alias.
+*/
+char *conf_alias_to_workgroup(const char *alias)
+{
+    int x;
+    
+       DEBUG(4,("alias_to_workgroup: %s", alias));
+
+    for(x=0; x < nexttoken; x++)
+    {
+               DEBUG(4,("%s ", smbbrowse_workgroups[x].browsing_alias));
+
+        if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
+        {
+                       DEBUG(4,("OK\n"));
+            return smbbrowse_workgroups[x].work_name;
+        }
+    }
+       DEBUG(4,("not found\n"));
+    return (char*)NULL;
+}
+
+/*
+** Given an alias name for this server, return the name of the workgroup 
+** for which it is the browsing alias.
+*/
+int conf_alias_to_token(const char *alias)
+{
+    int x;
+    
+    for(x=0; x < nexttoken; x++)
+    {
+        if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
+        {
+            return x;
+        }
+    }
+    return -1;
+}
+
+/*
+** Since there is no smbbrowse.conf file, we will fill in 
+** the structures with information from the smb.conf file.
+*/
+static void default_smbbrowse_conf(const char *default_name)
+{
+    struct smbbrowse *w;
+    
+    /* The workgroup specified in smb.conf */
+    w = new_workgroup((struct smbbrowse *)NULL, lp_workgroup(), default_name);
+    w->should_local_master = lp_preferred_master();
+    w->should_domain_master = lp_domain_master();
+    w->should_workgroup_member = True;
+
+    /* default action: allow any new workgroup to be added */
+    w = new_workgroup((struct smbbrowse *)NULL, "*", default_name);
+    w->should_local_master = False;
+    w->should_domain_master = False;
+    w->should_workgroup_member = False;
+}
+
+/*
+** This function is called from main().
+*/
+void read_smbbrowse_conf(char *default_name)
+{
+  FILE *f = fopen(BROWSEFILE,"r");
+  if (f)
+  {
+    while (!feof(f))
+    {
+      pstring line;
+      char *ptr;
+      int count = 0;
+  
+      pstring work_name;
+      struct smbbrowse *w;
+
+      if (!fgets_slash(line,sizeof(pstring),f)) continue;
+  
+      if (*line == '#') continue;
+  
+      strcpy(work_name,"");
+        
+      ptr = line;
+        
+      if (next_token(&ptr, work_name, NULL)) ++count;
+        
+      if (count <= 0) continue;
+        
+      w = new_workgroup((struct smbbrowse *)NULL, work_name, default_name);
+      w->should_local_master = lp_local_master();
+      w->should_domain_master = lp_domain_master();
+      w->should_workgroup_member = True;
+    }
+
+    fclose(f);
+  }
+  else
+  {
+    DEBUG(2,("Can't open browse configuration file %s\n",BROWSEFILE));
+  }
+  default_smbbrowse_conf(default_name);    
+}
+
+
index 1f16553b0f416e848041300dd20b0ae8dbd8468f..74777a9145670c2b683cf8b7d923324c82459547 100644 (file)
 
    04 jul 96: lkcl@pires.co.uk
    created module namedbname containing name database functions
+
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -52,14 +56,14 @@ uint16 nb_type = 0; /* samba's NetBIOS name type */
   ****************************************************************************/
 void set_samba_nb_type(void)
 {
-       if (lp_wins_support() || (*lp_wins_server()))
-       {
-               nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
-       }
-       else
-       {
-               nb_type = NB_BFLAG; /* samba is broadcast-only node type */
-       }
+    if (lp_wins_support() || (*lp_wins_server()))
+    {
+        nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
+    }
+    else
+    {
+        nb_type = NB_BFLAG; /* samba is broadcast-only node type */
+    }
 }
 
 
@@ -69,7 +73,7 @@ void set_samba_nb_type(void)
 BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
 {
   return n1->name_type == n2->name_type &&
-                strequal(n1->name ,n2->name ) &&
+         strequal(n1->name ,n2->name ) &&
          strequal(n1->scope,n2->scope);
 }
 
@@ -140,22 +144,22 @@ void remove_name(struct subnet_record *d, struct name_record *n)
   find a name in a namelist.
   **************************************************************************/
 struct name_record *find_name(struct name_record *n,
-                       struct nmb_name *name,
-                       int search)
+            struct nmb_name *name,
+            int search)
 {
-       struct name_record *ret;
+    struct name_record *ret;
   
-       for (ret = n; ret; ret = ret->next)
-       {
-               if (name_equal(&ret->name,name))
-               {
-                       /* self search: self names only */
-                       if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
-                               continue;
-         
-                       return ret;
-               }
-       }
+    for (ret = n; ret; ret = ret->next)
+    {
+        if (name_equal(&ret->name,name))
+        {
+            /* self search: self names only */
+            if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
+                continue;
+      
+            return ret;
+        }
+    }
     return NULL;
 }
 
@@ -168,29 +172,31 @@ struct name_record *find_name(struct name_record *n,
   FIND_WINS - look for names in the WINS record
   **************************************************************************/
 struct name_record *find_name_search(struct subnet_record **d,
-                       struct nmb_name *name,
-                       int search, struct in_addr ip)
+            struct nmb_name *name,
+            int search, struct in_addr ip)
 {
-       if (d == NULL) return NULL; /* bad error! */
-       
-    if (search & FIND_LOCAL) {
-      if (*d != NULL) {
-       struct name_record *n = find_name((*d)->namelist, name, search);
-       DEBUG(4,("find_name on local: %s %s search %x\n",
-                namestr(name),inet_ntoa(ip), search));
-       if (n) return n;
-      }
+    if (d == NULL) return NULL; /* bad error! */
+    
+    if (search & FIND_LOCAL)
+    {
+        if (*d != NULL)
+        {
+            struct name_record *n = find_name((*d)->namelist, name, search);
+            DEBUG(4,("find_name on local: %s %s search %x\n",
+                        namestr(name),inet_ntoa(ip), search));
+            if (n) return n;
+        }
     }
 
-    if (!(search & FIND_WINS)) return NULL;
+    if ((search & FIND_WINS) != FIND_WINS) return NULL;
 
     /* find WINS subnet record. */
     *d = find_subnet(ipgrp);
-    
+
     if (*d == NULL) return NULL;
-    
+
     DEBUG(4,("find_name on WINS: %s %s search %x\n",
-            namestr(name),inet_ntoa(ip), search));
+                        namestr(name),inet_ntoa(ip), search));
     return find_name((*d)->namelist, name, search);
 }
 
@@ -228,20 +234,19 @@ void dump_names(void)
     {
       int i;
 
-         DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
-         DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
-      DEBUG(3,("%-19s TTL=%ld ",
-              namestr(&n->name),
-              n->death_time?n->death_time-t:0));
+      DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
+      DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
+      DEBUG(3,("%-19s TTL=%ld source=%d",
+           namestr(&n->name),
+           n->death_time?n->death_time-t:0, n->source));
 
         for (i = 0; i < n->num_ips; i++)
         {
-           DEBUG(3,("%15s NB=%2x source=%d",
-                   inet_ntoa(n->ip_flgs[i].ip),
-                   n->ip_flgs[i].nb_flags,n->source));
-
+           DEBUG(3,("%15s NB=%2x ",
+                        inet_ntoa(n->ip_flgs[i].ip),
+                        n->ip_flgs[i].nb_flags));
         }
-               DEBUG(3,("\n"));
+        DEBUG(3,("\n"));
 
       if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
       {
@@ -249,16 +254,16 @@ void dump_names(void)
          anything other than as a hexadecimal number :-) */
 
         fprintf(f, "%s#%02x %ld ",
-              n->name.name,n->name.name_type, /* XXXX ignore scope for now */
-              n->death_time);
+           n->name.name,n->name.name_type, /* XXXX ignore scope for now */
+           n->death_time);
 
         for (i = 0; i < n->num_ips; i++)
         {
            fprintf(f, "%s %2x ",
-                                               inet_ntoa(n->ip_flgs[i].ip),
-                                               n->ip_flgs[i].nb_flags);
+                        inet_ntoa(n->ip_flgs[i].ip),
+                        n->ip_flgs[i].nb_flags);
         }
-               fprintf(f, "\n");
+        fprintf(f, "\n");
       }
 
     }
@@ -307,12 +312,12 @@ void load_netbios_names(void)
       int type = 0;
       unsigned int nb_flags;
       time_t ttd;
-         struct in_addr ipaddr;
+      struct in_addr ipaddr;
 
-         enum name_source source;
+      enum name_source source;
 
       char *ptr;
-         int count = 0;
+      int count = 0;
 
       char *p;
 
@@ -320,20 +325,20 @@ void load_netbios_names(void)
 
       if (*line == '#') continue;
 
-       ptr = line;
+    ptr = line;
 
-       if (next_token(&ptr,name_str    ,NULL)) ++count;
-       if (next_token(&ptr,ttd_str     ,NULL)) ++count;
-       if (next_token(&ptr,ip_str      ,NULL)) ++count;
-       if (next_token(&ptr,nb_flags_str,NULL)) ++count;
+    if (next_token(&ptr,name_str    ,NULL)) ++count;
+    if (next_token(&ptr,ttd_str     ,NULL)) ++count;
+    if (next_token(&ptr,ip_str      ,NULL)) ++count;
+    if (next_token(&ptr,nb_flags_str,NULL)) ++count;
 
-       if (count <= 0) continue;
+    if (count <= 0) continue;
 
-       if (count != 4) {
-         DEBUG(0,("Ill formed wins line"));
-         DEBUG(0,("[%s]: name#type abs_time ip nb_flags\n",line));
-         continue;
-       }
+    if (count != 4) {
+      DEBUG(0,("Ill formed wins line"));
+      DEBUG(0,("[%s]: name#type abs_time ip nb_flags\n",line));
+      continue;
+    }
 
       /* netbios name. # divides the name from the type (hex): netbios#xx */
       strcpy(name,name_str);
@@ -341,15 +346,15 @@ void load_netbios_names(void)
       p = strchr(name,'#');
 
       if (p) {
-           *p = 0;
-           sscanf(p+1,"%x",&type);
+        *p = 0;
+        sscanf(p+1,"%x",&type);
       }
 
       /* decode the netbios flags (hex) and the time-to-die (seconds) */
-         sscanf(nb_flags_str,"%x",&nb_flags);
-         sscanf(ttd_str,"%ld",&ttd);
+      sscanf(nb_flags_str,"%x",&nb_flags);
+      sscanf(ttd_str,"%ld",&ttd);
 
-         ipaddr = *interpret_addr2(ip_str);
+      ipaddr = *interpret_addr2(ip_str);
 
       if (ip_equal(ipaddr,ipzero)) {
          source = SELF;
@@ -360,7 +365,7 @@ void load_netbios_names(void)
       }
 
       DEBUG(4, ("add WINS line: %s#%02x %ld %s %2x\n",
-              name,type, ttd, inet_ntoa(ipaddr), nb_flags));
+           name,type, ttd, inet_ntoa(ipaddr), nb_flags));
 
       /* add all entries that have 60 seconds or more to live */
       if (ttd - 60 > time(NULL) || ttd == 0)
@@ -380,8 +385,8 @@ void load_netbios_names(void)
   remove an entry from the name list
   ****************************************************************************/
 void remove_netbios_name(struct subnet_record *d,
-                       char *name,int type, enum name_source source,
-                        struct in_addr ip)
+            char *name,int type, enum name_source source,
+             struct in_addr ip)
 {
   struct nmb_name nn;
   struct name_record *n;
@@ -405,9 +410,9 @@ void remove_netbios_name(struct subnet_record *d,
 
   ****************************************************************************/
 struct name_record *add_netbios_entry(struct subnet_record *d,
-               char *name, int type, int nb_flags, 
-               int ttl, enum name_source source, struct in_addr ip,
-               BOOL new_only,BOOL wins)
+        char *name, int type, int nb_flags, 
+        int ttl, enum name_source source, struct in_addr ip,
+        BOOL new_only,BOOL wins)
 {
   struct name_record *n;
   struct name_record *n2=NULL;
@@ -465,46 +470,61 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
   if (!n2) add_name(d,n);
 
   DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
-               namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
+            namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
 
   return(n);
 }
 
 
 /*******************************************************************
-  expires old names in the namelist
+  expires or refreshes old names in the namelist
+
+  if the name is a samba SELF name, it must be refreshed rather than
+  removed.
   ******************************************************************/
-void expire_names(time_t t)
+void check_expire_names(time_t t)
 {
-       struct name_record *n;
-       struct name_record *next;
-       struct subnet_record *d;
-
-       /* expire old names */
-       for (d = subnetlist; d; d = d->next)
-       {
-         for (n = d->namelist; n; n = next)
-           {
-             next = n->next;
-             if (n->death_time && n->death_time < t)
-               {
-                 if (n->source == SELF) {
-                   DEBUG(3,("not expiring SELF name %s\n", namestr(&n->name)));
-                   n->death_time += 300;
-                   continue;
-                 }
-                 DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
-                 
-                 if (n->prev) n->prev->next = n->next;
-                 if (n->next) n->next->prev = n->prev;
-                 
-                 if (d->namelist == n) d->namelist = n->next; 
-                 
-                 free(n->ip_flgs);
-                 free(n);
-               }
-           }
-       }
+    struct name_record *n;
+    struct name_record *next;
+    struct subnet_record *d;
+
+    /* expire old names */
+    for (d = subnetlist; d; d = d->next)
+    {
+        for (n = d->namelist; n; n = next)
+        {
+            if (n->death_time && n->death_time < t)
+            {
+                if (n->source == SELF)
+                {
+                    /* refresh the samba name. if this refresh fails
+                       for any reason, it will be deleted.
+                     */
+                    DEBUG(3,("Refreshing SELF name %s\n", namestr(&n->name)));
+                    add_my_name_entry(d, -1, 
+                                    n->name.name, n->name.name_type,
+                                    n->ip_flgs[0].nb_flags);
+                    continue;
+                }         
+                
+                DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
+                              
+                next = n->next;
+                              
+                if (n->prev) n->prev->next = n->next;
+                if (n->next) n->next->prev = n->prev;
+                              
+                if (d->namelist == n) d->namelist = n->next; 
+                              
+                free(n->ip_flgs);
+                free(n);
+            }
+            else
+            {
+                next = n->next;
+            }
+        }
+    }
 }
 
 
@@ -512,8 +532,8 @@ void expire_names(time_t t)
   reply to a name query
   ****************************************************************************/
 struct name_record *search_for_name(struct subnet_record **d,
-                                       struct nmb_name *question,
-                                   struct in_addr ip, int Time, int search)
+                    struct nmb_name *question,
+                    struct in_addr ip, int Time, int search)
 {
   int name_type = question->name_type;
   char *qname = question->name;
@@ -538,10 +558,10 @@ struct name_record *search_for_name(struct subnet_record **d,
       
       /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
       if (!dns_type && name_type != 0x1b)
-       {
-         DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
-         return NULL;
-       }
+    {
+      DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
+      return NULL;
+    }
       
       /* look it up with DNS */      
       a = interpret_addr(qname);
@@ -549,18 +569,18 @@ struct name_record *search_for_name(struct subnet_record **d,
       putip((char *)&dns_ip,(char *)&a);
       
       if (!a)
-       {
-         /* no luck with DNS. We could possibly recurse here XXXX */
-         DEBUG(3,("no recursion.\n"));
+    {
+      /* no luck with DNS. We could possibly recurse here XXXX */
+      DEBUG(3,("no recursion.\n"));
       /* add the fail to our WINS cache of names. give it 1 hour in the cache */
-         add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
-                                               True, True);
-         return NULL;
-       }
+      add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
+                        True, True);
+      return NULL;
+    }
       
       /* add it to our WINS cache of names. give it 2 hours in the cache */
       n = add_netbios_entry(*d,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
-                                               True,True);
+                        True,True);
       
       /* failed to add it? yikes! */
       if (!n) return NULL;
index d89bfe8ae843bbd042faf8dffdaf8ee895c9a87b..10a9523b8da35c33e3842e56aed143c4ded77284 100644 (file)
@@ -92,8 +92,8 @@ void remove_response_record(struct subnet_record *d,
   create a name query response record
   **************************************************************************/
 struct response_record *make_response_queue_record(enum state_type state,
-                               int id,uint16 fd,
-                               int quest_type, char *name,int type, int nb_flags, time_t ttl,
+                               int id,uint16 fd, int quest_type,
+                int token, char *name,int type, int nb_flags, time_t ttl,
                                int server_type, char *my_name, char *my_comment,
                                BOOL bcast,BOOL recurse,
                                struct in_addr send_ip, struct in_addr reply_to_ip)
@@ -109,14 +109,16 @@ struct response_record *make_response_queue_record(enum state_type state,
   n->state = state;
   n->fd = fd;
   n->quest_type = quest_type;
+
+  n->token = token;
   make_nmb_name(&n->name, name, type, scope);
-  n->nb_flags = nb_flags;
   n->ttl = ttl;
   n->server_type = server_type;
   n->bcast = bcast;
   n->recurse = recurse;
+  n->reply.nb_flags = nb_flags;
+  n->reply.ip = reply_to_ip;
   n->send_ip = send_ip;
-  n->reply_to_ip = reply_to_ip;
   StrnCpy(my_name   , n->my_name   , sizeof(n->my_name   )-1);
   StrnCpy(my_comment, n->my_comment, sizeof(n->my_comment)-1);
 
index afb1dc1431550d80503ad30b37d2934b16622e59..260f8f3475e0072a5cdaa3a01f6be95c321cf399 100644 (file)
@@ -50,7 +50,7 @@ extern BOOL updatedlists;
   remove_all_servers indicates everybody dies.
   ******************************************************************/
 void remove_old_servers(struct work_record *work, time_t t,
-                                       BOOL remove_all)
+                    BOOL remove_all)
 {
   struct server_record *s;
   struct server_record *nexts;
@@ -59,23 +59,23 @@ void remove_old_servers(struct work_record *work, time_t t,
   for (s = work->serverlist; s; s = nexts)
     {
       if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
-       {
-         DEBUG(3,("Removing dead server %s\n",s->serv.name));
-         updatedlists = True;
-         nexts = s->next;
-         
-         if (s->prev) s->prev->next = s->next;
-         if (s->next) s->next->prev = s->prev;
-         
-         if (work->serverlist == s) 
-           work->serverlist = s->next; 
-
-         free(s);
-       }
+    {
+      DEBUG(3,("Removing dead server %s\n",s->serv.name));
+      updatedlists = True;
+      nexts = s->next;
+      
+      if (s->prev) s->prev->next = s->next;
+      if (s->next) s->next->prev = s->prev;
+      
+      if (work->serverlist == s) 
+        work->serverlist = s->next; 
+
+      free(s);
+    }
       else
-       {
-         nexts = s->next;
-       }
+    {
+      nexts = s->next;
+    }
     }
 }
 
@@ -107,17 +107,17 @@ static void add_server(struct work_record *work,struct server_record *s)
   **************************************************************************/
 struct server_record *find_server(struct work_record *work, char *name)
 {
-       struct server_record *ret;
+    struct server_record *ret;
   
-       if (!work) return NULL;
-
-       for (ret = work->serverlist; ret; ret = ret->next)
-       {
-               if (strequal(ret->serv.name,name))
-               {
-                       return ret;
-               }
-       }
+    if (!work) return NULL;
+
+    for (ret = work->serverlist; ret; ret = ret->next)
+    {
+        if (strequal(ret->serv.name,name))
+        {
+            return ret;
+        }
+    }
     return NULL;
 }
 
@@ -126,14 +126,15 @@ struct server_record *find_server(struct work_record *work, char *name)
   add a server entry
   ****************************************************************************/
 struct server_record *add_server_entry(struct subnet_record *d, 
-                                      struct work_record *work,
-                                      char *name,int servertype, 
-                                      int ttl,char *comment,
-                                      BOOL replace)
+                       struct work_record *work,
+                       char *name,int servertype, 
+                       int ttl,char *comment,
+                       BOOL replace)
 {
   BOOL newentry=False;
   struct server_record *s;
-  
+  int token = conf_workgroup_name_to_token(work->work_group, myname);
+
   if (name[0] == '*')
   {
       return (NULL);
@@ -160,16 +161,14 @@ struct server_record *add_server_entry(struct subnet_record *d,
     bzero((char *)s,sizeof(*s));
   }
   
-  
-  if (strequal(lp_workgroup(),work->work_group))
-    {
-         if (servertype)
-        servertype |= SV_TYPE_LOCAL_LIST_ONLY;
-    }
+  if (conf_should_workgroup_member(token))
+  {
+    if (servertype) servertype |= SV_TYPE_LOCAL_LIST_ONLY;
+  }
   else
-    {
+  {
       servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
-    }
+  }
   
   /* update the entry */
   StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
@@ -194,8 +193,8 @@ struct server_record *add_server_entry(struct subnet_record *d,
     }
   
   DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
-          name,servertype,comment,
-          work->work_group,inet_ntoa(d->bcast_ip)));
+       name,servertype,comment,
+       work->work_group,inet_ntoa(d->bcast_ip)));
   
   return(s);
 }
@@ -213,9 +212,9 @@ void expire_servers(time_t t)
       struct work_record *work;
       
       for (work = d->workgrouplist; work; work = work->next)
-       {
-         remove_old_servers(work, t, False);
-       }
+    {
+      remove_old_servers(work, t, False);
+    }
     }
 }
 
index 0bad79246ad7a968a590080c651f01e3a0492cff..94decb7f0b75aae8ebc825065cc44155a83c9d6b 100644 (file)
@@ -26,6 +26,9 @@
    04 jul 96: lkcl@pires.co.uk
    created module namedbsubnet containing subnet database functions
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -90,16 +93,16 @@ struct subnet_record *find_subnet(struct in_addr bcast_ip)
   for (d = subnetlist; d; d = d->next)
     {
         if (ip_equal(bcast_ip, wins_ip))
-           {
+        {
            if (ip_equal(bcast_ip, d->bcast_ip))
            {
                return d;
            }
         }
         else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
-           {
-             return(d);
-           }
+        {
+          return(d);
+        }
     }
   
   return (NULL);
@@ -154,24 +157,24 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
   ****************************************************************************/
 void add_subnet_interfaces(void)
 {
-       struct interface *i;
-
-       /* loop on all local interfaces */
-       for (i = local_interfaces; i; i = i->next)
-       {
-               /* add the interface into our subnet database */
-               if (!find_subnet(i->bcast))
-               {
-                 make_subnet(i->bcast,i->nmask);
-               }
-       }
-
-       /* add the pseudo-ip interface for WINS: 255.255.255.255 */
-       if (lp_wins_support() || (*lp_wins_server()))
+    struct interface *i;
+
+    /* loop on all local interfaces */
+    for (i = local_interfaces; i; i = i->next)
     {
-               struct in_addr wins_bcast = ipgrp;
-               struct in_addr wins_nmask = ipzero;
-               make_subnet(wins_bcast, wins_nmask);
+        /* add the interface into our subnet database */
+        if (!find_subnet(i->bcast))
+        {
+          make_subnet(i->bcast,i->nmask);
+        }
+    }
+
+    /* add the pseudo-ip interface for WINS: 255.255.255.255 */
+    if (lp_wins_support() || (*lp_wins_server()))
+    {
+        struct in_addr wins_bcast = ipgrp;
+        struct in_addr wins_nmask = ipzero;
+        make_subnet(wins_bcast, wins_nmask);
     }
 }
 
@@ -188,7 +191,7 @@ void add_my_subnets(char *group)
   
   if (*group == '*') return;
 
-       /* the coding choice is up to you, andrew: i can see why you don't want
+    /* the coding choice is up to you, andrew: i can see why you don't want
        global access to the local_interfaces structure: so it can't get
        messed up! */
     for (i = local_interfaces; i; i = i->next)
@@ -203,8 +206,8 @@ void add_my_subnets(char *group)
   to the named a workgroup.
   ****************************************************************************/
 struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
-                                      struct in_addr mask_ip,
-                                      char *name, BOOL add, BOOL lmhosts)
+                       struct in_addr mask_ip,
+                       char *name, BOOL add, BOOL lmhosts)
 {
   struct subnet_record *d;
 
@@ -222,29 +225,41 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
   /* add the domain into our domain database */
   if ((d = find_subnet(bcast_ip)) ||
       (d = make_subnet(bcast_ip, mask_ip)))
-    {
-      struct work_record *w = find_workgroupstruct(d, name, add);
+  {
+    struct work_record *work = find_workgroupstruct(d, name, add);
       
-      if (!w) return NULL;
-
-      /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
-        or register with WINS server, if it's our workgroup */
-      if (strequal(lp_workgroup(), name))
-       {
-         add_my_name_entry(d,name,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
-         add_my_name_entry(d,name,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
-       }
-      /* add samba server name to workgroup list. don't add
-         lmhosts server entries to local interfaces */
-      if (strequal(lp_workgroup(), name))
-      {
-       add_server_entry(d,w,myname,w->ServerType,0,lp_serverstring(),True);
+    if (!work) return NULL;
+
+    if (conf_should_workgroup_member(work->token))
+    {
+        /* add samba server name to workgroup list. don't add
+           lmhosts server entries to local interfaces */
+
+        pstring comment;
+        char *my_name    = conf_browsing_alias        (work->token);
+        char *my_comment = conf_browsing_alias_comment(work->token);
+
+        my_name    = my_name    ? my_name    : myname;
+        my_comment = my_comment ? my_comment : lp_server_comment();
+
+        StrnCpy(comment, my_comment, 43);
+
+        add_server_entry(d,work,my_name,
+                        work->ServerType | SV_TYPE_LOCAL_LIST_ONLY,
+                        0,comment,True);
+
         DEBUG(3,("Added server name entry %s at %s\n",
                   name,inet_ntoa(bcast_ip)));
-      }
-      
-      return d;
+
+        /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
+           or register with WINS server, if it's our workgroup */
+        add_my_name_entry(d,work->token,name,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
+        add_my_name_entry(d,work->token,name,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
     }
+      
+    return d;
+  }
+
   return NULL;
 }
 
@@ -290,31 +305,31 @@ void write_browse_list(void)
     {
       struct work_record *work;
       for (work = d->workgrouplist; work ; work = work->next)
-       {
-         struct server_record *s;
-         for (s = work->serverlist; s ; s = s->next)
-           {
-             fstring tmp;
-             
-             /* don't list domains I don't have a master for */
-             if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
-               {
-                 continue;
-               }
-             
-             /* output server details, plus what workgroup/domain
-                they're in. without the domain information, the
-                combined list of all servers in all workgroups gets
-                sent to anyone asking about any workgroup! */
-             
-             sprintf(tmp, "\"%s\"", s->serv.name);
-             fprintf(f, "%-25s ", tmp);
-             fprintf(f, "%08x ", s->serv.type);
-             sprintf(tmp, "\"%s\" ", s->serv.comment);
-             fprintf(f, "%-30s", tmp);
-             fprintf(f, "\"%s\"\n", work->work_group);
-           }
-       }
+    {
+      struct server_record *s;
+      for (s = work->serverlist; s ; s = s->next)
+        {
+          fstring tmp;
+          
+          /* don't list domains I don't have a master for */
+          if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
+        {
+          continue;
+        }
+          
+          /* output server details, plus what workgroup/domain
+         they're in. without the domain information, the
+         combined list of all servers in all workgroups gets
+         sent to anyone asking about any workgroup! */
+          
+          sprintf(tmp, "\"%s\"", s->serv.name);
+          fprintf(f, "%-25s ", tmp);
+          fprintf(f, "%08x ", s->serv.type);
+          sprintf(tmp, "\"%s\" ", s->serv.comment);
+          fprintf(f, "%-30s", tmp);
+          fprintf(f, "\"%s\"\n", work->work_group);
+        }
+    }
     }
   
   fclose(f);
index 04f2103254b5aa38c947c2225149d23a9b68d4c6..172a93860c2dab2be6be8b47aa27c78c2d84eb6e 100644 (file)
@@ -26,6 +26,9 @@
    04 jul 96: lkcl@pires.co.uk
    created module namedbwork containing workgroup database functions
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -40,9 +43,7 @@ extern struct subnet_record *subnetlist;
 
 extern struct in_addr ipgrp;
 
-int workgroup_count = 0; /* unique index key: one for each workgroup */
-
-
+extern pstring myname;
 
 /****************************************************************************
   add a workgroup into the domain list
@@ -75,11 +76,17 @@ static void add_workgroup(struct work_record *work, struct subnet_record *d)
 static struct work_record *make_workgroup(char *name)
 {
   struct work_record *work;
-  struct subnet_record *d;
   int t = -1;
   
   if (!name || !name[0]) return NULL;
   
+  /* conf_workgroup_name_to_token() gets or creates a unique index for the workgroup name */
+  if ((t = conf_workgroup_name_to_token(name, myname)) == -1)
+  {
+     DEBUG(3, ("work_record(\"%s\"): conf_workgroup_name_to_token() refuses to allow workgroup\n", name));
+     return (struct work_record *)NULL;
+  }
+  
   work = (struct work_record *)malloc(sizeof(*work));
   if (!work) return(NULL);
   
@@ -92,34 +99,16 @@ static struct work_record *make_workgroup(char *name)
   work->needelection = False;
   work->needannounce = True;
   work->state = MST_NONE;
-  
-  /* make sure all token representations of workgroups are unique */
-  
-  for (d = subnetlist; d && t == -1; d = d->next)
-    {
-      struct work_record *w;
-      for (w = d->workgrouplist; w && t == -1; w = w->next)
-       {
-         if (strequal(w->work_group, work->work_group)) t = w->token;
-       }
-    }
-  
-  if (t == -1)
-    {
-      work->token = ++workgroup_count;
-    }
-  else
-    {
-      work->token = t;
-    }
-  
+  work->token = t;
   
   /* WfWg  uses 01040b01 */
   /* Win95 uses 01041501 */
   /* NTAS  uses ???????? */
   work->ElectionCriterion  = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8); 
   work->ElectionCriterion |= (lp_os_level() << 24);
-  if (lp_domain_master()) {
+
+  if (conf_should_domain_master(work->token))
+  {
     work->ElectionCriterion |= 0x80;
   }
   
@@ -131,8 +120,8 @@ static struct work_record *make_workgroup(char *name)
   remove workgroups
   ******************************************************************/
 struct work_record *remove_workgroup(struct subnet_record *d, 
-                                    struct work_record *work,
-                                        BOOL remove_all_servers)
+                     struct work_record *work,
+                     BOOL remove_all_servers)
 {
   struct work_record *ret_work = NULL;
   
@@ -165,7 +154,7 @@ struct work_record *remove_workgroup(struct subnet_record *d,
   lmhosts file to be added.
   **************************************************************************/
 struct work_record *find_workgroupstruct(struct subnet_record *d, 
-                                        fstring name, BOOL add)
+                     fstring name, BOOL add)
 {
   struct work_record *ret, *work;
   
@@ -174,23 +163,26 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
   DEBUG(4, ("workgroup search for %s: ", name));
   
   if (strequal(name, "*"))
-    {
+  {
       DEBUG(2,("add any workgroups: initiating browser search on %s\n",
-              inet_ntoa(d->bcast_ip)));
+           inet_ntoa(d->bcast_ip)));
       queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
-                            MSBROWSE,0x1,0,0,0,NULL,NULL,
-                            True,False, d->bcast_ip, d->bcast_ip);
+                 -1,MSBROWSE,0x1,0,0,0,NULL,NULL,
+                 True,False, d->bcast_ip, d->bcast_ip);
       return NULL;
-    }
+  }
   
-  for (ret = d->workgrouplist; ret; ret = ret->next) {
-    if (!strcmp(ret->work_group,name)) {
+  for (ret = d->workgrouplist; ret; ret = ret->next)
+  {
+    if (!strcmp(ret->work_group,name))
+    {
       DEBUG(4, ("found\n"));
       return(ret);
     }
   }
 
-  if (!add) {
+  if (!add)
+  {
     DEBUG(4, ("not found\n"));
     return NULL;
   }
@@ -200,13 +192,13 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
   if ((work = make_workgroup(name)))
     {
       if (!ip_equal(d->bcast_ip, ipgrp) &&
-         lp_preferred_master() &&
-         strequal(lp_workgroup(), name))
-       {
-         DEBUG(3, ("preferred master startup for %s\n", work->work_group));
-         work->needelection = True;
-         work->ElectionCriterion |= (1<<3);
-       }
+          lp_preferred_master() &&
+          conf_should_local_master(work->token))
+    {
+      DEBUG(3, ("preferred master startup for %s\n", work->work_group));
+      work->needelection = True;
+      work->ElectionCriterion |= (1<<3);
+    }
       add_workgroup(work, d);
       return(work);
     }
@@ -224,25 +216,25 @@ void dump_workgroups(void)
   for (d = subnetlist; d; d = d->next)
     {
       if (d->workgrouplist)
-       {
-         struct work_record *work;
-         
-         DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
-         DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
-         
-         for (work = d->workgrouplist; work; work = work->next)
-           {
-             DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
-             if (work->serverlist)
-               {
-                 struct server_record *s;                
-                 for (s = work->serverlist; s; s = s->next)
-                   {
-                     DEBUG(4,("\t\t%s %8x (%s)\n",
-                              s->serv.name, s->serv.type, s->serv.comment));
-                   }
-               }
-           }
-       }
+    {
+      struct work_record *work;
+      
+      DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
+      DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
+      
+      for (work = d->workgrouplist; work; work = work->next)
+        {
+          DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
+          if (work->serverlist)
+        {
+          struct server_record *s;        
+          for (s = work->serverlist; s; s = s->next)
+            {
+              DEBUG(4,("\t\t%s %8x (%s)\n",
+                   s->serv.name, s->serv.type, s->serv.comment));
+            }
+        }
+        }
+    }
     }
 }
index 07429013e0db5380d9beef1bb9b1d4507a607172..225b0bfaae0424dfd8d4c5ad81d44685d3e1369f 100644 (file)
    04 jul 96: lkcl@pires.co.uk
    added system to become a master browser by stages.
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
 
 */
 
-#include "includes.h"
+#include "includes.h"          
 
 extern int ClientNMB;
 extern int ClientDGRAM;
@@ -39,7 +41,6 @@ extern int ClientDGRAM;
 extern int DEBUGLEVEL;
 extern pstring scope;
 
-extern pstring myname;
 extern struct in_addr ipzero;
 extern struct in_addr ipgrp;
 
@@ -51,6 +52,9 @@ extern struct subnet_record *subnetlist;
 
 extern uint16 nb_type; /* samba's NetBIOS name type */
 
+extern pstring myname;
+
+
 /*******************************************************************
   occasionally check to see if the master browser is around
   ******************************************************************/
@@ -68,22 +72,22 @@ void check_master_browser(void)
   dump_workgroups();
 
   for (d = subnetlist; d; d = d->next)
+  {
+    struct work_record *work;
+
+    for (work = d->workgrouplist; work; work = work->next)
     {
-      struct work_record *work;
+      /* if we are not the browse master of a workgroup, and we can't
+         find a browser on the subnet, do something about it. */
 
-      for (work = d->workgrouplist; work; work = work->next)
-       {
-         /* if we are not the browse master of a workgroup, and we can't
-            find a browser on the subnet, do something about it. */
-
-         if (!AM_MASTER(work))
-           {
-             queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
-                                  work->work_group,0x1d,0,0,0,NULL,NULL,
-                                  True,False,d->bcast_ip,d->bcast_ip);
-           }
-       }
+      if (!AM_MASTER(work))
+      {
+          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
+                   work->token, work->work_group,0x1d,0,0,0,NULL,NULL,
+                   True,False,d->bcast_ip,d->bcast_ip);
+      }
     }
+  }
 }
 
 
@@ -102,11 +106,11 @@ void browser_gone(char *work_name, struct in_addr ip)
   if (ip_equal(d->bcast_ip,ipgrp)) 
     return;
 
-  if (strequal(work->work_group, lp_workgroup()))
+  if (conf_should_local_master(work->token))
   {
 
       DEBUG(2,("Forcing election on %s %s\n",
-              work->work_group,inet_ntoa(d->bcast_ip)));
+           work->work_group,inet_ntoa(d->bcast_ip)));
 
       /* we can attempt to become master browser */
       work->needelection = True;
@@ -114,10 +118,10 @@ void browser_gone(char *work_name, struct in_addr ip)
   else
   {
      /* local interfaces: force an election */
-    send_election(d, work->work_group, 0, 0, myname);
+    send_election(d, work->work_group, 0, 0, conf_browsing_alias(work->token));
 
      /* only removes workgroup completely on a local interface 
-        persistent lmhosts entries on a local interface _will_ be removed).
+        persistent lmhosts entries on a local interface _will_ be removed.
       */
      remove_workgroup(d, work,True);
   }
@@ -128,7 +132,7 @@ void browser_gone(char *work_name, struct in_addr ip)
   send an election packet
   **************************************************************************/
 void send_election(struct subnet_record *d, char *group,uint32 criterion,
-                  int timeup,char *name)
+           int timeup,char *name)
 {
   pstring outbuf;
   char *p;
@@ -136,7 +140,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
   if (!d) return;
   
   DEBUG(2,("Sending election to %s for workgroup %s\n",
-          inet_ntoa(d->bcast_ip),group));         
+       inet_ntoa(d->bcast_ip),group));     
 
   bzero(outbuf,sizeof(outbuf));
   p = outbuf;
@@ -152,7 +156,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
   p = skip_string(p,1);
   
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
+              name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
 }
 
 
@@ -173,7 +177,7 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
     if (!(work = find_workgroupstruct(d, name, False))) return;
 
     if (ms_browser_name(name, name_type) ||
-        (AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
+        (AM_MASTER(work) && conf_should_workgroup_member(work->token) &&
          (name_type == 0x1d || name_type == 0x1b)))
     {
       int remove_type = 0;
@@ -184,7 +188,7 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
         remove_type = SV_TYPE_MASTER_BROWSER;
       if (name_type == 0x1b)
         remove_type = SV_TYPE_DOMAIN_MASTER;
-                       
+            
       become_nonmaster(d, work, remove_type);
     }
 }
@@ -197,17 +201,20 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
   whether to proceed to the next stage in samba becoming a master browser.
 
   **************************************************************************/
-void name_register_work(struct subnet_record *d, char *name, int name_type,
-                               int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
+void name_register_work(struct subnet_record *d, int token,
+                char *name, int name_type,
+                struct nmb_ip *data, time_t ttl, struct in_addr ip, BOOL bcast)
 {
   enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
-                                                               SELF : REGISTER;
+                                SELF : REGISTER;
 
   if (source == SELF)
   {
-    struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
+    char *work_name = conf_workgroup_name(token);
+    struct work_record *work = find_workgroupstruct(d, work_name, False);
 
-    add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
+    add_netbios_entry(d,name,name_type,data->nb_flags,
+                      ttl,source,data->ip,True,!bcast);
 
     if (work)
     {
@@ -251,11 +258,23 @@ void become_master(struct subnet_record *d, struct work_record *work)
 {
   uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE|
     SV_TYPE_POTENTIAL_BROWSER;
+  pstring comment;
+
+  char *my_name   ;
+  char *my_comment;
 
   if (!work) return;
   
+  my_name    = conf_browsing_alias(work->token);
+  my_comment = conf_browsing_alias_comment(work->token);
+
+  my_name    = my_name    ? my_name    : myname;
+  my_comment = my_comment ? my_comment : lp_server_comment();
+
+  StrnCpy(comment, my_comment, 43);
+  
   DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
-                                       work->work_group,inet_ntoa(d->bcast_ip),work->state));
+                    work->work_group,inet_ntoa(d->bcast_ip),work->state));
   
   switch (work->state)
   {
@@ -268,10 +287,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
 
       /* update our server status */
       work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
-      add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
+      add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
 
       /* add special browser name */
-      add_my_name_entry(d,MSBROWSE        ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
+      add_my_name_entry(d,work->token,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP);
 
       /* DON'T do anything else after calling add_my_name_entry() */
       return;
@@ -282,10 +301,11 @@ void become_master(struct subnet_record *d, struct work_record *work)
       work->state = MST_MSB; /* ... registering MSBROWSE was successful */
 
       /* add server entry on successful registration of MSBROWSE */
-      add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
+      add_server_entry(d,work,work->work_group,
+                       domain_type,0,conf_browsing_alias(work->token),True);
 
       /* add master name */
-      add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
+      add_my_name_entry(d,work->token,work->work_group,0x1d,nb_type|NB_ACTIVE);
   
       /* DON'T do anything else after calling add_my_name_entry() */
       return;
@@ -297,7 +317,8 @@ void become_master(struct subnet_record *d, struct work_record *work)
 
       /* update our server status */
       work->ServerType |= SV_TYPE_MASTER_BROWSER;
-      add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
+      add_server_entry(d,work,conf_browsing_alias(work->token),
+                       work->ServerType,0,comment,True);
 
       if (work->serverlist == NULL) /* no servers! */
       {
@@ -317,13 +338,14 @@ void become_master(struct subnet_record *d, struct work_record *work)
 
    case MST_DOMAIN_NONE:
    {
-      if (lp_domain_master())
+      if (conf_should_domain_master(work->token))
       {
         work->state = MST_DOMAIN_MEM; /* ... become domain member */
         DEBUG(3,("domain first stage: register as domain member\n"));
 
         /* add domain member name */
-        add_my_name_entry(d,work->work_group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
+        add_my_name_entry(d,work->token,work->work_group,0x1e,
+                          nb_type|NB_ACTIVE|NB_GROUP);
 
         /* DON'T do anything else after calling add_my_name_entry() */
         return;
@@ -338,19 +360,20 @@ void become_master(struct subnet_record *d, struct work_record *work)
 
    case MST_DOMAIN_MEM:
    {
-      if (lp_domain_master())
+      if (conf_should_domain_master(work->token))
       {
         work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
         DEBUG(3,("domain second stage: register as domain master\n"));
 
         if (lp_domain_logons())
-           {
+        {
           work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
-          add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
+          add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
         }
 
         /* add domain master name */
-        add_my_name_entry(d,work->work_group,0x1b,nb_type|NB_ACTIVE         );
+        add_my_name_entry(d,work->token,work->work_group,0x1b,
+                          nb_type|NB_ACTIVE         );
 
         /* DON'T do anything else after calling add_my_name_entry() */
         return;
@@ -366,10 +389,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
     case MST_DOMAIN_TST: /* while we were still a master browser... */
     {
       /* update our server status */
-      if (lp_domain_master())
+      if (conf_should_domain_master(work->token))
       {
         struct subnet_record *d1;
-               uint32 update_type = 0;
+        uint32 update_type = 0;
 
         DEBUG(3,("domain third stage: samba is now a domain master.\n"));
         work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
@@ -377,30 +400,30 @@ void become_master(struct subnet_record *d, struct work_record *work)
         update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER | 
          SV_TYPE_POTENTIAL_BROWSER;
 
-               work->ServerType |= update_type;
-               add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
-
-               for (d1 = subnetlist; d1; d1 = d1->next)
-               {
-               struct work_record *w;
-                       if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
-
-               for (w = d1->workgrouplist; w; w = w->next)
-                       {
-                               struct server_record *s = find_server(w, myname);
-                               if (strequal(w->work_group, work->work_group))
-                               {
-                                       w->ServerType |= update_type;
-                               }
-                               if (s)
-                               {
-                                       s->serv.type |= update_type;
-                                       DEBUG(4,("found server %s on %s: update to %8x\n",
-                                                                       s->serv.name, inet_ntoa(d1->bcast_ip),
-                                                                       s->serv.type));
-                               }
-                       }
-               }
+        work->ServerType |= update_type;
+        add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
+
+        for (d1 = subnetlist; d1; d1 = d1->next)
+        {
+            struct work_record *w;
+            if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
+
+            for (w = d1->workgrouplist; w; w = w->next)
+            {
+                struct server_record *s = find_server(w, my_name);
+                if (strequal(w->work_group, work->work_group))
+                {
+                    w->ServerType |= update_type;
+                }
+                if (s)
+                {
+                    s->serv.type |= update_type;
+                    DEBUG(4,("found server %s on %s: update to %8x\n",
+                                    s->serv.name, inet_ntoa(d1->bcast_ip),
+                                    s->serv.type));
+                }
+            }
+        }
       }
   
       break;
@@ -421,10 +444,25 @@ void become_master(struct subnet_record *d, struct work_record *work)
   names, and tells the world that we are no longer a master browser.
   ******************************************************************/
 void become_nonmaster(struct subnet_record *d, struct work_record *work,
-                               int remove_type)
+                int remove_type)
 {
   int new_server_type = work->ServerType;
 
+  pstring comment;
+
+  char *my_name   ;
+  char *my_comment;
+
+  if (!work) return;
+  
+  my_name    = conf_browsing_alias        (work->token);
+  my_comment = conf_browsing_alias_comment(work->token);
+
+  my_name    = my_name    ? my_name    : myname;
+  my_comment = my_comment ? my_comment : lp_server_comment();
+
+  StrnCpy(comment, my_comment, 43);
+  
   DEBUG(2,("Becoming non-master for %s\n",work->work_group));
   
   /* can only remove master or domain types with this function */
@@ -444,9 +482,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
     work->ElectionCriterion &= ~0x4;
     work->state = MST_NONE;
 
-       /* announce ourselves as no longer active as a master browser. */
-    announce_server(d, work, work->work_group, myname, 0, 0);
-    remove_name_entry(d,MSBROWSE        ,0x01);
+    remove_name_entry(d,work->token,MSBROWSE,0x01);
   }
   
   work->ServerType = new_server_type;
@@ -455,15 +491,21 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
   {
     if (work->state == MST_DOMAIN)
       work->state = MST_BROWSER;
-    remove_name_entry(d,work->work_group,0x1b);    
+    remove_name_entry(d,work->token,work->work_group,0x1b);
   }
 
   if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
   {
     if (work->state >= MST_BROWSER)
       work->state = MST_NONE;
-    remove_name_entry(d,work->work_group,0x1d);
+    remove_name_entry(d,work->token,work->work_group,0x1d);
   }
+
+  /* announce ourselves as no longer active as a master browser. */
+  announce_server(d,work,work->work_group,my_name,GET_TTL(0),work->ServerType);
+
+  /* update our internal records with our new server state */
+  add_server_entry(d, work, my_name, work->ServerType, 0, my_comment, True);
 }
 
 
@@ -486,25 +528,25 @@ void run_elections(void)
   {
     struct work_record *work;
     for (work = d->workgrouplist; work; work = work->next)
-       {
-         if (work->RunningElection)
-         {
-           send_election(d,work->work_group, work->ElectionCriterion,
-                           t-StartupTime,myname);
-             
-           if (work->ElectionCount++ >= 4)
-               {
-                 /* I won! now what :-) */
-                 DEBUG(2,(">>> Won election on %s %s <<<\n",
-                          work->work_group,inet_ntoa(d->bcast_ip)));
-                 
-                 work->RunningElection = False;
-                 work->state = MST_NONE;
-
-                 become_master(d, work);
-               }
-         }
-       }
+    {
+      if (work->RunningElection)
+      {
+        send_election(d,work->work_group, work->ElectionCriterion,
+                t-StartupTime,conf_browsing_alias(work->token));
+          
+        if (work->ElectionCount++ >= 4)
+        {
+          /* I won! now what :-) */
+          DEBUG(2,(">>> Won election on %s %s <<<\n",
+               work->work_group,inet_ntoa(d->bcast_ip)));
+          
+          work->RunningElection = False;
+          work->state = MST_NONE;
+
+          become_master(d, work);
+        }
+      }
+    }
   }
 }
 
@@ -513,7 +555,7 @@ void run_elections(void)
   work out if I win an election
   ******************************************************************/
 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
-                        int timeup,char *name)
+             int timeup,char *name)
 {  
   int mytimeup = time(NULL) - StartupTime;
   uint32 mycriterion = work->ElectionCriterion;
@@ -533,7 +575,7 @@ static BOOL win_election(struct work_record *work,int version,uint32 criterion,
   if (timeup > mytimeup) return(False);
   if (timeup < mytimeup) return(True);
 
-  if (strcasecmp(myname,name) > 0) return(False);
+  if (strcasecmp(conf_browsing_alias(work->token),name) > 0) return(False);
   
   return(True);
 }
@@ -571,30 +613,38 @@ void process_election(struct packet_struct *p,char *buf)
   if (same_context(dgram)) return;
   
   for (work = d->workgrouplist; work; work = work->next)
+  {
+    if (!conf_should_local_master(work->token)) continue;
+
+    if (win_election(work, version,criterion,timeup,name))
     {
-      if (!strequal(work->work_group, lp_workgroup()))
-       continue;
-
-      if (win_election(work, version,criterion,timeup,name)) {
-       if (!work->RunningElection) {
-         work->needelection = True;
-         work->ElectionCount=0;
-         work->state = MST_NONE;
-       }
-      } else {
-       work->needelection = False;
-         
-       if (work->RunningElection || AM_MASTER(work)) {
-         work->RunningElection = False;
-         DEBUG(3,(">>> Lost election on %s %s <<<\n",
-                  work->work_group,inet_ntoa(d->bcast_ip)));
-         if (AM_MASTER(work))
-           become_nonmaster(d, work,
-                            SV_TYPE_MASTER_BROWSER|
-                            SV_TYPE_DOMAIN_MASTER);
-       }
-      }
+        if (!work->RunningElection)
+        {
+          work->needelection = True;
+          work->ElectionCount=0;
+          work->state = MST_NONE;
+        }
+    }
+    else
+    {
+        work->needelection = False;
+          
+        if (work->RunningElection || AM_MASTER(work))
+        {
+          work->RunningElection = False;
+          DEBUG(3,(">>> Lost election on %s %s <<<\n",
+               work->work_group,inet_ntoa(d->bcast_ip)));
+          
+          /* if we are the master then remove our masterly names */
+          if (AM_MASTER(work))
+          {
+              become_nonmaster(d, work,
+                    SV_TYPE_MASTER_BROWSER|
+                    SV_TYPE_DOMAIN_MASTER);
+          }
+        }
     }
+  }
 }
 
 
@@ -615,18 +665,18 @@ BOOL check_elections(void)
     {
       struct work_record *work;
       for (work = d->workgrouplist; work; work = work->next)
-       {
-         run_any_election |= work->RunningElection;
-         
-         if (work->needelection && !work->RunningElection)
-           {
-             DEBUG(3,(">>> Starting election on %s %s <<<\n",
-                      work->work_group,inet_ntoa(d->bcast_ip)));
-             work->ElectionCount = 0;
-             work->RunningElection = True;
-             work->needelection = False;
-           }
-       }
+    {
+      run_any_election |= work->RunningElection;
+      
+      if (work->needelection && !work->RunningElection)
+        {
+          DEBUG(3,(">>> Starting election on %s %s <<<\n",
+               work->work_group,inet_ntoa(d->bcast_ip)));
+          work->ElectionCount = 0;
+          work->RunningElection = True;
+          work->needelection = False;
+        }
+    }
     }
   return run_any_election;
 }
index 5bfa55d4f1646645c4788f97588a99dd3cb6b943..1ebdf0a2bd6d74ddf59244c23d8038e0d841a866 100644 (file)
@@ -38,62 +38,137 @@ BOOL CanRecurse = True;
 extern pstring scope;
 extern struct in_addr ipgrp;
 
-static uint16 name_trn_id=0;
+extern uint16 name_trn_id;
 
 
-/***************************************************************************
-  updates the unique transaction identifier
-  **************************************************************************/
-void debug_browse_data(char *outbuf, int len)
+/****************************************************************************
+  process a nmb packet
+  ****************************************************************************/
+static void process_nmb(struct packet_struct *p)
 {
-    int i,j;
-    for (i = 0; i < len; i+= 16)
+  struct nmb_packet *nmb = &p->packet.nmb;
+
+  debug_nmb_packet(p);
+
+  switch (nmb->header.opcode) 
+  {
+    case 8: /* what is this?? */
+    case NMB_REG:
+    case NMB_REG_REFRESH:
+    {
+      if (nmb->header.response)
+      {
+        if (nmb->header.ancount==0) break;
+        response_netbios_packet(p);
+      }
+      else
+      {
+        if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
+        reply_name_reg(p);
+      }
+    break;
+    }
+      
+    case 0:
+    {
+      if (nmb->header.response)
+      {
+        switch (nmb->question.question_type)
+          {
+          case 0x0:
+        {
+          response_netbios_packet(p);
+          break;
+        }
+          }
+        return;
+      }
+      else if (nmb->header.qdcount>0) 
       {
-       DEBUG(4, ("%3x char ", i));
-       
-       for (j = 0; j < 16; j++)
-         {
-           unsigned char x = outbuf[i+j];
-           if (x < 32 || x > 127) x = '.';
-           
-           if (i+j >= len) break;
-           DEBUG(4, ("%c", x));
-         }
-       
-       DEBUG(4, (" hex ", i));
-       
-       for (j = 0; j < 16; j++)
-         {
-           if (i+j >= len) break;
-           DEBUG(4, (" %02x", outbuf[i+j]));
-         }
-       
-       DEBUG(4, ("\n"));
+        switch (nmb->question.question_type)
+          {
+          case NMB_QUERY:
+        {
+          reply_name_query(p);
+          break;
+        }
+          case NMB_STATUS:
+        {
+          reply_name_status(p);
+          break;
+        }
+          }
+        return;
+      }
+    break;
+      }
+      
+    case NMB_REL:
+    {
+      if (nmb->header.qdcount==0 || nmb->header.arcount==0)
+      {
+        DEBUG(2,("netbios release packet rejected\n"));
+        break;
       }
     
+      if (nmb->header.response)
+      {
+        if (nmb->header.ancount==0) break;
+        response_netbios_packet(p); 
+      }
+      else
+      {
+        reply_name_release(p);
+      }
+      break;
+    }
+  }
 }
 
 
 /***************************************************************************
   updates the unique transaction identifier
   **************************************************************************/
-static void update_name_trn_id(void)
+void debug_browse_data(char *outbuf, int len)
 {
-  if (!name_trn_id)
-  {
-    name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
-  }
-  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+    int i,j;
+    for (i = 0; i < len; i+= 16)
+      {
+    DEBUG(4, ("%3x char ", i));
+    
+    for (j = 0; j < 16; j++)
+      {
+        unsigned char x = outbuf[i+j];
+        if (x < 32 || x > 127) x = '.';
+        
+        if (i+j >= len) break;
+        DEBUG(4, ("%c", x));
+      }
+    
+    DEBUG(4, (" hex ", i));
+    
+    for (j = 0; j < 16; j++)
+      {
+        if (i+j >= len) break;
+        DEBUG(4, (" %02x", outbuf[i+j]));
+      }
+    
+    DEBUG(4, ("\n"));
+      }
+    
 }
 
 
 /****************************************************************************
   initiate a netbios packet
+  
+  if we are making queries to samba, then the ip must be zero. in this
+  instance, the packet is constructed and then dealt with immediately.
   ****************************************************************************/
-void initiate_netbios_packet(uint16 *id,
-                               int fd,int quest_type,char *name,int name_type,
-                           int nb_flags,BOOL bcast,BOOL recurse,
-                           struct in_addr to_ip)
+BOOL initiate_netbios_packet(uint16 id,
+                int fd,int quest_type,char *name,int name_type,
+                int nb_flags,BOOL bcast,BOOL recurse,
+                struct in_addr to_ip)
 {
   struct packet_struct p;
   struct nmb_packet *nmb = &p.packet.nmb;
@@ -101,8 +176,6 @@ void initiate_netbios_packet(uint16 *id,
   char *packet_type = "unknown";
   int opcode = -1;
 
-  if (!id) return;
-
   if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
   if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
   if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
@@ -110,18 +183,13 @@ void initiate_netbios_packet(uint16 *id,
   if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
   
   DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
-          packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
+       packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
 
-  if (opcode == -1) return;
+  if (opcode == -1) return False;
 
   bzero((char *)&p,sizeof(p));
 
-  if (*id == 0xffff) {
-    update_name_trn_id();
-    *id = name_trn_id; /* allow resending with same id */
-  }
-
-  nmb->header.name_trn_id = *id;
+  nmb->header.name_trn_id = id;
   nmb->header.opcode = opcode;
   nmb->header.response = False;
 
@@ -162,7 +230,7 @@ void initiate_netbios_packet(uint16 *id,
       nmb->additional->rdlength = 6;
       nmb->additional->rdata[0] = nb_flags;
       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
-    }
+  }
   
   p.ip = to_ip;
   p.port = NMB_PORT;
@@ -170,12 +238,21 @@ void initiate_netbios_packet(uint16 *id,
   p.timestamp = time(NULL);
   p.packet_type = NMB_PACKET;
   
-  if (!send_packet(&p)) {
-    DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
-    *id = 0xffff;
+  if (zero_ip(to_ip)) /* samba's own ip */
+  {
+    DEBUG(4,("process packet ourselves\n"));
+    /* respond internally to the packet. */
+    process_nmb(&p);
   }
-  
-  return;
+  else
+  {
+    if (!send_packet(&p)) {
+      DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
+      return False;
+    }
+  }
+
+  return True;
 }
 
 
@@ -183,9 +260,9 @@ void initiate_netbios_packet(uint16 *id,
   reply to a netbios name packet 
   ****************************************************************************/
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
-                               int rcode, int rcv_code, int opcode, BOOL recurse,
-                               struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
-                               char *data,int len)
+                int rcode, int rcv_code, int opcode, BOOL recurse,
+                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
+                char *data,int len)
 {
   struct packet_struct p;
   struct nmb_packet *nmb = &p.packet.nmb;
@@ -198,31 +275,31 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
   switch (rcv_code)
   {
     case NMB_STATUS:
-       {
+    {
       packet_type = "nmb_status";
       recursion_desired = True;
       break;
     }
     case NMB_QUERY:
-       {
+    {
       packet_type = "nmb_query";
       recursion_desired = True;
       break;
     }
     case NMB_REG:
-       {
+    {
       packet_type = "nmb_reg";
       recursion_desired = True;
       break;
     }
     case NMB_REL:
-       {
+    {
       packet_type = "nmb_rel";
       recursion_desired = False;
       break;
     }
     case NMB_WAIT_ACK:
-       {
+    {
       packet_type = "nmb_wack";
       recursion_desired = False;
       break;
@@ -230,14 +307,14 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
     default:
     {
       DEBUG(1,("replying netbios packet: %s %s\n",
-                   packet_type, namestr(rr_name), inet_ntoa(p.ip)));
+                packet_type, namestr(rr_name), inet_ntoa(p.ip)));
 
       return;
     }
   }
 
   DEBUG(4,("replying netbios packet: %s %s\n",
-          packet_type, namestr(rr_name), inet_ntoa(p.ip)));
+       packet_type, namestr(rr_name), inet_ntoa(p.ip)));
 
   nmb->header.name_trn_id = trn_id;
   nmb->header.opcode = opcode;
@@ -265,16 +342,25 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
   nmb->answers->ttl      = ttl;
   
   if (data && len)
-    {
-      nmb->answers->rdlength = len;
-      memcpy(nmb->answers->rdata, data, len);
-    }
+  {
+    nmb->answers->rdlength = len;
+    memcpy(nmb->answers->rdata, data, len);
+  }
   
   p.packet_type = NMB_PACKET;
   
   debug_nmb_packet(&p);
   
-  send_packet(&p);
+  if (zero_ip(p.ip)) /* samba's own ip */
+  {
+    DEBUG(4,("process response packet ourselves\n"));
+    /* respond internally to the packet. */
+    process_nmb(&p);
+  }
+  else
+  {
+    send_packet(&p);
+  }
 }
 
 
@@ -352,7 +438,7 @@ static void process_dgram(struct packet_struct *p)
 
   buf = &dgram->data[0];
   buf -= 4; /* XXXX for the pseudo tcp length - 
-              someday I need to get rid of this */
+           someday I need to get rid of this */
 
   if (CVAL(buf,smb_com) != SMBtrans) return;
 
@@ -360,8 +446,8 @@ static void process_dgram(struct packet_struct *p)
   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
 
   DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
-          namestr(&dgram->source_name),namestr(&dgram->dest_name),
-          smb_buf(buf),CVAL(buf2,0),len));
+       namestr(&dgram->source_name),namestr(&dgram->dest_name),
+       smb_buf(buf),CVAL(buf2,0),len));
 
  
   if (len <= 0) return;
@@ -379,83 +465,6 @@ static void process_dgram(struct packet_struct *p)
    }
 }
 
-/****************************************************************************
-  process a nmb packet
-  ****************************************************************************/
-static void process_nmb(struct packet_struct *p)
-{
-  struct nmb_packet *nmb = &p->packet.nmb;
-
-  debug_nmb_packet(p);
-
-  switch (nmb->header.opcode) 
-  {
-    case 8: /* what is this?? */
-    case NMB_REG:
-    case NMB_REG_REFRESH:
-    {
-       if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
-       if (nmb->header.response)
-         response_netbios_packet(p); /* response to registration dealt 
-                                        with here */
-       else
-         reply_name_reg(p);
-       break;
-    }
-      
-    case 0:
-    {
-         if (nmb->header.response)
-         {
-           switch (nmb->question.question_type)
-             {
-             case 0x0:
-               {
-                 response_netbios_packet(p);
-                 break;
-               }
-             }
-           return;
-         }
-      else if (nmb->header.qdcount>0) 
-         {
-           switch (nmb->question.question_type)
-             {
-             case NMB_QUERY:
-               {
-                 reply_name_query(p);
-                 break;
-               }
-             case NMB_STATUS:
-               {
-                 reply_name_status(p);
-                 break;
-               }
-             }
-           return;
-         }
-       break;
-      }
-      
-    case NMB_REL:
-    {
-      if (nmb->header.qdcount==0 || nmb->header.arcount==0)
-         {
-           DEBUG(2,("netbios release packet rejected\n"));
-           break;
-         }
-       
-       if (nmb->header.response)
-         response_netbios_packet(p); /* response to reply dealt with 
-                                        in here */
-       else
-         reply_name_release(p);
-      break;
-    }
-  }
-}
-
-
 /*******************************************************************
   run elements off the packet queue till its empty
   ******************************************************************/
@@ -466,15 +475,15 @@ void run_packet_queue()
   while ((p=packet_queue))
     {
       switch (p->packet_type)
-       {
-       case NMB_PACKET:
-         process_nmb(p);
-         break;
-         
-       case DGRAM_PACKET:
-         process_dgram(p);
-         break;
-       }
+    {
+    case NMB_PACKET:
+      process_nmb(p);
+      break;
+      
+    case DGRAM_PACKET:
+      process_dgram(p);
+      break;
+    }
       
       packet_queue = packet_queue->next;
       if (packet_queue) packet_queue->prev = NULL;
@@ -550,8 +559,8 @@ try_again:
   wrong things to do! I should send to the requestors port. XXX
   **************************************************************************/
 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
-                        char *dstname,int src_type,int dest_type,
-                        struct in_addr dest_ip,struct in_addr src_ip)
+             char *dstname,int src_type,int dest_type,
+             struct in_addr dest_ip,struct in_addr src_ip)
 {
   struct packet_struct p;
   struct dgram_packet *dgram = &p.packet.dgram;
index 7fcb41e79f0623738d80b0e65018315b764910e0..a9422116fbc90694db0011d1f11c41a61631bca7 100644 (file)
@@ -35,15 +35,30 @@ extern pstring scope;
 extern struct in_addr ipzero;
 extern struct in_addr ipgrp;
 
+uint16 name_trn_id=0;
+
+
+/***************************************************************************
+  updates the unique transaction identifier
+  **************************************************************************/
+void update_name_trn_id(void)
+{
+  if (!name_trn_id)
+  {
+    name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
+  }
+  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+}
+
 
 /***************************************************************************
   deals with an entry before it dies
   **************************************************************************/
 static void dead_netbios_entry(struct subnet_record *d,
-                               struct response_record *n)
+                struct response_record *n)
 {
   DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
-          inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
+       inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
 
   debug_state_type(n->state);
 
@@ -51,118 +66,118 @@ static void dead_netbios_entry(struct subnet_record *d,
   {
     case NAME_QUERY_CONFIRM:
     {
-               if (!lp_wins_support()) return; /* only if we're a WINS server */
+        if (!lp_wins_support()) return; /* only if we're a WINS server */
 
-               if (n->num_msgs == 0)
+        if (n->num_msgs == 0)
         {
-                       /* oops. name query had no response. check that the name is
-                          unique and then remove it from our WINS database */
-
-                       /* IMPORTANT: see query_refresh_names() */
-
-                       if ((!NAME_GROUP(n->nb_flags)))
-                       {
-                               struct subnet_record *d1 = find_subnet(ipgrp);
-                               if (d1)
-                               {
-                                       /* remove the name that had been registered with us,
-                                          and we're now getting no response when challenging.
-                                          see rfc1001.txt 15.5.2
-                                        */
-                                       remove_netbios_name(d1, n->name.name, n->name.name_type,
-                                                                       REGISTER, n->send_ip);
-                               }
-                       }
-               }
-               break;
+            /* oops. name query had no response. check that the name is
+               unique and then remove it from our WINS database */
+
+            /* IMPORTANT: see query_refresh_names() */
+
+            if ((!NAME_GROUP(n->reply.nb_flags)))
+            {
+                struct subnet_record *d1 = find_subnet(ipgrp);
+                if (d1)
+                {
+                    /* remove the name that had been registered with us,
+                       and we're now getting no response when challenging.
+                       see rfc1001.txt 15.5.2
+                     */
+                    remove_netbios_name(d1, n->name.name, n->name.name_type,
+                                    REGISTER, n->send_ip);
+                }
+            }
+        }
+        break;
+    }
+
+    case NAME_QUERY_MST_CHK:
+    {
+      /* if no response received, the master browser must have gone
+         down on that subnet, without telling anyone. */
+
+      /* IMPORTANT: see response_netbios_packet() */
+
+      if (n->num_msgs == 0)
+          browser_gone(n->name.name, n->send_ip);
+      break;
     }
 
-       case NAME_QUERY_MST_CHK:
-       {
-         /* if no response received, the master browser must have gone
-                down on that subnet, without telling anyone. */
-
-         /* IMPORTANT: see response_netbios_packet() */
-
-         if (n->num_msgs == 0)
-                 browser_gone(n->name.name, n->send_ip);
-         break;
-       }
-
-       case NAME_RELEASE:
-       {
-         /* if no response received, it must be OK for us to release the
-                name. nobody objected (including a potentially dead or deaf
-                WINS server) */
-
-         /* IMPORTANT: see response_name_release() */
-
-         if (ismyip(n->send_ip))
-         {
-               name_unregister_work(d,n->name.name,n->name.name_type);
-         }
-         if (!n->bcast)
-         {
-                DEBUG(0,("WINS server did not respond to name release!\n"));
+    case NAME_RELEASE:
+    {
+      /* if no response received, it must be OK for us to release the
+         name. nobody objected (including a potentially dead or deaf
+         WINS server) */
+
+      /* IMPORTANT: see response_name_release() */
+
+      if (ismyip(n->send_ip))
+      {
+        name_unregister_work(d,n->name.name,n->name.name_type);
+      }
+      if (!n->bcast)
+      {
+         DEBUG(0,("WINS server did not respond to name release!\n"));
          /* XXXX whoops. we have problems. must deal with this */
-         }
-         break;
-       }
-
-       case NAME_REGISTER_CHALLENGE:
-       {
-               /* name challenge: no reply. we can reply to the person that
-                  wanted the unique name and tell them that they can have it
-                */
-
-               add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
-                                               n->nb_flags, GET_TTL(0),
-                                               n->reply_to_ip, False, n->reply_to_ip);
-
-         if (!n->bcast)
-         {
-                DEBUG(1,("WINS server did not respond to name registration!\n"));
+      }
+      break;
+    }
+
+    case NAME_REGISTER_CHALLENGE:
+    {
+        /* name challenge: no reply. we can reply to the person that
+           wanted the unique name and tell them that they can have it
+         */
+
+        add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
+                        n->reply.nb_flags, GET_TTL(0),
+                        n->reply.ip, False, n->reply.ip);
+
+      if (!n->bcast)
+      {
+         DEBUG(1,("WINS server did not respond to name registration!\n"));
          /* XXXX whoops. we have problems. must deal with this */
-         }
+      }
       break;
-       }
-
-       case NAME_REGISTER:
-       {
-         /* if no response received, and we are using a broadcast registration
-                method, it must be OK for us to register the name: nobody objected 
-                on that subnet. if we are using a WINS server, then the WINS
-                server must be dead or deaf.
-          */
-         if (n->bcast)
-         {
-               /* broadcast method: implicit acceptance of the name registration
-                  by not receiving any objections. */
-
-               /* IMPORTANT: see response_name_reg() */
-
-               name_register_work(d,n->name.name,n->name.name_type,
-                               n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
-         }
-         else
-         {
-               /* received no response. rfc1001.txt states that after retrying,
-                  we should assume the WINS server is dead, and fall back to
-                  broadcasting (see bits about M nodes: can't find any right
+    }
+
+    case NAME_REGISTER:
+    {
+      /* if no response received, and we are using a broadcast registration
+         method, it must be OK for us to register the name: nobody objected 
+         on that subnet. if we are using a WINS server, then the WINS
+         server must be dead or deaf.
+       */
+      if (n->bcast)
+      {
+        /* broadcast method: implicit acceptance of the name registration
+           by not receiving any objections. */
+
+        /* IMPORTANT: see response_name_reg() */
+
+        name_register_work(d,n->token,n->name.name,n->name.name_type,
+                &n->reply, n->ttl, n->reply.ip, n->bcast);
+      }
+      else
+      {
+        /* received no response. rfc1001.txt states that after retrying,
+           we should assume the WINS server is dead, and fall back to
+           broadcasting (see bits about M nodes: can't find any right
            now) */
-               
-               DEBUG(1,("WINS server did not respond to name registration!\n"));
+        
+        DEBUG(1,("WINS server did not respond to name registration!\n"));
         /* XXXX whoops. we have problems. must deal with this */
-         }
-         break;
-       }
-
-       default:
-       {
-         /* nothing to do but delete the dead expected-response structure */
-         /* this is normal. */
-         break;
-       }
+      }
+      break;
+    }
+
+    default:
+    {
+      /* nothing to do but delete the dead expected-response structure */
+      /* this is normal. */
+      break;
+    }
   }
 }
 
@@ -184,33 +199,33 @@ void expire_netbios_response_entries()
 
     for (n = d->responselist; n; n = nextn)
     {
-         nextn = n->next;
+      nextn = n->next;
 
       if (n->repeat_time <= time(NULL))
-         {
-                 if (n->repeat_count > 0)
-                 {
-                       /* resend the entry */
-                       initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
-                                               n->name.name, n->name.name_type,
-                                     n->nb_flags, n->bcast, n->recurse, n->send_ip);
+      {
+          if (n->repeat_count > 0)
+          {
+            /* resend the entry */
+            initiate_netbios_packet(n->response_id, n->fd, n->quest_type,
+                        n->name.name, n->name.name_type,
+                      n->reply.nb_flags, n->bcast, n->recurse, n->send_ip);
 
             n->repeat_time += n->repeat_interval; /* XXXX ms needed */
             n->repeat_count--;
 
-                 }
-                 else
-                 {
+          }
+          else
+          {
               DEBUG(4,("timeout response %d for %s %s\n",
-                                               n->response_id, namestr(&n->name),
+                        n->response_id, namestr(&n->name),
                         inet_ntoa(n->send_ip)));
 
-                         dead_netbios_entry    (d,n); /* process the non-response */
+              dead_netbios_entry    (d,n); /* process the non-response */
               remove_response_record(d,n); /* remove the non-response */
 
-                         continue;
-                  }
-         }
+              continue;
+           }
+      }
     }
   }
 }
@@ -221,44 +236,56 @@ void expire_netbios_response_entries()
   name server instead, if it exists. if wins is false, and there has been no
   WINS server specified, the packet will NOT be sent.
   ****************************************************************************/
-struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
-                               int fd,int quest_type,enum state_type state,
-                           char *name,int name_type,int nb_flags, time_t ttl,
-                               int server_type, char *my_name, char *my_comment,
-                           BOOL bcast,BOOL recurse,
-                               struct in_addr send_ip, struct in_addr reply_to_ip)
+void queue_netbios_pkt_wins(struct subnet_record *d,
+                int fd,int quest_type,enum state_type state,
+                int token, char *name,int name_type,int nb_flags, time_t ttl,
+                int server_type, char *my_name, char *my_comment,
+                BOOL bcast,BOOL recurse,
+                struct in_addr send_ip, struct in_addr reply_to_ip)
 {
-  /* XXXX note: please see rfc1001.txt section 10 for details on this
-     function: it is currently inappropriate to use this - it will do
-     for now - once there is a clarification of B, M and P nodes and
-     which one samba is supposed to be
-   */
+      /* XXXX note: please see rfc1001.txt section 10 for details on this
+         function: it is currently inappropriate to use this - it will do
+         for now - once there is a clarification of B, M and P nodes and
+         which one samba is supposed to be
+       */
 
-  if ((!lp_wins_support()) && (*lp_wins_server()))
+    if ((!lp_wins_support()) && (*lp_wins_server()))
     {
-      /* samba is not a WINS server, and we are using a WINS server */
-      struct in_addr wins_ip;
-      wins_ip = *interpret_addr2(lp_wins_server());
-
-      if (!zero_ip(wins_ip))
-       {
-         bcast = False;
-         send_ip = wins_ip;
-       }
+        /* samba is not a WINS server, and we are using a WINS server */
+        struct in_addr wins_ip;
+        wins_ip = *interpret_addr2(lp_wins_server());
+        
+        if (!zero_ip(wins_ip))
+        {
+            bcast = False;
+            send_ip = wins_ip;
+        }
+        else
+        {
+            /* oops. smb.conf's wins server parameter MUST be a host_name 
+            or an ip_address. */
+            DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
+        }
+    }
+    
+    if (zero_ip(send_ip))
+    {
+      /* doing a netbios query to samba as a WINS server, internally */
+      if (lp_wins_support())
+      {
+                DEBUG(4,("queue netbios packet with ourselves...\n"));
+         bcast = False;
+      }
       else
-       {
-         /* oops. smb.conf's wins server parameter MUST be a host_name 
-            or an ip_address. */
-         DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
-       }
+      {
+        return;
+      }
     }
-
-  if (zero_ip(send_ip)) return NULL;
-
-  return queue_netbios_packet(d,fd, quest_type, state, 
-                      name, name_type, nb_flags, ttl,
+    
+    queue_netbios_packet(d,fd, quest_type, state, 
+               token, name, name_type, nb_flags, ttl,
                server_type,my_name,my_comment,
-                      bcast, recurse, send_ip, reply_to_ip);
+               bcast, recurse, send_ip, reply_to_ip);
 }
 
 
@@ -268,35 +295,37 @@ struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
   master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
   complete lists across a wide area network
   ****************************************************************************/
-struct response_record *queue_netbios_packet(struct subnet_record *d,
-                       int fd,int quest_type,enum state_type state,char *name,
-                       int name_type,int nb_flags, time_t ttl,
-                       int server_type, char *my_name, char *my_comment,
-                   BOOL bcast,BOOL recurse,
-                       struct in_addr send_ip, struct in_addr reply_to_ip)
+void queue_netbios_packet(struct subnet_record *d,
+            int fd,int quest_type,enum state_type state,
+            int token, char *name, int name_type,int nb_flags, time_t ttl,
+            int server_type, char *my_name, char *my_comment,
+            BOOL bcast,BOOL recurse,
+            struct in_addr send_ip, struct in_addr reply_to_ip)
 {
   struct in_addr wins_ip = ipgrp;
   struct response_record *n;
-  uint16 id = 0xffff;
 
   /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
-  if (ip_equal(wins_ip, send_ip)) return NULL;
-
-  initiate_netbios_packet(&id, fd, quest_type, name, name_type,
-                                     nb_flags, bcast, recurse, send_ip);
+  if (ip_equal(wins_ip, send_ip)) return;
+
+  update_name_trn_id();
+
+  /* queue the response expected because if we do a query with an ip
+     of zero, we are expecting to hear from ourself immediately */
+  if ((n = make_response_queue_record(state, name_trn_id, fd, quest_type,
+                        token, name, name_type, nb_flags, ttl,
+                        server_type, my_name, my_comment,
+                        bcast, recurse, send_ip, reply_to_ip)))
+  { 
+    add_response_record(d,n);
+  }
 
-  if (id == 0xffff) {
+  if (!initiate_netbios_packet(name_trn_id, fd, quest_type, name, name_type,
+                      nb_flags, bcast, recurse, send_ip))
+  {
+    /* packet wasn't sent - not expecting a response */
     DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
-    return NULL;
+    remove_response_record(d, n);
+    return;
   }
-  
-  if ((n = make_response_queue_record(state,id,fd,
-                                               quest_type,name,name_type,nb_flags,ttl,
-                                               server_type,my_name, my_comment,
-                                               bcast,recurse,send_ip,reply_to_ip)))
-    {
-      add_response_record(d,n);
-      return n;
-    }
-   return NULL;
 }
index c8bbb52811636540adf78bde5eb0d82a9accda47..20b46d5224263f5ddbc726da5f1738e28903a52a 100644 (file)
@@ -51,7 +51,7 @@ extern uint16 nb_type; /* samba's NetBIOS type */
   XXXX at present, the name is removed _even_ if a WINS server says keep it.
 
   ****************************************************************************/
-void remove_name_entry(struct subnet_record *d, char *name,int type)
+void remove_name_entry(struct subnet_record *d, int token, char *name,int type)
 {
   /* XXXX BUG: if samba is offering WINS support, it should still broadcast
       a de-registration packet to the local subnet before removing the
@@ -80,17 +80,18 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
      don't really own */  
   remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
 
-  if (ip_equal(d->bcast_ip, ipgrp)) {
-    if (!lp_wins_support()) {
-      /* not a WINS server: we have to release them on the network */
+  if (ip_equal(d->bcast_ip, ipgrp))
+  {
+      /* use WINS. this function can now be used to _either_
+         do the release on samba's own database _or_ release
+         the name with an arbitrary WINS server */
       queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
-                            name, type, 0, 0,0,NULL,NULL,
+                            token, name, type, 0, 0,0,NULL,NULL,
                             False, True, ipzero, ipzero);
-    }
   } else {
     /* local interface: release them on the network */
     queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
-                        name, type, 0, 0,0,NULL,NULL,
+                        token, name, type, 0, 0,0,NULL,NULL,
                         True, True, d->bcast_ip, d->bcast_ip);
   }
 }
@@ -103,7 +104,8 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
   it's just a matter of when this will be done (e.g after a time-out).
 
   ****************************************************************************/
-void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
+void add_my_name_entry(struct subnet_record *d, int token,
+                       char *name,int type,int nb_flags)
 {
   BOOL re_reg = False;
   struct nmb_name n;
@@ -115,7 +117,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
 
   make_nmb_name(&n, name, type, scope);
   if (find_name(d->namelist, &n, SELF))
-       re_reg = True;
+    re_reg = True;
 
   /* XXXX BUG: if samba is offering WINS support, it should still add the
      name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
@@ -123,6 +125,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
 
   if (ip_equal(d->bcast_ip, ipgrp))
   {
+#if 0
     if (lp_wins_support())
     {
       /* we are a WINS server. */
@@ -131,26 +134,38 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
          actually be true
        */
 
+      struct nmb_ip data;
+
+      data.nb_flags = nb_flags;
+      putip(&data.ip, ipzero);
+
       DEBUG(4,("samba as WINS server adding: "));
       /* this will call add_netbios_entry() */
-      name_register_work(d, name, type, nb_flags,0, ipzero, False);
+      
+      name_register_work(d, token, name, type, &data, GET_TTL(0),ipzero,False);
     }
     else
     {
+#endif
+      /* ipzero when not using an arbitrary wins server results in the
+         netbios packet being short-circuited to process_nmb()
+       */
       /* a time-to-live allows us to refresh this name with the WINS server. */
-         queue_netbios_pkt_wins(d,ClientNMB,
-                                re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
-                            name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
-                            False, True, ipzero, ipzero);
+      queue_netbios_pkt_wins(d,ClientNMB,
+                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
+                 token, name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
+                 False, True, ipzero, ipzero);
+#if 0
     }
+#endif
   }
   else
   {
     /* broadcast the packet, but it comes from ipzero */
-       queue_netbios_packet(d,ClientNMB,
-                                re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
-                            name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
-                            True, True, d->bcast_ip, ipzero);
+    queue_netbios_packet(d,ClientNMB,
+                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
+                 token, name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
+                 True, True, d->bcast_ip, ipzero);
   }
 }
 
@@ -161,6 +176,8 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
 void add_my_names(void)
 {
   struct subnet_record *d;
+  int token;
+
   /* each subnet entry, including WINS pseudo-subnet, has SELF names */
 
   /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
@@ -171,30 +188,54 @@ void add_my_names(void)
   {
     BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
 
-    add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
-    add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
-    add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE);
-    add_my_name_entry(d, myname,0x1f,nb_type|NB_ACTIVE);
-    
+    for (token = 0; token < get_num_workgroups(); token++)
+    {
+      char *my_name = conf_browsing_alias(token);
+      if (my_name)
+      {
+        add_my_name_entry(d, token, my_name,0x20,nb_type|NB_ACTIVE);
+        add_my_name_entry(d, token, my_name,0x03,nb_type|NB_ACTIVE);
+        add_my_name_entry(d, token, my_name,0x00,nb_type|NB_ACTIVE);
+        add_my_name_entry(d, token, my_name,0x1f,nb_type|NB_ACTIVE);
+      }
+    }
+
     /* these names are added permanently (ttl of zero) and will NOT be
        refreshed with the WINS server  */
+
     add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
-    add_netbios_entry(d,"*",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
     add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
     add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
-    
-    if (lp_domain_logons()) {
+
+    /* XXXX only be a logon server for the DEFAULT samba workgroup. for now. */
+
+    if (lp_domain_logons())
+    {
       /* XXXX the 0x1c is apparently something to do with domain logons */
-      add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
+      token = conf_workgroup_name_to_token(lp_workgroup(),myname);
+      add_my_name_entry(d, token, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
     }
   }
-  if (lp_domain_master() && (d = find_subnet(ipgrp)))
+
+  /* check becoming a domain master under all browser aliases */
+
+  if ((d = find_subnet(ipgrp)))
   {
-    struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
-    if (work && work->state == MST_NONE)
+    for (token = 0; token < get_num_workgroups(); token++)
     {
-      work->state = MST_DOMAIN_NONE;
-      become_master(d, work);
+      if (conf_should_domain_master(token))
+      {
+        char *work_name = conf_workgroup_name(token);
+        if (work_name)
+        {
+          struct work_record *work = find_workgroupstruct(d,work_name,True);
+          if (work && work->state == MST_NONE)
+          {
+            work->state = MST_DOMAIN_NONE;
+            become_master(d, work);
+          }
+        }
+      }
     }
   }
 }
@@ -205,52 +246,24 @@ void add_my_names(void)
   **************************************************************************/
 void remove_my_names()
 {
-       struct subnet_record *d;
-
-       for (d = subnetlist; d; d = d->next)
-       {
-               struct name_record *n, *next;
-
-               for (n = d->namelist; n; n = next)
-               {
-                       next = n->next;
-                       if (n->source == SELF)
-                       {
-                               /* get all SELF names removed from the WINS server's database */
-                               /* XXXX note: problem occurs if this removes the wrong one! */
-
-                               remove_name_entry(d,n->name.name, n->name.name_type);
-                       }
-               }
-       }
-}
-
-
-/*******************************************************************
-  refresh my own names
-  ******************************************************************/
-void refresh_my_names(time_t t)
-{
-  struct subnet_record *d;
+    struct subnet_record *d;
 
-  for (d = subnetlist; d; d = d->next)
-  {
-    struct name_record *n;
-         
-       for (n = d->namelist; n; n = n->next)
+    for (d = subnetlist; d; d = d->next)
     {
-      /* each SELF name has an individual time to be refreshed */
-      if (n->source == SELF && n->refresh_time < time(NULL) && 
-          n->death_time != 0)
-      {
-        add_my_name_entry(d,n->name.name,n->name.name_type,
-                          n->ip_flgs[0].nb_flags);
-       /* they get a new lease on life :-) */
-       n->death_time += GET_TTL(0);
-       n->refresh_time += GET_TTL(0);
-      }
+        struct name_record *n, *next;
+
+        for (n = d->namelist; n; n = next)
+        {
+            next = n->next;
+            if (n->source == SELF)
+            {
+                /* get all SELF names removed from the WINS server's database */
+                /* XXXX note: problem occurs if this removes the wrong one! */
+
+                remove_name_entry(d, -1, n->name.name, n->name.name_type);
+            }
+        }
     }
-  }
 }
 
 
@@ -265,55 +278,55 @@ void refresh_my_names(time_t t)
   ******************************************************************/
 void query_refresh_names(void)
 {
-       struct name_record *n;
-       struct subnet_record *d = find_subnet(ipgrp);
+    struct name_record *n;
+    struct subnet_record *d = find_subnet(ipgrp);
 
-       static time_t lasttime = 0;
-       time_t t = time(NULL);
+    static time_t lasttime = 0;
+    time_t t = time(NULL);
 
-       int count = 0;
-       int name_refresh_time = NAME_POLL_REFRESH_TIME;
-       int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
-       if (max_count > 10) max_count = 10;
+    int count = 0;
+    int name_refresh_time = NAME_POLL_REFRESH_TIME;
+    int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
+    if (max_count > 10) max_count = 10;
 
-       name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
+    name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
 
-       /* if (!lp_poll_wins()) return; polling of registered names allowed */
+    /* if (!lp_poll_wins()) return; polling of registered names allowed */
 
-       if (!d) return;
+    if (!d) return;
 
     if (!lasttime) lasttime = t;
-       if (t - lasttime < NAME_POLL_INTERVAL) return;
+    if (t - lasttime < NAME_POLL_INTERVAL) return;
 
     lasttime = time(NULL);
 
-       for (n = d->namelist; n; n = n->next)
-       {
-               /* only do unique, registered names */
-
-               if (n->source != REGISTER) continue;
-               if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
-
-               if (n->refresh_time < t)
-               {
-                 DEBUG(3,("Polling name %s\n", namestr(&n->name)));
-                 
-         queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
-                               n->name.name, n->name.name_type,
-                               0,0,0,NULL,NULL,
-                               False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip);
-                 count++;
-               }
-
-               if (count >= max_count)
-               {
-                       /* don't do too many of these at once, but do enough to
-                          cover everyone in the list */
-                       return;
-               }
-
-               /* this name will be checked on again, if it's not removed */
-               n->refresh_time += name_refresh_time;
-       }
+    for (n = d->namelist; n; n = n->next)
+    {
+        /* only do unique, registered names. */
+
+        if (n->source != REGISTER) continue;
+        if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
+
+        if (n->refresh_time < t)
+        {
+          DEBUG(3,("Polling name %s\n", namestr(&n->name)));
+          
+          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
+                -1,n->name.name, n->name.name_type,
+                0,0,0,NULL,NULL,
+                False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip);
+          count++;
+        }
+
+        if (count >= max_count)
+        {
+            /* don't do too many of these at once, but do enough to
+               cover everyone in the list */
+            return;
+        }
+
+        /* this name will be checked on again, if it's not removed */
+        n->refresh_time += name_refresh_time;
+    }
 }
 
index b01c2c25b4cc51ec43fe18b57fbd2857230d0ecd..ae568198ac8e6e77cded7fc423ec5032b4ba5ae4 100644 (file)
@@ -294,7 +294,7 @@ void reply_name_reg(struct packet_struct *p)
     /* initiate some enquiries to the current owner. */
        queue_netbios_packet(d,ClientNMB,NMB_QUERY,
                                                 NAME_REGISTER_CHALLENGE,
-                                                reply_name->name,reply_name->name_type,
+                                                -1,reply_name->name,reply_name->name_type,
                             nb_flags,0,0,NULL,NULL,
                                                 False, False, n->ip_flgs[0].ip, p->ip);
   }
index a4cda7cdfb5a412dbcce1de5036f68f5a648372c..0b8e23bfae0b8332059061050c1455a6031d4b2b 100644 (file)
@@ -46,38 +46,29 @@ extern struct in_addr ipzero;
   response for a reg release received. samba has asked a WINS server if it
   could release a name.
   **************************************************************************/
-static void response_name_release(struct subnet_record *d,
-                                                               struct packet_struct *p)
+static void response_name_release(struct nmb_ip *data, struct nmb_name *name,
+                struct subnet_record *d)
 {
-  struct nmb_packet *nmb = &p->packet.nmb;
-  char *name = nmb->question.question_name.name;
-  int   type = nmb->question.question_name.name_type;
-  
   DEBUG(4,("response name release received\n"));
   
-  if (nmb->header.rcode == 0 && nmb->answers->rdata)
+  if (data)
   {
     /* IMPORTANT: see expire_netbios_response_entries() */
 
-    struct in_addr found_ip;
-    putip((char*)&found_ip,&nmb->answers->rdata[2]);
-      
     /* NOTE: we only release our own names at present */
-    if (ismyip(found_ip))
+    if (ismyip(data->ip))
     {
-      name_unregister_work(d,name,type);
+      name_unregister_work(d, name->name, name->name_type);
     }
     else
     {
       DEBUG(2,("name release for different ip! %s %s\n",
-                  inet_ntoa(found_ip),
-                  namestr(&nmb->question.question_name)));
+                  inet_ntoa(data->ip),namestr(name)));
     }
   }
   else
   {
-    DEBUG(2,("name release for %s rejected!\n",
-              namestr(&nmb->question.question_name)));
+    DEBUG(2,("name release for %s rejected!\n",namestr(name)));
 
     /* XXXX PANIC! what to do if it's one of samba's own names? */
 
@@ -91,34 +82,25 @@ static void response_name_release(struct subnet_record *d,
 /****************************************************************************
 response for a reg request received
 **************************************************************************/
-static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
+static void response_name_reg(struct nmb_ip *data, struct nmb_name *name,
+                    time_t ttl, BOOL bcast, struct in_addr source_ip,
+                    struct subnet_record *d, int token)
 {
-  struct nmb_packet *nmb = &p->packet.nmb;
-  char *name = nmb->question.question_name.name;
-  int   type = nmb->question.question_name.name_type;
-  BOOL bcast = nmb->header.nm_flags.bcast;
-  
   DEBUG(4,("response name registration received!\n"));
   
-  if (nmb->header.rcode == 0 && nmb->answers->rdata)
+  if (data)
   {
     /* IMPORTANT: see expire_netbios_response_entries() */
 
-    int nb_flags = nmb->answers->rdata[0];
-    int ttl = nmb->answers->ttl;
-    struct in_addr found_ip;
-
-    putip((char*)&found_ip,&nmb->answers->rdata[2]);
-      
-    name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
+    name_register_work(d, token, name->name,name->name_type,
+                       data, ttl, source_ip, bcast);
   }
   else
   {
-    DEBUG(1,("name registration for %s rejected!\n",
-              namestr(&nmb->question.question_name)));
+    DEBUG(1,("name registration for %s rejected!\n", namestr(name)));
 
-       /* oh dear. we have problems. possibly unbecome a master browser. */
-    name_unregister_work(d,name,type);
+    /* oh dear. we have problems. possibly unbecome a master browser. */
+    name_unregister_work(d,name->name,name->name_type);
   }
 }
 
@@ -127,58 +109,53 @@ static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
   response from a name query announce host
   NAME_QUERY_ANNOUNCE_HOST is dealt with here
   ****************************************************************************/
-static void response_announce_host(struct nmb_name *ans_name, 
-               struct nmb_packet *nmb
-               struct response_record *n, struct subnet_record *d)
+static void response_announce_host(struct nmb_ip *data,
+        struct nmb_name *ans_name
+        struct response_record *n, struct subnet_record *d)
 {
-       DEBUG(4, ("Name query at %s ip %s - ",
-                 namestr(&n->name), inet_ntoa(n->send_ip)));
-
-       if (!name_equal(&n->name, ans_name))
-       {
-               /* someone gave us the wrong name as a reply. oops. */
-               /* XXXX should say to them 'oi! release that name!' */
-
-               DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
-               return;
-       }
-
-       if (nmb->header.rcode == 0 && nmb->answers->rdata)
-    {
-               /* we had sent out a name query to the current owner
-                  of a name because someone else wanted it. now they
-                  have responded saying that they still want the name,
-                  so the other host can't have it.
-                */
-
-               /* first check all the details are correct */
-
-               int nb_flags = nmb->answers->rdata[0];
-               struct in_addr found_ip;
-
-               putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
-               if (nb_flags != n->nb_flags)
-               {
-                       /* someone gave us the wrong nb_flags as a reply. oops. */
-                       /* XXXX should say to them 'oi! release that name!' */
-
-                       DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
-                       DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
-                       return;
-               }
-
-       /* do an announce host */
-       do_announce_host(ANN_HostAnnouncement,
-                               n->my_name  , 0x00, d->myip,
-                               n->name.name, 0x1d, found_ip,
-                               n->ttl,
-                               n->my_name, n->server_type, n->my_comment);
-       }
-       else
-       {
-               /* XXXX negative name query response. no master exists. oops */
-       }
+    DEBUG(4, ("Name query at %s ip %s - ",
+          namestr(&n->name), inet_ntoa(n->send_ip)));
+
+    if (!name_equal(&n->name, ans_name))
+    {
+        /* someone gave us the wrong name as a reply. oops. */
+        /* XXXX should say to them 'oi! release that name!' */
+
+        DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+        return;
+    }
+
+    if (data)
+    {
+        /* we had sent out a name query to the current owner
+           of a name because someone else wanted it. now they
+           have responded saying that they still want the name,
+           so the other host can't have it.
+         */
+
+        /* first check all the details are correct */
+
+        if (data->nb_flags != n->reply.nb_flags)
+        {
+            /* someone gave us the wrong nb_flags as a reply. oops. */
+            /* XXXX should say to them 'oi! release that name!' */
+
+            DEBUG(4,("expected nb_flags: %d\n", n->reply.nb_flags));
+            DEBUG(4,("unexpected nb_flags: %d\n", data->nb_flags));
+            return;
+        }
+
+        /* do an announce host */
+        do_announce_host(ANN_HostAnnouncement,
+                n->my_name  , 0x00, d->myip,
+                n->name.name, 0x1d, data->ip,
+                n->ttl,
+                n->my_name, n->server_type, n->my_comment);
+    }
+    else
+    {
+        /* XXXX negative name query response. no master exists. oops */
+    }
 }
 
 
@@ -187,18 +164,18 @@ static void response_announce_host(struct nmb_name *ans_name,
   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
   ****************************************************************************/
 static void response_server_check(struct nmb_name *ans_name, 
-               struct response_record *n, struct subnet_record *d)
+        struct response_record *n, struct subnet_record *d)
 {
     /* issue another state: this time to do a name status check */
 
     enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
-             NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
+          NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
 
     /* initiate a name status check on the server that replied */
     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
-                               ans_name->name, ans_name->name_type,
-                               0,0,0,NULL,NULL,
-                               False,False,n->send_ip,n->reply_to_ip);
+                -1,ans_name->name, ans_name->name_type,
+                0,0,0,NULL,NULL,
+                False,False,n->send_ip,n->reply.ip);
 }
 
 
@@ -208,8 +185,8 @@ static void response_server_check(struct nmb_name *ans_name,
   add all the names it finds into the namelist.
 ****************************************************************************/
 static BOOL interpret_node_status(struct subnet_record *d,
-                               char *p, struct nmb_name *name,int t,
-                          char *serv_name, struct in_addr ip, BOOL bcast)
+                char *p, struct nmb_name *name,int t,
+               char *serv_name, struct in_addr ip, BOOL bcast)
 {
   int level = t==0x20 ? 4 : 0;
   int numnames = CVAL(p,0);
@@ -252,44 +229,44 @@ static BOOL interpret_node_status(struct subnet_record *d,
       
       /* might as well update our namelist while we're at it */
       if (add)
-       {
-         struct in_addr nameip;
-         enum name_source src;
-         
-         if (ismyip(ip)) {
-           nameip = ipzero;
-           src = SELF;
-         } else {
-           nameip = ip;
-           src = STATUS_QUERY;
-         }
-         add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
-       
+    {
+      struct in_addr nameip;
+      enum name_source src;
+      
+      if (ismyip(ip)) {
+        nameip = ipzero;
+        src = SELF;
+      } else {
+        nameip = ip;
+        src = STATUS_QUERY;
+      }
+      add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
+    } 
 
       /* we want the server name */
       if (serv_name && !*serv_name && !group && t == 0)
-       {
-         StrnCpy(serv_name,qname,15);
-         serv_name[15] = 0;
-       }
+    {
+      StrnCpy(serv_name,qname,15);
+      serv_name[15] = 0;
+    }
       
       /* looking for a name and type? */
       if (name && !found && (t == type))
-       {
-         /* take a guess at some of the name types we're going to ask for.
-            evaluate whether they are group names or no... */
-         if (((t == 0x1b || t == 0x1d             ) && !group) ||
-             ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
-           {
-             found = True;
-             make_nmb_name(name,qname,type,scope);
-           }
-       }
+    {
+      /* take a guess at some of the name types we're going to ask for.
+         evaluate whether they are group names or no... */
+      if (((t == 0x1b || t == 0x1d             ) && !group) ||
+          ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
+        {
+          found = True;
+          make_nmb_name(name,qname,type,scope);
+        }
+    }
       
       DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
     }
   DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
-              IVAL(p,20),IVAL(p,24)));
+           IVAL(p,20),IVAL(p,24)));
   return found;
 }
 
@@ -299,28 +276,26 @@ static BOOL interpret_node_status(struct subnet_record *d,
   and NAME_STATUS_SRV_CHK dealt with here.
   ****************************************************************************/
 static void response_name_status_check(struct in_addr ip,
-               struct nmb_packet *nmb, BOOL bcast,
-               struct response_record *n, struct subnet_record *d)
+        char *data, BOOL bcast,
+        struct response_record *n, struct subnet_record *d)
 {
-       /* NMB_STATUS arrives: contains workgroup name and server name required.
+    /* NMB_STATUS arrives: contains workgroup name and server name required.
        amongst other things. */
 
-       struct nmb_name name;
-       fstring serv_name;
-
-       if (interpret_node_status(d,nmb->answers->rdata,
-                                 &name,name.name_type,serv_name,ip,bcast))
-       {
-               if (*serv_name)
-               {
-                       sync_server(n->state,serv_name,
-                                   name.name,name.name_type, n->send_ip);
-               }
-       }
-       else
-       {
-               DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
-       }
+    struct nmb_name name;
+    fstring serv_name;
+
+    if (interpret_node_status(d,data,&name,name.name_type,serv_name,ip,bcast))
+    {
+        if (*serv_name)
+        {
+            sync_server(n->state,serv_name,name.name,name.name_type,n->send_ip);
+        }
+    }
+    else
+    {
+        DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
+    }
 }
 
 
@@ -328,79 +303,74 @@ static void response_name_status_check(struct in_addr ip,
   response from a name query for secured WINS registration. a state of
   NAME_REGISTER_CHALLENGE is dealt with here.
   ****************************************************************************/
-static void response_name_query_register(struct nmb_packet *nmb, 
-               struct nmb_name *ans_name, 
-               struct response_record *n, struct subnet_record *d)
+static void response_name_query_register(struct nmb_ip *data,
+        struct nmb_name *ans_name, 
+        struct response_record *n, struct subnet_record *d)
 {
-       struct in_addr register_ip;
-       BOOL new_owner;
-
-       DEBUG(4, ("Name query at %s ip %s - ",
-                 namestr(&n->name), inet_ntoa(n->send_ip)));
-
-       if (!name_equal(&n->name, ans_name))
-       {
-               /* someone gave us the wrong name as a reply. oops. */
-               /* XXXX should say to them 'oi! release that name!' */
-
-               DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
-               return;
-       }
-
-       if (nmb->header.rcode == 0 && nmb->answers->rdata)
-    {
-               /* we had sent out a name query to the current owner
-                  of a name because someone else wanted it. now they
-                  have responded saying that they still want the name,
-                  so the other host can't have it.
-                */
-
-               /* first check all the details are correct */
-
-               int nb_flags = nmb->answers->rdata[0];
-               struct in_addr found_ip;
-
-               putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
-               if (nb_flags != n->nb_flags)
-               {
-                       /* someone gave us the wrong nb_flags as a reply. oops. */
-                       /* XXXX should say to them 'oi! release that name!' */
-
-                       DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
-                       DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
-                       return;
-               }
-
-               if (!ip_equal(n->send_ip, found_ip))
-               {
-                       /* someone gave us the wrong ip as a reply. oops. */
-                       /* XXXX should say to them 'oi! release that name!' */
-
-                       DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
-                       DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
-                       return;
-               }
-
-               DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
-
-               /* fine: now tell the other host they can't have the name */
-               register_ip = n->send_ip;
-               new_owner = False;
-       }
-       else
-       {
-               DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
-               /* the owner didn't want the name: the other host can have it */
-               register_ip = n->reply_to_ip;
-               new_owner = True;
-       }
-
-       /* register the old or the new owners' ip */
-       add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
-                                       GET_TTL(0), register_ip,
-                                       new_owner, n->reply_to_ip);
+    struct in_addr register_ip;
+    BOOL new_owner;
+
+    DEBUG(4, ("Name query at %s ip %s - ",
+          namestr(&n->name), inet_ntoa(n->send_ip)));
+
+    if (!name_equal(&n->name, ans_name))
+    {
+        /* someone gave us the wrong name as a reply. oops. */
+        /* XXXX should say to them 'oi! release that name!' */
+
+        DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+        return;
+    }
+
+    if (data)
+    {
+        /* we had sent out a name query to the current owner
+           of a name because someone else wanted it. now they
+           have responded saying that they still want the name,
+           so the other host can't have it.
+         */
+
+        /* first check all the details are correct */
+
+        if (data->nb_flags != n->reply.nb_flags)
+        {
+            /* someone gave us the wrong nb_flags as a reply. oops. */
+            /* XXXX should say to them 'oi! release that name!' */
+
+            DEBUG(4,("expected nb_flags: %d\n", n->reply.nb_flags));
+            DEBUG(4,("unexpected nb_flags: %d\n", data->nb_flags));
+            return;
+        }
+
+        if (!ip_equal(n->send_ip, data->ip))
+        {
+            /* someone gave us the wrong ip as a reply. oops. */
+            /* XXXX should say to them 'oi! release that name!' */
+
+            DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
+            DEBUG(4,("unexpected ip: %s\n", inet_ntoa(data->ip)));
+            return;
+        }
+
+        DEBUG(4, (" OK: %s\n", inet_ntoa(data->ip)));
+
+        /* fine: now tell the other host they can't have the name */
+        register_ip = n->send_ip;
+        new_owner = False;
+    }
+    else
+    {
+        DEBUG(4, (" NEGATIVE RESPONSE!\n"));
+
+        /* the owner didn't want the name: the other host can have it */
+        register_ip = n->reply.ip;
+        new_owner = True;
+    }
+
+    /* register the old or the new owners' ip */
+    add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,
+                    n->reply.nb_flags, GET_TTL(0), register_ip,
+                    new_owner, n->reply.ip);
 }
 
 
@@ -408,73 +378,68 @@ static void response_name_query_register(struct nmb_packet *nmb,
   response from a name query to sync browse lists or to update our netbios
   entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
   ****************************************************************************/
-static void response_name_query_sync(struct nmb_packet *nmb, 
-               struct nmb_name *ans_name, BOOL bcast,
-               struct response_record *n, struct subnet_record *d)
+static void response_name_query_sync(struct nmb_ip *data,
+        struct nmb_name *ans_name, BOOL bcast,
+        struct response_record *n, struct subnet_record *d)
 {
-       DEBUG(4, ("Name query at %s ip %s - ",
-                 namestr(&n->name), inet_ntoa(n->send_ip)));
-
-       if (!name_equal(&n->name, ans_name))
-       {
-               /* someone gave us the wrong name as a reply. oops. */
-               DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
-               return;
-       }
-
-       if (nmb->header.rcode == 0 && nmb->answers->rdata)
-    {
-               int nb_flags = nmb->answers->rdata[0];
-               struct in_addr found_ip;
-
-               putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
-               if (!ip_equal(n->send_ip, found_ip))
-               {
-                       /* someone gave us the wrong ip as a reply. oops. */
-                       DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
-                       DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
-                       return;
-               }
-
-               DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
-
-               if (n->state == NAME_QUERY_SYNC_LOCAL ||
-                   n->state == NAME_QUERY_SYNC_REMOTE)
-               {
-                       struct work_record *work = NULL;
-                       if ((work = find_workgroupstruct(d, ans_name->name, False)))
-                       {
-                               BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
-
-                               /* the server is there: sync quick before it (possibly) dies! */
-                               sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
-                                                       found_ip, local_list_only);
-                       }
-               }
-               else
-               {
-                       /* update our netbios name list (re-register it if necessary) */
-                       add_netbios_entry(d, ans_name->name, ans_name->name_type,
-                                                               nb_flags,GET_TTL(0),REGISTER,
-                                                               found_ip,False,!bcast);
-               }
-       }
-       else
-       {
-               DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
-               if (n->state == NAME_QUERY_CONFIRM)
-               {
-                       /* XXXX remove_netbios_entry()? */
-                       /* lots of things we ought to do, here. if we get here,
-                          then we're in a mess: our name database doesn't match
-                          reality. sort it out
+    DEBUG(4, ("Name query at %s ip %s - ",
+          namestr(&n->name), inet_ntoa(n->send_ip)));
+
+    if (!name_equal(&n->name, ans_name))
+    {
+        /* someone gave us the wrong name as a reply. oops. */
+        DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+        return;
+    }
+
+    if (data)
+    {
+        if (!ip_equal(n->send_ip, data->ip))
+        {
+            /* someone gave us the wrong ip as a reply. oops. */
+            DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
+            DEBUG(4,("unexpected ip: %s\n", inet_ntoa(data->ip)));
+            return;
+        }
+
+        DEBUG(4, (" OK: %s\n", inet_ntoa(data->ip)));
+
+        if (n->state == NAME_QUERY_SYNC_LOCAL ||
+            n->state == NAME_QUERY_SYNC_REMOTE)
+        {
+            struct work_record *work = NULL;
+            if ((work = find_workgroupstruct(d, ans_name->name, False)))
+            {
+                BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+
+                /* the server is there: sync quick before it (possibly) dies! */
+                sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
+                            data->ip, local_list_only);
+            }
+        }
+        else
+        {
+            /* update our netbios name list (re-register it if necessary) */
+            add_netbios_entry(d, ans_name->name, ans_name->name_type,
+                                data->nb_flags,GET_TTL(0),REGISTER,
+                                data->ip,False,!bcast);
+        }
+    }
+    else
+    {
+        DEBUG(4, (" NEGATIVE RESPONSE!\n"));
+
+        if (n->state == NAME_QUERY_CONFIRM)
+        {
+            /* XXXX remove_netbios_entry()? */
+            /* lots of things we ought to do, here. if we get here,
+               then we're in a mess: our name database doesn't match
+               reality. sort it out
              */
-               remove_netbios_name(d,n->name.name, n->name.name_type,
-                                                               REGISTER,n->send_ip);
-               }
-       }
+            remove_netbios_name(d,n->name.name, n->name.name_type,
+                                REGISTER,n->send_ip);
+        }
+    }
 }
 
 
@@ -486,9 +451,9 @@ static void debug_rr_type(int rr_type)
   switch (rr_type)
   {
       case NMB_STATUS: DEBUG(3,("Name status ")); break;
-         case NMB_QUERY : DEBUG(3,("Name query ")); break;
-         case NMB_REG   : DEBUG(3,("Name registration ")); break;
-         case NMB_REL   : DEBUG(3,("Name release ")); break;
+      case NMB_QUERY : DEBUG(3,("Name query ")); break;
+      case NMB_REG   : DEBUG(3,("Name registration ")); break;
+      case NMB_REL   : DEBUG(3,("Name release ")); break;
       default        : DEBUG(1,("wrong response packet type received")); break;
   }
 }
@@ -528,7 +493,7 @@ void debug_state_type(int state)
   (responses for certain types of operations are only expected from one host)
   ****************************************************************************/
 static BOOL response_problem_check(struct response_record *n,
-                       struct nmb_packet *nmb, char *qname)
+            struct nmb_packet *nmb, char *qname)
 {
   switch (nmb->answers->rr_type)
   {
@@ -556,21 +521,21 @@ static BOOL response_problem_check(struct response_record *n,
     { 
       if (n->num_msgs > 1)
       {
-                 if (nmb->header.rcode == 0 && nmb->answers->rdata)
-                 {
-                       int nb_flags = nmb->answers->rdata[0];
-
-                       if ((!NAME_GROUP(nb_flags)))
-                       {
-                          /* oh dear. more than one person responded to a unique name.
-                                 there is either a network problem, a configuration problem
-                                 or a server is mis-behaving */
-
-                          /* XXXX mark the name as in conflict, and then let the
-                                 person who just responded know that they must also mark it
-                                 as in conflict, and therefore must NOT use it.
+          if (nmb->header.rcode == 0 && nmb->answers->rdata)
+          {
+            int nb_flags = nmb->answers->rdata[0];
+
+            if ((!NAME_GROUP(nb_flags)))
+            {
+               /* oh dear. more than one person responded to a unique name.
+                  there is either a network problem, a configuration problem
+                  or a server is mis-behaving */
+
+               /* XXXX mark the name as in conflict, and then let the
+                  person who just responded know that they must also mark it
+                  as in conflict, and therefore must NOT use it.
                   see rfc1001.txt 15.1.3.5 */
-                                       
+                    
                /* this may cause problems for some early versions of nmbd */
 
                switch (n->state)
@@ -580,35 +545,35 @@ static BOOL response_problem_check(struct response_record *n,
                   /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
                   return False;
                 }
-                       case NAME_QUERY_ANNOUNCE_HOST:
-                       case NAME_QUERY_DOM_SRV_CHK:
+                case NAME_QUERY_ANNOUNCE_HOST:
+                case NAME_QUERY_DOM_SRV_CHK:
                 case NAME_QUERY_SRV_CHK:
                 case NAME_QUERY_MST_CHK:
                 {
-                     if (!strequal(qname,n->name.name))
-                     {
-                            /* one subnet, one master browser per workgroup */
-                            /* XXXX force an election? */
-
-                            DEBUG(3,("more than one master browser replied!\n"));
-                                return True;
-                         }
+                  if (!strequal(qname,n->name.name))
+                  {
+                     /* one subnet, one master browser per workgroup */
+                     /* XXXX force an election? */
+
+                     DEBUG(3,("more than one master browser replied!\n"));
+                     return True;
+                  }
                    break;
                 }
                 default: break;
                }
                DEBUG(3,("Unique Name conflict detected!\n"));
-                          return True;
-                       }
-                 }
-                 else
-                 {
+               return True;
+            }
+          }
+          else
+          {
              /* we have received a negative reply, having already received
                 at least one response (pos/neg). something's really wrong! */
 
-                DEBUG(3,("wierd name query problem detected!\n"));
-                    return True;
-                 }
+             DEBUG(3,("wierd name query problem detected!\n"));
+             return True;
+          }
        }
     }
   }
@@ -619,27 +584,30 @@ static BOOL response_problem_check(struct response_record *n,
   check that the response received is compatible with the response record
   ****************************************************************************/
 static BOOL response_compatible(struct response_record *n,
-                       struct nmb_packet *nmb)
+            struct nmb_packet *nmb)
 {
   switch (n->state)
   {
     case NAME_RELEASE:
     {
-               if (nmb->answers->rr_type != NMB_REL)
-               {
-                       DEBUG(1,("Name release reply has wrong answer rr_type\n"));
-                       return False;
-               }
+        if (nmb->answers->rr_type != NMB_REL)
+        {
+            DEBUG(1,("Name release reply has wrong answer rr_type\n"));
+            return False;
+        }
         break;
     }
 
     case NAME_REGISTER:
     {
-               if (nmb->answers->rr_type != NMB_REG)
-               {
-                       DEBUG(1,("Name register reply has wrong answer rr_type\n"));
-                       return False;
-               }
+/* rfc1002.txt states that nmb->answers->rr_type must equal 0x20 */
+#if 0
+        if (nmb->answers->rr_type != NMB_REG)
+        {
+            DEBUG(1,("Name register reply has wrong answer rr_type\n"));
+            return False;
+        }
+#endif
         break;
     }
 
@@ -653,29 +621,29 @@ static BOOL response_compatible(struct response_record *n,
     case NAME_QUERY_FIND_MST:
     case NAME_QUERY_MST_CHK:
     {
-               if (nmb->answers->rr_type != NMB_QUERY)
-               {
-                       DEBUG(1,("Name query reply has wrong answer rr_type\n"));
-                       return False;
-               }
-               break;
+        if (nmb->answers->rr_type != NMB_QUERY)
+        {
+            DEBUG(1,("Name query reply has wrong answer rr_type\n"));
+            return False;
+        }
+        break;
     }
       
     case NAME_STATUS_DOM_SRV_CHK:
     case NAME_STATUS_SRV_CHK:
     {
-               if (nmb->answers->rr_type != NMB_STATUS)
-               {
-                       DEBUG(1,("Name status reply has wrong answer rr_type\n"));
-                       return False;
-               }
-               break;
+        if (nmb->answers->rr_type != NMB_STATUS)
+        {
+            DEBUG(1,("Name status reply has wrong answer rr_type\n"));
+            return False;
+        }
+        break;
     }
       
     default:
     {
-               DEBUG(1,("unknown state type received in response_netbios_packet\n"));
-               return False;
+        DEBUG(1,("unknown state type received in response_netbios_packet\n"));
+        return False;
     }
   }
   return True;
@@ -685,27 +653,62 @@ static BOOL response_compatible(struct response_record *n,
 /****************************************************************************
   process the response packet received
   ****************************************************************************/
-static void response_process(struct subnet_record *d, struct packet_struct *p,
-                               struct response_record *n, struct nmb_packet *nmb,
-                               BOOL bcast, struct nmb_name *ans_name)
+void response_process(struct in_addr ip, struct subnet_record *d,
+                struct response_record *n, 
+                int rcode, char *nmb_data, struct nmb_name *q_name,
+                time_t ttl, BOOL bcast, struct nmb_name *ans_name)
 {
   switch (n->state)
   {
     case NAME_RELEASE:
     {
-        response_name_release(d, p);
+        struct nmb_ip found;
+        struct nmb_ip *data = NULL;
+        
+        if (rcode == 0 && nmb_data)
+        {
+            /* copy the netbios flags and the ip address out of the reply data */
+            found.nb_flags = nmb_data[0];
+            putip((char*)&found.ip,&nmb_data[2]);
+            
+            data = &found;
+        }
+        response_name_release(data, q_name, d);
         break;
     }
 
     case NAME_REGISTER:
     {
-               response_name_reg(d, p);
+        struct nmb_ip found;
+        struct nmb_ip *data = NULL;
+        
+        if (rcode == 0 && nmb_data)
+        {
+            /* copy the netbios flags and the ip address out of the reply data */
+            found.nb_flags = nmb_data[0];
+            putip((char*)&found.ip,&nmb_data[2]);
+            
+            data = &found;
+        }
+      
+        response_name_reg(data, ans_name, ttl, bcast, ip, d, n->token);
         break;
     }
 
     case NAME_REGISTER_CHALLENGE:
     {
-        response_name_query_register(nmb, ans_name, n, d);
+        struct nmb_ip found;
+        struct nmb_ip *data = NULL;
+        
+        if (rcode == 0 && nmb_data)
+        {
+            /* copy the netbios flags and the ip address out of the reply data */
+            found.nb_flags = nmb_data[0];
+            putip((char*)&found.ip,&nmb_data[2]);
+            
+            data = &found;
+        }
+        response_name_query_register(data, ans_name, n, d);
         break;
     }
 
@@ -713,44 +716,66 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
     case NAME_QUERY_SRV_CHK:
     case NAME_QUERY_FIND_MST:
     {
-               response_server_check(ans_name, n, d);
-               break;
+        response_server_check(ans_name, n, d);
+        break;
     }
       
     case NAME_STATUS_DOM_SRV_CHK:
     case NAME_STATUS_SRV_CHK:
     {
-               response_name_status_check(p->ip, nmb, bcast, n, d);
-               break;
+        response_name_status_check(ip,nmb_data,bcast,n,d);
+        break;
     }
       
     case NAME_QUERY_ANNOUNCE_HOST:
     {
-               response_announce_host(ans_name, nmb, n, d);
-               break;
+        struct nmb_ip found;
+        struct nmb_ip *data = NULL;
+        
+        if (rcode == 0 && nmb_data)
+        {
+            /* copy the netbios flags and the ip address out of the reply data */
+            found.nb_flags = nmb_data[0];
+            putip((char*)&found.ip,&nmb_data[2]);
+            
+            data = &found;
+        }
+        response_announce_host(data, ans_name, n, d);
+        break;
     }
       
     case NAME_QUERY_CONFIRM:
     case NAME_QUERY_SYNC_LOCAL:
     case NAME_QUERY_SYNC_REMOTE:
     {
-               response_name_query_sync(nmb, ans_name, bcast, n, d);
-               break;
+        struct nmb_ip found;
+        struct nmb_ip *data = NULL;
+        
+        if (rcode == 0 && nmb_data)
+        {
+            /* copy the netbios flags and the ip address out of the reply data */
+            found.nb_flags = nmb_data[0];
+            putip((char*)&found.ip,&nmb_data[2]);
+            
+            data = &found;
+        }
+        response_name_query_sync(data,ans_name,bcast,n,d);
+        break;
     }
     case NAME_QUERY_MST_CHK:
     {
-               /* no action required here. it's when NO responses are received
-                  that we need to do something. see expire_name_query_entries() */
-       
-               DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
-                                       namestr(&n->name), inet_ntoa(n->send_ip)));
-               break;
+        /* no action required here. it's when NO responses are received
+           that we need to do something. see expire_name_query_entries() */
+    
+        DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
+                    namestr(&n->name), inet_ntoa(n->send_ip)));
+        break;
     }
 
     default:
     {
-               DEBUG(1,("unknown state type received in response_netbios_packet\n"));
-               break;
+        DEBUG(1,("unknown state type received in response_netbios_packet\n"));
+        break;
     }
   }
 }
@@ -780,7 +805,9 @@ void response_netbios_packet(struct packet_struct *p)
     return;
   }
 
-  /* args wrong way round: spotted by ccm@shentel.net */
+  DEBUG(4,("response packet received: %s %d\n",
+              inet_ntoa(p->ip),n->response_id));
+
   if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
   {
     DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
@@ -792,13 +819,13 @@ void response_netbios_packet(struct packet_struct *p)
   {
       /* hm. the packet received was a response, but with no answer. wierd! */
       DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
-              inet_ntoa(p->ip), BOOLSTR(bcast)));
+           inet_ntoa(p->ip), BOOLSTR(bcast)));
       return;
   }
 
   ans_name = &nmb->answers->rr_name;
   DEBUG(3,("response for %s from %s (bcast=%s)\n",
-          namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
+       namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
   
   debug_rr_type(nmb->answers->rr_type);
 
@@ -816,7 +843,11 @@ void response_netbios_packet(struct packet_struct *p)
     return;
 
   /* now deal with the current state */
-  response_process(d, p, n, nmb, bcast, ans_name);
+  response_process(p->ip, d, n, 
+                    nmb->header.rcode, 
+                    nmb->answers->rdata,
+                    question,
+                    nmb->answers->ttl, bcast, ans_name);
 }
 
 
index 0380c1460affa2e7c693614af517ab41aae9a8b7..b341fcfdc868f898f653c73996d99f572a512869 100644 (file)
@@ -23,6 +23,9 @@
    14 jan 96: lkcl@pires.co.uk
    added multiple workgroup domain master support
 
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -36,15 +39,11 @@ extern int DEBUGLEVEL;
 extern pstring scope;
 extern BOOL CanRecurse;
 
-extern pstring myname;
-
 extern int ClientNMB;
 extern int ClientDGRAM;
 
 extern struct in_addr ipzero;
 
-extern int workgroup_count; /* total number of workgroups we know about */
-
 /* this is our domain/workgroup/server database */
 extern struct subnet_record *subnetlist;
 
@@ -64,7 +63,7 @@ state - 0x01 become backup instead of master
       - 0x02 remove all entries in browse list and become non-master
       - 0x04 stop master browser service altogether. NT ignores this 
 **************************************************************************/
-void reset_server(char *name, int state, struct in_addr ip)
+void reset_server(struct work_record *work, char *name, int state, struct in_addr ip)
 {
   char outbuf[20];
   char *p;
@@ -77,10 +76,10 @@ void reset_server(char *name, int state, struct in_addr ip)
   p += 2;
 
   DEBUG(2,("sending reset to %s %s of state %d\n",
-          name,inet_ntoa(ip),state));
+       name,inet_ntoa(ip),state));
 
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     myname,name,0x20,0x1d,ip,*iface_ip(ip));
+              conf_browsing_alias(work->token),name,0x20,0x1d,ip,*iface_ip(ip));
 }
 
 
@@ -99,47 +98,47 @@ void tell_become_backup(void)
     {
       struct work_record *work;
       for (work = d->workgrouplist; work; work = work->next)
-       {
-         struct server_record *s;
-         int num_servers = 0;
-         int num_backups = 0;
-         
-         for (s = work->serverlist; s; s = s->next)
-           {
-             if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
-             
-             num_servers++;
-             
-             if (strequal(myname, s->serv.name)) continue;
-             
-             if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
-               num_backups++;
-               continue;
-             }
-             
-             if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
-             
-             if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
-             
-             DEBUG(3,("num servers: %d num backups: %d\n", 
-                      num_servers, num_backups));
-             
-             /* make first server a backup server. thereafter make every
-                tenth server a backup server */
-             if (num_backups != 0 && (num_servers+9) / num_backups > 10)
-               {
-                 continue;
-               }
-             
-             DEBUG(2,("sending become backup to %s %s for %s\n",
-                      s->serv.name, inet_ntoa(d->bcast_ip),
-                      work->work_group));
-             
-             /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
-             do_announce_request(s->serv.name, work->work_group,
-                                 ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
-           }
-       }
+    {
+      struct server_record *s;
+      int num_servers = 0;
+      int num_backups = 0;
+      
+      for (s = work->serverlist; s; s = s->next)
+        {
+          if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
+          
+          num_servers++;
+          
+          if (strequal(conf_browsing_alias(work->token), s->serv.name)) continue;
+          
+          if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
+        num_backups++;
+        continue;
+          }
+          
+          if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
+          
+          if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
+          
+          DEBUG(3,("num servers: %d num backups: %d\n", 
+               num_servers, num_backups));
+          
+          /* make first server a backup server. thereafter make every
+         tenth server a backup server */
+          if (num_backups != 0 && (num_servers+9) / num_backups > 10)
+        {
+          continue;
+        }
+          
+          DEBUG(2,("sending become backup to %s %s for %s\n",
+               s->serv.name, inet_ntoa(d->bcast_ip),
+               work->work_group));
+          
+          /* type 11 request from conf_browsing_alias(work->token)(20) to WG(1e) for SERVER */
+          do_announce_request(s->serv.name, s->serv.name, work->work_group,
+                  ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
+        }
+    }
     }
 }
 
@@ -150,8 +149,23 @@ void tell_become_backup(void)
   ******************************************************************/
 BOOL same_context(struct dgram_packet *dgram)
 {
-  if (!strequal(dgram->dest_name  .scope,scope )) return(True);
-  if ( strequal(dgram->source_name.name ,myname)) return(True);
+  if (!strequal(dgram->dest_name  .scope,scope )) return True;
+  
+  return False;
+}
+
+
+/*******************************************************************
+  am I listening on a name. XXXX check the type of name as well.
+  ******************************************************************/
+BOOL listening_name(struct work_record *work, struct nmb_name *n)
+{
+  if (strequal(n->name,conf_browsing_alias(work->token)) ||
+      strequal(n->name,work->work_group) ||
+      strequal(n->name,MSBROWSE))
+    {
+      return(True);
+    }
   
   return(False);
 }
@@ -197,8 +211,8 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
   
   DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
   DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
-          namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
-          servertype,browse_type,browse_sig,comment));
+       namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
+       servertype,browse_type,browse_sig,comment));
   
   name[15] = 0;  
   
@@ -213,7 +227,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
        dgram->dest_name.name_type != 0x1))
     {
       DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
-               command, inet_ntoa(ip), namestr(&dgram->dest_name)));
+        command, inet_ntoa(ip), namestr(&dgram->dest_name)));
       return;
     }
   
@@ -265,7 +279,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
   if (command == ANN_LocalMasterAnnouncement)
   {
     add_browser_entry(serv_name,dgram->dest_name.name_type,
-                     work->work_group,30,ip,True);
+              work->work_group,30,ip,True);
   }
 }
 
@@ -278,26 +292,40 @@ static void process_master_announce(struct packet_struct *p,char *buf)
   struct in_addr ip = dgram->header.source_ip;
   struct subnet_record *d = find_subnet(ip);
   struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
+  char *to_name = dgram->dest_name.name; /* our primary name or an alias */
+
   char *name = buf;
-  struct work_record *work;
+  char *work_name; 
+  int token;
   name[15] = 0;
   
-  DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
+  DEBUG(3,("Master Announce from %s (%s)\n", name, inet_ntoa(ip)));
   
   if (same_context(dgram)) return;
   
   if (!d || !mydomain) return;
   
-  if (!lp_domain_master()) return;
-  
-  for (work = mydomain->workgrouplist; work; work = work->next)
+  token = conf_alias_to_token(to_name);
+
+  if (token == -1)
   {
-    if (AM_MASTER(work))
-    {
-         /* merge browse lists with them */
-         add_browser_entry(name,0x1b, work->work_group,30,ip,True);
-    }
+    DEBUG(4, ("alias %s not known\n", to_name));
+    return;
   }
+
+  /* carry on only if we are a domain master under the server alias */
+  if (!conf_should_domain_master(token)) return;
+
+  /* Convert the server name by which the master browser
+     called this server to the workgroup name. */
+  if ((work_name = conf_workgroup_name(token)) == (char*)NULL)
+  {
+      DEBUG(4, ("process_master_announce(): no alias for \"%s\"\n", to_name));
+      return;
+  }          
+  
+  /* merge browse lists with them */
+  add_browser_entry(name, 0x1b, work_name,30,ip,True);
 }
 
 /*******************************************************************
@@ -322,8 +350,8 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
   char *buf1;
   
   DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
-          namestr(&dgram->dest_name), inet_ntoa(ip),
-          count, info));
+       namestr(&dgram->dest_name), inet_ntoa(ip),
+       count, info));
   
   if (same_context(dgram)) return;
   
@@ -336,44 +364,44 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
     struct subnet_record *d;
       
     DEBUG(4,("Searching for backup browser %s at %s...\n",
-              buf1, inet_ntoa(ip)));
+           buf1, inet_ntoa(ip)));
       
     /* XXXX assume name is a DNS name NOT a netbios name. a more complete
-          approach is to use reply_name_query functionality to find the name */
+       approach is to use reply_name_query functionality to find the name */
 
     back_ip = *interpret_addr2(buf1);
       
     if (zero_ip(back_ip))
-       {
-         DEBUG(4,("Failed to find backup browser server using DNS\n"));
-         continue;
-       }
+    {
+      DEBUG(4,("Failed to find backup browser server using DNS\n"));
+      continue;
+    }
       
       DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
       DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
       
       /* XXXX function needs work */
-         continue;
+      continue;
 
     if ((d = find_subnet(back_ip)))
-       {
-         struct subnet_record *d1;
-         for (d1 = subnetlist; d1; d1 = d1->next)
-         {
-             struct work_record *work;
-             for (work = d1->workgrouplist; work; work = work->next)
-               {
-                 if (work->token == 0 /* token */)
-                 {
-                     queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
-                                          work->work_group,0x1d,
+    {
+      struct subnet_record *d1;
+      for (d1 = subnetlist; d1; d1 = d1->next)
+      {
+          struct work_record *work;
+          for (work = d1->workgrouplist; work; work = work->next)
+        {
+          if (work->token == 0 /* token */)
+          {
+              queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
+                       work->token,work->work_group,0x1d,
                        0,0,0,NULL,NULL,
-                                          False,False,back_ip,back_ip);
-                     return;
-                 }
-               }
-         }
-       }
+                       False,False,back_ip,back_ip);
+              return;
+          }
+        }
+      }
+    }
   }
 }
 
@@ -381,9 +409,9 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
 /****************************************************************************
   send a backup list response.
   **************************************************************************/
-static void send_backup_list(char *work_name, struct nmb_name *src_name,
-                            int token, uint32 info,
-                            int name_type, struct in_addr ip)
+static void send_backup_list(struct work_record *work, struct nmb_name *src_name,
+                 int token, uint32 info,
+                 int name_type, struct in_addr ip)
 {                     
   char outbuf[1024];
   char *p, *countptr, *nameptr;
@@ -391,8 +419,8 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
   char *theirname = src_name->name;
   
   DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", 
-          work_name, inet_ntoa(ip),
-          myname,0x0,theirname,0x0));     
+       work->work_group, inet_ntoa(ip),
+       conf_browsing_alias(work->token),0x0,theirname,0x0));     
   
   if (name_type == 0x1d)
     {
@@ -424,62 +452,51 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
 
 #if 0
 
-  for (d = subnetlist; d; d = d->next)
-  {
-      struct work_record *work;
+  struct server_record *s;
       
-      for (work = d->workgrouplist; work; work = work->next)
-       {
-         struct server_record *s;
-         
-         if (!strequal(work->work_group, work_name)) continue;
-         
-         for (s = work->serverlist; s; s = s->next)
-           { 
-             BOOL found = False;
-             char *n;
-             
-             if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
-             
-             for (n = nameptr; n < p; n = skip_string(n, 1))
-               {
-                 if (strequal(n, s->serv.name)) found = True;
-               }
-             
-             if (found) continue; /* exclude names already added */
-             
-             /* workgroup request: include all backup browsers in the list */
-             /* domain request: include all domain members in the list */
-
-             if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
-                     (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
-               {                          
-                 DEBUG(4, ("%s ", s->serv.name));
-                 
-                 count++;
-                 strcpy(p,s->serv.name);
-                 strupper(p);
-                 p = skip_string(p,1);
-               }
-        }
-       }
+  for (s = work->serverlist; s; s = s->next)
+  { 
+      BOOL found = False;
+      char *n;
+          
+      if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
+          
+    for (n = nameptr; n < p; n = skip_string(n, 1))
+    {
+      if (strequal(n, s->serv.name)) found = True;
+    }
+          
+    if (found) continue; /* exclude names already added */
+          
+      /* workgroup request: include all backup browsers in the list */
+      /* domain request: include all domain members in the list */
+
+    if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
+        (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
+    {                          
+      DEBUG(4, ("%s ", s->serv.name));
+          
+      count++;
+      strcpy(p,s->serv.name);
+      strupper(p);
+      p = skip_string(p,1);
+    }
   }
-
 #endif
 
-       count++;
-       strcpy(p,myname);
-       strupper(p);
-       p = skip_string(p,1);
+    count++;
+    strcpy(p,conf_browsing_alias(work->token));
+    strupper(p);
+    p = skip_string(p,1);
 
   if (count == 0)
-    {
+  {
       DEBUG(4, ("none\n"));
-    }
+  }
   else
-    {
+  {
       DEBUG(4, (" - count %d\n", count));
-    }
+  }
   
   CVAL(countptr, 0) = count;
 
@@ -488,7 +505,7 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
     debug_browse_data(outbuf, len);
   }
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     myname,theirname,0x0,0x0,ip,*iface_ip(ip));
+              conf_browsing_alias(work->token),theirname,0x0,0x0,ip,*iface_ip(ip));
 }
 
 
@@ -519,24 +536,24 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
   
   if (name_type != 0x1b && name_type != 0x1d) {
     DEBUG(0,("backup request to wrong type %d from %s\n",
-             name_type,inet_ntoa(ip)));
+          name_type,inet_ntoa(ip)));
     return;
   }
   
   for (d = subnetlist; d; d = d->next)
     {
       for (work = d->workgrouplist; work; work = work->next)
-       {
-         if (strequal(work->work_group, dgram->dest_name.name))
-           {
-             DEBUG(2,("sending backup list to %s %s id=%x\n",
-                      namestr(&dgram->dest_name),inet_ntoa(ip),info));
-  
-             send_backup_list(work->work_group,&dgram->source_name,
-                              token,info,name_type,ip);
-             return;
-           }
-       
+    {
+      if (strequal(work->work_group, dgram->dest_name.name))
+        {
+          DEBUG(2,("sending backup list to %s %s id=%x\n",
+               namestr(&dgram->dest_name),inet_ntoa(ip),info));
+  
+          send_backup_list(work,&dgram->source_name,
+                   token,info,name_type,ip);
+          return;
+        }
+    } 
     }
 }
 
@@ -556,23 +573,23 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
   int state = CVAL(buf,0);
 
   DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n",
-          namestr(&dgram->dest_name), state));
+       namestr(&dgram->dest_name), state));
 
   /* stop being a master but still deal with being a backup browser */
   if (state & 0x1)
     {
       struct subnet_record *d;
       for (d = subnetlist; d; d = d->next)
-       {
-         struct work_record *work;
-         for (work = d->workgrouplist; work; work = work->next)
-           {
-             if (AM_MASTER(work))
-               {
-                 become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
-               }
-           }
-       }
+    {
+      struct work_record *work;
+      for (work = d->workgrouplist; work; work = work->next)
+        {
+          if (AM_MASTER(work))
+        {
+          become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
+        }
+        }
+    }
     }
   
   /* XXXX documentation inconsistency: the above description does not
@@ -581,21 +598,21 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
 
   /* totally delete all servers and start afresh */
   if (state & 0x2)
+  {
+    struct subnet_record *d;
+    for (d = subnetlist; d; d = d->next)
     {
-      struct subnet_record *d;
-      for (d = subnetlist; d; d = d->next)
-       {
-         struct work_record *work;
-         for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
-       }
-      add_my_subnets(lp_workgroup());
+      struct work_record *work;
+      for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
     }
+    add_my_subnets(lp_workgroup());
+  }
   
   /* stop browsing altogether. i don't think this is a good idea! */
   if (state & 0x4)
-    {
+  {
       DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
-    }
+  }
 }
 
 /*******************************************************************
@@ -616,9 +633,9 @@ static void process_announce_request(struct packet_struct *p,char *buf)
   name[15] = 0;
   
   DEBUG(3,("Announce request from %s to %s token=0x%X\n",
-          name,namestr(&dgram->dest_name), token));
+       name,namestr(&dgram->dest_name), token));
   
-  if (strequal(dgram->source_name.name,myname)) return;
+  if (strequal(dgram->source_name.name,conf_browsing_alias(work->token))) return;
   
   /* XXXX BUG or FEATURE?: need to ensure that we are a member of
      this workgroup before announcing, particularly as we only
@@ -630,20 +647,19 @@ static void process_announce_request(struct packet_struct *p,char *buf)
   if (!d) return;
   
   for (work = d->workgrouplist; work; work = work->next)
-    {
+  {
      /* XXXX BUG: the destination name type should also be checked,
         not just the name. e.g if the name is WORKGROUP(0x1d) then
         we should only respond if we own that name */
     
       if (strequal(dgram->dest_name.name,work->work_group)) 
-       {
-         work->needannounce = True;
-       }
+    {
+      work->needannounce = True;
     }
+  }
 }
 
 
-
 /****************************************************************************
 process a browse frame
 ****************************************************************************/
@@ -657,27 +673,27 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
     case ANN_LocalMasterAnnouncement:
       {
         debug_browse_data(buf, len);
-       process_announce(p,command,buf+1);
-       break;
+    process_announce(p,command,buf+1);
+    break;
       }
       
     case ANN_AnnouncementRequest:
       {
-       process_announce_request(p,buf+1);
-       break;
+    process_announce_request(p,buf+1);
+    break;
       }
       
     case ANN_Election:
       {
-       process_election(p,buf+1);
-       break;
+    process_election(p,buf+1);
+    break;
       }
       
     case ANN_GetBackupListReq:
       {
         debug_browse_data(buf, len);
-       process_send_backup_list(p,buf+1);
-       break;
+    process_send_backup_list(p,buf+1);
+    break;
       }
       
     case ANN_GetBackupListResp:
@@ -689,22 +705,22 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
       
     case ANN_ResetBrowserState:
       {
-       process_reset_browser(p, buf+1);
-       break;
+    process_reset_browser(p, buf+1);
+    break;
       }
       
     case ANN_MasterAnnouncement:
       {
-       process_master_announce(p,buf+1);
-       break;
+    process_master_announce(p,buf+1);
+    break;
       }
       
     default:
       {
-       struct dgram_packet *dgram = &p->packet.dgram;
-       DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
-                command, namestr(&dgram->source_name), 
-                inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+    struct dgram_packet *dgram = &p->packet.dgram;
+    DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
+         command, namestr(&dgram->source_name), 
+         inet_ntoa(p->ip), namestr(&dgram->dest_name)));
       }
     }
 }
index 5b3fd19491de9a013fb639778ccdc2d2d1cdf6e8..4a3d139fdad32f1921b202717f98b464f83ed008 100644 (file)
    14 jan 96: lkcl@pires.co.uk
    added multiple workgroup domain master support
 
+
+   30 July 96: David.Chappell@mail.trincoll.edu
+   Expanded multiple workgroup domain master browser support.
+
 */
 
 #include "includes.h"
@@ -165,10 +169,10 @@ static void expire_names_and_servers(void)
   time_t t = time(NULL);
   
   if (!lastrun) lastrun = t;
-  if (t < lastrun + 5) return;
+  if (t < lastrun + 15) return; /* give samba time to check its names */
   lastrun = t;
   
-  expire_names(t);
+  check_expire_names(t); /* this checks samba's NetBIOS names */
   expire_servers(t);
 }
 
@@ -187,10 +191,10 @@ BOOL reload_services(BOOL test)
       pstring fname;
       strcpy(fname,lp_configfile());
       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
-       {
-         strcpy(servicesf,fname);
-         test = False;
-       }
+    {
+      strcpy(servicesf,fname);
+      test = False;
+    }
     }
 
   if (test && !lp_file_list_changed())
@@ -251,32 +255,32 @@ static void load_hosts_file(char *fname)
       if (count <= 0) continue;
       
       if (count > 0 && count < 2) {
-       DEBUG(0,("Ill formed hosts line [%s]\n",line));     
-       continue;
+    DEBUG(0,("Ill formed hosts line [%s]\n",line));     
+    continue;
       }
       
       if (count >= 4) {
-       DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
-       continue;
+    DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
+    continue;
       }
       
       DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
       
       if (strchr(flags,'G') || strchr(flags,'S')) {
-       DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
-       continue;
+    DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
+    continue;
       }
       
       if (strchr(flags,'M')) {
-       source = SELF;
-       strcpy(myname,name);
+    source = SELF;
+    strcpy(myname,name);
       }
       
       ipaddr = *interpret_addr2(ip);
       d = find_subnet(ipaddr);
       if (d) {
-       add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
-       add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
+    add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
+    add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
       } 
     }
   
@@ -292,8 +296,7 @@ static void process(void)
   BOOL run_election;
 
   while (True)
-    {
-      time_t t = time(NULL);
+  {
       run_election = check_elections();
       listen_for_packets(run_election);
 
@@ -310,12 +313,11 @@ static void process(void)
 
       expire_names_and_servers();
       expire_netbios_response_entries();
-      refresh_my_names(t);
 
       write_browse_list();
       do_browser_lists();
       check_master_browser();
-    }
+  }
 }
 
 
@@ -435,50 +437,50 @@ static void usage(char *pname)
   while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
     {
       switch (opt)
-       {
-       case 's':
-         strcpy(servicesf,optarg);
-         break;          
-       case 'N':
-       case 'B':
-       case 'I':
-       case 'C':
-       case 'G':
-         DEBUG(0,("Obsolete option '%c' used\n",opt));
-         break;
-       case 'H':
-         strcpy(host_file,optarg);
-         break;
-       case 'n':
-         strcpy(myname,optarg);
-         strupper(myname);
-         break;
-       case 'l':
-         sprintf(debugf,"%s.nmb",optarg);
-         break;
-       case 'i':
-         strcpy(scope,optarg);
-         strupper(scope);
-         break;
-       case 'D':
-         is_daemon = True;
-         break;
-       case 'd':
-         DEBUGLEVEL = atoi(optarg);
-         break;
-       case 'p':
-         port = atoi(optarg);
-         break;
-       case 'h':
-         usage(argv[0]);
-         exit(0);
-         break;
-       default:
-         if (!is_a_socket(0)) {
-           usage(argv[0]);
-         }
-         break;
-       }
+    {
+    case 's':
+      strcpy(servicesf,optarg);
+      break;      
+    case 'N':
+    case 'B':
+    case 'I':
+    case 'C':
+    case 'G':
+      DEBUG(0,("Obsolete option '%c' used\n",opt));
+      break;
+    case 'H':
+      strcpy(host_file,optarg);
+      break;
+    case 'n':
+      strcpy(myname,optarg);
+      strupper(myname);
+      break;
+    case 'l':
+      sprintf(debugf,"%s.nmb",optarg);
+      break;
+    case 'i':
+      strcpy(scope,optarg);
+      strupper(scope);
+      break;
+    case 'D':
+      is_daemon = True;
+      break;
+    case 'd':
+      DEBUGLEVEL = atoi(optarg);
+      break;
+    case 'p':
+      port = atoi(optarg);
+      break;
+    case 'h':
+      usage(argv[0]);
+      exit(0);
+      break;
+    default:
+      if (!is_a_socket(0)) {
+        usage(argv[0]);
+      }
+      break;
+    }
     }
 
   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
@@ -487,10 +489,18 @@ static void usage(char *pname)
   get_myname(myhostname,NULL);
 
   if (!reload_services(False))
-    return(-1);        
-
+    return(-1); 
+  
   init_structs();
 
+  /* reads the smbbrowse.conf file. this is an alias mapping between
+     workgroups and samba NetBIOS aliases. samba can therefore be
+     a member of multiple workgroups, a local master browser of
+     multiple workgroups, or a domain master browser of multiple
+     workgroups, via each NetBIOS name alias. the aliases MUST
+     be unique for this to work. */
+  read_smbbrowse_conf(myname);
+    
   reload_services(True);
 
   set_samba_nb_type();
index 2efb364bcae5a929ced3f5dd912d8e2c886b27b7..5a4d93f1a000b93b8460fe04fde85bb4effc8a73 100644 (file)
@@ -48,7 +48,7 @@ fudge for getpass function
 ****************************************************************************/
 char *getsmbpass(char *pass)
 {
-       return "dummy"; /* return anything: it should be ignored anyway */
+    return "dummy"; /* return anything: it should be ignored anyway */
 }
 
 /****************************************************************************
@@ -84,43 +84,46 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv
   p = skip_string(p,1);
   
   if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
-                  &rprcnt,&rdrcnt, param,NULL,
-                  &rparam,&rdata))
+           &rprcnt,&rdrcnt, param,NULL,
+           &rparam,&rdata))
     {
       int res = SVAL(rparam,0);
       int converter=SVAL(rparam,2);
       int i;
       
       if (res == 0)
-       {
-         count=SVAL(rparam,4);
-         p = rdata;
-         
-         for (i = 0;i < count;i++, p += 26)
-           {
-             char *sname = p;
-             uint32 stype = IVAL(p,18);
-             int comment_offset = IVAL(p,22) & 0xFFFF;
-             char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
-             
-             struct work_record *w = work;
-             
-             DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
-             
-             if (stype & SV_TYPE_DOMAIN_ENUM)
-               {
-                 /* creates workgroup on remote subnet */
-                 if ((w = find_workgroupstruct(d,sname,True)))
-                   {
-                     announce_request(w, d->bcast_ip);
-                   }
-               }
-             
-          if (w)
-               add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
-           }
-       }
+    {
+      count=SVAL(rparam,4);
+      p = rdata;
+      
+      for (i = 0;i < count;i++, p += 26)
+        {
+          char *sname = p;
+          uint32 stype = IVAL(p,18);
+          int comment_offset = IVAL(p,22) & 0xFFFF;
+          char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
+          
+          struct work_record *w = work;
+          
+          DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
+          
+        if (stype & SV_TYPE_DOMAIN_ENUM)
+        {
+          /* creates workgroup on remote subnet */
+          if ((w = find_workgroupstruct(d,sname,True)))
+            {
+              announce_request(w, d->bcast_ip);
+            }
+        }
+
+        if (w)
+        {
+          add_server_entry(d,w,sname,stype & ~SV_TYPE_LOCAL_LIST_ONLY,
+                           lp_max_ttl(),cmnt,False);
+        }
+      }
     }
+  }
   
   if (rparam) free(rparam);
   if (rdata) free(rdata);
@@ -136,7 +139,7 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv
   do a NetServerEnum and update our server and workgroup databases.
   ******************************************************************/
 void sync_browse_lists(struct subnet_record *d, struct work_record *work,
-               char *name, int nm_type, struct in_addr ip, BOOL local)
+        char *name, int nm_type, struct in_addr ip, BOOL local)
 {
   uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
 
@@ -151,7 +154,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
   got_pass = True;
   
   DEBUG(4,("sync browse lists with %s for %s %s\n",
-           work->work_group, name, inet_ntoa(ip)));
+        work->work_group, name, inet_ntoa(ip)));
   
   strcpy(workgroup,work->work_group);
   strcpy(desthost,name);
@@ -170,11 +173,11 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
   if (cli_open_sockets(SMB_PORT))
     {
       if (cli_send_login(NULL,NULL,True,True))
-       {
-         add_info(d, work, local_type|SV_TYPE_DOMAIN_ENUM);
-         add_info(d, work, local_type|(SV_TYPE_ALL&
+    {
+      add_info(d, work, local_type|SV_TYPE_DOMAIN_ENUM);
+      add_info(d, work, local_type|(SV_TYPE_ALL&
                       ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY)));
-       }
+    }
       
       close_sockets();
     }
index 87209d1bb7c21fbac77c48fcefac695dac574e82..2a76ce70f773e60168602bcd5c4e1ebbb9158df6 100644 (file)
@@ -106,33 +106,34 @@ extern int coding_system;
  */
 typedef struct
 {
-  char *szPrintcapname;
-  char *szLockDir;
-  char *szRootdir;
+  char *szAutoServices;
+  char *szCharacterSet;
+  char *szConfigFile;
   char *szDefaultService;
   char *szDfree;
-  char *szMsgCommand;
+  char *szDomainController;
   char *szHostsEquiv;
-  char *szServerString;
-  char *szAutoServices;
-  char *szPasswdProgram;
-  char *szPasswdChat;
+  char *szInterfaces;
+  char *szLockDir;
   char *szLogFile;
-  char *szConfigFile;
-  char *szSMBPasswdFile;
+  char *szLogonScript;
+  char *szMsgCommand;
+  char *szPasswdChat;
+  char *szPasswdProgram;
   char *szPasswordServer;
+  char *szPrintcapname;
+  char *szRemoteAnnounce;
+  char *szRootdir;
+  char *szServerComment;
+  char *szServerString;
+  char *szSmbrun;
+  char *szSMBPasswdFile;
+  char *szSocketAddress;
   char *szSocketOptions;
-  char *szValidChars;
-  char *szWorkGroup;
-  char *szDomainController;
   char *szUsernameMap;
-  char *szCharacterSet;
-  char *szLogonScript;
-  char *szSmbrun;
+  char *szValidChars;
   char *szWINSserver;
-  char *szInterfaces;
-  char *szRemoteAnnounce;
-  char *szSocketAddress;
+  char *szWorkGroup;
   int max_log_size;
   int mangled_stack;
   int max_xmit;
@@ -152,6 +153,7 @@ typedef struct
   BOOL bWINSsupport;
   BOOL bWINSproxy;
   BOOL bPreferredMaster;
+  BOOL bLocalMaster;
   BOOL bDomainMaster;
   BOOL bDomainLogons;
   BOOL bEncryptPasswords;
@@ -382,6 +384,7 @@ struct parm_struct
   {"hosts equiv",      P_STRING,  P_GLOBAL, &Globals.szHostsEquiv,      NULL},
   {"preload",          P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL},
   {"auto services",    P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL},
+  {"server comment",   P_STRING,  P_GLOBAL, &Globals.szServerComment,   NULL},
   {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL},
   {"printcap name",    P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL},
   {"printcap",         P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL},
@@ -425,6 +428,7 @@ struct parm_struct
   {"wins server",      P_STRING,  P_GLOBAL, &Globals.szWINSserver,      NULL},
   {"preferred master", P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL},
   {"prefered master",  P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL},
+  {"local master",     P_BOOL,    P_GLOBAL, &Globals.bLocalMaster,      NULL},
   {"domain master",    P_BOOL,    P_GLOBAL, &Globals.bDomainMaster,     NULL},
   {"domain logons",    P_BOOL,    P_GLOBAL, &Globals.bDomainLogons,     NULL},
   {"browse list",      P_BOOL,    P_GLOBAL, &Globals.bBrowseList,       NULL},
@@ -560,6 +564,9 @@ static void init_globals(void)
   string_set(&Globals.szSocketAddress, "0.0.0.0");
   sprintf(s,"Samba %s",VERSION);
   string_set(&Globals.szServerString,s);
+  strcpy(s,"Samba %v"); /* samba comment */
+  string_sub(s,"%v",VERSION);
+  string_set(&Globals.szServerComment,s);
   Globals.bLoadPrinters = True;
   Globals.bUseRhosts = False;
   Globals.max_packet = 65535;
@@ -584,8 +591,9 @@ static void init_globals(void)
   Globals.bSyslogOnly = False;
   Globals.os_level = 0;
   Globals.max_ttl = 60*60*4; /* 2 hours default */
-  Globals.bPreferredMaster = True;
-  Globals.bDomainMaster = False;
+  Globals.bPreferredMaster = True; /* force election on startup */
+  Globals.bLocalMaster  = True; /* master browser on local subnet */
+  Globals.bDomainMaster = False; /* maintain wide area network browse list */
   Globals.bDomainLogons = False;
   Globals.bBrowseList = True;
   Globals.bWINSsupport = True;
@@ -724,6 +732,7 @@ FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
+FN_GLOBAL_STRING(lp_server_comment,&Globals.szServerComment)
 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
@@ -747,6 +756,7 @@ FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
 
 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
+FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
index dd9b9661ae8e99cc424bd72d53cd87903da8c7fe..916d7e3cc493fe559fceb456928b111e71cfb051 100644 (file)
@@ -983,8 +983,26 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
 
   if (strcmp(str1, "WrLehDz") == 0) {
     StrnCpy(domain, p, sizeof(fstring)-1);
-  } else {
-    StrnCpy(domain, lp_workgroup(), sizeof(fstring)-1);    
+  }
+  else
+  {
+    /* a server will connect to us under one of samba's NetBIOS
+       name aliases, and by not giving us a domain name it
+       assumes we know which domain it's talking about.
+       do a look-up for the workgroup name against the name
+       the host connected to us as.
+     */
+       
+    char *work_alias;
+       char host_alias[16];
+
+       StrnCpy(host_alias, local_machine, 15);
+       work_alias = conf_alias_to_workgroup(host_alias); /* look-up */
+
+       DEBUG(4,("host alias: %s work_alias: %s\n",
+                               host_alias, work_alias));
+       if (work_alias)
+      StrnCpy(domain, work_alias, sizeof(fstring)-1);    
   }
 
   if (lp_browse_list())
@@ -1668,9 +1686,23 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
       pstring comment;
       uint32 servertype=DFLT_SERVER_TYPE;
 
+      char *work_alias;
+         char host_alias[16];
+         char domain[16];
+  
+         StrnCpy(host_alias, local_machine, 15);
+         work_alias = conf_alias_to_workgroup(host_alias); /* look-up */
+  
+         DEBUG(4,("host alias: