Coverage Report

Created: 2025-12-31 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/libsmb/nmblib.c
Line
Count
Source
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
const char *global_nmbd_socket_dir(void)
27
0
{
28
0
  return lp_parm_const_string(-1, "nmbd", "socket dir",
29
0
            get_dyn_NMBDSOCKETDIR());
30
0
}
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
static const char *lookup_opcode_name( int opcode )
51
0
{
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
0
  }
60
0
  return "<unknown opcode>";
61
0
}
62
63
/****************************************************************************
64
 Print out a res_rec structure.
65
****************************************************************************/
66
67
static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
68
0
{
69
0
  int i, j;
70
71
0
  DEBUGADD( 4, ( "    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
72
0
    hdr,
73
0
    nmb_namestr(&res->rr_name),
74
0
    res->rr_type,
75
0
    res->rr_class,
76
0
    res->ttl ) );
77
78
0
  if (res->rdlength == 0) {
79
0
    return;
80
0
  }
81
82
0
  for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
83
0
    DEBUGADD(4, ("    %s %3x char ", hdr, i));
84
85
0
    for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
86
0
      unsigned char x = res->rdata[i+j];
87
0
      if (x < 32 || x > 127)
88
0
        x = '.';
89
90
0
      if (i+j >= res->rdlength)
91
0
        break;
92
0
      DEBUGADD(4, ("%c", x));
93
0
    }
94
95
0
    DEBUGADD(4, ("   hex "));
96
97
0
    for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
98
0
      if (i+j >= res->rdlength)
99
0
        break;
100
0
      DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
101
0
    }
102
103
0
    DEBUGADD(4, ("\n"));
104
0
  }
105
0
}
106
107
/****************************************************************************
108
 Process a nmb packet.
109
****************************************************************************/
110
111
void debug_nmb_packet(struct packet_struct *p)
112
0
{
113
0
  struct nmb_packet *nmb = &p->packet.nmb;
114
115
0
  if( DEBUGLVL( 4 ) ) {
116
0
    dbgtext( "nmb packet from %s(%d) header: id=%d "
117
0
        "opcode=%s(%d) response=%s\n",
118
0
      inet_ntoa(p->ip), p->port,
119
0
      nmb->header.name_trn_id,
120
0
      lookup_opcode_name(nmb->header.opcode),
121
0
      nmb->header.opcode,
122
0
      BOOLSTR(nmb->header.response) );
123
0
    dbgtext( "    header: flags: bcast=%s rec_avail=%s "
124
0
        "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
0
        "nscount=%d arcount=%d\n",
132
0
      nmb->header.rcode,
133
0
      nmb->header.qdcount,
134
0
      nmb->header.ancount,
135
0
      nmb->header.nscount,
136
0
      nmb->header.arcount );
137
0
  }
138
139
0
  if (nmb->header.qdcount) {
140
0
    DEBUGADD( 4, ( "    question: q_name=%s q_type=%d q_class=%d\n",
141
0
      nmb_namestr(&nmb->question.question_name),
142
0
      nmb->question.question_type,
143
0
      nmb->question.question_class) );
144
0
  }
145
146
0
  if (nmb->answers && nmb->header.ancount) {
147
0
    debug_nmb_res_rec(nmb->answers,"answers");
148
0
  }
149
0
  if (nmb->nsrecs && nmb->header.nscount) {
150
0
    debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
151
0
  }
152
0
  if (nmb->additional && nmb->header.arcount) {
153
0
    debug_nmb_res_rec(nmb->additional,"additional");
154
0
  }
155
0
}
156
157
/*******************************************************************
158
 Handle "compressed" name pointers.
159
******************************************************************/
160
161
static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
162
           bool *got_pointer,int *ret)
