summaryrefslogtreecommitdiff
path: root/source3
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 /source3
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)
Diffstat (limited to 'source3')
-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;
}
+ }
}