summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamba Release Account <samba-bugs@samba.org>1996-07-01 18:29:21 +0000
committerSamba Release Account <samba-bugs@samba.org>1996-07-01 18:29:21 +0000
commit7a804a2e838846715f036e5e93630a4436a4ec4b (patch)
treec31452440cd49448bec35d4abba4b89ee659165f
parenta853abd9ae082d5b69093e662a57194b17babaff (diff)
downloadsamba-7a804a2e838846715f036e5e93630a4436a4ec4b.tar.gz
samba-7a804a2e838846715f036e5e93630a4436a4ec4b.tar.bz2
samba-7a804a2e838846715f036e5e93630a4436a4ec4b.zip
updated the NetBIOS code due to some bugs found by writing the first draft
of the low level design docs. (This used to be commit 103012e5f2fac09598d60c4263c3a30992680729)
-rw-r--r--source3/include/proto.h238
-rw-r--r--source3/nameresp.c82
-rw-r--r--source3/nameserv.c471
3 files changed, 523 insertions, 268 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ce02be129f..8dc3df0183 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1,20 +1,39 @@
/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from access.c */
+
BOOL check_access(int snum);
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
BOOL fromhost(int sock,struct from_host *f);
+
+/*The following definitions come from charcnv.c */
+
char *unix2dos_format(char *str,BOOL overwrite);
char *dos2unix_format(char *str, BOOL overwrite);
int interpret_character_set(char *str, int def);
+
+/*The following definitions come from charset.c */
+
void charset_initialise(void);
void add_char_string(char *s);
+
+/*The following definitions come from chgpasswd.c */
+
BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
+
+/*The following definitions come from client.c */
+
void setup_pkt(char *outbuf);
void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
void cmd_help(void);
BOOL reopen_connection(char *inbuf,char *outbuf);
char *smb_errstr(char *inbuf);
+
+/*The following definitions come from clientutil.c */
+
void cli_setup_pkt(char *outbuf);
BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
int *param_len, char **data,char **param);
@@ -29,6 +48,9 @@ BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int fl
BOOL cli_open_sockets(int port);
BOOL cli_reopen_connection(char *inbuf,char *outbuf);
char *smb_errstr(char *inbuf);
+
+/*The following definitions come from clitar.c */
+
int strslashcmp(const char *s1, const char *s2);
void cmd_block(void);
void cmd_tarmode(void);
@@ -37,6 +59,9 @@ void cmd_tar(char *inbuf, char *outbuf);
int process_tar(char *inbuf, char *outbuf);
int clipfind(char **aret, int ret, char *tok);
int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
+
+/*The following definitions come from dir.c */
+
void init_dptrs(void);
char *dptr_path(int key);
char *dptr_wcard(int key);
@@ -62,10 +87,18 @@ int TellDir(void *p);
void DirCacheAdd(char *path,char *name,char *dname,int snum);
char *DirCacheCheck(char *path,char *name,int snum);
void DirCacheFlush(int snum);
+
+/*The following definitions come from fault.c */
+
void fault_setup(void (*fn)());
+
+/*The following definitions come from getsmbpass.c */
+
char *getsmbpass(char *prompt) ;
+
+/*The following definitions come from interface.c */
+
void load_interfaces(void);
-void add_subnet_interfaces(void);
void iface_set_default(char *ip,char *bcast,char *nmask);
BOOL ismyip(struct in_addr ip);
BOOL ismybcast(struct in_addr bcast);
@@ -74,8 +107,17 @@ struct in_addr *iface_n_ip(int n);
struct in_addr *iface_bcast(struct in_addr ip);
struct in_addr *iface_nmask(struct in_addr ip);
struct in_addr *iface_ip(struct in_addr ip);
+
+/*The following definitions come from ipc.c */
+
int reply_trans(char *inbuf,char *outbuf);
+
+/*The following definitions come from kanji.c */
+
int interpret_coding_system(char *str, int def);
+
+/*The following definitions come from loadparm.c */
+
char *lp_string(char *s);
char *lp_logfile(void);
char *lp_smbrun(void);
@@ -208,6 +250,9 @@ void lp_dump(void);
int lp_servicenumber(char *pszServiceName);
char *my_workgroup(void);
char *volume_label(int snum);
+
+/*The following definitions come from locking.c */
+
BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
int file_lock(char *name,int timeout);
void file_unlock(int fd);
@@ -220,6 +265,9 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid);
void del_share_mode(int fnum);
BOOL set_share_mode(int fnum,int mode);
void clean_share_files(void);
+
+/*The following definitions come from mangle.c */
+
int str_checksum(char *s);
BOOL is_8_3(char *fname);
void create_mangled_stack(int size);
@@ -227,30 +275,50 @@ BOOL check_mangled_stack(char *s);
BOOL is_mangled(char *s);
void mangle_name_83(char *s);
BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
+
+/*The following definitions come from md4.c */
+
+
+/*The following definitions come from message.c */
+
int reply_sends(char *inbuf,char *outbuf);
int reply_sendstrt(char *inbuf,char *outbuf);
int reply_sendtxt(char *inbuf,char *outbuf);
int reply_sendend(char *inbuf,char *outbuf);
+
+/*The following definitions come from nameannounce.c */
+
void announce_request(struct work_record *work, struct in_addr ip);
void do_announce_request(char *info, char *to_name, int announce_type,
int from,
int to, struct in_addr dest_ip);
void announce_backup(void);
+void do_announce_host(int command,
+ char *from_name, int from_type, struct in_addr from_ip,
+ char *to_name , int to_type , struct in_addr to_ip,
+ int updatecount, time_t announce_interval,
+ char *server_name, int server_type, char *server_comment);
+void announce_server(struct subnet_record *d, struct work_record *work,
+ char *name, char *comment, time_t ttl, int server_type);
void announce_host(void);
void announce_master(void);
+
+/*The following definitions come from namedb.c */
+
struct work_record *remove_workgroup(struct subnet_record *d,
struct work_record *work);
void expire_browse_cache(time_t t);
struct work_record *find_workgroupstruct(struct subnet_record *d,
fstring name, BOOL add);
-struct subnet_record *find_subnet(struct in_addr source_ip);
+struct subnet_record *find_subnet(struct in_addr bcast_ip);
void dump_workgroups(void);
-struct subnet_record *add_subnet_entry(struct in_addr source_ip,
- struct in_addr source_mask,
+void add_subnet_interfaces(void);
+struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
+ struct in_addr mask_ip,
char *name, BOOL add, BOOL lmhosts);
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
time_t ttl, struct in_addr ip);
-void remove_server(struct work_record *work, char *name);
+void remove_my_servers(void);
struct server_record *add_server_entry(struct subnet_record *d,
struct work_record *work,
char *name,int servertype,
@@ -258,36 +326,44 @@ struct server_record *add_server_entry(struct subnet_record *d,
BOOL replace);
void write_browse_list(void);
void expire_servers(time_t t);
-void query_refresh_names(void);
+
+/*The following definitions come from nameelect.c */
+
void check_master_browser(void);
void browser_gone(char *work_name, struct in_addr ip);
void send_election(struct subnet_record *d, char *group,uint32 criterion,
int timeup,char *name);
void become_nonmaster(struct subnet_record *d, struct work_record *work,
- int remove_type);
+ int remove_type);
void run_elections(void);
void process_election(struct packet_struct *p,char *buf);
BOOL check_elections(void);
+
+/*The following definitions come from namequery.c */
+
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
struct in_addr to_ip,char *master,char *rname,
void (*fn)());
BOOL name_query(int fd,char *name,int name_type,
BOOL bcast,BOOL recurse,
struct in_addr to_ip, struct in_addr *ip,void (*fn)());
-void expire_netbios_response_entries(void);
+
+/*The following definitions come from nameresp.c */
+
+void expire_netbios_response_entries();
void reply_netbios_packet(struct packet_struct *p1,int trn_id,
- int rcode,int opcode,BOOL recurse,
- struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
- char *data,int len);
+ int rcode,int opcode, BOOL recurse,
+ struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
+ char *data,int len);
void queue_netbios_pkt_wins(struct subnet_record *d,
int fd,int quest_type,enum cmd_type cmd,
- char *name,int name_type, int nb_flags, time_t ttl,
+ char *name,int name_type,int nb_flags, time_t ttl,
BOOL bcast,BOOL recurse,struct in_addr to_ip);
void queue_netbios_packet(struct subnet_record *d,
- int fd,int quest_type,enum cmd_type cmd,char *name,
- int name_type,int nb_flags,time_t ttl,
- BOOL bcast,BOOL recurse, struct in_addr to_ip);
-struct response_record *find_response_record(struct subnet_record *d,
+ int fd,int quest_type,enum cmd_type cmd,char *name,
+ int name_type,int nb_flags, time_t ttl,
+ BOOL bcast,BOOL recurse, struct in_addr to_ip);
+struct response_record *find_response_record(struct subnet_record **d,
uint16 id);
void queue_packet(struct packet_struct *packet);
void run_packet_queue();
@@ -298,38 +374,39 @@ BOOL interpret_node_status(struct subnet_record *d,
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
char *dstname,int src_type,int dest_type,
struct in_addr dest_ip,struct in_addr src_ip);
+
+/*The following definitions come from nameserv.c */
+
void remove_name(struct subnet_record *d, struct name_record *n);
void dump_names(void);
-void remove_netbios_name(struct subnet_record *d, char *name,int type,
- enum name_source source,
+void load_netbios_names(void);
+void remove_netbios_name(struct subnet_record *d,
+ char *name,int type, enum name_source source,
struct in_addr ip);
-struct name_record *add_netbios_entry(struct subnet_record *d, char *name,
- int type, int nb_flags, int ttl,
- enum name_source source,
- struct in_addr ip,
- BOOL new_only, BOOL wins);
+struct name_record *add_netbios_entry(struct subnet_record *d,
+ char *name, int type, int nb_flags,
+ int ttl, enum name_source source, struct in_addr ip,
+ BOOL new_only,BOOL wins);
void remove_name_entry(struct subnet_record *d, char *name,int type);
-void add_my_name_entry(struct subnet_record *d, char *name,int type,int nb_flags);
-void do_announce_host(int command,
- char *from, int from_type, struct in_addr from_ip,
- char *to , int to_type , struct in_addr to_ip,
- int update_count, time_t announce_interval,
- char *server_name, int server_type, char *server_comment);
-void load_netbios_names(void);
+void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
void add_my_names(void);
-void remove_my_names(void);
-void remove_my_servers(void);
-void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type);
+void remove_my_names();
void refresh_my_names(time_t t);
+void query_refresh_names(void);
void expire_names(time_t t);
-void response_name_release(struct subnet_record *d,struct packet_struct *p);
+void response_name_release(struct subnet_record *d, struct packet_struct *p);
void reply_name_release(struct packet_struct *p);
-void response_name_reg(struct subnet_record *d,struct packet_struct *p);
+void response_name_reg(struct subnet_record *d, struct packet_struct *p);
void reply_name_reg(struct packet_struct *p);
void reply_name_status(struct packet_struct *p);
+struct name_record *search_for_name(struct subnet_record **d,
+ struct nmb_name *question,
+ struct in_addr ip, int Time, int search);
void reply_name_query(struct packet_struct *p);
void process_nmb(struct packet_struct *p);
+
+/*The following definitions come from namework.c */
+
void reset_server(char *name, int state, struct in_addr ip);
void tell_become_backup(void);
void do_browser_lists(void);
@@ -343,7 +420,13 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len);
BOOL listening_type(struct packet_struct *p, int command);
void process_browse_packet(struct packet_struct *p,char *buf,int len);
void process_dgram(struct packet_struct *p);
+
+/*The following definitions come from nmbd.c */
+
BOOL reload_services(BOOL test);
+
+/*The following definitions come from nmblib.c */
+
void debug_nmb_packet(struct packet_struct *p);
char *namestr(struct nmb_name *n);
void free_nmb_packet(struct nmb_packet *nmb);
@@ -352,11 +435,23 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type);
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
+
+/*The following definitions come from nmblookup.c */
+
int main(int argc,char *argv[]);
+
+/*The following definitions come from nmbsync.c */
+
char *getsmbpass(char *pass);
void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- char *name, int nm_type, struct in_addr ip);
+ char *name, int nm_type, struct in_addr ip);
+
+/*The following definitions come from params.c */
+
BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
+
+/*The following definitions come from password.c */
+
void generate_next_challenge(char *challenge);
BOOL set_challenge(char *challenge);
BOOL last_challenge(char *challenge);
@@ -376,18 +471,36 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
BOOL check_hosts_equiv(char *user);
BOOL server_cryptkey(char *buf);
BOOL server_validate(char *buf);
+
+/*The following definitions come from pcap.c */
+
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
void pcap_printer_fn(void (*fn)());
+
+/*The following definitions come from predict.c */
+
int read_predict(int fd,int offset,char *buf,char **ptr,int num);
void do_read_prediction();
void invalidate_read_prediction(int fd);
+
+/*The following definitions come from printing.c */
+
void lpq_reset(int snum);
void print_file(int fnum);
int get_printqueue(int snum,int cnum,print_queue_struct **queue,
print_status_struct *status);
void del_printqueue(int cnum,int snum,int jobid);
void status_printjob(int cnum,int snum,int jobid,int status);
+
+/*The following definitions come from quotas.c */
+
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
+
+/*The following definitions come from replace.c */
+
char *Strstr(char *s, char *p);
time_t Mktime(struct tm *t);
int InNetGr(char *group,char *host,char *user,char *dom);
@@ -395,6 +508,9 @@ void *malloc_wrapped(int size,char *file,int line);
void *realloc_wrapped(void *ptr,int size,char *file,int line);
void free_wrapped(void *ptr,char *file,int line);
void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
+
+/*The following definitions come from reply.c */
+
int reply_special(char *inbuf,char *outbuf);
int reply_tcon(char *inbuf,char *outbuf);
int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
@@ -445,6 +561,9 @@ int reply_writebmpx(char *inbuf,char *outbuf);
int reply_writebs(char *inbuf,char *outbuf);
int reply_setattrE(char *inbuf,char *outbuf);
int reply_getattrE(char *inbuf,char *outbuf);
+
+/*The following definitions come from server.c */
+
mode_t unix_mode(int cnum,int dosmode);
int dos_mode(int cnum,char *path,struct stat *sbuf);
int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
@@ -486,6 +605,9 @@ void standard_sub(int cnum,char *s);
char *smb_fn_name(int type);
int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
+
+/*The following definitions come from smbencrypt.c */
+
void str_to_key(uchar *str,uchar *key);
void D1(uchar *k, uchar *d, uchar *out);
void E1(uchar *k, uchar *d, uchar *out);
@@ -494,10 +616,25 @@ void E_P24(uchar *p21, uchar *c8, uchar *p24);
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
void E_md4hash(uchar *passwd, uchar *p16);
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
+
+/*The following definitions come from smbpass.c */
+
+
+/*The following definitions come from smbpasswd.c */
+
+
+/*The following definitions come from smbrun.c */
+
+
+/*The following definitions come from status.c */
+
void Ucrit_addUsername(pstring username);
unsigned int Ucrit_checkUsername(pstring username);
void Ucrit_addPid(int pid);
unsigned int Ucrit_checkPid(int pid);
+
+/*The following definitions come from system.c */
+
int sys_select(fd_set *fds,struct timeval *tval);
int sys_select(fd_set *fds,struct timeval *tval);
int sys_unlink(char *fname);
@@ -512,7 +649,16 @@ int sys_utime(char *fname,struct utimbuf *times);
int sys_rename(char *from, char *to);
int sys_chown(char *fname,int uid,int gid);
int sys_chroot(char *dname);
+
+/*The following definitions come from testparm.c */
+
+
+/*The following definitions come from testprns.c */
+
int main(int argc, char *argv[]);
+
+/*The following definitions come from time.c */
+
void GetTimeOfDay(struct timeval *tval);
void TimeInit(void);
int TimeDiff(time_t t);
@@ -527,20 +673,35 @@ time_t make_unix_date2(void *date_ptr);
time_t make_unix_date3(void *date_ptr);
BOOL set_filetime(char *fname,time_t mtime);
char *timestring(void );
+
+/*The following definitions come from trans2.c */
+
int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
+
+/*The following definitions come from ufc.c */
+
char *ufc_crypt(char *key,char *salt);
+
+/*The following definitions come from uid.c */
+
void init_uid(void);
BOOL become_guest(void);
BOOL become_user(int cnum, int uid);
BOOL unbecome_user(void );
int smbrun(char *cmd,char *outfile);
+
+/*The following definitions come from username.c */
+
char *get_home_dir(char *user);
void map_username(char *user);
struct passwd *Get_Pwnam(char *user,BOOL allow_change);
BOOL user_in_list(char *user,char *list);
+
+/*The following definitions come from util.c */
+
void setup_logging(char *pname,BOOL interactive);
void reopen_logs(void);
BOOL is_a_socket(int fd);
@@ -647,6 +808,9 @@ char *gidtoname(int gid);
void BlockSignals(BOOL block);
void ajt_panic(void);
char *readdirname(void *p);
+
+/*The following definitions come from vt_mode.c */
+
int VT_Check(char *buffer);
int VT_Start_utmp(void);
int VT_Stop_utmp(void);
diff --git a/source3/nameresp.c b/source3/nameresp.c
index 31df799691..14b9956186 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -39,6 +39,19 @@ extern struct in_addr ipgrp;
int num_response_packets = 0;
/***************************************************************************
+ 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;
+}
+
+
+/***************************************************************************
add an initated name query into the list
**************************************************************************/
static void add_response_record(struct subnet_record *d,
@@ -74,20 +87,20 @@ static void dead_netbios_entry(struct subnet_record *d,
inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
switch (n->cmd_type)
- {
+ {
case NAME_QUERY_CONFIRM:
- {
+ {
if (!lp_wins_support()) return; /* only if we're a WINS server */
- if (n->num_msgs == 0)
+ if (n->num_msgs == 0)
{
/* oops. name query had no response. check that the name is
unique and then remove it from our WINS database */
-
+
/* IMPORTANT: see query_refresh_names() */
-
+
if ((!NAME_GROUP(n->nb_flags)))
- {
+ {
struct subnet_record *d = find_subnet(ipgrp);
if (d)
{
@@ -97,24 +110,24 @@ static void dead_netbios_entry(struct subnet_record *d,
*/
remove_netbios_name(d, n->name.name, n->name.name_type,
REGISTER, n->to_ip);
- }
- }
-}
+ }
+ }
+ }
break;
}
case NAME_QUERY_MST_CHK:
-{
+ {
/* if no response received, the master browser must have gone
down on that subnet, without telling anyone. */
-
+
/* IMPORTANT: see response_netbios_packet() */
if (n->num_msgs == 0)
browser_gone(n->name.name, n->to_ip);
break;
}
-
+
case NAME_RELEASE:
{
/* if no response received, it must be OK for us to release the
@@ -122,7 +135,7 @@ static void dead_netbios_entry(struct subnet_record *d,
WINS server) */
/* IMPORTANT: see response_name_release() */
-
+
if (ismyip(n->to_ip))
{
remove_netbios_name(d,n->name.name,n->name.name_type,SELF,n->to_ip);
@@ -133,7 +146,7 @@ static void dead_netbios_entry(struct subnet_record *d,
}
break;
}
-
+
case NAME_REGISTER:
{
/* if no response received, and we are using a broadcast registration
@@ -145,14 +158,14 @@ static void dead_netbios_entry(struct subnet_record *d,
{
/* broadcast method: implicit acceptance of the name registration
by not receiving any objections. */
-
+
/* IMPORTANT: see response_name_reg() */
-
+
enum name_source source = ismyip(n->to_ip) ? SELF : REGISTER;
-
+
add_netbios_entry(d,n->name.name,n->name.name_type,
n->nb_flags, n->ttl, source,n->to_ip, True,!n->bcast);
- }
+ }
else
{
/* XXXX oops. this is where i wish this code could retry DGRAM
@@ -160,12 +173,12 @@ static void dead_netbios_entry(struct subnet_record *d,
received no response. rfc1001.txt states that after retrying,
we should assume the WINS server is dead, and fall back to
broadcasting. */
-
+
DEBUG(1,("WINS server did not respond to name registration!\n"));
}
break;
}
-
+
default:
{
/* nothing to do but delete the dead expected-response structure */
@@ -181,8 +194,8 @@ static void dead_netbios_entry(struct subnet_record *d,
****************************************************************************/
static void initiate_netbios_packet(uint16 *id,
int fd,int quest_type,char *name,int name_type,
- int nb_flags,BOOL bcast,BOOL recurse,
- struct in_addr to_ip)
+ int nb_flags,BOOL bcast,BOOL recurse,
+ struct in_addr to_ip)
{
struct packet_struct p;
struct nmb_packet *nmb = &p.packet.nmb;
@@ -204,9 +217,7 @@ static void initiate_netbios_packet(uint16 *id,
bzero((char *)&p,sizeof(p));
- if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
- (getpid()%(unsigned)100);
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+ update_name_trn_id();
if (*id == 0xffff) *id = name_trn_id; /* allow resending with same id */
@@ -409,7 +420,7 @@ void queue_netbios_pkt_wins(struct subnet_record *d,
static struct response_record *
make_response_queue_record(enum cmd_type cmd,int id,int fd,
int quest_type, char *name,int type, int nb_flags, time_t ttl,
- BOOL bcast,BOOL recurse,struct in_addr ip)
+ BOOL bcast,BOOL recurse, struct in_addr ip)
{
struct response_record *n;
@@ -476,19 +487,24 @@ void queue_netbios_packet(struct subnet_record *d,
/****************************************************************************
find a response in a subnet's name query response list.
**************************************************************************/
-struct response_record *find_response_record(struct subnet_record *d,
+struct response_record *find_response_record(struct subnet_record **d,
uint16 id)
-{
+{
struct response_record *n;
if (!d) return NULL;
- for (n = d->responselist; n; n = n->next)
+ for ((*d) = subnetlist; (*d); (*d) = (*d)->next)
+ {
+ for (n = (*d)->responselist; n; n = n->next)
{
- if (n->response_id == id) {
- return n;
+ if (n->response_id == id) {
+ return n;
}
}
+ }
+
+ *d = NULL;
return NULL;
}
@@ -724,11 +740,13 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
bzero((char *)&p,sizeof(p));
+ update_name_trn_id();
+
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
dgram->header.flags.node_type = M_NODE;
dgram->header.flags.first = True;
dgram->header.flags.more = False;
- dgram->header.dgm_id = name_trn_id++;
+ dgram->header.dgm_id = name_trn_id;
dgram->header.source_ip = src_ip;
dgram->header.source_port = DGRAM_PORT;
dgram->header.dgm_length = 0; /* let build_dgram() handle this */
diff --git a/source3/nameserv.c b/source3/nameserv.c
index 7b72f93952..557bad73c3 100644
--- a/source3/nameserv.c
+++ b/source3/nameserv.c
@@ -121,26 +121,28 @@ void remove_name(struct subnet_record *d, struct name_record *n)
/****************************************************************************
- find a name in a namelist
+ find a name in a namelist.
**************************************************************************/
static struct name_record *find_name(struct name_record *n,
struct nmb_name *name,
int search, struct in_addr ip)
{
- struct name_record *ret;
+ struct name_record *ret;
for (ret = n; ret; ret = ret->next)
- {
+ {
if (name_equal(&ret->name,name))
{
/* self search: self names only */
if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
continue;
-
+
+ /* zero ip is either samba's ip or a way of finding a
+ name without needing to know the ip address */
if (zero_ip(ip) || ip_equal(ip, ret->ip))
{
- return ret;
- }
+ return ret;
+ }
}
}
return NULL;
@@ -159,7 +161,7 @@ static struct name_record *find_name_search(struct subnet_record **d,
int search, struct in_addr ip)
{
if (d == NULL) return NULL; /* bad error! */
-
+
if ((search & FIND_LOCAL) == FIND_LOCAL)
{
if (*d != NULL)
@@ -169,8 +171,8 @@ static struct name_record *find_name_search(struct subnet_record **d,
else
{
DEBUG(4,("local find_name_search with a NULL subnet pointer\n"));
- return NULL;
-}
+ return NULL;
+ }
}
if ((search & FIND_WINS) != FIND_WINS) return NULL;
@@ -223,7 +225,7 @@ void dump_names(void)
fstring data;
/* XXXX i have little imagination as to how to output nb_flags as
- anything other than a hexadecimal number :-) */
+ anything other than as a hexadecimal number :-) */
sprintf(data, "%s#%02x %s %ld %2x",
n->name.name,n->name.name_type, /* XXXX ignore the scope for now */
@@ -238,7 +240,7 @@ void dump_names(void)
DEBUG(3,("%s %15s TTL=%15d NBFLAGS=%2x\n",
namestr(&n->name),
inet_ntoa(n->ip),
- n->death_time?n->death_time-t:0,
+ n->death_time?n->death_time-t:0,
n->nb_flags));
}
@@ -366,7 +368,7 @@ void remove_netbios_name(struct subnet_record *d,
/* if it's not a special browser name, search the WINS database */
if (type != 0x01 && type != 0x1d && type != 0x1e)
search |= FIND_WINS;
-
+
make_nmb_name(&nn, name, type, scope);
n = find_name_search(&d, &nn, search, ip);
@@ -434,7 +436,10 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
n = n2;
}
- if (ttl) n->death_time = time(NULL)+ttl*3;
+ if (ttl)
+ n->death_time = time(NULL)+ttl*3;
+ n->refresh_time = time(NULL)+GET_TTL(ttl);
+
n->ip = ip;
n->nb_flags = nb_flags;
n->source = source;
@@ -453,6 +458,10 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
****************************************************************************/
void remove_name_entry(struct subnet_record *d, char *name,int type)
{
+ /* XXXX BUG: if samba is offering WINS support, it should still broadcast
+ a de-registration packet to the local subnet before removing the
+ name from its local-subnet name database. */
+
if (lp_wins_support())
{
/* we are a WINS server. */
@@ -466,7 +475,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
/* not a WINS server: cannot just remove our own names: we have to
ask permission from the WINS server, or if no reply is received,
_then_ we can remove the name */
-
+
struct name_record n;
struct name_record *n2=NULL;
@@ -508,16 +517,23 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
/* always add our own entries */
add_netbios_entry(d,name,type,nb_flags,0,SELF,ipzero,False,lp_wins_support());
+ /* 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
+ regarding the point about M-nodes. */
+
if (!lp_wins_support())
- {
- /* we aren't supporting WINS: register name using broadcast or
- contact WINS server */
+ {
+ /* samba isn't supporting WINS itself: register the name using broadcast
+ or with another WINS server.
+ XXXX note: we may support WINS and also know about other WINS servers
+ in the future.
+ */
- queue_netbios_pkt_wins(d,ClientNMB,
+ queue_netbios_pkt_wins(d,ClientNMB,
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
name, type, nb_flags, GET_TTL(0),
False, True, ipzero);
- }
+ }
}
@@ -530,12 +546,13 @@ void add_my_names(void)
struct subnet_record *d;
struct in_addr ip = ipzero;
-
- /* each subnet entry, including the WINS one, must have its own
- netbios name. */
- /* XXXX if there was a transport layer added to samba (ipx/spx, netbeui
- etc) then there would be yet _another_ for-loop, this time on the
- transport type */
+
+ /* each subnet entry, including WINS pseudo-subnet, has SELF names */
+
+ /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
+ there would be yet _another_ for-loop, this time on the transport type
+ */
+
for (d = subnetlist; d; d = d->next)
{
add_my_name_entry(d, myname,0x20,NB_ACTIVE);
@@ -548,11 +565,11 @@ void add_my_names(void)
add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
if (wins) {
- /* the 0x1c name gets added by any WINS server it seems */
+ /* the 0x1c name gets added by any WINS server it seems */
add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
+ }
}
}
-}
/****************************************************************************
@@ -560,21 +577,24 @@ void add_my_names(void)
**************************************************************************/
void remove_my_names()
{
- struct subnet_record *d;
+ struct subnet_record *d;
- for (d = subnetlist; d; d = d->next)
- {
- struct name_record *n;
-
- for (n = d->namelist; n; n = n->next)
- {
- if (n->source == SELF)
+ for (d = subnetlist; d; d = d->next)
{
- /* get all SELF names removed from the WINS server's database */
- remove_name_entry(d,n->name.name, n->name.name_type);
+ 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);
+ }
}
}
- }
}
@@ -583,17 +603,31 @@ void remove_my_names()
******************************************************************/
void refresh_my_names(time_t t)
{
- static time_t lasttime = 0;
-
- if (t - lasttime < REFRESH_TIME)
- return;
- lasttime = t;
+ struct subnet_record *d;
- add_my_names();
+ for (d = subnetlist; d; d = d->next)
+ {
+ struct name_record *n;
+
+ for (n = d->namelist; n; n = n->next)
+ {
+ /* each SELF name has an individual time to be refreshed */
+ if (n->source == SELF && n->refresh_time < time(NULL))
+ {
+ add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
+ }
+ }
+ }
}
/*******************************************************************
queries names occasionally. an over-cautious, non-trusting WINS server!
+
+ this function has been added because nmbd could be restarted. it
+ is generally a good idea to check all the names that have been
+ reloaded from file.
+
+ XXXX which names to poll and which not can be refined at a later date.
******************************************************************/
void query_refresh_names(void)
{
@@ -652,34 +686,34 @@ void query_refresh_names(void)
******************************************************************/
void expire_names(time_t t)
{
- struct name_record *n;
- struct name_record *next;
+ struct name_record *n;
+ struct name_record *next;
struct subnet_record *d;
-
- /* expire old names */
+
+ /* expire old names */
for (d = subnetlist; d; d = d->next)
{
for (n = d->namelist; n; n = next)
- {
- if (n->death_time && n->death_time < t)
- {
- DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
-
- next = n->next;
-
- if (n->prev) n->prev->next = n->next;
- if (n->next) n->next->prev = n->prev;
-
+ {
+ if (n->death_time && n->death_time < t)
+ {
+ DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
+
+ next = n->next;
+
+ if (n->prev) n->prev->next = n->next;
+ if (n->next) n->next->prev = n->prev;
+
if (d->namelist == n) d->namelist = n->next;
-
- free(n);
- }
- else
- {
- next = n->next;
+
+ free(n);
+ }
+ else
+ {
+ next = n->next;
+ }
+ }
}
- }
-}
}
@@ -703,9 +737,9 @@ void response_name_release(struct subnet_record *d, struct packet_struct *p)
putip((char*)&found_ip,&nmb->answers->rdata[2]);
if (ismyip(found_ip))
- {
+ {
remove_netbios_name(d,name,type,SELF,found_ip);
- }
+ }
}
else
{
@@ -720,8 +754,8 @@ void response_name_release(struct subnet_record *d, struct packet_struct *p)
/****************************************************************************
- reply to a name release
- ****************************************************************************/
+reply to a name release
+****************************************************************************/
void reply_name_release(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -738,7 +772,7 @@ void reply_name_release(struct packet_struct *p)
putip((char *)&ip,&nmb->additional->rdata[2]);
DEBUG(3,("Name release on name %s rcode=%d\n",
- namestr(&nmb->question.question_name),rcode));
+ namestr(&nmb->question.question_name),rcode));
if (!(d = find_req_subnet(p->ip, bcast)))
{
@@ -773,7 +807,7 @@ void reply_name_release(struct packet_struct *p)
/* Send a NAME RELEASE RESPONSE */
reply_netbios_packet(p,nmb->header.name_trn_id,
- rcode,opcode,True,
+ rcode,opcode,True,
&nmb->question.question_name,
nmb->question.question_type,
nmb->question.question_class,
@@ -783,8 +817,8 @@ void reply_name_release(struct packet_struct *p)
/****************************************************************************
- response for a reg request received
- **************************************************************************/
+response for a reg request received
+**************************************************************************/
void response_name_reg(struct subnet_record *d, struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -820,9 +854,9 @@ void response_name_reg(struct subnet_record *d, struct packet_struct *p)
been rejected: e.g if it was our GROUP(1d) name, we must unbecome
a master browser. */
- if (!(work = find_workgroupstruct(d, name, False))) return;
+ remove_netbios_name(d,name,type,SELF,ipzero);
- /* remove_netbios_name(d,name,type,SELF,ipzero); */
+ if (!(work = find_workgroupstruct(d, name, False))) return;
if (AM_MASTER(work) && (type == 0x1d || type == 0x1b))
{
@@ -837,8 +871,8 @@ void response_name_reg(struct subnet_record *d, struct packet_struct *p)
/****************************************************************************
- reply to a reg request
- **************************************************************************/
+reply to a reg request
+**************************************************************************/
void reply_name_reg(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -848,7 +882,7 @@ void reply_name_reg(struct packet_struct *p)
char *qname = question->name;
int name_type = question->name_type;
int name_class = nmb->question.question_class;
-
+
BOOL bcast = nmb->header.nm_flags.bcast;
int ttl = GET_TTL(nmb->additional->ttl);
@@ -856,7 +890,7 @@ void reply_name_reg(struct packet_struct *p)
BOOL group = NAME_GROUP(nb_flags);
int rcode = 0;
int opcode = nmb->header.opcode;
-
+
struct subnet_record *d = NULL;
struct name_record *n = NULL;
BOOL success = True;
@@ -895,19 +929,19 @@ void reply_name_reg(struct packet_struct *p)
n = find_name_search(&d, question, search, from_ip);
if (n)
- {
- if (!group) /* unique names */
+ {
+ if (!group) /* unique names */
{
if (n->source == SELF || NAME_GROUP(n->nb_flags))
- {
+ {
/* no-one can register one of samba's names, nor can they
register a name that's a group name as a unique name */
rcode = 6;
success = False;
- }
+ }
else if(!ip_equal(ip, n->ip))
- {
+ {
/* hm. this unique name doesn't belong to them. */
/* XXXX rfc1001.txt says:
@@ -931,6 +965,11 @@ void reply_name_reg(struct packet_struct *p)
for checking with current owner of name, then getting back
to us... IF current owner no longer owns the unique name */
+ /* XXXX please note also that samba cannot cope with
+ _receiving_ such redirecting, non-secured registration
+ packets. code to do this needs to be added.
+ */
+
rcode = 0;
success = False;
recurse = False;
@@ -944,21 +983,21 @@ void reply_name_reg(struct packet_struct *p)
name_class = ?;
XXXX sorry, guys: i really can't see what name_type
and name_class should be set to according to rfc1001 */
- }
+ }
else
- {
+ {
n->ip = ip;
n->death_time = ttl?p->timestamp+ttl*3:0;
DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
- }
+ }
}
- else
+ else
{
/* refresh the name */
if (n->source != SELF)
- {
+ {
n->death_time = ttl?p->timestamp + ttl*3:0;
- }
+ }
}
/* XXXX bug reported by terryt@ren.pc.athabascau.ca */
@@ -968,15 +1007,21 @@ void reply_name_reg(struct packet_struct *p)
if (n->source == DNSFAIL)
n->source = REGISTER;
- }
+ }
else
- {
+ {
/* add the name to our name/subnet, or WINS, database */
n = add_netbios_entry(d,qname,name_type,nb_flags,ttl,REGISTER,ip,
True,!bcast);
- }
+ }
- if (bcast) return;
+ /* if samba owns a unique name on a subnet, then it must respond and
+ disallow the attempted registration. if the registration is
+ successful by broadcast, only then is there no need to respond
+ (implicit registration: see rfc1001.txt 15.2.1).
+ */
+
+ if (bcast || !success) return;
rdata[0] = nb_flags;
rdata[1] = 0;
@@ -993,8 +1038,8 @@ void reply_name_reg(struct packet_struct *p)
/****************************************************************************
- reply to a name status query
- ****************************************************************************/
+reply to a name status query
+****************************************************************************/
void reply_name_status(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -1014,16 +1059,16 @@ void reply_name_status(struct packet_struct *p)
inet_ntoa(p->ip)));
return;
}
-
+
DEBUG(3,("Name status for name %s %s\n",
- namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
+ namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
n = find_name_search(&d, &nmb->question.question_name,
FIND_SELF|FIND_LOCAL,
p->ip);
if (!n) return;
-
+
/* XXXX hack, we should calculate exactly how many will fit */
bufend = &rdata[MAX_DGRAM_SIZE] - 18;
countptr = buf = rdata;
@@ -1040,7 +1085,7 @@ void reply_name_status(struct packet_struct *p)
/* start with first bit of putting info in buffer: the name */
bzero(buf,18);
- sprintf(buf,"%-15.15s",n->name.name);
+ sprintf(buf,"%-15.15s",n->name.name);
strupper(buf);
/* now check if we want to exclude other workgroup names
@@ -1062,7 +1107,7 @@ void reply_name_status(struct packet_struct *p)
names_added++;
}
-
+
SCVAL(countptr,0,names_added);
/* XXXXXXX we should fill in more fields of the statistics structure */
@@ -1079,7 +1124,7 @@ void reply_name_status(struct packet_struct *p)
/* Send a POSITIVE NAME STATUS RESPONSE */
reply_netbios_packet(p,nmb->header.name_trn_id,
- 0,0,True,
+ 0,0,True,
&nmb->question.question_name,
nmb->question.question_type,
nmb->question.question_class,
@@ -1107,7 +1152,7 @@ struct name_record *search_for_name(struct subnet_record **d,
n = find_name_search(d,question,search,ip);
if (*d == NULL) return NULL;
-
+
/* now try DNS lookup. */
if (!n)
{
@@ -1186,7 +1231,7 @@ with directed name queries:
a negative response, a positive response, or a wait-for-acknowledgement
packet, and then later on a pos/neg response.
- ****************************************************************************/
+****************************************************************************/
void reply_name_query(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -1253,55 +1298,59 @@ void reply_name_query(struct packet_struct *p)
}
if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
- {
+ {
/* don't respond to broadcast queries unless the query is for
- a name we own or it is for a Primary Domain Controller name */
+ a name we own or it is for a Primary Domain Controller name */
if (bcast && n->source != SELF && name_type != 0x1b) {
- if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
- /* never reply with a negative response to broadcast queries */
- return;
+ if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
+ /* never reply with a negative response to broadcast queries */
+ return;
+ }
}
- }
-
+
/* name is directed query, or it's self, or it's a PDC type name, or
we're replying on behalf of a caller because they are on a different
subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
switched off in environments where broadcasts are forwarded */
+ /* XXXX note: for proxy servers, we should forward the query on to
+ another WINS server if the name is not in our database, or we are
+ not a WINS server ourselves
+ */
ttl = n->death_time - p->timestamp;
retip = n->ip;
nb_flags = n->nb_flags;
- }
+ }
else
- {
+ {
if (bcast) return; /* never reply negative response to bcasts */
success = False;
- }
-
+ }
+
/* if the IP is 0 then substitute my IP */
if (zero_ip(retip)) retip = *iface_ip(p->ip);
-
+
if (success)
- {
+ {
rcode = 0;
DEBUG(3,("OK %s\n",inet_ntoa(retip)));
- }
+ }
else
- {
+ {
rcode = 3;
DEBUG(3,("UNKNOWN\n"));
- }
+ }
if (success)
- {
+ {
rdata[0] = nb_flags;
rdata[1] = 0;
putip(&rdata[2],(char *)&retip);
- }
+ }
reply_netbios_packet(p,nmb->header.name_trn_id,
- rcode,0,True,
+ rcode,0,True,
&nmb->question.question_name,
nmb->question.question_type,
nmb->question.question_class,
@@ -1332,7 +1381,7 @@ static void response_server_check(struct nmb_name *ans_name,
/****************************************************************************
response from a name status check. commands of type NAME_STATUS_MASTER_CHECK
and NAME_STATUS_CHECK dealt with here.
-****************************************************************************/
+ ****************************************************************************/
static void response_name_status_check(struct in_addr ip,
struct nmb_packet *nmb, BOOL bcast,
struct response_record *n, struct subnet_record *d)
@@ -1345,18 +1394,18 @@ static void response_name_status_check(struct in_addr ip,
if (interpret_node_status(d,nmb->answers->rdata,
&name,0x1d,serv_name,ip,bcast))
- {
+ {
if (*serv_name)
{
sync_server(n->cmd_type,serv_name,
name.name,name.name_type, n->to_ip);
- }
- }
+ }
+ }
else
{
DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
- }
- }
+ }
+}
/****************************************************************************
@@ -1369,7 +1418,14 @@ static void response_name_query_sync(struct nmb_packet *nmb,
{
DEBUG(4, ("Name query at %s ip %s - ",
namestr(&n->name), inet_ntoa(n->to_ip)));
-
+
+ if (!name_equal(n->name, ans_name))
+ {
+ /* someone gave us the wrong name as a reply. oops. */
+ DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+ return;
+ }
+
if (nmb->header.rcode == 0 && nmb->answers->rdata)
{
int nb_flags = nmb->answers->rdata[0];
@@ -1377,6 +1433,14 @@ static void response_name_query_sync(struct nmb_packet *nmb,
putip((char*)&found_ip,&nmb->answers->rdata[2]);
+ if (!ip_equal(n->ip, found_ip))
+ {
+ /* someone gave us the wrong ip as a reply. oops. */
+ DEBUG(4,("expected ip: %s\n", inet_ntoa(n->ip)));
+ DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
+ return;
+ }
+
DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
if (n->cmd_type == NAME_QUERY_SYNC)
@@ -1388,12 +1452,12 @@ static void response_name_query_sync(struct nmb_packet *nmb,
sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
found_ip);
}
- }
+ }
else
{
- /* update our netbios name list */
+ /* 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),STATUS_QUERY,
+ nb_flags,GET_TTL(0),REGISTER,
found_ip,False,!bcast);
}
}
@@ -1408,6 +1472,8 @@ static void response_name_query_sync(struct nmb_packet *nmb,
then we're in a mess: our name database doesn't match
reality. sort it out
*/
+ remove_netbios_name(d,n->name.name, n->name.name_type,
+ REGISTER,n->ip);
}
}
}
@@ -1416,7 +1482,7 @@ static void response_name_query_sync(struct nmb_packet *nmb,
report the response record type
****************************************************************************/
static void debug_rr_type(int rr_type)
- {
+{
switch (rr_type)
{
case NMB_STATUS: DEBUG(3,("Name status ")); break;
@@ -1446,7 +1512,7 @@ static void debug_cmd_type(int cmd_type)
case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
default: break;
- }
+ }
}
/****************************************************************************
@@ -1456,39 +1522,39 @@ static void debug_cmd_type(int cmd_type)
****************************************************************************/
static BOOL response_problem_check(struct response_record *n,
struct nmb_packet *nmb, char *qname)
- {
+{
switch (nmb->answers->rr_type)
- {
+ {
case NMB_REL:
{
if (n->num_msgs > 1)
{
DEBUG(1,("more than one release name response received!\n"));
return True;
- }
+ }
break;
- }
+ }
case NMB_REG:
- {
+ {
if (n->num_msgs > 1)
{
DEBUG(1,("more than one register name response received!\n"));
return True;
- }
- break;
- }
-
+ }
+ break;
+ }
+
case NMB_QUERY:
- {
+ {
if (n->num_msgs > 1)
- {
+ {
if (nmb->header.rcode == 0 && nmb->answers->rdata)
{
int nb_flags = nmb->answers->rdata[0];
-
+
if ((!NAME_GROUP(nb_flags)))
- {
+ {
/* oh dear. more than one person responded to a unique name.
there is either a network problem, a configuration problem
or a server is mis-behaving */
@@ -1501,7 +1567,7 @@ static BOOL response_problem_check(struct response_record *n,
/* this may cause problems for some early versions of nmbd */
switch (n->cmd_type)
- {
+ {
case NAME_QUERY_MST_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_MST_CHK:
@@ -1521,17 +1587,17 @@ static BOOL response_problem_check(struct response_record *n,
}
DEBUG(3,("Unique Name conflict detected!\n"));
return True;
+ }
}
- }
- else
- {
+ else
+ {
/* we have received a negative reply, having already received
at least one response (pos/neg). something's really wrong! */
DEBUG(3,("wierd name query problem detected!\n"));
return True;
- }
- }
+ }
+ }
}
}
return False;
@@ -1542,7 +1608,7 @@ static BOOL response_problem_check(struct response_record *n,
****************************************************************************/
static BOOL response_compatible(struct response_record *n,
struct nmb_packet *nmb)
- {
+{
switch (n->cmd_type)
{
case NAME_RELEASE:
@@ -1551,19 +1617,19 @@ static BOOL response_compatible(struct response_record *n,
{
DEBUG(1,("Name release reply has wrong answer rr_type\n"));
return False;
- }
- break;
- }
-
+ }
+ break;
+ }
+
case NAME_REGISTER:
- {
+ {
if (nmb->answers->rr_type != NMB_REG)
- {
+ {
DEBUG(1,("Name register reply has wrong answer rr_type\n"));
return False;
}
break;
- }
+ }
case NAME_QUERY_CONFIRM:
case NAME_QUERY_SYNC:
@@ -1572,30 +1638,30 @@ static BOOL response_compatible(struct response_record *n,
case NAME_QUERY_FIND_MST:
case NAME_QUERY_MST_CHK:
{
- if (nmb->answers->rr_type != NMB_QUERY)
- {
- DEBUG(1,("Name query reply has wrong answer rr_type\n"));
+ if (nmb->answers->rr_type != NMB_QUERY)
+ {
+ DEBUG(1,("Name query reply has wrong answer rr_type\n"));
return False;
- }
- break;
- }
+ }
+ break;
+ }
case NAME_STATUS_MASTER_CHECK:
case NAME_STATUS_CHECK:
- {
+ {
if (nmb->answers->rr_type != NMB_STATUS)
- {
+ {
DEBUG(1,("Name status reply has wrong answer rr_type\n"));
return False;
}
break;
}
-
+
default:
{
DEBUG(0,("unknown command received in response_netbios_packet\n"));
break;
- }
+ }
}
return True;
}
@@ -1609,7 +1675,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
BOOL bcast, struct nmb_name *ans_name)
{
switch (n->cmd_type)
- {
+ {
case NAME_RELEASE:
{
response_name_release(d, p);
@@ -1620,15 +1686,15 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
{
response_name_reg(d, p);
break;
- }
-
+ }
+
case NAME_QUERY_MST_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_FIND_MST:
{
response_server_check(ans_name, n, d);
- break;
- }
+ break;
+ }
case NAME_STATUS_MASTER_CHECK:
case NAME_STATUS_CHECK:
@@ -1654,11 +1720,11 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
}
default:
- {
- DEBUG(0,("unknown command received in response_netbios_packet\n"));
- break;
- }
+ {
+ DEBUG(0,("unknown command received in response_netbios_packet\n"));
+ break;
}
+ }
}
@@ -1675,9 +1741,21 @@ static void response_netbios_packet(struct packet_struct *p)
struct response_record *n;
struct subnet_record *d = NULL;
- if (!(d = find_req_subnet(p->ip, bcast)))
+ if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
+ DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
+ return;
+ }
+
+ if (!d)
+ {
+ DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
+ return;
+ }
+
+ if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
{
- DEBUG(3,("response packet: bcast %s not known\n", inet_ntoa(p->ip)));
+ DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
+ DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
return;
}
@@ -1693,11 +1771,6 @@ static void response_netbios_packet(struct packet_struct *p)
DEBUG(3,("response for %s from %s (bcast=%s)\n",
namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
- if (!(n = find_response_record(d,nmb->header.name_trn_id))) {
- DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
- return;
- }
-
debug_rr_type(nmb->answers->rr_type);
n->num_msgs++; /* count number of responses received */
@@ -1728,22 +1801,22 @@ void process_nmb(struct packet_struct *p)
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)
+ {
+ if (nmb->header.response)
{
switch (nmb->question.question_type)
{
@@ -1755,7 +1828,7 @@ void process_nmb(struct packet_struct *p)
}
return;
}
- else if (nmb->header.qdcount>0)
+ else if (nmb->header.qdcount>0)
{
switch (nmb->question.question_type)
{
@@ -1776,8 +1849,8 @@ void process_nmb(struct packet_struct *p)
}
case NMB_REL:
- {
- if (nmb->header.qdcount==0 || nmb->header.arcount==0)
+ {
+ if (nmb->header.qdcount==0 || nmb->header.arcount==0)
{
DEBUG(2,("netbios release packet rejected\n"));
break;
@@ -1787,8 +1860,8 @@ void process_nmb(struct packet_struct *p)
response_netbios_packet(p); /* response to reply dealt with in here */
else
reply_name_release(p);
- break;
- }
+ break;
}
+ }
}