163
425k
{
164
425k
  int loop_count=0;
165
166
518k
  while ((ubuf[*offset] & 0xC0) == 0xC0) {
167
93.6k
    if (!*got_pointer)
168
89.9k
      (*ret) += 2;
169
93.6k
    (*got_pointer)=True;
170
93.6k
    if (*offset > length - 2) {
171
9
      return False;
172
9
    }
173
93.6k
    (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
174
93.6k
    if (loop_count++ == 10 ||
175
93.6k
        (*offset) < 0 || (*offset)>(length-2)) {
176
23
      return False;
177
23
    }
178
93.6k
  }
179
425k
  return True;
180
425k
}
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
static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
188
355k
{
189
355k
  size_t m,n=0;
190
355k
  unsigned char *ubuf = (unsigned char *)inbuf;
191
355k
  int ret = 0;
192
355k
  bool got_pointer=False;
193
355k
  size_t loop_count=0;
194
355k
  int offset = ofs;
195
196
355k
  if (length - offset < 2)
197
92
    return(0);
198
199
  /* handle initial name pointers */
200
355k
  if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
201
15
    return(0);
202
203
355k
  m = ubuf[offset];
204
205
  /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
206
355k
  if (m != 32) {
207
52
    return 0;
208
52
  }
209
  /* Cannot go past length. */
210
355k
  if (offset+m+2 > length) {
211
14
    return 0;
212
14
  }
213
214
355k
  memset((char *)name,'\0',sizeof(*name));
215
216
  /* the "compressed" part */
217
355k
  if (!got_pointer)
218
266k
    ret += m + 2;
219
355k
  offset++;
220
6.03M
  while (m > 0) {
221
5.68M
    unsigned char c1,c2;
222
5.68M
    c1 = ubuf[offset++]-'A';
223
5.68M
    c2 = ubuf[offset++]-'A';
224
5.68M
    if ((c1 & 0xF0) || (c2 & 0xF0)) {
225
30
      return(0);
226
30
    }
227
5.68M
    if (n >= sizeof(name->name)) {
228
0
      return 0;
229
0
    }
230
5.68M
    name->name[n++] = (c1<<4) | c2;
231
5.68M
    m -= 2;
232
5.68M
  }
233
  /*
234
   * RFC1002: For a valid NetBIOS name, exiting from the above,
235
   * n *must* be MAX_NETBIOSNAME_LEN (16).
236
   */
237
355k
  if (n != MAX_NETBIOSNAME_LEN) {
238
0
    return 0;
239
0
  }
240
241
  /* parse out the name type, its always
242
   * in the 16th byte of the name */
243
355k
  name->name_type = ((unsigned char)name->name[15]) & 0xff;
244
245
  /* remove trailing spaces */
246
355k
  name->name[15] = 0;
247
355k
  n = 14;
248
4.67M
  while (n && name->name[n]==' ')
249
4.32M
    name->name[n--] = 0;
250
251
  /* now the domain parts (if any) */
252
355k
  n = 0;
253
425k
  while (ubuf[offset]) {
254
    /* we can have pointers within the domain part as well */
255
69.8k
    if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
256
17
      return(0);
257
258
69.8k
    m = ubuf[offset];
259
    /*
260
     * Don't allow null domain parts.
261
     */
262
69.8k
    if (!m)
263
2
      return(0);
264
69.8k
    if (!got_pointer)
265
1.21k
      ret += m+1;
266
69.8k
    if (n)
267
23.1k
      name->scope[n++] = '.';
268
69.8k
    if (m+2+offset>length || n+m+1>sizeof(name->scope))
269
51
      return(0);
270
69.7k
    offset++;
271
1.64M
    while (m--)
272
1.57M
      name->scope[n++] = (char)ubuf[offset++];
273
274
    /*
275
     * Watch for malicious loops.
276
     */
277
69.7k
    if (loop_count++ == 10)
278
3
      return 0;
279
69.7k
  }
280
355k
  name->scope[n++] = 0;
281
282
355k
  return(ret);
283
355k
}
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
void put_name(char *dest, const char *name, int pad, unsigned int name_type)
292
485k
{
293
485k
  size_t len = strlen(name);
294
295
485k
  memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
296
485k
      len : MAX_NETBIOSNAME_LEN - 1);
297
485k
  if (len < MAX_NETBIOSNAME_LEN - 1) {
298
479k
    memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
299
479k
  }
300
485k
  dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
301
485k
}
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
static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
315
485k
{
316
485k
  int ret,m;
317
485k
  nstring buf1;
318
485k
  char *p;
319
320
485k
  if (strcmp(name->name,"*") == 0) {
321
    /* special case for wildcard name */
322
4.40k
    put_name(buf1, "*", '\0', name->name_type);
323
481k
  } else {
324
481k
    put_name(buf1, name->name, ' ', name->name_type);
325
481k
  }
326
327
485k
  if (buf) {
328
242k
    if (offset >= buflen) {
329
0
      return 0;
330
0
    }
331
242k
    buf[offset] = 0x20;
332
242k
  }
333
334
485k
  ret = 34;
335
336
8.25M
  for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
337
7.76M
    if (buf) {
338
3.88M
      if (offset+2+2*m >= buflen) {
339
0
        return 0;
340
0
      }
341
3.88M
      buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
342
3.88M
      buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
343
3.88M
    }
344
7.76M
  }
345
485k
  offset += 33;
346
347
485k
  if (buf) {
348
242k
    if (offset >= buflen) {
349
0
      return 0;
350
0
    }
351
242k
    buf[offset] = 0;
352
242k
  }
353
354
485k
  if (name->scope[0]) {
355
    /* XXXX this scope handling needs testing */
356
81.1k
    size_t scopenamelen = strlen(name->scope) + 1;
357
81.1k
    ret += scopenamelen;
358
81.1k
    if (buf) {
359
40.5k
      if (offset+1+scopenamelen >= buflen) {
360
0
        return 0;
361
0
      }
362
40.5k
      strlcpy(&buf[offset+1],name->scope,
363
40.5k
          buflen - (offset+1));
364
365
40.5k
      p = &buf[offset+1];
366
63.1k
      while ((p = strchr_m(p,'.'))) {
367
22.5k
        buf[offset] = PTR_DIFF(p,&buf[offset+1]);
368
22.5k
        offset += (buf[offset] + 1);
369
22.5k
        if (offset+1 >= buflen) {
370
0
          return 0;
371
0
        }
372
22.5k
        p = &buf[offset+1];
373
22.5k
      }
374
40.5k
      buf[offset] = strlen(&buf[offset+1]);
375
40.5k
    }
376
81.1k
  }
377
378
485k
  return ret;
