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