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 897 : const char *global_nmbd_socket_dir(void)
27 : {
28 897 : 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 4911 : static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
68 : {
69 0 : int i, j;
70 :
71 4911 : 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 4911 : if (res->rdlength == 0) {
79 0 : return;
80 : }
81 :
82 11188 : for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
83 6277 : DEBUGADD(4, (" %s %3x char ", hdr, i));
84 :
85 57543 : for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
86 56177 : unsigned char x = res->rdata[i+j];
87 56177 : if (x < 32 || x > 127)
88 30659 : x = '.';
89 :
90 56177 : if (i+j >= res->rdlength)
91 4911 : break;
92 51266 : DEBUGADD(4, ("%c", x));
93 : }
94 :
95 6277 : DEBUGADD(4, (" hex "));
96 :
97 57543 : for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
98 56177 : if (i+j >= res->rdlength)
99 4911 : break;
100 51266 : DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
101 : }
102 :
103 6277 : DEBUGADD(4, ("\n"));
104 : }
105 : }
106 :
107 : /****************************************************************************
108 : Process a nmb packet.
109 : ****************************************************************************/
110 :
111 9359 : void debug_nmb_packet(struct packet_struct *p)
112 : {
113 9359 : struct nmb_packet *nmb = &p->packet.nmb;
114 :
115 9359 : 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 9359 : if (nmb->header.qdcount) {
140 7980 : 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 9359 : if (nmb->answers && nmb->header.ancount) {
147 1379 : debug_nmb_res_rec(nmb->answers,"answers");
148 : }
149 9359 : if (nmb->nsrecs && nmb->header.nscount) {
150 0 : debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
151 : }
152 9359 : if (nmb->additional && nmb->header.arcount) {
153 3532 : debug_nmb_res_rec(nmb->additional,"additional");
154 : }
155 9359 : }
156 :
157 : /*******************************************************************
158 : Handle "compressed" name pointers.
159 : ******************************************************************/
160 :
161 17497 : static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
162 : bool *got_pointer,int *ret)
163 : {
164 17497 : int loop_count=0;
165 :
166 21769 : while ((ubuf[*offset] & 0xC0) == 0xC0) {
167 4272 : if (!*got_pointer)
168 4272 : (*ret) += 2;
169 4272 : (*got_pointer)=True;
170 4272 : if (*offset > length - 2) {
171 0 : return False;
172 : }
173 4272 : (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
174 4272 : if (loop_count++ == 10 ||
175 4272 : (*offset) < 0 || (*offset)>(length-2)) {
176 0 : return False;
177 : }
178 : }
179 17497 : 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 17497 : static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
188 : {
189 17497 : size_t m,n=0;
190 17497 : unsigned char *ubuf = (unsigned char *)inbuf;
191 17497 : int ret = 0;
192 17497 : bool got_pointer=False;
193 17497 : size_t loop_count=0;
194 17497 : int offset = ofs;
195 :
196 17497 : if (length - offset < 2)
197 0 : return(0);
198 :
199 : /* handle initial name pointers */
200 17497 : if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
201 0 : return(0);
202 :
203 17497 : m = ubuf[offset];
204 :
205 : /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
206 17497 : if (m != 32) {
207 0 : return 0;
208 : }
209 : /* Cannot go past length. */
210 17497 : if (offset+m+2 > length) {
211 0 : return 0;
212 : }
213 :
214 17497 : memset((char *)name,'\0',sizeof(*name));
215 :
216 : /* the "compressed" part */
217 17497 : if (!got_pointer)
218 13225 : ret += m + 2;
219 17497 : offset++;
220 297449 : while (m > 0) {
221 0 : unsigned char c1,c2;
222 279952 : c1 = ubuf[offset++]-'A';
223 279952 : c2 = ubuf[offset++]-'A';
224 279952 : if ((c1 & 0xF0) || (c2 & 0xF0)) {
225 0 : return(0);
226 : }
227 279952 : if (n >= sizeof(name->name)) {
228 0 : return 0;
229 : }
230 279952 : name->name[n++] = (c1<<4) | c2;
231 279952 : 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 17497 : 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 17497 : name->name_type = ((unsigned char)name->name[15]) & 0xff;
244 :
245 : /* remove trailing spaces */
246 17497 : name->name[15] = 0;
247 17497 : n = 14;
248 96180 : while (n && name->name[n]==' ')
249 78683 : name->name[n--] = 0;
250 :
251 : /* now the domain parts (if any) */
252 17497 : n = 0;
253 17497 : 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 17497 : name->scope[n++] = 0;
281 :
282 17497 : 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 9882 : void put_name(char *dest, const char *name, int pad, unsigned int name_type)
292 : {
293 9882 : size_t len = strlen(name);
294 :
295 9882 : memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
296 : len : MAX_NETBIOSNAME_LEN - 1);
297 9882 : if (len < MAX_NETBIOSNAME_LEN - 1) {
298 8650 : memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
299 : }
300 9882 : dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
301 9882 : }
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 7786 : 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 7786 : if (strcmp(name->name,"*") == 0) {
321 : /* special case for wildcard name */
322 104 : put_name(buf1, "*", '\0', name->name_type);
323 : } else {
324 7682 : put_name(buf1, name->name, ' ', name->name_type);
325 : }
326 :
327 7786 : if (buf) {
328 4573 : if (offset >= buflen) {
329 0 : return 0;
330 : }
331 4573 : buf[offset] = 0x20;
332 : }
333 :
334 7786 : ret = 34;
335 :
336 132362 : for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
337 124576 : if (buf) {
338 73168 : if (offset+2+2*m >= buflen) {
339 0 : return 0;
340 : }
341 73168 : buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
342 73168 : buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
343 : }
344 : }
345 7786 : offset += 33;
346 :
347 7786 : if (buf) {
348 4573 : if (offset >= buflen) {
349 0 : return 0;
350 : }
351 4573 : buf[offset] = 0;
352 : }
353 :
354 7786 : 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 7786 : 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 4748 : 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 4748 : *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
412 4748 : if (!*recs)
413 0 : return(False);
414 :
415 4748 : memset((char *)*recs,'\0',sizeof(**recs)*count);
416 :
417 9496 : for (i=0;i<count;i++) {
418 4748 : int l = parse_nmb_name(inbuf,*offset,length,
419 4748 : &(*recs)[i].rr_name);
420 4748 : (*offset) += l;
421 4748 : if (!l || (*offset)+10 > length) {
422 0 : SAFE_FREE(*recs);
423 0 : return(False);
424 : }
425 4748 : (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
426 4748 : (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
427 4748 : (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
428 4748 : (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
429 4748 : (*offset) += 10;
430 4748 : if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
431 4748 : (*offset)+(*recs)[i].rdlength > length) {
432 0 : SAFE_FREE(*recs);
433 0 : return(False);
434 : }
435 4748 : memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
436 4748 : (*offset) += (*recs)[i].rdlength;
437 : }
438 4748 : 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 1762 : static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
447 : {
448 1762 : int ret=0;
449 0 : int i;
450 :
451 3524 : for (i=0;i<count;i++) {
452 1762 : int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
453 1762 : offset += l;
454 1762 : ret += l;
455 1762 : if (buf) {
456 881 : RSSVAL(buf,offset,recs[i].rr_type);
457 881 : RSSVAL(buf,offset+2,recs[i].rr_class);
458 881 : RSIVAL(buf,offset+4,(unsigned int)recs[i].ttl);
459 881 : RSSVAL(buf,offset+8,recs[i].rdlength);
460 881 : memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
461 : }
462 1762 : offset += 10+recs[i].rdlength;
463 1762 : ret += 10+recs[i].rdlength;
464 : }
465 :
466 1762 : 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 2514 : static int put_compressed_name_ptr(unsigned char *buf,
475 : int offset,
476 : struct res_rec *rec,
477 : int ptr_offset)
478 : {
479 2514 : int ret=offset;
480 2514 : if (buf) {
481 1257 : buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
482 1257 : buf[offset+1] = (ptr_offset & 0xFF);
483 : }
484 2514 : offset += 2;
485 2514 : if (buf) {
486 1257 : RSSVAL(buf,offset,rec->rr_type);
487 1257 : RSSVAL(buf,offset+2,rec->rr_class);
488 1257 : RSIVAL(buf,offset+4,rec->ttl);
489 1257 : RSSVAL(buf,offset+8,rec->rdlength);
490 1257 : memcpy(buf+offset+10,rec->rdata,rec->rdlength);
491 : }
492 2514 : offset += 10+rec->rdlength;
493 2514 : ret = (offset - ret);
494 :
495 2514 : 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 1963 : static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
506 : {
507 0 : size_t offset;
508 0 : int flags;
509 :
510 1963 : memset((char *)dgram,'\0',sizeof(*dgram));
511 :
512 1963 : if (length < 14)
513 0 : return(False);
514 :
515 1963 : dgram->header.msg_type = CVAL(inbuf,0);
516 1963 : flags = CVAL(inbuf,1);
517 1963 : dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
518 1963 : if (flags & 1)
519 0 : dgram->header.flags.more = True;
520 1963 : if (flags & 2)
521 1963 : dgram->header.flags.first = True;
522 1963 : dgram->header.dgm_id = RSVAL(inbuf,2);
523 1963 : putip((char *)&dgram->header.source_ip,inbuf+4);
524 1963 : dgram->header.source_port = RSVAL(inbuf,8);
525 1963 : dgram->header.dgm_length = RSVAL(inbuf,10);
526 1963 : dgram->header.packet_offset = RSVAL(inbuf,12);
527 :
528 1963 : offset = 14;
529 :
530 1963 : if (dgram->header.msg_type == 0x10 ||
531 1919 : dgram->header.msg_type == 0x11 ||
532 0 : dgram->header.msg_type == 0x12) {
533 1963 : offset += parse_nmb_name(inbuf,offset,length,
534 : &dgram->source_name);
535 1963 : offset += parse_nmb_name(inbuf,offset,length,
536 : &dgram->dest_name);
537 : }
538 :
539 1963 : if (offset >= length || (length-offset > sizeof(dgram->data)))
540 0 : return(False);
541 :
542 1963 : dgram->datasize = length-offset;
543 1963 : 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 1963 : SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
549 1963 : memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
550 :
551 1963 : 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 9301 : static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
560 : {
561 0 : int nm_flags,offset;
562 :
563 9301 : memset((char *)nmb,'\0',sizeof(*nmb));
564 :
565 9301 : if (length < 12)
566 0 : return(False);
567 :
568 : /* parse the header */
569 9301 : nmb->header.name_trn_id = RSVAL(inbuf,0);
570 :
571 9301 : DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
572 :
573 9301 : nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
574 9301 : nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
575 9301 : nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
576 9301 : nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
577 9301 : nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
578 9301 : nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
579 9301 : nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
580 9301 : nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
581 9301 : nmb->header.rcode = CVAL(inbuf,3) & 0xF;
582 9301 : nmb->header.qdcount = RSVAL(inbuf,4);
583 9301 : nmb->header.ancount = RSVAL(inbuf,6);
584 9301 : nmb->header.nscount = RSVAL(inbuf,8);
585 9301 : nmb->header.arcount = RSVAL(inbuf,10);
586 :
587 9301 : if (nmb->header.qdcount) {
588 8823 : offset = parse_nmb_name(inbuf,12,length,
589 : &nmb->question.question_name);
590 8823 : if (!offset)
591 0 : return(False);
592 :
593 8823 : if (length - (12+offset) < 4)
594 0 : return(False);
595 8823 : nmb->question.question_type = RSVAL(inbuf,12+offset);
596 8823 : nmb->question.question_class = RSVAL(inbuf,12+offset+2);
597 :
598 8823 : offset += 12+4;
599 : } else {
600 478 : offset = 12;
601 : }
602 :
603 : /* and any resource records */
604 9301 : if (nmb->header.ancount &&
605 478 : !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
606 : nmb->header.ancount))
607 0 : return(False);
608 :
609 9301 : 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 9301 : if (nmb->header.arcount &&
615 4270 : !parse_alloc_res_rec(inbuf,&offset,length,
616 : &nmb->additional, nmb->header.arcount))
617 0 : return(False);
618 :
619 9301 : return(True);
620 : }
621 :
622 : /*******************************************************************
623 : 'Copy constructor' for an nmb packet.
624 : ******************************************************************/
625 :
626 10 : 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 10 : 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 10 : *pkt_copy = *packet;
640 :
641 : /* Ensure this copy is not locked. */
642 10 : pkt_copy->locked = False;
643 10 : pkt_copy->recv_fd = -1;
644 10 : pkt_copy->send_fd = -1;
645 :
646 : /* Ensure this copy has no resource records. */
647 10 : nmb = &packet->packet.nmb;
648 10 : copy_nmb = &pkt_copy->packet.nmb;
649 :
650 10 : copy_nmb->answers = NULL;
651 10 : copy_nmb->nsrecs = NULL;
652 10 : copy_nmb->additional = NULL;
653 :
654 : /* Now copy any resource records. */
655 :
656 10 : if (nmb->answers) {
657 10 : if((copy_nmb->answers = SMB_MALLOC_ARRAY(
658 : struct res_rec,nmb->header.ancount)) == NULL)
659 0 : goto free_and_exit;
660 10 : memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
661 10 : nmb->header.ancount * sizeof(struct res_rec));
662 : }
663 10 : 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 10 : 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 10 : 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 12 : struct packet_struct *copy_packet(struct packet_struct *packet)
723 : {
724 12 : if(packet->packet_type == NMB_PACKET)
725 10 : 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 9708 : static void free_nmb_packet(struct nmb_packet *nmb)
736 : {
737 9708 : SAFE_FREE(nmb->answers);
738 9708 : SAFE_FREE(nmb->nsrecs);
739 9708 : SAFE_FREE(nmb->additional);
740 9708 : }
741 :
742 : /*******************************************************************
743 : Free up any resources associated with a dgram packet.
744 : ******************************************************************/
745 :
746 1965 : static void free_dgram_packet(struct dgram_packet *nmb)
747 : {
748 : /* We have nothing to do for a dgram packet. */
749 1965 : }
750 :
751 : /*******************************************************************
752 : Free up any resources associated with a packet.
753 : ******************************************************************/
754 :
755 11673 : void free_packet(struct packet_struct *packet)
756 : {
757 11673 : if (packet->locked)
758 0 : return;
759 11673 : if (packet->packet_type == NMB_PACKET)
760 9708 : free_nmb_packet(&packet->packet.nmb);
761 1965 : else if (packet->packet_type == DGRAM_PACKET)
762 1965 : free_dgram_packet(&packet->packet.dgram);
763 11673 : ZERO_STRUCTPN(packet);
764 11673 : SAFE_FREE(packet);
765 : }
766 :
767 444 : int packet_trn_id(struct packet_struct *p)
768 : {
769 0 : int result;
770 444 : switch (p->packet_type) {
771 444 : case NMB_PACKET:
772 444 : result = p->packet.nmb.header.name_trn_id;
773 444 : 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 444 : return result;
781 : }
782 :
783 : /*******************************************************************
784 : Parse a packet buffer into a packet structure.
785 : ******************************************************************/
786 :
787 11264 : 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 11264 : bool ok=False;
794 :
795 11264 : p = SMB_MALLOC_P(struct packet_struct);
796 11264 : if (!p)
797 0 : return(NULL);
798 :
799 11264 : ZERO_STRUCTP(p); /* initialize for possible padding */
800 :
801 11264 : p->next = NULL;
802 11264 : p->prev = NULL;
803 11264 : p->ip = ip;
804 11264 : p->port = port;
805 11264 : p->locked = False;
806 11264 : p->timestamp = time(NULL);
807 11264 : p->packet_type = packet_type;
808 :
809 11264 : switch (packet_type) {
810 9301 : case NMB_PACKET:
811 9301 : ok = parse_nmb(buf,length,&p->packet.nmb);
812 9301 : break;
813 :
814 1963 : case DGRAM_PACKET:
815 1963 : ok = parse_dgram(buf,length,&p->packet.dgram);
816 1963 : break;
817 : }
818 :
819 11264 : if (!ok) {
820 0 : free_packet(p);
821 0 : return NULL;
822 : }
823 :
824 11264 : return p;
825 : }
826 :
827 447 : 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 447 : pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
833 447 : if (pkt == NULL) {
834 0 : return NULL;
835 : }
836 447 : pkt->locked = false;
837 447 : pkt->recv_fd = -1;
838 447 : pkt->send_fd = -1;
839 :
840 447 : if (src->packet_type == NMB_PACKET) {
841 444 : const struct nmb_packet *nsrc = &src->packet.nmb;
842 444 : struct nmb_packet *ndst = &pkt->packet.nmb;
843 :
844 444 : if (nsrc->answers != NULL) {
845 444 : ndst->answers = talloc_memdup(
846 : pkt, nsrc->answers,
847 : sizeof(struct res_rec) * nsrc->header.ancount);
848 444 : if (ndst->answers == NULL) {
849 0 : goto fail;
850 : }
851 : }
852 444 : 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 444 : 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 447 : 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 447 : 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 447 : pkt = parse_packet(buf, length, packet_type, ip, port);
890 447 : if (pkt == NULL) {
891 0 : return NULL;
892 : }
893 447 : result = copy_packet_talloc(mem_ctx, pkt);
894 447 : free_packet(pkt);
895 447 : return result;
896 : }
897 :
898 : /*******************************************************************
899 : Send a udp packet on a already open socket.
900 : ******************************************************************/
901 :
902 2998 : static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
903 : {
904 2998 : bool ret = False;
905 0 : int i;
906 0 : struct sockaddr_in sock_out;
907 :
908 : /* set the address and port */
909 2998 : memset((char *)&sock_out,'\0',sizeof(sock_out));
910 2998 : putip((char *)&sock_out.sin_addr,(char *)&ip);
911 2998 : sock_out.sin_port = htons( port );
912 2998 : sock_out.sin_family = AF_INET;
913 :
914 2998 : 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 3015 : for (i = 0; i < 5; i++) {
922 3015 : ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
923 : sizeof(sock_out)) >= 0);
924 3015 : if (ret || errno != ECONNREFUSED)
925 : break;
926 : }
927 :
928 2998 : if (!ret)
929 63 : DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
930 : inet_ntoa(ip),port,strerror(errno)));
931 :
932 2998 : 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 680 : static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
941 : {
942 680 : unsigned char *ubuf = (unsigned char *)buf;
943 680 : int offset=0;
944 :
945 : /* put in the header */
946 680 : if (buf) {
947 680 : ubuf[0] = dgram->header.msg_type;
948 680 : ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
949 680 : if (dgram->header.flags.more)
950 0 : ubuf[1] |= 1;
951 680 : if (dgram->header.flags.first)
952 680 : ubuf[1] |= 2;
953 680 : RSSVAL(ubuf,2,dgram->header.dgm_id);
954 680 : putip(ubuf+4,(char *)&dgram->header.source_ip);
955 680 : RSSVAL(ubuf,8,dgram->header.source_port);
956 680 : RSSVAL(ubuf,12,dgram->header.packet_offset);
957 : }
958 :
959 680 : offset = 14;
960 :
961 680 : if (dgram->header.msg_type == 0x10 ||
962 623 : dgram->header.msg_type == 0x11 ||
963 0 : dgram->header.msg_type == 0x12) {
964 680 : offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
965 680 : offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
966 : }
967 :
968 680 : if (buf) {
969 680 : memcpy(ubuf+offset,dgram->data,dgram->datasize);
970 : }
971 680 : 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 680 : dgram->header.dgm_length = (offset - 14);
978 680 : if (buf) {
979 680 : RSSVAL(ubuf,10,dgram->header.dgm_length);
980 : }
981 :
982 680 : return offset;
983 : }
984 :
985 : /*******************************************************************
986 : Build a nmb name
987 : *******************************************************************/
988 :
989 6797 : void make_nmb_name( struct nmb_name *n, const char *name, int type)
990 : {
991 0 : fstring unix_name;
992 6797 : memset( (char *)n, '\0', sizeof(struct nmb_name) );
993 6797 : fstrcpy(unix_name, name);
994 6797 : (void)strupper_m(unix_name);
995 6797 : push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
996 6797 : n->name_type = (unsigned int)type & 0xFF;
997 6797 : push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE);
998 6797 : }
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 3213 : static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
1017 : {
1018 3213 : unsigned char *ubuf = (unsigned char *)buf;
1019 3213 : int offset=0;
1020 :
1021 3213 : if (len && len < 12) {
1022 0 : return 0;
1023 : }
1024 :
1025 : /* put in the header */
1026 3213 : if (buf) {
1027 3213 : RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1028 3213 : ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1029 3213 : if (nmb->header.response)
1030 881 : ubuf[offset+2] |= (1<<7);
1031 3213 : if (nmb->header.nm_flags.authoritative &&
1032 881 : nmb->header.response)
1033 881 : ubuf[offset+2] |= 0x4;
1034 3213 : if (nmb->header.nm_flags.trunc)
1035 0 : ubuf[offset+2] |= 0x2;
1036 3213 : if (nmb->header.nm_flags.recursion_desired)
1037 2968 : ubuf[offset+2] |= 0x1;
1038 3213 : if (nmb->header.nm_flags.recursion_available &&
1039 829 : nmb->header.response)
1040 829 : ubuf[offset+3] |= 0x80;
1041 3213 : if (nmb->header.nm_flags.bcast)
1042 2106 : ubuf[offset+3] |= 0x10;
1043 3213 : ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1044 :
1045 3213 : RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1046 3213 : RSSVAL(ubuf,offset+6,nmb->header.ancount);
1047 3213 : RSSVAL(ubuf,offset+8,nmb->header.nscount);
1048 3213 : RSSVAL(ubuf,offset+10,nmb->header.arcount);
1049 : }
1050 :
1051 3213 : offset += 12;
1052 3213 : if (nmb->header.qdcount) {
1053 : /* XXXX this doesn't handle a qdcount of > 1 */
1054 2332 : if (len) {
1055 : /* Length check. */
1056 2332 : int extra = put_nmb_name(NULL,0,offset,
1057 : &nmb->question.question_name);
1058 2332 : if (offset + extra > len) {
1059 0 : return 0;
1060 : }
1061 : }
1062 2332 : offset += put_nmb_name((char *)ubuf,len,offset,
1063 : &nmb->question.question_name);
1064 2332 : if (buf) {
1065 2332 : RSSVAL(ubuf,offset,nmb->question.question_type);
1066 2332 : RSSVAL(ubuf,offset+2,nmb->question.question_class);
1067 : }
1068 2332 : offset += 4;
1069 : }
1070 :
1071 3213 : if (nmb->header.ancount) {
1072 881 : if (len) {
1073 : /* Length check. */
1074 881 : int extra = put_res_rec(NULL,0,offset,nmb->answers,
1075 : nmb->header.ancount);
1076 881 : if (offset + extra > len) {
1077 0 : return 0;
1078 : }
1079 : }
1080 881 : offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1081 : nmb->header.ancount);
1082 : }
1083 :
1084 3213 : 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 3213 : if((nmb->header.response == False) &&
1105 2332 : ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1106 1079 : (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1107 1075 : (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1108 1075 : (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1109 1075 : (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1110 1257 : (nmb->header.arcount == 1)) {
1111 :
1112 1257 : if (len) {
1113 : /* Length check. */
1114 1257 : int extra = put_compressed_name_ptr(NULL,offset,
1115 : nmb->additional,12);
1116 1257 : if (offset + extra > len) {
1117 0 : return 0;
1118 : }
1119 : }
1120 1257 : offset += put_compressed_name_ptr(ubuf,offset,
1121 1257 : nmb->additional,12);
1122 1956 : } 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 3213 : return offset;
1135 : }
1136 :
1137 : /*******************************************************************
1138 : Linearise a packet.
1139 : ******************************************************************/
1140 :
1141 3893 : int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1142 : {
1143 3893 : int len = 0;
1144 :
1145 3893 : switch (p->packet_type) {
1146 3213 : case NMB_PACKET:
1147 3213 : len = build_nmb(buf,buflen,&p->packet.nmb);
1148 3213 : break;
1149 :
1150 680 : case DGRAM_PACKET:
1151 680 : len = build_dgram(buf,buflen,&p->packet.dgram);
1152 680 : break;
1153 : }
1154 :
1155 3893 : return len;
1156 : }
1157 :
1158 : /*******************************************************************
1159 : Send a packet_struct.
1160 : ******************************************************************/
1161 :
1162 2998 : bool send_packet(struct packet_struct *p)
1163 : {
1164 0 : char buf[1024];
1165 2998 : int len=0;
1166 :
1167 2998 : memset(buf,'\0',sizeof(buf));
1168 :
1169 2998 : len = build_packet(buf, sizeof(buf), p);
1170 :
1171 2998 : if (!len)
1172 0 : return(False);
1173 :
1174 2998 : 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 31 : bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1188 : {
1189 31 : struct dgram_packet *dgram = &p->packet.dgram;
1190 0 : char *buf;
1191 :
1192 31 : buf = &dgram->data[0];
1193 31 : buf -= 4;
1194 :
1195 31 : buf = smb_buf(buf);
1196 :
1197 31 : if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1198 31 : return True;
1199 : }
1200 :
1201 0 : 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 : return matching_len_bits(p2+2, sort_ip, 4) -
1239 0 : matching_len_bits(p1+2, sort_ip, 4);
1240 : }
1241 :
1242 : /****************************************************************************
1243 : Sort a set of 6 byte name query response records so that the IPs that
1244 : have the most leading bits in common with the specified address come first.
1245 : ***************************************************************************/
1246 :
1247 827 : void sort_query_replies(char *data, int n, struct in_addr ip)
1248 : {
1249 827 : if (n <= 1)
1250 827 : return;
1251 :
1252 0 : putip(sort_ip, (char *)&ip);
1253 :
1254 : /* TODO:
1255 : this can't use TYPESAFE_QSORT() as the types are wrong.
1256 : It should be fixed to use a real type instead of char*
1257 : */
1258 0 : qsort(data, n, 6, QSORT_CAST name_query_comp);
1259 : }
1260 :
1261 : /****************************************************************************
1262 : Interpret the weird netbios "name" into a unix fstring. Return the name type.
1263 : Returns -1 on error.
1264 : ****************************************************************************/
1265 :
1266 2076 : static int name_interpret(unsigned char *buf, size_t buf_len,
1267 : unsigned char *in, fstring name)
1268 : {
1269 2076 : unsigned char *end_ptr = buf + buf_len;
1270 0 : int ret;
1271 0 : unsigned int len;
1272 0 : fstring out_string;
1273 2076 : unsigned char *out = (unsigned char *)out_string;
1274 :
1275 2076 : *out=0;
1276 :
1277 2076 : if (in >= end_ptr) {
1278 0 : return -1;
1279 : }
1280 2076 : len = (*in++) / 2;
1281 :
1282 2076 : if (len<1) {
1283 0 : return -1;
1284 : }
1285 :
1286 35292 : while (len--) {
1287 33216 : if (&in[1] >= end_ptr) {
1288 0 : return -1;
1289 : }
1290 33216 : if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1291 0 : *out = 0;
1292 0 : return(0);
1293 : }
1294 33216 : *out = ((in[0]-'A')<<4) + (in[1]-'A');
1295 33216 : in += 2;
1296 33216 : out++;
1297 33216 : if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1298 0 : return -1;
1299 : }
1300 : }
1301 2076 : ret = out[-1];
1302 2076 : out[-1] = 0;
1303 :
1304 2076 : pull_ascii_fstring(name, out_string);
1305 :
1306 2076 : return(ret);
1307 : }
1308 :
1309 : /****************************************************************************
1310 : Mangle a name into netbios format.
1311 : Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1312 : ****************************************************************************/
1313 :
1314 2096 : char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1315 : {
1316 0 : int i;
1317 0 : int len;
1318 0 : nstring buf;
1319 0 : char *result;
1320 0 : char *p;
1321 :
1322 2096 : result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1323 2096 : if (result == NULL) {
1324 0 : return NULL;
1325 : }
1326 2096 : p = result;
1327 :
1328 : /* Safely copy the input string, In, into buf[]. */
1329 2096 : if (strcmp(In,"*") == 0)
1330 0 : put_name(buf, "*", '\0', 0x00);
1331 : else {
1332 : /* We use an fstring here as mb dos names can expend x3 when
1333 : going to utf8. */
1334 0 : fstring buf_unix;
1335 0 : nstring buf_dos;
1336 :
1337 2096 : pull_ascii_fstring(buf_unix, In);
1338 2096 : if (!strupper_m(buf_unix)) {
1339 0 : return NULL;
1340 : }
1341 :
1342 2096 : push_ascii_nstring(buf_dos, buf_unix);
1343 2096 : put_name(buf, buf_dos, ' ', name_type);
1344 : }
1345 :
1346 : /* Place the length of the first field into the output buffer. */
1347 2096 : p[0] = 32;
1348 2096 : p++;
1349 :
1350 : /* Now convert the name to the rfc1001/1002 format. */
1351 35632 : for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1352 33536 : p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1353 33536 : p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1354 : }
1355 2096 : p += 32;
1356 2096 : p[0] = '\0';
1357 :
1358 : /* Add the scope string. */
1359 2096 : for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1360 0 : switch( (lp_netbios_scope())[i] ) {
1361 0 : case '\0':
1362 0 : p[0] = len;
1363 0 : if( len > 0 )
1364 0 : p[len+1] = 0;
1365 0 : return result;
1366 0 : case '.':
1367 0 : p[0] = len;
1368 0 : p += (len + 1);
1369 0 : len = -1;
1370 0 : break;
1371 0 : default:
1372 0 : p[len+1] = (lp_netbios_scope())[i];
1373 0 : break;
1374 : }
1375 : }
1376 :
1377 2096 : return result;
1378 : }
1379 :
1380 : /****************************************************************************
1381 : Find a pointer to a netbios name.
1382 : ****************************************************************************/
1383 :
1384 2076 : static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1385 : {
1386 2076 : unsigned char c = 0;
1387 :
1388 2076 : if (ofs > buf_len || buf_len < 1) {
1389 0 : return NULL;
1390 : }
1391 :
1392 2076 : c = *(unsigned char *)(buf+ofs);
1393 2076 : if ((c & 0xC0) == 0xC0) {
1394 0 : uint16_t l = 0;
1395 :
1396 0 : if (ofs > buf_len - 1) {
1397 0 : return NULL;
1398 : }
1399 0 : l = RSVAL(buf, ofs) & 0x3FFF;
1400 0 : if (l > buf_len) {
1401 0 : return NULL;
1402 : }
1403 0 : DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1404 0 : return(buf + l);
1405 : } else {
1406 2076 : return(buf+ofs);
1407 : }
1408 : }
1409 :
1410 : /****************************************************************************
1411 : Extract a netbios name from a buf (into a unix string) return name type.
1412 : Returns -1 on error.
1413 : ****************************************************************************/
1414 :
1415 2076 : int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1416 : {
1417 2076 : unsigned char *p = name_ptr(buf,buf_len,ofs);
1418 :
1419 2076 : name[0] = '\0';
1420 2076 : if (p == NULL) {
1421 0 : return -1;
1422 : }
1423 2076 : return(name_interpret(buf,buf_len,p,name));
1424 : }
1425 :
1426 : /****************************************************************************
1427 : Return the total storage length of a mangled name.
1428 : Returns -1 on error.
1429 : ****************************************************************************/
1430 :
1431 4180 : int name_len(unsigned char *s1, size_t buf_len)
1432 : {
1433 : /* NOTE: this argument _must_ be unsigned */
1434 4180 : unsigned char *s = (unsigned char *)s1;
1435 4180 : int len = 0;
1436 :
1437 4180 : if (buf_len < 1) {
1438 0 : return -1;
1439 : }
1440 : /* If the two high bits of the byte are set, return 2. */
1441 4180 : if (0xC0 == (*s & 0xC0)) {
1442 0 : if (buf_len < 2) {
1443 0 : return -1;
1444 : }
1445 0 : return(2);
1446 : }
1447 :
1448 : /* Add up the length bytes. */
1449 8356 : for (len = 1; (*s); s += (*s) + 1) {
1450 4180 : len += *s + 1;
1451 4180 : if (len > buf_len) {
1452 4 : return -1;
1453 : }
1454 : }
1455 :
1456 4176 : return(len);
1457 : }
1458 :
1459 : /*******************************************************************
1460 : Setup the word count and byte count for a client smb message.
1461 : ********************************************************************/
1462 :
1463 625 : int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
1464 : {
1465 625 : if (zero && (num_words || num_bytes)) {
1466 625 : memset(buf + smb_size,'\0',num_words*2 + num_bytes);
1467 : }
1468 625 : SCVAL(buf,smb_wct,num_words);
1469 625 : SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1470 625 : smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1471 625 : return (smb_size + num_words*2 + num_bytes);
1472 : }
|