379
485k
}
380
381
/*******************************************************************
382
 Useful for debugging messages.
383
******************************************************************/
384
385
char *nmb_namestr(const struct nmb_name *n)
386
0
{
387
0
  fstring name;
388
0
  char *result;
389
390
0
  pull_ascii_fstring(name, n->name);
391
0
  if (!n->scope[0])
392
0
    result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
393
0
           n->name_type);
394
0
  else
395
0
    result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
396
0
           n->name_type, n->scope);
397
398
0
  SMB_ASSERT(result != NULL);
399
0
  return result;
400
0
}
401
402
/*******************************************************************
403
 Allocate and parse some resource records.
404
******************************************************************/
405
406
static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
407
        struct res_rec **recs, int count)
408
697
{
409
697
  int i;
410
411
697
  *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
412
697
  if (!*recs)
413
0
    return(False);
414
415
697
  memset((char *)*recs,'\0',sizeof(**recs)*count);
416
417
355k
  for (i=0;i<count;i++) {
418
355k
    int l = parse_nmb_name(inbuf,*offset,length,
419
355k
        &(*recs)[i].rr_name);
420
355k
    (*offset) += l;
421
355k
    if (!l || (*offset)+10 > length) {
422
235
      SAFE_FREE(*recs);
423
235
      return(False);
424
235
    }
425
354k
    (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
426
354k
    (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
427
354k
    (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
428
354k
    (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
429
354k
    (*offset) += 10;
430
354k
    if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
431
354k
        (*offset)+(*recs)[i].rdlength > length) {
432
45
      SAFE_FREE(*recs);
433
45
      return(False);
434
45
    }
435
354k
    memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
436
354k
    (*offset) += (*recs)[i].rdlength;
437
354k
  }
438
417
  return(True);
439
697
}
440
441
/*******************************************************************
442
 Put a resource record into a packet.
443
 If buf == NULL this is a length calculation.
444
******************************************************************/
445
446
static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
447
706
{
448
706
  int ret=0;
449
706
  int i;
450
451
486k
  for (i=0;i<count;i++) {
452
485k
    int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
453
485k
    offset += l;
454
485k
    ret += l;
455
485k
    if (buf) {
456
242k
      RSSVAL(buf,offset,recs[i].rr_type);
457
242k
      RSSVAL(buf,offset+2,recs[i].rr_class);
458
242k
      RSIVAL(buf,offset+4,(unsigned int)recs[i].ttl);
459
242k
      RSSVAL(buf,offset+8,recs[i].rdlength);
460
242k
      memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
461
242k
    }
462
485k
    offset += 10+recs[i].rdlength;
463
485k
    ret += 10+recs[i].rdlength;
464
485k
  }
465
466
706
  return ret;
467
706
}
468
469
/*******************************************************************
470
 Put a compressed name pointer record into a packet.
471
 If buf == NULL this is a length calculation.
472
******************************************************************/
473
474
static int put_compressed_name_ptr(unsigned char *buf,
475
        int offset,
476
        struct res_rec *rec,
477
        int ptr_offset)
478
70
{
479
70
  int ret=offset;
480
70
  if (buf) {
481
35
    buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
482
35
    buf[offset+1] = (ptr_offset & 0xFF);
483
35
  }
484
70
  offset += 2;
485
70
  if (buf) {
486
35
    RSSVAL(buf,offset,rec->rr_type);
487
35
    RSSVAL(buf,offset+2,rec->rr_class);
488
35
    RSIVAL(buf,offset+4,rec->ttl);
489
35
    RSSVAL(buf,offset+8,rec->rdlength);
490
35
    memcpy(buf+offset+10,rec->rdata,rec->rdlength);
491
35
  }
492
70
  offset += 10+rec->rdlength;
493
70
  ret = (offset - ret);
494
495
70
  return ret;
496
70
}
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
static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
506
0
{
507
0
  size_t offset;
508
0
  int flags;
509
510
0
  memset((char *)dgram,'\0',sizeof(*dgram));
511
512
0
  if (length < 14)
513
0
    return(False);
514
515
0
  dgram->header.msg_type = CVAL(inbuf,0);
516
0
  flags = CVAL(inbuf,1);
517
0
  dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
518
0
  if (flags & 1)
519
0
    dgram->header.flags.more = True;
520
0
  if (flags & 2)
521
0
    dgram->header.flags.first = True;
522
0
  dgram->header.dgm_id = RSVAL(inbuf,2);
523
0
  putip((char *)&dgram->header.source_ip,inbuf+4);
524
0
  dgram->header.source_port = RSVAL(inbuf,8);
525
0
  dgram->header.dgm_length = RSVAL(inbuf,10);
526
0
  dgram->header.packet_offset = RSVAL(inbuf,12);
527
528
0
  offset = 14;
529
530
0
  if (dgram->header.msg_type == 0x10 ||
531
0
      dgram->header.msg_type == 0x11 ||
532
0
      dgram->header.msg_type == 0x12) {
533
0
    offset += parse_nmb_name(inbuf,offset,length,
534
0
        &dgram->source_name);
535
0
    offset += parse_nmb_name(inbuf,offset,length,
536
0
        &dgram->dest_name);
537
0
  }
538
539
0
  if (offset >= length || (length-offset > sizeof(dgram->data)))
540
0
    return(False);
541
542
0
  dgram->datasize = length-offset;
543
0
  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
0
  SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
549
0
  memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
550
551
0
  return(True);
552
0
}
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
static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
560
742
{
561
742
  int nm_flags,offset;
562
563
742
  memset((char *)nmb,'\0',sizeof(*nmb));
564
565
742
  if (length < 12)
566
5
    return(False);
567
568
  /* parse the header */
569
737
  nmb->header.name_trn_id = RSVAL(inbuf,0);
570
571
737
  DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
572
573
737
  nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
574
737
  nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
575
737
  nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
576
737
  nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
577
737
  nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
578
737
  nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
579
737
  nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
580
737
  nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
581
737
  nmb->header.rcode = CVAL(inbuf,3) & 0xF;
582
737
  nmb->header.qdcount = RSVAL(inbuf,4);
583
737
  nmb->header.ancount = RSVAL(inbuf,6);
584
737
  nmb->header.nscount = RSVAL(inbuf,8);
585
737
  nmb->header.arcount = RSVAL(inbuf,10);
586
587
737
  if (nmb->header.qdcount) {
588
315
    offset = parse_nmb_name(inbuf,12,length,
589
315
        &nmb->question.question_name);
590
315
    if (!offset)
591
104
      return(False);
592
593
211
    if (length - (12+offset) < 4)
594
11
      return(False);
595
200
    nmb->question.question_type = RSVAL(inbuf,12+offset);
596
200
    nmb->question.question_class = RSVAL(inbuf,12+offset+2);
597
598
200
    offset += 12+4;
599
422
  } else {
600
422
    offset = 12;
601
422
  }
602
603
  /* and any resource records */
604
622
  if (nmb->header.ancount &&
605
287
      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
606
287
          nmb->header.ancount))
607
145
    return(False);
608
609
477
  if (nmb->header.nscount &&
610
189
      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
611
189
          nmb->header.nscount))
612
71
    return(False);
613
614
406
  if (nmb->header.arcount &&
615
221
      !parse_alloc_res_rec(inbuf,&offset,length,
616
221
        &nmb->additional, nmb->header.arcount))
617
64
    return(False);
618
619
342
  return(True);
620
406
}
621
622
/*******************************************************************
623
 'Copy constructor' for an nmb packet.
624
******************************************************************/
625
626
static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
627
0
{
628
0
  struct nmb_packet *nmb;
629
0
  struct nmb_packet *copy_nmb;
630
0
  struct packet_struct *pkt_copy;
631
632
0
  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
0
  }
636
637
  /* Structure copy of entire thing. */
638
639
0
  *pkt_copy = *packet;
640
641
  /* Ensure this copy is not locked. */
642
0
  pkt_copy->locked = False;
643
0
  pkt_copy->recv_fd = -1;
644
0
  pkt_copy->send_fd = -1;
645
646
  /* Ensure this copy has no resource records. */
647
0
  nmb = &packet->packet.nmb;
648
0
  copy_nmb = &pkt_copy->packet.nmb;
649
650
0
  copy_nmb->answers = NULL;
651
0
  copy_nmb->nsrecs = NULL;
652
0
  copy_nmb->additional = NULL;
653
654
  /* Now copy any resource records. */
655
656
0
  if (nmb->answers) {
657
0
    if((copy_nmb->answers = SMB_MALLOC_ARRAY(
658
0
        struct res_rec,nmb->header.ancount)) == NULL)
659
0
      goto free_and_exit;
660
0
    memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
661
0
        nmb->header.ancount * sizeof(struct res_rec));
662
0
  }
