mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
backout all the changes to nmbd.
The 1.9.16 tree is now back to 1.9.16p2 as far as nmbd is concerned
apart from a small change that fixes the announce type in two places.
(This used to be commit 45e66a69d3
)
This commit is contained in:
parent
5a2f52b79e
commit
afd08462ad
@ -3787,12 +3787,10 @@ static BOOL list_servers(char *wk_grp)
|
|||||||
|
|
||||||
for (i=0;i<count;i++) {
|
for (i=0;i<count;i++) {
|
||||||
char *sname = p2;
|
char *sname = p2;
|
||||||
uint32 stype = IVAL(p2,18);
|
|
||||||
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
||||||
printf("\t%-16.16s %s (%8x)\n",
|
printf("\t%-16.16s %s\n",
|
||||||
sname,
|
sname,
|
||||||
comment_offset?rdata+comment_offset-converter:"",
|
comment_offset?rdata+comment_offset-converter:"");
|
||||||
stype);
|
|
||||||
|
|
||||||
ok=True;
|
ok=True;
|
||||||
p2 += 26;
|
p2 += 26;
|
||||||
@ -3828,12 +3826,10 @@ static BOOL list_servers(char *wk_grp)
|
|||||||
|
|
||||||
for (i=0;i<count;i++) {
|
for (i=0;i<count;i++) {
|
||||||
char *sname = p2;
|
char *sname = p2;
|
||||||
uint32 stype = IVAL(p2,18);
|
|
||||||
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
||||||
printf("\t%-16.16s %s (%8x)\n",
|
printf("\t%-16.16s %s\n",
|
||||||
sname,
|
sname,
|
||||||
comment_offset?rdata+comment_offset-converter:"",
|
comment_offset?rdata+comment_offset-converter:"");
|
||||||
stype);
|
|
||||||
|
|
||||||
ok=True;
|
ok=True;
|
||||||
p2 += 26;
|
p2 += 26;
|
||||||
|
@ -54,19 +54,6 @@
|
|||||||
#define NB_HFLAG 0x60 /* microsoft 'hybrid' node type */
|
#define NB_HFLAG 0x60 /* microsoft 'hybrid' node type */
|
||||||
#define NB_FLGMSK 0x60
|
#define NB_FLGMSK 0x60
|
||||||
|
|
||||||
|
|
||||||
#define WG_BROWSE_SIGNATURE 0x017e
|
|
||||||
#define WG_BROWSE_VERSION 0xff08
|
|
||||||
|
|
||||||
#define HOST_BROWSE_SIGNATURE 0xaa55
|
|
||||||
#define HOST_BROWSE_VERSION 0x010f
|
|
||||||
|
|
||||||
#define WG_MAJOR_VERSION 0x03
|
|
||||||
#define WG_MINOR_VERSION 0x0a
|
|
||||||
|
|
||||||
#define HOST_MAJOR_VERSION 0x04 /* nt/as host version */
|
|
||||||
#define HOST_MINOR_VERSION 0x01 /* one better than current nt/as version */
|
|
||||||
|
|
||||||
#define REFRESH_TIME (15*60)
|
#define REFRESH_TIME (15*60)
|
||||||
#define NAME_POLL_REFRESH_TIME (5*60)
|
#define NAME_POLL_REFRESH_TIME (5*60)
|
||||||
#define NAME_POLL_INTERVAL 15
|
#define NAME_POLL_INTERVAL 15
|
||||||
@ -86,7 +73,7 @@
|
|||||||
/* server type identifiers */
|
/* server type identifiers */
|
||||||
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
||||||
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
|
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
|
||||||
#define AM_DMBRSE(work) (work->ServerType & SV_TYPE_DOMAIN_MASTER)
|
#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
|
||||||
|
|
||||||
/* microsoft browser NetBIOS name */
|
/* microsoft browser NetBIOS name */
|
||||||
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
||||||
@ -112,19 +99,19 @@ enum master_state
|
|||||||
|
|
||||||
enum state_type
|
enum state_type
|
||||||
{
|
{
|
||||||
NAME_STATUS_DOM_SRV_CHK,
|
NAME_STATUS_DOM_SRV_CHK,
|
||||||
NAME_STATUS_SRV_CHK,
|
NAME_STATUS_SRV_CHK,
|
||||||
NAME_REGISTER_CHALLENGE,
|
NAME_REGISTER_CHALLENGE,
|
||||||
NAME_REGISTER,
|
NAME_REGISTER,
|
||||||
NAME_RELEASE,
|
NAME_RELEASE,
|
||||||
NAME_QUERY_CONFIRM,
|
NAME_QUERY_CONFIRM,
|
||||||
NAME_QUERY_ANNOUNCE_HOST,
|
NAME_QUERY_ANNOUNCE_HOST,
|
||||||
NAME_QUERY_SYNC_LOCAL,
|
NAME_QUERY_SYNC_LOCAL,
|
||||||
NAME_QUERY_SYNC_REMOTE,
|
NAME_QUERY_SYNC_REMOTE,
|
||||||
NAME_QUERY_DOM_SRV_CHK,
|
NAME_QUERY_DOM_SRV_CHK,
|
||||||
NAME_QUERY_SRV_CHK,
|
NAME_QUERY_SRV_CHK,
|
||||||
NAME_QUERY_FIND_MST,
|
NAME_QUERY_FIND_MST,
|
||||||
NAME_QUERY_MST_CHK
|
NAME_QUERY_MST_CHK
|
||||||
};
|
};
|
||||||
|
|
||||||
/* a netbios name structure */
|
/* a netbios name structure */
|
||||||
@ -134,14 +121,6 @@ struct nmb_name {
|
|||||||
int name_type;
|
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 */
|
/* a netbios flags + ip address structure */
|
||||||
/* this is used for multi-homed systems and for internet group names */
|
/* this is used for multi-homed systems and for internet group names */
|
||||||
struct nmb_ip
|
struct nmb_ip
|
||||||
@ -169,16 +148,16 @@ struct name_record
|
|||||||
/* browse and backup server cache for synchronising browse list */
|
/* browse and backup server cache for synchronising browse list */
|
||||||
struct browse_cache_record
|
struct browse_cache_record
|
||||||
{
|
{
|
||||||
struct browse_cache_record *next;
|
struct browse_cache_record *next;
|
||||||
struct browse_cache_record *prev;
|
struct browse_cache_record *prev;
|
||||||
|
|
||||||
char name[17];
|
pstring name;
|
||||||
int type;
|
int type;
|
||||||
char group[17];
|
pstring group;
|
||||||
struct in_addr ip;
|
struct in_addr ip;
|
||||||
time_t sync_time;
|
time_t sync_time;
|
||||||
BOOL synced;
|
BOOL synced;
|
||||||
BOOL local;
|
BOOL local;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* this is used to hold the list of servers in my domain, and is */
|
/* this is used to hold the list of servers in my domain, and is */
|
||||||
@ -204,7 +183,7 @@ struct work_record
|
|||||||
enum master_state state;
|
enum master_state state;
|
||||||
|
|
||||||
/* work group info */
|
/* work group info */
|
||||||
char work_group[17];
|
fstring work_group;
|
||||||
int token; /* used when communicating with backup browsers */
|
int token; /* used when communicating with backup browsers */
|
||||||
int ServerType;
|
int ServerType;
|
||||||
|
|
||||||
@ -235,18 +214,17 @@ struct response_record
|
|||||||
int fd;
|
int fd;
|
||||||
int quest_type;
|
int quest_type;
|
||||||
struct nmb_name name;
|
struct nmb_name name;
|
||||||
struct nmb_ip reply;
|
int nb_flags;
|
||||||
time_t ttl;
|
time_t ttl;
|
||||||
enum name_source source;
|
|
||||||
|
|
||||||
int token; /* unique workgroup token id */
|
|
||||||
int server_type;
|
int server_type;
|
||||||
char my_name[17];
|
fstring my_name;
|
||||||
char my_comment[50];
|
fstring my_comment;
|
||||||
|
|
||||||
BOOL bcast;
|
BOOL bcast;
|
||||||
BOOL recurse;
|
BOOL recurse;
|
||||||
struct in_addr send_ip;
|
struct in_addr send_ip;
|
||||||
|
struct in_addr reply_to_ip;
|
||||||
|
|
||||||
int num_msgs;
|
int num_msgs;
|
||||||
|
|
||||||
|
@ -124,7 +124,6 @@ char *lp_smbrun(void);
|
|||||||
char *lp_configfile(void);
|
char *lp_configfile(void);
|
||||||
char *lp_smb_passwd_file(void);
|
char *lp_smb_passwd_file(void);
|
||||||
char *lp_serverstring(void);
|
char *lp_serverstring(void);
|
||||||
char *lp_server_comment(void);
|
|
||||||
char *lp_printcapname(void);
|
char *lp_printcapname(void);
|
||||||
char *lp_lockdir(void);
|
char *lp_lockdir(void);
|
||||||
char *lp_rootdir(void);
|
char *lp_rootdir(void);
|
||||||
@ -147,7 +146,6 @@ char *lp_interfaces(void);
|
|||||||
char *lp_socket_address(void);
|
char *lp_socket_address(void);
|
||||||
BOOL lp_wins_support(void);
|
BOOL lp_wins_support(void);
|
||||||
BOOL lp_wins_proxy(void);
|
BOOL lp_wins_proxy(void);
|
||||||
BOOL lp_local_master(void);
|
|
||||||
BOOL lp_domain_master(void);
|
BOOL lp_domain_master(void);
|
||||||
BOOL lp_domain_logons(void);
|
BOOL lp_domain_logons(void);
|
||||||
BOOL lp_preferred_master(void);
|
BOOL lp_preferred_master(void);
|
||||||
@ -294,22 +292,20 @@ int reply_sendend(char *inbuf,char *outbuf);
|
|||||||
/*The following definitions come from nameannounce.c */
|
/*The following definitions come from nameannounce.c */
|
||||||
|
|
||||||
void announce_request(struct work_record *work, struct in_addr ip);
|
void announce_request(struct work_record *work, struct in_addr ip);
|
||||||
void do_announce_request(char *info, char *from_name, char *to_name,
|
void do_announce_request(char *info, char *to_name, int announce_type,
|
||||||
int announce_type, int from, int to, struct in_addr dest_ip);
|
int from,
|
||||||
|
int to, struct in_addr dest_ip);
|
||||||
void sync_server(enum state_type state, char *serv_name, char *work_name,
|
void sync_server(enum state_type state, char *serv_name, char *work_name,
|
||||||
int name_type,
|
int name_type,
|
||||||
struct in_addr ip);
|
struct in_addr ip);
|
||||||
void do_announce_host(int command,
|
void do_announce_host(int command,
|
||||||
char *from_name, int from_type, struct in_addr from_ip,
|
char *from_name, int from_type, struct in_addr from_ip,
|
||||||
char *to_name , int to_type , struct in_addr to_ip,
|
char *to_name , int to_type , struct in_addr to_ip,
|
||||||
time_t announce_interval,
|
time_t announce_interval,
|
||||||
char *server_name, int server_type,
|
char *server_name, int server_type, char *server_comment);
|
||||||
char major_version, char minor_version,
|
|
||||||
uint16 browse_version, uint16 browse_sig,
|
|
||||||
char *server_comment);
|
|
||||||
void remove_my_servers(void);
|
void remove_my_servers(void);
|
||||||
void announce_server(struct subnet_record *d, struct work_record *work,
|
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_host(void);
|
||||||
void announce_master(void);
|
void announce_master(void);
|
||||||
void announce_remote(void);
|
void announce_remote(void);
|
||||||
@ -318,7 +314,7 @@ void announce_remote(void);
|
|||||||
|
|
||||||
void expire_browse_cache(time_t t);
|
void expire_browse_cache(time_t t);
|
||||||
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
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);
|
void do_browser_lists(void);
|
||||||
|
|
||||||
/*The following definitions come from nameconf.c */
|
/*The following definitions come from nameconf.c */
|
||||||
@ -326,10 +322,8 @@ void do_browser_lists(void);
|
|||||||
int get_num_workgroups(void);
|
int get_num_workgroups(void);
|
||||||
int conf_workgroup_name_to_token(char *workgroup_name,char *default_name);
|
int conf_workgroup_name_to_token(char *workgroup_name,char *default_name);
|
||||||
char *conf_workgroup_name(int token);
|
char *conf_workgroup_name(int token);
|
||||||
int conf_should_preferred_master(int token);
|
|
||||||
int conf_should_workgroup_member(int token);
|
int conf_should_workgroup_member(int token);
|
||||||
int conf_should_local_master(int token);
|
int conf_should_local_master(int token);
|
||||||
int conf_should_domain_logon(int token);
|
|
||||||
int conf_should_domain_master(int token);
|
int conf_should_domain_master(int token);
|
||||||
char *conf_browsing_alias(int token);
|
char *conf_browsing_alias(int token);
|
||||||
char *conf_browsing_alias_comment(int token);
|
char *conf_browsing_alias_comment(int token);
|
||||||
@ -344,24 +338,24 @@ BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
|
|||||||
BOOL ms_browser_name(char *name, int type);
|
BOOL ms_browser_name(char *name, int type);
|
||||||
void remove_name(struct subnet_record *d, struct name_record *n);
|
void remove_name(struct subnet_record *d, struct name_record *n);
|
||||||
struct name_record *find_name(struct name_record *n,
|
struct name_record *find_name(struct name_record *n,
|
||||||
struct nmb_name *name,
|
struct nmb_name *name,
|
||||||
int search);
|
int search);
|
||||||
struct name_record *find_name_search(struct subnet_record **d,
|
struct name_record *find_name_search(struct subnet_record **d,
|
||||||
struct nmb_name *name,
|
struct nmb_name *name,
|
||||||
int search, struct in_addr ip);
|
int search, struct in_addr ip);
|
||||||
void dump_names(void);
|
void dump_names(void);
|
||||||
void load_netbios_names(void);
|
void load_netbios_names(void);
|
||||||
void remove_netbios_name(struct subnet_record *d,
|
void remove_netbios_name(struct subnet_record *d,
|
||||||
char *name,int type, enum name_source source,
|
char *name,int type, enum name_source source,
|
||||||
struct in_addr ip);
|
struct in_addr ip);
|
||||||
struct name_record *add_netbios_entry(struct subnet_record *d,
|
struct name_record *add_netbios_entry(struct subnet_record *d,
|
||||||
char *name, int type, int nb_flags,
|
char *name, int type, int nb_flags,
|
||||||
int ttl, enum name_source source, struct in_addr ip,
|
int ttl, enum name_source source, struct in_addr ip,
|
||||||
BOOL new_only,BOOL wins);
|
BOOL new_only,BOOL wins);
|
||||||
void check_expire_names(time_t t);
|
void expire_names(time_t t);
|
||||||
struct name_record *search_for_name(struct subnet_record **d,
|
struct name_record *search_for_name(struct subnet_record **d,
|
||||||
struct nmb_name *question,
|
struct nmb_name *question,
|
||||||
struct in_addr ip, int Time, int search);
|
struct in_addr ip, int Time, int search);
|
||||||
|
|
||||||
/*The following definitions come from namedbresp.c */
|
/*The following definitions come from namedbresp.c */
|
||||||
|
|
||||||
@ -370,9 +364,8 @@ void add_response_record(struct subnet_record *d,
|
|||||||
void remove_response_record(struct subnet_record *d,
|
void remove_response_record(struct subnet_record *d,
|
||||||
struct response_record *n);
|
struct response_record *n);
|
||||||
struct response_record *make_response_queue_record(enum state_type state,
|
struct response_record *make_response_queue_record(enum state_type state,
|
||||||
int id,uint16 fd, int quest_type,
|
int id,uint16 fd,
|
||||||
int token, char *name,int type,
|
int quest_type, char *name,int type, int nb_flags, time_t ttl,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
|
||||||
int server_type, char *my_name, char *my_comment,
|
int server_type, char *my_name, char *my_comment,
|
||||||
BOOL bcast,BOOL recurse,
|
BOOL bcast,BOOL recurse,
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip);
|
struct in_addr send_ip, struct in_addr reply_to_ip);
|
||||||
@ -382,13 +375,13 @@ struct response_record *find_response_record(struct subnet_record **d,
|
|||||||
/*The following definitions come from namedbserver.c */
|
/*The following definitions come from namedbserver.c */
|
||||||
|
|
||||||
void remove_old_servers(struct work_record *work, time_t t,
|
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 *find_server(struct work_record *work, char *name);
|
||||||
struct server_record *add_server_entry(struct subnet_record *d,
|
struct server_record *add_server_entry(struct subnet_record *d,
|
||||||
struct work_record *work,
|
struct work_record *work,
|
||||||
char *name,int servertype,
|
char *name,int servertype,
|
||||||
int ttl,char *comment,
|
int ttl,char *comment,
|
||||||
BOOL replace);
|
BOOL replace);
|
||||||
void expire_servers(time_t t);
|
void expire_servers(time_t t);
|
||||||
|
|
||||||
/*The following definitions come from namedbsubnet.c */
|
/*The following definitions come from namedbsubnet.c */
|
||||||
@ -396,21 +389,19 @@ void expire_servers(time_t t);
|
|||||||
struct subnet_record *find_subnet(struct in_addr bcast_ip);
|
struct subnet_record *find_subnet(struct in_addr bcast_ip);
|
||||||
struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
|
struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
|
||||||
void add_subnet_interfaces(void);
|
void add_subnet_interfaces(void);
|
||||||
void add_workgroup_to_subnet(char *group, struct in_addr bcast_ip,
|
void add_my_subnets(char *group);
|
||||||
struct in_addr mask_ip);
|
|
||||||
void add_workgroups_to_subnets();
|
|
||||||
struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||||
struct in_addr mask_ip,
|
struct in_addr mask_ip,
|
||||||
char *name, BOOL add, BOOL lmhosts);
|
char *name, BOOL add, BOOL lmhosts);
|
||||||
void write_browse_list(void);
|
void write_browse_list(void);
|
||||||
|
|
||||||
/*The following definitions come from namedbwork.c */
|
/*The following definitions come from namedbwork.c */
|
||||||
|
|
||||||
struct work_record *remove_workgroup(struct subnet_record *d,
|
struct work_record *remove_workgroup(struct subnet_record *d,
|
||||||
struct work_record *work,
|
struct work_record *work,
|
||||||
BOOL remove_all_servers);
|
BOOL remove_all_servers);
|
||||||
struct work_record *find_workgroupstruct(struct subnet_record *d,
|
struct work_record *find_workgroupstruct(struct subnet_record *d,
|
||||||
fstring name, BOOL add);
|
fstring name, BOOL add);
|
||||||
void dump_workgroups(void);
|
void dump_workgroups(void);
|
||||||
|
|
||||||
/*The following definitions come from nameelect.c */
|
/*The following definitions come from nameelect.c */
|
||||||
@ -418,14 +409,13 @@ void dump_workgroups(void);
|
|||||||
void check_master_browser(void);
|
void check_master_browser(void);
|
||||||
void browser_gone(char *work_name, struct in_addr ip);
|
void browser_gone(char *work_name, struct in_addr ip);
|
||||||
void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
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_unregister_work(struct subnet_record *d, char *name, int name_type);
|
||||||
void name_register_work(struct subnet_record *d, int token,
|
void name_register_work(struct subnet_record *d, char *name, int name_type,
|
||||||
char *name, int name_type, enum name_source source,
|
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
|
||||||
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_master(struct subnet_record *d, struct work_record *work);
|
||||||
void become_nonmaster(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 run_elections(void);
|
||||||
void process_election(struct packet_struct *p,char *buf);
|
void process_election(struct packet_struct *p,char *buf);
|
||||||
BOOL check_elections(void);
|
BOOL check_elections(void);
|
||||||
@ -437,20 +427,20 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len);
|
|||||||
/*The following definitions come from namepacket.c */
|
/*The following definitions come from namepacket.c */
|
||||||
|
|
||||||
void debug_browse_data(char *outbuf, int len);
|
void debug_browse_data(char *outbuf, int len);
|
||||||
BOOL initiate_netbios_packet(uint16 id,
|
void initiate_netbios_packet(uint16 *id,
|
||||||
int fd,int quest_type,char *name,int name_type,
|
int fd,int quest_type,char *name,int name_type,
|
||||||
int nb_flags,BOOL bcast,BOOL recurse,
|
int nb_flags,BOOL bcast,BOOL recurse,
|
||||||
struct in_addr to_ip);
|
struct in_addr to_ip);
|
||||||
void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
||||||
int rcode, int rcv_code, int opcode, BOOL recurse,
|
int rcode, int rcv_code, int opcode, BOOL recurse,
|
||||||
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
||||||
char *data,int len);
|
char *data,int len);
|
||||||
void queue_packet(struct packet_struct *packet);
|
void queue_packet(struct packet_struct *packet);
|
||||||
void run_packet_queue();
|
void run_packet_queue();
|
||||||
void listen_for_packets(BOOL run_election);
|
void listen_for_packets(BOOL run_election);
|
||||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||||
char *dstname,int src_type,int dest_type,
|
char *dstname,int src_type,int dest_type,
|
||||||
struct in_addr dest_ip,struct in_addr src_ip);
|
struct in_addr dest_ip,struct in_addr src_ip);
|
||||||
|
|
||||||
/*The following definitions come from namequery.c */
|
/*The following definitions come from namequery.c */
|
||||||
|
|
||||||
@ -463,30 +453,27 @@ BOOL name_query(int fd,char *name,int name_type,
|
|||||||
|
|
||||||
/*The following definitions come from nameresp.c */
|
/*The following definitions come from nameresp.c */
|
||||||
|
|
||||||
void update_name_trn_id(void);
|
|
||||||
void expire_netbios_response_entries();
|
void expire_netbios_response_entries();
|
||||||
void queue_netbios_pkt_wins(struct subnet_record *d,
|
struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
|
||||||
int fd,int quest_type,enum state_type state,
|
int fd,int quest_type,enum state_type state,
|
||||||
int token, char *name,int name_type,
|
char *name,int name_type,int nb_flags, time_t ttl,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
int server_type, char *my_name, char *my_comment,
|
||||||
int server_type, char *my_name, char *my_comment,
|
BOOL bcast,BOOL recurse,
|
||||||
BOOL bcast,BOOL recurse,
|
struct in_addr send_ip, struct in_addr reply_to_ip);
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip);
|
struct response_record *queue_netbios_packet(struct subnet_record *d,
|
||||||
void queue_netbios_packet(struct subnet_record *d,
|
int fd,int quest_type,enum state_type state,char *name,
|
||||||
int fd,int quest_type,enum state_type state,
|
int name_type,int nb_flags, time_t ttl,
|
||||||
int token, char *name, int name_type,
|
int server_type, char *my_name, char *my_comment,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
BOOL bcast,BOOL recurse,
|
||||||
int server_type, char *my_name, char *my_comment,
|
struct in_addr send_ip, struct in_addr reply_to_ip);
|
||||||
BOOL bcast,BOOL recurse,
|
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip);
|
|
||||||
|
|
||||||
/*The following definitions come from nameserv.c */
|
/*The following definitions come from nameserv.c */
|
||||||
|
|
||||||
void remove_name_entry(struct subnet_record *d, int token, char *name,int type);
|
void remove_name_entry(struct subnet_record *d, char *name,int type);
|
||||||
void add_my_name_entry(struct subnet_record *d, int token,
|
void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
|
||||||
char *name,int type,int nb_flags);
|
|
||||||
void add_my_names(void);
|
void add_my_names(void);
|
||||||
void remove_my_names();
|
void remove_my_names();
|
||||||
|
void refresh_my_names(time_t t);
|
||||||
void query_refresh_names(void);
|
void query_refresh_names(void);
|
||||||
|
|
||||||
/*The following definitions come from nameservreply.c */
|
/*The following definitions come from nameservreply.c */
|
||||||
@ -508,18 +495,13 @@ void reply_name_query(struct packet_struct *p);
|
|||||||
/*The following definitions come from nameservresp.c */
|
/*The following definitions come from nameservresp.c */
|
||||||
|
|
||||||
void debug_state_type(int state);
|
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);
|
void response_netbios_packet(struct packet_struct *p);
|
||||||
|
|
||||||
/*The following definitions come from namework.c */
|
/*The following definitions come from namework.c */
|
||||||
|
|
||||||
void reset_server(struct work_record *work, char *name, int state, struct in_addr ip);
|
void reset_server(char *name, int state, struct in_addr ip);
|
||||||
void tell_become_backup(void);
|
void tell_become_backup(void);
|
||||||
BOOL same_context(struct dgram_packet *dgram);
|
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);
|
void process_browse_packet(struct packet_struct *p,char *buf,int len);
|
||||||
|
|
||||||
/*The following definitions come from nmbd.c */
|
/*The following definitions come from nmbd.c */
|
||||||
@ -545,7 +527,7 @@ int main(int argc,char *argv[]);
|
|||||||
|
|
||||||
char *getsmbpass(char *pass);
|
char *getsmbpass(char *pass);
|
||||||
void sync_browse_lists(struct subnet_record *d, struct work_record *work,
|
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);
|
||||||
|
|
||||||
/*The following definitions come from params.c */
|
/*The following definitions come from params.c */
|
||||||
|
|
||||||
@ -769,7 +751,6 @@ unsigned int Ucrit_checkPid(int pid);
|
|||||||
int sys_select(fd_set *fds,struct timeval *tval);
|
int sys_select(fd_set *fds,struct timeval *tval);
|
||||||
int sys_select(fd_set *fds,struct timeval *tval);
|
int sys_select(fd_set *fds,struct timeval *tval);
|
||||||
int sys_unlink(char *fname);
|
int sys_unlink(char *fname);
|
||||||
unsigned int sys_random(int max_range);
|
|
||||||
int sys_open(char *fname,int flags,int mode);
|
int sys_open(char *fname,int flags,int mode);
|
||||||
DIR *sys_opendir(char *dname);
|
DIR *sys_opendir(char *dname);
|
||||||
int sys_stat(char *fname,struct stat *sbuf);
|
int sys_stat(char *fname,struct stat *sbuf);
|
||||||
|
@ -380,10 +380,10 @@ typedef struct
|
|||||||
/* used for server information: client, nameserv and ipc */
|
/* used for server information: client, nameserv and ipc */
|
||||||
struct server_info_struct
|
struct server_info_struct
|
||||||
{
|
{
|
||||||
char name[17];
|
fstring name;
|
||||||
uint32 type;
|
uint32 type;
|
||||||
char comment[50];
|
fstring comment;
|
||||||
char domain[17]; /* used ONLY in ipc.c NOT namework.c */
|
fstring domain; /* used ONLY in ipc.c NOT namework.c */
|
||||||
BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
|
BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,15 +115,6 @@ int sys_unlink(char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
random number generator
|
|
||||||
********************************************************************/
|
|
||||||
unsigned int sys_random(int max_range)
|
|
||||||
{
|
|
||||||
return(((unsigned int)random()) % max_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
a simple open() wrapper
|
a simple open() wrapper
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
@ -65,7 +65,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
|
|||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
{
|
{
|
||||||
if (i+j >= res->rdlength) break;
|
if (i+j >= res->rdlength) break;
|
||||||
DEBUG(4, ("%02x", (unsigned char)res->rdata[i+j]));
|
DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, ("\n"));
|
DEBUG(4, ("\n"));
|
||||||
|
@ -23,18 +23,19 @@
|
|||||||
14 jan 96: lkcl@pires.co.uk
|
14 jan 96: lkcl@pires.co.uk
|
||||||
added multiple workgroup domain master support
|
added multiple workgroup domain master support
|
||||||
|
|
||||||
30 July 96: David.Chappell@mail.trincoll.edu
|
|
||||||
Expanded multiple workgroup domain master browser support.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
#define TEST_CODE
|
||||||
|
|
||||||
extern int DEBUGLEVEL;
|
extern int DEBUGLEVEL;
|
||||||
extern BOOL CanRecurse;
|
extern BOOL CanRecurse;
|
||||||
|
|
||||||
extern struct in_addr ipzero;
|
extern struct in_addr ipzero;
|
||||||
|
|
||||||
|
extern pstring myname;
|
||||||
|
|
||||||
extern int ClientDGRAM;
|
extern int ClientDGRAM;
|
||||||
extern int ClientNMB;
|
extern int ClientNMB;
|
||||||
|
|
||||||
@ -42,17 +43,14 @@ extern int ClientNMB;
|
|||||||
extern struct subnet_record *subnetlist;
|
extern struct subnet_record *subnetlist;
|
||||||
|
|
||||||
extern int updatecount;
|
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)
|
void announce_request(struct work_record *work, struct in_addr ip)
|
||||||
{
|
{
|
||||||
@ -64,7 +62,7 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
|||||||
work->needannounce = True;
|
work->needannounce = True;
|
||||||
|
|
||||||
DEBUG(2,("sending announce request to %s for workgroup %s\n",
|
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));
|
bzero(outbuf,sizeof(outbuf));
|
||||||
p = outbuf;
|
p = outbuf;
|
||||||
@ -73,7 +71,8 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
|||||||
|
|
||||||
CVAL(p,0) = work->token; /* (local) unique workgroup token id */
|
CVAL(p,0) = work->token; /* (local) unique workgroup token id */
|
||||||
p++;
|
p++;
|
||||||
StrnCpy(p,conf_browsing_alias(work->token),16);
|
StrnCpy(p,myname,16);
|
||||||
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
/* XXXX note: if we sent the announcement request to 0x1d instead
|
/* XXXX note: if we sent the announcement request to 0x1d instead
|
||||||
@ -81,17 +80,16 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
|||||||
us instead of the members of the workgroup. wha-hey! */
|
us instead of the members of the workgroup. wha-hey! */
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||||
conf_browsing_alias(work->token),work->work_group,
|
myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
|
||||||
0x20, 0x1e,
|
|
||||||
ip,*iface_ip(ip));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
request an announcement
|
request an announcement
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void do_announce_request(char *info, char *from_name, char *to_name,
|
void do_announce_request(char *info, char *to_name, int announce_type,
|
||||||
int announce_type, int from, int to, struct in_addr dest_ip)
|
int from,
|
||||||
|
int to, struct in_addr dest_ip)
|
||||||
{
|
{
|
||||||
pstring outbuf;
|
pstring outbuf;
|
||||||
char *p;
|
char *p;
|
||||||
@ -102,15 +100,14 @@ void do_announce_request(char *info, char *from_name, char *to_name,
|
|||||||
p++;
|
p++;
|
||||||
|
|
||||||
DEBUG(2,("sending announce type %d: info %s to %s - server %s(%x)\n",
|
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);
|
StrnCpy(p,info,16);
|
||||||
strupper(p);
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||||
from_name,to_name,from,to,
|
myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
|
||||||
dest_ip,*iface_ip(dest_ip));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -119,23 +116,19 @@ void do_announce_request(char *info, char *from_name, char *to_name,
|
|||||||
control ends up back here via response_name_query.
|
control ends up back here via response_name_query.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void sync_server(enum state_type state, char *serv_name, char *work_name,
|
void sync_server(enum state_type state, char *serv_name, char *work_name,
|
||||||
int name_type,
|
int name_type,
|
||||||
struct in_addr ip)
|
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) */
|
/* with a domain master we can get the whole list (not local only list) */
|
||||||
BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
|
BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
|
||||||
|
|
||||||
add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
|
add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
|
||||||
|
|
||||||
if (state == NAME_STATUS_DOM_SRV_CHK && conf_should_local_master(token))
|
if (state == NAME_STATUS_DOM_SRV_CHK)
|
||||||
{
|
{
|
||||||
/* announce ourselves as a master browser to serv_name */
|
/* announce ourselves as a master browser to serv_name */
|
||||||
do_announce_request(conf_browsing_alias(token), /* info */
|
do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
|
||||||
conf_browsing_alias(token), /* from */
|
0x20, 0, ip);
|
||||||
serv_name, /* to */
|
|
||||||
ANN_MasterAnnouncement, 0x20, 0,ip);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,50 +137,46 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
|
|||||||
send a host announcement packet
|
send a host announcement packet
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void do_announce_host(int command,
|
void do_announce_host(int command,
|
||||||
char *from_name, int from_type, struct in_addr from_ip,
|
char *from_name, int from_type, struct in_addr from_ip,
|
||||||
char *to_name , int to_type , struct in_addr to_ip,
|
char *to_name , int to_type , struct in_addr to_ip,
|
||||||
time_t announce_interval,
|
time_t announce_interval,
|
||||||
char *server_name, int server_type,
|
char *server_name, int server_type, char *server_comment)
|
||||||
char major_version, char minor_version,
|
|
||||||
uint16 browse_version, uint16 browse_sig,
|
|
||||||
char *server_comment)
|
|
||||||
{
|
{
|
||||||
pstring outbuf;
|
pstring outbuf;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
bzero(outbuf,sizeof(outbuf));
|
bzero(outbuf,sizeof(outbuf));
|
||||||
p = outbuf+1;
|
p = outbuf+1;
|
||||||
|
|
||||||
/* command type */
|
/* command type */
|
||||||
CVAL(outbuf,0) = command;
|
CVAL(outbuf,0) = command;
|
||||||
|
|
||||||
/* announcement parameters */
|
/* announcement parameters */
|
||||||
CVAL(p,0) = updatecount;
|
CVAL(p,0) = updatecount;
|
||||||
SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
|
SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
|
||||||
|
|
||||||
StrnCpy(p+5,server_name,16);
|
StrnCpy(p+5,server_name,16);
|
||||||
strupper(p+5);
|
strupper(p+5);
|
||||||
|
|
||||||
CVAL(p,21) = major_version;
|
CVAL(p,21) = 0x02; /* major version */
|
||||||
CVAL(p,22) = minor_version;
|
CVAL(p,22) = 0x02; /* minor version */
|
||||||
|
|
||||||
SIVAL(p,23,server_type);
|
SIVAL(p,23,server_type);
|
||||||
|
SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
|
||||||
|
SSVAL(p,29,0xaa55); /* browse signature */
|
||||||
|
|
||||||
SSVAL(p,27,browse_version);
|
strcpy(p+31,server_comment);
|
||||||
SSVAL(p,29,browse_sig);
|
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));
|
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
|
||||||
|
|
||||||
/* send the announcement */
|
/* send the announcement */
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||||
PTR_DIFF(p,outbuf),
|
PTR_DIFF(p,outbuf),
|
||||||
from_name, to_name,
|
from_name, to_name,
|
||||||
from_type, to_type,
|
from_type, to_type,
|
||||||
to_ip, from_ip);
|
to_ip, from_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -196,23 +185,20 @@ void do_announce_host(int command,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void remove_my_servers(void)
|
void remove_my_servers(void)
|
||||||
{
|
{
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
for (s = work->serverlist; s; s = s->next)
|
for (s = work->serverlist; s; s = s->next)
|
||||||
{
|
{
|
||||||
if (!strequal(conf_browsing_alias(work->token),s->serv.name))
|
if (!strequal(myname,s->serv.name)) continue;
|
||||||
{
|
announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -220,14 +206,13 @@ void remove_my_servers(void)
|
|||||||
announce a server entry
|
announce a server entry
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void announce_server(struct subnet_record *d, struct work_record *work,
|
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)
|
||||||
{
|
{
|
||||||
/* domain type cannot have anything in it that might confuse
|
/* domain type cannot have anything in it that might confuse
|
||||||
a client into thinking that the domain is in fact a server.
|
a client into thinking that the domain is in fact a server.
|
||||||
(SV_TYPE_SERVER_UNIX, for example)
|
(SV_TYPE_SERVER_UNIX, for example)
|
||||||
*/
|
*/
|
||||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||||
|
|
||||||
BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
|
BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
|
||||||
|
|
||||||
if (wins_iface && server_type != 0)
|
if (wins_iface && server_type != 0)
|
||||||
@ -235,13 +220,14 @@ void announce_server(struct subnet_record *d, struct work_record *work,
|
|||||||
/* wins pseudo-ip interface */
|
/* wins pseudo-ip interface */
|
||||||
if (!AM_MASTER(work))
|
if (!AM_MASTER(work))
|
||||||
{
|
{
|
||||||
/* non-master announce by unicast to the domain master */
|
/* non-master announce by unicast to the domain
|
||||||
|
master */
|
||||||
if (!lp_wins_support() && *lp_wins_server())
|
if (!lp_wins_support() && *lp_wins_server())
|
||||||
{
|
{
|
||||||
/* look up the domain master with the WINS server */
|
/* look up the domain master with the WINS server */
|
||||||
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
|
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
|
||||||
NAME_QUERY_ANNOUNCE_HOST,
|
NAME_QUERY_ANNOUNCE_HOST,
|
||||||
work->token,work->work_group,0x1b,0,0,ttl*1000,
|
work->work_group,0x1b,0,ttl*1000,
|
||||||
server_type,name,comment,
|
server_type,name,comment,
|
||||||
False, False, ipzero, d->bcast_ip);
|
False, False, ipzero, d->bcast_ip);
|
||||||
}
|
}
|
||||||
@ -257,7 +243,9 @@ void announce_server(struct subnet_record *d, struct work_record *work,
|
|||||||
|
|
||||||
/* XXXX any other kinds of announcements we need to consider here?
|
/* XXXX any other kinds of announcements we need to consider here?
|
||||||
e.g local master browsers... no. local master browsers do
|
e.g local master browsers... no. local master browsers do
|
||||||
local master announcements to their domain master.
|
local master announcements to their domain master. they even
|
||||||
|
use WINS lookup of the domain master if another wins server
|
||||||
|
is being used!
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -268,13 +256,10 @@ void announce_server(struct subnet_record *d, struct work_record *work,
|
|||||||
inet_ntoa(d->bcast_ip),work->work_group));
|
inet_ntoa(d->bcast_ip),work->work_group));
|
||||||
|
|
||||||
do_announce_host(ANN_LocalMasterAnnouncement,
|
do_announce_host(ANN_LocalMasterAnnouncement,
|
||||||
name , 0x00, d->myip,
|
name , 0x00, d->myip,
|
||||||
work->work_group, 0x1e, d->bcast_ip,
|
work->work_group, 0x1e, d->bcast_ip,
|
||||||
ttl*1000,
|
ttl*1000,
|
||||||
name, server_type,
|
name, server_type, comment);
|
||||||
HOST_MAJOR_VERSION, HOST_MINOR_VERSION,
|
|
||||||
HOST_BROWSE_VERSION, HOST_BROWSE_SIGNATURE,
|
|
||||||
comment);
|
|
||||||
|
|
||||||
DEBUG(3,("sending domain announce to %s for %s\n",
|
DEBUG(3,("sending domain announce to %s for %s\n",
|
||||||
inet_ntoa(d->bcast_ip),work->work_group));
|
inet_ntoa(d->bcast_ip),work->work_group));
|
||||||
@ -283,13 +268,11 @@ void announce_server(struct subnet_record *d, struct work_record *work,
|
|||||||
if (server_type != 0)
|
if (server_type != 0)
|
||||||
{
|
{
|
||||||
do_announce_host(ANN_DomainAnnouncement,
|
do_announce_host(ANN_DomainAnnouncement,
|
||||||
name , 0x00, d->myip,
|
name , 0x00, d->myip,
|
||||||
MSBROWSE, 0x01, d->bcast_ip,
|
MSBROWSE, 0x01, d->bcast_ip,
|
||||||
ttl*1000,
|
ttl*1000,
|
||||||
work->work_group, server_type ? domain_type : 0,
|
work->work_group, server_type ? domain_type : 0,
|
||||||
WG_MAJOR_VERSION, WG_MINOR_VERSION,
|
name);
|
||||||
WG_BROWSE_VERSION, WG_BROWSE_SIGNATURE,
|
|
||||||
name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -298,13 +281,10 @@ void announce_server(struct subnet_record *d, struct work_record *work,
|
|||||||
inet_ntoa(d->bcast_ip),work->work_group));
|
inet_ntoa(d->bcast_ip),work->work_group));
|
||||||
|
|
||||||
do_announce_host(ANN_HostAnnouncement,
|
do_announce_host(ANN_HostAnnouncement,
|
||||||
name , 0x00, d->myip,
|
name , 0x00, d->myip,
|
||||||
work->work_group, 0x1d, d->bcast_ip,
|
work->work_group, 0x1d, d->bcast_ip,
|
||||||
ttl*1000,
|
ttl*1000,
|
||||||
name, server_type,
|
name, server_type, comment);
|
||||||
HOST_MAJOR_VERSION, HOST_MINOR_VERSION,
|
|
||||||
HOST_BROWSE_VERSION, HOST_BROWSE_SIGNATURE,
|
|
||||||
comment);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,6 +297,11 @@ void announce_host(void)
|
|||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
pstring comment;
|
pstring comment;
|
||||||
|
char *my_name;
|
||||||
|
|
||||||
|
StrnCpy(comment, lp_serverstring(), 43);
|
||||||
|
|
||||||
|
my_name = *myname ? myname : "NoName";
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
@ -325,63 +310,62 @@ void announce_host(void)
|
|||||||
if (ip_equal(d->bcast_ip, ipgrp)) continue;
|
if (ip_equal(d->bcast_ip, ipgrp)) continue;
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
uint32 stype = work->ServerType;
|
uint32 stype = work->ServerType;
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
|
BOOL announce = False;
|
||||||
char *my_name = conf_browsing_alias(work->token);
|
|
||||||
char *my_comment = conf_browsing_alias_comment(work->token);
|
|
||||||
|
|
||||||
StrnCpy(comment, my_comment, 43);
|
|
||||||
|
|
||||||
/* must work on the code that does announcements at up to
|
/* must work on the code that does announcements at up to
|
||||||
30 seconds later if a master browser sends us a request
|
30 seconds later if a master browser sends us a request
|
||||||
announce.
|
announce.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (work->needannounce) {
|
if (work->needannounce) {
|
||||||
/* drop back to a max 3 minute announce - this is to prevent a
|
/* drop back to a max 3 minute announce - this is to prevent a
|
||||||
single lost packet from stuffing things up for too long */
|
single lost packet from stuffing things up for too long */
|
||||||
work->announce_interval = MIN(work->announce_interval,
|
work->announce_interval = MIN(work->announce_interval,
|
||||||
CHECK_TIME_MIN_HOST_ANNCE*60);
|
CHECK_TIME_MIN_HOST_ANNCE*60);
|
||||||
work->lastannounce_time = t - (work->announce_interval+1);
|
work->lastannounce_time = t - (work->announce_interval+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* announce every minute at first then progress to every 12 mins */
|
/* announce every minute at first then progress to every 12 mins */
|
||||||
if (work->lastannounce_time &&
|
if (work->lastannounce_time &&
|
||||||
(t - work->lastannounce_time) < work->announce_interval)
|
(t - work->lastannounce_time) < work->announce_interval)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (work->announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60)
|
if (work->announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60)
|
||||||
work->announce_interval += 60;
|
work->announce_interval += 60;
|
||||||
|
|
||||||
work->lastannounce_time = t;
|
work->lastannounce_time = t;
|
||||||
|
|
||||||
for (s = work->serverlist; s; s = s->next) {
|
for (s = work->serverlist; s; s = s->next) {
|
||||||
if (strequal(my_name, s->serv.name))
|
if (strequal(myname, s->serv.name)) {
|
||||||
{
|
announce = True;
|
||||||
announce_server(d,work,my_name,comment,
|
break;
|
||||||
work->announce_interval,stype);
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
if (announce) {
|
||||||
|
announce_server(d,work,my_name,comment,
|
||||||
if (work->needannounce)
|
work->announce_interval,stype);
|
||||||
{
|
}
|
||||||
work->needannounce = False;
|
|
||||||
break;
|
if (work->needannounce)
|
||||||
/* sorry: can't do too many announces. do some more later */
|
{
|
||||||
}
|
work->needannounce = False;
|
||||||
}
|
break;
|
||||||
|
/* sorry: can't do too many announces. do some more later */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
announce samba as a master to all other primary domain conrollers.
|
announce myself as a master to all other primary domain conrollers.
|
||||||
|
|
||||||
this actually gets done in search_and_sync_workgroups() via the
|
this actually gets done in search_and_sync_workgroups() via the
|
||||||
NAME_QUERY_DOM_SRV_CHK state, if there is a response from the
|
NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
|
||||||
name query initiated here. see response_name_query()
|
name query initiated here. see response_name_query()
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void announce_master(void)
|
void announce_master(void)
|
||||||
@ -393,108 +377,97 @@ void announce_master(void)
|
|||||||
|
|
||||||
if (!last) last = t;
|
if (!last) last = t;
|
||||||
if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
|
if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last = t;
|
last = t;
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
|
||||||
struct work_record *work;
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
|
||||||
{
|
{
|
||||||
if (AM_MASTER(work) || AM_DMBRSE(work))
|
struct work_record *work;
|
||||||
{
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
am_master = True;
|
{
|
||||||
}
|
if (AM_MASTER(work))
|
||||||
|
{
|
||||||
|
am_master = True;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!am_master) return; /* only proceed if we are a master browser */
|
if (!am_master) return; /* only proceed if we are a master browser */
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
|
||||||
struct work_record *work;
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct work_record *work;
|
||||||
for (s = work->serverlist; s; s = s->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (strequal(s->serv.name, conf_browsing_alias(work->token))) continue;
|
struct server_record *s;
|
||||||
|
for (s = work->serverlist; s; s = s->next)
|
||||||
/* all master browsers */
|
{
|
||||||
if (s->serv.type & SV_TYPE_DOMAIN_MASTER)
|
if (strequal(s->serv.name, myname)) continue;
|
||||||
{
|
|
||||||
/* check the existence of a domain master for this workgroup,
|
/* all DOMs (which should also be master browsers) */
|
||||||
and if one exists at the specified ip, sync with it and
|
if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
|
||||||
announce ourselves as a local master browser to it */
|
{
|
||||||
|
/* check the existence of a pdc for this workgroup, and if
|
||||||
/* exclude lp_domain_controller() from this check if it's
|
one exists at the specified ip, sync with it and announce
|
||||||
in our browse lists, because it's dealt with separately
|
ourselves as a master browser to it */
|
||||||
*/
|
|
||||||
if (!*lp_domain_controller() ||
|
if (!*lp_domain_controller() ||
|
||||||
!strequal(lp_domain_controller(), s->serv.name))
|
!strequal(lp_domain_controller(), s->serv.name))
|
||||||
{
|
{
|
||||||
if (lp_wins_support() || *lp_wins_server())
|
if (!lp_wins_support() && *lp_wins_server())
|
||||||
{
|
{
|
||||||
/* query the WINS server (that may include samba itself)
|
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
|
||||||
to find the browse master
|
NAME_QUERY_DOM_SRV_CHK,
|
||||||
*/
|
work->work_group,0x1b,0,0,0,NULL,NULL,
|
||||||
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
|
False, False, ipzero, ipzero);
|
||||||
NAME_QUERY_DOM_SRV_CHK,
|
}
|
||||||
work->token,
|
else
|
||||||
work->work_group,0x1b,0,0,0,0,NULL,NULL,
|
{
|
||||||
False, False, ipzero, ipzero);
|
struct subnet_record *d2;
|
||||||
}
|
for (d2 = subnetlist; d2; d2 = d2->next)
|
||||||
else
|
{
|
||||||
{
|
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
||||||
struct subnet_record *d2;
|
NAME_QUERY_DOM_SRV_CHK,
|
||||||
for (d2 = subnetlist; d2; d2 = d2->next)
|
work->work_group,0x1b,0,0,0,NULL,NULL,
|
||||||
{
|
True, False, d2->bcast_ip, d2->bcast_ip);
|
||||||
/* query by broadcast on every local interface
|
}
|
||||||
to find the browse master
|
}
|
||||||
*/
|
}
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
}
|
||||||
NAME_QUERY_DOM_SRV_CHK,
|
}
|
||||||
work->token, work->work_group,0x1b,
|
|
||||||
0,0,0,0,NULL,NULL,
|
/* now do primary domain controller - the one that's not
|
||||||
True, False, d2->bcast_ip, d2->bcast_ip);
|
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())
|
||||||
/* now do primary domain controller - the one that's not
|
{
|
||||||
necessarily in our browse lists, although it ought to be
|
struct in_addr ip;
|
||||||
this pdc is the one that we get TOLD about through smb.conf.
|
BOOL bcast = False;
|
||||||
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
|
ip = *interpret_addr2(lp_domain_controller());
|
||||||
in the code above) */
|
|
||||||
|
if (zero_ip(ip)) {
|
||||||
if (*lp_domain_controller())
|
ip = d->bcast_ip;
|
||||||
{
|
bcast = True;
|
||||||
struct in_addr ip;
|
}
|
||||||
|
|
||||||
ip = *interpret_addr2(lp_domain_controller());
|
DEBUG(2, ("Searching for DOM %s at %s\n",
|
||||||
|
lp_domain_controller(), inet_ntoa(ip)));
|
||||||
/* 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
|
/* check the existence of a pdc for this workgroup, and if
|
||||||
samba's local subnets
|
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,
|
||||||
DEBUG(2, ("Searching for DOM %s at %s\n",
|
work->work_group,0x1b,0,0,0,NULL,NULL,
|
||||||
lp_domain_controller(), inet_ntoa(ip)));
|
bcast, False, ip, 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,0,NULL,NULL,
|
|
||||||
False, False, ip, ip);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -512,7 +485,6 @@ void announce_remote(void)
|
|||||||
pstring s2;
|
pstring s2;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
char *comment,*workgroup;
|
char *comment,*workgroup;
|
||||||
int token;
|
|
||||||
int stype = DFLT_SERVER_TYPE;
|
int stype = DFLT_SERVER_TYPE;
|
||||||
|
|
||||||
if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
|
if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
|
||||||
@ -523,16 +495,13 @@ void announce_remote(void)
|
|||||||
s = lp_remote_announce();
|
s = lp_remote_announce();
|
||||||
if (!*s) return;
|
if (!*s) return;
|
||||||
|
|
||||||
comment = lp_serverstring(); /* default comment */
|
comment = lp_serverstring();
|
||||||
workgroup = lp_workgroup(); /* default workgroup name */
|
workgroup = lp_workgroup();
|
||||||
|
|
||||||
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
|
/* the entries are of the form a.b.c.d/WORKGROUP with
|
||||||
WORKGROUP being optional */
|
WORKGROUP being optional */
|
||||||
char *wgroup;
|
char *wgroup;
|
||||||
char *my_name;
|
|
||||||
extern pstring myname; /* samba's default NetBIOS name */
|
|
||||||
|
|
||||||
wgroup = strchr(s2,'/');
|
wgroup = strchr(s2,'/');
|
||||||
if (wgroup) *wgroup++ = 0;
|
if (wgroup) *wgroup++ = 0;
|
||||||
@ -541,17 +510,10 @@ void announce_remote(void)
|
|||||||
|
|
||||||
addr = *interpret_addr2(s2);
|
addr = *interpret_addr2(s2);
|
||||||
|
|
||||||
token = conf_workgroup_name_to_token(wgroup, myname);
|
do_announce_host(ANN_HostAnnouncement,myname,0x20,*iface_ip(addr),
|
||||||
my_name = conf_browsing_alias(token);
|
wgroup,0x1e,addr,
|
||||||
my_name = my_name ? my_name : myname;
|
REMOTE_ANNOUNCE_INTERVAL,
|
||||||
|
myname,stype,comment);
|
||||||
do_announce_host(ANN_HostAnnouncement,
|
|
||||||
my_name, 0x20, *iface_ip(addr),
|
|
||||||
wgroup , 0x1e, addr,
|
|
||||||
REMOTE_ANNOUNCE_INTERVAL,
|
|
||||||
my_name,stype,
|
|
||||||
HOST_MAJOR_VERSION, HOST_MINOR_VERSION,
|
|
||||||
HOST_BROWSE_VERSION, HOST_BROWSE_SIGNATURE,
|
|
||||||
comment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
14 jan 96: lkcl@pires.co.uk
|
14 jan 96: lkcl@pires.co.uk
|
||||||
added multiple workgroup domain master support
|
added multiple workgroup domain master support
|
||||||
|
|
||||||
30 July 96: David.Chappell@mail.trincoll.edu
|
|
||||||
Expanded multiple workgroup domain master browser support.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
@ -74,21 +71,21 @@ void expire_browse_cache(time_t t)
|
|||||||
for (b = browserlist; b; b = nextb)
|
for (b = browserlist; b; b = nextb)
|
||||||
{
|
{
|
||||||
if (b->synced && b->sync_time < t)
|
if (b->synced && b->sync_time < t)
|
||||||
{
|
{
|
||||||
DEBUG(3,("Removing dead cached browser %s\n",b->name));
|
DEBUG(3,("Removing dead cached browser %s\n",b->name));
|
||||||
nextb = b->next;
|
nextb = b->next;
|
||||||
|
|
||||||
if (b->prev) b->prev->next = b->next;
|
if (b->prev) b->prev->next = b->next;
|
||||||
if (b->next) b->next->prev = b->prev;
|
if (b->next) b->next->prev = b->prev;
|
||||||
|
|
||||||
if (browserlist == b) browserlist = b->next;
|
if (browserlist == b) browserlist = b->next;
|
||||||
|
|
||||||
free(b);
|
free(b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextb = b->next;
|
nextb = b->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +94,7 @@ void expire_browse_cache(time_t t)
|
|||||||
add a browser entry
|
add a browser entry
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
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;
|
BOOL newentry=False;
|
||||||
|
|
||||||
@ -112,9 +109,9 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
|||||||
if (b && b->synced)
|
if (b && b->synced)
|
||||||
{
|
{
|
||||||
/* entries get left in the cache for a while. this stops sync'ing too
|
/* 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",
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,12 +146,12 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
|||||||
add_browse_cache(b);
|
add_browse_cache(b);
|
||||||
|
|
||||||
DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
|
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
|
else
|
||||||
{
|
{
|
||||||
DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
|
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);
|
return(b);
|
||||||
@ -169,23 +166,23 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
|
|||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
|
||||||
if( (d = find_subnet(b->ip)) == (struct subnet_record *)NULL ) return;
|
if (!(d = find_subnet(b->ip))) return;
|
||||||
|
|
||||||
if (!(work = find_workgroupstruct(d, b->group, False))) return;
|
if (!(work = find_workgroupstruct(d, b->group, False))) return;
|
||||||
|
|
||||||
/* only sync if we are the master */
|
/* only sync if we are the master */
|
||||||
if (AM_MASTER(work)) {
|
if (AM_MASTER(work)) {
|
||||||
|
|
||||||
/* first check whether the group we intend to sync with exists. if it
|
/* first check whether the group we intend to sync with exists. if it
|
||||||
doesn't, the server must have died. o dear. */
|
doesn't, the server must have died. o dear. */
|
||||||
|
|
||||||
/* see response_netbios_packet() or expire_netbios_response_entries() */
|
/* see response_netbios_packet() or expire_netbios_response_entries() */
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
||||||
b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
|
b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
|
||||||
work->token,b->group,0x20,0,0,0,0,NULL,NULL,
|
b->group,0x20,0,0,0,NULL,NULL,
|
||||||
False,False,b->ip,b->ip);
|
False,False,b->ip,b->ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->synced = True;
|
b->synced = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,10 @@ struct smbbrowse
|
|||||||
char work_name[16]; /* workgroup name */
|
char work_name[16]; /* workgroup name */
|
||||||
char browsing_alias[16]; /* alias for our role in this workgroup */
|
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 */
|
struct server_identity *my_names; /* a list of server name we should appear here as */
|
||||||
BOOL should_workgroup_member; /* should we be a member of this workgroup? */
|
BOOL should_workgroup_member; /* should we try to become a member of this workgroup? */
|
||||||
BOOL should_local_master; /* should we be a master browser? */
|
BOOL should_local_master; /* should we try to become a master browser? */
|
||||||
BOOL should_preferred_master; /* should we initiate attempts to become a master browser? */
|
BOOL should_domain_master; /* should we try to become the domain master browser? */
|
||||||
BOOL should_domain_master; /* should we be the domain master browser? */
|
} ;
|
||||||
BOOL should_domain_logon; /* should we be the domain logon? */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The whole list */
|
/* The whole list */
|
||||||
static struct smbbrowse *smbbrowse_workgroups = (struct smbbrowse*)NULL;
|
static struct smbbrowse *smbbrowse_workgroups = (struct smbbrowse*)NULL;
|
||||||
@ -89,7 +87,7 @@ static struct smbbrowse *new_workgroup(struct smbbrowse *model,
|
|||||||
{
|
{
|
||||||
struct smbbrowse *new;
|
struct smbbrowse *new;
|
||||||
|
|
||||||
if ( ! (array_size > nexttoken) )
|
if( ! (array_size > nexttoken) )
|
||||||
{
|
{
|
||||||
array_size += 10;
|
array_size += 10;
|
||||||
smbbrowse_workgroups = (struct smbbrowse*)realloc(smbbrowse_workgroups,
|
smbbrowse_workgroups = (struct smbbrowse*)realloc(smbbrowse_workgroups,
|
||||||
@ -98,7 +96,7 @@ static struct smbbrowse *new_workgroup(struct smbbrowse *model,
|
|||||||
|
|
||||||
new = &smbbrowse_workgroups[nexttoken];
|
new = &smbbrowse_workgroups[nexttoken];
|
||||||
|
|
||||||
if (model != (struct smbbrowse *)NULL )
|
if(model != (struct smbbrowse *)NULL )
|
||||||
memcpy(new, model, sizeof(struct smbbrowse));
|
memcpy(new, model, sizeof(struct smbbrowse));
|
||||||
else
|
else
|
||||||
memset(new, 0, sizeof(struct smbbrowse));
|
memset(new, 0, sizeof(struct smbbrowse));
|
||||||
@ -129,22 +127,22 @@ int conf_workgroup_name_to_token(char *workgroup_name,char *default_name)
|
|||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
/* Look for an existing instance. */
|
/* Look for an existing instance. */
|
||||||
for (idx=0; idx < nexttoken; idx++)
|
for(idx=0; idx < nexttoken; idx++)
|
||||||
{
|
{
|
||||||
if (strequal(workgroup_name, smbbrowse_workgroups[idx].work_name))
|
if(strequal(workgroup_name, smbbrowse_workgroups[idx].work_name))
|
||||||
{
|
{
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if creating new ones in admissable. */
|
/* See if creating new ones in admissable. */
|
||||||
for (idx=0; idx < nexttoken; idx++)
|
for(idx=0; idx < nexttoken; idx++)
|
||||||
{
|
{
|
||||||
if (strequal("*", smbbrowse_workgroups[idx].work_name))
|
if(strequal("*", smbbrowse_workgroups[idx].work_name))
|
||||||
{
|
{
|
||||||
struct smbbrowse *w = new_workgroup(&smbbrowse_workgroups[idx],
|
struct smbbrowse *w = new_workgroup(&smbbrowse_workgroups[idx],
|
||||||
workgroup_name, default_name);
|
workgroup_name, default_name);
|
||||||
w->should_workgroup_member = True;
|
w->should_workgroup_member = False;
|
||||||
|
|
||||||
return (nexttoken - 1);
|
return (nexttoken - 1);
|
||||||
}
|
}
|
||||||
@ -160,7 +158,7 @@ int conf_workgroup_name_to_token(char *workgroup_name,char *default_name)
|
|||||||
*/
|
*/
|
||||||
static int range_check(int token)
|
static int range_check(int token)
|
||||||
{
|
{
|
||||||
if (token < 0 || token >= nexttoken)
|
if(token < 0 || token >= nexttoken)
|
||||||
{
|
{
|
||||||
DEBUG(0, ("range_check(): failed\n"));
|
DEBUG(0, ("range_check(): failed\n"));
|
||||||
return True;
|
return True;
|
||||||
@ -174,25 +172,12 @@ static int range_check(int token)
|
|||||||
*/
|
*/
|
||||||
char *conf_workgroup_name(int token)
|
char *conf_workgroup_name(int token)
|
||||||
{
|
{
|
||||||
if (range_check(token))
|
if(range_check(token))
|
||||||
return (char*)NULL;
|
return (char*)NULL;
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].work_name;
|
return smbbrowse_workgroups[token].work_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Given a token, return True if we should try
|
|
||||||
** to become a master browser.
|
|
||||||
*/
|
|
||||||
int conf_should_preferred_master(int token)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (range_check(token))
|
|
||||||
return False;
|
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].should_preferred_master;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given a token, return True if we should try
|
** Given a token, return True if we should try
|
||||||
** to become a master browser.
|
** to become a master browser.
|
||||||
@ -200,7 +185,7 @@ int conf_should_preferred_master(int token)
|
|||||||
int conf_should_workgroup_member(int token)
|
int conf_should_workgroup_member(int token)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (range_check(token))
|
if(range_check(token))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].should_workgroup_member;
|
return smbbrowse_workgroups[token].should_workgroup_member;
|
||||||
@ -211,22 +196,12 @@ int conf_should_workgroup_member(int token)
|
|||||||
** to become a master browser.
|
** to become a master browser.
|
||||||
*/
|
*/
|
||||||
int conf_should_local_master(int token)
|
int conf_should_local_master(int token)
|
||||||
{
|
{
|
||||||
if (range_check(token)) return False;
|
if(range_check(token))
|
||||||
|
return False;
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].should_local_master;
|
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_logon(int token)
|
|
||||||
{
|
|
||||||
if (range_check(token)) return False;
|
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].should_domain_logon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given a token, return True if we should try
|
** Given a token, return True if we should try
|
||||||
@ -234,7 +209,7 @@ int conf_should_domain_logon(int token)
|
|||||||
*/
|
*/
|
||||||
int conf_should_domain_master(int token)
|
int conf_should_domain_master(int token)
|
||||||
{
|
{
|
||||||
if (range_check(token))
|
if(range_check(token))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].should_domain_master;
|
return smbbrowse_workgroups[token].should_domain_master;
|
||||||
@ -244,12 +219,12 @@ int conf_should_domain_master(int token)
|
|||||||
** Given a token, return the name.
|
** Given a token, return the name.
|
||||||
*/
|
*/
|
||||||
char *conf_browsing_alias(int token)
|
char *conf_browsing_alias(int token)
|
||||||
{
|
{
|
||||||
if (range_check(token))
|
if(range_check(token))
|
||||||
return (char*)NULL;
|
return (char*)NULL;
|
||||||
|
|
||||||
return smbbrowse_workgroups[token].browsing_alias;
|
return smbbrowse_workgroups[token].browsing_alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the server comment which should be used with the
|
** Return the server comment which should be used with the
|
||||||
@ -257,11 +232,11 @@ char *conf_browsing_alias(int token)
|
|||||||
*/
|
*/
|
||||||
char *conf_browsing_alias_comment(int token)
|
char *conf_browsing_alias_comment(int token)
|
||||||
{
|
{
|
||||||
if (range_check(token))
|
if(range_check(token))
|
||||||
return (char*) NULL;
|
return (char*) NULL;
|
||||||
|
|
||||||
return lp_server_comment();
|
return "Browser";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given an alias name for this server, return the name of the workgroup
|
** Given an alias name for this server, return the name of the workgroup
|
||||||
@ -273,11 +248,11 @@ char *conf_alias_to_workgroup(char *alias)
|
|||||||
|
|
||||||
DEBUG(4,("alias_to_workgroup: %s", alias));
|
DEBUG(4,("alias_to_workgroup: %s", alias));
|
||||||
|
|
||||||
for (x=0; x < nexttoken; x++)
|
for(x=0; x < nexttoken; x++)
|
||||||
{
|
{
|
||||||
DEBUG(4,("%s ", smbbrowse_workgroups[x].browsing_alias));
|
DEBUG(4,("%s ", smbbrowse_workgroups[x].browsing_alias));
|
||||||
|
|
||||||
if (strequal(alias, smbbrowse_workgroups[x].browsing_alias))
|
if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
|
||||||
{
|
{
|
||||||
DEBUG(4,("OK\n"));
|
DEBUG(4,("OK\n"));
|
||||||
return smbbrowse_workgroups[x].work_name;
|
return smbbrowse_workgroups[x].work_name;
|
||||||
@ -295,9 +270,9 @@ int conf_alias_to_token(char *alias)
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
for (x=0; x < nexttoken; x++)
|
for(x=0; x < nexttoken; x++)
|
||||||
{
|
{
|
||||||
if (strequal(alias, smbbrowse_workgroups[x].browsing_alias))
|
if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@ -315,19 +290,15 @@ static void default_smbbrowse_conf(char *default_name)
|
|||||||
|
|
||||||
/* The workgroup specified in smb.conf */
|
/* The workgroup specified in smb.conf */
|
||||||
w = new_workgroup((struct smbbrowse *)NULL, lp_workgroup(), default_name);
|
w = new_workgroup((struct smbbrowse *)NULL, lp_workgroup(), default_name);
|
||||||
w->should_local_master = lp_local_master();
|
w->should_local_master = lp_preferred_master();
|
||||||
w->should_domain_master = lp_domain_master();
|
w->should_domain_master = lp_domain_master();
|
||||||
w->should_domain_logon = lp_domain_logons();
|
|
||||||
w->should_workgroup_member = True;
|
w->should_workgroup_member = True;
|
||||||
|
|
||||||
/* default action: allow any new workgroup to be added. this is
|
/* default action: allow any new workgroup to be added */
|
||||||
_not_ the same as the old 1.9.14-1.9.15 definition of "*"
|
|
||||||
*/
|
|
||||||
w = new_workgroup((struct smbbrowse *)NULL, "*", default_name);
|
w = new_workgroup((struct smbbrowse *)NULL, "*", default_name);
|
||||||
w->should_local_master = False;
|
w->should_local_master = False;
|
||||||
w->should_domain_master = False;
|
w->should_domain_master = False;
|
||||||
w->should_workgroup_member = False;
|
w->should_workgroup_member = False;
|
||||||
w->should_domain_logon = False;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -360,10 +331,8 @@ void read_smbbrowse_conf(char *default_name)
|
|||||||
if (count <= 0) continue;
|
if (count <= 0) continue;
|
||||||
|
|
||||||
w = new_workgroup((struct smbbrowse *)NULL, work_name, default_name);
|
w = new_workgroup((struct smbbrowse *)NULL, work_name, default_name);
|
||||||
w->should_local_master = lp_local_master();
|
w->should_local_master = lp_local_master();
|
||||||
w->should_domain_master = lp_domain_master();
|
w->should_domain_master = lp_domain_master();
|
||||||
w->should_preferred_master = lp_preferred_master();
|
|
||||||
w->should_domain_logon = lp_domain_logons();
|
|
||||||
w->should_workgroup_member = True;
|
w->should_workgroup_member = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,6 @@
|
|||||||
|
|
||||||
04 jul 96: lkcl@pires.co.uk
|
04 jul 96: lkcl@pires.co.uk
|
||||||
created module namedbname containing name database functions
|
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"
|
#include "includes.h"
|
||||||
@ -47,16 +43,6 @@ extern struct subnet_record *subnetlist;
|
|||||||
|
|
||||||
uint16 nb_type = 0; /* samba's NetBIOS name type */
|
uint16 nb_type = 0; /* samba's NetBIOS name type */
|
||||||
|
|
||||||
static char *source_description[] =
|
|
||||||
{
|
|
||||||
"STATUS_QUERY",
|
|
||||||
"LMHOSTS",
|
|
||||||
"REG",
|
|
||||||
"SELF",
|
|
||||||
"DNS",
|
|
||||||
"DNSFAIL"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
samba's NetBIOS name type
|
samba's NetBIOS name type
|
||||||
@ -66,14 +52,14 @@ static char *source_description[] =
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void set_samba_nb_type(void)
|
void set_samba_nb_type(void)
|
||||||
{
|
{
|
||||||
if (lp_wins_support() || (*lp_wins_server()))
|
if (lp_wins_support() || (*lp_wins_server()))
|
||||||
{
|
{
|
||||||
nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
|
nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nb_type = NB_BFLAG; /* samba is broadcast-only node type */
|
nb_type = NB_BFLAG; /* samba is broadcast-only node type */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,7 +69,7 @@ void set_samba_nb_type(void)
|
|||||||
BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
|
BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
|
||||||
{
|
{
|
||||||
return n1->name_type == n2->name_type &&
|
return n1->name_type == n2->name_type &&
|
||||||
strequal(n1->name ,n2->name ) &&
|
strequal(n1->name ,n2->name ) &&
|
||||||
strequal(n1->scope,n2->scope);
|
strequal(n1->scope,n2->scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,22 +140,22 @@ void remove_name(struct subnet_record *d, struct name_record *n)
|
|||||||
find a name in a namelist.
|
find a name in a namelist.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
struct name_record *find_name(struct name_record *n,
|
struct name_record *find_name(struct name_record *n,
|
||||||
struct nmb_name *name,
|
struct nmb_name *name,
|
||||||
int search)
|
int search)
|
||||||
{
|
{
|
||||||
struct name_record *ret;
|
struct name_record *ret;
|
||||||
|
|
||||||
for (ret = n; ret; ret = ret->next)
|
for (ret = n; ret; ret = ret->next)
|
||||||
{
|
{
|
||||||
if (name_equal(&ret->name,name))
|
if (name_equal(&ret->name,name))
|
||||||
{
|
{
|
||||||
/* self search: self names only */
|
/* self search: self names only */
|
||||||
if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
|
if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,31 +168,29 @@ struct name_record *find_name(struct name_record *n,
|
|||||||
FIND_WINS - look for names in the WINS record
|
FIND_WINS - look for names in the WINS record
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
struct name_record *find_name_search(struct subnet_record **d,
|
struct name_record *find_name_search(struct subnet_record **d,
|
||||||
struct nmb_name *name,
|
struct nmb_name *name,
|
||||||
int search, struct in_addr ip)
|
int search, struct in_addr ip)
|
||||||
{
|
{
|
||||||
if (d == NULL) return NULL; /* bad error! */
|
if (d == NULL) return NULL; /* bad error! */
|
||||||
|
|
||||||
if (search & FIND_LOCAL)
|
if (search & FIND_LOCAL) {
|
||||||
{
|
if (*d != NULL) {
|
||||||
if (*d != NULL)
|
struct name_record *n = find_name((*d)->namelist, name, search);
|
||||||
{
|
DEBUG(4,("find_name on local: %s %s search %x\n",
|
||||||
struct name_record *n = find_name((*d)->namelist, name, search);
|
namestr(name),inet_ntoa(ip), search));
|
||||||
DEBUG(4,("find_name on local: %s %s search %x\n",
|
if (n) return n;
|
||||||
namestr(name),inet_ntoa(ip), search));
|
}
|
||||||
if (n) return n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((search & FIND_WINS) != FIND_WINS) return NULL;
|
if (!(search & FIND_WINS)) return NULL;
|
||||||
|
|
||||||
/* find WINS subnet record. */
|
/* find WINS subnet record. */
|
||||||
*d = find_subnet(ipgrp);
|
*d = find_subnet(ipgrp);
|
||||||
|
|
||||||
if (*d == NULL) return NULL;
|
if (*d == NULL) return NULL;
|
||||||
|
|
||||||
DEBUG(4,("find_name on WINS: %s %s search %x\n",
|
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);
|
return find_name((*d)->namelist, name, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,18 +228,20 @@ void dump_names(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG(3,("%-15s ", inet_ntoa(d->bcast_ip)));
|
DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
|
||||||
DEBUG(3,("%-19s TTL=%7ld %s ",
|
DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
|
||||||
namestr(&n->name),
|
DEBUG(3,("%-19s TTL=%ld ",
|
||||||
n->death_time?n->death_time-t:0, source_description[n->source]));
|
namestr(&n->name),
|
||||||
|
n->death_time?n->death_time-t:0));
|
||||||
|
|
||||||
for (i = 0; i < n->num_ips; i++)
|
for (i = 0; i < n->num_ips; i++)
|
||||||
{
|
{
|
||||||
DEBUG(3,("%-15s NB=%2x ",
|
DEBUG(3,("%15s NB=%2x source=%d",
|
||||||
inet_ntoa(n->ip_flgs[i].ip),
|
inet_ntoa(n->ip_flgs[i].ip),
|
||||||
(unsigned char)n->ip_flgs[i].nb_flags));
|
n->ip_flgs[i].nb_flags,n->source));
|
||||||
|
|
||||||
}
|
}
|
||||||
DEBUG(3,("\n"));
|
DEBUG(3,("\n"));
|
||||||
|
|
||||||
if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
|
if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
|
||||||
{
|
{
|
||||||
@ -263,16 +249,16 @@ void dump_names(void)
|
|||||||
anything other than as a hexadecimal number :-) */
|
anything other than as a hexadecimal number :-) */
|
||||||
|
|
||||||
fprintf(f, "%s#%02x %ld ",
|
fprintf(f, "%s#%02x %ld ",
|
||||||
n->name.name,n->name.name_type, /* XXXX ignore scope for now */
|
n->name.name,n->name.name_type, /* XXXX ignore scope for now */
|
||||||
n->death_time);
|
n->death_time);
|
||||||
|
|
||||||
for (i = 0; i < n->num_ips; i++)
|
for (i = 0; i < n->num_ips; i++)
|
||||||
{
|
{
|
||||||
fprintf(f, "%s %2x ",
|
fprintf(f, "%s %2x ",
|
||||||
inet_ntoa(n->ip_flgs[i].ip),
|
inet_ntoa(n->ip_flgs[i].ip),
|
||||||
(unsigned char)n->ip_flgs[i].nb_flags);
|
n->ip_flgs[i].nb_flags);
|
||||||
}
|
}
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -321,12 +307,12 @@ void load_netbios_names(void)
|
|||||||
int type = 0;
|
int type = 0;
|
||||||
unsigned int nb_flags;
|
unsigned int nb_flags;
|
||||||
time_t ttd;
|
time_t ttd;
|
||||||
struct in_addr ipaddr;
|
struct in_addr ipaddr;
|
||||||
|
|
||||||
enum name_source source;
|
enum name_source source;
|
||||||
|
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
@ -334,20 +320,20 @@ void load_netbios_names(void)
|
|||||||
|
|
||||||
if (*line == '#') continue;
|
if (*line == '#') continue;
|
||||||
|
|
||||||
ptr = line;
|
ptr = line;
|
||||||
|
|
||||||
if (next_token(&ptr,name_str ,NULL)) ++count;
|
if (next_token(&ptr,name_str ,NULL)) ++count;
|
||||||
if (next_token(&ptr,ttd_str ,NULL)) ++count;
|
if (next_token(&ptr,ttd_str ,NULL)) ++count;
|
||||||
if (next_token(&ptr,ip_str ,NULL)) ++count;
|
if (next_token(&ptr,ip_str ,NULL)) ++count;
|
||||||
if (next_token(&ptr,nb_flags_str,NULL)) ++count;
|
if (next_token(&ptr,nb_flags_str,NULL)) ++count;
|
||||||
|
|
||||||
if (count <= 0) continue;
|
if (count <= 0) continue;
|
||||||
|
|
||||||
if (count != 4) {
|
if (count != 4) {
|
||||||
DEBUG(0,("Ill formed wins line"));
|
DEBUG(0,("Ill formed wins line"));
|
||||||
DEBUG(0,("[%s]: name#type abs_time ip nb_flags\n",line));
|
DEBUG(0,("[%s]: name#type abs_time ip nb_flags\n",line));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* netbios name. # divides the name from the type (hex): netbios#xx */
|
/* netbios name. # divides the name from the type (hex): netbios#xx */
|
||||||
strcpy(name,name_str);
|
strcpy(name,name_str);
|
||||||
@ -355,15 +341,15 @@ void load_netbios_names(void)
|
|||||||
p = strchr(name,'#');
|
p = strchr(name,'#');
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
sscanf(p+1,"%x",&type);
|
sscanf(p+1,"%x",&type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode the netbios flags (hex) and the time-to-die (seconds) */
|
/* decode the netbios flags (hex) and the time-to-die (seconds) */
|
||||||
sscanf(nb_flags_str,"%x",&nb_flags);
|
sscanf(nb_flags_str,"%x",&nb_flags);
|
||||||
sscanf(ttd_str,"%ld",&ttd);
|
sscanf(ttd_str,"%ld",&ttd);
|
||||||
|
|
||||||
ipaddr = *interpret_addr2(ip_str);
|
ipaddr = *interpret_addr2(ip_str);
|
||||||
|
|
||||||
if (ip_equal(ipaddr,ipzero)) {
|
if (ip_equal(ipaddr,ipzero)) {
|
||||||
source = SELF;
|
source = SELF;
|
||||||
@ -374,7 +360,7 @@ void load_netbios_names(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, ("add WINS line: %s#%02x %ld %s %2x\n",
|
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 */
|
/* add all entries that have 60 seconds or more to live */
|
||||||
if (ttd - 60 > time(NULL) || ttd == 0)
|
if (ttd - 60 > time(NULL) || ttd == 0)
|
||||||
@ -394,8 +380,8 @@ void load_netbios_names(void)
|
|||||||
remove an entry from the name list
|
remove an entry from the name list
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void remove_netbios_name(struct subnet_record *d,
|
void remove_netbios_name(struct subnet_record *d,
|
||||||
char *name,int type, enum name_source source,
|
char *name,int type, enum name_source source,
|
||||||
struct in_addr ip)
|
struct in_addr ip)
|
||||||
{
|
{
|
||||||
struct nmb_name nn;
|
struct nmb_name nn;
|
||||||
struct name_record *n;
|
struct name_record *n;
|
||||||
@ -419,22 +405,14 @@ void remove_netbios_name(struct subnet_record *d,
|
|||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct name_record *add_netbios_entry(struct subnet_record *d,
|
struct name_record *add_netbios_entry(struct subnet_record *d,
|
||||||
char *name, int type, int nb_flags,
|
char *name, int type, int nb_flags,
|
||||||
int ttl, enum name_source source, struct in_addr ip,
|
int ttl, enum name_source source, struct in_addr ip,
|
||||||
BOOL new_only,BOOL wins)
|
BOOL new_only,BOOL wins)
|
||||||
{
|
{
|
||||||
struct name_record *n;
|
struct name_record *n;
|
||||||
struct name_record *n2=NULL;
|
struct name_record *n2=NULL;
|
||||||
int search = 0;
|
int search = 0;
|
||||||
BOOL self;
|
BOOL self = source == SELF;
|
||||||
|
|
||||||
if (iface_ip(ip))
|
|
||||||
{
|
|
||||||
source = SELF;
|
|
||||||
putip(&ip, &ipzero);
|
|
||||||
}
|
|
||||||
|
|
||||||
self = source == SELF;
|
|
||||||
|
|
||||||
/* add the name to the WINS list if the name comes from a directed query */
|
/* add the name to the WINS list if the name comes from a directed query */
|
||||||
search |= wins ? FIND_WINS : FIND_LOCAL;
|
search |= wins ? FIND_WINS : FIND_LOCAL;
|
||||||
@ -487,57 +465,46 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
|
|||||||
if (!n2) add_name(d,n);
|
if (!n2) add_name(d,n);
|
||||||
|
|
||||||
DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\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);
|
return(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
expires or refreshes old names in the namelist
|
expires old names in the namelist
|
||||||
|
|
||||||
if the name is a samba SELF name, it must be refreshed rather than
|
|
||||||
removed.
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void check_expire_names(time_t t)
|
void expire_names(time_t t)
|
||||||
{
|
{
|
||||||
struct name_record *n;
|
struct name_record *n;
|
||||||
struct name_record *next;
|
struct name_record *next;
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
|
|
||||||
/* expire old names */
|
/* expire old names */
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
for (n = d->namelist; n; n = next)
|
for (n = d->namelist; n; n = next)
|
||||||
{
|
{
|
||||||
next = n->next;
|
next = n->next;
|
||||||
|
if (n->death_time && n->death_time < t)
|
||||||
if (n->death_time && n->death_time < t)
|
{
|
||||||
{
|
if (n->source == SELF) {
|
||||||
if (n->source == SELF)
|
DEBUG(3,("not expiring SELF name %s\n", namestr(&n->name)));
|
||||||
{
|
n->death_time += 300;
|
||||||
/* refresh the samba name. if this refresh fails
|
continue;
|
||||||
for any reason, it will be deleted.
|
}
|
||||||
*/
|
DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
|
||||||
DEBUG(3,("Refreshing SELF name %s\n", namestr(&n->name)));
|
|
||||||
add_my_name_entry(d, -1,
|
if (n->prev) n->prev->next = n->next;
|
||||||
n->name.name, n->name.name_type,
|
if (n->next) n->next->prev = n->prev;
|
||||||
n->ip_flgs[0].nb_flags);
|
|
||||||
continue;
|
if (d->namelist == n) d->namelist = n->next;
|
||||||
}
|
|
||||||
|
free(n->ip_flgs);
|
||||||
DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
|
free(n);
|
||||||
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -545,8 +512,8 @@ void check_expire_names(time_t t)
|
|||||||
reply to a name query
|
reply to a name query
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct name_record *search_for_name(struct subnet_record **d,
|
struct name_record *search_for_name(struct subnet_record **d,
|
||||||
struct nmb_name *question,
|
struct nmb_name *question,
|
||||||
struct in_addr ip, int Time, int search)
|
struct in_addr ip, int Time, int search)
|
||||||
{
|
{
|
||||||
int name_type = question->name_type;
|
int name_type = question->name_type;
|
||||||
char *qname = question->name;
|
char *qname = question->name;
|
||||||
@ -571,10 +538,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 */
|
/* only do DNS lookups if the query is for type 0x20 or type 0x0 */
|
||||||
if (!dns_type && name_type != 0x1b)
|
if (!dns_type && name_type != 0x1b)
|
||||||
{
|
{
|
||||||
DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
|
DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look it up with DNS */
|
/* look it up with DNS */
|
||||||
a = interpret_addr(qname);
|
a = interpret_addr(qname);
|
||||||
@ -582,18 +549,18 @@ struct name_record *search_for_name(struct subnet_record **d,
|
|||||||
putip((char *)&dns_ip,(char *)&a);
|
putip((char *)&dns_ip,(char *)&a);
|
||||||
|
|
||||||
if (!a)
|
if (!a)
|
||||||
{
|
{
|
||||||
/* no luck with DNS. We could possibly recurse here XXXX */
|
/* no luck with DNS. We could possibly recurse here XXXX */
|
||||||
DEBUG(3,("no recursion.\n"));
|
DEBUG(3,("no recursion.\n"));
|
||||||
/* add the fail to our WINS cache of names. give it 1 hour in the cache */
|
/* 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,
|
add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
|
||||||
True, True);
|
True, True);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add it to our WINS cache of names. give it 2 hours in the cache */
|
/* 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,
|
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! */
|
/* failed to add it? yikes! */
|
||||||
if (!n) return NULL;
|
if (!n) return NULL;
|
||||||
|
@ -92,9 +92,8 @@ void remove_response_record(struct subnet_record *d,
|
|||||||
create a name query response record
|
create a name query response record
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
struct response_record *make_response_queue_record(enum state_type state,
|
struct response_record *make_response_queue_record(enum state_type state,
|
||||||
int id,uint16 fd, int quest_type,
|
int id,uint16 fd,
|
||||||
int token, char *name,int type,
|
int quest_type, char *name,int type, int nb_flags, time_t ttl,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
|
||||||
int server_type, char *my_name, char *my_comment,
|
int server_type, char *my_name, char *my_comment,
|
||||||
BOOL bcast,BOOL recurse,
|
BOOL bcast,BOOL recurse,
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip)
|
struct in_addr send_ip, struct in_addr reply_to_ip)
|
||||||
@ -110,17 +109,14 @@ struct response_record *make_response_queue_record(enum state_type state,
|
|||||||
n->state = state;
|
n->state = state;
|
||||||
n->fd = fd;
|
n->fd = fd;
|
||||||
n->quest_type = quest_type;
|
n->quest_type = quest_type;
|
||||||
|
|
||||||
n->token = token;
|
|
||||||
make_nmb_name(&n->name, name, type, scope);
|
make_nmb_name(&n->name, name, type, scope);
|
||||||
|
n->nb_flags = nb_flags;
|
||||||
n->ttl = ttl;
|
n->ttl = ttl;
|
||||||
n->source = source;
|
|
||||||
n->server_type = server_type;
|
n->server_type = server_type;
|
||||||
n->bcast = bcast;
|
n->bcast = bcast;
|
||||||
n->recurse = recurse;
|
n->recurse = recurse;
|
||||||
n->reply.nb_flags = nb_flags;
|
|
||||||
n->reply.ip = reply_to_ip;
|
|
||||||
n->send_ip = send_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_name , n->my_name , sizeof(n->my_name )-1);
|
||||||
StrnCpy(my_comment, n->my_comment, sizeof(n->my_comment)-1);
|
StrnCpy(my_comment, n->my_comment, sizeof(n->my_comment)-1);
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ extern BOOL updatedlists;
|
|||||||
remove_all_servers indicates everybody dies.
|
remove_all_servers indicates everybody dies.
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void remove_old_servers(struct work_record *work, time_t t,
|
void remove_old_servers(struct work_record *work, time_t t,
|
||||||
BOOL remove_all)
|
BOOL remove_all)
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
struct server_record *nexts;
|
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)
|
for (s = work->serverlist; s; s = nexts)
|
||||||
{
|
{
|
||||||
if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
|
if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
|
||||||
{
|
{
|
||||||
DEBUG(3,("Removing dead server %s\n",s->serv.name));
|
DEBUG(3,("Removing dead server %s\n",s->serv.name));
|
||||||
updatedlists = True;
|
updatedlists = True;
|
||||||
nexts = s->next;
|
nexts = s->next;
|
||||||
|
|
||||||
if (s->prev) s->prev->next = s->next;
|
if (s->prev) s->prev->next = s->next;
|
||||||
if (s->next) s->next->prev = s->prev;
|
if (s->next) s->next->prev = s->prev;
|
||||||
|
|
||||||
if (work->serverlist == s)
|
if (work->serverlist == s)
|
||||||
work->serverlist = s->next;
|
work->serverlist = s->next;
|
||||||
|
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
else
|
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 *find_server(struct work_record *work, char *name)
|
||||||
{
|
{
|
||||||
struct server_record *ret;
|
struct server_record *ret;
|
||||||
|
|
||||||
if (!work) return NULL;
|
if (!work) return NULL;
|
||||||
|
|
||||||
for (ret = work->serverlist; ret; ret = ret->next)
|
for (ret = work->serverlist; ret; ret = ret->next)
|
||||||
{
|
{
|
||||||
if (strequal(ret->serv.name,name))
|
if (strequal(ret->serv.name,name))
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,15 +126,14 @@ struct server_record *find_server(struct work_record *work, char *name)
|
|||||||
add a server entry
|
add a server entry
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct server_record *add_server_entry(struct subnet_record *d,
|
struct server_record *add_server_entry(struct subnet_record *d,
|
||||||
struct work_record *work,
|
struct work_record *work,
|
||||||
char *name,int servertype,
|
char *name,int servertype,
|
||||||
int ttl,char *comment,
|
int ttl,char *comment,
|
||||||
BOOL replace)
|
BOOL replace)
|
||||||
{
|
{
|
||||||
BOOL newentry=False;
|
BOOL newentry=False;
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
int token = conf_workgroup_name_to_token(work->work_group, myname);
|
|
||||||
|
|
||||||
if (name[0] == '*')
|
if (name[0] == '*')
|
||||||
{
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -161,14 +160,16 @@ struct server_record *add_server_entry(struct subnet_record *d,
|
|||||||
bzero((char *)s,sizeof(*s));
|
bzero((char *)s,sizeof(*s));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf_should_workgroup_member(token))
|
|
||||||
{
|
if (strequal(lp_workgroup(),work->work_group))
|
||||||
if (servertype) servertype |= SV_TYPE_LOCAL_LIST_ONLY;
|
{
|
||||||
}
|
if (servertype)
|
||||||
|
servertype |= SV_TYPE_LOCAL_LIST_ONLY;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
|
servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the entry */
|
/* update the entry */
|
||||||
StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
|
StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
|
||||||
@ -193,8 +194,8 @@ struct server_record *add_server_entry(struct subnet_record *d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
|
DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
|
||||||
name,servertype,comment,
|
name,servertype,comment,
|
||||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||||
|
|
||||||
return(s);
|
return(s);
|
||||||
}
|
}
|
||||||
@ -212,9 +213,9 @@ void expire_servers(time_t t)
|
|||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
remove_old_servers(work, t, False);
|
remove_old_servers(work, t, False);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +26,6 @@
|
|||||||
04 jul 96: lkcl@pires.co.uk
|
04 jul 96: lkcl@pires.co.uk
|
||||||
created module namedbsubnet containing subnet database functions
|
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"
|
#include "includes.h"
|
||||||
@ -93,16 +90,16 @@ struct subnet_record *find_subnet(struct in_addr bcast_ip)
|
|||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
if (ip_equal(bcast_ip, wins_ip))
|
if (ip_equal(bcast_ip, wins_ip))
|
||||||
{
|
{
|
||||||
if (ip_equal(bcast_ip, d->bcast_ip))
|
if (ip_equal(bcast_ip, d->bcast_ip))
|
||||||
{
|
{
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
|
else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
|
||||||
{
|
{
|
||||||
return(d);
|
return(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -157,60 +154,47 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void add_subnet_interfaces(void)
|
void add_subnet_interfaces(void)
|
||||||
{
|
{
|
||||||
struct interface *i;
|
struct interface *i;
|
||||||
|
|
||||||
/* loop on all local interfaces */
|
/* loop on all local interfaces */
|
||||||
for (i = local_interfaces; i; i = i->next)
|
for (i = local_interfaces; i; i = i->next)
|
||||||
{
|
{
|
||||||
/* add the interface into our subnet database */
|
/* add the interface into our subnet database */
|
||||||
if (!find_subnet(i->bcast))
|
if (!find_subnet(i->bcast))
|
||||||
{
|
{
|
||||||
make_subnet(i->bcast,i->nmask);
|
make_subnet(i->bcast,i->nmask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
|
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
|
||||||
if (lp_wins_support() || (*lp_wins_server()))
|
if (lp_wins_support() || (*lp_wins_server()))
|
||||||
{
|
{
|
||||||
struct in_addr wins_bcast = ipgrp;
|
struct in_addr wins_bcast = ipgrp;
|
||||||
struct in_addr wins_nmask = ipzero;
|
struct in_addr wins_nmask = ipzero;
|
||||||
make_subnet(wins_bcast, wins_nmask);
|
make_subnet(wins_bcast, wins_nmask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
add the default workgroups into my domain
|
|
||||||
**************************************************************************/
|
|
||||||
void add_workgroup_to_subnet(char *group, struct in_addr bcast_ip,
|
|
||||||
struct in_addr mask_ip)
|
|
||||||
{
|
|
||||||
if (group && *group != '*')
|
|
||||||
{
|
|
||||||
DEBUG(4,("add_wg_to_subnet: %s %s\n", group, inet_ntoa(bcast_ip)));
|
|
||||||
add_subnet_entry(bcast_ip,mask_ip,group, True, False);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
add the default workgroup into my domain
|
add the default workgroup into my domain
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void add_workgroups_to_subnets()
|
void add_my_subnets(char *group)
|
||||||
{
|
{
|
||||||
struct interface *i;
|
struct interface *i;
|
||||||
|
|
||||||
/* add or find domain on our local subnet, in the default workgroup */
|
/* add or find domain on our local subnet, in the default workgroup */
|
||||||
|
|
||||||
|
if (*group == '*') return;
|
||||||
|
|
||||||
for (i = local_interfaces; i; i = i->next)
|
/* 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
|
||||||
int token;
|
messed up! */
|
||||||
for (token = 0; token < get_num_workgroups(); token++)
|
for (i = local_interfaces; i; i = i->next)
|
||||||
{
|
{
|
||||||
add_workgroup_to_subnet(conf_workgroup_name(token),i->bcast,i->nmask);
|
add_subnet_entry(i->bcast,i->nmask,group, True, False);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -219,49 +203,48 @@ void add_workgroups_to_subnets()
|
|||||||
to the named a workgroup.
|
to the named a workgroup.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||||
struct in_addr mask_ip,
|
struct in_addr mask_ip,
|
||||||
char *name, BOOL add, BOOL lmhosts)
|
char *name, BOOL add, BOOL lmhosts)
|
||||||
{
|
{
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
|
|
||||||
DEBUG(4,("add_subnet_entry: %s %\n", name,inet_ntoa(bcast_ip)));
|
/* XXXX andrew: struct in_addr ip appears not to be referenced at all except
|
||||||
|
in the DEBUG comment. i assume that the DEBUG comment below actually
|
||||||
|
intends to refer to bcast_ip? i don't know.
|
||||||
|
|
||||||
if (zero_ip(bcast_ip)) bcast_ip = *iface_bcast(bcast_ip);
|
struct in_addr ip = ipgrp;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (zero_ip(bcast_ip))
|
||||||
|
bcast_ip = *iface_bcast(bcast_ip);
|
||||||
|
|
||||||
/* add the domain into our domain database */
|
/* add the domain into our domain database */
|
||||||
if ((d = find_subnet(bcast_ip)) || (d = make_subnet(bcast_ip, mask_ip)))
|
if ((d = find_subnet(bcast_ip)) ||
|
||||||
{
|
(d = make_subnet(bcast_ip, mask_ip)))
|
||||||
struct work_record *work = find_workgroupstruct(d, name, add);
|
|
||||||
|
|
||||||
if (!work) return NULL;
|
|
||||||
|
|
||||||
if (conf_should_workgroup_member(work->token))
|
|
||||||
{
|
{
|
||||||
/* add samba server name to workgroup list. don't add
|
struct work_record *w = find_workgroupstruct(d, name, add);
|
||||||
lmhosts server entries to local interfaces */
|
|
||||||
|
if (!w) return NULL;
|
||||||
pstring comment;
|
|
||||||
char *my_name = conf_browsing_alias (work->token);
|
|
||||||
char *my_comment = conf_browsing_alias_comment(work->token);
|
|
||||||
|
|
||||||
StrnCpy(comment, my_comment, 43);
|
|
||||||
|
|
||||||
add_server_entry(d,work,my_name,
|
|
||||||
work->ServerType | SV_TYPE_LOCAL_LIST_ONLY,
|
|
||||||
0,comment,True);
|
|
||||||
|
|
||||||
|
/* 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);
|
||||||
DEBUG(3,("Added server name entry %s at %s\n",
|
DEBUG(3,("Added server name entry %s at %s\n",
|
||||||
name,inet_ntoa(bcast_ip)));
|
name,inet_ntoa(bcast_ip)));
|
||||||
|
}
|
||||||
/* 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 d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,31 +290,31 @@ void write_browse_list(void)
|
|||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work ; work = work->next)
|
for (work = d->workgrouplist; work ; work = work->next)
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
for (s = work->serverlist; s ; s = s->next)
|
for (s = work->serverlist; s ; s = s->next)
|
||||||
{
|
{
|
||||||
fstring tmp;
|
fstring tmp;
|
||||||
|
|
||||||
/* don't list domains I don't have a master for */
|
/* don't list domains I don't have a master for */
|
||||||
if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
|
if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* output server details, plus what workgroup/domain
|
/* output server details, plus what workgroup/domain
|
||||||
they're in. without the domain information, the
|
they're in. without the domain information, the
|
||||||
combined list of all servers in all workgroups gets
|
combined list of all servers in all workgroups gets
|
||||||
sent to anyone asking about any workgroup! */
|
sent to anyone asking about any workgroup! */
|
||||||
|
|
||||||
sprintf(tmp, "\"%s\"", s->serv.name);
|
sprintf(tmp, "\"%s\"", s->serv.name);
|
||||||
fprintf(f, "%-25s ", tmp);
|
fprintf(f, "%-25s ", tmp);
|
||||||
fprintf(f, "%08x ", s->serv.type);
|
fprintf(f, "%08x ", s->serv.type);
|
||||||
sprintf(tmp, "\"%s\" ", s->serv.comment);
|
sprintf(tmp, "\"%s\" ", s->serv.comment);
|
||||||
fprintf(f, "%-30s", tmp);
|
fprintf(f, "%-30s", tmp);
|
||||||
fprintf(f, "\"%s\"\n", work->work_group);
|
fprintf(f, "\"%s\"\n", work->work_group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -26,9 +26,6 @@
|
|||||||
04 jul 96: lkcl@pires.co.uk
|
04 jul 96: lkcl@pires.co.uk
|
||||||
created module namedbwork containing workgroup database functions
|
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"
|
#include "includes.h"
|
||||||
@ -43,7 +40,9 @@ extern struct subnet_record *subnetlist;
|
|||||||
|
|
||||||
extern struct in_addr ipgrp;
|
extern struct in_addr ipgrp;
|
||||||
|
|
||||||
extern pstring myname;
|
int workgroup_count = 0; /* unique index key: one for each workgroup */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
add a workgroup into the domain list
|
add a workgroup into the domain list
|
||||||
@ -76,17 +75,11 @@ static void add_workgroup(struct work_record *work, struct subnet_record *d)
|
|||||||
static struct work_record *make_workgroup(char *name)
|
static struct work_record *make_workgroup(char *name)
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
struct subnet_record *d;
|
||||||
int t = -1;
|
int t = -1;
|
||||||
|
|
||||||
if (!name || !name[0]) return NULL;
|
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));
|
work = (struct work_record *)malloc(sizeof(*work));
|
||||||
if (!work) return(NULL);
|
if (!work) return(NULL);
|
||||||
|
|
||||||
@ -99,16 +92,34 @@ static struct work_record *make_workgroup(char *name)
|
|||||||
work->needelection = False;
|
work->needelection = False;
|
||||||
work->needannounce = True;
|
work->needannounce = True;
|
||||||
work->state = MST_NONE;
|
work->state = MST_NONE;
|
||||||
work->token = t;
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* WfWg uses 01040b01 */
|
/* WfWg uses 01040b01 */
|
||||||
/* Win95 uses 01041501 */
|
/* Win95 uses 01041501 */
|
||||||
/* NTAS uses ???????? */
|
/* NTAS uses ???????? */
|
||||||
work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
|
work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
|
||||||
work->ElectionCriterion |= (lp_os_level() << 24);
|
work->ElectionCriterion |= (lp_os_level() << 24);
|
||||||
|
if (lp_domain_master()) {
|
||||||
if (conf_should_domain_master(work->token))
|
|
||||||
{
|
|
||||||
work->ElectionCriterion |= 0x80;
|
work->ElectionCriterion |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +131,8 @@ static struct work_record *make_workgroup(char *name)
|
|||||||
remove workgroups
|
remove workgroups
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
struct work_record *remove_workgroup(struct subnet_record *d,
|
struct work_record *remove_workgroup(struct subnet_record *d,
|
||||||
struct work_record *work,
|
struct work_record *work,
|
||||||
BOOL remove_all_servers)
|
BOOL remove_all_servers)
|
||||||
{
|
{
|
||||||
struct work_record *ret_work = NULL;
|
struct work_record *ret_work = NULL;
|
||||||
|
|
||||||
@ -154,7 +165,7 @@ struct work_record *remove_workgroup(struct subnet_record *d,
|
|||||||
lmhosts file to be added.
|
lmhosts file to be added.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
struct work_record *find_workgroupstruct(struct subnet_record *d,
|
struct work_record *find_workgroupstruct(struct subnet_record *d,
|
||||||
fstring name, BOOL add)
|
fstring name, BOOL add)
|
||||||
{
|
{
|
||||||
struct work_record *ret, *work;
|
struct work_record *ret, *work;
|
||||||
|
|
||||||
@ -163,51 +174,39 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
|
|||||||
DEBUG(4, ("workgroup search for %s: ", name));
|
DEBUG(4, ("workgroup search for %s: ", name));
|
||||||
|
|
||||||
if (strequal(name, "*"))
|
if (strequal(name, "*"))
|
||||||
{
|
|
||||||
#if 0 /* XXXX this is being called too many times */
|
|
||||||
|
|
||||||
DEBUG(2,("add any workgroups: initiating browser search on %s\n",
|
|
||||||
inet_ntoa(d->bcast_ip)));
|
|
||||||
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
|
|
||||||
-1,MSBROWSE,0x1,0,0,0,0,NULL,NULL,
|
|
||||||
True,False, d->bcast_ip, d->bcast_ip);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ret = d->workgrouplist; ret; ret = ret->next)
|
|
||||||
{
|
|
||||||
if (!strcmp(ret->work_group,name))
|
|
||||||
{
|
{
|
||||||
|
DEBUG(2,("add any workgroups: initiating browser search on %s\n",
|
||||||
|
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);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ret = d->workgrouplist; ret; ret = ret->next) {
|
||||||
|
if (!strcmp(ret->work_group,name)) {
|
||||||
DEBUG(4, ("found\n"));
|
DEBUG(4, ("found\n"));
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!add)
|
if (!add) {
|
||||||
{
|
|
||||||
DEBUG(4, ("not found\n"));
|
DEBUG(4, ("not found\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4,("not found: creating\n"));
|
DEBUG(4,("not found: creating\n"));
|
||||||
|
|
||||||
if ((work = make_workgroup(name)) != NULL)
|
if ((work = make_workgroup(name)))
|
||||||
{
|
|
||||||
DEBUG(4,("bcast_ip:%s preferred master=%s local_master=%s\n",
|
|
||||||
inet_ntoa(d->bcast_ip),
|
|
||||||
BOOLSTR(conf_should_preferred_master(work->token)),
|
|
||||||
BOOLSTR(conf_should_local_master(work->token)) ));
|
|
||||||
|
|
||||||
if (!ip_equal(d->bcast_ip, ipgrp) &&
|
|
||||||
conf_should_preferred_master(work->token) &&
|
|
||||||
conf_should_local_master (work->token))
|
|
||||||
{
|
{
|
||||||
DEBUG(3, ("preferred master startup for %s\n", work->work_group));
|
if (!ip_equal(d->bcast_ip, ipgrp) &&
|
||||||
work->needelection = True;
|
lp_preferred_master() &&
|
||||||
work->ElectionCriterion |= (1<<3);
|
strequal(lp_workgroup(), name))
|
||||||
}
|
{
|
||||||
|
DEBUG(3, ("preferred master startup for %s\n", work->work_group));
|
||||||
|
work->needelection = True;
|
||||||
|
work->ElectionCriterion |= (1<<3);
|
||||||
|
}
|
||||||
add_workgroup(work, d);
|
add_workgroup(work, d);
|
||||||
return(work);
|
return(work);
|
||||||
}
|
}
|
||||||
@ -225,25 +224,25 @@ void dump_workgroups(void)
|
|||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
if (d->workgrouplist)
|
if (d->workgrouplist)
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
|
||||||
DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
|
DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
|
||||||
DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
|
DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
|
DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
|
||||||
if (work->serverlist)
|
if (work->serverlist)
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
for (s = work->serverlist; s; s = s->next)
|
for (s = work->serverlist; s; s = s->next)
|
||||||
{
|
{
|
||||||
DEBUG(4,("\t\t%s %8x (%s)\n",
|
DEBUG(4,("\t\t%s %8x (%s)\n",
|
||||||
s->serv.name, s->serv.type, s->serv.comment));
|
s->serv.name, s->serv.type, s->serv.comment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,10 @@
|
|||||||
04 jul 96: lkcl@pires.co.uk
|
04 jul 96: lkcl@pires.co.uk
|
||||||
added system to become a master browser by stages.
|
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 ClientNMB;
|
||||||
extern int ClientDGRAM;
|
extern int ClientDGRAM;
|
||||||
@ -41,6 +39,7 @@ extern int ClientDGRAM;
|
|||||||
extern int DEBUGLEVEL;
|
extern int DEBUGLEVEL;
|
||||||
extern pstring scope;
|
extern pstring scope;
|
||||||
|
|
||||||
|
extern pstring myname;
|
||||||
extern struct in_addr ipzero;
|
extern struct in_addr ipzero;
|
||||||
extern struct in_addr ipgrp;
|
extern struct in_addr ipgrp;
|
||||||
|
|
||||||
@ -52,9 +51,6 @@ extern struct subnet_record *subnetlist;
|
|||||||
|
|
||||||
extern uint16 nb_type; /* samba's NetBIOS name type */
|
extern uint16 nb_type; /* samba's NetBIOS name type */
|
||||||
|
|
||||||
extern pstring myname;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
occasionally check to see if the master browser is around
|
occasionally check to see if the master browser is around
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@ -72,22 +68,22 @@ void check_master_browser(void)
|
|||||||
dump_workgroups();
|
dump_workgroups();
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
|
||||||
struct work_record *work;
|
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
|
||||||
{
|
{
|
||||||
/* if we are not the browse master of a workgroup, and we can't
|
struct work_record *work;
|
||||||
find a browser on the subnet, do something about it. */
|
|
||||||
|
|
||||||
if (!AM_MASTER(work))
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
|
/* if we are not the browse master of a workgroup, and we can't
|
||||||
work->token, work->work_group,0x1d,REGISTER,0,0,0,NULL,NULL,
|
find a browser on the subnet, do something about it. */
|
||||||
True,False,d->bcast_ip,d->bcast_ip);
|
|
||||||
}
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -106,10 +102,11 @@ void browser_gone(char *work_name, struct in_addr ip)
|
|||||||
if (ip_equal(d->bcast_ip,ipgrp))
|
if (ip_equal(d->bcast_ip,ipgrp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (conf_should_local_master(work->token))
|
if (strequal(work->work_group, lp_workgroup()))
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUG(2,("Forcing election on %s %s\n",
|
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 */
|
/* we can attempt to become master browser */
|
||||||
work->needelection = True;
|
work->needelection = True;
|
||||||
@ -117,10 +114,10 @@ void browser_gone(char *work_name, struct in_addr ip)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* local interfaces: force an election */
|
/* local interfaces: force an election */
|
||||||
send_election(d, work->work_group, 0, 0, conf_browsing_alias(work->token));
|
send_election(d, work->work_group, 0, 0, myname);
|
||||||
|
|
||||||
/* only removes workgroup completely on a local interface
|
/* 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);
|
remove_workgroup(d, work,True);
|
||||||
}
|
}
|
||||||
@ -131,7 +128,7 @@ void browser_gone(char *work_name, struct in_addr ip)
|
|||||||
send an election packet
|
send an election packet
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
||||||
int timeup,char *name)
|
int timeup,char *name)
|
||||||
{
|
{
|
||||||
pstring outbuf;
|
pstring outbuf;
|
||||||
char *p;
|
char *p;
|
||||||
@ -139,7 +136,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
|||||||
if (!d) return;
|
if (!d) return;
|
||||||
|
|
||||||
DEBUG(2,("Sending election to %s for workgroup %s\n",
|
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));
|
bzero(outbuf,sizeof(outbuf));
|
||||||
p = outbuf;
|
p = outbuf;
|
||||||
@ -155,7 +152,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
|||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -175,10 +172,8 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
|||||||
|
|
||||||
if (!(work = find_workgroupstruct(d, name, False))) return;
|
if (!(work = find_workgroupstruct(d, name, False))) return;
|
||||||
|
|
||||||
if (!AM_MASTER(work) && !AM_DMBRSE(work)) return;
|
|
||||||
|
|
||||||
if (ms_browser_name(name, name_type) ||
|
if (ms_browser_name(name, name_type) ||
|
||||||
(conf_should_workgroup_member(work->token) &&
|
(AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
|
||||||
(name_type == 0x1d || name_type == 0x1b)))
|
(name_type == 0x1d || name_type == 0x1b)))
|
||||||
{
|
{
|
||||||
int remove_type = 0;
|
int remove_type = 0;
|
||||||
@ -189,7 +184,7 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
|||||||
remove_type = SV_TYPE_MASTER_BROWSER;
|
remove_type = SV_TYPE_MASTER_BROWSER;
|
||||||
if (name_type == 0x1b)
|
if (name_type == 0x1b)
|
||||||
remove_type = SV_TYPE_DOMAIN_MASTER;
|
remove_type = SV_TYPE_DOMAIN_MASTER;
|
||||||
|
|
||||||
become_nonmaster(d, work, remove_type);
|
become_nonmaster(d, work, remove_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,17 +197,17 @@ 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.
|
whether to proceed to the next stage in samba becoming a master browser.
|
||||||
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void name_register_work(struct subnet_record *d, int token,
|
void name_register_work(struct subnet_record *d, char *name, int name_type,
|
||||||
char *name, int name_type, enum name_source source,
|
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
|
||||||
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;
|
||||||
|
|
||||||
if (source == SELF)
|
if (source == SELF)
|
||||||
{
|
{
|
||||||
char *work_name = conf_workgroup_name(token);
|
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||||
struct work_record *work = find_workgroupstruct(d, work_name, False);
|
|
||||||
|
|
||||||
add_netbios_entry(d,name,name_type,data->nb_flags,
|
add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
|
||||||
ttl,source,data->ip,True,!bcast);
|
|
||||||
|
|
||||||
if (work)
|
if (work)
|
||||||
{
|
{
|
||||||
@ -254,8 +249,6 @@ void name_register_work(struct subnet_record *d, int token,
|
|||||||
******************************************************************/
|
******************************************************************/
|
||||||
void become_master(struct subnet_record *d, struct work_record *work)
|
void become_master(struct subnet_record *d, struct work_record *work)
|
||||||
{
|
{
|
||||||
pstring comment;
|
|
||||||
|
|
||||||
/* domain type must be limited to domain enum + server type. it must
|
/* domain type must be limited to domain enum + server type. it must
|
||||||
not have SV_TYPE_SERVER or anything else with SERVER in it, else
|
not have SV_TYPE_SERVER or anything else with SERVER in it, else
|
||||||
clients get confused and start thinking this entry is a server
|
clients get confused and start thinking this entry is a server
|
||||||
@ -263,26 +256,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
*/
|
*/
|
||||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||||
|
|
||||||
char *my_name ;
|
|
||||||
char *my_comment;
|
|
||||||
|
|
||||||
if (!work) return;
|
if (!work) return;
|
||||||
|
|
||||||
my_name = conf_browsing_alias(work->token);
|
|
||||||
my_comment = conf_browsing_alias_comment(work->token);
|
|
||||||
|
|
||||||
StrnCpy(comment, my_comment, 43);
|
|
||||||
|
|
||||||
if (!conf_should_local_master(work->token))
|
|
||||||
{
|
|
||||||
DEBUG(1,("Should not become master for %s %s\n",
|
|
||||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
|
||||||
work->state = MST_NONE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
|
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)
|
switch (work->state)
|
||||||
{
|
{
|
||||||
@ -295,10 +272,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
|
|
||||||
/* update our server status */
|
/* update our server status */
|
||||||
work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
|
work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
|
||||||
add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
|
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||||
|
|
||||||
/* add special browser name */
|
/* add special browser name */
|
||||||
add_my_name_entry(d,work->token,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
return;
|
||||||
@ -309,11 +286,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
work->state = MST_MSB; /* ... registering MSBROWSE was successful */
|
work->state = MST_MSB; /* ... registering MSBROWSE was successful */
|
||||||
|
|
||||||
/* add server entry on successful registration of MSBROWSE */
|
/* add server entry on successful registration of MSBROWSE */
|
||||||
add_server_entry(d,work,work->work_group,
|
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
|
||||||
domain_type,0,conf_browsing_alias(work->token),True);
|
|
||||||
|
|
||||||
/* add master name */
|
/* add master name */
|
||||||
add_my_name_entry(d,work->token,work->work_group,0x1d,nb_type|NB_ACTIVE);
|
add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
return;
|
||||||
@ -325,8 +301,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
|
|
||||||
/* update our server status */
|
/* update our server status */
|
||||||
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
||||||
add_server_entry(d,work,conf_browsing_alias(work->token),
|
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||||
work->ServerType,0,comment,True);
|
|
||||||
|
|
||||||
if (work->serverlist == NULL) /* no servers! */
|
if (work->serverlist == NULL) /* no servers! */
|
||||||
{
|
{
|
||||||
@ -346,14 +321,13 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
|
|
||||||
case MST_DOMAIN_NONE:
|
case MST_DOMAIN_NONE:
|
||||||
{
|
{
|
||||||
if (conf_should_domain_master(work->token))
|
if (lp_domain_master())
|
||||||
{
|
{
|
||||||
work->state = MST_DOMAIN_MEM; /* ... become domain member */
|
work->state = MST_DOMAIN_MEM; /* ... become domain member */
|
||||||
DEBUG(3,("domain first stage: register as domain member\n"));
|
DEBUG(3,("domain first stage: register as domain member\n"));
|
||||||
|
|
||||||
/* add domain member name */
|
/* add domain member name */
|
||||||
add_my_name_entry(d,work->token,work->work_group,0x1e,
|
add_my_name_entry(d,work->work_group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
|
||||||
nb_type|NB_ACTIVE|NB_GROUP);
|
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
return;
|
||||||
@ -368,20 +342,19 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
|
|
||||||
case MST_DOMAIN_MEM:
|
case MST_DOMAIN_MEM:
|
||||||
{
|
{
|
||||||
if (conf_should_domain_master(work->token))
|
if (lp_domain_master())
|
||||||
{
|
{
|
||||||
work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
|
work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
|
||||||
DEBUG(3,("domain second stage: register as domain master\n"));
|
DEBUG(3,("domain second stage: register as domain master\n"));
|
||||||
|
|
||||||
if (conf_should_domain_logon(work->token))
|
if (lp_domain_logons())
|
||||||
{
|
{
|
||||||
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
|
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
|
||||||
add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
|
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add domain master name */
|
/* add domain master name */
|
||||||
add_my_name_entry(d,work->token,work->work_group,0x1b,
|
add_my_name_entry(d,work->work_group,0x1b,nb_type|NB_ACTIVE );
|
||||||
nb_type|NB_ACTIVE );
|
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
return;
|
||||||
@ -397,10 +370,10 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
case MST_DOMAIN_TST: /* while we were still a master browser... */
|
case MST_DOMAIN_TST: /* while we were still a master browser... */
|
||||||
{
|
{
|
||||||
/* update our server status */
|
/* update our server status */
|
||||||
if (conf_should_domain_master(work->token))
|
if (lp_domain_master())
|
||||||
{
|
{
|
||||||
struct subnet_record *d1;
|
struct subnet_record *d1;
|
||||||
uint32 update_type = 0;
|
uint32 update_type = 0;
|
||||||
|
|
||||||
DEBUG(3,("domain third stage: samba is now a domain master.\n"));
|
DEBUG(3,("domain third stage: samba is now a domain master.\n"));
|
||||||
work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
|
work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
|
||||||
@ -408,30 +381,30 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER |
|
update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER |
|
||||||
SV_TYPE_POTENTIAL_BROWSER;
|
SV_TYPE_POTENTIAL_BROWSER;
|
||||||
|
|
||||||
work->ServerType |= update_type;
|
work->ServerType |= update_type;
|
||||||
add_server_entry(d,work,my_name,work->ServerType,0,comment,True);
|
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||||
|
|
||||||
for (d1 = subnetlist; d1; d1 = d1->next)
|
for (d1 = subnetlist; d1; d1 = d1->next)
|
||||||
{
|
{
|
||||||
struct work_record *w;
|
struct work_record *w;
|
||||||
if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
|
if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
|
||||||
|
|
||||||
for (w = d1->workgrouplist; w; w = w->next)
|
for (w = d1->workgrouplist; w; w = w->next)
|
||||||
{
|
{
|
||||||
struct server_record *s = find_server(w, my_name);
|
struct server_record *s = find_server(w, myname);
|
||||||
if (strequal(w->work_group, work->work_group))
|
if (strequal(w->work_group, work->work_group))
|
||||||
{
|
{
|
||||||
w->ServerType |= update_type;
|
w->ServerType |= update_type;
|
||||||
}
|
}
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
s->serv.type |= update_type;
|
s->serv.type |= update_type;
|
||||||
DEBUG(4,("found server %s on %s: update to %8x\n",
|
DEBUG(4,("found server %s on %s: update to %8x\n",
|
||||||
s->serv.name, inet_ntoa(d1->bcast_ip),
|
s->serv.name, inet_ntoa(d1->bcast_ip),
|
||||||
s->serv.type));
|
s->serv.type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -452,25 +425,11 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
names, and tells the world that we are no longer a master browser.
|
names, and tells the world that we are no longer a master browser.
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void become_nonmaster(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)
|
||||||
{
|
{
|
||||||
int new_server_type = work->ServerType;
|
int new_server_type = work->ServerType;
|
||||||
|
|
||||||
pstring comment;
|
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
|
||||||
|
|
||||||
char *my_name ;
|
|
||||||
char *my_comment;
|
|
||||||
BOOL wins = ip_equal(d->bcast_ip, ipgrp);
|
|
||||||
enum master_state state;
|
|
||||||
|
|
||||||
if (!work) return;
|
|
||||||
|
|
||||||
my_name = conf_browsing_alias (work->token);
|
|
||||||
my_comment = conf_browsing_alias_comment(work->token);
|
|
||||||
|
|
||||||
StrnCpy(comment, my_comment, 43);
|
|
||||||
|
|
||||||
DEBUG(2,("Becoming non-master for %s alias %s\n",work->work_group, my_name));
|
|
||||||
|
|
||||||
/* can only remove master or domain types with this function */
|
/* can only remove master or domain types with this function */
|
||||||
remove_type &= SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
|
remove_type &= SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
|
||||||
@ -480,7 +439,6 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
|
|||||||
remove_type |= SV_TYPE_DOMAIN_MASTER;
|
remove_type |= SV_TYPE_DOMAIN_MASTER;
|
||||||
|
|
||||||
new_server_type &= ~remove_type;
|
new_server_type &= ~remove_type;
|
||||||
state = work->state;
|
|
||||||
|
|
||||||
if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
|
if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
|
||||||
{
|
{
|
||||||
@ -490,40 +448,25 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
|
|||||||
work->ElectionCriterion &= ~0x4;
|
work->ElectionCriterion &= ~0x4;
|
||||||
work->state = MST_NONE;
|
work->state = MST_NONE;
|
||||||
|
|
||||||
remove_name_entry(d,work->token,MSBROWSE,0x01);
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
work->ServerType = new_server_type;
|
work->ServerType = new_server_type;
|
||||||
|
|
||||||
if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
|
if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
|
||||||
{
|
{
|
||||||
if (state == MST_DOMAIN)
|
if (work->state == MST_DOMAIN)
|
||||||
{
|
work->state = MST_BROWSER;
|
||||||
if (wins)
|
remove_name_entry(d,work->work_group,0x1b);
|
||||||
work->state = MST_NONE;
|
|
||||||
else
|
|
||||||
work->state = MST_BROWSER;
|
|
||||||
}
|
|
||||||
remove_name_entry(d,work->token,work->work_group,0x1b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
|
if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
|
||||||
{
|
{
|
||||||
if (state >= MST_BROWSER)
|
if (work->state >= MST_BROWSER)
|
||||||
work->state = MST_NONE;
|
work->state = MST_NONE;
|
||||||
remove_name_entry(d,work->token,work->work_group,0x1d);
|
remove_name_entry(d,work->work_group,0x1d);
|
||||||
}
|
|
||||||
|
|
||||||
/* update our internal records with our new server state */
|
|
||||||
add_server_entry(d, work, my_name, work->ServerType, 0, my_comment, True);
|
|
||||||
|
|
||||||
/* announce change in status on local interface */
|
|
||||||
if (!wins)
|
|
||||||
{
|
|
||||||
/* XXXX do we need also to do an announce with a time of zero
|
|
||||||
if we are no longer a local master browser?
|
|
||||||
*/
|
|
||||||
work->needannounce = True;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,27 +490,25 @@ void run_elections(void)
|
|||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (work->RunningElection)
|
if (work->RunningElection)
|
||||||
{
|
{
|
||||||
char *alias = conf_browsing_alias(work->token);
|
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;
|
||||||
|
|
||||||
send_election(d,work->work_group, work->ElectionCriterion,
|
become_master(d, work);
|
||||||
t-StartupTime,alias);
|
}
|
||||||
|
}
|
||||||
if (work->ElectionCount++ >= 4)
|
}
|
||||||
{
|
|
||||||
/* I won! now what :-) */
|
|
||||||
DEBUG(2,(">>> Won election for %s as %s on %s <<<\n",
|
|
||||||
work->work_group,alias,inet_ntoa(d->bcast_ip)));
|
|
||||||
|
|
||||||
work->RunningElection = False;
|
|
||||||
work->state = MST_NONE;
|
|
||||||
|
|
||||||
become_master(d, work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +517,7 @@ void run_elections(void)
|
|||||||
work out if I win an election
|
work out if I win an election
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
static BOOL win_election(struct work_record *work,int version,uint32 criterion,
|
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;
|
int mytimeup = time(NULL) - StartupTime;
|
||||||
uint32 mycriterion = work->ElectionCriterion;
|
uint32 mycriterion = work->ElectionCriterion;
|
||||||
@ -596,7 +537,7 @@ static BOOL win_election(struct work_record *work,int version,uint32 criterion,
|
|||||||
if (timeup > mytimeup) return(False);
|
if (timeup > mytimeup) return(False);
|
||||||
if (timeup < mytimeup) return(True);
|
if (timeup < mytimeup) return(True);
|
||||||
|
|
||||||
if (strcasecmp(conf_browsing_alias(work->token),name) > 0) return(False);
|
if (strcasecmp(myname,name) > 0) return(False);
|
||||||
|
|
||||||
return(True);
|
return(True);
|
||||||
}
|
}
|
||||||
@ -634,38 +575,30 @@ void process_election(struct packet_struct *p,char *buf)
|
|||||||
if (same_context(dgram)) return;
|
if (same_context(dgram)) return;
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (!conf_should_local_master(work->token)) continue;
|
if (!strequal(work->work_group, lp_workgroup()))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (win_election(work, version,criterion,timeup,name))
|
if (win_election(work, version,criterion,timeup,name)) {
|
||||||
{
|
if (!work->RunningElection) {
|
||||||
if (!work->RunningElection)
|
work->needelection = True;
|
||||||
{
|
work->ElectionCount=0;
|
||||||
work->needelection = True;
|
work->state = MST_NONE;
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -686,18 +619,18 @@ BOOL check_elections(void)
|
|||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
run_any_election |= work->RunningElection;
|
run_any_election |= work->RunningElection;
|
||||||
|
|
||||||
if (work->needelection && !work->RunningElection)
|
if (work->needelection && !work->RunningElection)
|
||||||
{
|
{
|
||||||
DEBUG(3,(">>> Starting election on %s %s <<<\n",
|
DEBUG(3,(">>> Starting election on %s %s <<<\n",
|
||||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||||
work->ElectionCount = 0;
|
work->ElectionCount = 0;
|
||||||
work->RunningElection = True;
|
work->RunningElection = True;
|
||||||
work->needelection = False;
|
work->needelection = False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return run_any_election;
|
return run_any_election;
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,7 @@
|
|||||||
Revision History:
|
Revision History:
|
||||||
|
|
||||||
14 jan 96: lkcl@pires.co.uk
|
14 jan 96: lkcl@pires.co.uk
|
||||||
added domain master browser support
|
added multiple workgroup domain master support
|
||||||
|
|
||||||
30 aug 96: lkcl@pires.co.uk
|
|
||||||
added multiple domain logon support, using extensions to David Chappell's
|
|
||||||
multiple domain master browser code.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -33,8 +29,13 @@
|
|||||||
|
|
||||||
extern int ClientDGRAM;
|
extern int ClientDGRAM;
|
||||||
|
|
||||||
|
#define TEST_CODE /* want to debug unknown browse packets */
|
||||||
|
|
||||||
extern int DEBUGLEVEL;
|
extern int DEBUGLEVEL;
|
||||||
|
|
||||||
|
extern pstring myname;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
process a domain logon packet
|
process a domain logon packet
|
||||||
|
|
||||||
@ -53,18 +54,14 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
pstring outbuf;
|
pstring outbuf;
|
||||||
int code,reply_code;
|
int code,reply_code;
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
char *my_name;
|
|
||||||
|
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
|
|
||||||
if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
|
if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((my_name = conf_browsing_alias(work->token)) == NULL) return;
|
if (!lp_domain_logons()) {
|
||||||
|
DEBUG(3,("No domain logons\n"));
|
||||||
if (!conf_should_domain_logon(work->token))
|
|
||||||
{
|
|
||||||
DEBUG(3,("No domain logons for %s (%s)\n", work->work_group, my_name));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +73,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
char *user = skip_string(machine,1);
|
char *user = skip_string(machine,1);
|
||||||
logname = skip_string(user,1);
|
logname = skip_string(user,1);
|
||||||
reply_code = 6;
|
reply_code = 6;
|
||||||
strcpy(reply_name, my_name);
|
strcpy(reply_name,myname);
|
||||||
strupper(reply_name);
|
strupper(reply_name);
|
||||||
add_slashes = True;
|
add_slashes = True;
|
||||||
DEBUG(3,("Domain login request from %s(%s) user=%s\n",
|
DEBUG(3,("Domain login request from %s(%s) user=%s\n",
|
||||||
@ -90,7 +87,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
reply_code = 7;
|
reply_code = 7;
|
||||||
strcpy(reply_name,lp_domain_controller());
|
strcpy(reply_name,lp_domain_controller());
|
||||||
if (!*reply_name) {
|
if (!*reply_name) {
|
||||||
strcpy(reply_name,my_name);
|
strcpy(reply_name,myname);
|
||||||
reply_code = 0xC;
|
reply_code = 0xC;
|
||||||
}
|
}
|
||||||
strupper(reply_name);
|
strupper(reply_name);
|
||||||
@ -124,8 +121,8 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
PutUniCode(q,reply_name);
|
PutUniCode(q,reply_name);
|
||||||
q += 2*(strlen(reply_name) + 1);
|
q += 2*(strlen(reply_name) + 1);
|
||||||
|
|
||||||
PutUniCode(q,work->work_group);
|
PutUniCode(q,lp_workgroup());
|
||||||
q += 2*(strlen(work->work_group) + 1);
|
q += 2*(strlen(lp_workgroup()) + 1);
|
||||||
|
|
||||||
SIVAL(q,0,1);
|
SIVAL(q,0,1);
|
||||||
q += 4;
|
q += 4;
|
||||||
@ -137,6 +134,6 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
q += 2;
|
q += 2;
|
||||||
|
|
||||||
send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
|
send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
|
||||||
my_name,&dgram->source_name.name[0],0x20,0,p->ip,
|
myname,&dgram->source_name.name[0],0x20,0,p->ip,
|
||||||
*iface_ip(p->ip));
|
*iface_ip(p->ip));
|
||||||
}
|
}
|
||||||
|
@ -38,92 +38,7 @@ BOOL CanRecurse = True;
|
|||||||
extern pstring scope;
|
extern pstring scope;
|
||||||
extern struct in_addr ipgrp;
|
extern struct in_addr ipgrp;
|
||||||
|
|
||||||
extern uint16 name_trn_id;
|
static uint16 name_trn_id=0;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
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.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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -134,69 +49,79 @@ void debug_browse_data(char *outbuf, int len)
|
|||||||
int i,j;
|
int i,j;
|
||||||
for (i = 0; i < len; i+= 16)
|
for (i = 0; i < len; i+= 16)
|
||||||
{
|
{
|
||||||
DEBUG(4, ("%3x char ", i));
|
DEBUG(4, ("%3x char ", i));
|
||||||
|
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
{
|
{
|
||||||
unsigned char x = outbuf[i+j];
|
unsigned char x = outbuf[i+j];
|
||||||
if (x < 32 || x > 127) x = '.';
|
if (x < 32 || x > 127) x = '.';
|
||||||
|
|
||||||
if (i+j >= len) break;
|
if (i+j >= len) break;
|
||||||
DEBUG(4, ("%c", x));
|
DEBUG(4, ("%c", x));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, (" hex ", i));
|
DEBUG(4, (" hex ", i));
|
||||||
|
|
||||||
for (j = 0; j < 16; j++)
|
for (j = 0; j < 16; j++)
|
||||||
{
|
{
|
||||||
if (i+j >= len) break;
|
if (i+j >= len) break;
|
||||||
DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
|
DEBUG(4, (" %02x", outbuf[i+j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, ("\n"));
|
DEBUG(4, ("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
updates the unique transaction identifier
|
||||||
|
**************************************************************************/
|
||||||
|
static 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
initiate a netbios packet
|
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.
|
|
||||||
|
|
||||||
netbios packets sent to an ip of zero are dealt with immediately by calling
|
|
||||||
process_nmb(), in order to allow, for example, querying of samba's WINS
|
|
||||||
records. at first, this seems like a really dumb thing to do. but then
|
|
||||||
again, the packet_struct created contains _exactly_ the information
|
|
||||||
required. the alternative is to take packet_struct out of the loop,
|
|
||||||
which is a fairly messy operation.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
BOOL initiate_netbios_packet(uint16 id,
|
void initiate_netbios_packet(uint16 *id,
|
||||||
int fd,int quest_type,char *name,int name_type,
|
int fd,int quest_type,char *name,int name_type,
|
||||||
int nb_flags,BOOL bcast,BOOL recurse,
|
int nb_flags,BOOL bcast,BOOL recurse,
|
||||||
struct in_addr to_ip)
|
struct in_addr to_ip)
|
||||||
{
|
{
|
||||||
struct packet_struct p;
|
struct packet_struct p;
|
||||||
struct nmb_packet *nmb = &p.packet.nmb;
|
struct nmb_packet *nmb = &p.packet.nmb;
|
||||||
struct res_rec additional_rec;
|
struct res_rec additional_rec;
|
||||||
char *pkt_type = "unknown";
|
char *packet_type = "unknown";
|
||||||
int opcode = -1;
|
int opcode = -1;
|
||||||
|
|
||||||
if (quest_type == NMB_STATUS) { pkt_type = "nmb_status"; opcode = 0; }
|
if (!id) return;
|
||||||
if (quest_type == NMB_QUERY ) { pkt_type = "nmb_query"; opcode = 0; }
|
|
||||||
if (quest_type == NMB_REG ) { pkt_type = "nmb_reg"; opcode = 5; }
|
if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
|
||||||
if (quest_type == NMB_REG_REFRESH) { pkt_type="nmb_reg_refresh"; opcode=9; }
|
if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
|
||||||
if (quest_type == NMB_REL ) { pkt_type = "nmb_rel"; opcode = 6; }
|
if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
|
||||||
|
if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
|
||||||
|
if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
|
||||||
|
|
||||||
DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
|
DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
|
||||||
pkt_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 False;
|
if (opcode == -1) return;
|
||||||
|
|
||||||
bzero((char *)&p,sizeof(p));
|
bzero((char *)&p,sizeof(p));
|
||||||
|
|
||||||
nmb->header.name_trn_id = id;
|
if (*id == 0xffff) {
|
||||||
|
update_name_trn_id();
|
||||||
|
*id = name_trn_id; /* allow resending with same id */
|
||||||
|
}
|
||||||
|
|
||||||
|
nmb->header.name_trn_id = *id;
|
||||||
nmb->header.opcode = opcode;
|
nmb->header.opcode = opcode;
|
||||||
nmb->header.response = False;
|
nmb->header.response = False;
|
||||||
|
|
||||||
@ -237,7 +162,7 @@ BOOL initiate_netbios_packet(uint16 id,
|
|||||||
nmb->additional->rdlength = 6;
|
nmb->additional->rdlength = 6;
|
||||||
nmb->additional->rdata[0] = nb_flags;
|
nmb->additional->rdata[0] = nb_flags;
|
||||||
putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
|
putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
p.ip = to_ip;
|
p.ip = to_ip;
|
||||||
p.port = NMB_PORT;
|
p.port = NMB_PORT;
|
||||||
@ -245,21 +170,12 @@ BOOL initiate_netbios_packet(uint16 id,
|
|||||||
p.timestamp = time(NULL);
|
p.timestamp = time(NULL);
|
||||||
p.packet_type = NMB_PACKET;
|
p.packet_type = NMB_PACKET;
|
||||||
|
|
||||||
if (zero_ip(to_ip)) /* samba's own ip */
|
if (!send_packet(&p)) {
|
||||||
{
|
DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
|
||||||
DEBUG(4,("process packet ourselves\n"));
|
*id = 0xffff;
|
||||||
/* respond internally to the packet. */
|
|
||||||
process_nmb(&p);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return;
|
||||||
if (!send_packet(&p)) {
|
|
||||||
DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,9 +183,9 @@ BOOL initiate_netbios_packet(uint16 id,
|
|||||||
reply to a netbios name packet
|
reply to a netbios name packet
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
||||||
int rcode, int rcv_code, int opcode, BOOL recurse,
|
int rcode, int rcv_code, int opcode, BOOL recurse,
|
||||||
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
||||||
char *data,int len)
|
char *data,int len)
|
||||||
{
|
{
|
||||||
struct packet_struct p;
|
struct packet_struct p;
|
||||||
struct nmb_packet *nmb = &p.packet.nmb;
|
struct nmb_packet *nmb = &p.packet.nmb;
|
||||||
@ -282,31 +198,31 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
|||||||
switch (rcv_code)
|
switch (rcv_code)
|
||||||
{
|
{
|
||||||
case NMB_STATUS:
|
case NMB_STATUS:
|
||||||
{
|
{
|
||||||
packet_type = "nmb_status";
|
packet_type = "nmb_status";
|
||||||
recursion_desired = True;
|
recursion_desired = True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NMB_QUERY:
|
case NMB_QUERY:
|
||||||
{
|
{
|
||||||
packet_type = "nmb_query";
|
packet_type = "nmb_query";
|
||||||
recursion_desired = True;
|
recursion_desired = True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NMB_REG:
|
case NMB_REG:
|
||||||
{
|
{
|
||||||
packet_type = "nmb_reg";
|
packet_type = "nmb_reg";
|
||||||
recursion_desired = True;
|
recursion_desired = True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NMB_REL:
|
case NMB_REL:
|
||||||
{
|
{
|
||||||
packet_type = "nmb_rel";
|
packet_type = "nmb_rel";
|
||||||
recursion_desired = False;
|
recursion_desired = False;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NMB_WAIT_ACK:
|
case NMB_WAIT_ACK:
|
||||||
{
|
{
|
||||||
packet_type = "nmb_wack";
|
packet_type = "nmb_wack";
|
||||||
recursion_desired = False;
|
recursion_desired = False;
|
||||||
break;
|
break;
|
||||||
@ -314,14 +230,14 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DEBUG(1,("replying netbios packet: %s %s\n",
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4,("replying netbios packet: %s %s\n",
|
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.name_trn_id = trn_id;
|
||||||
nmb->header.opcode = opcode;
|
nmb->header.opcode = opcode;
|
||||||
@ -349,25 +265,16 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
|||||||
nmb->answers->ttl = ttl;
|
nmb->answers->ttl = ttl;
|
||||||
|
|
||||||
if (data && len)
|
if (data && len)
|
||||||
{
|
{
|
||||||
nmb->answers->rdlength = len;
|
nmb->answers->rdlength = len;
|
||||||
memcpy(nmb->answers->rdata, data, len);
|
memcpy(nmb->answers->rdata, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.packet_type = NMB_PACKET;
|
p.packet_type = NMB_PACKET;
|
||||||
|
|
||||||
debug_nmb_packet(&p);
|
debug_nmb_packet(&p);
|
||||||
|
|
||||||
if (zero_ip(p.ip)) /* samba's own ip */
|
send_packet(&p);
|
||||||
{
|
|
||||||
DEBUG(4,("process response packet ourselves\n"));
|
|
||||||
/* respond internally to the packet. */
|
|
||||||
process_nmb(&p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
send_packet(&p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -445,7 +352,7 @@ static void process_dgram(struct packet_struct *p)
|
|||||||
|
|
||||||
buf = &dgram->data[0];
|
buf = &dgram->data[0];
|
||||||
buf -= 4; /* XXXX for the pseudo tcp length -
|
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;
|
if (CVAL(buf,smb_com) != SMBtrans) return;
|
||||||
|
|
||||||
@ -453,8 +360,8 @@ static void process_dgram(struct packet_struct *p)
|
|||||||
buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
|
buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
|
||||||
|
|
||||||
DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
|
DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
|
||||||
namestr(&dgram->source_name),namestr(&dgram->dest_name),
|
namestr(&dgram->source_name),namestr(&dgram->dest_name),
|
||||||
smb_buf(buf),CVAL(buf2,0),len));
|
smb_buf(buf),CVAL(buf2,0),len));
|
||||||
|
|
||||||
|
|
||||||
if (len <= 0) return;
|
if (len <= 0) return;
|
||||||
@ -472,6 +379,83 @@ 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
|
run elements off the packet queue till its empty
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@ -482,15 +466,15 @@ void run_packet_queue()
|
|||||||
while ((p=packet_queue))
|
while ((p=packet_queue))
|
||||||
{
|
{
|
||||||
switch (p->packet_type)
|
switch (p->packet_type)
|
||||||
{
|
{
|
||||||
case NMB_PACKET:
|
case NMB_PACKET:
|
||||||
process_nmb(p);
|
process_nmb(p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DGRAM_PACKET:
|
case DGRAM_PACKET:
|
||||||
process_dgram(p);
|
process_dgram(p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_queue = packet_queue->next;
|
packet_queue = packet_queue->next;
|
||||||
if (packet_queue) packet_queue->prev = NULL;
|
if (packet_queue) packet_queue->prev = NULL;
|
||||||
@ -566,8 +550,8 @@ try_again:
|
|||||||
wrong things to do! I should send to the requestors port. XXX
|
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,
|
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||||
char *dstname,int src_type,int dest_type,
|
char *dstname,int src_type,int dest_type,
|
||||||
struct in_addr dest_ip,struct in_addr src_ip)
|
struct in_addr dest_ip,struct in_addr src_ip)
|
||||||
{
|
{
|
||||||
struct packet_struct p;
|
struct packet_struct p;
|
||||||
struct dgram_packet *dgram = &p.packet.dgram;
|
struct dgram_packet *dgram = &p.packet.dgram;
|
||||||
|
@ -35,30 +35,15 @@ extern pstring scope;
|
|||||||
extern struct in_addr ipzero;
|
extern struct in_addr ipzero;
|
||||||
extern struct in_addr ipgrp;
|
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
|
deals with an entry before it dies
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void dead_netbios_entry(struct subnet_record *d,
|
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",
|
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);
|
debug_state_type(n->state);
|
||||||
|
|
||||||
@ -66,118 +51,118 @@ static void dead_netbios_entry(struct subnet_record *d,
|
|||||||
{
|
{
|
||||||
case NAME_QUERY_CONFIRM:
|
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
|
/* oops. name query had no response. check that the name is
|
||||||
unique and then remove it from our WINS database */
|
unique and then remove it from our WINS database */
|
||||||
|
|
||||||
/* IMPORTANT: see query_refresh_names() */
|
/* IMPORTANT: see query_refresh_names() */
|
||||||
|
|
||||||
if ((!NAME_GROUP(n->reply.nb_flags)))
|
if ((!NAME_GROUP(n->nb_flags)))
|
||||||
{
|
{
|
||||||
struct subnet_record *d1 = find_subnet(ipgrp);
|
struct subnet_record *d1 = find_subnet(ipgrp);
|
||||||
if (d1)
|
if (d1)
|
||||||
{
|
{
|
||||||
/* remove the name that had been registered with us,
|
/* remove the name that had been registered with us,
|
||||||
and we're now getting no response when challenging.
|
and we're now getting no response when challenging.
|
||||||
see rfc1001.txt 15.5.2
|
see rfc1001.txt 15.5.2
|
||||||
*/
|
*/
|
||||||
remove_netbios_name(d1, n->name.name, n->name.name_type,
|
remove_netbios_name(d1, n->name.name, n->name.name_type,
|
||||||
REGISTER, n->send_ip);
|
REGISTER, n->send_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_QUERY_MST_CHK:
|
case NAME_QUERY_MST_CHK:
|
||||||
{
|
{
|
||||||
/* if no response received, the master browser must have gone
|
/* if no response received, the master browser must have gone
|
||||||
down on that subnet, without telling anyone. */
|
down on that subnet, without telling anyone. */
|
||||||
|
|
||||||
/* IMPORTANT: see response_netbios_packet() */
|
/* IMPORTANT: see response_netbios_packet() */
|
||||||
|
|
||||||
if (n->num_msgs == 0)
|
if (n->num_msgs == 0)
|
||||||
browser_gone(n->name.name, n->send_ip);
|
browser_gone(n->name.name, n->send_ip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_RELEASE:
|
case NAME_RELEASE:
|
||||||
{
|
{
|
||||||
/* if no response received, it must be OK for us to release the
|
/* if no response received, it must be OK for us to release the
|
||||||
name. nobody objected (including a potentially dead or deaf
|
name. nobody objected (including a potentially dead or deaf
|
||||||
WINS server) */
|
WINS server) */
|
||||||
|
|
||||||
/* IMPORTANT: see response_name_release() */
|
/* IMPORTANT: see response_name_release() */
|
||||||
|
|
||||||
if (ismyip(n->send_ip))
|
if (ismyip(n->send_ip))
|
||||||
{
|
{
|
||||||
name_unregister_work(d,n->name.name,n->name.name_type);
|
name_unregister_work(d,n->name.name,n->name.name_type);
|
||||||
}
|
}
|
||||||
if (!n->bcast)
|
if (!n->bcast)
|
||||||
{
|
{
|
||||||
DEBUG(0,("WINS server did not respond to name release!\n"));
|
DEBUG(0,("WINS server did not respond to name release!\n"));
|
||||||
/* XXXX whoops. we have problems. must deal with this */
|
/* XXXX whoops. we have problems. must deal with this */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_REGISTER_CHALLENGE:
|
case NAME_REGISTER_CHALLENGE:
|
||||||
{
|
{
|
||||||
/* name challenge: no reply. we can reply to the person that
|
/* name challenge: no reply. we can reply to the person that
|
||||||
wanted the unique name and tell them that they can have it
|
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,
|
add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
|
||||||
n->reply.nb_flags, GET_TTL(0),
|
n->nb_flags, GET_TTL(0),
|
||||||
n->reply.ip, False, n->reply.ip);
|
n->reply_to_ip, False, n->reply_to_ip);
|
||||||
|
|
||||||
if (!n->bcast)
|
if (!n->bcast)
|
||||||
{
|
{
|
||||||
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 */
|
/* XXXX whoops. we have problems. must deal with this */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_REGISTER:
|
case NAME_REGISTER:
|
||||||
{
|
{
|
||||||
/* if no response received, and we are using a broadcast registration
|
/* if no response received, and we are using a broadcast registration
|
||||||
method, it must be OK for us to register the name: nobody objected
|
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
|
on that subnet. if we are using a WINS server, then the WINS
|
||||||
server must be dead or deaf.
|
server must be dead or deaf.
|
||||||
*/
|
*/
|
||||||
if (n->bcast)
|
if (n->bcast)
|
||||||
{
|
{
|
||||||
/* broadcast method: implicit acceptance of the name registration
|
/* broadcast method: implicit acceptance of the name registration
|
||||||
by not receiving any objections. */
|
by not receiving any objections. */
|
||||||
|
|
||||||
/* IMPORTANT: see response_name_reg() */
|
/* IMPORTANT: see response_name_reg() */
|
||||||
|
|
||||||
name_register_work(d,n->token,n->name.name,n->name.name_type,
|
name_register_work(d,n->name.name,n->name.name_type,
|
||||||
n->source, &n->reply, n->ttl, n->reply.ip, n->bcast);
|
n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* received no response. rfc1001.txt states that after retrying,
|
/* received no response. rfc1001.txt states that after retrying,
|
||||||
we should assume the WINS server is dead, and fall back to
|
we should assume the WINS server is dead, and fall back to
|
||||||
broadcasting (see bits about M nodes: can't find any right
|
broadcasting (see bits about M nodes: can't find any right
|
||||||
now) */
|
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 */
|
/* XXXX whoops. we have problems. must deal with this */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* nothing to do but delete the dead expected-response structure */
|
/* nothing to do but delete the dead expected-response structure */
|
||||||
/* this is normal. */
|
/* this is normal. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,52 +184,81 @@ void expire_netbios_response_entries()
|
|||||||
|
|
||||||
for (n = d->responselist; n; n = nextn)
|
for (n = d->responselist; n; n = nextn)
|
||||||
{
|
{
|
||||||
nextn = n->next;
|
nextn = n->next;
|
||||||
|
|
||||||
if (n->repeat_time <= time(NULL))
|
if (n->repeat_time <= time(NULL))
|
||||||
{
|
{
|
||||||
if (n->repeat_count > 0)
|
if (n->repeat_count > 0)
|
||||||
{
|
{
|
||||||
/* resend the entry */
|
/* resend the entry */
|
||||||
initiate_netbios_packet(n->response_id, n->fd, n->quest_type,
|
initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
|
||||||
n->name.name, n->name.name_type,
|
n->name.name, n->name.name_type,
|
||||||
n->reply.nb_flags, n->bcast, n->recurse, n->send_ip);
|
n->nb_flags, n->bcast, n->recurse, n->send_ip);
|
||||||
|
|
||||||
n->repeat_time += n->repeat_interval; /* XXXX ms needed */
|
n->repeat_time += n->repeat_interval; /* XXXX ms needed */
|
||||||
n->repeat_count--;
|
n->repeat_count--;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(4,("timeout response %d for %s %s\n",
|
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)));
|
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 */
|
remove_response_record(d,n); /* remove the non-response */
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
wrapper function to override a broadcast message and send it to the WINS
|
||||||
|
name server instead, if it exists. if wins is false, and there has been no
|
||||||
|
WINS server specified, the packet will NOT be sent.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void queue_netbios_pkt_wins(struct subnet_record *d,
|
struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
|
||||||
int fd,int quest_type,enum state_type state,
|
int fd,int quest_type,enum state_type state,
|
||||||
int token, char *name,int name_type,
|
char *name,int name_type,int nb_flags, time_t ttl,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
int server_type, char *my_name, char *my_comment,
|
||||||
int server_type, char *my_name, char *my_comment,
|
BOOL bcast,BOOL recurse,
|
||||||
BOOL bcast,BOOL recurse,
|
struct in_addr send_ip, struct in_addr reply_to_ip)
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip)
|
|
||||||
{
|
{
|
||||||
queue_netbios_packet(d,fd, quest_type, state,
|
/* XXXX note: please see rfc1001.txt section 10 for details on this
|
||||||
token, name, name_type, source, nb_flags, ttl,
|
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()))
|
||||||
|
{
|
||||||
|
/* 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)) return NULL;
|
||||||
|
|
||||||
|
return queue_netbios_packet(d,fd, quest_type, state,
|
||||||
|
name, name_type, nb_flags, ttl,
|
||||||
server_type,my_name,my_comment,
|
server_type,my_name,my_comment,
|
||||||
bcast, recurse, send_ip, reply_to_ip);
|
bcast, recurse, send_ip, reply_to_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -253,83 +267,36 @@ void queue_netbios_pkt_wins(struct subnet_record *d,
|
|||||||
this is intended to be used (not exclusively) for broadcasting to
|
this is intended to be used (not exclusively) for broadcasting to
|
||||||
master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
|
master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
|
||||||
complete lists across a wide area network
|
complete lists across a wide area network
|
||||||
|
|
||||||
a broadcast message will be over-ridden if the packet it sent to an
|
|
||||||
ip of zero, and the packet will be sent to the WINS name server instead,
|
|
||||||
if it exists. if samba is configured to be a WINS server, then the
|
|
||||||
packet will be dealt with _as if_ it had been sent on the network,
|
|
||||||
but in fact the function process_nmb() is called.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void queue_netbios_packet(struct subnet_record *d,
|
struct response_record *queue_netbios_packet(struct subnet_record *d,
|
||||||
int fd,int quest_type,enum state_type state,
|
int fd,int quest_type,enum state_type state,char *name,
|
||||||
int token, char *name, int name_type,
|
int name_type,int nb_flags, time_t ttl,
|
||||||
enum name_source source, int nb_flags, time_t ttl,
|
int server_type, char *my_name, char *my_comment,
|
||||||
int server_type, char *my_name, char *my_comment,
|
BOOL bcast,BOOL recurse,
|
||||||
BOOL bcast,BOOL recurse,
|
struct in_addr send_ip, struct in_addr reply_to_ip)
|
||||||
struct in_addr send_ip, struct in_addr reply_to_ip)
|
|
||||||
{
|
{
|
||||||
|
struct in_addr wins_ip = ipgrp;
|
||||||
struct response_record *n;
|
struct response_record *n;
|
||||||
|
uint16 id = 0xffff;
|
||||||
|
|
||||||
/* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
|
/* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
|
||||||
if (ip_equal(send_ip, ipgrp)) return;
|
if (ip_equal(wins_ip, send_ip)) return NULL;
|
||||||
|
|
||||||
/* XXXX note: please see rfc1001.txt section 10 for details on this
|
initiate_netbios_packet(&id, fd, quest_type, name, name_type,
|
||||||
function: it is currently inappropriate to use this - it will do
|
nb_flags, bcast, recurse, send_ip);
|
||||||
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 (id == 0xffff) {
|
||||||
{
|
DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
|
||||||
/* samba is not a WINS server, and we are using a WINS server */
|
return NULL;
|
||||||
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))
|
if ((n = make_response_queue_record(state,id,fd,
|
||||||
{
|
quest_type,name,name_type,nb_flags,ttl,
|
||||||
/* doing a netbios query to samba as a WINS server, internally */
|
server_type,my_name, my_comment,
|
||||||
if (lp_wins_support()) /* samba is a WINS server */
|
bcast,recurse,send_ip,reply_to_ip)))
|
||||||
{
|
{
|
||||||
DEBUG(4,("queue netbios packet with ourselves...\n"));
|
add_response_record(d,n);
|
||||||
bcast = False;
|
return n;
|
||||||
}
|
}
|
||||||
else
|
return NULL;
|
||||||
{
|
|
||||||
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, source, nb_flags, ttl,
|
|
||||||
server_type, my_name, my_comment,
|
|
||||||
bcast, recurse, send_ip, reply_to_ip)))
|
|
||||||
{
|
|
||||||
add_response_record(d,n);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)));
|
|
||||||
remove_response_record(d, n);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
XXXX at present, the name is removed _even_ if a WINS server says keep it.
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void remove_name_entry(struct subnet_record *d, int token, char *name,int type)
|
void remove_name_entry(struct subnet_record *d, char *name,int type)
|
||||||
{
|
{
|
||||||
/* XXXX BUG: if samba is offering WINS support, it should still broadcast
|
/* XXXX BUG: if samba is offering WINS support, it should still broadcast
|
||||||
a de-registration packet to the local subnet before removing the
|
a de-registration packet to the local subnet before removing the
|
||||||
@ -80,18 +80,17 @@ void remove_name_entry(struct subnet_record *d, int token, char *name,int type)
|
|||||||
don't really own */
|
don't really own */
|
||||||
remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
|
remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
|
||||||
|
|
||||||
if (ip_equal(d->bcast_ip, ipgrp))
|
if (ip_equal(d->bcast_ip, ipgrp)) {
|
||||||
{
|
if (!lp_wins_support()) {
|
||||||
/* use WINS. this function can now be used to _either_
|
/* not a WINS server: we have to release them on the network */
|
||||||
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,
|
queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
|
||||||
token, name, type, SELF, 0, 0,0,NULL,NULL,
|
name, type, 0, 0,0,NULL,NULL,
|
||||||
False, True, ipzero, ipzero);
|
False, True, ipzero, ipzero);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* local interface: release them on the network */
|
/* local interface: release them on the network */
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
|
queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
|
||||||
token, name, type, SELF, 0, 0,0,NULL,NULL,
|
name, type, 0, 0,0,NULL,NULL,
|
||||||
True, True, d->bcast_ip, d->bcast_ip);
|
True, True, d->bcast_ip, d->bcast_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,8 +103,7 @@ void remove_name_entry(struct subnet_record *d, int token, char *name,int type)
|
|||||||
it's just a matter of when this will be done (e.g after a time-out).
|
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, int token,
|
void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
|
||||||
char *name,int type,int nb_flags)
|
|
||||||
{
|
{
|
||||||
BOOL re_reg = False;
|
BOOL re_reg = False;
|
||||||
struct nmb_name n;
|
struct nmb_name n;
|
||||||
@ -117,7 +115,7 @@ void add_my_name_entry(struct subnet_record *d, int token,
|
|||||||
|
|
||||||
make_nmb_name(&n, name, type, scope);
|
make_nmb_name(&n, name, type, scope);
|
||||||
if (find_name(d->namelist, &n, SELF))
|
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
|
/* 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
|
name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
|
||||||
@ -125,7 +123,6 @@ void add_my_name_entry(struct subnet_record *d, int token,
|
|||||||
|
|
||||||
if (ip_equal(d->bcast_ip, ipgrp))
|
if (ip_equal(d->bcast_ip, ipgrp))
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (lp_wins_support())
|
if (lp_wins_support())
|
||||||
{
|
{
|
||||||
/* we are a WINS server. */
|
/* we are a WINS server. */
|
||||||
@ -134,38 +131,26 @@ void add_my_name_entry(struct subnet_record *d, int token,
|
|||||||
actually be true
|
actually be true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct nmb_ip data;
|
|
||||||
|
|
||||||
data.nb_flags = nb_flags;
|
|
||||||
putip(&data.ip, ipzero);
|
|
||||||
|
|
||||||
DEBUG(4,("samba as WINS server adding: "));
|
DEBUG(4,("samba as WINS server adding: "));
|
||||||
/* this will call add_netbios_entry() */
|
/* this will call add_netbios_entry() */
|
||||||
|
name_register_work(d, name, type, nb_flags,0, ipzero, False);
|
||||||
name_register_work(d,token,name,type,SELF,&data,GET_TTL(0),ipzero,False);
|
|
||||||
}
|
}
|
||||||
else
|
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. */
|
/* a time-to-live allows us to refresh this name with the WINS server. */
|
||||||
queue_netbios_pkt_wins(d,ClientNMB,
|
queue_netbios_pkt_wins(d,ClientNMB,
|
||||||
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
||||||
token, name, type, SELF, nb_flags, GET_TTL(0),0,NULL,NULL,
|
name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
|
||||||
False, True, ipzero, ipzero);
|
False, True, ipzero, ipzero);
|
||||||
#if 0
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* broadcast the packet, but it comes from ipzero */
|
/* broadcast the packet, but it comes from ipzero */
|
||||||
queue_netbios_packet(d,ClientNMB,
|
queue_netbios_packet(d,ClientNMB,
|
||||||
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
||||||
token, name, type, SELF, nb_flags, GET_TTL(0),0,NULL,NULL,
|
name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
|
||||||
True, True, d->bcast_ip, ipzero);
|
True, True, d->bcast_ip, ipzero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +161,6 @@ void add_my_name_entry(struct subnet_record *d, int token,
|
|||||||
void add_my_names(void)
|
void add_my_names(void)
|
||||||
{
|
{
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
int token;
|
|
||||||
|
|
||||||
/* each subnet entry, including WINS pseudo-subnet, has SELF names */
|
/* each subnet entry, including WINS pseudo-subnet, has SELF names */
|
||||||
|
|
||||||
/* XXXX if there was a transport layer added to samba (ipx/spx etc) then
|
/* XXXX if there was a transport layer added to samba (ipx/spx etc) then
|
||||||
@ -186,56 +169,32 @@ void add_my_names(void)
|
|||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
BOOL wins = ip_equal(d->bcast_ip,ipgrp);
|
BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
|
||||||
|
|
||||||
for (token = 0; token < get_num_workgroups(); token++)
|
|
||||||
{
|
|
||||||
char *my_name = conf_browsing_alias(token);
|
|
||||||
char *wg_name = conf_workgroup_name(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_name && conf_should_domain_logon(token))
|
|
||||||
{
|
|
||||||
/* the 0x1c is to do with domain logons */
|
|
||||||
add_my_name_entry(d, token, wg_name,0x1c,nb_type|NB_ACTIVE|NB_GROUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/* these names are added permanently (ttl of zero) and will NOT be
|
/* these names are added permanently (ttl of zero) and will NOT be
|
||||||
refreshed with the WINS server */
|
refreshed with the WINS server */
|
||||||
|
|
||||||
add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
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__",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);
|
add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (lp_domain_master() && (d = find_subnet(ipgrp)))
|
||||||
/* check becoming a domain master under all browser aliases */
|
|
||||||
|
|
||||||
if ((d = find_subnet(ipgrp)))
|
|
||||||
{
|
{
|
||||||
for (token = 0; token < get_num_workgroups(); token++)
|
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
|
||||||
|
if (work && work->state == MST_NONE)
|
||||||
{
|
{
|
||||||
if (conf_should_domain_master(token))
|
work->state = MST_DOMAIN_NONE;
|
||||||
{
|
become_master(d, work);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,24 +205,52 @@ void add_my_names(void)
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void remove_my_names()
|
void remove_my_names()
|
||||||
{
|
{
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
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;
|
||||||
|
|
||||||
|
for (d = subnetlist; d; d = d->next)
|
||||||
|
{
|
||||||
|
struct name_record *n;
|
||||||
|
|
||||||
|
for (n = d->namelist; n; n = n->next)
|
||||||
{
|
{
|
||||||
struct name_record *n, *next;
|
/* each SELF name has an individual time to be refreshed */
|
||||||
|
if (n->source == SELF && n->refresh_time < time(NULL) &&
|
||||||
for (n = d->namelist; n; n = next)
|
n->death_time != 0)
|
||||||
{
|
{
|
||||||
next = n->next;
|
add_my_name_entry(d,n->name.name,n->name.name_type,
|
||||||
if (n->source == SELF)
|
n->ip_flgs[0].nb_flags);
|
||||||
{
|
/* they get a new lease on life :-) */
|
||||||
/* get all SELF names removed from the WINS server's database */
|
n->death_time += GET_TTL(0);
|
||||||
/* XXXX note: problem occurs if this removes the wrong one! */
|
n->refresh_time += GET_TTL(0);
|
||||||
|
}
|
||||||
remove_name_entry(d, -1, n->name.name, n->name.name_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,55 +265,55 @@ void remove_my_names()
|
|||||||
******************************************************************/
|
******************************************************************/
|
||||||
void query_refresh_names(void)
|
void query_refresh_names(void)
|
||||||
{
|
{
|
||||||
struct name_record *n;
|
struct name_record *n;
|
||||||
struct subnet_record *d = find_subnet(ipgrp);
|
struct subnet_record *d = find_subnet(ipgrp);
|
||||||
|
|
||||||
static time_t lasttime = 0;
|
static time_t lasttime = 0;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int name_refresh_time = NAME_POLL_REFRESH_TIME;
|
int name_refresh_time = NAME_POLL_REFRESH_TIME;
|
||||||
int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
|
int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
|
||||||
if (max_count > 10) max_count = 10;
|
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 (!lasttime) lasttime = t;
|
||||||
if (t - lasttime < NAME_POLL_INTERVAL) return;
|
if (t - lasttime < NAME_POLL_INTERVAL) return;
|
||||||
|
|
||||||
lasttime = time(NULL);
|
lasttime = time(NULL);
|
||||||
|
|
||||||
for (n = d->namelist; n; n = n->next)
|
for (n = d->namelist; n; n = n->next)
|
||||||
{
|
{
|
||||||
/* only do unique, registered names. */
|
/* only do unique, registered names */
|
||||||
|
|
||||||
if (n->source != REGISTER) continue;
|
if (n->source != REGISTER) continue;
|
||||||
if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
|
if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
|
||||||
|
|
||||||
if (n->refresh_time < t)
|
if (n->refresh_time < t)
|
||||||
{
|
{
|
||||||
DEBUG(3,("Polling name %s\n", namestr(&n->name)));
|
DEBUG(3,("Polling name %s\n", namestr(&n->name)));
|
||||||
|
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
|
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
|
||||||
-1,n->name.name, n->name.name_type,
|
n->name.name, n->name.name_type,
|
||||||
n->source,0,0,0,NULL,NULL,
|
0,0,0,NULL,NULL,
|
||||||
False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip);
|
False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count >= max_count)
|
if (count >= max_count)
|
||||||
{
|
{
|
||||||
/* don't do too many of these at once, but do enough to
|
/* don't do too many of these at once, but do enough to
|
||||||
cover everyone in the list */
|
cover everyone in the list */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this name will be checked on again, if it's not removed */
|
/* this name will be checked on again, if it's not removed */
|
||||||
n->refresh_time += name_refresh_time;
|
n->refresh_time += name_refresh_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +294,8 @@ void reply_name_reg(struct packet_struct *p)
|
|||||||
/* initiate some enquiries to the current owner. */
|
/* initiate some enquiries to the current owner. */
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
||||||
NAME_REGISTER_CHALLENGE,
|
NAME_REGISTER_CHALLENGE,
|
||||||
-1,reply_name->name,reply_name->name_type,
|
reply_name->name,reply_name->name_type,
|
||||||
n->source, nb_flags,0,0,NULL,NULL,
|
nb_flags,0,0,NULL,NULL,
|
||||||
False, False, n->ip_flgs[0].ip, p->ip);
|
False, False, n->ip_flgs[0].ip, p->ip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -46,29 +46,38 @@ extern struct in_addr ipzero;
|
|||||||
response for a reg release received. samba has asked a WINS server if it
|
response for a reg release received. samba has asked a WINS server if it
|
||||||
could release a name.
|
could release a name.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void response_name_release(struct nmb_ip *data, struct nmb_name *name,
|
static void response_name_release(struct subnet_record *d,
|
||||||
struct subnet_record *d)
|
struct packet_struct *p)
|
||||||
{
|
{
|
||||||
|
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"));
|
DEBUG(4,("response name release received\n"));
|
||||||
|
|
||||||
if (data)
|
if (nmb->header.rcode == 0 && nmb->answers->rdata)
|
||||||
{
|
{
|
||||||
/* IMPORTANT: see expire_netbios_response_entries() */
|
/* 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 */
|
/* NOTE: we only release our own names at present */
|
||||||
if (ismyip(data->ip))
|
if (ismyip(found_ip))
|
||||||
{
|
{
|
||||||
name_unregister_work(d, name->name, name->name_type);
|
name_unregister_work(d,name,type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(2,("name release for different ip! %s %s\n",
|
DEBUG(2,("name release for different ip! %s %s\n",
|
||||||
inet_ntoa(data->ip),namestr(name)));
|
inet_ntoa(found_ip),
|
||||||
|
namestr(&nmb->question.question_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(2,("name release for %s rejected!\n",namestr(name)));
|
DEBUG(2,("name release for %s rejected!\n",
|
||||||
|
namestr(&nmb->question.question_name)));
|
||||||
|
|
||||||
/* XXXX PANIC! what to do if it's one of samba's own names? */
|
/* XXXX PANIC! what to do if it's one of samba's own names? */
|
||||||
|
|
||||||
@ -82,25 +91,34 @@ static void response_name_release(struct nmb_ip *data, struct nmb_name *name,
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
response for a reg request received
|
response for a reg request received
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void response_name_reg(struct nmb_ip *data, struct nmb_name *name,
|
static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
|
||||||
time_t ttl, BOOL bcast, struct in_addr source_ip,
|
|
||||||
struct subnet_record *d, enum name_source source, 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"));
|
DEBUG(4,("response name registration received!\n"));
|
||||||
|
|
||||||
if (data)
|
if (nmb->header.rcode == 0 && nmb->answers->rdata)
|
||||||
{
|
{
|
||||||
/* IMPORTANT: see expire_netbios_response_entries() */
|
/* IMPORTANT: see expire_netbios_response_entries() */
|
||||||
|
|
||||||
name_register_work(d, token, name->name,name->name_type,
|
int nb_flags = nmb->answers->rdata[0];
|
||||||
source, data, ttl, source_ip, bcast);
|
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);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(1,("name registration for %s rejected!\n", namestr(name)));
|
DEBUG(1,("name registration for %s rejected!\n",
|
||||||
|
namestr(&nmb->question.question_name)));
|
||||||
|
|
||||||
/* oh dear. we have problems. possibly unbecome a master browser. */
|
/* oh dear. we have problems. possibly unbecome a master browser. */
|
||||||
name_unregister_work(d,name->name,name->name_type);
|
name_unregister_work(d,name,type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,56 +127,58 @@ static void response_name_reg(struct nmb_ip *data, struct nmb_name *name,
|
|||||||
response from a name query announce host
|
response from a name query announce host
|
||||||
NAME_QUERY_ANNOUNCE_HOST is dealt with here
|
NAME_QUERY_ANNOUNCE_HOST is dealt with here
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void response_announce_host(struct nmb_ip *data,
|
static void response_announce_host(struct nmb_name *ans_name,
|
||||||
struct nmb_name *ans_name,
|
struct nmb_packet *nmb,
|
||||||
struct response_record *n, struct subnet_record *d)
|
struct response_record *n, struct subnet_record *d)
|
||||||
{
|
{
|
||||||
DEBUG(4, ("Name query at %s ip %s - ",
|
DEBUG(4, ("Name query at %s ip %s - ",
|
||||||
namestr(&n->name), inet_ntoa(n->send_ip)));
|
namestr(&n->name), inet_ntoa(n->send_ip)));
|
||||||
|
|
||||||
if (!name_equal(&n->name, ans_name))
|
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)
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong name as a reply. oops. */
|
/* we had sent out a name query to the current owner
|
||||||
/* XXXX should say to them 'oi! release that name!' */
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
|
/* first check all the details are correct */
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data)
|
int nb_flags = nmb->answers->rdata[0];
|
||||||
{
|
struct in_addr found_ip;
|
||||||
/* 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 */
|
putip((char*)&found_ip,&nmb->answers->rdata[2]);
|
||||||
|
|
||||||
if (data->nb_flags != n->reply.nb_flags)
|
if (nb_flags != n->nb_flags)
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong nb_flags as a reply. oops. */
|
/* someone gave us the wrong nb_flags as a reply. oops. */
|
||||||
/* XXXX should say to them 'oi! release that name!' */
|
/* XXXX should say to them 'oi! release that name!' */
|
||||||
|
|
||||||
DEBUG(4,("expected nb_flags: %d\n", n->reply.nb_flags));
|
DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
|
||||||
DEBUG(4,("unexpected nb_flags: %d\n", data->nb_flags));
|
DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do an announce host */
|
/* do an announce host */
|
||||||
do_announce_host(ANN_HostAnnouncement,
|
do_announce_host(ANN_HostAnnouncement,
|
||||||
n->my_name , 0x00, d->myip,
|
n->my_name , 0x00, d->myip,
|
||||||
n->name.name, 0x1d, data->ip,
|
n->name.name, 0x1d, found_ip,
|
||||||
n->ttl,
|
n->ttl,
|
||||||
n->my_name, n->server_type,
|
n->my_name, n->server_type, n->my_comment);
|
||||||
HOST_MAJOR_VERSION, HOST_MINOR_VERSION,
|
}
|
||||||
HOST_BROWSE_VERSION, HOST_BROWSE_SIGNATURE,
|
else
|
||||||
n->my_comment);
|
{
|
||||||
}
|
/* XXXX negative name query response. no master exists. oops */
|
||||||
else
|
}
|
||||||
{
|
|
||||||
/* XXXX negative name query response. no master exists. oops */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -167,18 +187,18 @@ static void response_announce_host(struct nmb_ip *data,
|
|||||||
NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
|
NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void response_server_check(struct nmb_name *ans_name,
|
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 */
|
/* issue another state: this time to do a name status check */
|
||||||
|
|
||||||
enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
|
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 */
|
/* initiate a name status check on the server that replied */
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
|
queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
|
||||||
-1,ans_name->name, ans_name->name_type,
|
ans_name->name, ans_name->name_type,
|
||||||
0,0,0,0,NULL,NULL,
|
0,0,0,NULL,NULL,
|
||||||
False,False,n->send_ip,n->reply.ip);
|
False,False,n->send_ip,n->reply_to_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -188,8 +208,8 @@ static void response_server_check(struct nmb_name *ans_name,
|
|||||||
add all the names it finds into the namelist.
|
add all the names it finds into the namelist.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static BOOL interpret_node_status(struct subnet_record *d,
|
static BOOL interpret_node_status(struct subnet_record *d,
|
||||||
char *p, struct nmb_name *name,int t,
|
char *p, struct nmb_name *name,int t,
|
||||||
char *serv_name, struct in_addr ip, BOOL bcast)
|
char *serv_name, struct in_addr ip, BOOL bcast)
|
||||||
{
|
{
|
||||||
int level = t==0x20 ? 4 : 0;
|
int level = t==0x20 ? 4 : 0;
|
||||||
int numnames = CVAL(p,0);
|
int numnames = CVAL(p,0);
|
||||||
@ -232,44 +252,44 @@ static BOOL interpret_node_status(struct subnet_record *d,
|
|||||||
|
|
||||||
/* might as well update our namelist while we're at it */
|
/* might as well update our namelist while we're at it */
|
||||||
if (add)
|
if (add)
|
||||||
{
|
{
|
||||||
struct in_addr nameip;
|
struct in_addr nameip;
|
||||||
enum name_source src;
|
enum name_source src;
|
||||||
|
|
||||||
if (ismyip(ip)) {
|
if (ismyip(ip)) {
|
||||||
nameip = ipzero;
|
nameip = ipzero;
|
||||||
src = SELF;
|
src = SELF;
|
||||||
} else {
|
} else {
|
||||||
nameip = ip;
|
nameip = ip;
|
||||||
src = STATUS_QUERY;
|
src = STATUS_QUERY;
|
||||||
}
|
}
|
||||||
add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
|
add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we want the server name */
|
/* we want the server name */
|
||||||
if (serv_name && !*serv_name && !group && t == 0)
|
if (serv_name && !*serv_name && !group && t == 0)
|
||||||
{
|
{
|
||||||
StrnCpy(serv_name,qname,15);
|
StrnCpy(serv_name,qname,15);
|
||||||
serv_name[15] = 0;
|
serv_name[15] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* looking for a name and type? */
|
/* looking for a name and type? */
|
||||||
if (name && !found && (t == type))
|
if (name && !found && (t == type))
|
||||||
{
|
{
|
||||||
/* take a guess at some of the name types we're going to ask for.
|
/* take a guess at some of the name types we're going to ask for.
|
||||||
evaluate whether they are group names or no... */
|
evaluate whether they are group names or no... */
|
||||||
if (((t == 0x1b || t == 0x1d ) && !group) ||
|
if (((t == 0x1b || t == 0x1d ) && !group) ||
|
||||||
((t == 0x20 || t == 0x1c || t == 0x1e) && group))
|
((t == 0x20 || t == 0x1c || t == 0x1e) && group))
|
||||||
{
|
{
|
||||||
found = True;
|
found = True;
|
||||||
make_nmb_name(name,qname,type,scope);
|
make_nmb_name(name,qname,type,scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
|
DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
|
||||||
}
|
}
|
||||||
DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
|
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;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,26 +299,28 @@ static BOOL interpret_node_status(struct subnet_record *d,
|
|||||||
and NAME_STATUS_SRV_CHK dealt with here.
|
and NAME_STATUS_SRV_CHK dealt with here.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void response_name_status_check(struct in_addr ip,
|
static void response_name_status_check(struct in_addr ip,
|
||||||
char *data, BOOL bcast,
|
struct nmb_packet *nmb, BOOL bcast,
|
||||||
struct response_record *n, struct subnet_record *d)
|
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. */
|
amongst other things. */
|
||||||
|
|
||||||
struct nmb_name name;
|
struct nmb_name name;
|
||||||
fstring serv_name;
|
fstring serv_name;
|
||||||
|
|
||||||
if (interpret_node_status(d,data,&name,name.name_type,serv_name,ip,bcast))
|
if (interpret_node_status(d,nmb->answers->rdata,
|
||||||
{
|
&name,name.name_type,serv_name,ip,bcast))
|
||||||
if (*serv_name)
|
{
|
||||||
{
|
if (*serv_name)
|
||||||
sync_server(n->state,serv_name,name.name,name.name_type,n->send_ip);
|
{
|
||||||
}
|
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"));
|
else
|
||||||
}
|
{
|
||||||
|
DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -306,74 +328,79 @@ static void response_name_status_check(struct in_addr ip,
|
|||||||
response from a name query for secured WINS registration. a state of
|
response from a name query for secured WINS registration. a state of
|
||||||
NAME_REGISTER_CHALLENGE is dealt with here.
|
NAME_REGISTER_CHALLENGE is dealt with here.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void response_name_query_register(struct nmb_ip *data,
|
static void response_name_query_register(struct nmb_packet *nmb,
|
||||||
struct nmb_name *ans_name,
|
struct nmb_name *ans_name,
|
||||||
struct response_record *n, struct subnet_record *d)
|
struct response_record *n, struct subnet_record *d)
|
||||||
{
|
{
|
||||||
struct in_addr register_ip;
|
struct in_addr register_ip;
|
||||||
BOOL new_owner;
|
BOOL new_owner;
|
||||||
|
|
||||||
DEBUG(4, ("Name query at %s ip %s - ",
|
DEBUG(4, ("Name query at %s ip %s - ",
|
||||||
namestr(&n->name), inet_ntoa(n->send_ip)));
|
namestr(&n->name), inet_ntoa(n->send_ip)));
|
||||||
|
|
||||||
if (!name_equal(&n->name, ans_name))
|
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)
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong name as a reply. oops. */
|
/* we had sent out a name query to the current owner
|
||||||
/* XXXX should say to them 'oi! release that name!' */
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
|
/* first check all the details are correct */
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data)
|
int nb_flags = nmb->answers->rdata[0];
|
||||||
{
|
struct in_addr found_ip;
|
||||||
/* 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 */
|
putip((char*)&found_ip,&nmb->answers->rdata[2]);
|
||||||
|
|
||||||
if (data->nb_flags != n->reply.nb_flags)
|
if (nb_flags != n->nb_flags)
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong nb_flags as a reply. oops. */
|
/* someone gave us the wrong nb_flags as a reply. oops. */
|
||||||
/* XXXX should say to them 'oi! release that name!' */
|
/* XXXX should say to them 'oi! release that name!' */
|
||||||
|
|
||||||
DEBUG(4,("expected nb_flags: %d\n", n->reply.nb_flags));
|
DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
|
||||||
DEBUG(4,("unexpected nb_flags: %d\n", data->nb_flags));
|
DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ip_equal(n->send_ip, data->ip))
|
if (!ip_equal(n->send_ip, found_ip))
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong ip as a reply. oops. */
|
/* someone gave us the wrong ip as a reply. oops. */
|
||||||
/* XXXX should say to them 'oi! release that name!' */
|
/* XXXX should say to them 'oi! release that name!' */
|
||||||
|
|
||||||
DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
|
DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
|
||||||
DEBUG(4,("unexpected ip: %s\n", inet_ntoa(data->ip)));
|
DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, (" OK: %s\n", inet_ntoa(data->ip)));
|
DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
|
||||||
|
|
||||||
/* fine: now tell the other host they can't have the name */
|
/* fine: now tell the other host they can't have the name */
|
||||||
register_ip = n->send_ip;
|
register_ip = n->send_ip;
|
||||||
new_owner = False;
|
new_owner = False;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(4, (" NEGATIVE RESPONSE!\n"));
|
DEBUG(4, (" NEGATIVE RESPONSE!\n"));
|
||||||
|
|
||||||
/* the owner didn't want the name: the other host can have it */
|
/* the owner didn't want the name: the other host can have it */
|
||||||
register_ip = n->reply.ip;
|
register_ip = n->reply_to_ip;
|
||||||
new_owner = True;
|
new_owner = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register the old or the new owners' ip */
|
/* register the old or the new owners' ip */
|
||||||
add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,
|
add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
|
||||||
n->reply.nb_flags, GET_TTL(0), register_ip,
|
GET_TTL(0), register_ip,
|
||||||
new_owner, n->reply.ip);
|
new_owner, n->reply_to_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -381,68 +408,73 @@ static void response_name_query_register(struct nmb_ip *data,
|
|||||||
response from a name query to sync browse lists or to update our netbios
|
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
|
entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void response_name_query_sync(struct nmb_ip *data,
|
static void response_name_query_sync(struct nmb_packet *nmb,
|
||||||
struct nmb_name *ans_name, BOOL bcast,
|
struct nmb_name *ans_name, BOOL bcast,
|
||||||
struct response_record *n, struct subnet_record *d)
|
struct response_record *n, struct subnet_record *d)
|
||||||
{
|
{
|
||||||
DEBUG(4, ("Name query at %s ip %s - ",
|
DEBUG(4, ("Name query at %s ip %s - ",
|
||||||
namestr(&n->name), inet_ntoa(n->send_ip)));
|
namestr(&n->name), inet_ntoa(n->send_ip)));
|
||||||
|
|
||||||
if (!name_equal(&n->name, ans_name))
|
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)
|
||||||
{
|
{
|
||||||
/* someone gave us the wrong name as a reply. oops. */
|
int nb_flags = nmb->answers->rdata[0];
|
||||||
DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
|
struct in_addr found_ip;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data)
|
putip((char*)&found_ip,&nmb->answers->rdata[2]);
|
||||||
{
|
|
||||||
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 (!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;
|
||||||
|
}
|
||||||
|
|
||||||
if (n->state == NAME_QUERY_SYNC_LOCAL ||
|
DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
|
||||||
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! */
|
if (n->state == NAME_QUERY_SYNC_LOCAL ||
|
||||||
sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
|
n->state == NAME_QUERY_SYNC_REMOTE)
|
||||||
data->ip, local_list_only);
|
{
|
||||||
}
|
struct work_record *work = NULL;
|
||||||
}
|
if ((work = find_workgroupstruct(d, ans_name->name, False)))
|
||||||
else
|
{
|
||||||
{
|
BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
|
||||||
/* 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)
|
/* the server is there: sync quick before it (possibly) dies! */
|
||||||
{
|
sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
|
||||||
/* XXXX remove_netbios_entry()? */
|
found_ip, local_list_only);
|
||||||
/* 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
|
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
|
||||||
*/
|
*/
|
||||||
remove_netbios_name(d,n->name.name, n->name.name_type,
|
remove_netbios_name(d,n->name.name, n->name.name_type,
|
||||||
REGISTER,n->send_ip);
|
REGISTER,n->send_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -454,9 +486,9 @@ static void debug_rr_type(int rr_type)
|
|||||||
switch (rr_type)
|
switch (rr_type)
|
||||||
{
|
{
|
||||||
case NMB_STATUS: DEBUG(3,("Name status ")); break;
|
case NMB_STATUS: DEBUG(3,("Name status ")); break;
|
||||||
case NMB_QUERY : DEBUG(3,("Name query ")); break;
|
case NMB_QUERY : DEBUG(3,("Name query ")); break;
|
||||||
case NMB_REG : DEBUG(3,("Name registration ")); break;
|
case NMB_REG : DEBUG(3,("Name registration ")); break;
|
||||||
case NMB_REL : DEBUG(3,("Name release ")); break;
|
case NMB_REL : DEBUG(3,("Name release ")); break;
|
||||||
default : DEBUG(1,("wrong response packet type received")); break;
|
default : DEBUG(1,("wrong response packet type received")); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +528,7 @@ void debug_state_type(int state)
|
|||||||
(responses for certain types of operations are only expected from one host)
|
(responses for certain types of operations are only expected from one host)
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static BOOL response_problem_check(struct response_record *n,
|
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)
|
switch (nmb->answers->rr_type)
|
||||||
{
|
{
|
||||||
@ -524,21 +556,21 @@ static BOOL response_problem_check(struct response_record *n,
|
|||||||
{
|
{
|
||||||
if (n->num_msgs > 1)
|
if (n->num_msgs > 1)
|
||||||
{
|
{
|
||||||
if (nmb->header.rcode == 0 && nmb->answers->rdata)
|
if (nmb->header.rcode == 0 && nmb->answers->rdata)
|
||||||
{
|
{
|
||||||
int nb_flags = nmb->answers->rdata[0];
|
int nb_flags = nmb->answers->rdata[0];
|
||||||
|
|
||||||
if ((!NAME_GROUP(nb_flags)))
|
if ((!NAME_GROUP(nb_flags)))
|
||||||
{
|
{
|
||||||
/* oh dear. more than one person responded to a unique name.
|
/* oh dear. more than one person responded to a unique name.
|
||||||
there is either a network problem, a configuration problem
|
there is either a network problem, a configuration problem
|
||||||
or a server is mis-behaving */
|
or a server is mis-behaving */
|
||||||
|
|
||||||
/* XXXX mark the name as in conflict, and then let the
|
/* XXXX mark the name as in conflict, and then let the
|
||||||
person who just responded know that they must also mark it
|
person who just responded know that they must also mark it
|
||||||
as in conflict, and therefore must NOT use it.
|
as in conflict, and therefore must NOT use it.
|
||||||
see rfc1001.txt 15.1.3.5 */
|
see rfc1001.txt 15.1.3.5 */
|
||||||
|
|
||||||
/* this may cause problems for some early versions of nmbd */
|
/* this may cause problems for some early versions of nmbd */
|
||||||
|
|
||||||
switch (n->state)
|
switch (n->state)
|
||||||
@ -548,35 +580,35 @@ static BOOL response_problem_check(struct response_record *n,
|
|||||||
/* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
|
/* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
case NAME_QUERY_ANNOUNCE_HOST:
|
case NAME_QUERY_ANNOUNCE_HOST:
|
||||||
case NAME_QUERY_DOM_SRV_CHK:
|
case NAME_QUERY_DOM_SRV_CHK:
|
||||||
case NAME_QUERY_SRV_CHK:
|
case NAME_QUERY_SRV_CHK:
|
||||||
case NAME_QUERY_MST_CHK:
|
case NAME_QUERY_MST_CHK:
|
||||||
{
|
{
|
||||||
if (!strequal(qname,n->name.name))
|
if (!strequal(qname,n->name.name))
|
||||||
{
|
{
|
||||||
/* one subnet, one master browser per workgroup */
|
/* one subnet, one master browser per workgroup */
|
||||||
/* XXXX force an election? */
|
/* XXXX force an election? */
|
||||||
|
|
||||||
DEBUG(3,("more than one master browser replied!\n"));
|
DEBUG(3,("more than one master browser replied!\n"));
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
DEBUG(3,("Unique Name conflict detected!\n"));
|
DEBUG(3,("Unique Name conflict detected!\n"));
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* we have received a negative reply, having already received
|
/* we have received a negative reply, having already received
|
||||||
at least one response (pos/neg). something's really wrong! */
|
at least one response (pos/neg). something's really wrong! */
|
||||||
|
|
||||||
DEBUG(3,("wierd name query problem detected!\n"));
|
DEBUG(3,("wierd name query problem detected!\n"));
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,30 +619,27 @@ static BOOL response_problem_check(struct response_record *n,
|
|||||||
check that the response received is compatible with the response record
|
check that the response received is compatible with the response record
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static BOOL response_compatible(struct response_record *n,
|
static BOOL response_compatible(struct response_record *n,
|
||||||
struct nmb_packet *nmb)
|
struct nmb_packet *nmb)
|
||||||
{
|
{
|
||||||
switch (n->state)
|
switch (n->state)
|
||||||
{
|
{
|
||||||
case NAME_RELEASE:
|
case NAME_RELEASE:
|
||||||
{
|
{
|
||||||
if (nmb->answers->rr_type != NMB_REL)
|
if (nmb->answers->rr_type != NMB_REL)
|
||||||
{
|
{
|
||||||
DEBUG(1,("Name release reply has wrong answer rr_type\n"));
|
DEBUG(1,("Name release reply has wrong answer rr_type\n"));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_REGISTER:
|
case NAME_REGISTER:
|
||||||
{
|
{
|
||||||
/* rfc1002.txt states that nmb->answers->rr_type must equal 0x20 */
|
if (nmb->answers->rr_type != NMB_REG)
|
||||||
#if 0
|
{
|
||||||
if (nmb->answers->rr_type != NMB_REG)
|
DEBUG(1,("Name register reply has wrong answer rr_type\n"));
|
||||||
{
|
return False;
|
||||||
DEBUG(1,("Name register reply has wrong answer rr_type\n"));
|
}
|
||||||
return False;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,29 +653,29 @@ static BOOL response_compatible(struct response_record *n,
|
|||||||
case NAME_QUERY_FIND_MST:
|
case NAME_QUERY_FIND_MST:
|
||||||
case NAME_QUERY_MST_CHK:
|
case NAME_QUERY_MST_CHK:
|
||||||
{
|
{
|
||||||
if (nmb->answers->rr_type != NMB_QUERY)
|
if (nmb->answers->rr_type != NMB_QUERY)
|
||||||
{
|
{
|
||||||
DEBUG(1,("Name query reply has wrong answer rr_type\n"));
|
DEBUG(1,("Name query reply has wrong answer rr_type\n"));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_STATUS_DOM_SRV_CHK:
|
case NAME_STATUS_DOM_SRV_CHK:
|
||||||
case NAME_STATUS_SRV_CHK:
|
case NAME_STATUS_SRV_CHK:
|
||||||
{
|
{
|
||||||
if (nmb->answers->rr_type != NMB_STATUS)
|
if (nmb->answers->rr_type != NMB_STATUS)
|
||||||
{
|
{
|
||||||
DEBUG(1,("Name status reply has wrong answer rr_type\n"));
|
DEBUG(1,("Name status reply has wrong answer rr_type\n"));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DEBUG(1,("unknown state type received in response_netbios_packet\n"));
|
DEBUG(1,("unknown state type received in response_netbios_packet\n"));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
@ -656,62 +685,27 @@ static BOOL response_compatible(struct response_record *n,
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
process the response packet received
|
process the response packet received
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void response_process(struct in_addr ip, struct subnet_record *d,
|
static void response_process(struct subnet_record *d, struct packet_struct *p,
|
||||||
struct response_record *n,
|
struct response_record *n, struct nmb_packet *nmb,
|
||||||
int rcode, char *nmb_data, struct nmb_name *q_name,
|
BOOL bcast, struct nmb_name *ans_name)
|
||||||
time_t ttl, BOOL bcast, struct nmb_name *ans_name)
|
|
||||||
{
|
{
|
||||||
switch (n->state)
|
switch (n->state)
|
||||||
{
|
{
|
||||||
case NAME_RELEASE:
|
case NAME_RELEASE:
|
||||||
{
|
{
|
||||||
struct nmb_ip found;
|
response_name_release(d, p);
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_REGISTER:
|
case NAME_REGISTER:
|
||||||
{
|
{
|
||||||
struct nmb_ip found;
|
response_name_reg(d, p);
|
||||||
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->source,n->token);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_REGISTER_CHALLENGE:
|
case NAME_REGISTER_CHALLENGE:
|
||||||
{
|
{
|
||||||
struct nmb_ip found;
|
response_name_query_register(nmb, ans_name, n, d);
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,66 +713,44 @@ void response_process(struct in_addr ip, struct subnet_record *d,
|
|||||||
case NAME_QUERY_SRV_CHK:
|
case NAME_QUERY_SRV_CHK:
|
||||||
case NAME_QUERY_FIND_MST:
|
case NAME_QUERY_FIND_MST:
|
||||||
{
|
{
|
||||||
response_server_check(ans_name, n, d);
|
response_server_check(ans_name, n, d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_STATUS_DOM_SRV_CHK:
|
case NAME_STATUS_DOM_SRV_CHK:
|
||||||
case NAME_STATUS_SRV_CHK:
|
case NAME_STATUS_SRV_CHK:
|
||||||
{
|
{
|
||||||
response_name_status_check(ip,nmb_data,bcast,n,d);
|
response_name_status_check(p->ip, nmb, bcast, n, d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NAME_QUERY_ANNOUNCE_HOST:
|
case NAME_QUERY_ANNOUNCE_HOST:
|
||||||
{
|
{
|
||||||
struct nmb_ip found;
|
response_announce_host(ans_name, nmb, n, d);
|
||||||
struct nmb_ip *data = NULL;
|
break;
|
||||||
|
|
||||||
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_CONFIRM:
|
||||||
case NAME_QUERY_SYNC_LOCAL:
|
case NAME_QUERY_SYNC_LOCAL:
|
||||||
case NAME_QUERY_SYNC_REMOTE:
|
case NAME_QUERY_SYNC_REMOTE:
|
||||||
{
|
{
|
||||||
struct nmb_ip found;
|
response_name_query_sync(nmb, ans_name, bcast, n, d);
|
||||||
struct nmb_ip *data = NULL;
|
break;
|
||||||
|
|
||||||
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:
|
case NAME_QUERY_MST_CHK:
|
||||||
{
|
{
|
||||||
/* no action required here. it's when NO responses are received
|
/* no action required here. it's when NO responses are received
|
||||||
that we need to do something. see expire_name_query_entries() */
|
that we need to do something. see expire_name_query_entries() */
|
||||||
|
|
||||||
DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
|
DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
|
||||||
namestr(&n->name), inet_ntoa(n->send_ip)));
|
namestr(&n->name), inet_ntoa(n->send_ip)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DEBUG(1,("unknown state type received in response_netbios_packet\n"));
|
DEBUG(1,("unknown state type received in response_netbios_packet\n"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -808,9 +780,7 @@ void response_netbios_packet(struct packet_struct *p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4,("response packet received: %s %d\n",
|
/* args wrong way round: spotted by ccm@shentel.net */
|
||||||
inet_ntoa(p->ip),n->response_id));
|
|
||||||
|
|
||||||
if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
|
if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
|
||||||
{
|
{
|
||||||
DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
|
DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
|
||||||
@ -822,13 +792,13 @@ void response_netbios_packet(struct packet_struct *p)
|
|||||||
{
|
{
|
||||||
/* hm. the packet received was a response, but with no answer. wierd! */
|
/* hm. the packet received was a response, but with no answer. wierd! */
|
||||||
DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
|
DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
|
||||||
inet_ntoa(p->ip), BOOLSTR(bcast)));
|
inet_ntoa(p->ip), BOOLSTR(bcast)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans_name = &nmb->answers->rr_name;
|
ans_name = &nmb->answers->rr_name;
|
||||||
DEBUG(3,("response for %s from %s (bcast=%s)\n",
|
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);
|
debug_rr_type(nmb->answers->rr_type);
|
||||||
|
|
||||||
@ -846,13 +816,7 @@ void response_netbios_packet(struct packet_struct *p)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* now deal with the current state */
|
/* now deal with the current state */
|
||||||
response_process(p->ip, d, n,
|
response_process(d, p, n, nmb, bcast, ans_name);
|
||||||
nmb->header.rcode,
|
|
||||||
nmb->answers->rdata,
|
|
||||||
question,
|
|
||||||
nmb->answers->ttl, bcast, ans_name);
|
|
||||||
|
|
||||||
remove_response_record(d, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
14 jan 96: lkcl@pires.co.uk
|
14 jan 96: lkcl@pires.co.uk
|
||||||
added multiple workgroup domain master support
|
added multiple workgroup domain master support
|
||||||
|
|
||||||
30 July 96: David.Chappell@mail.trincoll.edu
|
|
||||||
Expanded multiple workgroup domain master browser support.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
@ -33,34 +30,41 @@
|
|||||||
extern int ClientNMB;
|
extern int ClientNMB;
|
||||||
extern int ClientDGRAM;
|
extern int ClientDGRAM;
|
||||||
|
|
||||||
|
#define TEST_CODE /* want to debug unknown browse packets */
|
||||||
|
|
||||||
extern int DEBUGLEVEL;
|
extern int DEBUGLEVEL;
|
||||||
extern pstring scope;
|
extern pstring scope;
|
||||||
extern BOOL CanRecurse;
|
extern BOOL CanRecurse;
|
||||||
|
|
||||||
|
extern pstring myname;
|
||||||
|
|
||||||
extern int ClientNMB;
|
extern int ClientNMB;
|
||||||
extern int ClientDGRAM;
|
extern int ClientDGRAM;
|
||||||
|
|
||||||
extern struct in_addr ipzero;
|
extern struct in_addr ipzero;
|
||||||
|
|
||||||
|
extern int workgroup_count; /* total number of workgroups we know about */
|
||||||
|
|
||||||
/* this is our domain/workgroup/server database */
|
/* this is our domain/workgroup/server database */
|
||||||
extern struct subnet_record *subnetlist;
|
extern struct subnet_record *subnetlist;
|
||||||
|
|
||||||
extern int updatecount;
|
extern int updatecount;
|
||||||
|
|
||||||
|
/* backup request types: which servers are to be included */
|
||||||
|
#define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
|
||||||
|
#define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
|
||||||
|
|
||||||
extern time_t StartupTime;
|
extern time_t StartupTime;
|
||||||
|
|
||||||
extern BOOL updatedlists;
|
extern BOOL updatedlists;
|
||||||
|
|
||||||
extern pstring myname;
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
tell a server to become a backup browser
|
tell a server to become a backup browser
|
||||||
state - 0x01 become backup instead of master
|
state - 0x01 become backup instead of master
|
||||||
- 0x02 remove all entries in browse list and become non-master
|
- 0x02 remove all entries in browse list and become non-master
|
||||||
- 0x04 stop master browser service altogether. NT ignores this
|
- 0x04 stop master browser service altogether. NT ignores this
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void reset_server(struct work_record *work, char *name, int state, struct in_addr ip)
|
void reset_server(char *name, int state, struct in_addr ip)
|
||||||
{
|
{
|
||||||
char outbuf[20];
|
char outbuf[20];
|
||||||
char *p;
|
char *p;
|
||||||
@ -73,10 +77,10 @@ void reset_server(struct work_record *work, char *name, int state, struct in_add
|
|||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
DEBUG(2,("sending reset to %s %s of state %d\n",
|
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),
|
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||||
conf_browsing_alias(work->token),name,0x20,0x1d,ip,*iface_ip(ip));
|
myname,name,0x20,0x1d,ip,*iface_ip(ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -95,47 +99,47 @@ void tell_become_backup(void)
|
|||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
struct server_record *s;
|
struct server_record *s;
|
||||||
int num_servers = 0;
|
int num_servers = 0;
|
||||||
int num_backups = 0;
|
int num_backups = 0;
|
||||||
|
|
||||||
for (s = work->serverlist; s; s = s->next)
|
for (s = work->serverlist; s; s = s->next)
|
||||||
{
|
{
|
||||||
if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
|
if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
|
||||||
|
|
||||||
num_servers++;
|
num_servers++;
|
||||||
|
|
||||||
if (strequal(conf_browsing_alias(work->token), s->serv.name)) continue;
|
if (strequal(myname, s->serv.name)) continue;
|
||||||
|
|
||||||
if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
|
if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
|
||||||
num_backups++;
|
num_backups++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
|
if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
|
||||||
|
|
||||||
if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
|
if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
|
||||||
|
|
||||||
DEBUG(3,("num servers: %d num backups: %d\n",
|
DEBUG(3,("num servers: %d num backups: %d\n",
|
||||||
num_servers, num_backups));
|
num_servers, num_backups));
|
||||||
|
|
||||||
/* make first server a backup server. thereafter make every
|
/* make first server a backup server. thereafter make every
|
||||||
tenth server a backup server */
|
tenth server a backup server */
|
||||||
if (num_backups != 0 && (num_servers+9) / num_backups > 10)
|
if (num_backups != 0 && (num_servers+9) / num_backups > 10)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(2,("sending become backup to %s %s for %s\n",
|
DEBUG(2,("sending become backup to %s %s for %s\n",
|
||||||
s->serv.name, inet_ntoa(d->bcast_ip),
|
s->serv.name, inet_ntoa(d->bcast_ip),
|
||||||
work->work_group));
|
work->work_group));
|
||||||
|
|
||||||
/* type 11 request from conf_browsing_alias(work->token)(20) to WG(1e) for SERVER */
|
/* type 11 request from MYNAME(20) to WG(1e) for SERVER */
|
||||||
do_announce_request(s->serv.name, s->serv.name, work->work_group,
|
do_announce_request(s->serv.name, work->work_group,
|
||||||
ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
|
ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,23 +150,8 @@ void tell_become_backup(void)
|
|||||||
******************************************************************/
|
******************************************************************/
|
||||||
BOOL same_context(struct dgram_packet *dgram)
|
BOOL same_context(struct dgram_packet *dgram)
|
||||||
{
|
{
|
||||||
if (!strequal(dgram->dest_name .scope,scope )) return True;
|
if (!strequal(dgram->dest_name .scope,scope )) return(True);
|
||||||
|
if ( strequal(dgram->source_name.name ,myname)) 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);
|
return(False);
|
||||||
}
|
}
|
||||||
@ -208,8 +197,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,("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",
|
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,
|
namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
|
||||||
servertype,browse_type,browse_sig,comment));
|
servertype,browse_type,browse_sig,comment));
|
||||||
|
|
||||||
name[15] = 0;
|
name[15] = 0;
|
||||||
|
|
||||||
@ -224,7 +213,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
|
|||||||
dgram->dest_name.name_type != 0x1))
|
dgram->dest_name.name_type != 0x1))
|
||||||
{
|
{
|
||||||
DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +265,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
|
|||||||
if (command == ANN_LocalMasterAnnouncement)
|
if (command == ANN_LocalMasterAnnouncement)
|
||||||
{
|
{
|
||||||
add_browser_entry(serv_name,dgram->dest_name.name_type,
|
add_browser_entry(serv_name,dgram->dest_name.name_type,
|
||||||
work->work_group,30,ip,True);
|
work->work_group,30,ip,True);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,40 +278,26 @@ static void process_master_announce(struct packet_struct *p,char *buf)
|
|||||||
struct in_addr ip = dgram->header.source_ip;
|
struct in_addr ip = dgram->header.source_ip;
|
||||||
struct subnet_record *d = find_subnet(ip);
|
struct subnet_record *d = find_subnet(ip);
|
||||||
struct subnet_record *mydomain = find_subnet(*iface_bcast(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;
|
char *name = buf;
|
||||||
char *work_name;
|
struct work_record *work;
|
||||||
int token;
|
|
||||||
name[15] = 0;
|
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 (same_context(dgram)) return;
|
||||||
|
|
||||||
if (!d || !mydomain) return;
|
if (!d || !mydomain) return;
|
||||||
|
|
||||||
token = conf_alias_to_token(to_name);
|
if (!lp_domain_master()) return;
|
||||||
|
|
||||||
if (token == -1)
|
|
||||||
{
|
|
||||||
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 */
|
for (work = mydomain->workgrouplist; work; work = work->next)
|
||||||
add_browser_entry(name, 0x1b, work_name,30,ip,True);
|
{
|
||||||
|
if (AM_MASTER(work))
|
||||||
|
{
|
||||||
|
/* merge browse lists with them */
|
||||||
|
add_browser_entry(name,0x1b, work->work_group,30,ip,True);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@ -343,44 +318,62 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
|
|||||||
struct dgram_packet *dgram = &p->packet.dgram;
|
struct dgram_packet *dgram = &p->packet.dgram;
|
||||||
struct in_addr ip = dgram->header.source_ip;
|
struct in_addr ip = dgram->header.source_ip;
|
||||||
int count = CVAL(buf,0);
|
int count = CVAL(buf,0);
|
||||||
unsigned int pick;
|
|
||||||
uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
|
uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
|
||||||
char *buf1;
|
char *buf1;
|
||||||
|
|
||||||
DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
|
DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
|
||||||
namestr(&dgram->dest_name), inet_ntoa(ip),
|
namestr(&dgram->dest_name), inet_ntoa(ip),
|
||||||
count, info));
|
count, info));
|
||||||
|
|
||||||
if (same_context(dgram)) return;
|
if (same_context(dgram)) return;
|
||||||
|
|
||||||
if (count <= 0) return;
|
if (count <= 0) return;
|
||||||
|
|
||||||
pick = sys_random(count);
|
|
||||||
|
|
||||||
/* go through the list of servers attempting to sync browse lists */
|
/* go through the list of servers attempting to sync browse lists */
|
||||||
for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
|
for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
|
||||||
{
|
{
|
||||||
|
struct in_addr back_ip;
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
|
|
||||||
if (count != pick) continue;
|
DEBUG(4,("Searching for backup browser %s at %s...\n",
|
||||||
|
buf1, inet_ntoa(ip)));
|
||||||
DEBUG(4,("Searching for backup browser %s...\n", buf1));
|
|
||||||
|
|
||||||
if ((d = find_subnet(ip)) != NULL)
|
/* 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 */
|
||||||
struct work_record *work;
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
back_ip = *interpret_addr2(buf1);
|
||||||
{
|
|
||||||
if (work->token == 0 /* token */)
|
if (zero_ip(back_ip))
|
||||||
{
|
{
|
||||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
|
DEBUG(4,("Failed to find backup browser server using DNS\n"));
|
||||||
work->token,work->work_group,0x1d,
|
continue;
|
||||||
0,0,0,0,NULL,NULL,
|
}
|
||||||
False,False,ipzero,ipzero);
|
|
||||||
return;
|
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;
|
||||||
|
|
||||||
|
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,
|
||||||
|
0,0,0,NULL,NULL,
|
||||||
|
False,False,back_ip,back_ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,9 +381,9 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
send a backup list response.
|
send a backup list response.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void send_backup_list(struct work_record *work, struct nmb_name *src_name,
|
static void send_backup_list(char *work_name, struct nmb_name *src_name,
|
||||||
int token, uint32 info,
|
int token, uint32 info,
|
||||||
int name_type, struct in_addr ip)
|
int name_type, struct in_addr ip)
|
||||||
{
|
{
|
||||||
char outbuf[1024];
|
char outbuf[1024];
|
||||||
char *p, *countptr, *nameptr;
|
char *p, *countptr, *nameptr;
|
||||||
@ -398,8 +391,8 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name
|
|||||||
char *theirname = src_name->name;
|
char *theirname = src_name->name;
|
||||||
|
|
||||||
DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
|
DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
|
||||||
work->work_group, inet_ntoa(ip),
|
work_name, inet_ntoa(ip),
|
||||||
conf_browsing_alias(work->token),0x0,theirname,0x0));
|
myname,0x0,theirname,0x0));
|
||||||
|
|
||||||
if (name_type == 0x1d)
|
if (name_type == 0x1d)
|
||||||
{
|
{
|
||||||
@ -431,51 +424,62 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
struct server_record *s;
|
for (d = subnetlist; d; d = d->next)
|
||||||
|
{
|
||||||
|
struct work_record *work;
|
||||||
|
|
||||||
for (s = work->serverlist; s; s = s->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
BOOL found = False;
|
struct server_record *s;
|
||||||
char *n;
|
|
||||||
|
if (!strequal(work->work_group, work_name)) continue;
|
||||||
if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
|
|
||||||
|
for (s = work->serverlist; s; s = s->next)
|
||||||
for (n = nameptr; n < p; n = skip_string(n, 1))
|
{
|
||||||
{
|
BOOL found = False;
|
||||||
if (strequal(n, s->serv.name)) found = True;
|
char *n;
|
||||||
}
|
|
||||||
|
if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
|
||||||
if (found) continue; /* exclude names already added */
|
|
||||||
|
for (n = nameptr; n < p; n = skip_string(n, 1))
|
||||||
/* workgroup request: include all backup browsers in the list */
|
{
|
||||||
/* domain request: include all domain members in the list */
|
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 & SV_TYPE_MASTER_BROWSER)) ||
|
if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
|
||||||
(name_type == 0x1b && (s->serv.type & SV_TYPE_DOMAIN_BROWSER)))
|
(name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
|
||||||
{
|
{
|
||||||
DEBUG(4, ("%s ", s->serv.name));
|
DEBUG(4, ("%s ", s->serv.name));
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
strcpy(p,s->serv.name);
|
strcpy(p,s->serv.name);
|
||||||
strupper(p);
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
strcpy(p,conf_browsing_alias(work->token));
|
strcpy(p,myname);
|
||||||
strupper(p);
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
DEBUG(4, ("none\n"));
|
DEBUG(4, ("none\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG(4, (" - count %d\n", count));
|
DEBUG(4, (" - count %d\n", count));
|
||||||
}
|
}
|
||||||
|
|
||||||
CVAL(countptr, 0) = count;
|
CVAL(countptr, 0) = count;
|
||||||
|
|
||||||
@ -484,7 +488,7 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name
|
|||||||
debug_browse_data(outbuf, len);
|
debug_browse_data(outbuf, len);
|
||||||
}
|
}
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||||
conf_browsing_alias(work->token),theirname,0x0,0x0,ip,*iface_ip(ip));
|
myname,theirname,0x0,0x0,ip,*iface_ip(ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -515,24 +519,24 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
|
|||||||
|
|
||||||
if (name_type != 0x1b && name_type != 0x1d) {
|
if (name_type != 0x1b && name_type != 0x1d) {
|
||||||
DEBUG(0,("backup request to wrong type %d from %s\n",
|
DEBUG(0,("backup request to wrong type %d from %s\n",
|
||||||
name_type,inet_ntoa(ip)));
|
name_type,inet_ntoa(ip)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (strequal(work->work_group, dgram->dest_name.name))
|
if (strequal(work->work_group, dgram->dest_name.name))
|
||||||
{
|
{
|
||||||
DEBUG(2,("sending backup list to %s %s id=%x\n",
|
DEBUG(2,("sending backup list to %s %s id=%x\n",
|
||||||
namestr(&dgram->dest_name),inet_ntoa(ip),info));
|
namestr(&dgram->dest_name),inet_ntoa(ip),info));
|
||||||
|
|
||||||
send_backup_list(work,&dgram->source_name,
|
send_backup_list(work->work_group,&dgram->source_name,
|
||||||
token,info,name_type,ip);
|
token,info,name_type,ip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,23 +556,23 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
|
|||||||
int state = CVAL(buf,0);
|
int state = CVAL(buf,0);
|
||||||
|
|
||||||
DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n",
|
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 */
|
/* stop being a master but still deal with being a backup browser */
|
||||||
if (state & 0x1)
|
if (state & 0x1)
|
||||||
{
|
{
|
||||||
struct subnet_record *d;
|
struct subnet_record *d;
|
||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (AM_MASTER(work))
|
if (AM_MASTER(work))
|
||||||
{
|
{
|
||||||
become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
|
become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXXX documentation inconsistency: the above description does not
|
/* XXXX documentation inconsistency: the above description does not
|
||||||
@ -577,24 +581,21 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
|
|||||||
|
|
||||||
/* totally delete all servers and start afresh */
|
/* totally delete all servers and start afresh */
|
||||||
if (state & 0x2)
|
if (state & 0x2)
|
||||||
{
|
|
||||||
/* remove all workgroups (and their servers) from database */
|
|
||||||
struct subnet_record *d;
|
|
||||||
for (d = subnetlist; d; d = d->next)
|
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct subnet_record *d;
|
||||||
for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add all known workgroups back into database */
|
|
||||||
add_workgroups_to_subnets();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop browsing altogether. i don't think this is a good idea! */
|
/* stop browsing altogether. i don't think this is a good idea! */
|
||||||
if (state & 0x4)
|
if (state & 0x4)
|
||||||
{
|
{
|
||||||
DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
|
DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@ -610,43 +611,39 @@ static void process_announce_request(struct packet_struct *p,char *buf)
|
|||||||
struct in_addr ip = dgram->header.source_ip;
|
struct in_addr ip = dgram->header.source_ip;
|
||||||
struct subnet_record *d = find_subnet(ip);
|
struct subnet_record *d = find_subnet(ip);
|
||||||
int token = CVAL(buf,0);
|
int token = CVAL(buf,0);
|
||||||
int wg_token = 0;
|
|
||||||
char *name = buf+1;
|
char *name = buf+1;
|
||||||
char *samba_alias;
|
|
||||||
|
|
||||||
name[15] = 0;
|
name[15] = 0;
|
||||||
|
|
||||||
DEBUG(3,("Announce request from %s to %s token=0x%X\n",
|
DEBUG(3,("Announce request from %s to %s token=0x%X\n",
|
||||||
name,namestr(&dgram->dest_name), token));
|
name,namestr(&dgram->dest_name), token));
|
||||||
|
|
||||||
/* look up the index for this workgroup */
|
if (strequal(dgram->source_name.name,myname)) return;
|
||||||
wg_token = conf_workgroup_name_to_token(dgram->dest_name.name,myname);
|
|
||||||
if (wg_token == -1) return;
|
|
||||||
|
|
||||||
/* check that samba is participating in this workgroup */
|
|
||||||
if (!conf_should_workgroup_member(wg_token)) return;
|
|
||||||
|
|
||||||
/* find samba's NetBIOS alias it operates under in this workgroup */
|
|
||||||
if ((samba_alias = conf_browsing_alias(wg_token)) == (char*)NULL) return;
|
|
||||||
|
|
||||||
/* ignore announce requests from samba under its own alias.
|
|
||||||
this should no longer happen because code has been added to
|
|
||||||
discard packets from ourself. */
|
|
||||||
if (strequal(dgram->source_name.name,samba_alias)) return;
|
|
||||||
|
|
||||||
|
/* XXXX BUG or FEATURE?: need to ensure that we are a member of
|
||||||
|
this workgroup before announcing, particularly as we only
|
||||||
|
respond on local interfaces anyway.
|
||||||
|
|
||||||
|
if (strequal(dgram->dest_name, lp_workgroup()) return; ???
|
||||||
|
*/
|
||||||
|
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
for (work = d->workgrouplist; work; work = work->next)
|
for (work = d->workgrouplist; work; work = work->next)
|
||||||
{
|
{
|
||||||
if (wg_token == work->token) work->needannounce = True;
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
process a browse frame
|
process a browse frame
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -660,27 +657,27 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
case ANN_LocalMasterAnnouncement:
|
case ANN_LocalMasterAnnouncement:
|
||||||
{
|
{
|
||||||
debug_browse_data(buf, len);
|
debug_browse_data(buf, len);
|
||||||
process_announce(p,command,buf+1);
|
process_announce(p,command,buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANN_AnnouncementRequest:
|
case ANN_AnnouncementRequest:
|
||||||
{
|
{
|
||||||
process_announce_request(p,buf+1);
|
process_announce_request(p,buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANN_Election:
|
case ANN_Election:
|
||||||
{
|
{
|
||||||
process_election(p,buf+1);
|
process_election(p,buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANN_GetBackupListReq:
|
case ANN_GetBackupListReq:
|
||||||
{
|
{
|
||||||
debug_browse_data(buf, len);
|
debug_browse_data(buf, len);
|
||||||
process_send_backup_list(p,buf+1);
|
process_send_backup_list(p,buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANN_GetBackupListResp:
|
case ANN_GetBackupListResp:
|
||||||
@ -692,22 +689,22 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
|
|
||||||
case ANN_ResetBrowserState:
|
case ANN_ResetBrowserState:
|
||||||
{
|
{
|
||||||
process_reset_browser(p, buf+1);
|
process_reset_browser(p, buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANN_MasterAnnouncement:
|
case ANN_MasterAnnouncement:
|
||||||
{
|
{
|
||||||
process_master_announce(p,buf+1);
|
process_master_announce(p,buf+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
struct dgram_packet *dgram = &p->packet.dgram;
|
struct dgram_packet *dgram = &p->packet.dgram;
|
||||||
DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
|
DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
|
||||||
command, namestr(&dgram->source_name),
|
command, namestr(&dgram->source_name),
|
||||||
inet_ntoa(p->ip), namestr(&dgram->dest_name)));
|
inet_ntoa(p->ip), namestr(&dgram->dest_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,6 @@
|
|||||||
14 jan 96: lkcl@pires.co.uk
|
14 jan 96: lkcl@pires.co.uk
|
||||||
added multiple workgroup domain master support
|
added multiple workgroup domain master support
|
||||||
|
|
||||||
|
|
||||||
30 July 96: David.Chappell@mail.trincoll.edu
|
|
||||||
Expanded multiple workgroup domain master browser support.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
@ -169,10 +165,10 @@ static void expire_names_and_servers(void)
|
|||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
|
||||||
if (!lastrun) lastrun = t;
|
if (!lastrun) lastrun = t;
|
||||||
if (t < lastrun + 15) return; /* give samba time to check its names */
|
if (t < lastrun + 5) return;
|
||||||
lastrun = t;
|
lastrun = t;
|
||||||
|
|
||||||
check_expire_names(t); /* this checks samba's NetBIOS names */
|
expire_names(t);
|
||||||
expire_servers(t);
|
expire_servers(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,10 +187,10 @@ BOOL reload_services(BOOL test)
|
|||||||
pstring fname;
|
pstring fname;
|
||||||
strcpy(fname,lp_configfile());
|
strcpy(fname,lp_configfile());
|
||||||
if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
|
if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
|
||||||
{
|
{
|
||||||
strcpy(servicesf,fname);
|
strcpy(servicesf,fname);
|
||||||
test = False;
|
test = False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test && !lp_file_list_changed())
|
if (test && !lp_file_list_changed())
|
||||||
@ -255,32 +251,32 @@ static void load_hosts_file(char *fname)
|
|||||||
if (count <= 0) continue;
|
if (count <= 0) continue;
|
||||||
|
|
||||||
if (count > 0 && count < 2) {
|
if (count > 0 && count < 2) {
|
||||||
DEBUG(0,("Ill formed hosts line [%s]\n",line));
|
DEBUG(0,("Ill formed hosts line [%s]\n",line));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count >= 4) {
|
if (count >= 4) {
|
||||||
DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
|
DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
|
DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
|
||||||
|
|
||||||
if (strchr(flags,'G') || strchr(flags,'S')) {
|
if (strchr(flags,'G') || strchr(flags,'S')) {
|
||||||
DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
|
DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(flags,'M')) {
|
if (strchr(flags,'M')) {
|
||||||
source = SELF;
|
source = SELF;
|
||||||
strcpy(myname,name);
|
strcpy(myname,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipaddr = *interpret_addr2(ip);
|
ipaddr = *interpret_addr2(ip);
|
||||||
d = find_subnet(ipaddr);
|
d = find_subnet(ipaddr);
|
||||||
if (d) {
|
if (d) {
|
||||||
add_netbios_entry(d,name,0x00,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);
|
add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +292,8 @@ static void process(void)
|
|||||||
BOOL run_election;
|
BOOL run_election;
|
||||||
|
|
||||||
while (True)
|
while (True)
|
||||||
{
|
{
|
||||||
|
time_t t = time(NULL);
|
||||||
run_election = check_elections();
|
run_election = check_elections();
|
||||||
listen_for_packets(run_election);
|
listen_for_packets(run_election);
|
||||||
|
|
||||||
@ -313,11 +310,12 @@ static void process(void)
|
|||||||
|
|
||||||
expire_names_and_servers();
|
expire_names_and_servers();
|
||||||
expire_netbios_response_entries();
|
expire_netbios_response_entries();
|
||||||
|
refresh_my_names(t);
|
||||||
|
|
||||||
write_browse_list();
|
write_browse_list();
|
||||||
do_browser_lists();
|
do_browser_lists();
|
||||||
check_master_browser();
|
check_master_browser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -437,50 +435,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)
|
while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
strcpy(servicesf,optarg);
|
strcpy(servicesf,optarg);
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'C':
|
case 'C':
|
||||||
case 'G':
|
case 'G':
|
||||||
DEBUG(0,("Obsolete option '%c' used\n",opt));
|
DEBUG(0,("Obsolete option '%c' used\n",opt));
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
strcpy(host_file,optarg);
|
strcpy(host_file,optarg);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
strcpy(myname,optarg);
|
strcpy(myname,optarg);
|
||||||
strupper(myname);
|
strupper(myname);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
sprintf(debugf,"%s.nmb",optarg);
|
sprintf(debugf,"%s.nmb",optarg);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
strcpy(scope,optarg);
|
strcpy(scope,optarg);
|
||||||
strupper(scope);
|
strupper(scope);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
is_daemon = True;
|
is_daemon = True;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
DEBUGLEVEL = atoi(optarg);
|
DEBUGLEVEL = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
port = atoi(optarg);
|
port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!is_a_socket(0)) {
|
if (!is_a_socket(0)) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
|
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
|
||||||
@ -489,18 +487,10 @@ static void usage(char *pname)
|
|||||||
get_myname(myhostname,NULL);
|
get_myname(myhostname,NULL);
|
||||||
|
|
||||||
if (!reload_services(False))
|
if (!reload_services(False))
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
init_structs();
|
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);
|
reload_services(True);
|
||||||
|
|
||||||
set_samba_nb_type();
|
set_samba_nb_type();
|
||||||
@ -530,7 +520,7 @@ static void usage(char *pname)
|
|||||||
DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
|
DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
add_workgroups_to_subnets();
|
add_my_subnets(lp_workgroup());
|
||||||
|
|
||||||
DEBUG(3,("Checked names\n"));
|
DEBUG(3,("Checked names\n"));
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ fudge for getpass function
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
char *getsmbpass(char *pass)
|
char *getsmbpass(char *pass)
|
||||||
{
|
{
|
||||||
return "dummy"; /* return anything: it should be ignored anyway */
|
return "dummy"; /* return anything: it should be ignored anyway */
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -84,46 +84,43 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv
|
|||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
|
if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
|
||||||
&rprcnt,&rdrcnt, param,NULL,
|
&rprcnt,&rdrcnt, param,NULL,
|
||||||
&rparam,&rdata))
|
&rparam,&rdata))
|
||||||
{
|
{
|
||||||
int res = SVAL(rparam,0);
|
int res = SVAL(rparam,0);
|
||||||
int converter=SVAL(rparam,2);
|
int converter=SVAL(rparam,2);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
{
|
{
|
||||||
count=SVAL(rparam,4);
|
count=SVAL(rparam,4);
|
||||||
p = rdata;
|
p = rdata;
|
||||||
|
|
||||||
for (i = 0;i < count;i++, p += 26)
|
for (i = 0;i < count;i++, p += 26)
|
||||||
{
|
{
|
||||||
char *sname = p;
|
char *sname = p;
|
||||||
uint32 stype = IVAL(p,18);
|
uint32 stype = IVAL(p,18);
|
||||||
int comment_offset = IVAL(p,22) & 0xFFFF;
|
int comment_offset = IVAL(p,22) & 0xFFFF;
|
||||||
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
|
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
|
||||||
|
|
||||||
struct work_record *w = work;
|
struct work_record *w = work;
|
||||||
|
|
||||||
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
|
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
|
||||||
|
|
||||||
if (stype & SV_TYPE_DOMAIN_ENUM)
|
if (stype & SV_TYPE_DOMAIN_ENUM)
|
||||||
{
|
{
|
||||||
/* creates workgroup on remote subnet */
|
/* creates workgroup on remote subnet */
|
||||||
if ((w = find_workgroupstruct(d,sname,True)))
|
if ((w = find_workgroupstruct(d,sname,True)))
|
||||||
{
|
{
|
||||||
announce_request(w, d->bcast_ip);
|
announce_request(w, d->bcast_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w)
|
if (w)
|
||||||
{
|
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
|
||||||
add_server_entry(d,w,sname,stype & ~SV_TYPE_LOCAL_LIST_ONLY,
|
}
|
||||||
lp_max_ttl(),cmnt,False);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (rparam) free(rparam);
|
if (rparam) free(rparam);
|
||||||
if (rdata) free(rdata);
|
if (rdata) free(rdata);
|
||||||
@ -139,7 +136,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.
|
do a NetServerEnum and update our server and workgroup databases.
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void sync_browse_lists(struct subnet_record *d, struct work_record *work,
|
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;
|
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
|
||||||
|
|
||||||
@ -154,7 +151,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
|
|||||||
got_pass = True;
|
got_pass = True;
|
||||||
|
|
||||||
DEBUG(4,("sync browse lists with %s for %s %s\n",
|
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(workgroup,work->work_group);
|
||||||
strcpy(desthost,name);
|
strcpy(desthost,name);
|
||||||
@ -173,11 +170,11 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
|
|||||||
if (cli_open_sockets(SMB_PORT))
|
if (cli_open_sockets(SMB_PORT))
|
||||||
{
|
{
|
||||||
if (cli_send_login(NULL,NULL,True,True))
|
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_DOMAIN_ENUM);
|
||||||
add_info(d, work, local_type|(SV_TYPE_ALL&
|
add_info(d, work, local_type|(SV_TYPE_ALL&
|
||||||
~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY)));
|
~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
close_sockets();
|
close_sockets();
|
||||||
}
|
}
|
||||||
|
@ -106,34 +106,33 @@ extern int coding_system;
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *szAutoServices;
|
char *szPrintcapname;
|
||||||
char *szCharacterSet;
|
char *szLockDir;
|
||||||
char *szConfigFile;
|
char *szRootdir;
|
||||||
char *szDefaultService;
|
char *szDefaultService;
|
||||||
char *szDfree;
|
char *szDfree;
|
||||||
char *szDomainController;
|
|
||||||
char *szHostsEquiv;
|
|
||||||
char *szInterfaces;
|
|
||||||
char *szLockDir;
|
|
||||||
char *szLogFile;
|
|
||||||
char *szLogonScript;
|
|
||||||
char *szMsgCommand;
|
char *szMsgCommand;
|
||||||
char *szPasswdChat;
|
char *szHostsEquiv;
|
||||||
char *szPasswdProgram;
|
|
||||||
char *szPasswordServer;
|
|
||||||
char *szPrintcapname;
|
|
||||||
char *szRemoteAnnounce;
|
|
||||||
char *szRootdir;
|
|
||||||
char *szServerComment;
|
|
||||||
char *szServerString;
|
char *szServerString;
|
||||||
char *szSmbrun;
|
char *szAutoServices;
|
||||||
|
char *szPasswdProgram;
|
||||||
|
char *szPasswdChat;
|
||||||
|
char *szLogFile;
|
||||||
|
char *szConfigFile;
|
||||||
char *szSMBPasswdFile;
|
char *szSMBPasswdFile;
|
||||||
char *szSocketAddress;
|
char *szPasswordServer;
|
||||||
char *szSocketOptions;
|
char *szSocketOptions;
|
||||||
char *szUsernameMap;
|
|
||||||
char *szValidChars;
|
char *szValidChars;
|
||||||
char *szWINSserver;
|
|
||||||
char *szWorkGroup;
|
char *szWorkGroup;
|
||||||
|
char *szDomainController;
|
||||||
|
char *szUsernameMap;
|
||||||
|
char *szCharacterSet;
|
||||||
|
char *szLogonScript;
|
||||||
|
char *szSmbrun;
|
||||||
|
char *szWINSserver;
|
||||||
|
char *szInterfaces;
|
||||||
|
char *szRemoteAnnounce;
|
||||||
|
char *szSocketAddress;
|
||||||
int max_log_size;
|
int max_log_size;
|
||||||
int mangled_stack;
|
int mangled_stack;
|
||||||
int max_xmit;
|
int max_xmit;
|
||||||
@ -153,7 +152,6 @@ typedef struct
|
|||||||
BOOL bWINSsupport;
|
BOOL bWINSsupport;
|
||||||
BOOL bWINSproxy;
|
BOOL bWINSproxy;
|
||||||
BOOL bPreferredMaster;
|
BOOL bPreferredMaster;
|
||||||
BOOL bLocalMaster;
|
|
||||||
BOOL bDomainMaster;
|
BOOL bDomainMaster;
|
||||||
BOOL bDomainLogons;
|
BOOL bDomainLogons;
|
||||||
BOOL bEncryptPasswords;
|
BOOL bEncryptPasswords;
|
||||||
@ -384,7 +382,6 @@ struct parm_struct
|
|||||||
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
|
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
|
||||||
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
|
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
|
||||||
{"auto services", 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},
|
{"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
|
||||||
{"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
|
{"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
|
||||||
{"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
|
{"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
|
||||||
@ -428,7 +425,6 @@ struct parm_struct
|
|||||||
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
|
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
|
||||||
{"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
|
{"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
|
||||||
{"prefered 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 master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
|
||||||
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
|
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
|
||||||
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
|
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
|
||||||
@ -564,9 +560,6 @@ static void init_globals(void)
|
|||||||
string_set(&Globals.szSocketAddress, "0.0.0.0");
|
string_set(&Globals.szSocketAddress, "0.0.0.0");
|
||||||
sprintf(s,"Samba %s",VERSION);
|
sprintf(s,"Samba %s",VERSION);
|
||||||
string_set(&Globals.szServerString,s);
|
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.bLoadPrinters = True;
|
||||||
Globals.bUseRhosts = False;
|
Globals.bUseRhosts = False;
|
||||||
Globals.max_packet = 65535;
|
Globals.max_packet = 65535;
|
||||||
@ -591,9 +584,8 @@ static void init_globals(void)
|
|||||||
Globals.bSyslogOnly = False;
|
Globals.bSyslogOnly = False;
|
||||||
Globals.os_level = 0;
|
Globals.os_level = 0;
|
||||||
Globals.max_ttl = 60*60*4; /* 2 hours default */
|
Globals.max_ttl = 60*60*4; /* 2 hours default */
|
||||||
Globals.bPreferredMaster = True; /* force election on startup */
|
Globals.bPreferredMaster = True;
|
||||||
Globals.bLocalMaster = True; /* master browser on local subnet */
|
Globals.bDomainMaster = False;
|
||||||
Globals.bDomainMaster = False; /* maintain wide area network browse list */
|
|
||||||
Globals.bDomainLogons = False;
|
Globals.bDomainLogons = False;
|
||||||
Globals.bBrowseList = True;
|
Globals.bBrowseList = True;
|
||||||
Globals.bWINSsupport = True;
|
Globals.bWINSsupport = True;
|
||||||
@ -732,7 +724,6 @@ FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
|
|||||||
FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
|
FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
|
||||||
FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
|
FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
|
||||||
FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
|
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_printcapname,&Globals.szPrintcapname)
|
||||||
FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
|
FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
|
||||||
FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
|
FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
|
||||||
@ -756,7 +747,6 @@ FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
|
|||||||
|
|
||||||
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
|
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
|
||||||
FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
|
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_master,&Globals.bDomainMaster)
|
||||||
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
|
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
|
||||||
FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
|
FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
|
||||||
|
@ -812,7 +812,10 @@ static int get_server_info(uint32 servertype,
|
|||||||
if (!next_token(&ptr,s->name , NULL)) continue;
|
if (!next_token(&ptr,s->name , NULL)) continue;
|
||||||
if (!next_token(&ptr,stype , NULL)) continue;
|
if (!next_token(&ptr,stype , NULL)) continue;
|
||||||
if (!next_token(&ptr,s->comment, NULL)) continue;
|
if (!next_token(&ptr,s->comment, NULL)) continue;
|
||||||
if (!next_token(&ptr,s->domain , NULL)) continue;
|
if (!next_token(&ptr,s->domain , NULL)) {
|
||||||
|
/* this allows us to cope with an old nmbd */
|
||||||
|
strcpy(s->domain,lp_workgroup());
|
||||||
|
}
|
||||||
|
|
||||||
if (sscanf(stype,"%X",&s->type) != 1) {
|
if (sscanf(stype,"%X",&s->type) != 1) {
|
||||||
DEBUG(4,("r:host file "));
|
DEBUG(4,("r:host file "));
|
||||||
@ -980,22 +983,8 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
|
|||||||
|
|
||||||
if (strcmp(str1, "WrLehDz") == 0) {
|
if (strcmp(str1, "WrLehDz") == 0) {
|
||||||
StrnCpy(domain, p, sizeof(fstring)-1);
|
StrnCpy(domain, p, sizeof(fstring)-1);
|
||||||
}
|
} else {
|
||||||
else
|
StrnCpy(domain, lp_workgroup(), sizeof(fstring)-1);
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, sizeof(fstring)-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp_browse_list())
|
if (lp_browse_list())
|
||||||
@ -1679,19 +1668,9 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
|
|||||||
pstring comment;
|
pstring comment;
|
||||||
uint32 servertype=DFLT_SERVER_TYPE;
|
uint32 servertype=DFLT_SERVER_TYPE;
|
||||||
|
|
||||||
char *work_alias;
|
|
||||||
char domain[16];
|
|
||||||
|
|
||||||
work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, sizeof(fstring)-1);
|
|
||||||
else
|
|
||||||
*domain = 0;
|
|
||||||
|
|
||||||
strcpy(comment,lp_serverstring());
|
strcpy(comment,lp_serverstring());
|
||||||
|
|
||||||
if ((count=get_server_info(SV_TYPE_ALL,&servers,domain))>0) {
|
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
|
||||||
for (i=0;i<count;i++)
|
for (i=0;i<count;i++)
|
||||||
if (strequal(servers[i].name,local_machine)) {
|
if (strequal(servers[i].name,local_machine)) {
|
||||||
servertype = servers[i].type;
|
servertype = servers[i].type;
|
||||||
@ -1744,14 +1723,6 @@ static BOOL api_NetWkstaGetInfo(int cnum,int uid, char *param,char *data,
|
|||||||
char *p2;
|
char *p2;
|
||||||
extern pstring sesssetup_user;
|
extern pstring sesssetup_user;
|
||||||
int level = SVAL(p,0);
|
int level = SVAL(p,0);
|
||||||
char domain[17];
|
|
||||||
|
|
||||||
char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, 16);
|
|
||||||
else
|
|
||||||
StrnCpy(domain, lp_workgroup(), 16);
|
|
||||||
|
|
||||||
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
|
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
|
||||||
|
|
||||||
@ -1782,7 +1753,7 @@ static BOOL api_NetWkstaGetInfo(int cnum,int uid, char *param,char *data,
|
|||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
||||||
StrCpy(p2,domain);
|
strcpy(p2,lp_workgroup());
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
@ -1791,7 +1762,7 @@ static BOOL api_NetWkstaGetInfo(int cnum,int uid, char *param,char *data,
|
|||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
||||||
strcpy(p2,domain); /* login domain?? */
|
strcpy(p2,lp_workgroup()); /* login domain?? */
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
@ -2014,14 +1985,6 @@ static BOOL api_WWkstaUserLogon(int cnum,int uid, char *param,char *data,
|
|||||||
int uLevel;
|
int uLevel;
|
||||||
struct pack_desc desc;
|
struct pack_desc desc;
|
||||||
char* name;
|
char* name;
|
||||||
char domain[17];
|
|
||||||
|
|
||||||
char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, 16);
|
|
||||||
else
|
|
||||||
StrnCpy(domain, lp_workgroup(), 16);
|
|
||||||
|
|
||||||
uLevel = SVAL(p,0);
|
uLevel = SVAL(p,0);
|
||||||
name = p + 2;
|
name = p + 2;
|
||||||
@ -2064,7 +2027,7 @@ static BOOL api_WWkstaUserLogon(int cnum,int uid, char *param,char *data,
|
|||||||
strupper(mypath);
|
strupper(mypath);
|
||||||
PACKS(&desc,"z",mypath); /* computer */
|
PACKS(&desc,"z",mypath); /* computer */
|
||||||
}
|
}
|
||||||
PACKS(&desc,"z",domain);/* domain */
|
PACKS(&desc,"z",lp_workgroup());/* domain */
|
||||||
PACKS(&desc,"z",lp_logon_script()); /* script path */
|
PACKS(&desc,"z",lp_logon_script()); /* script path */
|
||||||
PACKI(&desc,"D",0); /* reserved */
|
PACKI(&desc,"D",0); /* reserved */
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ extern BOOL case_sensitive;
|
|||||||
extern pstring sesssetup_user;
|
extern pstring sesssetup_user;
|
||||||
extern int Client;
|
extern int Client;
|
||||||
|
|
||||||
extern pstring local_machine;
|
|
||||||
|
|
||||||
/* this macro should always be used to extract an fnum (smb_fid) from
|
/* this macro should always be used to extract an fnum (smb_fid) from
|
||||||
a packet to ensure chaining works correctly */
|
a packet to ensure chaining works correctly */
|
||||||
#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
|
#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
|
||||||
@ -253,18 +251,9 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
|
|||||||
{
|
{
|
||||||
uint32 dword1;
|
uint32 dword1;
|
||||||
uint16 word1;
|
uint16 word1;
|
||||||
int wglen;
|
char * workgroup = lp_workgroup();
|
||||||
|
int wglen = strlen(workgroup);
|
||||||
int i;
|
int i;
|
||||||
char domain[17];
|
|
||||||
|
|
||||||
char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, 16);
|
|
||||||
else
|
|
||||||
StrnCpy(domain, lp_workgroup(), 16);
|
|
||||||
|
|
||||||
wglen = strlen(domain);
|
|
||||||
|
|
||||||
/* All kinds of mysterious numbers here */
|
/* All kinds of mysterious numbers here */
|
||||||
*rdata_len = 90 + 2 * wglen;
|
*rdata_len = 90 + 2 * wglen;
|
||||||
@ -290,7 +279,7 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
|
|||||||
SIVAL(*rdata,0x2C,4);
|
SIVAL(*rdata,0x2C,4);
|
||||||
SIVAL(*rdata,0x34,wglen);
|
SIVAL(*rdata,0x34,wglen);
|
||||||
for ( i = 0 ; i < wglen ; i++ )
|
for ( i = 0 ; i < wglen ; i++ )
|
||||||
(*rdata)[0x38 + i * 2] = domain[i];
|
(*rdata)[0x38 + i * 2] = workgroup[i];
|
||||||
|
|
||||||
/* Now fill in the rest */
|
/* Now fill in the rest */
|
||||||
i = 0x38 + wglen * 2;
|
i = 0x38 + wglen * 2;
|
||||||
|
@ -37,7 +37,6 @@ extern connection_struct Connections[];
|
|||||||
extern files_struct Files[];
|
extern files_struct Files[];
|
||||||
extern BOOL case_sensitive;
|
extern BOOL case_sensitive;
|
||||||
extern pstring sesssetup_user;
|
extern pstring sesssetup_user;
|
||||||
extern fstring local_machine;
|
|
||||||
extern int Client;
|
extern int Client;
|
||||||
|
|
||||||
/* this macro should always be used to extract an fnum (smb_fid) from
|
/* this macro should always be used to extract an fnum (smb_fid) from
|
||||||
@ -55,6 +54,7 @@ int reply_special(char *inbuf,char *outbuf)
|
|||||||
int msg_flags = CVAL(inbuf,1);
|
int msg_flags = CVAL(inbuf,1);
|
||||||
pstring name1,name2;
|
pstring name1,name2;
|
||||||
extern fstring remote_machine;
|
extern fstring remote_machine;
|
||||||
|
extern fstring local_machine;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
*name1 = *name2 = 0;
|
*name1 = *name2 = 0;
|
||||||
@ -319,14 +319,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
|||||||
BOOL guest=False;
|
BOOL guest=False;
|
||||||
BOOL computer_id=False;
|
BOOL computer_id=False;
|
||||||
|
|
||||||
char domain[17];
|
|
||||||
|
|
||||||
char *work_alias = conf_alias_to_workgroup(local_machine); /* look-up */
|
|
||||||
|
|
||||||
if (work_alias)
|
|
||||||
StrnCpy(domain, work_alias, 16);
|
|
||||||
else
|
|
||||||
StrnCpy(domain, lp_workgroup(), 16);
|
|
||||||
*smb_apasswd = 0;
|
*smb_apasswd = 0;
|
||||||
|
|
||||||
sess_uid = SVAL(inbuf,smb_uid);
|
sess_uid = SVAL(inbuf,smb_uid);
|
||||||
@ -460,7 +452,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
|||||||
p = smb_buf(outbuf);
|
p = smb_buf(outbuf);
|
||||||
strcpy(p,"Unix"); p = skip_string(p,1);
|
strcpy(p,"Unix"); p = skip_string(p,1);
|
||||||
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
|
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
|
||||||
strcpy(p,domain); p = skip_string(p,1);
|
strcpy(p,lp_workgroup()); p = skip_string(p,1);
|
||||||
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
|
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
|
||||||
/* perhaps grab OS version here?? */
|
/* perhaps grab OS version here?? */
|
||||||
}
|
}
|
||||||
|
@ -3746,8 +3746,6 @@ static void usage(char *pname)
|
|||||||
DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
|
DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
|
||||||
}
|
}
|
||||||
|
|
||||||
read_smbbrowse_conf(myhostname);
|
|
||||||
|
|
||||||
process();
|
process();
|
||||||
close_sockets();
|
close_sockets();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user