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