663
0
  if (nmb->nsrecs) {
664
0
    if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
665
0
        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
0
  }
670
0
  if (nmb->additional) {
671
0
    if((copy_nmb->additional = SMB_MALLOC_ARRAY(
672
0
        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
0
  }
677
678
0
  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
0
}
690
691
/*******************************************************************
692
  'Copy constructor' for a dgram packet.
693
******************************************************************/
694
695
static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
696
0
{
697
0
  struct packet_struct *pkt_copy;
698
699
0
  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
0
  }
703
704
  /* Structure copy of entire thing. */
705
706
0
  *pkt_copy = *packet;
707
708
  /* Ensure this copy is not locked. */
709
0
  pkt_copy->locked = False;
710
0
  pkt_copy->recv_fd = -1;
711
0
  pkt_copy->send_fd = -1;
712
713
  /* There are no additional pointers in a dgram packet,
714
    we are finished. */
715
0
  return pkt_copy;
716
0
}
717
718
/*******************************************************************
719
 'Copy constructor' for a generic packet.
720
******************************************************************/
721
722
struct packet_struct *copy_packet(struct packet_struct *packet)
723
0
{
724
0
  if(packet->packet_type == NMB_PACKET)
725
0
    return copy_nmb_packet(packet);
726
0
  else if (packet->packet_type == DGRAM_PACKET)
727
0
    return copy_dgram_packet(packet);
728
0
  return NULL;
729
0
}
730
731
/*******************************************************************
732
 Free up any resources associated with an nmb packet.
733
******************************************************************/
734
735
static void free_nmb_packet(struct nmb_packet *nmb)
736
742
{
737
742
  SAFE_FREE(nmb->answers);
738
742
  SAFE_FREE(nmb->nsrecs);
739
742
  SAFE_FREE(nmb->additional);
740
742
}
741
742
/*******************************************************************
743
 Free up any resources associated with a dgram packet.
744
******************************************************************/
745
746
static void free_dgram_packet(struct dgram_packet *nmb)
747
0
{
748
  /* We have nothing to do for a dgram packet. */
749
0
}
750
751
/*******************************************************************
752
 Free up any resources associated with a packet.
753
******************************************************************/
754
755
void free_packet(struct packet_struct *packet)
756
742
{
757
742
  if (packet->locked)
758
0
    return;
759
742
  if (packet->packet_type == NMB_PACKET)
760
742
    free_nmb_packet(&packet->packet.nmb);
761
0
  else if (packet->packet_type == DGRAM_PACKET)
762
0
    free_dgram_packet(&packet->packet.dgram);
763
742
  ZERO_STRUCTPN(packet);
764
742
  SAFE_FREE(packet);
765
742
}
766
767
int packet_trn_id(struct packet_struct *p)
768
0
{
769
0
  int result;
770
0
  switch (p->packet_type) {
771
0
  case NMB_PACKET:
772
0
    result = p->packet.nmb.header.name_trn_id;
773
0
    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
0
  }
780
0
  return result;
781
0
}
782
783
/*******************************************************************
784
 Parse a packet buffer into a packet structure.
785
******************************************************************/
786
787
struct packet_struct *parse_packet(char *buf,int length,
788
           enum packet_type packet_type,
789
           struct in_addr ip,
790
           int port)
791
742
{
792
742
  struct packet_struct *p;
793
742
  bool ok=False;
794
795
742
  p = SMB_MALLOC_P(struct packet_struct);
796
742
  if (!p)
797
0
    return(NULL);
798
799
742
  ZERO_STRUCTP(p);  /* initialize for possible padding */
800
801
742
  p->next = NULL;
802
742
  p->prev = NULL;
803
742
  p->ip = ip;
804
742
  p->port = port;
805
742
  p->locked = False;
806
742
  p->timestamp = time(NULL);
807
742
  p->packet_type = packet_type;
808
809
742
  switch (packet_type) {
810
742
  case NMB_PACKET:
811
742
    ok = parse_nmb(buf,length,&p->packet.nmb);
812
742
    break;
813
814
0
  case DGRAM_PACKET:
815
0
    ok = parse_dgram(buf,length,&p->packet.dgram);
816
0
    break;
817
742
  }
818
819
742
  if (!ok) {
820
400
    free_packet(p);
821
400
    return NULL;
822
400
  }
823
824
342
  return p;
825
742
}
826
827
static struct packet_struct *copy_packet_talloc(
828
  TALLOC_CTX *mem_ctx, const struct packet_struct *src)
829
0
{
830
0
  struct packet_struct *pkt;
831
832
0
  pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
833
0
  if (pkt == NULL) {
834
0
    return NULL;
835
0
  }
836
0
  pkt->locked = false;
837
0
  pkt->recv_fd = -1;
838
0
  pkt->send_fd = -1;
839
840
0
  if (src->packet_type == NMB_PACKET) {
841
0
    const struct nmb_packet *nsrc = &src->packet.nmb;
842
0
    struct nmb_packet *ndst = &pkt->packet.nmb;
843
844
0
    if (nsrc->answers != NULL) {
845
0
      ndst->answers = talloc_memdup(
846
0
        pkt, nsrc->answers,
847
0
        sizeof(struct res_rec) * nsrc->header.ancount);
848
0
      if (ndst->answers == NULL) {
849
0
        goto fail;
850
0
      }
851
0
    }
852
0
    if (nsrc->nsrecs != NULL) {
853
0
      ndst->nsrecs = talloc_memdup(
854
0
        pkt, nsrc->nsrecs,
855
0
        sizeof(struct res_rec) * nsrc->header.nscount);
856
0
      if (ndst->nsrecs == NULL) {
857
0
        goto fail;
858
0
      }
859
0
    }
860
0
    if (nsrc->additional != NULL) {
861
0
      ndst->additional = talloc_memdup(
862
0
        pkt, nsrc->additional,
863
0
        sizeof(struct res_rec) * nsrc->header.arcount);
864
0
      if (ndst->additional == NULL) {
865
0
        goto fail;
866
0
      }
867
0
    }
868
0
  }
869
870
0
  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
0
}
880
881
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
0
{
887
0
  struct packet_struct *pkt, *result;
888
889
0
  pkt = parse_packet(buf, length, packet_type, ip, port);
890
0
  if (pkt == NULL) {
891
0
    return NULL;
892
0
  }
893
0
  result = copy_packet_talloc(mem_ctx, pkt);
894
0
  free_packet(pkt);
895
0
  return result;
896
0
}
897
898
/*******************************************************************
899
 Send a udp packet on a already open socket.
900
******************************************************************/
901
902
static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
903
0
{
904
0
  bool ret = False;
905
0
  int i;
906
0
  struct sockaddr_in sock_out;
907
908
  /* set the address and port */
909
0
  memset((char *)&sock_out,'\0',sizeof(sock_out));
910
0
  putip((char *)&sock_out.sin_addr,(char *)&ip);
911
0
  sock_out.sin_port = htons( port );
912
0
  sock_out.sin_family = AF_INET;
913
914
0
  DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
915
0
      len, inet_ntoa(ip), port ) );
