From 7a804a2e838846715f036e5e93630a4436a4ec4b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Mon, 1 Jul 1996 18:29:21 +0000 Subject: 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) --- source3/include/proto.h | 238 ++++++++++++++++++++---- source3/nameresp.c | 82 +++++---- source3/nameserv.c | 471 ++++++++++++++++++++++++++++-------------------- 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 @@ -38,6 +38,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 **************************************************************************/ @@ -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; } + } } -- cgit