1/* 2 Unix SMB/CIFS implementation. 3 NBT netbios routines and daemon - version 2 4 Copyright (C) Andrew Tridgell 1994-1998 5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998 6 Copyright (C) Jeremy Allison 1994-2003 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 22 This file contains all the code to process NetBIOS requests coming 23 in on port 137. It does not deal with the code needed to service 24 WINS server requests, but only broadcast and unicast requests. 25 26*/ 27 28#include "includes.h" 29 30/**************************************************************************** 31Send a name release response. 32**************************************************************************/ 33 34static void send_name_release_response(int rcode, struct packet_struct *p) 35{ 36 struct nmb_packet *nmb = &p->packet.nmb; 37 char rdata[6]; 38 39 memcpy(&rdata[0], &nmb->additional->rdata[0], 6); 40 41 reply_netbios_packet(p, /* Packet to reply to. */ 42 rcode, /* Result code. */ 43 NMB_REL, /* nmbd type code. */ 44 NMB_NAME_RELEASE_OPCODE, /* opcode. */ 45 0, /* ttl. */ 46 rdata, /* data to send. */ 47 6); /* data length. */ 48} 49 50/**************************************************************************** 51Process a name release packet on a broadcast subnet. 52Ignore it if it's not one of our names. 53****************************************************************************/ 54 55void process_name_release_request(struct subnet_record *subrec, 56 struct packet_struct *p) 57{ 58 struct nmb_packet *nmb = &p->packet.nmb; 59 struct in_addr owner_ip; 60 struct nmb_name *question = &nmb->question.question_name; 61 unstring qname; 62 BOOL bcast = nmb->header.nm_flags.bcast; 63 uint16 nb_flags = get_nb_flags(nmb->additional->rdata); 64 BOOL group = (nb_flags & NB_GROUP) ? True : False; 65 struct name_record *namerec; 66 int rcode = 0; 67 68 putip((char *)&owner_ip,&nmb->additional->rdata[2]); 69 70 if(!bcast) { 71 /* We should only get broadcast name release packets here. 72 Anyone trying to release unicast should be going to a WINS 73 server. If the code gets here, then either we are not a wins 74 server and they sent it anyway, or we are a WINS server and 75 the request was malformed. Either way, log an error here. 76 and send an error reply back. 77 */ 78 DEBUG(0,("process_name_release_request: unicast name release request \ 79received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n", 80 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name)); 81 82 send_name_release_response(FMT_ERR, p); 83 return; 84 } 85 86 DEBUG(3,("process_name_release_request: Name release on name %s, \ 87subnet %s from owner IP %s\n", 88 nmb_namestr(&nmb->question.question_name), 89 subrec->subnet_name, inet_ntoa(owner_ip))); 90 91 /* If someone is releasing a broadcast group name, just ignore it. */ 92 if( group && !ismyip(owner_ip) ) 93 return; 94 95 /* 96 * Code to work around a bug in FTP OnNet software NBT implementation. 97 * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e> 98 * names and *don't set the group bit* !!!!! 99 */ 100 101 pull_ascii_nstring(qname, sizeof(qname), question->name); 102 if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) && 103 ((question->name_type == 0x0) || (question->name_type == 0x1e))) { 104 DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \ 105group release name %s from IP %s on subnet %s with no group bit set.\n", 106 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name )); 107 return; 108 } 109 110 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 111 112 /* We only care about someone trying to release one of our names. */ 113 if( namerec && ( (namerec->data.source == SELF_NAME) 114 || (namerec->data.source == PERMANENT_NAME) ) ) { 115 rcode = ACT_ERR; 116 DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \ 117on subnet %s being rejected as it is one of our names.\n", 118 nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name)); 119 } 120 121 if(rcode == 0) 122 return; 123 124 /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */ 125 send_name_release_response(rcode, p); 126} 127 128/**************************************************************************** 129Send a name registration response. 130**************************************************************************/ 131 132static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p) 133{ 134 struct nmb_packet *nmb = &p->packet.nmb; 135 char rdata[6]; 136 137 memcpy(&rdata[0], &nmb->additional->rdata[0], 6); 138 139 reply_netbios_packet(p, /* Packet to reply to. */ 140 rcode, /* Result code. */ 141 NMB_REG, /* nmbd type code. */ 142 NMB_NAME_REG_OPCODE, /* opcode. */ 143 ttl, /* ttl. */ 144 rdata, /* data to send. */ 145 6); /* data length. */ 146} 147 148/**************************************************************************** 149Process a name refresh request on a broadcast subnet. 150**************************************************************************/ 151 152void process_name_refresh_request(struct subnet_record *subrec, 153 struct packet_struct *p) 154{ 155 struct nmb_packet *nmb = &p->packet.nmb; 156 struct nmb_name *question = &nmb->question.question_name; 157 BOOL bcast = nmb->header.nm_flags.bcast; 158 struct in_addr from_ip; 159 160 putip((char *)&from_ip,&nmb->additional->rdata[2]); 161 162 if(!bcast) { 163 /* We should only get broadcast name refresh packets here. 164 Anyone trying to refresh unicast should be going to a WINS 165 server. If the code gets here, then either we are not a wins 166 server and they sent it anyway, or we are a WINS server and 167 the request was malformed. Either way, log an error here. 168 and send an error reply back. 169 */ 170 DEBUG(0,("process_name_refresh_request: unicast name registration request \ 171received for name %s from IP %s on subnet %s.\n", 172 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 173 DEBUG(0,("Error - should be sent to WINS server\n")); 174 175 send_name_registration_response(FMT_ERR, 0, p); 176 return; 177 } 178 179 /* Just log a message. We really don't care about broadcast name refreshes. */ 180 181 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \ 182IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 183} 184 185/**************************************************************************** 186Process a name registration request on a broadcast subnet. 187**************************************************************************/ 188 189void process_name_registration_request(struct subnet_record *subrec, 190 struct packet_struct *p) 191{ 192 struct nmb_packet *nmb = &p->packet.nmb; 193 struct nmb_name *question = &nmb->question.question_name; 194 BOOL bcast = nmb->header.nm_flags.bcast; 195 uint16 nb_flags = get_nb_flags(nmb->additional->rdata); 196 BOOL group = (nb_flags & NB_GROUP) ? True : False; 197 struct name_record *namerec = NULL; 198 int ttl = nmb->additional->ttl; 199 struct in_addr from_ip; 200 201 putip((char *)&from_ip,&nmb->additional->rdata[2]); 202 203 if(!bcast) { 204 /* We should only get broadcast name registration packets here. 205 Anyone trying to register unicast should be going to a WINS 206 server. If the code gets here, then either we are not a wins 207 server and they sent it anyway, or we are a WINS server and 208 the request was malformed. Either way, log an error here. 209 and send an error reply back. 210 */ 211 DEBUG(0,("process_name_registration_request: unicast name registration request \ 212received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n", 213 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 214 215 send_name_registration_response(FMT_ERR, 0, p); 216 return; 217 } 218 219 DEBUG(3,("process_name_registration_request: Name registration for name %s \ 220IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 221 222 /* See if the name already exists. */ 223 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 224 225 /* 226 * If the name being registered exists and is a WINS_PROXY_NAME 227 * then delete the WINS proxy name entry so we don't reply erroneously 228 * later to queries. 229 */ 230 231 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME)) { 232 remove_name_from_namelist( subrec, namerec ); 233 namerec = NULL; 234 } 235 236 if (!group) { 237 /* Unique name. */ 238 239 if( (namerec != NULL) 240 && ( (namerec->data.source == SELF_NAME) 241 || (namerec->data.source == PERMANENT_NAME) 242 || NAME_GROUP(namerec) ) ) { 243 /* No-one can register one of Samba's names, nor can they 244 register a name that's a group name as a unique name */ 245 246 send_name_registration_response(ACT_ERR, 0, p); 247 return; 248 } else if(namerec != NULL) { 249 /* Update the namelist record with the new information. */ 250 namerec->data.ip[0] = from_ip; 251 update_name_ttl(namerec, ttl); 252 253 DEBUG(3,("process_name_registration_request: Updated name record %s \ 254with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name)); 255 return; 256 } 257 } else { 258 /* Group name. */ 259 260 if( (namerec != NULL) 261 && !NAME_GROUP(namerec) 262 && ( (namerec->data.source == SELF_NAME) 263 || (namerec->data.source == PERMANENT_NAME) ) ) { 264 /* Disallow group names when we have a unique name. */ 265 send_name_registration_response(ACT_ERR, 0, p); 266 return; 267 } 268 } 269} 270 271/**************************************************************************** 272This is used to sort names for a name status into a sensible order. 273We put our own names first, then in alphabetical order. 274**************************************************************************/ 275 276static int status_compare(char *n1,char *n2) 277{ 278 unstring name1, name2; 279 int l1,l2,l3; 280 281 memset(name1, '\0', sizeof(name1)); 282 memset(name2, '\0', sizeof(name2)); 283 pull_ascii_nstring(name1, sizeof(name1), n1); 284 pull_ascii_nstring(name2, sizeof(name2), n2); 285 n1 = name1; 286 n2 = name2; 287 288 /* It's a bit tricky because the names are space padded */ 289 for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) 290 ; 291 for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) 292 ; 293 l3 = strlen(global_myname()); 294 295 if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 && 296 (l2!=l3 || strncmp(n2,global_myname(),l3) != 0)) 297 return -1; 298 299 if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 && 300 (l1!=l3 || strncmp(n1,global_myname(),l3) != 0)) 301 return 1; 302 303 return memcmp(n1,n2,sizeof(name1)); 304} 305 306/**************************************************************************** 307 Process a node status query 308 ****************************************************************************/ 309 310void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p) 311{ 312 struct nmb_packet *nmb = &p->packet.nmb; 313 unstring qname; 314 int ques_type = nmb->question.question_name.name_type; 315 char rdata[MAX_DGRAM_SIZE]; 316 char *countptr, *buf, *bufend, *buf0; 317 int names_added,i; 318 struct name_record *namerec; 319 320 pull_ascii_nstring(qname, sizeof(qname), nmb->question.question_name.name); 321 322 DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \ 323subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name)); 324 325 if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_SELF_NAME)) == 0) { 326 DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \ 327subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), 328 inet_ntoa(p->ip), subrec->subnet_name)); 329 330 return; 331 } 332 333 /* this is not an exact calculation. the 46 is for the stats buffer 334 and the 60 is to leave room for the header etc */ 335 bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60); 336 countptr = buf = rdata; 337 buf += 1; 338 buf0 = buf; 339 340 names_added = 0; 341 342 namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); 343 344 while (buf < bufend) { 345 if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) { 346 int name_type = namerec->name.name_type; 347 unstring name; 348 349 pull_ascii_nstring(name, sizeof(name), namerec->name.name); 350 strupper_m(name); 351 if (!strequal(name,"*") && 352 !strequal(name,"__SAMBA__") && 353 (name_type < 0x1b || name_type >= 0x20 || 354 ques_type < 0x1b || ques_type >= 0x20 || 355 strequal(qname, name))) { 356 /* Start with the name. */ 357 size_t len; 358 push_ascii_nstring(buf, name); 359 len = strlen(buf); 360 memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - len - 1); 361 buf[MAX_NETBIOSNAME_LEN - 1] = '\0'; 362 363 /* Put the name type and netbios flags in the buffer. */ 364 365 buf[15] = name_type; 366 set_nb_flags( &buf[16],namerec->data.nb_flags ); 367 buf[16] |= NB_ACTIVE; /* all our names are active */ 368 369 buf += 18; 370 371 names_added++; 372 } 373 } 374 375 /* Remove duplicate names. */ 376 if (names_added > 1) { 377 qsort( buf0, names_added, 18, QSORT_CAST status_compare ); 378 } 379 380 for( i=1; i < names_added ; i++ ) { 381 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) { 382 names_added--; 383 if (names_added == i) 384 break; 385 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i)); 386 i--; 387 } 388 } 389 390 buf = buf0 + 18*names_added; 391 392 namerec = (struct name_record *)ubi_trNext( namerec ); 393 394 if (!namerec) { 395 /* End of the subnet specific name list. Now 396 add the names on the unicast subnet . */ 397 struct subnet_record *uni_subrec = unicast_subnet; 398 399 if (uni_subrec != subrec) { 400 subrec = uni_subrec; 401 namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); 402 } 403 } 404 if (!namerec) 405 break; 406 407 } 408 409 SCVAL(countptr,0,names_added); 410 411 /* We don't send any stats as they could be used to attack 412 the protocol. */ 413 memset(buf,'\0',46); 414 415 buf += 46; 416 417 /* Send a NODE STATUS RESPONSE */ 418 reply_netbios_packet(p, /* Packet to reply to. */ 419 0, /* Result code. */ 420 NMB_STATUS, /* nmbd type code. */ 421 NMB_NAME_QUERY_OPCODE, /* opcode. */ 422 0, /* ttl. */ 423 rdata, /* data to send. */ 424 PTR_DIFF(buf,rdata)); /* data length. */ 425} 426 427 428/*************************************************************************** 429Process a name query. 430 431For broadcast name queries: 432 433 - Only reply if the query is for one of YOUR names. 434 - NEVER send a negative response to a broadcast query. 435 436****************************************************************************/ 437 438void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p) 439{ 440 struct nmb_packet *nmb = &p->packet.nmb; 441 struct nmb_name *question = &nmb->question.question_name; 442 int name_type = question->name_type; 443 BOOL bcast = nmb->header.nm_flags.bcast; 444 int ttl=0; 445 int rcode = 0; 446 char *prdata = NULL; 447 char rdata[6]; 448 BOOL success = False; 449 struct name_record *namerec = NULL; 450 int reply_data_len = 0; 451 int i; 452 453 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n", 454 inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question))); 455 456 /* Look up the name in the cache - if the request is a broadcast request that 457 came from a subnet we don't know about then search all the broadcast subnets 458 for a match (as we don't know what interface the request came in on). */ 459 460 if(subrec == remote_broadcast_subnet) 461 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME); 462 else 463 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 464 465 /* Check if it is a name that expired */ 466 if (namerec && 467 ((namerec->data.death_time != PERMANENT_TTL) && 468 (namerec->data.death_time < p->timestamp))) { 469 DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name))); 470 namerec = NULL; 471 } 472 473 if (namerec) { 474 /* 475 * Always respond to unicast queries. 476 * Don't respond to broadcast queries unless the query is for 477 * a name we own, a Primary Domain Controller name, or a WINS_PROXY 478 * name with type 0 or 0x20. WINS_PROXY names are only ever added 479 * into the namelist if we were configured as a WINS proxy. 480 */ 481 482 if (!bcast || 483 (bcast && ((name_type == 0x1b) || 484 (namerec->data.source == SELF_NAME) || 485 (namerec->data.source == PERMANENT_NAME) || 486 ((namerec->data.source == WINS_PROXY_NAME) && 487 ((name_type == 0) || (name_type == 0x20)))))) { 488 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, 489 or it's a Domain Master type. */ 490 491 /* 492 * If this is a WINS_PROXY_NAME, then ceck that none of the IP 493 * addresses we are returning is on the same broadcast subnet 494 * as the requesting packet. If it is then don't reply as the 495 * actual machine will be replying also and we don't want two 496 * replies to a broadcast query. 497 */ 498 499 if (namerec->data.source == WINS_PROXY_NAME) { 500 for( i = 0; i < namerec->data.num_ips; i++) { 501 if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) { 502 DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n", 503 nmb_namestr(&namerec->name), subrec->subnet_name )); 504 return; 505 } 506 } 507 } 508 509 ttl = (namerec->data.death_time != PERMANENT_TTL) ? 510 namerec->data.death_time - p->timestamp : lp_max_ttl(); 511 512 /* Copy all known ip addresses into the return data. */ 513 /* Optimise for the common case of one IP address so 514 we don't need a malloc. */ 515 516 if (namerec->data.num_ips == 1) { 517 prdata = rdata; 518 } else { 519 if ((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) { 520 DEBUG(0,("process_name_query_request: malloc fail !\n")); 521 return; 522 } 523 } 524 525 for (i = 0; i < namerec->data.num_ips; i++) { 526 set_nb_flags(&prdata[i*6],namerec->data.nb_flags); 527 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]); 528 } 529 530 sort_query_replies(prdata, i, p->ip); 531 532 reply_data_len = namerec->data.num_ips * 6; 533 success = True; 534 } 535 } 536 537 /* 538 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy() 539 * set we should initiate a WINS query here. On success we add the resolved name 540 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query. 541 */ 542 543 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() && 544 bcast && (subrec != remote_broadcast_subnet)) { 545 make_wins_proxy_name_query_request( subrec, p, question ); 546 return; 547 } 548 549 if (!success && bcast) { 550 if(prdata != rdata) 551 SAFE_FREE(prdata); 552 return; /* Never reply with a negative response to broadcasts. */ 553 } 554 555 /* 556 * Final check. From observation, if a unicast packet is sent 557 * to a non-WINS server with the recursion desired bit set 558 * then never send a negative response. 559 */ 560 561 if(!success && !bcast && nmb->header.nm_flags.recursion_desired) { 562 if(prdata != rdata) 563 SAFE_FREE(prdata); 564 return; 565 } 566 567 if (success) { 568 rcode = 0; 569 DEBUG(3,("OK\n")); 570 } else { 571 rcode = NAM_ERR; 572 DEBUG(3,("UNKNOWN\n")); 573 } 574 575 /* See rfc1002.txt 4.2.13. */ 576 577 reply_netbios_packet(p, /* Packet to reply to. */ 578 rcode, /* Result code. */ 579 NMB_QUERY, /* nmbd type code. */ 580 NMB_NAME_QUERY_OPCODE, /* opcode. */ 581 ttl, /* ttl. */ 582 prdata, /* data to send. */ 583 reply_data_len); /* data length. */ 584 585 if(prdata != rdata) 586 SAFE_FREE(prdata); 587} 588