916
917
  /*
918
   * Patch to fix asynch error notifications from Linux kernel.
919
   */
920
921
0
  for (i = 0; i < 5; i++) {
922
0
    ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
923
0
          sizeof(sock_out)) >= 0);
924
0
    if (ret || errno != ECONNREFUSED)
925
0
      break;
926
0
  }
927
928
0
  if (!ret)
929
0
    DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
930
0
      inet_ntoa(ip),port,strerror(errno)));
931
932
0
  return(ret);
933
0
}
934
935
/*******************************************************************
936
 Build a dgram packet ready for sending.
937
 If buf == NULL this is a length calculation.
938
******************************************************************/
939
940
static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
941
0
{
942
0
  unsigned char *ubuf = (unsigned char *)buf;
943
0
  int offset=0;
944
945
  /* put in the header */
946
0
  if (buf) {
947
0
    ubuf[0] = dgram->header.msg_type;
948
0
    ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
949
0
    if (dgram->header.flags.more)
950
0
      ubuf[1] |= 1;
951
0
    if (dgram->header.flags.first)
952
0
      ubuf[1] |= 2;
953
0
    RSSVAL(ubuf,2,dgram->header.dgm_id);
954
0
    putip(ubuf+4,(char *)&dgram->header.source_ip);
955
0
    RSSVAL(ubuf,8,dgram->header.source_port);
956
0
    RSSVAL(ubuf,12,dgram->header.packet_offset);
957
0
  }
958
959
0
  offset = 14;
960
961
0
  if (dgram->header.msg_type == 0x10 ||
962
0
      dgram->header.msg_type == 0x11 ||
963
0
      dgram->header.msg_type == 0x12) {
964
0
    offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
965
0
    offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
966
0
  }
967
968
0
  if (buf) {
969
0
    memcpy(ubuf+offset,dgram->data,dgram->datasize);
970
0
  }
971
0
  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
0
  dgram->header.dgm_length = (offset - 14);
978
0
  if (buf) {
979
0
    RSSVAL(ubuf,10,dgram->header.dgm_length);
980
0
  }
981
982
0
  return offset;
983
0
}
984
985
/*******************************************************************
986
 Build a nmb name
987
*******************************************************************/
988
989
void make_nmb_name( struct nmb_name *n, const char *name, int type)
990
0
{
991
0
  fstring unix_name;
992
0
  memset( (char *)n, '\0', sizeof(struct nmb_name) );
993
0
  fstrcpy(unix_name, name);
994
0
  (void)strupper_m(unix_name);
995
0
  push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
996
0
  n->name_type = (unsigned int)type & 0xFF;
997
0
  push_ascii(n->scope,  lp_netbios_scope(), 64, STR_TERMINATE);
998
0
}
999
1000
/*******************************************************************
1001
  Compare two nmb names
1002
******************************************************************/
1003
1004
bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
1005
0
{
1006
0
  return ((n1->name_type == n2->name_type) &&
1007
0
    strequal(n1->name ,n2->name ) &&
1008
0
    strequal(n1->scope,n2->scope));
1009
0
}
1010
1011
/*******************************************************************
1012
 Build a nmb packet ready for sending.
1013
 If buf == NULL this is a length calculation.
1014
******************************************************************/
1015
1016
static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
1017
342
{
1018
342
  unsigned char *ubuf = (unsigned char *)buf;
1019
342
  int offset=0;
1020
1021
342
  if (len && len < 12) {
1022
0
    return 0;
1023
0
  }
1024
1025
  /* put in the header */
1026
342
  if (buf) {
1027
342
    RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1028
342
    ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1029
342
    if (nmb->header.response)
1030
48
      ubuf[offset+2] |= (1<<7);
1031
342
    if (nmb->header.nm_flags.authoritative &&
1032
150
        nmb->header.response)
1033
32
      ubuf[offset+2] |= 0x4;
1034
342
    if (nmb->header.nm_flags.trunc)
1035
126
      ubuf[offset+2] |= 0x2;
1036
342
    if (nmb->header.nm_flags.recursion_desired)
1037
111
      ubuf[offset+2] |= 0x1;
1038
342
    if (nmb->header.nm_flags.recursion_available &&
1039
36
        nmb->header.response)
1040
16
      ubuf[offset+3] |= 0x80;
1041
342
    if (nmb->header.nm_flags.bcast)
1042
82
      ubuf[offset+3] |= 0x10;
1043
342
    ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1044
1045
342
    RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1046
342
    RSSVAL(ubuf,offset+6,nmb->header.ancount);
1047
342
    RSSVAL(ubuf,offset+8,nmb->header.nscount);
1048
342
    RSSVAL(ubuf,offset+10,nmb->header.arcount);
1049
342
  }
1050
1051
342
  offset += 12;
1052
342
  if (nmb->header.qdcount) {
1053
    /* XXXX this doesn't handle a qdcount of > 1 */
1054
108
    if (len) {
1055
      /* Length check. */
1056
108
      int extra = put_nmb_name(NULL,0,offset,
1057
108
          &nmb->question.question_name);
1058
108
      if (offset + extra > len) {
1059
0
        return 0;
1060
0
      }
1061
108
    }
1062
108
    offset += put_nmb_name((char *)ubuf,len,offset,
1063
108
        &nmb->question.question_name);
1064
108
    if (buf) {
1065
108
      RSSVAL(ubuf,offset,nmb->question.question_type);
1066
108
      RSSVAL(ubuf,offset+2,nmb->question.question_class);
1067
108
    }
1068
108
    offset += 4;
1069
108
  }
1070
1071
342
  if (nmb->header.ancount) {
1072
122
    if (len) {
1073
      /* Length check. */
1074
122
      int extra = put_res_rec(NULL,0,offset,nmb->answers,
1075
122
          nmb->header.ancount);
1076
122
      if (offset + extra > len) {
1077
0
        return 0;
1078
0
      }
1079
122
    }
1080
122
    offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1081
122
        nmb->header.ancount);
1082
122
  }
