2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
6 Copyright (C) Jeremy Allison 1994-1998
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.
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.
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.
26 #define WINS_LIST "wins.dat"
27 #define WINS_VERSION 1
29 extern int DEBUGLEVEL;
30 extern struct in_addr ipzero;
34 /****************************************************************************
35 hash our interfaces and netbios names settings
36 *****************************************************************************/
37 static unsigned wins_hash(void)
40 unsigned ret = iface_hash();
41 extern char **my_netbios_names;
43 for (i=0;my_netbios_names[i];i++)
44 ret ^= str_checksum(my_netbios_names[i]);
46 ret ^= str_checksum(lp_workgroup());
52 /****************************************************************************
53 Determine if this packet should be allocated to the WINS server.
54 *****************************************************************************/
56 BOOL packet_is_for_wins_server(struct packet_struct *packet)
58 struct nmb_packet *nmb = &packet->packet.nmb;
60 /* Only unicast packets go to a WINS server. */
61 if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
63 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
67 /* Check for node status requests. */
68 if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
71 switch(nmb->header.opcode)
74 * A WINS server issues WACKS, not receives them.
77 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
80 * A WINS server only processes registration and
81 * release requests, not responses.
83 case NMB_NAME_REG_OPCODE:
84 case NMB_NAME_MULTIHOMED_REG_OPCODE:
85 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
86 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
87 if(nmb->header.response)
89 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
94 case NMB_NAME_RELEASE_OPCODE:
95 if(nmb->header.response)
97 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
103 * Only process unicast name queries with rd = 1.
105 case NMB_NAME_QUERY_OPCODE:
106 if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
108 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
117 /****************************************************************************
118 Utility function to decide what ttl to give a register/refresh request.
119 *****************************************************************************/
121 static int get_ttl_from_packet(struct nmb_packet *nmb)
123 int ttl = nmb->additional->ttl;
125 if(ttl < lp_min_wins_ttl() )
126 ttl = lp_min_wins_ttl();
128 if(ttl > lp_max_wins_ttl() )
129 ttl = lp_max_wins_ttl();
134 /****************************************************************************
135 Load or create the WINS database.
136 *****************************************************************************/
138 BOOL initialise_wins(void)
141 time_t time_now = time(NULL);
145 if(!lp_we_are_a_wins_server())
148 add_samba_names_to_subnet(wins_server_subnet);
151 /* Setup the async dns. */
155 pstrcpy(fname,lp_lockdir());
156 trim_string(fname,NULL,"/");
158 pstrcat(fname,WINS_LIST);
160 if((fp = fopen(fname,"r")) == NULL)
162 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
163 fname, strerror(errno) ));
169 pstring name_str, ip_str, ttl_str, nb_flags_str;
170 unsigned int num_ips;
172 struct in_addr *ip_list;
176 enum name_source source;
185 /* Read a line from the wins.dat file. Strips whitespace
186 from the beginning and end of the line.
188 if (!fgets_slash(line,sizeof(pstring),fp))
194 if (strncmp(line,"VERSION ", 8) == 0) {
195 if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
196 version != WINS_VERSION ||
197 hash != wins_hash()) {
198 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
208 * Now we handle multiple IP addresses per name we need
209 * to iterate over the line twice. The first time to
210 * determine how many IP addresses there are, the second
211 * time to actually parse them into the ip_list array.
214 if (!next_token(&ptr,name_str,NULL))
216 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
220 if (!next_token(&ptr,ttl_str,NULL))
222 DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
227 * Determine the number of IP addresses per line.
232 got_token = next_token(&ptr,ip_str,NULL);
235 if(got_token && strchr(ip_str, '.'))
240 } while( got_token && was_ip);
244 DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
250 DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
254 /* Allocate the space for the ip_list. */
255 if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
257 DEBUG(0,("initialise_wins: Malloc fail !\n"));
261 /* Reset and re-parse the line. */
263 next_token(&ptr,name_str,NULL);
264 next_token(&ptr,ttl_str,NULL);
265 for(i = 0; i < num_ips; i++)
267 next_token(&ptr, ip_str, NULL);
268 ip_list[i] = *interpret_addr2(ip_str);
269 if (ip_equal(ip_list[i], ipzero))
272 next_token(&ptr,nb_flags_str,NULL);
275 * Deal with SELF or REGISTER name encoding. Default is REGISTER
276 * for compatibility with old nmbds.
279 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
281 DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
282 free((char *)ip_list);
286 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
287 nb_flags_str[strlen(nb_flags_str)-1] = '\0';
289 /* Netbios name. # divides the name from the type (hex): netbios#xx */
290 pstrcpy(name,name_str);
292 if((p = strchr(name,'#')) != NULL)
295 sscanf(p+1,"%x",&type);
298 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
299 sscanf(nb_flags_str,"%x",&nb_flags);
300 sscanf(ttl_str,"%d",&ttl);
302 /* add all entries that have 60 seconds or more to live */
303 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
305 if(ttl != PERMANENT_TTL)
308 DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
309 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
311 (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
312 ttl, REGISTER_NAME, num_ips, ip_list );
317 DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
318 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
321 free((char *)ip_list);
328 /****************************************************************************
329 Send a WINS WACK (Wait ACKnowledgement) response.
330 **************************************************************************/
332 static void send_wins_wack_response(int ttl, struct packet_struct *p)
334 struct nmb_packet *nmb = &p->packet.nmb;
335 unsigned char rdata[2];
337 rdata[0] = rdata[1] = 0;
339 /* Taken from nmblib.c - we need to send back almost
340 identical bytes from the requesting packet header. */
342 rdata[0] = (nmb->header.opcode & 0xF) << 3;
343 if (nmb->header.nm_flags.authoritative &&
344 nmb->header.response) rdata[0] |= 0x4;
345 if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
346 if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
347 if (nmb->header.nm_flags.recursion_available &&
348 nmb->header.response) rdata[1] |= 0x80;
349 if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
351 reply_netbios_packet(p, /* Packet to reply to. */
352 0, /* Result code. */
353 NMB_WAIT_ACK, /* nmbd type code. */
354 NMB_WACK_OPCODE, /* opcode. */
356 (char *)rdata, /* data to send. */
357 2); /* data length. */
360 /****************************************************************************
361 Send a WINS name registration response.
362 **************************************************************************/
364 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
366 struct nmb_packet *nmb = &p->packet.nmb;
369 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
371 reply_netbios_packet(p, /* Packet to reply to. */
372 rcode, /* Result code. */
373 WINS_REG, /* nmbd type code. */
374 NMB_NAME_REG_OPCODE, /* opcode. */
376 rdata, /* data to send. */
377 6); /* data length. */
380 /***********************************************************************
381 Deal with a name refresh request to a WINS server.
382 ************************************************************************/
384 void wins_process_name_refresh_request(struct subnet_record *subrec,
385 struct packet_struct *p)
387 struct nmb_packet *nmb = &p->packet.nmb;
388 struct nmb_name *question = &nmb->question.question_name;
389 BOOL bcast = nmb->header.nm_flags.bcast;
390 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
391 BOOL group = (nb_flags & NB_GROUP) ? True : False;
392 struct name_record *namerec = NULL;
393 int ttl = get_ttl_from_packet(nmb);
394 struct in_addr from_ip;
396 putip((char *)&from_ip,&nmb->additional->rdata[2]);
401 * We should only get unicast name refresh packets here.
402 * Anyone trying to refresh broadcast should not be going to a WINS
403 * server. Log an error here.
406 DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
407 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
408 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
412 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
413 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
416 * See if the name already exists.
419 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
422 * If this is a refresh request and the name doesn't exist then
428 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
429 the name does not exist.\n", namestr(question) ));
430 send_wins_name_registration_response(NAM_ERR, 0, p);
435 * Check that the group bits for the refreshing name and the
436 * name in our database match.
439 if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
441 DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
442 does not match group bit in WINS for this name.\n", namestr(question), group ? "True" : "False" ));
443 send_wins_name_registration_response(RFS_ERR, 0, p);
448 * For a unique name check that the person refreshing the name is one of the registered IP
449 * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
450 * Just return success for unique 0x1d refreshes. For normal group names update the ttl
451 * and return success.
454 if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
459 update_name_ttl(namerec, ttl);
460 send_wins_name_registration_response(0, ttl, p);
466 * Normal groups are all registered with an IP address of 255.255.255.255
467 * so we can't search for the IP address.
469 update_name_ttl(namerec, ttl);
470 send_wins_name_registration_response(0, ttl, p);
473 else if(!group && (question->name_type == 0x1d))
476 * Special name type - just pretend the refresh succeeded.
478 send_wins_name_registration_response(0, ttl, p);
487 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
488 is IP is not known to the name.\n", namestr(question), inet_ntoa(from_ip) ));
489 send_wins_name_registration_response(RFS_ERR, 0, p);
494 /***********************************************************************
495 Deal with a name registration request query success to a client that
498 We have a locked pointer to the original packet stashed away in the
499 userdata pointer. The success here is actually a failure as it means
500 the client we queried wants to keep the name, so we must return
501 a registration failure to the original requestor.
502 ************************************************************************/
504 static void wins_register_query_success(struct subnet_record *subrec,
505 struct userdata_struct *userdata,
506 struct nmb_name *question_name,
508 struct res_rec *answers)
510 struct packet_struct *orig_reg_packet;
512 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
514 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
515 name %s. Rejecting registration request.\n", inet_ntoa(ip), namestr(question_name) ));
517 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
519 orig_reg_packet->locked = False;
520 free_packet(orig_reg_packet);
523 /***********************************************************************
524 Deal with a name registration request query failure to a client that
527 We have a locked pointer to the original packet stashed away in the
528 userdata pointer. The failure here is actually a success as it means
529 the client we queried didn't want to keep the name, so we can remove
530 the old name record and then successfully add the new name.
531 ************************************************************************/
533 static void wins_register_query_fail(struct subnet_record *subrec,
534 struct response_record *rrec,
535 struct nmb_name *question_name,
538 struct userdata_struct *userdata = rrec->userdata;
539 struct packet_struct *orig_reg_packet;
540 struct nmb_packet *nmb;
541 struct name_record *namerec = NULL;
545 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
547 nmb = &orig_reg_packet->packet.nmb;
549 nb_flags = get_nb_flags(nmb->additional->rdata);
550 group = (nb_flags & NB_GROUP) ? True : False;
553 * We want to just add the name, as we now know the original owner
554 * didn't want it. But we can't just do that as an arbitary
555 * amount of time may have taken place between the name query
556 * request and this timeout/error response. So we check that
557 * the name still exists and is in the same state - if so
558 * we remove it and call wins_process_name_registration_request()
559 * as we know it will do the right thing now.
562 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
564 if( (namerec != NULL)
565 && (namerec->data.source == REGISTER_NAME)
566 && ip_equal(rrec->packet->ip, *namerec->data.ip) )
568 remove_name_from_namelist( subrec, namerec);
573 wins_process_name_registration_request(subrec, orig_reg_packet);
575 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
576 querying for name %s in order to replace it and this reply.\n", namestr(question_name) ));
578 orig_reg_packet->locked = False;
579 free_packet(orig_reg_packet);
582 /***********************************************************************
583 Deal with a name registration request to a WINS server.
585 Use the following pseudocode :
593 | +--- existing name is group
596 | | +--- add name (return).
599 | +--- exiting name is unique
602 | +--- query existing owner (return).
605 +--------name doesn't exist
608 +--- add name (return).
616 | +--- existing name is group
619 | | +--- fail add (return).
622 | +--- exiting name is unique
625 | +--- query existing owner (return).
628 +--------name doesn't exist
631 +--- add name (return).
633 As can be seen from the above, the two cases may be collapsed onto each
634 other with the exception of the case where the name already exists and
635 is a group name. This case we handle with an if statement.
637 ************************************************************************/
639 void wins_process_name_registration_request(struct subnet_record *subrec,
640 struct packet_struct *p)
642 struct nmb_packet *nmb = &p->packet.nmb;
643 struct nmb_name *question = &nmb->question.question_name;
644 BOOL bcast = nmb->header.nm_flags.bcast;
645 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
646 int ttl = get_ttl_from_packet(nmb);
647 struct name_record *namerec = NULL;
648 struct in_addr from_ip;
649 BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
651 putip((char *)&from_ip,&nmb->additional->rdata[2]);
656 * We should only get unicast name registration packets here.
657 * Anyone trying to register broadcast should not be going to a WINS
658 * server. Log an error here.
661 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
662 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
663 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
667 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
668 IP %s\n", registering_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
671 * See if the name already exists.
674 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
677 * Deal with the case where the name found was a dns entry.
678 * Remove it as we now have a NetBIOS client registering the
682 if( (namerec != NULL)
683 && ( (namerec->data.source == DNS_NAME)
684 || (namerec->data.source == DNSFAIL_NAME) ) )
686 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
687 a dns lookup - removing it.\n", namestr(question) ));
688 remove_name_from_namelist( subrec, namerec );
693 * Reject if the name exists and is not a REGISTER_NAME.
694 * (ie. Don't allow any static names to be overwritten.
697 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
699 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
700 to register name %s. Name already exists in WINS with source type %d.\n",
701 namestr(question), namerec->data.source ));
702 send_wins_name_registration_response(RFS_ERR, 0, p);
707 * Special policy decisions based on MS documentation.
708 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
709 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
713 * A group name is always added as the local broadcast address, except
714 * for group names ending in 0x1c.
715 * Group names with type 0x1c are registered with individual IP addresses.
718 if(registering_group_name && (question->name_type != 0x1c))
719 from_ip = *interpret_addr2("255.255.255.255");
722 * Ignore all attempts to register a unique 0x1d name, although return success.
725 if(!registering_group_name && (question->name_type == 0x1d))
727 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
728 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
729 send_wins_name_registration_response(0, ttl, p);
734 * Next two cases are the 'if statement' mentioned above.
737 if((namerec != NULL) && NAME_GROUP(namerec))
739 if(registering_group_name)
742 * If we are adding a group name, the name exists and is also a group entry just add this
743 * IP address to it and update the ttl.
746 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
747 inet_ntoa(from_ip), namestr(question) ));
749 * Check the ip address is not already in the group.
751 if(!find_ip_in_name_record(namerec, from_ip))
752 add_ip_to_name_record(namerec, from_ip);
753 update_name_ttl(namerec, ttl);
754 send_wins_name_registration_response(0, ttl, p);
760 * If we are adding a unique name, the name exists in the WINS db
761 * and is a group name then reject the registration.
764 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
765 already exists in WINS as a GROUP name.\n", namestr(question) ));
766 send_wins_name_registration_response(RFS_ERR, 0, p);
772 * From here on down we know that if the name exists in the WINS db it is
773 * a unique name, not a group name.
777 * If the name exists and is one of our names then check the
778 * registering IP address. If it's not one of ours then automatically
779 * reject without doing the query - we know we will reject it.
782 if((namerec != NULL) && (is_myname(namerec->name.name)) )
786 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
787 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
788 send_wins_name_registration_response(RFS_ERR, 0, p);
794 * It's one of our names and one of our IP's - update the ttl.
796 update_name_ttl(namerec, ttl);
797 send_wins_name_registration_response(0, ttl, p);
803 * If the name exists and it is a unique registration and the registering IP
804 * is the same as the the (single) already registered IP then just update the ttl.
807 if( !registering_group_name
809 && (namerec->data.num_ips == 1)
810 && ip_equal( namerec->data.ip[0], from_ip ) )
812 update_name_ttl( namerec, ttl );
813 send_wins_name_registration_response( 0, ttl, p );
818 * Finally if the name exists do a query to the registering machine
819 * to see if they still claim to have the name.
822 if( namerec != NULL )
824 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
825 struct userdata_struct *userdata = (struct userdata_struct *)ud;
828 * First send a WACK to the registering machine.
831 send_wins_wack_response(60, p);
834 * When the reply comes back we need the original packet.
835 * Lock this so it won't be freed and then put it into
836 * the userdata structure.
841 userdata = (struct userdata_struct *)ud;
843 userdata->copy_fn = NULL;
844 userdata->free_fn = NULL;
845 userdata->userdata_len = sizeof(struct packet_struct *);
846 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
849 * Use the new call to send a query directly to an IP address.
850 * This sends the query directly to the IP address, and ensures
851 * the recursion desired flag is not set (you were right Luke :-).
852 * This function should *only* be called from the WINS server
856 query_name_from_wins_server( *namerec->data.ip,
859 wins_register_query_success,
860 wins_register_query_fail,
866 * Name did not exist - add it.
869 (void)add_name_to_subnet( subrec, question->name, question->name_type,
870 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
872 send_wins_name_registration_response(0, ttl, p);
875 /***********************************************************************
876 Deal with a mutihomed name query success to the machine that
877 requested the multihomed name registration.
879 We have a locked pointer to the original packet stashed away in the
881 ************************************************************************/
883 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
884 struct userdata_struct *userdata,
885 struct nmb_name *question_name,
887 struct res_rec *answers)
889 struct packet_struct *orig_reg_packet;
890 struct nmb_packet *nmb;
891 struct name_record *namerec = NULL;
892 struct in_addr from_ip;
895 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
897 nmb = &orig_reg_packet->packet.nmb;
899 putip((char *)&from_ip,&nmb->additional->rdata[2]);
900 ttl = get_ttl_from_packet(nmb);
903 * We want to just add the new IP, as we now know the requesting
904 * machine claims to own it. But we can't just do that as an arbitary
905 * amount of time may have taken place between the name query
906 * request and this response. So we check that
907 * the name still exists and is in the same state - if so
908 * we just add the extra IP and update the ttl.
911 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
913 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
915 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
916 a subsequent IP addess.\n", namestr(question_name) ));
917 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
919 orig_reg_packet->locked = False;
920 free_packet(orig_reg_packet);
925 if(!find_ip_in_name_record(namerec, from_ip))
926 add_ip_to_name_record(namerec, from_ip);
927 update_name_ttl(namerec, ttl);
928 send_wins_name_registration_response(0, ttl, orig_reg_packet);
930 orig_reg_packet->locked = False;
931 free_packet(orig_reg_packet);
934 /***********************************************************************
935 Deal with a name registration request query failure to a client that
938 We have a locked pointer to the original packet stashed away in the
940 ************************************************************************/
942 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
943 struct response_record *rrec,
944 struct nmb_name *question_name,
947 struct userdata_struct *userdata = rrec->userdata;
948 struct packet_struct *orig_reg_packet;
950 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
952 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
953 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), namestr(question_name) ));
954 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
956 orig_reg_packet->locked = False;
957 free_packet(orig_reg_packet);
961 /***********************************************************************
962 Deal with a multihomed name registration request to a WINS server.
963 These cannot be group name registrations.
964 ***********************************************************************/
966 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
967 struct packet_struct *p)
969 struct nmb_packet *nmb = &p->packet.nmb;
970 struct nmb_name *question = &nmb->question.question_name;
971 BOOL bcast = nmb->header.nm_flags.bcast;
972 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
973 int ttl = get_ttl_from_packet(nmb);
974 struct name_record *namerec = NULL;
975 struct in_addr from_ip;
976 BOOL group = (nb_flags & NB_GROUP) ? True : False;;
978 putip((char *)&from_ip,&nmb->additional->rdata[2]);
983 * We should only get unicast name registration packets here.
984 * Anyone trying to register broadcast should not be going to a WINS
985 * server. Log an error here.
988 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
989 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
990 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
995 * Only unique names should be registered multihomed.
1000 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1001 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1002 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1006 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1007 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
1010 * Deal with policy regarding 0x1d names.
1013 if(question->name_type == 0x1d)
1015 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1016 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1017 send_wins_name_registration_response(0, ttl, p);
1022 * See if the name already exists.
1025 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1028 * Deal with the case where the name found was a dns entry.
1029 * Remove it as we now have a NetBIOS client registering the
1033 if( (namerec != NULL)
1034 && ( (namerec->data.source == DNS_NAME)
1035 || (namerec->data.source == DNSFAIL_NAME) ) )
1037 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1038 - removing it.\n", namestr(question) ));
1039 remove_name_from_namelist( subrec, namerec);
1044 * Reject if the name exists and is not a REGISTER_NAME.
1045 * (ie. Don't allow any static names to be overwritten.
1048 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1050 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1051 to register name %s. Name already exists in WINS with source type %d.\n",
1052 namestr(question), namerec->data.source ));
1053 send_wins_name_registration_response(RFS_ERR, 0, p);
1058 * Reject if the name exists and is a GROUP name.
1061 if((namerec != NULL) && NAME_GROUP(namerec))
1063 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1064 already exists in WINS as a GROUP name.\n", namestr(question) ));
1065 send_wins_name_registration_response(RFS_ERR, 0, p);
1070 * From here on down we know that if the name exists in the WINS db it is
1071 * a unique name, not a group name.
1075 * If the name exists and is one of our names then check the
1076 * registering IP address. If it's not one of ours then automatically
1077 * reject without doing the query - we know we will reject it.
1080 if((namerec != NULL) && (is_myname(namerec->name.name)) )
1082 if(!ismyip(from_ip))
1084 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1085 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
1086 send_wins_name_registration_response(RFS_ERR, 0, p);
1092 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1095 if(!find_ip_in_name_record(namerec, from_ip))
1096 add_ip_to_name_record(namerec, from_ip);
1097 update_name_ttl(namerec, ttl);
1098 send_wins_name_registration_response(0, ttl, p);
1104 * If the name exists check if the IP address is already registered
1105 * to that name. If so then update the ttl and reply success.
1108 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1110 update_name_ttl(namerec, ttl);
1111 send_wins_name_registration_response(0, ttl, p);
1116 * If the name exists do a query to the owner
1117 * to see if they still want the name.
1122 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1123 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1126 * First send a WACK to the registering machine.
1129 send_wins_wack_response(60, p);
1132 * When the reply comes back we need the original packet.
1133 * Lock this so it won't be freed and then put it into
1134 * the userdata structure.
1139 userdata = (struct userdata_struct *)ud;
1141 userdata->copy_fn = NULL;
1142 userdata->free_fn = NULL;
1143 userdata->userdata_len = sizeof(struct packet_struct *);
1144 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1147 * Use the new call to send a query directly to an IP address.
1148 * This sends the query directly to the IP address, and ensures
1149 * the recursion desired flag is not set (you were right Luke :-).
1150 * This function should *only* be called from the WINS server
1154 query_name_from_wins_server( p->ip,
1156 question->name_type,
1157 wins_multihomed_register_query_success,
1158 wins_multihomed_register_query_fail,
1165 * Name did not exist - add it.
1168 (void)add_name_to_subnet( subrec, question->name, question->name_type,
1169 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
1171 send_wins_name_registration_response(0, ttl, p);
1174 /***********************************************************************
1175 Deal with the special name query for *<1b>.
1176 ***********************************************************************/
1178 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1179 struct packet_struct *p)
1181 struct name_record *namerec = NULL;
1186 * Go through all the names in the WINS db looking for those
1187 * ending in <1b>. Use this to calculate the number of IP
1188 * addresses we need to return.
1192 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1194 namerec = (struct name_record *)ubi_trNext( namerec ) )
1196 if( namerec->name.name_type == 0x1b )
1197 num_ips += namerec->data.num_ips;
1203 * There are no 0x1b names registered. Return name query fail.
1205 send_wins_name_query_response(NAM_ERR, p, NULL);
1209 if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1211 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1216 * Go through all the names again in the WINS db looking for those
1217 * ending in <1b>. Add their IP addresses into the list we will
1222 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1224 namerec = (struct name_record *)ubi_trNext( namerec ) )
1226 if(namerec->name.name_type == 0x1b)
1229 for(i = 0; i < namerec->data.num_ips; i++)
1231 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1232 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1239 * Send back the reply containing the IP list.
1242 reply_netbios_packet(p, /* Packet to reply to. */
1243 0, /* Result code. */
1244 WINS_QUERY, /* nmbd type code. */
1245 NMB_NAME_QUERY_OPCODE, /* opcode. */
1246 lp_min_wins_ttl(), /* ttl. */
1247 prdata, /* data to send. */
1248 num_ips*6); /* data length. */
1253 /****************************************************************************
1254 Send a WINS name query response.
1255 **************************************************************************/
1257 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1258 struct name_record *namerec)
1261 char *prdata = rdata;
1262 int reply_data_len = 0;
1270 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1271 namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1273 /* Copy all known ip addresses into the return data. */
1274 /* Optimise for the common case of one IP address so
1275 we don't need a malloc. */
1277 if( namerec->data.num_ips == 1 )
1281 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1283 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1288 for(i = 0; i < namerec->data.num_ips; i++)
1290 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1291 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1294 sort_query_replies(prdata, i, p->ip);
1296 reply_data_len = namerec->data.num_ips * 6;
1299 reply_netbios_packet(p, /* Packet to reply to. */
1300 rcode, /* Result code. */
1301 WINS_QUERY, /* nmbd type code. */
1302 NMB_NAME_QUERY_OPCODE, /* opcode. */
1304 prdata, /* data to send. */
1305 reply_data_len); /* data length. */
1307 if((prdata != rdata) && (prdata != NULL))
1311 /***********************************************************************
1312 Deal with a name query.
1313 ***********************************************************************/
1315 void wins_process_name_query_request(struct subnet_record *subrec,
1316 struct packet_struct *p)
1318 struct nmb_packet *nmb = &p->packet.nmb;
1319 struct nmb_name *question = &nmb->question.question_name;
1320 struct name_record *namerec = NULL;
1322 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1323 namestr(question), inet_ntoa(p->ip) ));
1326 * Special name code. If the queried name is *<1b> then search
1327 * the entire WINS database and return a list of all the IP addresses
1328 * registered to any <1b> name. This is to allow domain master browsers
1329 * to discover other domains that may not have a presence on their subnet.
1332 if(strequal( question->name, "*") && (question->name_type == 0x1b))
1334 process_wins_dmb_query_request( subrec, p);
1338 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1343 * If it's a DNSFAIL_NAME then reply name not found.
1346 if( namerec->data.source == DNSFAIL_NAME )
1348 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1349 namestr(question) ));
1350 send_wins_name_query_response(NAM_ERR, p, namerec);
1355 * If the name has expired then reply name not found.
1358 if( (namerec->data.death_time != PERMANENT_TTL)
1359 && (namerec->data.death_time < p->timestamp) )
1361 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1362 namestr(question) ));
1363 send_wins_name_query_response(NAM_ERR, p, namerec);
1367 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1368 namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1370 send_wins_name_query_response(0, p, namerec);
1375 * Name not found in WINS - try a dns query if it's a 0x20 name.
1378 if(lp_dns_proxy() &&
1379 ((question->name_type == 0x20) || question->name_type == 0))
1382 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1383 namestr(question) ));
1385 queue_dns_query(p, question, &namerec);
1390 * Name not found - return error.
1393 send_wins_name_query_response(NAM_ERR, p, NULL);
1396 /****************************************************************************
1397 Send a WINS name release response.
1398 **************************************************************************/
1400 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1402 struct nmb_packet *nmb = &p->packet.nmb;
1405 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1407 reply_netbios_packet(p, /* Packet to reply to. */
1408 rcode, /* Result code. */
1409 NMB_REL, /* nmbd type code. */
1410 NMB_NAME_RELEASE_OPCODE, /* opcode. */
1412 rdata, /* data to send. */
1413 6); /* data length. */
1416 /***********************************************************************
1417 Deal with a name release.
1418 ***********************************************************************/
1420 void wins_process_name_release_request(struct subnet_record *subrec,
1421 struct packet_struct *p)
1423 struct nmb_packet *nmb = &p->packet.nmb;
1424 struct nmb_name *question = &nmb->question.question_name;
1425 BOOL bcast = nmb->header.nm_flags.bcast;
1426 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1427 struct name_record *namerec = NULL;
1428 struct in_addr from_ip;
1429 BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1431 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1436 * We should only get unicast name registration packets here.
1437 * Anyone trying to register broadcast should not be going to a WINS
1438 * server. Log an error here.
1441 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1442 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1443 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1447 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1448 IP %s\n", releasing_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
1451 * Deal with policy regarding 0x1d names.
1454 if(!releasing_group_name && (question->name_type == 0x1d))
1456 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1457 to release name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1458 send_wins_name_release_response(0, p);
1463 * See if the name already exists.
1466 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1468 if( (namerec == NULL)
1469 || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1471 send_wins_name_release_response(NAM_ERR, p);
1476 * Check that the sending machine has permission to release this name.
1477 * If it's a group name not ending in 0x1c then just say yes and let
1478 * the group time out.
1481 if(releasing_group_name && (question->name_type != 0x1c))
1483 send_wins_name_release_response(0, p);
1488 * Check that the releasing node is on the list of IP addresses
1489 * for this name. Disallow the release if not.
1492 if(!find_ip_in_name_record(namerec, from_ip))
1494 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1495 release name %s as IP %s is not one of the known IP's for this name.\n",
1496 namestr(question), inet_ntoa(from_ip) ));
1497 send_wins_name_release_response(NAM_ERR, p);
1502 * Release the name and then remove the IP from the known list.
1505 send_wins_name_release_response(0, p);
1506 remove_ip_from_name_record(namerec, from_ip);
1509 * Remove the name entirely if no IP addresses left.
1511 if (namerec->data.num_ips == 0)
1512 remove_name_from_namelist(subrec, namerec);
1516 /*******************************************************************
1517 WINS time dependent processing.
1518 ******************************************************************/
1520 void initiate_wins_processing(time_t t)
1522 static time_t lasttime = 0;
1526 if (t - lasttime < 5)
1529 if(!lp_we_are_a_wins_server())
1532 expire_names_on_subnet(wins_server_subnet, t);
1534 if(wins_server_subnet->namelist_changed)
1535 wins_write_database();
1537 wins_server_subnet->namelist_changed = False;
1540 /*******************************************************************
1541 Write out the current WINS database.
1542 ******************************************************************/
1544 void wins_write_database(void)
1546 struct name_record *namerec;
1547 pstring fname, fnamenew;
1551 if(!lp_we_are_a_wins_server())
1554 pstrcpy(fname,lp_lockdir());
1555 trim_string(fname,NULL,"/");
1557 pstrcat(fname,WINS_LIST);
1558 pstrcpy(fnamenew,fname);
1559 pstrcat(fnamenew,".");
1561 if((fp = fopen(fnamenew,"w")) == NULL)
1563 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1567 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1569 fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
1572 = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1574 namerec = (struct name_record *)ubi_trNext( namerec ) )
1579 DEBUGADD(4,("%-19s ", namestr(&namerec->name) ));
1581 if( namerec->data.death_time != PERMANENT_TTL )
1583 tm = LocalTime(&namerec->data.death_time);
1584 DEBUGADD(4,("TTL = %s", asctime(tm) ));
1587 DEBUGADD(4,("TTL = PERMANENT\t"));
1589 for (i = 0; i < namerec->data.num_ips; i++)
1590 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1591 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1593 if( namerec->data.source == REGISTER_NAME )
1595 fprintf(fp, "\"%s#%02x\" %d ",
1596 namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1597 (int)namerec->data.death_time);
1599 for (i = 0; i < namerec->data.num_ips; i++)
1600 fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1601 fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1607 chmod(fnamenew,0644);
1608 rename(fnamenew,fname);