summaryrefslogtreecommitdiffstats
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/nameserv.h58
-rw-r--r--source3/include/proto.h349
-rw-r--r--source3/lib/util.c666
-rw-r--r--source3/nameannounce.c421
-rw-r--r--source3/namebrowse.c57
-rw-r--r--source3/nameconf.c349
-rw-r--r--source3/namedbname.c268
-rw-r--r--source3/namedbresp.c10
-rw-r--r--source3/namedbserver.c89
-rw-r--r--source3/namedbsubnet.c151
-rw-r--r--source3/namedbwork.c120
-rw-r--r--source3/nameelect.c306
-rw-r--r--source3/namepacket.c327
-rw-r--r--source3/nameresp.c381
-rw-r--r--source3/nameserv.c243
-rw-r--r--source3/nameservreply.c2
-rw-r--r--source3/nameservresp.c757
-rw-r--r--source3/namework.c412
-rw-r--r--source3/nmbd/nmbd.c142
-rw-r--r--source3/nmbsync.c77
-rw-r--r--source3/param/loadparm.c52
-rw-r--r--source3/smbd/ipc.c38
-rw-r--r--source3/smbd/server.c2
23 files changed, 2863 insertions, 2414 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index e4876bac57..404c0531e5 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -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;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e20238fee4..293179d4ab 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 31ad3da31c..45fdb04506 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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);
diff --git a/source3/nameannounce.c b/source3/nameannounce.c
index ff2c89df85..84a5f2627e 100644
--- a/source3/nameannounce.c
+++ b/source3/nameannounce.c
@@ -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);
}
-
}
diff --git a/source3/namebrowse.c b/source3/namebrowse.c
index b426bc7a15..8ebf7b8c90 100644
--- a/source3/namebrowse.c
+++ b/source3/namebrowse.c
@@ -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
index 0000000000..79fa2abe43
--- /dev/null
+++ b/source3/nameconf.c
@@ -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);
+}
+
+
diff --git a/source3/namedbname.c b/source3/namedbname.c
index 1f16553b0f..74777a9145 100644
--- a/source3/namedbname.c
+++ b/source3/namedbname.c
@@ -27,6 +27,10 @@
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;
diff --git a/source3/namedbresp.c b/source3/namedbresp.c
index d89bfe8ae8..10a9523b8d 100644
--- a/source3/namedbresp.c
+++ b/source3/namedbresp.c
@@ -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);
diff --git a/source3/namedbserver.c b/source3/namedbserver.c
index afb1dc1431..260f8f3475 100644
--- a/source3/namedbserver.c
+++ b/source3/namedbserver.c
@@ -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);
+ }
}
}
diff --git a/source3/namedbsubnet.c b/source3/namedbsubnet.c
index 0bad79246a..94decb7f0b 100644
--- a/source3/namedbsubnet.c
+++ b/source3/namedbsubnet.c
@@ -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);
diff --git a/source3/namedbwork.c b/source3/namedbwork.c
index 04f2103254..172a93860c 100644
--- a/source3/namedbwork.c
+++ b/source3/namedbwork.c
@@ -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));
+ }
+ }
+ }
+ }
}
}
diff --git a/source3/nameelect.c b/source3/nameelect.c
index 07429013e0..225b0bfaae 100644
--- a/source3/nameelect.c
+++ b/source3/nameelect.c
@@ -28,10 +28,12 @@
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;
}
diff --git a/source3/namepacket.c b/source3/namepacket.c
index 5bfa55d4f1..1ebdf0a2bd 100644
--- a/source3/namepacket.c
+++ b/source3/namepacket.c
@@ -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;
diff --git a/source3/nameresp.c b/source3/nameresp.c
index 7fcb41e79f..a9422116fb 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -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;
}
diff --git a/source3/nameserv.c b/source3/nameserv.c
index c8bbb52811..20b46d5224 100644
--- a/source3/nameserv.c
+++ b/source3/nameserv.c
@@ -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;
+ }
}
diff --git a/source3/nameservreply.c b/source3/nameservreply.c
index b01c2c25b4..ae568198ac 100644
--- a/source3/nameservreply.c
+++ b/source3/nameservreply.c
@@ -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);
}
diff --git a/source3/nameservresp.c b/source3/nameservresp.c
index a4cda7cdfb..0b8e23bfae 100644
--- a/source3/nameservresp.c
+++ b/source3/nameservresp.c
@@ -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);
}
diff --git a/source3/namework.c b/source3/namework.c
index 0380c1460a..b341fcfdc8 100644
--- a/source3/namework.c
+++ b/source3/namework.c
@@ -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)));
}
}
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 5b3fd19491..4a3d139fda 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -23,6 +23,10 @@
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();
diff --git a/source3/nmbsync.c b/source3/nmbsync.c
index 2efb364bca..5a4d93f1a0 100644
--- a/source3/nmbsync.c
+++ b/source3/nmbsync.c
@@ -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();
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 87209d1bb7..2a76ce70f7 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -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)
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index dd9b9661ae..916d7e3cc4 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -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: %s work_alias: %s\n",
+ host_alias, work_alias));
+ if (work_alias)
+ StrnCpy(domain, work_alias, sizeof(fstring)-1);
+ else
+ *domain = 0;
+
strcpy(comment,lp_serverstring());
- if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
+ if ((count=get_server_info(SV_TYPE_ALL,&servers,domain))>0) {
for (i=0;i<count;i++)
if (strequal(servers[i].name,local_machine)) {
servertype = servers[i].type;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 0e0a524f16..4aaab4c087 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -3746,6 +3746,8 @@ static void usage(char *pname)
DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
}
+ read_smbbrowse_conf(myhostname);
+
process();
close_sockets();