1083
1084
342
  if (nmb->header.nscount) {
1085
109
    if (len) {
1086
      /* Length check. */
1087
109
      int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1088
109
        nmb->header.nscount);
1089
109
      if (offset + extra > len) {
1090
0
        return 0;
1091
0
      }
1092
109
    }
1093
109
    offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1094
109
        nmb->header.nscount);
1095
109
  }
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
342
  if((nmb->header.response == False) &&
1105
294
    ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1106
269
    (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1107
223
    (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1108
199
    (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1109
183
    (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1110
124
    (nmb->header.arcount == 1)) {
1111
1112
35
    if (len) {
1113
      /* Length check. */
1114
35
      int extra = put_compressed_name_ptr(NULL,offset,
1115
35
          nmb->additional,12);
1116
35
      if (offset + extra > len) {
1117
0
        return 0;
1118
0
      }
1119
35
    }
1120
35
    offset += put_compressed_name_ptr(ubuf,offset,
1121
35
        nmb->additional,12);
1122
307
  } else if (nmb->header.arcount) {
1123
122
    if (len) {
1124
      /* Length check. */
1125
122
      int extra = put_res_rec(NULL,0,offset,nmb->additional,
1126
122
        nmb->header.arcount);
1127
122
      if (offset + extra > len) {
1128
0
        return 0;
1129
0
      }
1130
122
    }
1131
122
    offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1132
122
      nmb->header.arcount);
1133
122
  }
1134
342
  return offset;
1135
342
}
1136
1137
/*******************************************************************
1138
 Linearise a packet.
1139
******************************************************************/
1140
1141
int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1142
342
{
1143
342
  int len = 0;
1144
1145
342
  switch (p->packet_type) {
1146
342
  case NMB_PACKET:
1147
342
    len = build_nmb(buf,buflen,&p->packet.nmb);
1148
342
    break;
1149
1150
0
  case DGRAM_PACKET:
1151
0
    len = build_dgram(buf,buflen,&p->packet.dgram);
1152
0
    break;
1153
342
  }
1154
1155
342
  return len;
1156
342
}
1157
1158
/*******************************************************************
1159
 Send a packet_struct.
1160
******************************************************************/
1161
1162
bool send_packet(struct packet_struct *p)
1163
0
{
1164
0
  char buf[1024];
1165
0
  int len=0;
1166
1167
0
  memset(buf,'\0',sizeof(buf));
1168
1169
0
  len = build_packet(buf, sizeof(buf), p);
1170
1171
0
  if (!len)
1172
0
    return(False);
1173
1174
0
  return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1175
0
}
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
bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1188
0
{
1189
0
  struct dgram_packet *dgram = &p->packet.dgram;
1190
0
  char *buf;
1191
1192
0
  buf = &dgram->data[0];
1193
0
  buf -= 4;
1194
1195
0
  buf = smb_buf(buf);
1196
1197
0
  if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1198
0
    return True;
1199
0
  }
1200
1201
0
  return False;
1202
0
}
1203
1204
/****************************************************************************
1205
 Return the number of bits that match between two len character buffers
1206
***************************************************************************/
1207
1208
int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1209
0
{
1210
0
  size_t i, j;
1211
0
  int ret = 0;
1212
0
  for (i=0; i<len; i++) {
1213
0
    if (p1[i] != p2[i])
1214
0
      break;
1215
0
    ret += 8;
1216
0
  }
1217
1218
0
  if (i==len)
1219
0
    return ret;
1220
1221
0
  for (j=0; j<8; j++) {
1222
0
    if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1223
0
      break;
1224
0
    ret++;
1225
0
  }
1226
1227
0
  return ret;
1228
0
}
1229
1230
static unsigned char sort_ip[4];
1231
1232
/****************************************************************************
1233
 Compare two query reply records.
1234
***************************************************************************/
1235
1236
static int name_query_comp(unsigned char *p1, unsigned char *p2)
1237
0
{
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
0
}
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
void sort_query_replies(char *data, int n, struct in_addr ip)
1250
0
{
1251
0
  if (n <= 1)
1252
0
    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
0
}
1262
1263
/****************************************************************************
1264
 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1265
 Returns -1 on error.
1266
****************************************************************************/
1267
1268
static int name_interpret(unsigned char *buf, size_t buf_len,
1269
    unsigned char *in, fstring name)
1270
0
{
1271
0
  unsigned char *end_ptr = buf + buf_len;
1272
0
  int ret;
1273
0
  unsigned int len;
1274
0
  fstring out_string;
1275
0
  unsigned char *out = (unsigned char *)out_string;
1276
1277
0
  *out=0;
1278
1279
0
  if (in >= end_ptr) {
1280
0
    return -1;
1281
0
  }
1282
0
  len = (*in++) / 2;
1283
1284
0
  if (len<1) {
1285
0
    return -1;
1286
0
  }
1287
1288
0
  while (len--) {
1289
0
    if (&in[1] >= end_ptr) {
1290
0
      return -1;
1291
0
    }
1292
0
    if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1293
0
      *out = 0;
1294
0
      return(0);
1295
0
    }
1296
0
    *out = ((in[0]-'A')<<4) + (in[1]-'A');
1297
0
    in += 2;
1298
0
    out++;
1299
0
    if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1300
0
      return -1;
1301
0
    }
1302
0
  }
