From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/libsmb/nmblib.c | 936 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 936 insertions(+) create mode 100644 source3/libsmb/nmblib.c (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c new file mode 100644 index 0000000000..6743227173 --- /dev/null +++ b/source3/libsmb/nmblib.c @@ -0,0 +1,936 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios library routines + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" +#include "nameserv.h" + +extern int DEBUGLEVEL; + +int num_good_sends=0; +int num_good_receives=0; +static uint16 name_trn_id = 0; +BOOL CanRecurse = True; +extern pstring scope; + +/******************************************************************* + handle "compressed" name pointers + ******************************************************************/ +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, + BOOL *got_pointer,int *ret) +{ + int loop_count=0; + + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); +} + +/******************************************************************* + parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid + ******************************************************************/ +static int parse_nmb_name(char *inbuf,int offset,int length, + struct nmb_name *name) +{ + int m,n=0; + unsigned char *ubuf = (unsigned char *)inbuf; + int ret = 0; + BOOL got_pointer=False; + + if (length - offset < 2) return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + + m = ubuf[offset]; + + if (!m) return(0); + if ((m & 0xC0) || offset+m+2 > length) return(0); + + bzero((char *)name,sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) ret += m + 2; + offset++; + while (m) { + unsigned char c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0)) return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==16) { + /* parse out the name type, + its always in the 16th byte of the name */ + name->name_type = name->name[15]; + + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while ((m=ubuf[offset])) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + + if (!got_pointer) ret += m+1; + if (n) name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); + offset++; + while (m--) name->scope[n++] = (char)ubuf[offset++]; + } + name->scope[n++] = 0; + + return(ret); +} + + +/******************************************************************* + put a compressed nmb name into a buffer. return the length of the + compressed name + + compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. + ******************************************************************/ +static int put_nmb_name(char *buf,int offset,struct nmb_name *name) +{ + int ret,m; + fstring buf1; + char *p; + + if (name->name[0] == '*') { + /* special case for wildcard name */ + bzero(buf1,20); + buf1[0] = '*'; + } else { + sprintf(buf1,"%-15.15s%c",name->name,name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m<16;m++) { + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + strcpy(&buf[offset+1],name->scope); + + p = &buf[offset+1]; + while ((p = strchr(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset]); + offset += buf[offset]; + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); +} + +/******************************************************************* + useful for debugging messages + ******************************************************************/ +char *namestr(struct nmb_name *n) +{ + static int i=0; + static fstring ret[4]; + char *p = ret[i]; + + if (!n->scope[0]) + sprintf(p,"%s(%x)",n->name,n->name_type); + else + sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope); + + i = (i+1)%4; + return(p); +} + +/******************************************************************* + allocate are parse some resource records + ******************************************************************/ +static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, + struct res_rec **recs, + int count) +{ + int i; + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) return(False); + + bzero(*recs,sizeof(**recs)*count); + + for (i=0;i length) { + free(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + free(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); +} + +/******************************************************************* + put a resource record into a packet + ******************************************************************/ +static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) +{ + int ret=0; + int i; + + for (i=0;iheader.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) dgram->header.flags.more = True; + if (flags & 2) dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } + + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); + + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); + + return(True); +} + + +/******************************************************************* + parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + ******************************************************************/ +static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) +{ + int nm_flags,offset; + + bzero((char *)nmb,sizeof(*nmb)); + + if (length < 12) return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); + + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) return(False); + + if (length - (12+offset) < 4) return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); + + if (nmb->header.arcount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); + + return(True); +} + +/******************************************************************* + free up any resources associated with an nmb packet + ******************************************************************/ +void free_nmb_packet(struct nmb_packet *nmb) +{ + if (nmb->answers) free(nmb->answers); + if (nmb->nsrecs) free(nmb->nsrecs); + if (nmb->additional) free(nmb->additional); +} + +/******************************************************************* + free up any resources associated with a packet + ******************************************************************/ +void free_packet(struct packet_struct *packet) +{ + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + free(packet); +} + +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct *read_packet(int fd,enum packet_type packet_type) +{ + extern struct in_addr lastip; + extern int lastport; + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + BOOL ok=False; + + length = read_udp_socket(fd,buf,sizeof(buf)); + if (length < MIN_DGRAM_SIZE) return(NULL); + + packet = (struct packet_struct *)malloc(sizeof(*packet)); + if (!packet) return(NULL); + + packet->next = NULL; + packet->prev = NULL; + packet->ip = lastip; + packet->port = lastport; + packet->fd = fd; + packet->timestamp = time(NULL); + packet->packet_type = packet_type; + switch (packet_type) + { + case NMB_PACKET: + ok = parse_nmb(buf,length,&packet->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram(buf,length,&packet->packet.dgram); + break; + } + if (!ok) { + free(packet); + return(NULL); + } + + num_good_receives++; + + DEBUG(4,("%s received a packet of len %d from (%s) port %d\n", + timestring(),length,inet_ntoa(packet->ip),packet->port)); + + return(packet); +} + + +/******************************************************************* + send a udp packet on a already open socket + ******************************************************************/ +static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) +{ + BOOL ret; + struct sockaddr_in sock_out; + + /* set the address and port */ + bzero((char *)&sock_out,sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; + + DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n", + timestring(),len,inet_ntoa(ip),port)); + + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, + sizeof(sock_out)) >= 0); + + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); + + if (ret) + num_good_sends++; + + return(ret); +} + +/******************************************************************* + build a dgram packet ready for sending + + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. + ******************************************************************/ +static int build_dgram(char *buf,struct packet_struct *p) +{ + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) ubuf[1] |= 1; + if (dgram->header.flags.first) ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length */ + dgram->header.dgm_length = offset; + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); +} + +/******************************************************************* + build a nmb name + ******************************************************************/ +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) +{ + strcpy(n->name,name); + strupper(n->name); + n->name_type = type; + strcpy(n->scope,this_scope); +} + + +/******************************************************************* + build a nmb packet ready for sending + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) + ******************************************************************/ +static int build_nmb(char *buf,struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); + + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + if (nmb->header.arcount) + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + + return(offset); +} + + +/******************************************************************* + send a packet_struct + ******************************************************************/ +BOOL send_packet(struct packet_struct *p) +{ + char buf[1024]; + int len=0; + + bzero(buf,sizeof(buf)); + + switch (p->packet_type) + { + case NMB_PACKET: + len = build_nmb(buf,p); + break; + + case DGRAM_PACKET: + len = build_dgram(buf,p); + break; + } + + if (!len) return(False); + + return(send_udp(p->fd,buf,len,p->ip,p->port)); +} + +/**************************************************************************** + receive a packet with timeout on a open UDP filedescriptor + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_packet(int fd,enum packet_type type,int t) +{ + fd_set fds; + struct timeval timeout; + + FD_ZERO(&fds); + FD_SET(fd,&fds); + timeout.tv_sec = t/1000; + timeout.tv_usec = 1000*(t%1000); + + sys_select(&fds,&timeout); + + if (FD_ISSET(fd,&fds)) + return(read_packet(fd,type)); + + return(NULL); +} + + +/**************************************************************************** +interpret a node status response +****************************************************************************/ +static void interpret_node_status(char *p, char *master,char *rname) +{ + int level = (master||rname)?4:0; + int numnames = CVAL(p,0); + DEBUG(level,("received %d names\n",numnames)); + + if (rname) *rname = 0; + if (master) *master = 0; + + p += 1; + while (numnames--) + { + char qname[17]; + int type; + fstring flags; + *flags = 0; + StrnCpy(qname,p,15); + type = CVAL(p,15); + p += 16; + + if (p[0] & 0x80) strcat(flags," "); + if ((p[0] & 0x60) == 0) strcat(flags,"B "); + if ((p[0] & 0x60) == 1) strcat(flags,"P "); + if ((p[0] & 0x60) == 2) strcat(flags,"M "); + if ((p[0] & 0x60) == 3) strcat(flags,"_ "); + if (p[0] & 0x10) strcat(flags," "); + if (p[0] & 0x08) strcat(flags," "); + if (p[0] & 0x04) strcat(flags," "); + if (p[0] & 0x02) strcat(flags," "); + + if (master && !*master && type == 0x1d) { + StrnCpy(master,qname,15); + trim_string(master,NULL," "); + } + + if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { + StrnCpy(rname,qname,15); + trim_string(rname,NULL," "); + } + + DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags)); + p+=2; + } + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", + IVAL(p,20),IVAL(p,24))); +} + + +/**************************************************************************** + do a netbios name status query on a host + + the "master" parameter is a hack used for finding workgroups. + **************************************************************************/ +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname, + void (*fn)()) +{ + BOOL found=False; + int retries = 2; + int retry_time = 5000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + + 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; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = CanRecurse; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x21; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + interpret_node_status(&nmb2->answers->rdata[0], master,rname); + free_packet(p2); + return(True); + } + } + + + DEBUG(0,("No status response (this is not unusual)\n")); + + return(False); +} + + +/**************************************************************************** + do a netbios name query to find someones IP + ****************************************************************************/ +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)()) +{ + BOOL found=False; + int retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + + 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; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = CanRecurse; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later + (put it on the queue?) */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + if (ip) { + putip((char *)ip,&nmb2->answers->rdata[2]); + DEBUG(fn?3:2,("Got a positive name query response from %s", + inet_ntoa(p2->ip))); + DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); + } + found=True; retries=0; + free_packet(p2); + if (fn) break; + } + } + + return(found); +} + + +/**************************************************************************** + construct and send a netbios DGRAM + + Note that this currently sends all answers to port 138. thats the + wrong things to do! I should send to the requestors port. XXX + **************************************************************************/ +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len, + char *srcname,char *dstname, + int src_type,int dest_type, + struct in_addr dest_ip, + struct in_addr src_ip) +{ + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr,*p2; + char tmp[4]; + + bzero((char *)&p,sizeof(p)); + + 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.source_ip = src_ip; + dgram->header.source_port = DGRAM_PORT; + dgram->header.dgm_length = 0; /* let build_dgram() handle this */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,src_type,scope); + make_nmb_name(&dgram->dest_name,dstname,dest_type,scope); + + ptr = &dgram->data[0]; + + /* now setup the smb part */ + ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + strcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buf,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */ + + p.ip = dest_ip; + p.port = DGRAM_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + return(send_packet(&p)); +} + + -- cgit From 58734631b4233ec08b7a262587e400792f31f185 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 May 1996 15:13:29 +0000 Subject: Lots of changes! - add faq info on NT printer handling - add "delete readonly" option to help rcs users - add stuff to man pages on new printer options - add "proxy name resolution" option - add "command string" -c option to smbclient (thanks Ken) - split time functions into time.c - rearrange the quotas stuff a bit and fix some bugs - complete rehash of the time handling code thanks to Paul Eggert - fix nmblookup output a bit - add plp print queue parsing from Bertrand Wallrich (This used to be commit 635b56f19c817527c52e9bbde31faa6a8a47777b) --- source3/libsmb/nmblib.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6743227173..1f78996156 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -625,16 +625,17 @@ static void interpret_node_status(char *p, char *master,char *rname) char qname[17]; int type; fstring flags; + int i; *flags = 0; StrnCpy(qname,p,15); type = CVAL(p,15); p += 16; - if (p[0] & 0x80) strcat(flags," "); - if ((p[0] & 0x60) == 0) strcat(flags,"B "); - if ((p[0] & 0x60) == 1) strcat(flags,"P "); - if ((p[0] & 0x60) == 2) strcat(flags,"M "); - if ((p[0] & 0x60) == 3) strcat(flags,"_ "); + strcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); if (p[0] & 0x10) strcat(flags," "); if (p[0] & 0x08) strcat(flags," "); if (p[0] & 0x04) strcat(flags," "); @@ -650,7 +651,10 @@ static void interpret_node_status(char *p, char *master,char *rname) trim_string(rname,NULL," "); } - DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags)); + for (i = strlen( qname) ; --i >= 0 ; ) { + if (!isprint(qname[i])) qname[i] = '.'; + } + DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); p+=2; } DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", -- cgit From a2c1623827406667a4f2f058c24f1d971f6627f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 06:42:03 +0000 Subject: a huge pile of changes :-) The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c) --- source3/libsmb/nmblib.c | 445 +++++++++++------------------------------------- 1 file changed, 101 insertions(+), 344 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1f78996156..d8d6eb0ee4 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,15 +21,104 @@ */ #include "includes.h" -#include "nameserv.h" +#include "localnet.h" +#include "loadparm.h" +extern struct in_addr myip; extern int DEBUGLEVEL; -int num_good_sends=0; -int num_good_receives=0; -static uint16 name_trn_id = 0; -BOOL CanRecurse = True; +int num_good_sends = 0; +int num_good_receives = 0; extern pstring scope; +extern pstring myname; +extern struct in_addr ipzero; + + +/**************************************************************************** + print out a res_rec structure + ****************************************************************************/ +static void debug_nmb_res_rec(struct res_rec *res, char *hdr) +{ + int i, j; + + DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl)); + + if (res->rdlength == 0 || res->rdata == NULL) return; + + for (i = 0; i < res->rdlength; i+= 16) + { + DEBUG(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < 16; j++) + { + unsigned char x = res->rdata[i+j]; + if (x < 32 || x > 127) x = '.'; + + if (i+j >= res->rdlength) break; + DEBUG(4, ("%c", x)); + } + + DEBUG(4, (" hex ", i)); + + for (j = 0; j < 16; j++) + { + if (i+j >= res->rdlength) break; + DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + } + + DEBUG(4, ("\n")); + } +} + +/**************************************************************************** + process a nmb packet + ****************************************************************************/ +void debug_nmb_packet(struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + + DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n", + inet_ntoa(p->ip), + nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response))); + DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative))); + DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount)); + + if (nmb->header.qdcount) + { + DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n", + namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class)); + } + + if (nmb->answers && nmb->header.ancount) + { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) + { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) + { + debug_nmb_res_rec(nmb->additional,"additional"); + } +} /******************************************************************* handle "compressed" name pointers @@ -38,7 +127,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; - + while ((ubuf[*offset] & 0xC0) == 0xC0) { if (!*got_pointer) (*ret) += 2; (*got_pointer)=True; @@ -54,8 +143,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, parse a nmb name from "compressed" format to something readable return the space taken by the name, or 0 if the name is invalid ******************************************************************/ -static int parse_nmb_name(char *inbuf,int offset,int length, - struct nmb_name *name) +static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) { int m,n=0; unsigned char *ubuf = (unsigned char *)inbuf; @@ -186,11 +274,10 @@ char *namestr(struct nmb_name *n) } /******************************************************************* - allocate are parse some resource records + allocate and parse some resource records ******************************************************************/ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, - struct res_rec **recs, - int count) + struct res_rec **recs, int count) { int i; *recs = (struct res_rec *)malloc(sizeof(**recs)*count); @@ -382,10 +469,10 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - + length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -528,6 +615,7 @@ static int build_nmb(char *buf,struct packet_struct *p) if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; ubuf[offset+3] |= (nmb->header.rcode & 0xF); + RSSVAL(ubuf,offset+4,nmb->header.qdcount); RSSVAL(ubuf,offset+6,nmb->header.ancount); RSSVAL(ubuf,offset+8,nmb->header.nscount); @@ -607,334 +695,3 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) } -/**************************************************************************** -interpret a node status response -****************************************************************************/ -static void interpret_node_status(char *p, char *master,char *rname) -{ - int level = (master||rname)?4:0; - int numnames = CVAL(p,0); - DEBUG(level,("received %d names\n",numnames)); - - if (rname) *rname = 0; - if (master) *master = 0; - - p += 1; - while (numnames--) - { - char qname[17]; - int type; - fstring flags; - int i; - *flags = 0; - StrnCpy(qname,p,15); - type = CVAL(p,15); - p += 16; - - strcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); - if (p[0] & 0x10) strcat(flags," "); - if (p[0] & 0x08) strcat(flags," "); - if (p[0] & 0x04) strcat(flags," "); - if (p[0] & 0x02) strcat(flags," "); - - if (master && !*master && type == 0x1d) { - StrnCpy(master,qname,15); - trim_string(master,NULL," "); - } - - if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { - StrnCpy(rname,qname,15); - trim_string(rname,NULL," "); - } - - for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint(qname[i])) qname[i] = '.'; - } - DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); - p+=2; - } - DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", - IVAL(p,20),IVAL(p,24))); -} - - -/**************************************************************************** - do a netbios name status query on a host - - the "master" parameter is a hack used for finding workgroups. - **************************************************************************/ -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname, - void (*fn)()) -{ - BOOL found=False; - int retries = 2; - int retry_time = 5000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - - 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; - - nmb->header.name_trn_id = name_trn_id; - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = CanRecurse; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type,scope); - - nmb->question.question_type = 0x21; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return(False); - - retries--; - - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount || - nmb2->answers->rr_type != 0x21) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; - } - - interpret_node_status(&nmb2->answers->rdata[0], master,rname); - free_packet(p2); - return(True); - } - } - - - DEBUG(0,("No status response (this is not unusual)\n")); - - return(False); -} - - -/**************************************************************************** - do a netbios name query to find someones IP - ****************************************************************************/ -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)()) -{ - BOOL found=False; - int retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - - 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; - - nmb->header.name_trn_id = name_trn_id; - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = CanRecurse; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type,scope); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return(False); - - retries--; - - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later - (put it on the queue?) */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; - } - - if (ip) { - putip((char *)ip,&nmb2->answers->rdata[2]); - DEBUG(fn?3:2,("Got a positive name query response from %s", - inet_ntoa(p2->ip))); - DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); - } - found=True; retries=0; - free_packet(p2); - if (fn) break; - } - } - - return(found); -} - - -/**************************************************************************** - construct and send a netbios DGRAM - - Note that this currently sends all answers to port 138. thats the - wrong things to do! I should send to the requestors port. XXX - **************************************************************************/ -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len, - char *srcname,char *dstname, - int src_type,int dest_type, - struct in_addr dest_ip, - struct in_addr src_ip) -{ - struct packet_struct p; - struct dgram_packet *dgram = &p.packet.dgram; - char *ptr,*p2; - char tmp[4]; - - bzero((char *)&p,sizeof(p)); - - 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.source_ip = src_ip; - dgram->header.source_port = DGRAM_PORT; - dgram->header.dgm_length = 0; /* let build_dgram() handle this */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,src_type,scope); - make_nmb_name(&dgram->dest_name,dstname,dest_type,scope); - - ptr = &dgram->data[0]; - - /* now setup the smb part */ - ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - strcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buf,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */ - - p.ip = dest_ip; - p.port = DGRAM_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - return(send_packet(&p)); -} - - -- cgit From a2641cfe00b7857056fd8fd1e020aae7ea817690 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 15:14:47 +0000 Subject: Did more integration of Lukes code ready for the first release. I've now got WINS registration working, and refresh working. Its looking pretty good so far, but needs lots of testing. (This used to be commit 045014aa57721b9701ca379bcab055b908773184) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d8d6eb0ee4..87fe5fee78 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -472,7 +472,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); -- cgit From e38afbf38210b8cf30c5b13dc5ea96a6dda433f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Jun 1996 15:16:09 +0000 Subject: - changed some debug levels in clientutil.c - added dir_check_ftype() to clean up the file type checking a bit - added check for libc version >= 5 for setfsuid() for Linux - moved the AM_MASTER() and related macros to nameserv.h - added proper defines for the various netbios announce types - don't call the announce_backup() code, as I'm pretty sure its wrong it sent ANN_GetBackupListReq packets as broadcasts, they are supposed to be used only by clients to the master browser to find a list of available backup servers to remote a netserverenum to, I don't think nmbd should ever send one. - fixed a bug in the browse list writing - minor debug cleanups - put in the code to discard our own broadcasts (it won't work for multi-homed hosts though) - changed ELECTION_VERSION to 1 so we can be beaten by a NT 3.51 server by lowering the os level. - only do sync_browse_lists() if we are the master browser, otherwise we'll cause network overload - don't call tell_become_backup() as it appears to be badly broken, it should only be used when the machine being told has its MAINTAIN_LIST to to auto. Not calling it does no great harm anyway - fix a nasty bug where becomebackup was confused with reset browser! - make setbuffer() not get caught by the auto protototypes (This used to be commit cfbad9b08242962f41595273de08a7293fe432b1) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 87fe5fee78..d82d89f653 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -500,7 +500,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) num_good_receives++; - DEBUG(4,("%s received a packet of len %d from (%s) port %d\n", + DEBUG(5,("%s received a packet of len %d from (%s) port %d\n", timestring(),length,inet_ntoa(packet->ip),packet->port)); return(packet); @@ -521,7 +521,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n", + DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n", timestring(),len,inet_ntoa(ip),port)); ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, -- cgit From b9ae225b28f4707609e6436dad4be7ebdd7e181f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jun 1996 11:43:09 +0000 Subject: - added interface.c and removed all the references to myip, bcast_ip and Netmask, instead replacing them with calls to routines in interface.c - got rid of old MAXINT define - added code to ensure we only return one entry for each name in the ipc enum routines - added new_only option to add_netbios_entry() to prevent overwriting of important names - minor time handling fixup (This used to be commit 7ed71b73ae745da099072eee36fc2700d1d91407) --- source3/libsmb/nmblib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d82d89f653..e1737cd41c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,10 +21,8 @@ */ #include "includes.h" -#include "localnet.h" #include "loadparm.h" -extern struct in_addr myip; extern int DEBUGLEVEL; int num_good_sends = 0; -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/libsmb/nmblib.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e1737cd41c..3434f31a33 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; -- cgit From 396311075cc808278e6dd8469e3ac7eb7e7498c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Aug 1996 08:57:55 +0000 Subject: - sequent-ptx support from bressler@iftccu.ca.boeing.com (Rick Bressler) - machten support from Trevor Strohman (trev@figment.tenon.com) - added qinfo command to client as part of drag-and-drop printer support for win95 from David Chappell He also added the "printer driver" option - use sigblock() on more systems and use sigsetmask(0) instead of sigunblock() as its more portable. This beats a problem with zombies on heavilily loaded systems. - added internals.doc written by David Chappell into the source tree - get rid of PRINT_COMMAND options from local.h as they are no longer relevent - new kanji code from Fujita - don't set the recursion_available flag on queries in nmbd - fix a potential bug with pointer subtraction in printing.c - got rid of error_count code as the real fix (the EOF problem) is now in (This used to be commit aa6f8b04d125b5bc00f267abf72b800228aabf7d) --- source3/libsmb/nmblib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3434f31a33..4113b34cab 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -609,7 +609,8 @@ static int build_nmb(char *buf,struct packet_struct *p) if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) ubuf[offset+3] |= 0x80; if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; ubuf[offset+3] |= (nmb->header.rcode & 0xF); -- cgit From 5a2f52b79e28530c454cb488a44588147640f061 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 14:09:22 +0000 Subject: - a huge pile of changes from Luke which implement the browse.conf stuff and also fix a pile of nmbd bugs. Unfortunately I found it very hard to disentangle the new features from the bug fixes so I am putting in the new code. I hope this is the last big pile of changes to the 1.9.16 series! (This used to be commit 20b6203dac4bbb43e4e7bea0b214496d76d679d9) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4113b34cab..ef5c9da434 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -65,7 +65,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUG(4, ("%02x", (unsigned char)res->rdata[i+j])); } DEBUG(4, ("\n")); -- cgit From afd08462ad5ff6b3c4bf621e39c55853a608175e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 15:41:30 +0000 Subject: backout all the changes to nmbd. The 1.9.16 tree is now back to 1.9.16p2 as far as nmbd is concerned apart from a small change that fixes the announce type in two places. (This used to be commit 45e66a69d320024877c8b13f12b21bf895e04410) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ef5c9da434..4113b34cab 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -65,7 +65,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02x", (unsigned char)res->rdata[i+j])); + DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); } DEBUG(4, ("\n")); -- cgit From 38087ccb4071bfff29801026e2bf5c47565305b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Oct 1996 02:54:37 +0000 Subject: - use workgroup from smb.conf in smbclient - change debug level on clitar stuff - define MAP_FILE if not defined - ensure we never set authoritative on queries in nmbd - fake a positive response to SMBioctl, apparently this is needed for some WfWg printer drivers - deny file access for non-fcbopen queries when (access_allowed == AREAD && flags == O_RDWR) - add sys_waitpid() (This used to be commit 61e3116e573637d6b5a878eeb8db72831e3c5bd1) --- source3/libsmb/nmblib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4113b34cab..c70311f997 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -395,7 +395,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; nmb->header.rcode = CVAL(inbuf,3) & 0xF; nmb->header.qdcount = RSVAL(inbuf,4); nmb->header.ancount = RSVAL(inbuf,6); @@ -606,7 +606,8 @@ static int build_nmb(char *buf,struct packet_struct *p) RSSVAL(ubuf,offset,nmb->header.name_trn_id); ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.authoritative && + nmb->header.response) ubuf[offset+2] |= 0x4; if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; if (nmb->header.nm_flags.recursion_available && -- cgit From ab0bdc6682815fe9878afdda6cc8119798fa2770 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 7 Mar 1997 17:28:41 +0000 Subject: Added better debug for what kind of netbios packet we got. jra@cygnus.com (This used to be commit 4563d978feaed37aab78e62461026a79dbc50249) --- source3/libsmb/nmblib.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c70311f997..a0f93331d9 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -30,6 +30,34 @@ extern pstring scope; extern pstring myname; extern struct in_addr ipzero; +static struct opcode_names { + const char *nmb_opcode_name; + int opcode; +} nmb_header_opcode_names[] = { + { "Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"refresh", 8 }, + {0, -1 } +}; + +/**************************************************************************** + * Lookup a nmb opcode name. + ****************************************************************************/ + +const char *lookup_opcode_name( int opcode ) +{ + struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; +} /**************************************************************************** print out a res_rec structure @@ -79,9 +107,11 @@ void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n", + DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n", inet_ntoa(p->ip), - nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response))); + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode,BOOLSTR(nmb->header.response))); DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", BOOLSTR(nmb->header.nm_flags.bcast), BOOLSTR(nmb->header.nm_flags.recursion_available), -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index a0f93331d9..89a5cf9534 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios library routines - Copyright (C) Andrew Tridgell 1994-1995 + Copyright (C) Andrew Tridgell 1994-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 3ab97ebe6db1a5a4a0573c7c8482c94876bbce9a Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 30 May 1997 20:40:48 +0000 Subject: charcnv.c: Fixed silly bugs detected on IRIX. client.c: Fixed silly bugs detected on IRIX. namedbname.c: Stopped 1d names from being registered in WINS db. namedbsubnet.c: Only register 1e names on broadcast subnet. nameelect.c: Changed add_my_name entries. Forced host announces if we have less than 10 servers listed. Fixed registering 1b domain name issues. namepacket.c: Added error message when dgram discarded. nameserv.c: Added notion of 'direct' names that are not registered on the network. Needed to get around bugs in earlier nmbd handling of DOMAIN(1b) names. nameservreply.c:Tidied up debug message. nameservresp.c: Added response_name_query_domain() code. Deals with re-registering DOMAIN(1b) name. nmbd.c: Fixed silly bugs detected on IRIX. nmblib.c: Added paranoia debugs. proto.h: Updated remove_name_entry(), add_my_name_entry(). server.c: Fixed silly bugs detected on IRIX. trans2.c: Fixed silly bugs detected on IRIX. uid.c: Fixed silly bugs detected on IRIX. version.h: Updated to alpha3. Jeremy (jallison@whistle.com). (This used to be commit f08222bd8b86a061c52d22015f946a4737eb47fd) --- source3/libsmb/nmblib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 89a5cf9534..bc967bdacb 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -418,6 +418,9 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) /* parse the header */ nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); @@ -521,6 +524,8 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) break; } if (!ok) { + DEBUG(10,("parse_nmb: discarding packet id = %d\n", + packet->packet.nmb.header.name_trn_id)); free(packet); return(NULL); } -- cgit From 33a003de4056532be0c9a199d4857b9da1b18034 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Sep 1997 16:37:18 +0000 Subject: This commit does 3 main things: 1) put the encryption code in by default, with no #ifdef. It is still disabled by default so you need to add "encrypt passwords = yes" in smb.conf but at least all binaries will have it. 2) cleanup the kanji code so it compiles with no warnings 3) get rid of lots of uses of ugly non-portable C code. The main offender being things like "register" but also remove uses of the "const" keyword as there are compilers out there that don't support it and even those that do often complain about its usage. Users don't like warnings :-( There is still some work to do. We need to replace the md4 code with our own implementation. The current code (from rfc1186) is PD but is not very portable. The new RFC (rfc1320) is more portable but adds copyright restrictions. I'll do a from-scratch MD4 soon. We also need to test that what I've implemented is portable. It should be, but I'm too tired right now to test it on anything other than intel linux. (This used to be commit db917c62c14315afe6f0745a8097c1bca25cbf07) --- source3/libsmb/nmblib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index bc967bdacb..456a8218d8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -31,8 +31,8 @@ extern pstring myname; extern struct in_addr ipzero; static struct opcode_names { - const char *nmb_opcode_name; - int opcode; + char *nmb_opcode_name; + int opcode; } nmb_header_opcode_names[] = { { "Query", 0 }, {"Registration", 5 }, @@ -46,7 +46,7 @@ static struct opcode_names { * Lookup a nmb opcode name. ****************************************************************************/ -const char *lookup_opcode_name( int opcode ) +char *lookup_opcode_name( int opcode ) { struct opcode_names *op_namep; int i; -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 456a8218d8..48f988de2a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -616,10 +616,10 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - strcpy(n->name,name); + fstrcpy(n->name,name); strupper(n->name); n->name_type = type; - strcpy(n->scope,this_scope); + fstrcpy(n->scope,this_scope); } -- cgit From 54c3f7bbb02bc12fec53aeb042f5356f100e3472 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Oct 1997 09:17:21 +0000 Subject: add the port number to a debug statement (This used to be commit 97d06dd05e952a134be26ec5998ec4b8d38991dd) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 48f988de2a..e8f281bc25 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -107,8 +107,8 @@ void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), + DEBUG(4,("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, nmb->header.name_trn_id, lookup_opcode_name(nmb->header.opcode), nmb->header.opcode,BOOLSTR(nmb->header.response))); -- cgit From e5c319186d079eeef55a7ee62fac2a993e932938 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Oct 1997 11:02:00 +0000 Subject: Implemented asynchronous DNS lookups in nmbd. I realised this afternoon just how easy it is to add this, so I thought I'd implement it while the idea was fresh. nmbd forks at startup and uses a pipe to talk to its child. The child does the DNS lookups and the file descriptor of the child is added to the main select loop. While I was doing this I discovered a bug in nmbd that explains why the dns proxy option has been so expensive. The DNS cache entries in the WINS list were never being checked, which means we always did a DNS lookup even if we have done it before and it is in cache. I'm sure this used to work (I tested the DNS cache when I added it) so someone broke it :-( Anyway, the async DNS gets rid of the problem completely. I'll commit just the fix to the DNS cache bug to the 1.9.17 tree. You can disable async DNS by adding -DSYNC_DNS to the compile flags. (This used to be commit 178e27de0791c1ff3268cb456ed5c5efc9ac2a01) --- source3/libsmb/nmblib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e8f281bc25..121008685b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -482,9 +482,11 @@ void free_nmb_packet(struct nmb_packet *nmb) ******************************************************************/ void free_packet(struct packet_struct *packet) { - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - free(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + free(packet); } /******************************************************************* @@ -511,6 +513,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) packet->ip = lastip; packet->port = lastport; packet->fd = fd; + packet->locked = False; packet->timestamp = time(NULL); packet->packet_type = packet_type; switch (packet_type) -- cgit From be0f2e14b5d32fe29b57e4c80f8da5c9cfa66e60 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 24 Oct 1997 13:51:17 +0000 Subject: nmblib.c : adding some debug info pipenetlog.c pipentlsa.c pipesrvsvc.c : using unistrn2 instead of unistr2 in the SAM logon username. wrong offset for command in request (use "reserved" field not cancel_count. AGH i'll get there) (This used to be commit 6d301d2cfd25b18ba18685d926d7a5bc08695b6d) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 121008685b..6a91b20ea8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -697,6 +697,7 @@ BOOL send_packet(struct packet_struct *p) { case NMB_PACKET: len = build_nmb(buf,p); + debug_nmb_packet(p); break; case DGRAM_PACKET: -- cgit From 64f0348a3f994334abe64a4d4896109c3c8c9039 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Dec 1997 14:16:07 +0000 Subject: This is it ! The mega-merge of the JRA_NMBD_REWRITE branch back into the main tree. For the cvs logs of all the files starting nmbd_*.c, look in the JRA_NMBD_REWRITE branch. That branch has now been discontinued. Jeremy. (This used to be commit d80b0cb645f81d16734929a0b27a91c6650499bb) --- source3/libsmb/nmblib.c | 161 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 147 insertions(+), 14 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6a91b20ea8..0335f01833 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -34,11 +34,13 @@ static struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { - { "Query", 0 }, + {"Query", 0 }, {"Registration", 5 }, {"Release", 6 }, {"WACK", 7 }, - {"refresh", 8 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, {0, -1 } }; @@ -205,7 +207,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na if (n==16) { /* parse out the name type, its always in the 16th byte of the name */ - name->name_type = name->name[15]; + name->name_type = ((unsigned char)name->name[15]) & 0xff; /* remove trailing spaces */ name->name[15] = 0; @@ -249,6 +251,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) /* special case for wildcard name */ bzero(buf1,20); buf1[0] = '*'; + buf1[15] = name->name_type; } else { sprintf(buf1,"%-15.15s%c",name->name,name->name_type); } @@ -292,9 +295,9 @@ char *namestr(struct nmb_name *n) char *p = ret[i]; if (!n->scope[0]) - sprintf(p,"%s(%x)",n->name,n->name_type); + sprintf(p,"%s<%02x>",n->name,n->name_type); else - sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope); + sprintf(p,"%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); @@ -467,26 +470,146 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) return(True); } +/******************************************************************* + 'Copy constructor' for an nmb packet + ******************************************************************/ +static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) +{ + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) + { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) + { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) + { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + +free_and_exit: + + if(copy_nmb->answers) + free((char *)copy_nmb->answers); + if(copy_nmb->nsrecs) + free((char *)copy_nmb->nsrecs); + if(copy_nmb->additional) + free((char *)copy_nmb->additional); + free((char *)pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; +} + +/******************************************************************* + 'Copy constructor' for a dgram packet + ******************************************************************/ +static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) +{ + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; +} + +/******************************************************************* + 'Copy constructor' for a generic packet + ******************************************************************/ +struct packet_struct *copy_packet(struct packet_struct *packet) +{ + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; +} + /******************************************************************* free up any resources associated with an nmb packet ******************************************************************/ -void free_nmb_packet(struct nmb_packet *nmb) +static void free_nmb_packet(struct nmb_packet *nmb) { if (nmb->answers) free(nmb->answers); if (nmb->nsrecs) free(nmb->nsrecs); if (nmb->additional) free(nmb->additional); } +/******************************************************************* + free up any resources associated with a dgram packet + ******************************************************************/ +static void free_dgram_packet(struct dgram_packet *nmb) +{ + /* We have nothing to do for a dgram packet. */ +} + /******************************************************************* free up any resources associated with a packet ******************************************************************/ void free_packet(struct packet_struct *packet) { - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - free(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + free(packet); } /******************************************************************* @@ -619,12 +742,22 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - fstrcpy(n->name,name); + StrnCpy(n->name,name,15); strupper(n->name); - n->name_type = type; - fstrcpy(n->scope,this_scope); + n->name_type = (unsigned int)type & 0xFF; + StrnCpy(n->scope,this_scope,63); } +/******************************************************************* + Compare two nmb names + ******************************************************************/ + +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) +{ + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); +} /******************************************************************* build a nmb packet ready for sending -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0335f01833..1400b88434 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios library routines - Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Andrew Tridgell 1994-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From a1db330263e15a9c5db9fe38a7278bd1408ae79d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Mar 1998 01:27:27 +0000 Subject: RFC1002 says we must put compressed name pointers in the following outgoing packets : NMB_NAME_REG_OPCODE, NMB_NAME_RELEASE_OPCODE, NMB_NAME_REFRESH_OPCODE, NMB_NAME_MULTIHOMED_REG_OPCODE. A WINS server written by Shadow Software was rejecting our packets as we weren't using name pointers in those requests (talk about picky :-). Jeremy. (This used to be commit a31aa09173db30c39f59d4ee5761075b0e00dd71) --- source3/libsmb/nmblib.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1400b88434..f2aee12615 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -362,6 +362,27 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) return(ret); } +/******************************************************************* + put a compressed name pointer record into a packet + ******************************************************************/ +static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) +{ + int ret=0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; + + return(ret); +} + /******************************************************************* parse a dgram packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise @@ -808,10 +829,27 @@ static int build_nmb(char *buf,struct packet_struct *p) offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, nmb->header.nscount); - if (nmb->header.arcount) + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + + } else if (nmb->header.arcount) { offset += put_res_rec((char *)ubuf,offset,nmb->additional, nmb->header.arcount); - + } return(offset); } -- cgit From e7ac86607c80912e55ac7179b100cea22749c16f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Apr 1998 01:12:08 +0000 Subject: This looks like a big change but really isn't. It is changing the global variables "myname" and "myworkgroup" to "global_myname" and "global_myworkgroup" respectively. This is to make it very explicit when we are messing with a global (don't ask - it makes the domain client code much clearer :-). Jeremy. (This used to be commit 866406bfe399cf757c8275093dacd5ce4843afa0) --- source3/libsmb/nmblib.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f2aee12615..9c7b260c59 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -27,7 +27,6 @@ extern int DEBUGLEVEL; int num_good_sends = 0; int num_good_receives = 0; extern pstring scope; -extern pstring myname; extern struct in_addr ipzero; static struct opcode_names { -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9c7b260c59..5a8a037ce5 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -294,9 +294,9 @@ char *namestr(struct nmb_name *n) char *p = ret[i]; if (!n->scope[0]) - sprintf(p,"%s<%02x>",n->name,n->name_type); + slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); else - sprintf(p,"%s<%02x>.%s",n->name,n->name_type,n->scope); + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 5a8a037ce5..6c178758c6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -252,7 +252,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) buf1[0] = '*'; buf1[15] = name->name_type; } else { - sprintf(buf1,"%-15.15s%c",name->name,name->name_type); + slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); } buf[offset] = 0x20; @@ -270,7 +270,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - strcpy(&buf[offset+1],name->scope); + pstrcpy(&buf[offset+1],name->scope); p = &buf[offset+1]; while ((p = strchr(p,'.'))) { -- cgit From 4b587cd3ed32b416b43865bcc0afb21d7af3eecb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 May 1998 05:03:17 +0000 Subject: test for overflow in nmb name parsing code (This used to be commit 204a939807d6fe66fcd721aabf7a88ee33eb23d6) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6c178758c6..f59371d559 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -197,7 +197,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0)) return(0); + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0); name->name[n++] = (c1<<4) | c2; m -= 2; } -- cgit From d8b0a8bab2334e9214975e3ac35c1556c4030fd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Jun 1998 00:27:44 +0000 Subject: nisppass.c: Fixed incorrect parameter usage. nmbd_become_lmb.c: Add 'force_new_election' parameter to some functions. This allows the start of the election to be done *after* the demotion from local master browser is done. Also changed code so release of 1d name is done immediately to allow other local master to gain it. nmbd_elections.c: Ensured no elections are run until we have registered the WORKGROUP<1e> name that we must listen on to participate in elections. nmbd_incomingdgrams.c: Use force_new_election code. nmbd_namelistdb.c: Make update_name_in_namelist static. nmbd_subnetdb.c: Fix bug in comparison function. We cannot use memcmp as structure packing may make this fail. nmbd_packets.c: Ensure that we only send one release packet when sending a broadcast packet. nmbd_workgroupdb.c: Ensure we put the correct value in the ElectionCriterion field. nmblib.c: Ensure make_nmb_name zero's the struct nmb_name. Jeremy. (This used to be commit 1fcb094ba04f01be1261ac92198c25b21b0d5ad5) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f59371d559..89b0fa7a92 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -762,6 +762,7 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { + memset((char *)n, '\0', sizeof(struct nmb_name)); StrnCpy(n->name,name,15); strupper(n->name); n->name_type = (unsigned int)type & 0xFF; -- cgit From a5ddf0881e2410b7d4d8f1a389785e4db28d989e Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Tue, 14 Jul 1998 01:52:09 +0000 Subject: Added strupper() function call to up-case the scope field in the make_nmb_name() function. Database lookups (eg. gdbm) will often use byte-by-byte comparisons, so it is important that the case and padding are correct. Chris -)----- (This used to be commit d64ca4250ff0df4ceffe49b7d462df699a6981b4) --- source3/libsmb/nmblib.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 89b0fa7a92..66f85d40fd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -759,14 +759,15 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name - ******************************************************************/ -void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) + *******************************************************************/ +void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope ) { - memset((char *)n, '\0', sizeof(struct nmb_name)); - StrnCpy(n->name,name,15); - strupper(n->name); + memset( (char *)n, '\0', sizeof(struct nmb_name) ); + StrnCpy( n->name, name, 15 ); + strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; - StrnCpy(n->scope,this_scope,63); + StrnCpy( n->scope, this_scope, 63 ); + strupper( n->scope ); } /******************************************************************* -- cgit From 28900ea26ff1c8d41328bba30206db7fe91e2184 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 31 Jul 1998 22:39:15 +0000 Subject: As per a Andrew's message, I went through and removed the timestring() timestamps from several DEBUG messages. The timestamps are redundant now that DEBUG() provides them automatically. There are still a few more files to do, but I've got to get home for dinner. Chris -)----- (This used to be commit 60286ccecaa6028d687e6406755016455e3b3a26) --- source3/libsmb/nmblib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 66f85d40fd..62c3f22b1a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -678,8 +678,8 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) num_good_receives++; - DEBUG(5,("%s received a packet of len %d from (%s) port %d\n", - timestring(),length,inet_ntoa(packet->ip),packet->port)); + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa(packet->ip), packet->port ) ); return(packet); } @@ -699,8 +699,8 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n", - timestring(),len,inet_ntoa(ip),port)); + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); -- cgit From f1abfacd4d230075e5c4029271f2f3952ac2c68a Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 3 Aug 1998 18:13:13 +0000 Subject: I finished removing timestring() calls from DEBUG() messages. Also went through and changed some DEBUG() calls to DEBUGADD() to combine output under a single timestamp. There were too many timestamps. Note that Jeremy has told me that he's working on adding a config parameter to turn timestamps off. Cool. Chris -)----- (This used to be commit 247dbc9a24987035a47f1ba4fa143b1e2c050e92) --- source3/libsmb/nmblib.c | 77 ++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 62c3f22b1a..9c7a606a26 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -67,18 +67,19 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) { int i, j; - DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl)); - - if (res->rdlength == 0 || res->rdata == NULL) return; + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; for (i = 0; i < res->rdlength; i+= 16) { - DEBUG(4, (" %s %3x char ", hdr, i)); + DEBUGADD(4, (" %s %3x char ", hdr, i)); for (j = 0; j < 16; j++) { @@ -86,18 +87,18 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) if (x < 32 || x > 127) x = '.'; if (i+j >= res->rdlength) break; - DEBUG(4, ("%c", x)); + DEBUGADD(4, ("%c", x)); } - DEBUG(4, (" hex ", i)); + DEBUGADD(4, (" hex ", i)); for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); } - DEBUG(4, ("\n")); + DEBUGADD(4, ("\n")); } } @@ -107,34 +108,38 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - - DEBUG(4,("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode,BOOLSTR(nmb->header.response))); - DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative))); - DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount)); + + if( DEBUGLVL( 4 ) ) + { + dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response) ); + dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative) ); + dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount ); + } if (nmb->header.qdcount) { - DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n", - namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class)); + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); } - if (nmb->answers && nmb->header.ancount) + if (nmb->answers && nmb->header.ancount) { debug_nmb_res_rec(nmb->answers,"answers"); } -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9c7a606a26..c887ff55de 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -90,7 +90,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) DEBUGADD(4, ("%c", x)); } - DEBUGADD(4, (" hex ", i)); + DEBUGADD(4, (" hex ")); for (j = 0; j < 16; j++) { -- cgit From 8978aae69699ccab76fdf95037948b1cc7e7c286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 03:52:05 +0000 Subject: much cleaner chain pointer handling for both files and pipes. the chain pointer is now stored as a static and is set whenever a handle is created or extracted. This also makes the code less error prone. (This used to be commit 068a862982bea726e8d7b1b4065d510b9840a272) --- source3/libsmb/nmblib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c887ff55de..9390302ab2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -26,8 +26,6 @@ extern int DEBUGLEVEL; int num_good_sends = 0; int num_good_receives = 0; -extern pstring scope; -extern struct in_addr ipzero; static struct opcode_names { char *nmb_opcode_name; -- cgit From 38142a1ebbe860778e26eaff68585726061c05e2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Aug 1998 21:46:29 +0000 Subject: This checking fixes the statcache bug that stopped NetBench from running correctly. Added new parameter "stat cache size" - set to 50 by default. I now declare the statcache code officially "open" for business :-). It gets a hit rate of 97% with a NetBench run and seems to make using a case insensitive run as efficient as a case sensitive run. Also tidied up our sys_select usage - added a maxfd parameter and also added an implementation of select in terms of poll(), for systems where poll() is much faster. This is disabled by default. Jeremy. (This used to be commit 779b924ec1f6c81ff578d22295b20fece698d1fc) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9390302ab2..81a9505d6b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -899,7 +899,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(&fds,&timeout); + sys_select(fd+1,&fds,&timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 179e8c66f121e01b5e69ad8b1c39f8a1a1e45814 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Aug 1998 08:45:23 +0000 Subject: changed the way that name query records are sorted in replies. They are now sorted by the number of common leading bits in the IP address with the address of the querying host. (This used to be commit 4460a1bc6aa7666d1c71d32ba73855d6ed32320a) --- source3/libsmb/nmblib.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 81a9505d6b..7729380615 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -908,3 +908,47 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) } +/**************************************************************************** +return the number of bits that match between two 4 character buffers + ***************************************************************************/ +static int matching_bits(uchar *p1, uchar *p2) +{ + int i, j, ret = 0; + for (i=0; i<4; i++) { + if (p1[i] != p2[i]) break; + ret += 8; + } + + if (i==4) return ret; + + for (j=0; j<8; j++) { + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + ret++; + } + + return ret; +} + + +static uchar sort_ip[4]; + +/**************************************************************************** +compare two query reply records + ***************************************************************************/ +static int name_query_comp(uchar *p1, uchar *p2) +{ + return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); +} + +/**************************************************************************** +sort a set of 6 byte name query response records so that the IPs that +have the most leading bits in common with the specified address come first + ***************************************************************************/ +void sort_query_replies(char *data, int n, struct in_addr ip) +{ + if (n <= 1) return; + + putip(sort_ip, (char *)&ip); + + qsort(data, n, 6, name_query_comp); +} -- cgit From cc022132a6dd937eff330612ebaaefe23bff8a6c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 03:13:20 +0000 Subject: cast the qsort to prevent warnings (This used to be commit 55333edd2eed33961ced4eb4b6898f5ca9ca1820) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7729380615..ab57590b6f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -950,5 +950,5 @@ void sort_query_replies(char *data, int n, struct in_addr ip) putip(sort_ip, (char *)&ip); - qsort(data, n, 6, name_query_comp); + qsort(data, n, 6, QSORT_CAST name_query_comp); } -- cgit From e9ea36e4d2270bd7d32da12ef6d6e2299641582d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:07:05 +0000 Subject: tridge the destroyer returns! prompted by the interpret_security() dead code that Jean-Francois pointed out I added a make target "finddead" that finds potentially dead (ie. unused) code. It spat out 304 function names ... I went through these are deleted many of them, making others static (finddead also reports functions that are used only in the local file). in doing this I have almost certainly deleted some useful code. I may have even prevented compilation with some compile options. I apologise. I decided it was better to get rid of this code now and add back the one or two functions that are needed than to keep all this baggage. So, if I have done a bit too much "destroying" then let me know. Keep the swearing to a minimum :) One bit I didn't do is the ubibt code. Chris, can you look at that? Heaps of unused functions there. Can they be made static? (This used to be commit 2204475c87f3024ea8fd1fbd7385b2def617a46f) --- source3/libsmb/nmblib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ab57590b6f..d08003133f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -44,8 +44,7 @@ static struct opcode_names { /**************************************************************************** * Lookup a nmb opcode name. ****************************************************************************/ - -char *lookup_opcode_name( int opcode ) +static char *lookup_opcode_name( int opcode ) { struct opcode_names *op_namep; int i; -- cgit From 7c3c022a8913aec76a175095475cfcf8a4dfd698 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 10:46:52 +0000 Subject: use *SMBSERVER convention in smbwrapper to allow us to connect to servers that we don't know the netbios name of. (This used to be commit 147d49dade3901835b5d60b02c495bea544ff5e9) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d08003133f..87f483e9fd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -248,7 +248,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) fstring buf1; char *p; - if (name->name[0] == '*') { + if (strcmp(name->name,"*") == 0) { /* special case for wildcard name */ bzero(buf1,20); buf1[0] = '*'; -- cgit From d85dcf86d59c14cb624bbb69b658fc6aba842593 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Nov 1998 06:12:19 +0000 Subject: largely rewrote smbpasswd so that the code is understandable. This should allow us to call a function in swat rather than piping to smbpasswd. while doing this I also fixed quite a few "const char *" versus "char *" issues that cropped up while using const to track down bugs in the code. This led to changes in several generic functions. The smbpasswd changes should be correct but they have not been extensively tested. At least if I have introduced bugs then we should be able to fix them more easily than before. (This used to be commit 713864dd0322ae2ae2d83e333d85be35a7eed4ec) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 87f483e9fd..6314a9076b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -762,7 +762,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name *******************************************************************/ -void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope ) +void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) { memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); -- cgit From 24ca89bfb03fb82e975eff94070275ee403cd0f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Nov 1998 01:04:13 +0000 Subject: Removed acconfig.h configure configure.in include/config.h.in: Made smbwrapper not made by default. nmbd*: Changed all calls to namestr() to nmbd_namestr() to fix broken FreeBSD include file problem...sigh. Jeremy. (This used to be commit 9ee8f39aed8772a05c203161b4ae6b7d90d67481) --- source3/libsmb/nmblib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6314a9076b..b91a2944a3 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -66,7 +66,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", hdr, - namestr(&res->rr_name), + nmb_namestr(&res->rr_name), res->rr_type, res->rr_class, res->ttl ) ); @@ -131,7 +131,7 @@ void debug_nmb_packet(struct packet_struct *p) if (nmb->header.qdcount) { DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - namestr(&nmb->question.question_name), + nmb_namestr(&nmb->question.question_name), nmb->question.question_type, nmb->question.question_class) ); } @@ -289,7 +289,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) /******************************************************************* useful for debugging messages ******************************************************************/ -char *namestr(struct nmb_name *n) +char *nmb_namestr(struct nmb_name *n) { static int i=0; static fstring ret[4]; -- cgit From 3ba68d045c4f1f2c6dea014d11189cbabc3e0eb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 14 Nov 1998 04:16:07 +0000 Subject: automatically uppercase server and share names (win95 won't handle lowercase share names!) (This used to be commit dddf1d8522707b828cac466c4a9ab2807d098573) --- source3/libsmb/nmblib.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b91a2944a3..7f3bcc9642 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -764,12 +764,12 @@ static int build_dgram(char *buf,struct packet_struct *p) *******************************************************************/ void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) { - memset( (char *)n, '\0', sizeof(struct nmb_name) ); - StrnCpy( n->name, name, 15 ); - strupper( n->name ); - n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, this_scope, 63 ); - strupper( n->scope ); + memset( (char *)n, '\0', sizeof(struct nmb_name) ); + StrnCpy( n->name, name, 15 ); + strupper( n->name ); + n->name_type = (unsigned int)type & 0xFF; + StrnCpy( n->scope, this_scope, 63 ); + strupper( n->scope ); } /******************************************************************* -- cgit From e204f1d8a3f54cb6bd8549b15a59af9a525b3392 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Nov 1998 04:15:23 +0000 Subject: Changes to make the default prefix /usr/local/samba - as it was in 1.9.18p10. acconfig.h configure configure.in include/config.h.in: Fixes to DEC OSF1. libsmb/nmblib.c: Fixes to nmbd jumps in scope names. Jeremy. (This used to be commit 5ad77769be85e6727319afb0f02e5d94c2f9f16f) --- source3/libsmb/nmblib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7f3bcc9642..14dc5ecee2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -218,10 +218,11 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na /* now the domain parts (if any) */ n = 0; - while ((m=ubuf[offset])) { + while (ubuf[offset]) { /* we can have pointers within the domain part as well */ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + m = ubuf[offset]; if (!got_pointer) ret += m+1; if (n) name->scope[n++] = '.'; if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); -- cgit From f63e8070488e079c899cde90e8452796f3af4e5f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 19:02:37 +0000 Subject: safe string version of nmb_namestr. (This used to be commit 250621b3cec5fc463d348432d1d0ff5fb59e7a29) --- source3/libsmb/nmblib.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 14dc5ecee2..54b1779f44 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -287,6 +287,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) return(ret); } + /******************************************************************* useful for debugging messages ******************************************************************/ @@ -296,15 +297,23 @@ char *nmb_namestr(struct nmb_name *n) static fstring ret[4]; char *p = ret[i]; - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); + nmb_safe_namestr(n, p, sizeof(fstring)); i = (i+1)%4; return(p); } +/******************************************************************* + useful for debugging messages + ******************************************************************/ +void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len) +{ + if (!n->scope[0]) + slprintf(str, len-1, "%s<%02x>",n->name,n->name_type); + else + slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); +} + /******************************************************************* allocate and parse some resource records ******************************************************************/ -- cgit From ccc8585567804d6a7e6f684a97d58871e2fd9f8a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 18 Nov 1999 00:26:11 +0000 Subject: added regqueryval command (experimental) to get reg_io_q_info() and reg_io_r_info() working properly. previously they weren't well understood (well, they were the first of the registry functions i did, back in december 97, ok??? :-) set ntversion to 0x1 in SAMQUERY, so that we reply same as NT4 srv. (This used to be commit 98ddeaf442cb30972cb281bf0489a6e5f7eb2883) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 54b1779f44..9dca4731ad 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -742,7 +742,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /* put in the header */ ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2); if (dgram->header.flags.more) ubuf[1] |= 1; if (dgram->header.flags.first) ubuf[1] |= 2; RSSVAL(ubuf,2,dgram->header.dgm_id); -- cgit From 6ddfc68e0496dc41f8c9a022a0b04a2066b43c9d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 02:15:14 +0000 Subject: sys_select added one more argument (read, write selectors). (This used to be commit e4d92ff9dfc51735e6932748f66a7c20b2c1cb6a) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9dca4731ad..ba951a809a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -908,7 +908,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + sys_select(fd+1,&fds,NULL, &timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From f521205cb3d188fdcadcbd205dcfda4a7dcb89a0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 19:14:37 +0000 Subject: jeremy is going to hate me for this. created an "nmb-agent" utility that, yes: it connects to the 137 socket and accepts unix socket connections which it redirects onto port 137. it uses the name_trn_id field to filter requests to the correct location. name_query() and name_status() are the first victims to use this feature (by specifying a file descriptor of -1). (This used to be commit d923bc8da2cf996408194d98381409191dd81a16) --- source3/libsmb/nmblib.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ba951a809a..127cfeb130 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -651,15 +651,38 @@ void free_packet(struct packet_struct *packet) struct packet_struct *read_packet(int fd,enum packet_type packet_type) { extern struct in_addr lastip; + struct nmb_state con; extern int lastport; struct packet_struct *packet; char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - length = read_udp_socket(fd,buf,sizeof(buf)); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + uint16 trn_id = 0; + if (!read_nmb_sock(fd, &con)) + { + return False; + } + if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + return False; + } + } + + length = read_udp_socket(fd,buf,sizeof(buf)); + + dump_data(100, buf, length); + if (length < MIN_DGRAM_SIZE) return(NULL); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + lastip = con.ip; + lastport = con.port; + } + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -674,15 +697,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) switch (packet_type) { case NMB_PACKET: + case NMB_SOCK_PACKET: ok = parse_nmb(buf,length,&packet->packet.nmb); break; case DGRAM_PACKET: + case DGRAM_SOCK_PACKET: ok = parse_dgram(buf,length,&packet->packet.dgram); break; } if (!ok) { - DEBUG(10,("parse_nmb: discarding packet id = %d\n", + DEBUG(10,("read_packet: discarding packet id = %d\n", packet->packet.nmb.header.name_trn_id)); free(packet); return(NULL); @@ -880,18 +905,65 @@ BOOL send_packet(struct packet_struct *p) switch (p->packet_type) { case NMB_PACKET: + case NMB_SOCK_PACKET: len = build_nmb(buf,p); debug_nmb_packet(p); break; case DGRAM_PACKET: + case DGRAM_SOCK_PACKET: len = build_dgram(buf,p); break; } if (!len) return(False); - return(send_udp(p->fd,buf,len,p->ip,p->port)); + switch (p->packet_type) + { + case DGRAM_PACKET: + case NMB_PACKET: + return(send_udp(p->fd,buf,len,p->ip,p->port)); + break; + + case NMB_SOCK_PACKET: + case DGRAM_SOCK_PACKET: + { + fstring qbuf; + struct nmb_state nmb; + int qlen; + uint16 trn_id; + char *q = qbuf + 4; + + nmb.ip = p->ip; + nmb.port = p->port; + + SSVAL(q, 0, 0); + q += 2; + SSVAL(q, 0, 0); + q += 2; + memcpy(q, &nmb, sizeof(nmb)); + q += sizeof(nmb); + + qlen = PTR_DIFF(q, qbuf); + SIVAL(qbuf, 0, qlen); + + dump_data(100, qbuf, qlen); + + if (write(p->fd,qbuf,qlen) != qlen) + { + return False; + } + qlen = read(p->fd, &trn_id, sizeof(trn_id)); + + if (qlen != sizeof(trn_id)) + { + return False; + } + return write(p->fd,buf,len) == len; + } + } + + return False; } /**************************************************************************** @@ -961,3 +1033,76 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } + +BOOL read_nmb_sock(int c, struct nmb_state *con) +{ + fstring buf; + char *p = buf; + int rl; + uint32 len; + uint16 version; + uint16 command; + + ZERO_STRUCTP(con); + + rl = read(c, &buf, sizeof(len)); + + if (rl < 0) + { + DEBUG(0,("read_nmb_sock: error\n")); + return False; + } + if (rl != sizeof(len)) + { + DEBUG(0,("Unable to read length\n")); + dump_data(0, buf, sizeof(len)); + return False; + } + + len = IVAL(buf, 0); + + if (len > sizeof(buf)) + { + DEBUG(0,("length %d too long\n", len)); + return False; + } + + rl = read(c, buf, len); + + if (rl < 0) + { + DEBUG(0,("Unable to read from connection\n")); + return False; + } + +#ifdef DEBUG_PASSWORD + dump_data(100, buf, rl); +#endif + version = SVAL(p, 0); + p += 2; + command = SVAL(p, 0); + p += 2; + + memcpy(con, p, sizeof(*con)); + p += sizeof(*con); + + DEBUG(10,("read_nmb_sock: ip %s port: %d\n", + inet_ntoa(con->ip), con->port)); + + if (PTR_DIFF(p, buf) != rl) + { + DEBUG(0,("Buffer size %d %d!\n", + PTR_DIFF(p, buf), rl)); + return False; + } + + return True; +} + +int get_nmb_sock(void) +{ + fstring path; + slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent"); + + return open_pipe_sock(path); +} -- cgit From ddda7722a673cefc89a55133f99c07dd153b1f19 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 23:40:21 +0000 Subject: argh! how horrible! spent ages working out why packets weren't being received properly when a UDP "retry" occurs. it's because reads and writes must be interleaved / matched. scenario: nmblookup connects to agent, sends request. agent receives request, broadcasts it on 137. agent RECEIVES 137 broadcast, sends it to nmblookup agent receives RESPONSE to 137 broadcast, sends it to nmblookup. if reads are not equally interspersed with writes, then second send will fail. if you think this is odd behaviour and that the agent should be filtering its own UDP traffic, think again. agent will be, potentially, redirecting nmbd traffic (including WINS server) not just client programs. (This used to be commit 43e158c4261e51678d6e7f77ceb4a1c7281a2525) --- source3/libsmb/nmblib.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 127cfeb130..006cb5f5ee 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -672,9 +672,18 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) } length = read_udp_socket(fd,buf,sizeof(buf)); - + dump_data(100, buf, length); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + uint16 trn_id = 0; + if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + return False; + } + } + if (length < MIN_DGRAM_SIZE) return(NULL); if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) @@ -900,6 +909,8 @@ BOOL send_packet(struct packet_struct *p) char buf[1024]; int len=0; + DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type)); + bzero(buf,sizeof(buf)); switch (p->packet_type) @@ -951,15 +962,25 @@ BOOL send_packet(struct packet_struct *p) if (write(p->fd,qbuf,qlen) != qlen) { + DEBUG(0,("send_packet: write hdr failed\n")); return False; } - qlen = read(p->fd, &trn_id, sizeof(trn_id)); - - if (qlen != sizeof(trn_id)) + if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + DEBUG(0,("send_packet: 1st ack failed\n")); + return False; + } + if (write(p->fd,buf,len) != len) + { + DEBUG(0,("send_packet: write packet failed\n")); + return False; + } + if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) { + DEBUG(0,("send_packet: 2nd ack failed\n")); return False; } - return write(p->fd,buf,len) == len; + return True; } } @@ -980,6 +1001,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); + DEBUG(100,("receive_packet: %d %d\n", fd, type)); sys_select(fd+1,&fds,NULL, &timeout); if (FD_ISSET(fd,&fds)) -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/libsmb/nmblib.c | 288 +++++++++++++----------------------------------- 1 file changed, 77 insertions(+), 211 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 006cb5f5ee..3b14fd2c6b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -179,27 +179,34 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na unsigned char *ubuf = (unsigned char *)inbuf; int ret = 0; BOOL got_pointer=False; + int loop_count=0; - if (length - offset < 2) return(0); + if (length - offset < 2) + return(0); /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!m) return(0); - if ((m & 0xC0) || offset+m+2 > length) return(0); + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); - bzero((char *)name,sizeof(*name)); + memset((char *)name,'\0',sizeof(*name)); /* the "compressed" part */ - if (!got_pointer) ret += m + 2; + if (!got_pointer) + ret += m + 2; offset++; - while (m) { + while (m > 0) { unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0); + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); name->name[n++] = (c1<<4) | c2; m -= 2; } @@ -213,21 +220,38 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na /* remove trailing spaces */ name->name[15] = 0; n = 14; - while (n && name->name[n]==' ') name->name[n--] = 0; + while (n && name->name[n]==' ') + name->name[n--] = 0; } /* now the domain parts (if any) */ n = 0; while (ubuf[offset]) { /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!got_pointer) ret += m+1; - if (n) name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); offset++; - while (m--) name->scope[n++] = (char)ubuf[offset++]; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; } name->scope[n++] = 0; @@ -251,7 +275,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (strcmp(name->name,"*") == 0) { /* special case for wildcard name */ - bzero(buf1,20); + memset(buf1,'\0',20); buf1[0] = '*'; buf1[15] = name->name_type; } else { @@ -287,7 +311,6 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) return(ret); } - /******************************************************************* useful for debugging messages ******************************************************************/ @@ -297,23 +320,15 @@ char *nmb_namestr(struct nmb_name *n) static fstring ret[4]; char *p = ret[i]; - nmb_safe_namestr(n, p, sizeof(fstring)); + if (!n->scope[0]) + slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); + else + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); } -/******************************************************************* - useful for debugging messages - ******************************************************************/ -void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len) -{ - if (!n->scope[0]) - slprintf(str, len-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); -} - /******************************************************************* allocate and parse some resource records ******************************************************************/ @@ -324,13 +339,14 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, *recs = (struct res_rec *)malloc(sizeof(**recs)*count); if (!*recs) return(False); - bzero(*recs,sizeof(**recs)*count); + memset((char *)*recs,'\0',sizeof(**recs)*count); for (i=0;i length) { free(*recs); + *recs = NULL; return(False); } (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); @@ -341,6 +357,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { free(*recs); + *recs = NULL; return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); @@ -405,7 +422,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) int offset; int flags; - bzero((char *)dgram,sizeof(*dgram)); + memset((char *)dgram,'\0',sizeof(*dgram)); if (length < 14) return(False); @@ -447,7 +464,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { int nm_flags,offset; - bzero((char *)nmb,sizeof(*nmb)); + memset((char *)nmb,'\0',sizeof(*nmb)); if (length < 12) return(False); @@ -563,12 +580,18 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) free_and_exit: - if(copy_nmb->answers) + if(copy_nmb->answers) { free((char *)copy_nmb->answers); - if(copy_nmb->nsrecs) + copy_nmb->answers = NULL; + } + if(copy_nmb->nsrecs) { free((char *)copy_nmb->nsrecs); - if(copy_nmb->additional) + copy_nmb->nsrecs = NULL; + } + if(copy_nmb->additional) { free((char *)copy_nmb->additional); + copy_nmb->additional = NULL; + } free((char *)pkt_copy); DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); @@ -617,9 +640,18 @@ struct packet_struct *copy_packet(struct packet_struct *packet) ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) { - if (nmb->answers) free(nmb->answers); - if (nmb->nsrecs) free(nmb->nsrecs); - if (nmb->additional) free(nmb->additional); + if (nmb->answers) { + free(nmb->answers); + nmb->answers = NULL; + } + if (nmb->nsrecs) { + free(nmb->nsrecs); + nmb->nsrecs = NULL; + } + if (nmb->additional) { + free(nmb->additional); + nmb->additional = NULL; + } } /******************************************************************* @@ -641,6 +673,7 @@ void free_packet(struct packet_struct *packet) free_nmb_packet(&packet->packet.nmb); else if (packet->packet_type == DGRAM_PACKET) free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); free(packet); } @@ -651,47 +684,15 @@ void free_packet(struct packet_struct *packet) struct packet_struct *read_packet(int fd,enum packet_type packet_type) { extern struct in_addr lastip; - struct nmb_state con; extern int lastport; struct packet_struct *packet; char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - uint16 trn_id = 0; - if (!read_nmb_sock(fd, &con)) - { - return False; - } - if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - return False; - } - } - - length = read_udp_socket(fd,buf,sizeof(buf)); - - dump_data(100, buf, length); - - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - uint16 trn_id = 0; - if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - return False; - } - } - + length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - lastip = con.ip; - lastport = con.port; - } - packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -706,19 +707,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) switch (packet_type) { case NMB_PACKET: - case NMB_SOCK_PACKET: ok = parse_nmb(buf,length,&packet->packet.nmb); break; case DGRAM_PACKET: - case DGRAM_SOCK_PACKET: ok = parse_dgram(buf,length,&packet->packet.dgram); break; } if (!ok) { DEBUG(10,("read_packet: discarding packet id = %d\n", packet->packet.nmb.header.name_trn_id)); - free(packet); + free_packet(packet); return(NULL); } @@ -740,7 +739,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) struct sockaddr_in sock_out; /* set the address and port */ - bzero((char *)&sock_out,sizeof(sock_out)); + memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)&ip); sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; @@ -776,7 +775,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /* put in the header */ ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2); + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); if (dgram->header.flags.more) ubuf[1] |= 1; if (dgram->header.flags.first) ubuf[1] |= 2; RSSVAL(ubuf,2,dgram->header.dgm_id); @@ -909,82 +908,23 @@ BOOL send_packet(struct packet_struct *p) char buf[1024]; int len=0; - DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type)); - - bzero(buf,sizeof(buf)); + memset(buf,'\0',sizeof(buf)); switch (p->packet_type) { case NMB_PACKET: - case NMB_SOCK_PACKET: len = build_nmb(buf,p); debug_nmb_packet(p); break; case DGRAM_PACKET: - case DGRAM_SOCK_PACKET: len = build_dgram(buf,p); break; } if (!len) return(False); - switch (p->packet_type) - { - case DGRAM_PACKET: - case NMB_PACKET: - return(send_udp(p->fd,buf,len,p->ip,p->port)); - break; - - case NMB_SOCK_PACKET: - case DGRAM_SOCK_PACKET: - { - fstring qbuf; - struct nmb_state nmb; - int qlen; - uint16 trn_id; - char *q = qbuf + 4; - - nmb.ip = p->ip; - nmb.port = p->port; - - SSVAL(q, 0, 0); - q += 2; - SSVAL(q, 0, 0); - q += 2; - memcpy(q, &nmb, sizeof(nmb)); - q += sizeof(nmb); - - qlen = PTR_DIFF(q, qbuf); - SIVAL(qbuf, 0, qlen); - - dump_data(100, qbuf, qlen); - - if (write(p->fd,qbuf,qlen) != qlen) - { - DEBUG(0,("send_packet: write hdr failed\n")); - return False; - } - if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - DEBUG(0,("send_packet: 1st ack failed\n")); - return False; - } - if (write(p->fd,buf,len) != len) - { - DEBUG(0,("send_packet: write packet failed\n")); - return False; - } - if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - DEBUG(0,("send_packet: 2nd ack failed\n")); - return False; - } - return True; - } - } - - return False; + return(send_udp(p->fd,buf,len,p->ip,p->port)); } /**************************************************************************** @@ -1001,8 +941,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - DEBUG(100,("receive_packet: %d %d\n", fd, type)); - sys_select(fd+1,&fds,NULL, &timeout); + sys_select(fd+1,&fds,&timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); @@ -1055,76 +994,3 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } - -BOOL read_nmb_sock(int c, struct nmb_state *con) -{ - fstring buf; - char *p = buf; - int rl; - uint32 len; - uint16 version; - uint16 command; - - ZERO_STRUCTP(con); - - rl = read(c, &buf, sizeof(len)); - - if (rl < 0) - { - DEBUG(0,("read_nmb_sock: error\n")); - return False; - } - if (rl != sizeof(len)) - { - DEBUG(0,("Unable to read length\n")); - dump_data(0, buf, sizeof(len)); - return False; - } - - len = IVAL(buf, 0); - - if (len > sizeof(buf)) - { - DEBUG(0,("length %d too long\n", len)); - return False; - } - - rl = read(c, buf, len); - - if (rl < 0) - { - DEBUG(0,("Unable to read from connection\n")); - return False; - } - -#ifdef DEBUG_PASSWORD - dump_data(100, buf, rl); -#endif - version = SVAL(p, 0); - p += 2; - command = SVAL(p, 0); - p += 2; - - memcpy(con, p, sizeof(*con)); - p += sizeof(*con); - - DEBUG(10,("read_nmb_sock: ip %s port: %d\n", - inet_ntoa(con->ip), con->port)); - - if (PTR_DIFF(p, buf) != rl) - { - DEBUG(0,("Buffer size %d %d!\n", - PTR_DIFF(p, buf), rl)); - return False; - } - - return True; -} - -int get_nmb_sock(void) -{ - fstring path; - slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent"); - - return open_pipe_sock(path); -} -- cgit From 574788039f53fada4769731ea3fafe9710417b71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 03:17:16 +0000 Subject: added the unexpected packet database (unexpected.tdb) this means "nmblookup -S" now always works, even with broken servers the database stores all unexpected replies and these can be accessed by any client. while doing this I cleaned up a couple of functions, and put in place a better trn_id generator. in most places the code got quite a bit simpler due to the addition of simple helper functions. I haven't yet put the code in to take advantage of this for pdc replies - that will be next. Jeremys pdc finding code will then work :) (This used to be commit 280e6359d36c9bc8dcded302f15c3a1db8e3feeb) --- source3/libsmb/nmblib.c | 174 ++++++++++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 64 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3b14fd2c6b..13f7e11123 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -678,55 +678,69 @@ void free_packet(struct packet_struct *packet) } /******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket +parse a packet buffer into a packet structure ******************************************************************/ -struct packet_struct *read_packet(int fd,enum packet_type packet_type) +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type) { - extern struct in_addr lastip; - extern int lastport; - struct packet_struct *packet; - char buf[MAX_DGRAM_SIZE]; - int length; - BOOL ok=False; - - length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); - - packet = (struct packet_struct *)malloc(sizeof(*packet)); - if (!packet) return(NULL); - - packet->next = NULL; - packet->prev = NULL; - packet->ip = lastip; - packet->port = lastport; - packet->fd = fd; - packet->locked = False; - packet->timestamp = time(NULL); - packet->packet_type = packet_type; - switch (packet_type) - { - case NMB_PACKET: - ok = parse_nmb(buf,length,&packet->packet.nmb); - break; + extern struct in_addr lastip; + extern int lastport; + struct packet_struct *p; + BOOL ok=False; + + p = (struct packet_struct *)malloc(sizeof(*p)); + if (!p) return(NULL); + + p->next = NULL; + p->prev = NULL; + p->ip = lastip; + p->port = lastport; + p->locked = False; + p->timestamp = time(NULL); + p->packet_type = packet_type; + + switch (packet_type) { + case NMB_PACKET: + ok = parse_nmb(buf,length,&p->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram(buf,length,&p->packet.dgram); + break; + } - case DGRAM_PACKET: - ok = parse_dgram(buf,length,&packet->packet.dgram); - break; - } - if (!ok) { - DEBUG(10,("read_packet: discarding packet id = %d\n", - packet->packet.nmb.header.name_trn_id)); - free_packet(packet); - return(NULL); - } + if (!ok) { + free_packet(p); + return NULL; + } - num_good_receives++; + return p; +} - DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, inet_ntoa(packet->ip), packet->port ) ); +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct *read_packet(int fd,enum packet_type packet_type) +{ + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + + length = read_udp_socket(fd,buf,sizeof(buf)); + if (length < MIN_DGRAM_SIZE) return(NULL); + + packet = parse_packet(buf, length, packet_type); + if (!packet) return NULL; - return(packet); + packet->fd = fd; + + num_good_receives++; + + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa(packet->ip), packet->port ) ); + + return(packet); } @@ -900,6 +914,26 @@ static int build_nmb(char *buf,struct packet_struct *p) } +/******************************************************************* +linearise a packet + ******************************************************************/ +int build_packet(char *buf, struct packet_struct *p) +{ + int len = 0; + + switch (p->packet_type) { + case NMB_PACKET: + len = build_nmb(buf,p); + break; + + case DGRAM_PACKET: + len = build_dgram(buf,p); + break; + } + + return len; +} + /******************************************************************* send a packet_struct ******************************************************************/ @@ -910,17 +944,7 @@ BOOL send_packet(struct packet_struct *p) memset(buf,'\0',sizeof(buf)); - switch (p->packet_type) - { - case NMB_PACKET: - len = build_nmb(buf,p); - debug_nmb_packet(p); - break; - - case DGRAM_PACKET: - len = build_dgram(buf,p); - break; - } + len = build_packet(buf, p); if (!len) return(False); @@ -933,20 +957,42 @@ BOOL send_packet(struct packet_struct *p) ***************************************************************************/ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { - fd_set fds; - struct timeval timeout; + fd_set fds; + struct timeval timeout; - FD_ZERO(&fds); - FD_SET(fd,&fds); - timeout.tv_sec = t/1000; - timeout.tv_usec = 1000*(t%1000); + FD_ZERO(&fds); + FD_SET(fd,&fds); + timeout.tv_sec = t/1000; + timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + sys_select(fd+1,&fds,&timeout); - if (FD_ISSET(fd,&fds)) - return(read_packet(fd,type)); + if (FD_ISSET(fd,&fds)) + return(read_packet(fd,type)); + + return(NULL); +} + + +/**************************************************************************** + receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) +{ + struct packet_struct *p; + + p = receive_packet(fd, NMB_PACKET, t); + + if (p && p->packet.nmb.header.response && + p->packet.nmb.header.name_trn_id == trn_id) { + return p; + } + if (p) free_packet(p); - return(NULL); + /* try the unexpected packet queue */ + return receive_unexpected_137(trn_id); } -- cgit From 632b4f806eae15e319b8f62caef5d25634cf720c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 06:30:50 +0000 Subject: added suppport for unexpected udp/138 packets I also fixed up the lookup_pdc_name() code so that it now works, even with a NT server that insists on replying to udp/138. The method I used to match packets was to use the mailslot string as a datagram ID. The true dgm_id doesn't work as NT doesn't set it correctly. uggh. PS: Jeremy, I had to change your code quite a bit, are you sure this worked with a Samba PDC?? The code looked broken, it got the offsets wrong in the SMB portion of the packet and filled in the IP incorrectly. (This used to be commit 32f66f4ea63038cb4b3785bdf1762abdde076f5d) --- source3/libsmb/nmblib.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 13f7e11123..9ddfd3a6c6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -979,7 +979,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) queue. The packet must be a reply packet and have the specified trn_id The timeout is in milliseconds ***************************************************************************/ -struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) { struct packet_struct *p; @@ -992,7 +992,48 @@ struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) if (p) free_packet(p); /* try the unexpected packet queue */ - return receive_unexpected_137(trn_id); + return receive_unexpected(NMB_PACKET, trn_id, NULL); +} + +/**************************************************************************** + receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified dgm_id + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) +{ + struct packet_struct *p; + + p = receive_packet(fd, DGRAM_PACKET, t); + + if (p && match_mailslot_name(p, mailslot_name)) { + return p; + } + if (p) free_packet(p); + + /* try the unexpected packet queue */ + return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); +} + + +/**************************************************************************** + see if a datagram has the right mailslot name +***************************************************************************/ +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) +{ + struct dgram_packet *dgram = &p->packet.dgram; + char *buf; + + buf = &dgram->data[0]; + buf -= 4; + + buf = smb_buf(buf); + + if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) { + return True; + } + + return False; } -- cgit From 171da4d78736730557a94b44af9f2d62081b80ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 06:55:36 +0000 Subject: this looks like a big commit, but it isn't really :) This fixes our netbios scope handling. We now have a 'netbios scope' option in smb.conf and the scope option is removed from make_nmb_name() this was prompted by a bug in our PDC finding code where it didn't append the scope to the query of the '*' name. (This used to be commit b563be824b8c3141c49558eced7829b48d4ab26f) --- source3/libsmb/nmblib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9ddfd3a6c6..e2ba79b006 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -819,13 +819,14 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name *******************************************************************/ -void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) +void make_nmb_name( struct nmb_name *n, const char *name, int type) { + extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, this_scope, 63 ); + StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); } -- cgit From 6e8548acb381499142e8d3b0a2eac2061e160b02 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 12:40:34 +0000 Subject: fixed a comment (This used to be commit 32f29c490e6265c8a383ce771943f937c49bfabc) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e2ba79b006..b83081d7f0 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -998,7 +998,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) /**************************************************************************** receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified dgm_id + queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds ***************************************************************************/ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) -- cgit From 1f28a345526908214240f36942c3a58e1f7bd138 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 22:29:27 +0000 Subject: Multiple-dot scope handling fix from Greg Bowering gb@pobox.com Jeremy. (This used to be commit 693a582c23599bbdd45adb30401b1162e44fd274) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b83081d7f0..7b62ca4546 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -301,8 +301,8 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) p = &buf[offset+1]; while ((p = strchr(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset]); - offset += buf[offset]; + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); p = &buf[offset+1]; } buf[offset] = strlen(&buf[offset+1]); -- cgit From 4acd40ee0015dd417a7a008f7fd2a183f8e30225 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 27 Mar 2000 01:33:43 +0000 Subject: moved nmblib-specific code from util.c to nmblib.c. (This used to be commit 1b9077a1d5295bc8522b83ebed2d41d5dbd28a27) --- source3/libsmb/nmblib.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 203 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7b62ca4546..dae7cf087a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -80,7 +80,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { - unsigned char x = res->rdata[i+j]; + uchar x = res->rdata[i+j]; if (x < 32 || x > 127) x = '.'; if (i+j >= res->rdlength) break; @@ -92,7 +92,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); } DEBUGADD(4, ("\n")); @@ -153,7 +153,7 @@ void debug_nmb_packet(struct packet_struct *p) /******************************************************************* handle "compressed" name pointers ******************************************************************/ -static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, +static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; @@ -176,7 +176,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) { int m,n=0; - unsigned char *ubuf = (unsigned char *)inbuf; + uchar *ubuf = (uchar *)inbuf; int ret = 0; BOOL got_pointer=False; int loop_count=0; @@ -202,7 +202,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na ret += m + 2; offset++; while (m > 0) { - unsigned char c1,c2; + uchar c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) @@ -215,7 +215,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na if (n==16) { /* parse out the name type, its always in the 16th byte of the name */ - name->name_type = ((unsigned char)name->name[15]) & 0xff; + name->name_type = ((uchar)name->name[15]) & 0xff; /* remove trailing spaces */ name->name[15] = 0; @@ -393,7 +393,7 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) /******************************************************************* put a compressed name pointer record into a packet ******************************************************************/ -static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) +static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset) { int ret=0; buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); @@ -784,7 +784,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) static int build_dgram(char *buf,struct packet_struct *p) { struct dgram_packet *dgram = &p->packet.dgram; - unsigned char *ubuf = (unsigned char *)buf; + uchar *ubuf = (uchar *)buf; int offset=0; /* put in the header */ @@ -852,7 +852,7 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) static int build_nmb(char *buf,struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - unsigned char *ubuf = (unsigned char *)buf; + uchar *ubuf = (uchar *)buf; int offset=0; /* put in the header */ @@ -1082,3 +1082,197 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } + + +#define TRUNCATE_NETBIOS_NAME 1 + +/******************************************************************* + convert, possibly using a stupid microsoft-ism which has destroyed + the transport independence of netbios (for CIFS vendors that usually + use the Win95-type methods, not for NT to NT communication, which uses + DCE/RPC and therefore full-length unicode strings...) a dns name into + a netbios name. + + the netbios name (NOT necessarily null-terminated) is truncated to 15 + characters. + + ******************************************************************/ +char *dns_to_netbios_name(char *dns_name) +{ + static char netbios_name[16]; + int i; + StrnCpy(netbios_name, dns_name, 15); + netbios_name[15] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' this even applies, by + mistake, to workgroup (domain) names, which is _really_ daft. + */ + for (i = 15; i >= 0; i--) + { + if (netbios_name[i] == '.') + { + netbios_name[i] = 0; + break; + } + } +#endif /* TRUNCATE_NETBIOS_NAME */ + + return netbios_name; +} + + +/**************************************************************************** +interpret the weird netbios "name". Return the name type +****************************************************************************/ +static int name_interpret(char *in,char *out) +{ + int ret; + int len = (*in++) / 2; + + *out=0; + + if (len > 30 || len<1) return(0); + + while (len--) + { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + *out = 0; + ret = out[-1]; + +#ifdef NETBIOS_SCOPE + /* Handle any scope names */ + while(*in) + { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(uchar *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } +#endif + return(ret); +} + +/**************************************************************************** +mangle a name into netbios format + + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. +****************************************************************************/ +int name_mangle( char *In, char *Out, char name_type ) + { + int i; + int c; + int len; + char buf[20]; + char *p = Out; + extern pstring global_scope; + + /* Safely copy the input string, In, into buf[]. */ + (void)memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) + buf[0] = '*'; + else + (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for( i = 0; i < 16; i++ ) + { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (c & 0x000F) + 'A'; + } + p += 32; + p[0] = '\0'; + + /* Add the scope string. */ + for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + { + switch( global_scope[i] ) + { + case '\0': + p[0] = len; + if( len > 0 ) + p[len+1] = 0; + return( name_len(Out) ); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = global_scope[i]; + break; + } + } + + return( name_len(Out) ); + } /* name_mangle */ + + +/**************************************************************************** +find a pointer to a netbios name +****************************************************************************/ +static char *name_ptr(char *buf,int ofs) +{ + uchar c = *(uchar *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) + { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } + else + return(buf+ofs); +} + +/**************************************************************************** +extract a netbios name from a buf +****************************************************************************/ +int name_extract(char *buf,int ofs,char *name) +{ + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + pstrcpy(name,""); + if (d < -50 || d > 50) return(0); + return(name_interpret(p,name)); +} + +/**************************************************************************** +return the total storage length of a mangled name +****************************************************************************/ +int name_len(char *s1) +{ + /* NOTE: this argument _must_ be unsigned */ + uchar *s = (uchar *)s1; + int len; + + /* If the two high bits of the byte are set, return 2. */ + if (0xC0 == (*s & 0xC0)) + return(2); + + /* Add up the length bytes. */ + for (len = 1; (*s); s += (*s) + 1) { + len += *s + 1; + SMB_ASSERT(len < 80); + } + + return(len); +} /* name_len */ + + -- cgit From 5dfa33bf715d850bfd0530c6ff3d0496195126a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 18:27:58 +0000 Subject: Fix from David Collier-Brown - sys_select return was not being checked. Jeremy. (This used to be commit a9c4371a2dc27e499ad6d35af1b598a4af0026c8) --- source3/libsmb/nmblib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index dae7cf087a..f8f38fe44d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -966,7 +966,11 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + if (sys_select(fd+1,&fds,&timeout) == -1) { + /* errno should be EBADF or EINVAL. */ + DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); + return NULL; + } if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 2c978311dcb869b91a7787feba7f537056f4b90d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 18:53:03 +0000 Subject: Ho hum - forgot timeout case. Jeremy. (This used to be commit 597ecd724e0d4ac7c19eb9fb85b3c9910bbfb114) --- source3/libsmb/nmblib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f8f38fe44d..d4955fa6a6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -960,18 +960,22 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { fd_set fds; struct timeval timeout; + int ret; FD_ZERO(&fds); FD_SET(fd,&fds); timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if (sys_select(fd+1,&fds,&timeout) == -1) { + if ((ret = sys_select(fd+1,&fds,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; } + if (ret == 0) /* timeout */ + return NULL; + if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 8843a6379d7c1cf59f0f3673cbc567b09994b7d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 11 Jun 2000 05:57:58 +0000 Subject: Linux kernel oplocks now seem to work, but need a _lot_ of testing I had to modify sys_select() to not loop on EINTR. I added a wrapper called sys_select_intr() which gives the old behaviour. (This used to be commit b28cc4163bc2faaa80c5782fc02c8f03c410cdeb) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d4955fa6a6..e290ee5d4f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -967,7 +967,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if ((ret = sys_select(fd+1,&fds,&timeout)) == -1) { + if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; -- cgit From 9c6acf4595d14cb0fc0c9bf17ce02de73af127cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 22:37:42 +0000 Subject: Fix from RFritz@lbl.gov for Linux ECONREFUSED async errors on Linux. Jeremy. (This used to be commit dd804fdb96ff49645647787c197a61a6515a474d) --- source3/libsmb/nmblib.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e290ee5d4f..01c4001f4c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -750,6 +750,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { BOOL ret; + int i; struct sockaddr_in sock_out; /* set the address and port */ @@ -760,9 +761,16 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", len, inet_ntoa(ip), port ) ); + + /* + * Patch to fix asynch error notifications from Linux kernel. + */ - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, - sizeof(sock_out)) >= 0); + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } if (!ret) DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", -- cgit From f9a2be782207013445e2f228a08e44b209a9133c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 2 Feb 2001 17:42:00 +0000 Subject: Convert netbios name to dos codepage in make_nmb_name(). This allows nmblookup and smbclient to work with i18n netbios names. (This used to be commit 2eabb7c229fb8a64d47757f291b327f5b7f26b55) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 01c4001f4c..22ff09faa3 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -832,6 +832,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); + unix_to_dos(n->name, True); strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); -- cgit From 2ef68c7e92d4661664f0410509f7cb551e74a198 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Apr 2001 19:12:06 +0000 Subject: Merge of Andrew's changes in 2.2. Jeremy. (This used to be commit fc76681812b1469208ad6c8847afdfc68bc6db49) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 22ff09faa3..0a6bbe87e2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -749,7 +749,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) ******************************************************************/ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret; + BOOL ret = False; int i; struct sockaddr_in sock_out; -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/libsmb/nmblib.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0a6bbe87e2..d3b0e68aef 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -831,9 +831,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) { extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - StrnCpy( n->name, name, 15 ); - unix_to_dos(n->name, True); - strupper( n->name ); + push_ascii(n->name, name, 15, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); -- cgit From 527e824293ee934ca5da0ef5424efe5ab7757248 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:36:09 +0000 Subject: strchr and strrchr are macros when compiling with optimisation in gcc, so we can't redefine them. damn. (This used to be commit c41fc06376d1a2b83690612304e85010b5e5f3cf) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d3b0e68aef..9d7167f305 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -300,7 +300,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) pstrcpy(&buf[offset+1],name->scope); p = &buf[offset+1]; - while ((p = strchr(p,'.'))) { + while ((p = strchr_m(p,'.'))) { buf[offset] = PTR_DIFF(p,&buf[offset+1]); offset += (buf[offset] + 1); p = &buf[offset+1]; -- cgit From 4294f6f2c80cb81fdf872bee87e171640e3601fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Aug 2001 18:05:12 +0000 Subject: allow for the NULL in make_nmb_name() (This used to be commit b6c78d4c6fde2065678dd62bbd9dd4af9c5e805b) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9d7167f305..6a24cb382c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -831,7 +831,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) { extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, 15, STR_TERMINATE|STR_UPPER); + push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); -- cgit From bcbd75f7add425ebee760ddbd2e80a1d4a51e619 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 03:33:37 +0000 Subject: move to SAFE_FREE() (This used to be commit 48fc6a6cd52e01b287030fbbf0aa08a6814c5e11) --- source3/libsmb/nmblib.c | 40 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 30 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6a24cb382c..4ecc887524 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -345,8 +345,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name); (*offset) += l; if (!l || (*offset)+10 > length) { - free(*recs); - *recs = NULL; + SAFE_FREE(*recs); return(False); } (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); @@ -356,8 +355,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, (*offset) += 10; if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { - free(*recs); - *recs = NULL; + SAFE_FREE(*recs); return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); @@ -580,19 +578,10 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) free_and_exit: - if(copy_nmb->answers) { - free((char *)copy_nmb->answers); - copy_nmb->answers = NULL; - } - if(copy_nmb->nsrecs) { - free((char *)copy_nmb->nsrecs); - copy_nmb->nsrecs = NULL; - } - if(copy_nmb->additional) { - free((char *)copy_nmb->additional); - copy_nmb->additional = NULL; - } - free((char *)pkt_copy); + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); return NULL; @@ -640,18 +629,9 @@ struct packet_struct *copy_packet(struct packet_struct *packet) ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) { - if (nmb->answers) { - free(nmb->answers); - nmb->answers = NULL; - } - if (nmb->nsrecs) { - free(nmb->nsrecs); - nmb->nsrecs = NULL; - } - if (nmb->additional) { - free(nmb->additional); - nmb->additional = NULL; - } + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); } /******************************************************************* @@ -674,7 +654,7 @@ void free_packet(struct packet_struct *packet) else if (packet->packet_type == DGRAM_PACKET) free_dgram_packet(&packet->packet.dgram); ZERO_STRUCTPN(packet); - free(packet); + SAFE_FREE(packet); } /******************************************************************* -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/libsmb/nmblib.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4ecc887524..d7bd7b49a0 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - int num_good_sends = 0; int num_good_receives = 0; @@ -1269,5 +1267,3 @@ int name_len(char *s1) return(len); } /* name_len */ - - -- cgit From fab88997b021ad66dd7f03220d95d1f7ee315140 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 08:12:44 +0000 Subject: This patch applied, except without the structure changes to nmblib.c Andrew Bartlett. From kai@cmail.ru Mon Oct 29 18:50:42 2001 Date: Fri, 19 Oct 2001 17:26:06 +0300 From: Andrew V. Samoilov To: samba-technical@lists.samba.org Subject: [patch]: makes some arrays const to be shared between processes Hi! This patch makes some arrays const. So these arrays go to text/rodata segment and are shared between all of the processes which use shared library with these arrays. Regards, Andrew V. Samoilov. P.S. Please cc your answer to kai@cmail.ru, I don't subscribed to this list. ChangeLog: * cliconnect.c (prots): Make const. * clierror.c (rap_errmap): Likewise. * nmblib.c (nmb_header_opcode_names): Likewise. (lookup_opcode_name): Make opcode_namep const. Eliminate i. * nterr.c (nt_err_code_struct): Typedef const. * smberr.c (err_code_struct): Make const. (err_classes): Likewise. (This used to be commit cb84485a2b0e1fdcb6fa90e0bfb97e125ae1b3dd) --- source3/libsmb/nmblib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d7bd7b49a0..dc39924818 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -25,7 +25,7 @@ int num_good_sends = 0; int num_good_receives = 0; -static struct opcode_names { +static const struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { @@ -42,9 +42,9 @@ static struct opcode_names { /**************************************************************************** * Lookup a nmb opcode name. ****************************************************************************/ -static char *lookup_opcode_name( int opcode ) +static const char *lookup_opcode_name( int opcode ) { - struct opcode_names *op_namep; + const struct opcode_names *op_namep; int i; for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { -- cgit From 4d726d00918045d77d13b37a8d033926fc811422 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:50:53 +0000 Subject: prevent a bogus insure wild ptr message (This used to be commit 1976a8f87544140363449a361f7c7347ef2c44f5) --- source3/libsmb/nmblib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index dc39924818..0061a4b977 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -171,13 +171,14 @@ static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, parse a nmb name from "compressed" format to something readable return the space taken by the name, or 0 if the name is invalid ******************************************************************/ -static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) +static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { int m,n=0; uchar *ubuf = (uchar *)inbuf; int ret = 0; BOOL got_pointer=False; int loop_count=0; + int offset = ofs; if (length - offset < 2) return(0); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libsmb/nmblib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0061a4b977..0d14461547 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. NBT netbios library routines Copyright (C) Andrew Tridgell 1994-1998 -- cgit From 69adbb0ce3bb9d5bd569c13aaa3ac8f390c1586a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jan 2002 23:26:12 +0000 Subject: Fix from Michael Steffens to make signal processing work correctly in winbindd. This is a really good patch that gives full select semantics to the Samba modified select. Jeremy. (This used to be commit 3af16ade173cac24c1ac5eff4a36b439f16ac036) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0d14461547..c78946fa09 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -952,7 +952,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) { + if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; -- cgit From 6f366b7809375e4d7b061278a739ce541d291a97 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 22 Apr 2002 03:09:23 +0000 Subject: Copying commit from HEAD. My seven-year-old daughter calls me 'Captain Pedantic'. I don't know which is freakier... the name or the fact that a seven-year-old knows what it means. Small change to correct the value we place in the DGM_LENGTH field of NBT Datagram messages. We have been counting the full datagram, but it's fairly clear in the RFCs that we should only count the source name, destination name, and payload. We've been overcharging by 14 bytes (the size of the NBT DGM header). This fix brings us in line with what Windows does, and what the RFCs say should be done. I'm a little surprised that this didn't cause any bugs or error messages. I guess no one actually checks this field. (This used to be commit c06a2ece7545a9d9f8cde04745b603f7d6c6a716) --- source3/libsmb/nmblib.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c78946fa09..9a37b4252a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -766,6 +766,14 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) XXXX This currently doesn't handle packets too big for one datagram. It should split them and use the packet_offset, more and first flags to handle the fragmentation. Yuck. + + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { @@ -795,8 +803,11 @@ static int build_dgram(char *buf,struct packet_struct *p) memcpy(ubuf+offset,dgram->data,dgram->datasize); offset += dgram->datasize; - /* automatically set the dgm_length */ - dgram->header.dgm_length = offset; + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); RSSVAL(ubuf,10,dgram->header.dgm_length); return(offset); -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9a37b4252a..ba0d8cee5d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1045,7 +1045,7 @@ BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) /**************************************************************************** return the number of bits that match between two 4 character buffers ***************************************************************************/ -static int matching_bits(uchar *p1, uchar *p2) +int matching_quad_bits(uchar *p1, uchar *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { @@ -1071,7 +1071,7 @@ compare two query reply records ***************************************************************************/ static int name_query_comp(uchar *p1, uchar *p2) { - return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); + return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/libsmb/nmblib.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ba0d8cee5d..43e32aebbd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -28,14 +28,14 @@ static const struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { - {"Query", 0 }, - {"Registration", 5 }, - {"Release", 6 }, - {"WACK", 7 }, - {"Refresh", 8 }, - {"Refresh(altcode)", 9 }, - {"Multi-homed Registration", 15 }, - {0, -1 } + {"Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, + {0, -1 } }; /**************************************************************************** @@ -814,15 +814,15 @@ static int build_dgram(char *buf,struct packet_struct *p) } /******************************************************************* - build a nmb name - *******************************************************************/ + Build a nmb name +*******************************************************************/ + void make_nmb_name( struct nmb_name *n, const char *name, int type) { - extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope, 63 ); + StrnCpy( n->scope, global_scope(), 63 ); strupper( n->scope ); } @@ -1180,7 +1180,6 @@ int name_mangle( char *In, char *Out, char name_type ) int len; char buf[20]; char *p = Out; - extern pstring global_scope; /* Safely copy the input string, In, into buf[]. */ (void)memset( buf, 0, 20 ); @@ -1204,9 +1203,9 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) { - switch( global_scope[i] ) + switch( (global_scope())[i] ) { case '\0': p[0] = len; @@ -1219,7 +1218,7 @@ int name_mangle( char *In, char *Out, char name_type ) len = -1; break; default: - p[len+1] = global_scope[i]; + p[len+1] = (global_scope())[i]; break; } } -- cgit From ccdfed5587d4da1f2a4154ed151626d79765cc8f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Dec 2002 19:59:04 +0000 Subject: Ensure global_scope() returns "", not the NULL string. Froma tpot fix. Jeremy. (This used to be commit 0ff254264e6e43399404595bc87b5bd889e17952) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 43e32aebbd..d38e2ff0ec 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1203,7 +1203,7 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { switch( (global_scope())[i] ) { -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/libsmb/nmblib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d38e2ff0ec..30ce5b6b10 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -25,7 +25,7 @@ int num_good_sends = 0; int num_good_receives = 0; static const struct opcode_names { - char *nmb_opcode_name; + const char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { {"Query", 0 }, @@ -57,7 +57,7 @@ static const char *lookup_opcode_name( int opcode ) /**************************************************************************** print out a res_rec structure ****************************************************************************/ -static void debug_nmb_res_rec(struct res_rec *res, char *hdr) +static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { int i, j; @@ -1005,7 +1005,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) +struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1024,7 +1024,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) /**************************************************************************** see if a datagram has the right mailslot name ***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) +BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; char *buf; -- cgit From 49d71c7e7b69662083d889966ca4600b5000f521 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 6 Jun 2003 05:31:30 +0000 Subject: fixed a pstrcpy() that is not on a pstring (This used to be commit f644b3d6d238e3c44d0358b44296a9360d16bb41) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 30ce5b6b10..b96111240f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -295,7 +295,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - pstrcpy(&buf[offset+1],name->scope); + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); p = &buf[offset+1]; while ((p = strchr_m(p,'.'))) { -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b96111240f..157a2bb43c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -823,7 +823,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope(), 63 ); - strupper( n->scope ); + strupper_m( n->scope ); } /******************************************************************* -- cgit From 455bb6de903ca3950d965b29190c09f116d91889 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 02:28:25 +0000 Subject: Some small fixes to our charset conversion code: - Treat the NMB names in the 'session request' packet as 'ASCII'. This means that we do not get invalid multibyte from the wire, even if we truncate in the conversion. (Otherwise we panic when we try to strupper_m it). - Remove acnv_uxu2(), as it was duplicated by push_ucs2_allocate() - Remove acnv_dosu2(), as it is not used. - In push_ucs2(), with the STR_UPPER flag, do the case conversion *after* the UCS2 conversion, when it we know that the length can't change. Also faster, as we don't need to do another 2 UCS2 conversions. Andrew Bartlett (This used to be commit 912035af1178424583d0bf887a391a0cac2acd87) --- source3/libsmb/nmblib.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 157a2bb43c..7e97dbf43a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1129,12 +1129,14 @@ char *dns_to_netbios_name(char *dns_name) /**************************************************************************** -interpret the weird netbios "name". Return the name type +interpret the weird netbios "name" into a unix fstring. Return the name type ****************************************************************************/ -static int name_interpret(char *in,char *out) +static int name_interpret(char *in, fstring name) { int ret; int len = (*in++) / 2; + fstring out_string; + char *out = out_string; *out=0; @@ -1165,6 +1167,8 @@ static int name_interpret(char *in,char *out) in += len; } #endif + pull_ascii(name, out, sizeof(fstring), sizeof(out), STR_TERMINATE); + return(ret); } @@ -1245,9 +1249,9 @@ static char *name_ptr(char *buf,int ofs) } /**************************************************************************** -extract a netbios name from a buf +extract a netbios name from a buf (into a unix string) ****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) +int name_extract(char *buf,int ofs, fstring name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); -- cgit From 1478bcd847cfe0fe8374f403f20761675d944413 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 03:29:40 +0000 Subject: Try again to fix up 'session request' name exchange. This time we actualy get the names... Andrew Bartlett (This used to be commit 7c9e204f7eb15139532f2cc522ed87d0ac34d118) --- source3/libsmb/nmblib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7e97dbf43a..6ee05f0104 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1152,8 +1152,8 @@ static int name_interpret(char *in, fstring name) in += 2; out++; } - *out = 0; ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE /* Handle any scope names */ @@ -1167,7 +1167,7 @@ static int name_interpret(char *in, fstring name) in += len; } #endif - pull_ascii(name, out, sizeof(fstring), sizeof(out), STR_TERMINATE); + pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); return(ret); } @@ -1249,7 +1249,7 @@ static char *name_ptr(char *buf,int ofs) } /**************************************************************************** -extract a netbios name from a buf (into a unix string) +extract a netbios name from a buf (into a unix string) return name type ****************************************************************************/ int name_extract(char *buf,int ofs, fstring name) { -- cgit From 647a048ad085c74ebbddb1957b690f3cb9ced178 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Aug 2003 00:26:37 +0000 Subject: Ensure nmb_namestr() converts back from CH_DOS to CH_UNIX. Jeremy. (This used to be commit eb792727437c74417f5ef7614b300ab84f06fdaf) --- source3/libsmb/nmblib.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6ee05f0104..b833a2f5df 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -310,21 +310,24 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) } /******************************************************************* - useful for debugging messages - ******************************************************************/ + Useful for debugging messages. +******************************************************************/ + char *nmb_namestr(struct nmb_name *n) { - static int i=0; - static fstring ret[4]; - char *p = ret[i]; - - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); - - i = (i+1)%4; - return(p); + static int i=0; + static fstring ret[4]; + fstring name; + char *p = ret[i]; + + pull_ascii_fstring(name, n->name); + if (!n->scope[0]) + slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); + else + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope); + + i = (i+1)%4; + return(p); } /******************************************************************* -- cgit From 5dfeda00028c1d22428736a85140dec6f46ff94c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Aug 2003 21:41:50 +0000 Subject: Use correct size (17 not 16) when doing a push_ascii(). Ensure that wins hook is called with unix charset. Jeremy. (This used to be commit ecb80573870103de7b3f332fb53bf6b952f25ee7) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b833a2f5df..23eac9ad7c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -823,7 +823,7 @@ static int build_dgram(char *buf,struct packet_struct *p) void make_nmb_name( struct nmb_name *n, const char *name, int type) { memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); + push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope(), 63 ); strupper_m( n->scope ); -- cgit From 9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Aug 2003 01:25:01 +0000 Subject: Fix the character set handling properly in nmbd. Also fix bug where iconv wasn't re-initialised on reading of "charset" parameters. This caused workgroup name to be set incorrectly if it contained an extended character. Jeremy. (This used to be commit 84ae44678a6c59c999bc1023fdd9b7ad87f4ec18) --- source3/libsmb/nmblib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 23eac9ad7c..ff38245435 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -825,8 +825,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope(), 63 ); - strupper_m( n->scope ); + push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); } /******************************************************************* -- cgit From 220d663b744107e03a278b564f4e00712a6fcffe Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 12 Mar 2004 21:35:15 +0000 Subject: if we are truncating to the . we need to start at the beginning in case there are multiple "."'s in the name. This code is protected with an #ifdef TRUNCATE_NETBIOS_NAME and this is #define'd to 1 directly above. Should we also get rid of the #ifdef? (This used to be commit 0375dace248eb3dc660fa2bca2808552e502b3f7) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ff38245435..d0ea57dc1c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1116,7 +1116,7 @@ char *dns_to_netbios_name(char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 15; i >= 0; i--) + for (i = 0; i >= 15; i--) { if (netbios_name[i] == '.') { -- cgit From fd2d4f87d440f24df0adc4cc29f22051536b0dee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 00:28:53 +0000 Subject: First part of patch from moriyama@miraclelinux.com (MORIYAMA Masayuki) to fix up netbios names with mb strings. Includes reformat of libsmb/nmblib.c so it's readable. Jeremy. (This used to be commit 966e49a48c352563cdd7f75fe2768f2d6612ec7e) --- source3/libsmb/nmblib.c | 1659 ++++++++++++++++++++++++----------------------- 1 file changed, 854 insertions(+), 805 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d0ea57dc1c..cbe495cd95 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -39,274 +39,289 @@ static const struct opcode_names { }; /**************************************************************************** - * Lookup a nmb opcode name. - ****************************************************************************/ + Lookup a nmb opcode name. +****************************************************************************/ + static const char *lookup_opcode_name( int opcode ) { - const struct opcode_names *op_namep; - int i; - - for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { - op_namep = &nmb_header_opcode_names[i]; - if(opcode == op_namep->opcode) - return op_namep->nmb_opcode_name; - } - return ""; + const struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; } /**************************************************************************** - print out a res_rec structure - ****************************************************************************/ + Print out a res_rec structure. +****************************************************************************/ + static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { - int i, j; - - DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - nmb_namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl ) ); - - if( res->rdlength == 0 || res->rdata == NULL ) - return; - - for (i = 0; i < res->rdlength; i+= 16) - { - DEBUGADD(4, (" %s %3x char ", hdr, i)); - - for (j = 0; j < 16; j++) - { - uchar x = res->rdata[i+j]; - if (x < 32 || x > 127) x = '.'; + int i, j; + + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + nmb_namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; + + for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) { + DEBUGADD(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + unsigned char x = res->rdata[i+j]; + if (x < 32 || x > 127) + x = '.'; - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%c", x)); - } + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%c", x)); + } - DEBUGADD(4, (" hex ")); + DEBUGADD(4, (" hex ")); - for (j = 0; j < 16; j++) - { - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); - } + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); + } - DEBUGADD(4, ("\n")); - } + DEBUGADD(4, ("\n")); + } } /**************************************************************************** - process a nmb packet - ****************************************************************************/ + Process a nmb packet. +****************************************************************************/ + void debug_nmb_packet(struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode, - BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount ); - } - - if (nmb->header.qdcount) - { - DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - nmb_namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class) ); - } - - if (nmb->answers && nmb->header.ancount) - { - debug_nmb_res_rec(nmb->answers,"answers"); - } - if (nmb->nsrecs && nmb->header.nscount) - { - debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); - } - if (nmb->additional && nmb->header.arcount) - { - debug_nmb_res_rec(nmb->additional,"additional"); - } + struct nmb_packet *nmb = &p->packet.nmb; + + if( DEBUGLVL( 4 ) ) { + dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response) ); + dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative) ); + dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount ); + } + + if (nmb->header.qdcount) { + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + nmb_namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); + } + + if (nmb->answers && nmb->header.ancount) { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) { + debug_nmb_res_rec(nmb->additional,"additional"); + } } /******************************************************************* - handle "compressed" name pointers - ******************************************************************/ -static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, + Handle "compressed" name pointers. +******************************************************************/ + +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { - int loop_count=0; + int loop_count=0; - while ((ubuf[*offset] & 0xC0) == 0xC0) { - if (!*got_pointer) (*ret) += 2; - (*got_pointer)=True; - (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); - } - } - return(True); + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) + (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); } /******************************************************************* - parse a nmb name from "compressed" format to something readable - return the space taken by the name, or 0 if the name is invalid - ******************************************************************/ + Parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid +******************************************************************/ + static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { - int m,n=0; - uchar *ubuf = (uchar *)inbuf; - int ret = 0; - BOOL got_pointer=False; - int loop_count=0; - int offset = ofs; - - if (length - offset < 2) - return(0); - - /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); + int m,n=0; + unsigned char *ubuf = (unsigned char *)inbuf; + int ret = 0; + BOOL got_pointer=False; + int loop_count=0; + int offset = ofs; + + if (length - offset < 2) + return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); - m = ubuf[offset]; - - if (!m) - return(0); - if ((m & 0xC0) || offset+m+2 > length) - return(0); - - memset((char *)name,'\0',sizeof(*name)); - - /* the "compressed" part */ - if (!got_pointer) - ret += m + 2; - offset++; - while (m > 0) { - uchar c1,c2; - c1 = ubuf[offset++]-'A'; - c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) - return(0); - name->name[n++] = (c1<<4) | c2; - m -= 2; - } - name->name[n] = 0; - - if (n==16) { - /* parse out the name type, - its always in the 16th byte of the name */ - name->name_type = ((uchar)name->name[15]) & 0xff; + m = ubuf[offset]; + + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); + + memset((char *)name,'\0',sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) + ret += m + 2; + offset++; + while (m > 0) { + unsigned char c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==MAX_NETBIOSNAME_LEN) { + /* parse out the name type, its always in the 16th byte of the name */ + name->name_type = ((unsigned char)name->name[15]) & 0xff; - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; - } - - /* now the domain parts (if any) */ - n = 0; - while (ubuf[offset]) { - /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - /* - * Don't allow null domain parts. - */ - if (!m) - return(0); - if (!got_pointer) - ret += m+1; - if (n) - name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) - return(0); - offset++; - while (m--) - name->scope[n++] = (char)ubuf[offset++]; - - /* - * Watch for malicious loops. - */ - if (loop_count++ == 10) - return 0; - } - name->scope[n++] = 0; - - return(ret); + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') + name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while (ubuf[offset]) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); + + m = ubuf[offset]; + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); + offset++; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; + } + name->scope[n++] = 0; + + return(ret); } +/**************************************************************************** + Put a netbios name, padding(s) and a name type into a 16 character buffer. + name is already in DOS charset. + [15 bytes name + padding][1 byte name type]. +****************************************************************************/ + +static void put_name(char *dest, const char *name, int pad, unsigned int name_type) +{ + size_t len = strlen(name); + + memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1); + if (len < MAX_NETBIOSNAME_LEN - 1) { + memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len); + } + dest[MAX_NETBIOSNAME_LEN - 1] = name_type; +} /******************************************************************* - put a compressed nmb name into a buffer. return the length of the - compressed name + Put a compressed nmb name into a buffer. Return the length of the + compressed name. + + Compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. +******************************************************************/ - compressed names are really weird. The "compression" doubles the - size. The idea is that it also means that compressed names conform - to the doman name system. See RFC1002. - ******************************************************************/ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { - int ret,m; - fstring buf1; - char *p; - - if (strcmp(name->name,"*") == 0) { - /* special case for wildcard name */ - memset(buf1,'\0',20); - buf1[0] = '*'; - buf1[15] = name->name_type; - } else { - slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); - } - - buf[offset] = 0x20; - - ret = 34; - - for (m=0;m<16;m++) { - buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); - } - offset += 33; - - buf[offset] = 0; - - if (name->scope[0]) { - /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; - safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); + int ret,m; + fstring buf1; + char *p; + + if (strcmp(name->name,"*") == 0) { + /* special case for wildcard name */ + put_name(buf1, "*", '\0', name->name_type); + } else { + put_name(buf1, name->name, ' ', name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); - p = &buf[offset+1]; - } - buf[offset] = strlen(&buf[offset+1]); - } - - return(ret); + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); } /******************************************************************* @@ -331,336 +346,347 @@ char *nmb_namestr(struct nmb_name *n) } /******************************************************************* - allocate and parse some resource records - ******************************************************************/ + Allocate and parse some resource records. +******************************************************************/ + static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, struct res_rec **recs, int count) { - int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); - if (!*recs) return(False); - - memset((char *)*recs,'\0',sizeof(**recs)*count); - - for (i=0;i length) { - SAFE_FREE(*recs); - return(False); - } - (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); - (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); - (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); - (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); - (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || - (*offset)+(*recs)[i].rdlength > length) { - SAFE_FREE(*recs); - return(False); - } - memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; - } - return(True); + int i; + + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) + return(False); + + memset((char *)*recs,'\0',sizeof(**recs)*count); + + for (i=0;i length) { + SAFE_FREE(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + SAFE_FREE(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); } /******************************************************************* - put a resource record into a packet - ******************************************************************/ + Put a resource record into a packet. +******************************************************************/ + static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) { - int ret=0; - int i; - - for (i=0;i> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); - offset += 2; - ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); - offset += 10+rec->rdlength; - ret += 10+rec->rdlength; + int ret=0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; - return(ret); + return(ret); } /******************************************************************* - parse a dgram packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise + Parse a dgram packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. + + This is documented in section 4.4.1 of RFC1002. +******************************************************************/ - this is documented in section 4.4.1 of RFC1002 - ******************************************************************/ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) { - int offset; - int flags; - - memset((char *)dgram,'\0',sizeof(*dgram)); - - if (length < 14) return(False); - - dgram->header.msg_type = CVAL(inbuf,0); - flags = CVAL(inbuf,1); - dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); - if (flags & 1) dgram->header.flags.more = True; - if (flags & 2) dgram->header.flags.first = True; - dgram->header.dgm_id = RSVAL(inbuf,2); - putip((char *)&dgram->header.source_ip,inbuf+4); - dgram->header.source_port = RSVAL(inbuf,8); - dgram->header.dgm_length = RSVAL(inbuf,10); - dgram->header.packet_offset = RSVAL(inbuf,12); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); - } + int offset; + int flags; + + memset((char *)dgram,'\0',sizeof(*dgram)); + + if (length < 14) + return(False); + + dgram->header.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) + dgram->header.flags.more = True; + if (flags & 2) + dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } - if (offset >= length || (length-offset > sizeof(dgram->data))) - return(False); + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); - dgram->datasize = length-offset; - memcpy(dgram->data,inbuf+offset,dgram->datasize); + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); - return(True); + return(True); } - /******************************************************************* - parse a nmb packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - ******************************************************************/ + Parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. +******************************************************************/ + static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { - int nm_flags,offset; - - memset((char *)nmb,'\0',sizeof(*nmb)); - - if (length < 12) return(False); - - /* parse the header */ - nmb->header.name_trn_id = RSVAL(inbuf,0); - - DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); - - nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; - nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; - nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); - nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; - nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; - nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; - nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; - nmb->header.rcode = CVAL(inbuf,3) & 0xF; - nmb->header.qdcount = RSVAL(inbuf,4); - nmb->header.ancount = RSVAL(inbuf,6); - nmb->header.nscount = RSVAL(inbuf,8); - nmb->header.arcount = RSVAL(inbuf,10); + int nm_flags,offset; + + memset((char *)nmb,'\0',sizeof(*nmb)); + + if (length < 12) + return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); - if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); - if (!offset) return(False); - - if (length - (12+offset) < 4) return(False); - nmb->question.question_type = RSVAL(inbuf,12+offset); - nmb->question.question_class = RSVAL(inbuf,12+offset+2); - - offset += 12+4; - } else { - offset = 12; - } - - /* and any resource records */ - if (nmb->header.ancount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, - nmb->header.ancount)) - return(False); - - if (nmb->header.nscount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, - nmb->header.nscount)) - return(False); + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) + return(False); + + if (length - (12+offset) < 4) + return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); - if (nmb->header.arcount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) - return(False); + if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); - return(True); + return(True); } /******************************************************************* - 'Copy constructor' for an nmb packet - ******************************************************************/ + 'Copy constructor' for an nmb packet. +******************************************************************/ + static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) { - struct nmb_packet *nmb; - struct nmb_packet *copy_nmb; - struct packet_struct *pkt_copy; - - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_nmb_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* Ensure this copy has no resource records. */ - nmb = &packet->packet.nmb; - copy_nmb = &pkt_copy->packet.nmb; - - copy_nmb->answers = NULL; - copy_nmb->nsrecs = NULL; - copy_nmb->additional = NULL; - - /* Now copy any resource records. */ - - if (nmb->answers) - { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, - nmb->header.ancount * sizeof(struct res_rec)); - } - if (nmb->nsrecs) - { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, - nmb->header.nscount * sizeof(struct res_rec)); - } - if (nmb->additional) - { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, - nmb->header.arcount * sizeof(struct res_rec)); - } - - return pkt_copy; - -free_and_exit: - - SAFE_FREE(copy_nmb->answers); - SAFE_FREE(copy_nmb->nsrecs); - SAFE_FREE(copy_nmb->additional); - SAFE_FREE(pkt_copy); - - DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); - return NULL; + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + + free_and_exit: + + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; } /******************************************************************* - 'Copy constructor' for a dgram packet - ******************************************************************/ + 'Copy constructor' for a dgram packet. +******************************************************************/ + static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { - struct packet_struct *pkt_copy; + struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_dgram_packet: malloc fail.\n")); - return NULL; - } + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } - /* Structure copy of entire thing. */ + /* Structure copy of entire thing. */ - *pkt_copy = *packet; + *pkt_copy = *packet; - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; - /* There are no additional pointers in a dgram packet, - we are finished. */ - return pkt_copy; + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; } /******************************************************************* - 'Copy constructor' for a generic packet - ******************************************************************/ + 'Copy constructor' for a generic packet. +******************************************************************/ + struct packet_struct *copy_packet(struct packet_struct *packet) { - if(packet->packet_type == NMB_PACKET) - return copy_nmb_packet(packet); - else if (packet->packet_type == DGRAM_PACKET) - return copy_dgram_packet(packet); - return NULL; + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; } /******************************************************************* - free up any resources associated with an nmb packet - ******************************************************************/ + Free up any resources associated with an nmb packet. +******************************************************************/ + static void free_nmb_packet(struct nmb_packet *nmb) { - SAFE_FREE(nmb->answers); - SAFE_FREE(nmb->nsrecs); - SAFE_FREE(nmb->additional); + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); } /******************************************************************* - free up any resources associated with a dgram packet - ******************************************************************/ + Free up any resources associated with a dgram packet. +******************************************************************/ + static void free_dgram_packet(struct dgram_packet *nmb) { - /* We have nothing to do for a dgram packet. */ + /* We have nothing to do for a dgram packet. */ } /******************************************************************* - free up any resources associated with a packet - ******************************************************************/ + Free up any resources associated with a packet. +******************************************************************/ + void free_packet(struct packet_struct *packet) { - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - else if (packet->packet_type == DGRAM_PACKET) - free_dgram_packet(&packet->packet.dgram); - ZERO_STRUCTPN(packet); - SAFE_FREE(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); + SAFE_FREE(packet); } /******************************************************************* -parse a packet buffer into a packet structure - ******************************************************************/ + Parse a packet buffer into a packet structure. +******************************************************************/ + struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type) { @@ -670,7 +696,8 @@ struct packet_struct *parse_packet(char *buf,int length, BOOL ok=False; p = (struct packet_struct *)malloc(sizeof(*p)); - if (!p) return(NULL); + if (!p) + return(NULL); p->next = NULL; p->prev = NULL; @@ -699,9 +726,10 @@ struct packet_struct *parse_packet(char *buf,int length, } /******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ + Read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket. +******************************************************************/ + struct packet_struct *read_packet(int fd,enum packet_type packet_type) { struct packet_struct *packet; @@ -709,10 +737,12 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) int length; length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); + if (length < MIN_DGRAM_SIZE) + return(NULL); packet = parse_packet(buf, length, packet_type); - if (!packet) return NULL; + if (!packet) + return NULL; packet->fd = fd; @@ -724,96 +754,99 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) return(packet); } - /******************************************************************* - send a udp packet on a already open socket - ******************************************************************/ + Send a udp packet on a already open socket. +******************************************************************/ + static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret = False; - int i; - struct sockaddr_in sock_out; - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; + BOOL ret = False; + int i; + struct sockaddr_in sock_out; + + /* set the address and port */ + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; - DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, inet_ntoa(ip), port ) ); + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); - /* - * Patch to fix asynch error notifications from Linux kernel. - */ + /* + * Patch to fix asynch error notifications from Linux kernel. + */ - for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); - if (ret || errno != ECONNREFUSED) - break; - } + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } - if (!ret) - DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); - if (ret) - num_good_sends++; + if (ret) + num_good_sends++; - return(ret); + return(ret); } /******************************************************************* - build a dgram packet ready for sending + Build a dgram packet ready for sending. - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + +******************************************************************/ - ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { - struct dgram_packet *dgram = &p->packet.dgram; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) ubuf[1] |= 1; - if (dgram->header.flags.first) ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); - } - - memcpy(ubuf+offset,dgram->data,dgram->datasize); - offset += dgram->datasize; - - /* automatically set the dgm_length - * NOTE: RFC1002 says the dgm_length does *not* - * include the fourteen-byte header. crh - */ - dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); - - return(offset); + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); } /******************************************************************* @@ -830,92 +863,99 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) /******************************************************************* Compare two nmb names - ******************************************************************/ +******************************************************************/ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) { - return ((n1->name_type == n2->name_type) && - strequal(n1->name ,n2->name ) && - strequal(n1->scope,n2->scope)); + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); } /******************************************************************* - build a nmb packet ready for sending + Build a nmb packet ready for sending. + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) +******************************************************************/ - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) - ******************************************************************/ static int build_nmb(char *buf,struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) + ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) + ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); - offset += 12; - if (nmb->header.qdcount) { - /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); - offset += 4; - } - - if (nmb->header.ancount) - offset += put_res_rec((char *)ubuf,offset,nmb->answers, - nmb->header.ancount); - - if (nmb->header.nscount) - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, - nmb->header.nscount); - - /* - * The spec says we must put compressed name pointers - * in the following outgoing packets : - * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, - * NAME_RELEASE_REQUEST. - */ - - if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - - } else if (nmb->header.arcount) { - offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); - } - return(offset); -} + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + } else if (nmb->header.arcount) { + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + } + return(offset); +} /******************************************************************* -linearise a packet - ******************************************************************/ + Linearise a packet. +******************************************************************/ + int build_packet(char *buf, struct packet_struct *p) { int len = 0; @@ -934,26 +974,29 @@ int build_packet(char *buf, struct packet_struct *p) } /******************************************************************* - send a packet_struct - ******************************************************************/ + Send a packet_struct. +******************************************************************/ + BOOL send_packet(struct packet_struct *p) { - char buf[1024]; - int len=0; + char buf[1024]; + int len=0; - memset(buf,'\0',sizeof(buf)); + memset(buf,'\0',sizeof(buf)); - len = build_packet(buf, p); + len = build_packet(buf, p); - if (!len) return(False); + if (!len) + return(False); - return(send_udp(p->fd,buf,len,p->ip,p->port)); + return(send_udp(p->fd,buf,len,p->ip,p->port)); } /**************************************************************************** - receive a packet with timeout on a open UDP filedescriptor - The timeout is in milliseconds - ***************************************************************************/ + Receive a packet with timeout on a open UDP filedescriptor. + The timeout is in milliseconds +***************************************************************************/ + struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { fd_set fds; @@ -980,12 +1023,12 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) return(NULL); } - /**************************************************************************** - receive a UDP/137 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified trn_id - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id. + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) { struct packet_struct *p; @@ -993,20 +1036,22 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) p = receive_packet(fd, NMB_PACKET, t); if (p && p->packet.nmb.header.response && - p->packet.nmb.header.name_trn_id == trn_id) { + p->packet.nmb.header.name_trn_id == trn_id) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(NMB_PACKET, trn_id, NULL); } /**************************************************************************** - receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified mailslot name - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified mailslot name + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1016,16 +1061,17 @@ struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_n if (p && match_mailslot_name(p, mailslot_name)) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); } - /**************************************************************************** - see if a datagram has the right mailslot name + See if a datagram has the right mailslot name. ***************************************************************************/ + BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; @@ -1043,71 +1089,76 @@ BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) return False; } - /**************************************************************************** -return the number of bits that match between two 4 character buffers - ***************************************************************************/ -int matching_quad_bits(uchar *p1, uchar *p2) + Return the number of bits that match between two 4 character buffers +***************************************************************************/ + +int matching_quad_bits(unsigned char *p1, unsigned char *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { - if (p1[i] != p2[i]) break; + if (p1[i] != p2[i]) + break; ret += 8; } - if (i==4) return ret; + if (i==4) + return ret; for (j=0; j<8; j++) { - if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) + break; ret++; } return ret; } - -static uchar sort_ip[4]; +static unsigned char sort_ip[4]; /**************************************************************************** -compare two query reply records - ***************************************************************************/ -static int name_query_comp(uchar *p1, uchar *p2) + Compare two query reply records. +***************************************************************************/ + +static int name_query_comp(unsigned char *p1, unsigned char *p2) { return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -sort a set of 6 byte name query response records so that the IPs that -have the most leading bits in common with the specified address come first - ***************************************************************************/ + Sort a set of 6 byte name query response records so that the IPs that + have the most leading bits in common with the specified address come first. +***************************************************************************/ + void sort_query_replies(char *data, int n, struct in_addr ip) { - if (n <= 1) return; + if (n <= 1) + return; putip(sort_ip, (char *)&ip); qsort(data, n, 6, QSORT_CAST name_query_comp); } - #define TRUNCATE_NETBIOS_NAME 1 /******************************************************************* - convert, possibly using a stupid microsoft-ism which has destroyed + Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually use the Win95-type methods, not for NT to NT communication, which uses DCE/RPC and therefore full-length unicode strings...) a dns name into a netbios name. - the netbios name (NOT necessarily null-terminated) is truncated to 15 + The netbios name (NOT necessarily null-terminated) is truncated to 15 characters. ******************************************************************/ -char *dns_to_netbios_name(char *dns_name) + +char *dns_to_netbios_name(const char *dns_name) { - static char netbios_name[16]; + static nstring netbios_name; int i; - StrnCpy(netbios_name, dns_name, 15); + StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; #ifdef TRUNCATE_NETBIOS_NAME @@ -1116,10 +1167,8 @@ char *dns_to_netbios_name(char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i >= 15; i--) - { - if (netbios_name[i] == '.') - { + for (i = 0; i >= 15; i--) { + if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } @@ -1129,146 +1178,146 @@ char *dns_to_netbios_name(char *dns_name) return netbios_name; } - /**************************************************************************** -interpret the weird netbios "name" into a unix fstring. Return the name type + Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ + static int name_interpret(char *in, fstring name) { - int ret; - int len = (*in++) / 2; - fstring out_string; - char *out = out_string; - - *out=0; - - if (len > 30 || len<1) return(0); - - while (len--) - { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; - } - ret = out[-1]; - out[-1] = 0; + int ret; + int len = (*in++) / 2; + fstring out_string; + char *out = out_string; + + *out=0; + + if (len > 30 || len<1) + return(0); + + while (len--) { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) - { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(uchar *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } + /* Handle any scope names */ + while(*in) { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(unsigned char *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } #endif - pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); + pull_ascii_fstring(name, out_string); - return(ret); + return(ret); } /**************************************************************************** -mangle a name into netbios format - - Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. + Mangle a name into netbios format. + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ + int name_mangle( char *In, char *Out, char name_type ) - { - int i; - int c; - int len; - char buf[20]; - char *p = Out; - - /* Safely copy the input string, In, into buf[]. */ - (void)memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) - buf[0] = '*'; - else - (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); - - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; - - /* Now convert the name to the rfc1001/1002 format. */ - for( i = 0; i < 16; i++ ) - { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; - } - p += 32; - p[0] = '\0'; - - /* Add the scope string. */ - for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) - { - switch( (global_scope())[i] ) - { - case '\0': - p[0] = len; - if( len > 0 ) - p[len+1] = 0; - return( name_len(Out) ); - case '.': - p[0] = len; - p += (len + 1); - len = -1; - break; - default: - p[len+1] = (global_scope())[i]; - break; - } - } - - return( name_len(Out) ); - } /* name_mangle */ +{ + int i; + int c; + int len; + char buf[20]; + char *p = Out; + + /* Safely copy the input string, In, into buf[]. */ + memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) { + buf[0] = '*'; + } else { + slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + } + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (c & 0x000F) + 'A'; + } + p += 32; + p[0] = '\0'; + + /* Add the scope string. */ + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { + switch( (global_scope())[i] ) { + case '\0': + p[0] = len; + if( len > 0 ) + p[len+1] = 0; + return( name_len(Out) ); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = (global_scope())[i]; + break; + } + } + + return( name_len(Out) ); +} /**************************************************************************** -find a pointer to a netbios name + Find a pointer to a netbios name. ****************************************************************************/ + static char *name_ptr(char *buf,int ofs) { - uchar c = *(uchar *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16 l = RSVAL(buf, ofs) & 0x3FFF; - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); + unsigned char c = *(unsigned char *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } else { + return(buf+ofs); + } } /**************************************************************************** -extract a netbios name from a buf (into a unix string) return name type + Extract a netbios name from a buf (into a unix string) return name type. ****************************************************************************/ + int name_extract(char *buf,int ofs, fstring name) { - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + + name[0] = '\0'; + if (d < -50 || d > 50) + return(0); + return(name_interpret(p,name)); } /**************************************************************************** -return the total storage length of a mangled name + Return the total storage length of a mangled name. ****************************************************************************/ + int name_len(char *s1) { /* NOTE: this argument _must_ be unsigned */ - uchar *s = (uchar *)s1; + unsigned char *s = (unsigned char *)s1; int len; /* If the two high bits of the byte are set, return 2. */ @@ -1282,4 +1331,4 @@ int name_len(char *s1) } return(len); -} /* name_len */ +} -- cgit From 6b9dbbcd249360fb9acd61d6900baccf621c9cce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:16:21 +0000 Subject: Modified fix for bugid #784. Based on a patch from moriyama@miraclelinux.com (MORIYAMA Masayuki). Don't use nstrings to hold workgroup and netbios names. The problem with them is that MB netbios and workgroup names in unix charset (particularly utf8) may be up to 3x bigger than the name when represented in dos charset (ie. cp932). So go back to using fstrings for these but translate into nstrings (ie. 16 byte length values) for transport on the wire. Jeremy. (This used to be commit b4ea493599ab414f7828b83f40a5a8b43479ff64) --- source3/libsmb/nmblib.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index cbe495cd95..bc2cca0e0e 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -285,7 +285,7 @@ static void put_name(char *dest, const char *name, int pad, unsigned int name_ty static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { int ret,m; - fstring buf1; + nstring buf1; char *p; if (strcmp(name->name,"*") == 0) { @@ -1230,17 +1230,24 @@ static int name_interpret(char *in, fstring name) int name_mangle( char *In, char *Out, char name_type ) { int i; - int c; int len; - char buf[20]; + nstring buf; char *p = Out; /* Safely copy the input string, In, into buf[]. */ - memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) { - buf[0] = '*'; - } else { - slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + if (strcmp(In,"*") == 0) + put_name(buf, "*", '\0', 0x00); + else { + /* We use an fstring here as mb dos names can expend x3 when + going to utf8. */ + fstring buf_unix; + nstring buf_dos; + + pull_ascii_fstring(buf_unix, In); + strupper_m(buf_unix); + + push_ascii_nstring(buf_dos, buf_unix); + put_name(buf, buf_dos, ' ', name_type); } /* Place the length of the first field into the output buffer. */ @@ -1249,9 +1256,8 @@ int name_mangle( char *In, char *Out, char name_type ) /* Now convert the name to the rfc1001/1002 format. */ for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; + p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (buf[i] & 0x000F) + 'A'; } p += 32; p[0] = '\0'; -- cgit From a0034d3586dadfddc18e4a3096564bf158d43e4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:47:21 +0000 Subject: Ensure we don't truncate strcmps to nstring anymore... Jeremy. (This used to be commit d7cf64b1e4e501bcd01ddc8279babc65d894a4b3) --- source3/libsmb/nmblib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index bc2cca0e0e..3c25eba744 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -855,8 +855,11 @@ static int build_dgram(char *buf,struct packet_struct *p) void make_nmb_name( struct nmb_name *n, const char *name, int type) { + fstring unix_name; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); + fstrcpy(unix_name, name); + strupper_m(unix_name); + push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE); n->name_type = (unsigned int)type & 0xFF; push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); } -- cgit From bb8a4a7991a04e16765f68e5cb770617d086e3d8 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 18 May 2004 18:13:19 +0000 Subject: r775: merge trunk 774 to samba 3_0 - fix bad compare in for loop (This used to be commit 3cb8f1d53583dac0b77495cbcd017c366af59891) --- source3/libsmb/nmblib.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3c25eba744..51a5671144 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1143,8 +1143,6 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } -#define TRUNCATE_NETBIOS_NAME 1 - /******************************************************************* Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually @@ -1164,19 +1162,17 @@ char *dns_to_netbios_name(const char *dns_name) StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; -#ifdef TRUNCATE_NETBIOS_NAME /* ok. this is because of a stupid microsoft-ism. if the called host name contains a '.', microsoft clients expect you to truncate the netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i >= 15; i--) { + for (i = 0; i < 15; i--) { if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } } -#endif /* TRUNCATE_NETBIOS_NAME */ return netbios_name; } -- cgit From 84cea46162d6328c2e3bc0166f5b27a0fa01b3f9 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 18 May 2004 20:48:14 +0000 Subject: r776: I should have just cut and pasted from my build area and I would have gotten this right :-) (This used to be commit 548070274efa12f8c9a4404145d8a2a8c85387b3) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 51a5671144..d883c5308d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1167,7 +1167,7 @@ char *dns_to_netbios_name(const char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i < 15; i--) { + for (i = 0; i < 15; i++) { if (netbios_name[i] == '.') { netbios_name[i] = 0; break; -- cgit From 571cc4811bc373a5b4aeda9e5635aff1ff650e06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Sep 2004 01:57:16 +0000 Subject: r2224: Make nmbd more robust against bad netbios packets. Jeremy. (This used to be commit dd9b17abd6b32c090840c1a0b797fd774711cb3a) --- source3/libsmb/nmblib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d883c5308d..7f22ce0096 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -475,6 +475,11 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) dgram->datasize = length-offset; memcpy(dgram->data,inbuf+offset,dgram->datasize); + /* Paranioa. Ensure the last 2 bytes in the dgram buffer are + zero. This should be true anyway, just enforce it for paranioa sake. JRA. */ + SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2)); + memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2); + return(True); } -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libsmb/nmblib.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7f22ce0096..1c93f7b1e2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -354,7 +354,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, { int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + *recs = SMB_MALLOC_ARRAY(struct res_rec, count); if (!*recs) return(False); @@ -557,7 +557,7 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) struct nmb_packet *copy_nmb; struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { DEBUG(0,("copy_nmb_packet: malloc fail.\n")); return NULL; } @@ -580,22 +580,19 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) /* Now copy any resource records. */ if (nmb->answers) { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->answers, (char *)nmb->answers, nmb->header.ancount * sizeof(struct res_rec)); } if (nmb->nsrecs) { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, nmb->header.nscount * sizeof(struct res_rec)); } if (nmb->additional) { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->additional, (char *)nmb->additional, nmb->header.arcount * sizeof(struct res_rec)); @@ -622,7 +619,7 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { DEBUG(0,("copy_dgram_packet: malloc fail.\n")); return NULL; } @@ -700,7 +697,7 @@ struct packet_struct *parse_packet(char *buf,int length, struct packet_struct *p; BOOL ok=False; - p = (struct packet_struct *)malloc(sizeof(*p)); + p = SMB_MALLOC_P(struct packet_struct); if (!p) return(NULL); -- cgit From 978ca8486031e43754a3c23757f361bf3a85f335 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/libsmb/nmblib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1c93f7b1e2..164f85be7b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,6 +21,9 @@ #include "includes.h" +extern struct in_addr lastip; +extern int lastport; + int num_good_sends = 0; int num_good_receives = 0; @@ -692,8 +695,6 @@ void free_packet(struct packet_struct *packet) struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type) { - extern struct in_addr lastip; - extern int lastport; struct packet_struct *p; BOOL ok=False; -- cgit From 83b987befdbba857131102700d237728784b6f69 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Dec 2005 23:06:38 +0000 Subject: r12107: Move to a tdb-based wins database. At the moment we still use it as though it were an in-memory db and dump out to a flat file every 2 mins, but that can now change. Jeremy. (This used to be commit a342681792724c1ae8561ba8d352c4ee6e2a5332) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 164f85be7b..4d84d7bc49 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -331,7 +331,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) Useful for debugging messages. ******************************************************************/ -char *nmb_namestr(struct nmb_name *n) +char *nmb_namestr(const struct nmb_name *n) { static int i=0; static fstring ret[4]; -- cgit From 351e749246a278b60a7e18c1eeafdc8ec70efea2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 12:24:25 +0000 Subject: r15240: Correctly disallow unauthorized access when logging on with the kerberized pam_winbind and workstation restrictions are in effect. The krb5 AS-REQ needs to add the host netbios-name in the address-list. We don't get the clear NT_STATUS_INVALID_WORKSTATION code back yet from the edata of the KRB_ERROR but the login at least fails when the local machine is not in the workstation list on the DC. Guenther (This used to be commit 8b2ba11508e2730aba074d7c095291fac2a62176) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4d84d7bc49..5280dfdbff 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -265,7 +265,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) [15 bytes name + padding][1 byte name type]. ****************************************************************************/ -static void put_name(char *dest, const char *name, int pad, unsigned int name_type) +void put_name(char *dest, const char *name, int pad, unsigned int name_type) { size_t len = strlen(name); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 5280dfdbff..b6dec4dc65 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/nmblib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b6dec4dc65..348555baf8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ -- cgit From 0d87820380416955a132d565a479b4234f78c113 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Oct 2007 20:43:55 +0000 Subject: r25492: Start adding IPv6 compatible code to lib/util_sock.c and deal with the ripple effects this causes. utmp has to change etc. Remove some global varables and store address/port in the unexpected db. Jeremy. (This used to be commit 18c6a2211d9e25233d01715b3f78977edcd6d869) --- source3/libsmb/nmblib.c | 473 +++++++++++++++++++++++++++++------------------- 1 file changed, 283 insertions(+), 190 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 348555baf8..74deb91a73 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1,28 +1,26 @@ -/* +/* Unix SMB/CIFS implementation. NBT netbios library routines Copyright (C) Andrew Tridgell 1994-1998 - + Copyright (C) Jeremy Allison 2007 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ #include "includes.h" -extern struct in_addr lastip; -extern int lastport; - int num_good_sends = 0; int num_good_receives = 0; @@ -82,12 +80,12 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) unsigned char x = res->rdata[i+j]; if (x < 32 || x > 127) x = '.'; - + if (i+j >= res->rdlength) break; DEBUGADD(4, ("%c", x)); } - + DEBUGADD(4, (" hex ")); for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { @@ -95,7 +93,7 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) break; DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); } - + DEBUGADD(4, ("\n")); } } @@ -109,19 +107,22 @@ void debug_nmb_packet(struct packet_struct *p) struct nmb_packet *nmb = &p->packet.nmb; if( DEBUGLVL( 4 ) ) { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + dbgtext( "nmb packet from %s(%d) header: id=%d " + "opcode=%s(%d) response=%s\n", inet_ntoa(p->ip), p->port, nmb->header.name_trn_id, lookup_opcode_name(nmb->header.opcode), nmb->header.opcode, BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + dbgtext( " header: flags: bcast=%s rec_avail=%s " + "rec_des=%s trunc=%s auth=%s\n", BOOLSTR(nmb->header.nm_flags.bcast), BOOLSTR(nmb->header.nm_flags.recursion_available), BOOLSTR(nmb->header.nm_flags.recursion_desired), BOOLSTR(nmb->header.nm_flags.trunc), BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + dbgtext( " header: rcode=%d qdcount=%d ancount=%d " + "nscount=%d arcount=%d\n", nmb->header.rcode, nmb->header.qdcount, nmb->header.ancount, @@ -155,17 +156,18 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; - + while ((ubuf[*offset] & 0xC0) == 0xC0) { if (!*got_pointer) (*ret) += 2; (*got_pointer)=True; (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); + if (loop_count++ == 10 || + (*offset) < 0 || (*offset)>(length-2)) { + return False; } } - return(True); + return True; } /******************************************************************* @@ -183,12 +185,12 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) int offset = ofs; if (length - offset < 2) - return(0); + return(0); /* handle initial name pointers */ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); - + m = ubuf[offset]; if (!m) @@ -214,14 +216,15 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) name->name[n] = 0; if (n==MAX_NETBIOSNAME_LEN) { - /* parse out the name type, its always in the 16th byte of the name */ + /* parse out the name type, its always + * in the 16th byte of the name */ name->name_type = ((unsigned char)name->name[15]) & 0xff; - + /* remove trailing spaces */ name->name[15] = 0; n = 14; while (n && name->name[n]==' ') - name->name[n--] = 0; + name->name[n--] = 0; } /* now the domain parts (if any) */ @@ -253,7 +256,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) if (loop_count++ == 10) return 0; } - name->scope[n++] = 0; + name->scope[n++] = 0; return(ret); } @@ -268,7 +271,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type) { size_t len = strlen(name); - memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1); + memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? + len : MAX_NETBIOSNAME_LEN - 1); if (len < MAX_NETBIOSNAME_LEN - 1) { memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len); } @@ -282,6 +286,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type) Compressed names are really weird. The "compression" doubles the size. The idea is that it also means that compressed names conform to the doman name system. See RFC1002. + + If buf == NULL this is a length calculation. ******************************************************************/ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) @@ -297,33 +303,42 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) put_name(buf1, name->name, ' ', name->name_type); } - buf[offset] = 0x20; + if (buf) { + buf[offset] = 0x20; + } ret = 34; for (m=0;m>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + if (buf) { + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } } offset += 33; - buf[offset] = 0; + if (buf) { + buf[offset] = 0; + } if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); - - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); + if (buf) { + safe_strcpy(&buf[offset+1],name->scope, + sizeof(name->scope)); + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); } - buf[offset] = strlen(&buf[offset+1]); } - return(ret); + return ret; } /******************************************************************* @@ -341,7 +356,8 @@ char *nmb_namestr(const struct nmb_name *n) if (!n->scope[0]) slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope); + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s", + name,n->name_type,n->scope); i = (i+1)%4; return(p); @@ -363,7 +379,8 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, memset((char *)*recs,'\0',sizeof(**recs)*count); for (i=0;i length) { SAFE_FREE(*recs); @@ -374,19 +391,20 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { SAFE_FREE(*recs); return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; + (*offset) += (*recs)[i].rdlength; } return(True); } /******************************************************************* Put a resource record into a packet. + If buf == NULL this is a length calculation. ******************************************************************/ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) @@ -398,42 +416,52 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) int l = put_nmb_name(buf,offset,&recs[i].rr_name); offset += l; ret += l; - RSSVAL(buf,offset,recs[i].rr_type); - RSSVAL(buf,offset+2,recs[i].rr_class); - RSIVAL(buf,offset+4,recs[i].ttl); - RSSVAL(buf,offset+8,recs[i].rdlength); - memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength); + if (buf) { + RSSVAL(buf,offset,recs[i].rr_type); + RSSVAL(buf,offset+2,recs[i].rr_class); + RSIVAL(buf,offset+4,recs[i].ttl); + RSSVAL(buf,offset+8,recs[i].rdlength); + memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength); + } offset += 10+recs[i].rdlength; ret += 10+recs[i].rdlength; } - return(ret); + return ret; } /******************************************************************* Put a compressed name pointer record into a packet. + If buf == NULL this is a length calculation. ******************************************************************/ -static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) -{ +static int put_compressed_name_ptr(unsigned char *buf, + int offset, + struct res_rec *rec, + int ptr_offset) +{ int ret=0; - buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); + if (buf) { + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + } offset += 2; ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); + if (buf) { + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + } offset += 10+rec->rdlength; ret += 10+rec->rdlength; - - return(ret); + + return ret; } /******************************************************************* - Parse a dgram packet. Return False if the packet can't be parsed + Parse a dgram packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise. This is documented in section 4.4.1 of RFC1002. @@ -466,19 +494,22 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) if (dgram->header.msg_type == 0x10 || dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length, + &dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length, + &dgram->dest_name); } - if (offset >= length || (length-offset > sizeof(dgram->data))) + if (offset >= length || (length-offset > sizeof(dgram->data))) return(False); dgram->datasize = length-offset; memcpy(dgram->data,inbuf+offset,dgram->datasize); /* Paranioa. Ensure the last 2 bytes in the dgram buffer are - zero. This should be true anyway, just enforce it for paranioa sake. JRA. */ + zero. This should be true anyway, just enforce it for + paranioa sake. JRA. */ SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2)); memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2); @@ -486,7 +517,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) } /******************************************************************* - Parse a nmb packet. Return False if the packet can't be parsed + Parse a nmb packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise. ******************************************************************/ @@ -511,15 +542,16 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; nmb->header.rcode = CVAL(inbuf,3) & 0xF; nmb->header.qdcount = RSVAL(inbuf,4); nmb->header.ancount = RSVAL(inbuf,6); nmb->header.nscount = RSVAL(inbuf,8); nmb->header.arcount = RSVAL(inbuf,10); - + if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + offset = parse_nmb_name(inbuf,12,length, + &nmb->question.question_name); if (!offset) return(False); @@ -534,16 +566,19 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) } /* and any resource records */ - if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + if (nmb->header.ancount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, nmb->header.ancount)) return(False); - if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + if (nmb->header.nscount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, nmb->header.nscount)) return(False); - - if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) + + if (nmb->header.arcount && + !parse_alloc_res_rec(inbuf,&offset,length, + &nmb->additional, nmb->header.arcount)) return(False); return(True); @@ -554,7 +589,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) ******************************************************************/ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) -{ +{ struct nmb_packet *nmb; struct nmb_packet *copy_nmb; struct packet_struct *pkt_copy; @@ -582,21 +617,24 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) /* Now copy any resource records. */ if (nmb->answers) { - if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL) + if((copy_nmb->answers = SMB_MALLOC_ARRAY( + struct res_rec,nmb->header.ancount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, nmb->header.ancount * sizeof(struct res_rec)); } if (nmb->nsrecs) { - if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL) + if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY( + struct res_rec, nmb->header.nscount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, nmb->header.nscount * sizeof(struct res_rec)); } if (nmb->additional) { - if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL) + if((copy_nmb->additional = SMB_MALLOC_ARRAY( + struct res_rec, nmb->header.arcount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, nmb->header.arcount * sizeof(struct res_rec)); } @@ -618,7 +656,7 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) ******************************************************************/ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) -{ +{ struct packet_struct *pkt_copy; if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { @@ -643,20 +681,20 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) ******************************************************************/ struct packet_struct *copy_packet(struct packet_struct *packet) -{ +{ if(packet->packet_type == NMB_PACKET) return copy_nmb_packet(packet); else if (packet->packet_type == DGRAM_PACKET) return copy_dgram_packet(packet); return NULL; } - + /******************************************************************* Free up any resources associated with an nmb packet. ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) -{ +{ SAFE_FREE(nmb->answers); SAFE_FREE(nmb->nsrecs); SAFE_FREE(nmb->additional); @@ -667,7 +705,7 @@ static void free_nmb_packet(struct nmb_packet *nmb) ******************************************************************/ static void free_dgram_packet(struct dgram_packet *nmb) -{ +{ /* We have nothing to do for a dgram packet. */ } @@ -676,8 +714,8 @@ static void free_dgram_packet(struct dgram_packet *nmb) ******************************************************************/ void free_packet(struct packet_struct *packet) -{ - if (packet->locked) +{ + if (packet->locked) return; if (packet->packet_type == NMB_PACKET) free_nmb_packet(&packet->packet.nmb); @@ -692,7 +730,9 @@ void free_packet(struct packet_struct *packet) ******************************************************************/ struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type) + enum packet_type packet_type, + struct in_addr ip, + int port) { struct packet_struct *p; BOOL ok=False; @@ -703,8 +743,8 @@ struct packet_struct *parse_packet(char *buf,int length, p->next = NULL; p->prev = NULL; - p->ip = lastip; - p->port = lastport; + p->ip = ip; + p->port = port; p->locked = False; p->timestamp = time(NULL); p->packet_type = packet_type; @@ -713,7 +753,7 @@ struct packet_struct *parse_packet(char *buf,int length, case NMB_PACKET: ok = parse_nmb(buf,length,&p->packet.nmb); break; - + case DGRAM_PACKET: ok = parse_dgram(buf,length,&p->packet.dgram); break; @@ -735,27 +775,34 @@ struct packet_struct *parse_packet(char *buf,int length, struct packet_struct *read_packet(int fd,enum packet_type packet_type) { struct packet_struct *packet; + struct sockaddr_storage sa; + struct sockaddr_in *si = (struct sockaddr_in *)&sa; char buf[MAX_DGRAM_SIZE]; int length; - - length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) - return(NULL); - - packet = parse_packet(buf, length, packet_type); + + length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa); + if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) { + return NULL; + } + + packet = parse_packet(buf, + length, + packet_type, + si->sin_addr, + si->sin_port); if (!packet) return NULL; packet->fd = fd; - + num_good_receives++; - + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", length, inet_ntoa(packet->ip), packet->port ) ); - + return(packet); } - + /******************************************************************* Send a udp packet on a already open socket. ******************************************************************/ @@ -771,16 +818,17 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) putip((char *)&sock_out.sin_addr,(char *)&ip); sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", len, inet_ntoa(ip), port ) ); /* * Patch to fix asynch error notifications from Linux kernel. */ - + for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, + sizeof(sock_out)) >= 0); if (ret || errno != ECONNREFUSED) break; } @@ -797,48 +845,41 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) /******************************************************************* Build a dgram packet ready for sending. - - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. - - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] - + If buf == NULL this is a length calculation. ******************************************************************/ -static int build_dgram(char *buf,struct packet_struct *p) +static int build_dgram(char *buf, size_t len, struct packet_struct *p) { struct dgram_packet *dgram = &p->packet.dgram; unsigned char *ubuf = (unsigned char *)buf; int offset=0; /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) - ubuf[1] |= 1; - if (dgram->header.flags.first) - ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); + if (buf) { + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + } offset = 14; if (dgram->header.msg_type == 0x10 || dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { + dgram->header.msg_type == 0x12) { offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); } - memcpy(ubuf+offset,dgram->data,dgram->datasize); + if (buf) { + memcpy(ubuf+offset,dgram->data,dgram->datasize); + } offset += dgram->datasize; /* automatically set the dgm_length @@ -846,9 +887,11 @@ static int build_dgram(char *buf,struct packet_struct *p) * include the fourteen-byte header. crh */ dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); + if (buf) { + RSSVAL(ubuf,10,dgram->header.dgm_length); + } - return(offset); + return offset; } /******************************************************************* @@ -879,59 +922,90 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) /******************************************************************* Build a nmb packet ready for sending. - - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) + If buf == NULL this is a length calculation. ******************************************************************/ -static int build_nmb(char *buf,struct packet_struct *p) +static int build_nmb(char *buf, size_t len, struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; unsigned char *ubuf = (unsigned char *)buf; int offset=0; + if (len && len < 12) { + return 0; + } + /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) - ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) - ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) - ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) - ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) - ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) - ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); - + if (buf) { + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) + ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) + ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); + } + offset += 12; if (nmb->header.qdcount) { /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); + if (len) { + /* Length check. */ + int extra = put_nmb_name(NULL,offset, + &nmb->question.question_name); + if (offset + extra > len) { + return 0; + } + } + offset += put_nmb_name((char *)ubuf,offset, + &nmb->question.question_name); + if (buf) { + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + } offset += 4; } - if (nmb->header.ancount) + if (nmb->header.ancount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->answers, + nmb->header.ancount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->answers, nmb->header.ancount); + } - if (nmb->header.nscount) + if (nmb->header.nscount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->nsrecs, + nmb->header.nscount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, nmb->header.nscount); + } /* * The spec says we must put compressed name pointers @@ -941,37 +1015,53 @@ static int build_nmb(char *buf,struct packet_struct *p) */ if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + if (len) { + /* Length check. */ + int extra = put_compressed_name_ptr(NULL,offset, + nmb->additional,12); + if (offset + extra > len) { + return 0; + } + } + offset += put_compressed_name_ptr(ubuf,offset, + nmb->additional,12); } else if (nmb->header.arcount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->additional, + nmb->header.arcount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); + nmb->header.arcount); } - return(offset); + return offset; } /******************************************************************* Linearise a packet. ******************************************************************/ -int build_packet(char *buf, struct packet_struct *p) +int build_packet(char *buf, size_t buflen, struct packet_struct *p) { int len = 0; switch (p->packet_type) { case NMB_PACKET: - len = build_nmb(buf,p); + len = build_nmb(buf,buflen,p); break; case DGRAM_PACKET: - len = build_dgram(buf,p); + len = build_dgram(buf,buflen,p); break; } @@ -989,7 +1079,7 @@ BOOL send_packet(struct packet_struct *p) memset(buf,'\0',sizeof(buf)); - len = build_packet(buf, p); + len = build_packet(buf, sizeof(buf), p); if (!len) return(False); @@ -1015,16 +1105,17 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ - DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); + DEBUG(0,("select returned -1, errno = %s (%d)\n", + strerror(errno), errno)); return NULL; } if (ret == 0) /* timeout */ return NULL; - if (FD_ISSET(fd,&fds)) + if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); - + return(NULL); } @@ -1057,7 +1148,8 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) The timeout is in milliseconds. ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) +struct packet_struct *receive_dgram_packet(int fd, int t, + const char *mailslot_name) { struct packet_struct *p; @@ -1114,8 +1206,8 @@ int matching_quad_bits(unsigned char *p1, unsigned char *p2) if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; ret++; - } - + } + return ret; } @@ -1127,7 +1219,8 @@ static unsigned char sort_ip[4]; static int name_query_comp(unsigned char *p1, unsigned char *p2) { - return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); + return matching_quad_bits(p2+2, sort_ip) - + matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** @@ -1163,7 +1256,7 @@ char *dns_to_netbios_name(const char *dns_name) int i; StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; - + /* ok. this is because of a stupid microsoft-ism. if the called host name contains a '.', microsoft clients expect you to truncate the netbios name up to and including the '.' this even applies, by @@ -1300,7 +1393,7 @@ static char *name_ptr(char *buf,int ofs) } else { return(buf+ofs); } -} +} /**************************************************************************** Extract a netbios name from a buf (into a unix string) return name type. @@ -1316,7 +1409,7 @@ int name_extract(char *buf,int ofs, fstring name) return(0); return(name_interpret(p,name)); } - + /**************************************************************************** Return the total storage length of a mangled name. ****************************************************************************/ -- cgit From 3dbb3d4c269ecf28f25d857aa8a4e5c1109ee5e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Oct 2007 01:11:33 +0000 Subject: r25510: Now we're returning the port instead of using a global, remember to use ntohs. Hopefully will fix the build farm. Jeremy. (This used to be commit 5174acccb589edbfbe4ba633f4178f7200d7d6c4) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 74deb91a73..61e24eb6f9 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -789,7 +789,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) length, packet_type, si->sin_addr, - si->sin_port); + ntohs(si->sin_port)); if (!packet) return NULL; -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libsmb/nmblib.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 61e24eb6f9..4d21258f99 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -152,8 +152,8 @@ void debug_nmb_packet(struct packet_struct *p) Handle "compressed" name pointers. ******************************************************************/ -static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, - BOOL *got_pointer,int *ret) +static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length, + bool *got_pointer,int *ret) { int loop_count=0; @@ -180,7 +180,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) int m,n=0; unsigned char *ubuf = (unsigned char *)inbuf; int ret = 0; - BOOL got_pointer=False; + bool got_pointer=False; int loop_count=0; int offset = ofs; @@ -367,7 +367,7 @@ char *nmb_namestr(const struct nmb_name *n) Allocate and parse some resource records. ******************************************************************/ -static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, +static bool parse_alloc_res_rec(char *inbuf,int *offset,int length, struct res_rec **recs, int count) { int i; @@ -467,7 +467,7 @@ static int put_compressed_name_ptr(unsigned char *buf, This is documented in section 4.4.1 of RFC1002. ******************************************************************/ -static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) +static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) { int offset; int flags; @@ -521,7 +521,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) or is invalid for some reason, True otherwise. ******************************************************************/ -static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) +static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { int nm_flags,offset; @@ -735,7 +735,7 @@ struct packet_struct *parse_packet(char *buf,int length, int port) { struct packet_struct *p; - BOOL ok=False; + bool ok=False; p = SMB_MALLOC_P(struct packet_struct); if (!p) @@ -807,9 +807,9 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) Send a udp packet on a already open socket. ******************************************************************/ -static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) +static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret = False; + bool ret = False; int i; struct sockaddr_in sock_out; @@ -913,7 +913,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) Compare two nmb names ******************************************************************/ -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) +bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) { return ((n1->name_type == n2->name_type) && strequal(n1->name ,n2->name ) && @@ -1072,7 +1072,7 @@ int build_packet(char *buf, size_t buflen, struct packet_struct *p) Send a packet_struct. ******************************************************************/ -BOOL send_packet(struct packet_struct *p) +bool send_packet(struct packet_struct *p) { char buf[1024]; int len=0; @@ -1169,7 +1169,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, See if a datagram has the right mailslot name. ***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) +bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; char *buf; -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libsmb/nmblib.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4d21258f99..7e152ab324 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1187,19 +1187,20 @@ bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name) } /**************************************************************************** - Return the number of bits that match between two 4 character buffers + Return the number of bits that match between two len character buffers ***************************************************************************/ -int matching_quad_bits(unsigned char *p1, unsigned char *p2) +int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len) { - int i, j, ret = 0; - for (i=0; i<4; i++) { + size_t i, j; + int ret = 0; + for (i=0; i Date: Sat, 24 Nov 2007 15:47:04 +0100 Subject: remove some statics (This used to be commit 97c9a4042d36178a728b5e0f8923091c7069366d) --- source3/libsmb/nmblib.c | 49 +++++++------------------------------------------ 1 file changed, 7 insertions(+), 42 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7e152ab324..2ff925ef36 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -347,20 +347,19 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) char *nmb_namestr(const struct nmb_name *n) { - static int i=0; - static fstring ret[4]; fstring name; - char *p = ret[i]; + char *result; pull_ascii_fstring(name, n->name); if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); + result = talloc_asprintf(talloc_tos(), "%s<%02x>", name, + n->name_type); else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s", - name,n->name_type,n->scope); + result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name, + n->name_type, n->scope); - i = (i+1)%4; - return(p); + SMB_ASSERT(result != NULL); + return result; } /******************************************************************* @@ -1239,40 +1238,6 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } -/******************************************************************* - Convert, possibly using a stupid microsoft-ism which has destroyed - the transport independence of netbios (for CIFS vendors that usually - use the Win95-type methods, not for NT to NT communication, which uses - DCE/RPC and therefore full-length unicode strings...) a dns name into - a netbios name. - - The netbios name (NOT necessarily null-terminated) is truncated to 15 - characters. - - ******************************************************************/ - -char *dns_to_netbios_name(const char *dns_name) -{ - static nstring netbios_name; - int i; - StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); - netbios_name[15] = 0; - - /* ok. this is because of a stupid microsoft-ism. if the called host - name contains a '.', microsoft clients expect you to truncate the - netbios name up to and including the '.' this even applies, by - mistake, to workgroup (domain) names, which is _really_ daft. - */ - for (i = 0; i < 15; i++) { - if (netbios_name[i] == '.') { - netbios_name[i] = 0; - break; - } - } - - return netbios_name; -} - /**************************************************************************** Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ -- cgit From a37873490f2c4e89e98780203d13e2f21a6ecebf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 17:05:26 +0100 Subject: packet_struct is used in several places as raw memory -> Fix more uninitialized variable warnings (This used to be commit 0af02db6f2f84a8ce5d614e5baec27f20b413c26) --- source3/libsmb/nmblib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 2ff925ef36..15a9a93ff2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -740,6 +740,8 @@ struct packet_struct *parse_packet(char *buf,int length, if (!p) return(NULL); + ZERO_STRUCTP(p); /* initialize for possible padding */ + p->next = NULL; p->prev = NULL; p->ip = ip; -- cgit From 8da1e033a876ab273bf4949535b31817585a953d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 Mar 2008 09:43:19 +0100 Subject: Pass specific packets to build_nmb and build_dgram To me it was not clear what parts of struct packet_struct are actually used in build_packet(). This makes it a bit more clear that only the specific parts are used. (This used to be commit eb8b6f2404e49d6a837935c5b411d78fb6ff23ef) --- source3/libsmb/nmblib.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/nmblib.c') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 15a9a93ff2..bfe5e7b97b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -849,9 +849,8 @@ static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port) If buf == NULL this is a length calculation. ******************************************************************/ -static int build_dgram(char *buf, size_t len, struct packet_struct *p) +static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram) { - struct dgram_packet *dgram = &p->packet.dgram; unsigned char *ubuf = (unsigned char *)buf; int offset=0; @@ -926,9 +925,8 @@ bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) If buf == NULL this is a length calculation. ******************************************************************/ -static int build_nmb(char *buf, size_t len, struct packet_struct *p) +static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb) { - struct nmb_packet *nmb = &p->packet.nmb; unsigned char *ubuf = (unsigned char *)buf; int offset=0; @@ -1058,11 +1056,11 @@ int build_packet(char *buf, size_t buflen, struct packet_struct *p) switch (p->packet_type) { case NMB_PACKET: - len = build_nmb(buf,buflen,p); + len = build_nmb(buf,buflen,&p->packet.nmb); break; case DGRAM_PACKET: - len = build_dgram(buf,buflen,p); + len = build_dgram(buf,buflen,&p->packet.dgram); break; } -- cgit