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