1303
0
  ret = out[-1];
1304
0
  out[-1] = 0;
1305
1306
0
  pull_ascii_fstring(name, out_string);
1307
1308
0
  return(ret);
1309
0
}
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
char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1317
0
{
1318
0
  int   i;
1319
0
  int   len;
1320
0
  nstring buf;
1321
0
  char *result;
1322
0
  char *p;
1323
1324
0
  result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1325
0
  if (result == NULL) {
1326
0
    return NULL;
1327
0
  }
1328
0
  p = result;
1329
1330
  /* Safely copy the input string, In, into buf[]. */
1331
0
  if (strcmp(In,"*") == 0)
1332
0
    put_name(buf, "*", '\0', 0x00);
1333
0
  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
0
    pull_ascii_fstring(buf_unix, In);
1340
0
    if (!strupper_m(buf_unix)) {
1341
0
      return NULL;
1342
0
    }
1343
1344
0
    push_ascii_nstring(buf_dos, buf_unix);
1345
0
    put_name(buf, buf_dos, ' ', name_type);
1346
0
  }
1347
1348
  /* Place the length of the first field into the output buffer. */
1349
0
  p[0] = 32;
1350
0
  p++;
1351
1352
  /* Now convert the name to the rfc1001/1002 format. */
1353
0
  for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1354
