LCOV - code coverage report
Current view: top level - source3/libsmb - nmblib.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 510 735 69.4 %
Date: 2024-05-31 13:13:24 Functions: 38 41 92.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    NBT netbios library routines
       4             :    Copyright (C) Andrew Tridgell 1994-1998
       5             :    Copyright (C) Jeremy Allison 2007
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : 
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libsmb/nmblib.h"
      24             : #include "lib/util/string_wrappers.h"
      25             : 
      26         909 : const char *global_nmbd_socket_dir(void)
      27             : {
      28         909 :         return lp_parm_const_string(-1, "nmbd", "socket dir",
      29             :                                     get_dyn_NMBDSOCKETDIR());
      30             : }
      31             : 
      32             : static const struct opcode_names {
      33             :         const char *nmb_opcode_name;
      34             :         int opcode;
      35             : } nmb_header_opcode_names[] = {
      36             :         {"Query",           0 },
      37             :         {"Registration",      5 },
      38             :         {"Release",           6 },
      39             :         {"WACK",              7 },
      40             :         {"Refresh",           8 },
      41             :         {"Refresh(altcode)",  9 },
      42             :         {"Multi-homed Registration", 15 },
      43             :         {0, -1 }
      44             : };
      45             : 
      46             : /****************************************************************************
      47             :  Lookup a nmb opcode name.
      48             : ****************************************************************************/
      49             : 
      50           0 : static const char *lookup_opcode_name( int opcode )
      51             : {
      52           0 :         const struct opcode_names *op_namep;
      53           0 :         int i;
      54             : 
      55           0 :         for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
      56           0 :                 op_namep = &nmb_header_opcode_names[i];
      57           0 :                 if(opcode == op_namep->opcode)
      58           0 :                         return op_namep->nmb_opcode_name;
      59             :         }
      60           0 :         return "<unknown opcode>";
      61             : }
      62             : 
      63             : /****************************************************************************
      64             :  Print out a res_rec structure.
      65             : ****************************************************************************/
      66             : 
      67        4908 : static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
      68             : {
      69           0 :         int i, j;
      70             : 
      71        4908 :         DEBUGADD( 4, ( "    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
      72             :                 hdr,
      73             :                 nmb_namestr(&res->rr_name),
      74             :                 res->rr_type,
      75             :                 res->rr_class,
      76             :                 res->ttl ) );
      77             : 
      78        4908 :         if (res->rdlength == 0) {
      79           0 :                 return;
      80             :         }
      81             : 
      82       11235 :         for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
      83        6327 :                 DEBUGADD(4, ("    %s %3x char ", hdr, i));
      84             : 
      85       58364 :                 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
      86       56945 :                         unsigned char x = res->rdata[i+j];
      87       56945 :                         if (x < 32 || x > 127)
      88       30889 :                                 x = '.';
      89             : 
      90       56945 :                         if (i+j >= res->rdlength)
      91        4908 :                                 break;
      92       52037 :                         DEBUGADD(4, ("%c", x));
      93             :                 }
      94             : 
      95        6327 :                 DEBUGADD(4, ("   hex "));
      96             : 
      97       58364 :                 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
      98       56945 :                         if (i+j >= res->rdlength)
      99        4908 :                                 break;
     100       52037 :                         DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
     101             :                 }
     102             : 
     103        6327 :                 DEBUGADD(4, ("\n"));
     104             :         }
     105             : }
     106             : 
     107             : /****************************************************************************
     108             :  Process a nmb packet.
     109             : ****************************************************************************/
     110             : 
     111        9490 : void debug_nmb_packet(struct packet_struct *p)
     112             : {
     113        9490 :         struct nmb_packet *nmb = &p->packet.nmb;
     114             : 
     115        9490 :         if( DEBUGLVL( 4 ) ) {
     116           0 :                 dbgtext( "nmb packet from %s(%d) header: id=%d "
     117             :                                 "opcode=%s(%d) response=%s\n",
     118             :                         inet_ntoa(p->ip), p->port,
     119             :                         nmb->header.name_trn_id,
     120             :                         lookup_opcode_name(nmb->header.opcode),
     121             :                         nmb->header.opcode,
     122           0 :                         BOOLSTR(nmb->header.response) );
     123           0 :                 dbgtext( "    header: flags: bcast=%s rec_avail=%s "
     124             :                                 "rec_des=%s trunc=%s auth=%s\n",
     125           0 :                         BOOLSTR(nmb->header.nm_flags.bcast),
     126           0 :                         BOOLSTR(nmb->header.nm_flags.recursion_available),
     127           0 :                         BOOLSTR(nmb->header.nm_flags.recursion_desired),
     128           0 :                         BOOLSTR(nmb->header.nm_flags.trunc),
     129           0 :                         BOOLSTR(nmb->header.nm_flags.authoritative) );
     130           0 :                 dbgtext( "    header: rcode=%d qdcount=%d ancount=%d "
     131             :                                 "nscount=%d arcount=%d\n",
     132             :                         nmb->header.rcode,
     133             :                         nmb->header.qdcount,
     134             :                         nmb->header.ancount,
     135             :                         nmb->header.nscount,
     136             :                         nmb->header.arcount );
     137             :         }
     138             : 
     139        9490 :         if (nmb->header.qdcount) {
     140        8099 :                 DEBUGADD( 4, ( "    question: q_name=%s q_type=%d q_class=%d\n",
     141             :                         nmb_namestr(&nmb->question.question_name),
     142             :                         nmb->question.question_type,
     143             :                         nmb->question.question_class) );
     144             :         }
     145             : 
     146        9490 :         if (nmb->answers && nmb->header.ancount) {
     147        1391 :                 debug_nmb_res_rec(nmb->answers,"answers");
     148             :         }
     149        9490 :         if (nmb->nsrecs && nmb->header.nscount) {
     150           0 :                 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
     151             :         }
     152        9490 :         if (nmb->additional && nmb->header.arcount) {
     153        3517 :                 debug_nmb_res_rec(nmb->additional,"additional");
     154             :         }
     155        9490 : }
     156             : 
     157             : /*******************************************************************
     158             :  Handle "compressed" name pointers.
     159             : ******************************************************************/
     160             : 
     161       17910 : static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
     162             :                              bool *got_pointer,int *ret)
     163             : {
     164       17910 :         int loop_count=0;
     165             : 
     166       22172 :         while ((ubuf[*offset] & 0xC0) == 0xC0) {
     167        4262 :                 if (!*got_pointer)
     168        4262 :                         (*ret) += 2;
     169        4262 :                 (*got_pointer)=True;
     170        4262 :                 if (*offset > length - 2) {
     171           0 :                         return False;
     172             :                 }
     173        4262 :                 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
     174        4262 :                 if (loop_count++ == 10 ||
     175        4262 :                                 (*offset) < 0 || (*offset)>(length-2)) {
     176           0 :                         return False;
     177             :                 }
     178             :         }
     179       17910 :         return True;
     180             : }
     181             : 
     182             : /*******************************************************************
     183             :  Parse a nmb name from "compressed" format to something readable
     184             :  return the space taken by the name, or 0 if the name is invalid
     185             : ******************************************************************/
     186             : 
     187       17910 : static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
     188             : {
     189       17910 :         size_t m,n=0;
     190       17910 :         unsigned char *ubuf = (unsigned char *)inbuf;
     191       17910 :         int ret = 0;
     192       17910 :         bool got_pointer=False;
     193       17910 :         size_t loop_count=0;
     194       17910 :         int offset = ofs;
     195             : 
     196       17910 :         if (length - offset < 2)
     197           0 :                 return(0);
     198             : 
     199             :         /* handle initial name pointers */
     200       17910 :         if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
     201           0 :                 return(0);
     202             : 
     203       17910 :         m = ubuf[offset];
     204             : 
     205             :         /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
     206       17910 :         if (m != 32) {
     207           0 :                 return 0;
     208             :         }
     209             :         /* Cannot go past length. */
     210       17910 :         if (offset+m+2 > length) {
     211           0 :                 return 0;
     212             :         }
     213             : 
     214       17910 :         memset((char *)name,'\0',sizeof(*name));
     215             : 
     216             :         /* the "compressed" part */
     217       17910 :         if (!got_pointer)
     218       13648 :                 ret += m + 2;
     219       17910 :         offset++;
     220      304470 :         while (m > 0) {
     221           0 :                 unsigned char c1,c2;
     222      286560 :                 c1 = ubuf[offset++]-'A';
     223      286560 :                 c2 = ubuf[offset++]-'A';
     224      286560 :                 if ((c1 & 0xF0) || (c2 & 0xF0)) {
     225           0 :                         return(0);
     226             :                 }
     227      286560 :                 if (n >= sizeof(name->name)) {
     228           0 :                         return 0;
     229             :                 }
     230      286560 :                 name->name[n++] = (c1<<4) | c2;
     231      286560 :                 m -= 2;
     232             :         }
     233             :         /*
     234             :          * RFC1002: For a valid NetBIOS name, exiting from the above,
     235             :          * n *must* be MAX_NETBIOSNAME_LEN (16).
     236             :          */
     237       17910 :         if (n != MAX_NETBIOSNAME_LEN) {
     238           0 :                 return 0;
     239             :         }
     240             : 
     241             :         /* parse out the name type, its always
     242             :          * in the 16th byte of the name */
     243       17910 :         name->name_type = ((unsigned char)name->name[15]) & 0xff;
     244             : 
     245             :         /* remove trailing spaces */
     246       17910 :         name->name[15] = 0;
     247       17910 :         n = 14;
     248       98696 :         while (n && name->name[n]==' ')
     249       80786 :                 name->name[n--] = 0;
     250             : 
     251             :         /* now the domain parts (if any) */
     252       17910 :         n = 0;
     253       17910 :         while (ubuf[offset]) {
     254             :                 /* we can have pointers within the domain part as well */
     255           0 :                 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
     256           0 :                         return(0);
     257             : 
     258           0 :                 m = ubuf[offset];
     259             :                 /*
     260             :                  * Don't allow null domain parts.
     261             :                  */
     262           0 :                 if (!m)
     263           0 :                         return(0);
     264           0 :                 if (!got_pointer)
     265           0 :                         ret += m+1;
     266           0 :                 if (n)
     267           0 :                         name->scope[n++] = '.';
     268           0 :                 if (m+2+offset>length || n+m+1>sizeof(name->scope))
     269           0 :                         return(0);
     270           0 :                 offset++;
     271           0 :                 while (m--)
     272           0 :                         name->scope[n++] = (char)ubuf[offset++];
     273             : 
     274             :                 /*
     275             :                  * Watch for malicious loops.
     276             :                  */
     277           0 :                 if (loop_count++ == 10)
     278           0 :                         return 0;
     279             :         }
     280       17910 :         name->scope[n++] = 0;
     281             : 
     282       17910 :         return(ret);
     283             : }
     284             : 
     285             : /****************************************************************************
     286             :  Put a netbios name, padding(s) and a name type into a 16 character buffer.
     287             :  name is already in DOS charset.
     288             :  [15 bytes name + padding][1 byte name type].
     289             : ****************************************************************************/
     290             : 
     291       10054 : void put_name(char *dest, const char *name, int pad, unsigned int name_type)
     292             : {
     293       10054 :         size_t len = strlen(name);
     294             : 
     295       10054 :         memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
     296             :                         len : MAX_NETBIOSNAME_LEN - 1);
     297       10054 :         if (len < MAX_NETBIOSNAME_LEN - 1) {
     298        8808 :                 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
     299             :         }
     300       10054 :         dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
     301       10054 : }
     302             : 
     303             : /*******************************************************************
     304             :  Put a compressed nmb name into a buffer. Return the length of the
     305             :  compressed name.
     306             : 
     307             :  Compressed names are really weird. The "compression" doubles the
     308             :  size. The idea is that it also means that compressed names conform
     309             :  to the domain name system. See RFC1002.
     310             : 
     311             :  If buf == NULL this is a length calculation.
     312             : ******************************************************************/
     313             : 
     314        7930 : static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
     315             : {
     316           0 :         int ret,m;
     317           0 :         nstring buf1;
     318           0 :         char *p;
     319             : 
     320        7930 :         if (strcmp(name->name,"*") == 0) {
     321             :                 /* special case for wildcard name */
     322         108 :                 put_name(buf1, "*", '\0', name->name_type);
     323             :         } else {
     324        7822 :                 put_name(buf1, name->name, ' ', name->name_type);
     325             :         }
     326             : 
     327        7930 :         if (buf) {
     328        4684 :                 if (offset >= buflen) {
     329           0 :                         return 0;
     330             :                 }
     331        4684 :                 buf[offset] = 0x20;
     332             :         }
     333             : 
     334        7930 :         ret = 34;
     335             : 
     336      134810 :         for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
     337      126880 :                 if (buf) {
     338       74944 :                         if (offset+2+2*m >= buflen) {
     339           0 :                                 return 0;
     340             :                         }
     341       74944 :                         buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
     342       74944 :                         buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
     343             :                 }
     344             :         }
     345        7930 :         offset += 33;
     346             : 
     347        7930 :         if (buf) {
     348        4684 :                 if (offset >= buflen) {
     349           0 :                         return 0;
     350             :                 }
     351        4684 :                 buf[offset] = 0;
     352             :         }
     353             : 
     354        7930 :         if (name->scope[0]) {
     355             :                 /* XXXX this scope handling needs testing */
     356           0 :                 size_t scopenamelen = strlen(name->scope) + 1;
     357           0 :                 ret += scopenamelen;
     358           0 :                 if (buf) {
     359           0 :                         if (offset+1+scopenamelen >= buflen) {
     360           0 :                                 return 0;
     361             :                         }
     362           0 :                         strlcpy(&buf[offset+1],name->scope,
     363           0 :                                         buflen - (offset+1));
     364             : 
     365           0 :                         p = &buf[offset+1];
     366           0 :                         while ((p = strchr_m(p,'.'))) {
     367           0 :                                 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
     368           0 :                                 offset += (buf[offset] + 1);
     369           0 :                                 if (offset+1 >= buflen) {
     370           0 :                                         return 0;
     371             :                                 }
     372           0 :                                 p = &buf[offset+1];
     373             :                         }
     374           0 :                         buf[offset] = strlen(&buf[offset+1]);
     375             :                 }
     376             :         }
     377             : 
     378        7930 :         return ret;
     379             : }
     380             : 
     381             : /*******************************************************************
     382             :  Useful for debugging messages.
     383             : ******************************************************************/
     384             : 
     385        2418 : char *nmb_namestr(const struct nmb_name *n)
     386             : {
     387           0 :         fstring name;
     388           0 :         char *result;
     389             : 
     390        2418 :         pull_ascii_fstring(name, n->name);
     391        2418 :         if (!n->scope[0])
     392        2418 :                 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
     393        2418 :                                          n->name_type);
     394             :         else
     395           0 :                 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
     396           0 :                                          n->name_type, n->scope);
     397             : 
     398        2418 :         SMB_ASSERT(result != NULL);
     399        2418 :         return result;
     400             : }
     401             : 
     402             : /*******************************************************************
     403             :  Allocate and parse some resource records.
     404             : ******************************************************************/
     405             : 
     406        4743 : static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
     407             :                                 struct res_rec **recs, int count)
     408             : {
     409           0 :         int i;
     410             : 
     411        4743 :         *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
     412        4743 :         if (!*recs)
     413           0 :                 return(False);
     414             : 
     415        4743 :         memset((char *)*recs,'\0',sizeof(**recs)*count);
     416             : 
     417        9486 :         for (i=0;i<count;i++) {
     418        4743 :                 int l = parse_nmb_name(inbuf,*offset,length,
     419        4743 :                                 &(*recs)[i].rr_name);
     420        4743 :                 (*offset) += l;
     421        4743 :                 if (!l || (*offset)+10 > length) {
     422           0 :                         SAFE_FREE(*recs);
     423           0 :                         return(False);
     424             :                 }
     425        4743 :                 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
     426        4743 :                 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
     427        4743 :                 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
     428        4743 :                 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
     429        4743 :                 (*offset) += 10;
     430        4743 :                 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
     431        4743 :                                 (*offset)+(*recs)[i].rdlength > length) {
     432           0 :                         SAFE_FREE(*recs);
     433           0 :                         return(False);
     434             :                 }
     435        4743 :                 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
     436        4743 :                 (*offset) += (*recs)[i].rdlength;
     437             :         }
     438        4743 :         return(True);
     439             : }
     440             : 
     441             : /*******************************************************************
     442             :  Put a resource record into a packet.
     443             :  If buf == NULL this is a length calculation.
     444             : ******************************************************************/
     445             : 
     446        1794 : static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
     447             : {
     448        1794 :         int ret=0;
     449           0 :         int i;
     450             : 
     451        3588 :         for (i=0;i<count;i++) {
     452        1794 :                 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
     453        1794 :                 offset += l;
     454        1794 :                 ret += l;
     455        1794 :                 if (buf) {
     456         897 :                         RSSVAL(buf,offset,recs[i].rr_type);
     457         897 :                         RSSVAL(buf,offset+2,recs[i].rr_class);
     458         897 :                         RSIVAL(buf,offset+4,(unsigned int)recs[i].ttl);
     459         897 :                         RSSVAL(buf,offset+8,recs[i].rdlength);
     460         897 :                         memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
     461             :                 }
     462        1794 :                 offset += 10+recs[i].rdlength;
     463        1794 :                 ret += 10+recs[i].rdlength;
     464             :         }
     465             : 
     466        1794 :         return ret;
     467             : }
     468             : 
     469             : /*******************************************************************
     470             :  Put a compressed name pointer record into a packet.
     471             :  If buf == NULL this is a length calculation.
     472             : ******************************************************************/
     473             : 
     474        2518 : static int put_compressed_name_ptr(unsigned char *buf,
     475             :                                 int offset,
     476             :                                 struct res_rec *rec,
     477             :                                 int ptr_offset)
     478             : {
     479        2518 :         int ret=offset;
     480        2518 :         if (buf) {
     481        1259 :                 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
     482        1259 :                 buf[offset+1] = (ptr_offset & 0xFF);
     483             :         }
     484        2518 :         offset += 2;
     485        2518 :         if (buf) {
     486        1259 :                 RSSVAL(buf,offset,rec->rr_type);
     487        1259 :                 RSSVAL(buf,offset+2,rec->rr_class);
     488        1259 :                 RSIVAL(buf,offset+4,rec->ttl);
     489        1259 :                 RSSVAL(buf,offset+8,rec->rdlength);
     490        1259 :                 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
     491             :         }
     492        2518 :         offset += 10+rec->rdlength;
     493        2518 :         ret = (offset - ret);
     494             : 
     495        2518 :         return ret;
     496             : }
     497             : 
     498             : /*******************************************************************
     499             :  Parse a dgram packet. Return False if the packet can't be parsed
     500             :  or is invalid for some reason, True otherwise.
     501             : 
     502             :  This is documented in section 4.4.1 of RFC1002.
     503             : ******************************************************************/
     504             : 
     505        2107 : static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
     506             : {
     507           0 :         size_t offset;
     508           0 :         int flags;
     509             : 
     510        2107 :         memset((char *)dgram,'\0',sizeof(*dgram));
     511             : 
     512        2107 :         if (length < 14)
     513           0 :                 return(False);
     514             : 
     515        2107 :         dgram->header.msg_type = CVAL(inbuf,0);
     516        2107 :         flags = CVAL(inbuf,1);
     517        2107 :         dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
     518        2107 :         if (flags & 1)
     519           0 :                 dgram->header.flags.more = True;
     520        2107 :         if (flags & 2)
     521        2107 :                 dgram->header.flags.first = True;
     522        2107 :         dgram->header.dgm_id = RSVAL(inbuf,2);
     523        2107 :         putip((char *)&dgram->header.source_ip,inbuf+4);
     524        2107 :         dgram->header.source_port = RSVAL(inbuf,8);
     525        2107 :         dgram->header.dgm_length = RSVAL(inbuf,10);
     526        2107 :         dgram->header.packet_offset = RSVAL(inbuf,12);
     527             : 
     528        2107 :         offset = 14;
     529             : 
     530        2107 :         if (dgram->header.msg_type == 0x10 ||
     531        2064 :                         dgram->header.msg_type == 0x11 ||
     532           0 :                         dgram->header.msg_type == 0x12) {
     533        2107 :                 offset += parse_nmb_name(inbuf,offset,length,
     534             :                                 &dgram->source_name);
     535        2107 :                 offset += parse_nmb_name(inbuf,offset,length,
     536             :                                 &dgram->dest_name);
     537             :         }
     538             : 
     539        2107 :         if (offset >= length || (length-offset > sizeof(dgram->data)))
     540           0 :                 return(False);
     541             : 
     542        2107 :         dgram->datasize = length-offset;
     543        2107 :         memcpy(dgram->data,inbuf+offset,dgram->datasize);
     544             : 
     545             :         /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
     546             :            zero. This should be true anyway, just enforce it for
     547             :            paranioa sake. JRA. */
     548        2107 :         SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
     549        2107 :         memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
     550             : 
     551        2107 :         return(True);
     552             : }
     553             : 
     554             : /*******************************************************************
     555             :  Parse a nmb packet. Return False if the packet can't be parsed
     556             :  or is invalid for some reason, True otherwise.
     557             : ******************************************************************/
     558             : 
     559        9438 : static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
     560             : {
     561           0 :         int nm_flags,offset;
     562             : 
     563        9438 :         memset((char *)nmb,'\0',sizeof(*nmb));
     564             : 
     565        9438 :         if (length < 12)
     566           0 :                 return(False);
     567             : 
     568             :         /* parse the header */
     569        9438 :         nmb->header.name_trn_id = RSVAL(inbuf,0);
     570             : 
     571        9438 :         DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
     572             : 
     573        9438 :         nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
     574        9438 :         nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
     575        9438 :         nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
     576        9438 :         nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
     577        9438 :         nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
     578        9438 :         nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
     579        9438 :         nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
     580        9438 :         nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
     581        9438 :         nmb->header.rcode = CVAL(inbuf,3) & 0xF;
     582        9438 :         nmb->header.qdcount = RSVAL(inbuf,4);
     583        9438 :         nmb->header.ancount = RSVAL(inbuf,6);
     584        9438 :         nmb->header.nscount = RSVAL(inbuf,8);
     585        9438 :         nmb->header.arcount = RSVAL(inbuf,10);
     586             : 
     587        9438 :         if (nmb->header.qdcount) {
     588        8953 :                 offset = parse_nmb_name(inbuf,12,length,
     589             :                                 &nmb->question.question_name);
     590        8953 :                 if (!offset)
     591           0 :                         return(False);
     592             : 
     593        8953 :                 if (length - (12+offset) < 4)
     594           0 :                         return(False);
     595        8953 :                 nmb->question.question_type = RSVAL(inbuf,12+offset);
     596        8953 :                 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
     597             : 
     598        8953 :                 offset += 12+4;
     599             :         } else {
     600         485 :                 offset = 12;
     601             :         }
     602             : 
     603             :         /* and any resource records */
     604        9438 :         if (nmb->header.ancount &&
     605         485 :                         !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
     606             :                                         nmb->header.ancount))
     607           0 :                 return(False);
     608             : 
     609        9438 :         if (nmb->header.nscount &&
     610           0 :                         !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
     611             :                                         nmb->header.nscount))
     612           0 :                 return(False);
     613             : 
     614        9438 :         if (nmb->header.arcount &&
     615        4258 :                         !parse_alloc_res_rec(inbuf,&offset,length,
     616             :                                 &nmb->additional, nmb->header.arcount))
     617           0 :                 return(False);
     618             : 
     619        9438 :         return(True);
     620             : }
     621             : 
     622             : /*******************************************************************
     623             :  'Copy constructor' for an nmb packet.
     624             : ******************************************************************/
     625             : 
     626           5 : static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
     627             : {
     628           0 :         struct nmb_packet *nmb;
     629           0 :         struct nmb_packet *copy_nmb;
     630           0 :         struct packet_struct *pkt_copy;
     631             : 
     632           5 :         if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
     633           0 :                 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
     634           0 :                 return NULL;
     635             :         }
     636             : 
     637             :         /* Structure copy of entire thing. */
     638             : 
     639           5 :         *pkt_copy = *packet;
     640             : 
     641             :         /* Ensure this copy is not locked. */
     642           5 :         pkt_copy->locked = False;
     643           5 :         pkt_copy->recv_fd = -1;
     644           5 :         pkt_copy->send_fd = -1;
     645             : 
     646             :         /* Ensure this copy has no resource records. */
     647           5 :         nmb = &packet->packet.nmb;
     648           5 :         copy_nmb = &pkt_copy->packet.nmb;
     649             : 
     650           5 :         copy_nmb->answers = NULL;
     651           5 :         copy_nmb->nsrecs = NULL;
     652           5 :         copy_nmb->additional = NULL;
     653             : 
     654             :         /* Now copy any resource records. */
     655             : 
     656           5 :         if (nmb->answers) {
     657           5 :                 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
     658             :                                 struct res_rec,nmb->header.ancount)) == NULL)
     659           0 :                         goto free_and_exit;
     660           5 :                 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
     661           5 :                                 nmb->header.ancount * sizeof(struct res_rec));
     662             :         }
     663           5 :         if (nmb->nsrecs) {
     664           0 :                 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
     665             :                                 struct res_rec, nmb->header.nscount)) == NULL)
     666           0 :                         goto free_and_exit;
     667           0 :                 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
     668           0 :                                 nmb->header.nscount * sizeof(struct res_rec));
     669             :         }
     670           5 :         if (nmb->additional) {
     671           0 :                 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
     672             :                                 struct res_rec, nmb->header.arcount)) == NULL)
     673           0 :                         goto free_and_exit;
     674           0 :                 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
     675           0 :                                 nmb->header.arcount * sizeof(struct res_rec));
     676             :         }
     677             : 
     678           5 :         return pkt_copy;
     679             : 
     680           0 :  free_and_exit:
     681             : 
     682           0 :         SAFE_FREE(copy_nmb->answers);
     683           0 :         SAFE_FREE(copy_nmb->nsrecs);
     684           0 :         SAFE_FREE(copy_nmb->additional);
     685           0 :         SAFE_FREE(pkt_copy);
     686             : 
     687           0 :         DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
     688           0 :         return NULL;
     689             : }
     690             : 
     691             : /*******************************************************************
     692             :   'Copy constructor' for a dgram packet.
     693             : ******************************************************************/
     694             : 
     695           2 : static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
     696             : {
     697           0 :         struct packet_struct *pkt_copy;
     698             : 
     699           2 :         if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
     700           0 :                 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
     701           0 :                 return NULL;
     702             :         }
     703             : 
     704             :         /* Structure copy of entire thing. */
     705             : 
     706           2 :         *pkt_copy = *packet;
     707             : 
     708             :         /* Ensure this copy is not locked. */
     709           2 :         pkt_copy->locked = False;
     710           2 :         pkt_copy->recv_fd = -1;
     711           2 :         pkt_copy->send_fd = -1;
     712             : 
     713             :         /* There are no additional pointers in a dgram packet,
     714             :                 we are finished. */
     715           2 :         return pkt_copy;
     716             : }
     717             : 
     718             : /*******************************************************************
     719             :  'Copy constructor' for a generic packet.
     720             : ******************************************************************/
     721             : 
     722           7 : struct packet_struct *copy_packet(struct packet_struct *packet)
     723             : {
     724           7 :         if(packet->packet_type == NMB_PACKET)
     725           5 :                 return copy_nmb_packet(packet);
     726           2 :         else if (packet->packet_type == DGRAM_PACKET)
     727           2 :                 return copy_dgram_packet(packet);
     728           0 :         return NULL;
     729             : }
     730             : 
     731             : /*******************************************************************
     732             :  Free up any resources associated with an nmb packet.
     733             : ******************************************************************/
     734             : 
     735        9845 : static void free_nmb_packet(struct nmb_packet *nmb)
     736             : {
     737        9845 :         SAFE_FREE(nmb->answers);
     738        9845 :         SAFE_FREE(nmb->nsrecs);
     739        9845 :         SAFE_FREE(nmb->additional);
     740        9845 : }
     741             : 
     742             : /*******************************************************************
     743             :  Free up any resources associated with a dgram packet.
     744             : ******************************************************************/
     745             : 
     746        2109 : static void free_dgram_packet(struct dgram_packet *nmb)
     747             : {
     748             :         /* We have nothing to do for a dgram packet. */
     749        2109 : }
     750             : 
     751             : /*******************************************************************
     752             :  Free up any resources associated with a packet.
     753             : ******************************************************************/
     754             : 
     755       11954 : void free_packet(struct packet_struct *packet)
     756             : {
     757       11954 :         if (packet->locked)
     758           0 :                 return;
     759       11954 :         if (packet->packet_type == NMB_PACKET)
     760        9845 :                 free_nmb_packet(&packet->packet.nmb);
     761        2109 :         else if (packet->packet_type == DGRAM_PACKET)
     762        2109 :                 free_dgram_packet(&packet->packet.dgram);
     763       11954 :         ZERO_STRUCTPN(packet);
     764       11954 :         SAFE_FREE(packet);
     765             : }
     766             : 
     767         447 : int packet_trn_id(struct packet_struct *p)
     768             : {
     769           0 :         int result;
     770         447 :         switch (p->packet_type) {
     771         447 :         case NMB_PACKET:
     772         447 :                 result = p->packet.nmb.header.name_trn_id;
     773         447 :                 break;
     774           0 :         case DGRAM_PACKET:
     775           0 :                 result = p->packet.dgram.header.dgm_id;
     776           0 :                 break;
     777           0 :         default:
     778           0 :                 result = -1;
     779             :         }
     780         447 :         return result;
     781             : }
     782             : 
     783             : /*******************************************************************
     784             :  Parse a packet buffer into a packet structure.
     785             : ******************************************************************/
     786             : 
     787       11545 : struct packet_struct *parse_packet(char *buf,int length,
     788             :                                    enum packet_type packet_type,
     789             :                                    struct in_addr ip,
     790             :                                    int port)
     791             : {
     792           0 :         struct packet_struct *p;
     793       11545 :         bool ok=False;
     794             : 
     795       11545 :         p = SMB_MALLOC_P(struct packet_struct);
     796       11545 :         if (!p)
     797           0 :                 return(NULL);
     798             : 
     799       11545 :         ZERO_STRUCTP(p);        /* initialize for possible padding */
     800             : 
     801       11545 :         p->next = NULL;
     802       11545 :         p->prev = NULL;
     803       11545 :         p->ip = ip;
     804       11545 :         p->port = port;
     805       11545 :         p->locked = False;
     806       11545 :         p->timestamp = time(NULL);
     807       11545 :         p->packet_type = packet_type;
     808             : 
     809       11545 :         switch (packet_type) {
     810        9438 :         case NMB_PACKET:
     811        9438 :                 ok = parse_nmb(buf,length,&p->packet.nmb);
     812        9438 :                 break;
     813             : 
     814        2107 :         case DGRAM_PACKET:
     815        2107 :                 ok = parse_dgram(buf,length,&p->packet.dgram);
     816        2107 :                 break;
     817             :         }
     818             : 
     819       11545 :         if (!ok) {
     820           0 :                 free_packet(p);
     821           0 :                 return NULL;
     822             :         }
     823             : 
     824       11545 :         return p;
     825             : }
     826             : 
     827         450 : static struct packet_struct *copy_packet_talloc(
     828             :         TALLOC_CTX *mem_ctx, const struct packet_struct *src)
     829             : {
     830           0 :         struct packet_struct *pkt;
     831             : 
     832         450 :         pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
     833         450 :         if (pkt == NULL) {
     834           0 :                 return NULL;
     835             :         }
     836         450 :         pkt->locked = false;
     837         450 :         pkt->recv_fd = -1;
     838         450 :         pkt->send_fd = -1;
     839             : 
     840         450 :         if (src->packet_type == NMB_PACKET) {
     841         447 :                 const struct nmb_packet *nsrc = &src->packet.nmb;
     842         447 :                 struct nmb_packet *ndst = &pkt->packet.nmb;
     843             : 
     844         447 :                 if (nsrc->answers != NULL) {
     845         447 :                         ndst->answers = talloc_memdup(
     846             :                                 pkt, nsrc->answers,
     847             :                                 sizeof(struct res_rec) * nsrc->header.ancount);
     848         447 :                         if (ndst->answers == NULL) {
     849           0 :                                 goto fail;
     850             :                         }
     851             :                 }
     852         447 :                 if (nsrc->nsrecs != NULL) {
     853           0 :                         ndst->nsrecs = talloc_memdup(
     854             :                                 pkt, nsrc->nsrecs,
     855             :                                 sizeof(struct res_rec) * nsrc->header.nscount);
     856           0 :                         if (ndst->nsrecs == NULL) {
     857           0 :                                 goto fail;
     858             :                         }
     859             :                 }
     860         447 :                 if (nsrc->additional != NULL) {
     861           0 :                         ndst->additional = talloc_memdup(
     862             :                                 pkt, nsrc->additional,
     863             :                                 sizeof(struct res_rec) * nsrc->header.arcount);
     864           0 :                         if (ndst->additional == NULL) {
     865           0 :                                 goto fail;
     866             :                         }
     867             :                 }
     868             :         }
     869             : 
     870         450 :         return pkt;
     871             : 
     872             :         /*
     873             :          * DGRAM packets have no substructures
     874             :          */
     875             : 
     876           0 : fail:
     877           0 :         TALLOC_FREE(pkt);
     878           0 :         return NULL;
     879             : }
     880             : 
     881         450 : struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
     882             :                                           char *buf,int length,
     883             :                                           enum packet_type packet_type,
     884             :                                           struct in_addr ip,
     885             :                                           int port)
     886             : {
     887           0 :         struct packet_struct *pkt, *result;
     888             : 
     889         450 :         pkt = parse_packet(buf, length, packet_type, ip, port);
     890         450 :         if (pkt == NULL) {
     891           0 :                 return NULL;
     892             :         }
     893         450 :         result = copy_packet_talloc(mem_ctx, pkt);
     894         450 :         free_packet(pkt);
     895         450 :         return result;
     896             : }
     897             : 
     898             : /*******************************************************************
     899             :  Send a udp packet on a already open socket.
     900             : ******************************************************************/
     901             : 
     902        3059 : static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
     903             : {
     904        3059 :         bool ret = False;
     905           0 :         int i;
     906           0 :         struct sockaddr_in sock_out;
     907             : 
     908             :         /* set the address and port */
     909        3059 :         memset((char *)&sock_out,'\0',sizeof(sock_out));
     910        3059 :         putip((char *)&sock_out.sin_addr,(char *)&ip);
     911        3059 :         sock_out.sin_port = htons( port );
     912        3059 :         sock_out.sin_family = AF_INET;
     913             : 
     914        3059 :         DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
     915             :                         len, inet_ntoa(ip), port ) );
     916             : 
     917             :         /*
     918             :          * Patch to fix asynch error notifications from Linux kernel.
     919             :          */
     920             : 
     921        3078 :         for (i = 0; i < 5; i++) {
     922        3078 :                 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
     923             :                                         sizeof(sock_out)) >= 0);
     924        3078 :                 if (ret || errno != ECONNREFUSED)
     925             :                         break;
     926             :         }
     927             : 
     928        3059 :         if (!ret)
     929          88 :                 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
     930             :                         inet_ntoa(ip),port,strerror(errno)));
     931             : 
     932        3059 :         return(ret);
     933             : }
     934             : 
     935             : /*******************************************************************
     936             :  Build a dgram packet ready for sending.
     937             :  If buf == NULL this is a length calculation.
     938             : ******************************************************************/
     939             : 
     940         719 : static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
     941             : {
     942         719 :         unsigned char *ubuf = (unsigned char *)buf;
     943         719 :         int offset=0;
     944             : 
     945             :         /* put in the header */
     946         719 :         if (buf) {
     947         719 :                 ubuf[0] = dgram->header.msg_type;
     948         719 :                 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
     949         719 :                 if (dgram->header.flags.more)
     950           0 :                         ubuf[1] |= 1;
     951         719 :                 if (dgram->header.flags.first)
     952         719 :                         ubuf[1] |= 2;
     953         719 :                 RSSVAL(ubuf,2,dgram->header.dgm_id);
     954         719 :                 putip(ubuf+4,(char *)&dgram->header.source_ip);
     955         719 :                 RSSVAL(ubuf,8,dgram->header.source_port);
     956         719 :                 RSSVAL(ubuf,12,dgram->header.packet_offset);
     957             :         }
     958             : 
     959         719 :         offset = 14;
     960             : 
     961         719 :         if (dgram->header.msg_type == 0x10 ||
     962         664 :                         dgram->header.msg_type == 0x11 ||
     963           0 :                         dgram->header.msg_type == 0x12) {
     964         719 :                 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
     965         719 :                 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
     966             :         }
     967             : 
     968         719 :         if (buf) {
     969         719 :                 memcpy(ubuf+offset,dgram->data,dgram->datasize);
     970             :         }
     971         719 :         offset += dgram->datasize;
     972             : 
     973             :         /* automatically set the dgm_length
     974             :          * NOTE: RFC1002 says the dgm_length does *not*
     975             :          *       include the fourteen-byte header. crh
     976             :          */
     977         719 :         dgram->header.dgm_length = (offset - 14);
     978         719 :         if (buf) {
     979         719 :                 RSSVAL(ubuf,10,dgram->header.dgm_length);
     980             :         }
     981             : 
     982         719 :         return offset;
     983             : }
     984             : 
     985             : /*******************************************************************
     986             :  Build a nmb name
     987             : *******************************************************************/
     988             : 
     989        6943 : void make_nmb_name( struct nmb_name *n, const char *name, int type)
     990             : {
     991           0 :         fstring unix_name;
     992        6943 :         memset( (char *)n, '\0', sizeof(struct nmb_name) );
     993        6943 :         fstrcpy(unix_name, name);
     994        6943 :         (void)strupper_m(unix_name);
     995        6943 :         push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
     996        6943 :         n->name_type = (unsigned int)type & 0xFF;
     997        6943 :         push_ascii(n->scope,  lp_netbios_scope(), 64, STR_TERMINATE);
     998        6943 : }
     999             : 
    1000             : /*******************************************************************
    1001             :   Compare two nmb names
    1002             : ******************************************************************/
    1003             : 
    1004           0 : bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
    1005             : {
    1006           0 :         return ((n1->name_type == n2->name_type) &&
    1007           0 :                 strequal(n1->name ,n2->name ) &&
    1008           0 :                 strequal(n1->scope,n2->scope));
    1009             : }
    1010             : 
    1011             : /*******************************************************************
    1012             :  Build a nmb packet ready for sending.
    1013             :  If buf == NULL this is a length calculation.
    1014             : ******************************************************************/
    1015             : 
    1016        3246 : static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
    1017             : {
    1018        3246 :         unsigned char *ubuf = (unsigned char *)buf;
    1019        3246 :         int offset=0;
    1020             : 
    1021        3246 :         if (len && len < 12) {
    1022           0 :                 return 0;
    1023             :         }
    1024             : 
    1025             :         /* put in the header */
    1026        3246 :         if (buf) {
    1027        3246 :                 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
    1028        3246 :                 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
    1029        3246 :                 if (nmb->header.response)
    1030         897 :                         ubuf[offset+2] |= (1<<7);
    1031        3246 :                 if (nmb->header.nm_flags.authoritative &&
    1032         897 :                                 nmb->header.response)
    1033         897 :                         ubuf[offset+2] |= 0x4;
    1034        3246 :                 if (nmb->header.nm_flags.trunc)
    1035           0 :                         ubuf[offset+2] |= 0x2;
    1036        3246 :                 if (nmb->header.nm_flags.recursion_desired)
    1037        2998 :                         ubuf[offset+2] |= 0x1;
    1038        3246 :                 if (nmb->header.nm_flags.recursion_available &&
    1039         843 :                                 nmb->header.response)
    1040         843 :                         ubuf[offset+3] |= 0x80;
    1041        3246 :                 if (nmb->header.nm_flags.bcast)
    1042        2122 :                         ubuf[offset+3] |= 0x10;
    1043        3246 :                 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
    1044             : 
    1045        3246 :                 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
    1046        3246 :                 RSSVAL(ubuf,offset+6,nmb->header.ancount);
    1047        3246 :                 RSSVAL(ubuf,offset+8,nmb->header.nscount);
    1048        3246 :                 RSSVAL(ubuf,offset+10,nmb->header.arcount);
    1049             :         }
    1050             : 
    1051        3246 :         offset += 12;
    1052        3246 :         if (nmb->header.qdcount) {
    1053             :                 /* XXXX this doesn't handle a qdcount of > 1 */
    1054        2349 :                 if (len) {
    1055             :                         /* Length check. */
    1056        2349 :                         int extra = put_nmb_name(NULL,0,offset,
    1057             :                                         &nmb->question.question_name);
    1058        2349 :                         if (offset + extra > len) {
    1059           0 :                                 return 0;
    1060             :                         }
    1061             :                 }
    1062        2349 :                 offset += put_nmb_name((char *)ubuf,len,offset,
    1063             :                                 &nmb->question.question_name);
    1064        2349 :                 if (buf) {
    1065        2349 :                         RSSVAL(ubuf,offset,nmb->question.question_type);
    1066        2349 :                         RSSVAL(ubuf,offset+2,nmb->question.question_class);
    1067             :                 }
    1068        2349 :                 offset += 4;
    1069             :         }
    1070             : 
    1071        3246 :         if (nmb->header.ancount) {
    1072         897 :                 if (len) {
    1073             :                         /* Length check. */
    1074         897 :                         int extra = put_res_rec(NULL,0,offset,nmb->answers,
    1075             :                                         nmb->header.ancount);
    1076         897 :                         if (offset + extra > len) {
    1077           0 :                                 return 0;
    1078             :                         }
    1079             :                 }
    1080         897 :                 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
    1081             :                                 nmb->header.ancount);
    1082             :         }
    1083             : 
    1084        3246 :         if (nmb->header.nscount) {
    1085           0 :                 if (len) {
    1086             :                         /* Length check. */
    1087           0 :                         int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
    1088             :                                 nmb->header.nscount);
    1089           0 :                         if (offset + extra > len) {
    1090           0 :                                 return 0;
    1091             :                         }
    1092             :                 }
    1093           0 :                 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
    1094             :                                 nmb->header.nscount);
    1095             :         }
    1096             : 
    1097             :         /*
    1098             :          * The spec says we must put compressed name pointers
    1099             :          * in the following outgoing packets :
    1100             :          * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
    1101             :          * NAME_RELEASE_REQUEST.
    1102             :          */
    1103             : 
    1104        3246 :         if((nmb->header.response == False) &&
    1105        2349 :                 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
    1106        1094 :                 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
    1107        1090 :                 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
    1108        1090 :                 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
    1109        1090 :                 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
    1110        1259 :                 (nmb->header.arcount == 1)) {
    1111             : 
    1112        1259 :                 if (len) {
    1113             :                         /* Length check. */
    1114        1259 :                         int extra = put_compressed_name_ptr(NULL,offset,
    1115             :                                         nmb->additional,12);
    1116        1259 :                         if (offset + extra > len) {
    1117           0 :                                 return 0;
    1118             :                         }
    1119             :                 }
    1120        1259 :                 offset += put_compressed_name_ptr(ubuf,offset,
    1121        1259 :                                 nmb->additional,12);
    1122        1987 :         } else if (nmb->header.arcount) {
    1123           0 :                 if (len) {
    1124             :                         /* Length check. */
    1125           0 :                         int extra = put_res_rec(NULL,0,offset,nmb->additional,
    1126             :                                 nmb->header.arcount);
    1127           0 :                         if (offset + extra > len) {
    1128           0 :                                 return 0;
    1129             :                         }
    1130             :                 }
    1131           0 :                 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
    1132             :                         nmb->header.arcount);
    1133             :         }
    1134        3246 :         return offset;
    1135             : }
    1136             : 
    1137             : /*******************************************************************
    1138             :  Linearise a packet.
    1139             : ******************************************************************/
    1140             : 
    1141        3965 : int build_packet(char *buf, size_t buflen, struct packet_struct *p)
    1142             : {
    1143        3965 :         int len = 0;
    1144             : 
    1145        3965 :         switch (p->packet_type) {
    1146        3246 :         case NMB_PACKET:
    1147        3246 :                 len = build_nmb(buf,buflen,&p->packet.nmb);
    1148        3246 :                 break;
    1149             : 
    1150         719 :         case DGRAM_PACKET:
    1151         719 :                 len = build_dgram(buf,buflen,&p->packet.dgram);
    1152         719 :                 break;
    1153             :         }
    1154             : 
    1155        3965 :         return len;
    1156             : }
    1157             : 
    1158             : /*******************************************************************
    1159             :  Send a packet_struct.
    1160             : ******************************************************************/
    1161             : 
    1162        3059 : bool send_packet(struct packet_struct *p)
    1163             : {
    1164           0 :         char buf[1024];
    1165        3059 :         int len=0;
    1166             : 
    1167        3059 :         memset(buf,'\0',sizeof(buf));
    1168             : 
    1169        3059 :         len = build_packet(buf, sizeof(buf), p);
    1170             : 
    1171        3059 :         if (!len)
    1172           0 :                 return(False);
    1173             : 
    1174        3059 :         return(send_udp(p->send_fd,buf,len,p->ip,p->port));
    1175             : }
    1176             : 
    1177             : /****************************************************************************
    1178             :  Receive a UDP/138 packet either via UDP or from the unexpected packet
    1179             :  queue. The packet must be a reply packet and have the specified mailslot name
    1180             :  The timeout is in milliseconds.
    1181             : ***************************************************************************/
    1182             : 
    1183             : /****************************************************************************
    1184             :  See if a datagram has the right mailslot name.
    1185             : ***************************************************************************/
    1186             : 
    1187          32 : bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
    1188             : {
    1189          32 :         struct dgram_packet *dgram = &p->packet.dgram;
    1190           0 :         char *buf;
    1191             : 
    1192          32 :         buf = &dgram->data[0];
    1193          32 :         buf -= 4;
    1194             : 
    1195          32 :         buf = smb_buf(buf);
    1196             : 
    1197          32 :         if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
    1198          30 :                 return True;
    1199             :         }
    1200             : 
    1201           2 :         return False;
    1202             : }
    1203             : 
    1204             : /****************************************************************************
    1205             :  Return the number of bits that match between two len character buffers
    1206             : ***************************************************************************/
    1207             : 
    1208         252 : int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
    1209             : {
    1210           0 :         size_t i, j;
    1211         252 :         int ret = 0;
    1212         504 :         for (i=0; i<len; i++) {
    1213         504 :                 if (p1[i] != p2[i])
    1214         252 :                         break;
    1215         252 :                 ret += 8;
    1216             :         }
    1217             : 
    1218         252 :         if (i==len)
    1219           0 :                 return ret;
    1220             : 
    1221         252 :         for (j=0; j<8; j++) {
    1222         252 :                 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
    1223         252 :                         break;
    1224           0 :                 ret++;
    1225             :         }
    1226             : 
    1227         252 :         return ret;
    1228             : }
    1229             : 
    1230             : static unsigned char sort_ip[4];
    1231             : 
    1232             : /****************************************************************************
    1233             :  Compare two query reply records.
    1234             : ***************************************************************************/
    1235             : 
    1236           0 : static int name_query_comp(unsigned char *p1, unsigned char *p2)
    1237             : {
    1238           0 :         int a = matching_len_bits(p1+2, sort_ip, 4);
    1239           0 :         int b = matching_len_bits(p2+2, sort_ip, 4);
    1240             :         /* reverse sort -- p2 derived value comes first */
    1241           0 :         return NUMERIC_CMP(b, a);
    1242             : }
    1243             : 
    1244             : /****************************************************************************
    1245             :  Sort a set of 6 byte name query response records so that the IPs that
    1246             :  have the most leading bits in common with the specified address come first.
    1247             : ***************************************************************************/
    1248             : 
    1249         841 : void sort_query_replies(char *data, int n, struct in_addr ip)
    1250             : {
    1251         841 :         if (n <= 1)
    1252         841 :                 return;
    1253             : 
    1254           0 :         putip(sort_ip, (char *)&ip);
    1255             : 
    1256             :         /* TODO:
    1257             :            this can't use TYPESAFE_QSORT() as the types are wrong.
    1258             :            It should be fixed to use a real type instead of char*
    1259             :         */
    1260           0 :         qsort(data, n, 6, QSORT_CAST name_query_comp);
    1261             : }
    1262             : 
    1263             : /****************************************************************************
    1264             :  Interpret the weird netbios "name" into a unix fstring. Return the name type.
    1265             :  Returns -1 on error.
    1266             : ****************************************************************************/
    1267             : 
    1268        2104 : static int name_interpret(unsigned char *buf, size_t buf_len,
    1269             :                 unsigned char *in, fstring name)
    1270             : {
    1271        2104 :         unsigned char *end_ptr = buf + buf_len;
    1272           0 :         int ret;
    1273           0 :         unsigned int len;
    1274           0 :         fstring out_string;
    1275        2104 :         unsigned char *out = (unsigned char *)out_string;
    1276             : 
    1277        2104 :         *out=0;
    1278             : 
    1279        2104 :         if (in >= end_ptr) {
    1280           0 :                 return -1;
    1281             :         }
    1282        2104 :         len = (*in++) / 2;
    1283             : 
    1284        2104 :         if (len<1) {
    1285           0 :                 return -1;
    1286             :         }
    1287             : 
    1288       35768 :         while (len--) {
    1289       33664 :                 if (&in[1] >= end_ptr) {
    1290           0 :                         return -1;
    1291             :                 }
    1292       33664 :                 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
    1293           0 :                         *out = 0;
    1294           0 :                         return(0);
    1295             :                 }
    1296       33664 :                 *out = ((in[0]-'A')<<4) + (in[1]-'A');
    1297       33664 :                 in += 2;
    1298       33664 :                 out++;
    1299       33664 :                 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
    1300           0 :                         return -1;
    1301             :                 }
    1302             :         }
    1303        2104 :         ret = out[-1];
    1304        2104 :         out[-1] = 0;
    1305             : 
    1306        2104 :         pull_ascii_fstring(name, out_string);
    1307             : 
    1308        2104 :         return(ret);
    1309             : }
    1310             : 
    1311             : /****************************************************************************
    1312             :  Mangle a name into netbios format.
    1313             :  Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
    1314             : ****************************************************************************/
    1315             : 
    1316        2124 : char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
    1317             : {
    1318           0 :         int   i;
    1319           0 :         int   len;
    1320           0 :         nstring buf;
    1321           0 :         char *result;
    1322           0 :         char *p;
    1323             : 
    1324        2124 :         result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
    1325        2124 :         if (result == NULL) {
    1326           0 :                 return NULL;
    1327             :         }
    1328        2124 :         p = result;
    1329             : 
    1330             :         /* Safely copy the input string, In, into buf[]. */
    1331        2124 :         if (strcmp(In,"*") == 0)
    1332           0 :                 put_name(buf, "*", '\0', 0x00);
    1333             :         else {
    1334             :                 /* We use an fstring here as mb dos names can expend x3 when
    1335             :                    going to utf8. */
    1336           0 :                 fstring buf_unix;
    1337           0 :                 nstring buf_dos;
    1338             : 
    1339        2124 :                 pull_ascii_fstring(buf_unix, In);
    1340        2124 :                 if (!strupper_m(buf_unix)) {
    1341           0 :                         return NULL;
    1342             :                 }
    1343             : 
    1344        2124 :                 push_ascii_nstring(buf_dos, buf_unix);
    1345        2124 :                 put_name(buf, buf_dos, ' ', name_type);
    1346             :         }
    1347             : 
    1348             :         /* Place the length of the first field into the output buffer. */
    1349        2124 :         p[0] = 32;
    1350        2124 :         p++;
    1351             : 
    1352             :         /* Now convert the name to the rfc1001/1002 format. */
    1353       36108 :         for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
    1354       33984 :                 p[i*2]     = ( (buf[i] >> 4) & 0x000F ) + 'A';
    1355       33984 :                 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
    1356             :         }
    1357        2124 :         p += 32;
    1358        2124 :         p[0] = '\0';
    1359             : 
    1360             :         /* Add the scope string. */
    1361        2124 :         for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
    1362           0 :                 switch( (lp_netbios_scope())[i] ) {
    1363           0 :                         case '\0':
    1364           0 :                                 p[0] = len;
    1365           0 :                                 if( len > 0 )
    1366           0 :                                         p[len+1] = 0;
    1367           0 :                                 return result;
    1368           0 :                         case '.':
    1369           0 :                                 p[0] = len;
    1370           0 :                                 p   += (len + 1);
    1371           0 :                                 len  = -1;
    1372           0 :                                 break;
    1373           0 :                         default:
    1374           0 :                                 p[len+1] = (lp_netbios_scope())[i];
    1375           0 :                                 break;
    1376             :                 }
    1377             :         }
    1378             : 
    1379        2124 :         return result;
    1380             : }
    1381             : 
    1382             : /****************************************************************************
    1383             :  Find a pointer to a netbios name.
    1384             : ****************************************************************************/
    1385             : 
    1386        2104 : static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
    1387             : {
    1388        2104 :         unsigned char c = 0;
    1389             : 
    1390        2104 :         if (ofs > buf_len || buf_len < 1) {
    1391           0 :                 return NULL;
    1392             :         }
    1393             : 
    1394        2104 :         c = *(unsigned char *)(buf+ofs);
    1395        2104 :         if ((c & 0xC0) == 0xC0) {
    1396           0 :                 uint16_t l = 0;
    1397             : 
    1398           0 :                 if (ofs > buf_len - 1) {
    1399           0 :                         return NULL;
    1400             :                 }
    1401           0 :                 l = RSVAL(buf, ofs) & 0x3FFF;
    1402           0 :                 if (l > buf_len) {
    1403           0 :                         return NULL;
    1404             :                 }
    1405           0 :                 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
    1406           0 :                 return(buf + l);
    1407             :         } else {
    1408        2104 :                 return(buf+ofs);
    1409             :         }
    1410             : }
    1411             : 
    1412             : /****************************************************************************
    1413             :  Extract a netbios name from a buf (into a unix string) return name type.
    1414             :  Returns -1 on error.
    1415             : ****************************************************************************/
    1416             : 
    1417        2104 : int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
    1418             : {
    1419        2104 :         unsigned char *p = name_ptr(buf,buf_len,ofs);
    1420             : 
    1421        2104 :         name[0] = '\0';
    1422        2104 :         if (p == NULL) {
    1423           0 :                 return -1;
    1424             :         }
    1425        2104 :         return(name_interpret(buf,buf_len,p,name));
    1426             : }
    1427             : 
    1428             : /****************************************************************************
    1429             :  Return the total storage length of a mangled name.
    1430             :  Returns -1 on error.
    1431             : ****************************************************************************/
    1432             : 
    1433        4236 : int name_len(unsigned char *s1, size_t buf_len)
    1434             : {
    1435             :         /* NOTE: this argument _must_ be unsigned */
    1436        4236 :         unsigned char *s = (unsigned char *)s1;
    1437        4236 :         int len = 0;
    1438             : 
    1439        4236 :         if (buf_len < 1) {
    1440           0 :                 return -1;
    1441             :         }
    1442             :         /* If the two high bits of the byte are set, return 2. */
    1443        4236 :         if (0xC0 == (*s & 0xC0)) {
    1444           0 :                 if (buf_len < 2) {
    1445           0 :                         return -1;
    1446             :                 }
    1447           0 :                 return(2);
    1448             :         }
    1449             : 
    1450             :         /* Add up the length bytes. */
    1451        8468 :         for (len = 1; (*s); s += (*s) + 1) {
    1452        4236 :                 len += *s + 1;
    1453        4236 :                 if (len > buf_len) {
    1454           4 :                         return -1;
    1455             :                 }
    1456             :         }
    1457             : 
    1458        4232 :         return(len);
    1459             : }
    1460             : 
    1461             : /*******************************************************************
    1462             :  Setup the word count and byte count for a client smb message.
    1463             : ********************************************************************/
    1464             : 
    1465         666 : int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
    1466             : {
    1467         666 :         if (zero && (num_words || num_bytes)) {
    1468         666 :                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
    1469             :         }
    1470         666 :         SCVAL(buf,smb_wct,num_words);
    1471         666 :         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
    1472         666 :         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
    1473         666 :         return (smb_size + num_words*2 + num_bytes);
    1474             : }

Generated by: LCOV version 1.14