0
    p[i*2]     = ( (buf[i] >> 4) & 0x000F ) + 'A';
1355
0
    p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1356
0
  }
1357
0
  p += 32;
1358
0
  p[0] = '\0';
1359
1360
  /* Add the scope string. */
1361
0
  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
0
    }
1377
0
  }
1378
1379
0
  return result;
1380
0
}
1381
1382
/****************************************************************************
1383
 Find a pointer to a netbios name.
1384
****************************************************************************/
1385
1386
static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1387
0
{
1388
0
  unsigned char c = 0;
1389
1390
0
  if (ofs > buf_len || buf_len < 1) {
1391
0
    return NULL;
1392
0
  }
1393
1394
0
  c = *(unsigned char *)(buf+ofs);
1395
0
  if ((c & 0xC0) == 0xC0) {
1396
0
    uint16_t l = 0;
1397
1398
0
    if (ofs > buf_len - 1) {
1399
0
      return NULL;
1400
0
    }
1401
0
    l = RSVAL(buf, ofs) & 0x3FFF;
1402
0
    if (l > buf_len) {
1403
0
      return NULL;
1404
0
    }
1405
0
    DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1406
0
    return(buf + l);
1407
0
  } else {
1408
0
    return(buf+ofs);
1409
0
  }
1410
0
}
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
int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1418
0
{
1419
0
  unsigned char *p = name_ptr(buf,buf_len,ofs);
1420
1421
0
  name[0] = '\0';
1422
0
  if (p == NULL) {
1423
0
    return -1;
1424
0
  }
1425
0
  return(name_interpret(buf,buf_len,p,name));
1426
0
}
1427
1428
/****************************************************************************
1429
 Return the total storage length of a mangled name.
1430
 Returns -1 on error.
1431
****************************************************************************/
1432
1433
int name_len(unsigned char *s1, size_t buf_len)
1434
0
{
1435
  /* NOTE: this argument _must_ be unsigned */
1436
0
  unsigned char *s = (unsigned char *)s1;
1437
0
  int len = 0;
1438
1439
0
  if (buf_len < 1) {
1440
0
    return -1;
1441
0
  }
1442
  /* If the two high bits of the byte are set, return 2. */
1443
0
  if (0xC0 == (*s & 0xC0)) {
1444
0
    if (buf_len < 2) {
1445
0
      return -1;
1446
0
    }
1447
0
    return(2);
1448
0
  }
1449
1450
  /* Add up the length bytes. */
1451
0
  for (len = 1; (*s); s += (*s) + 1) {
1452
0
    len += *s + 1;
1453
0
    if (len > buf_len) {
1454
0
      return -1;
1455
0
    }
1456
0
  }
1457
1458
0
  return(len);
1459
0
}
1460
1461
/*******************************************************************
1462
 Setup the word count and byte count for a client smb message.
1463
********************************************************************/
1464
1465
int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
1466
0
{
1467
0
  if (zero && (num_words || num_bytes)) {
1468
0
    memset(buf + smb_size,'\0',num_words*2 + num_bytes);
1469
0
  }
1470
0
  SCVAL(buf,smb_wct,num_words);
1471
0
  SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1472
0
  smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1473
0
  return (smb_size + num_words*2 + num_bytes);
1474
0
}