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;
33 /****************************************************************************
34 possibly call the WINS hook external program when a WINS change is made
35 *****************************************************************************/
36 static void wins_hook(char *operation, struct name_record *namerec, int ttl)
39 char *cmd = lp_wins_hook();
43 if (!cmd || !*cmd) return;
45 for (p=namerec->name.name; *p; p++) {
46 if (!(isalnum((int)*p) || strchr("._-",*p))) {
47 DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
53 p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
57 namerec->name.name_type,
60 for (i=0;i<namerec->data.num_ips;i++) {
61 p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
64 DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
65 smbrun(command, NULL, False);
69 /****************************************************************************
70 hash our interfaces and netbios names settings
71 *****************************************************************************/
72 static unsigned wins_hash(void)
75 unsigned ret = iface_hash();
76 extern char **my_netbios_names;
78 for (i=0;my_netbios_names[i];i++)
79 ret ^= str_checksum(my_netbios_names[i]);
81 ret ^= str_checksum(lp_workgroup());
87 /****************************************************************************
88 Determine if this packet should be allocated to the WINS server.
89 *****************************************************************************/
91 BOOL packet_is_for_wins_server(struct packet_struct *packet)
93 struct nmb_packet *nmb = &packet->packet.nmb;
95 /* Only unicast packets go to a WINS server. */
96 if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
98 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
102 /* Check for node status requests. */
103 if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
106 switch(nmb->header.opcode)
109 * A WINS server issues WACKS, not receives them.
111 case NMB_WACK_OPCODE:
112 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
115 * A WINS server only processes registration and
116 * release requests, not responses.
118 case NMB_NAME_REG_OPCODE:
119 case NMB_NAME_MULTIHOMED_REG_OPCODE:
120 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
121 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
122 if(nmb->header.response)
124 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
129 case NMB_NAME_RELEASE_OPCODE:
130 if(nmb->header.response)
132 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
138 * Only process unicast name queries with rd = 1.
140 case NMB_NAME_QUERY_OPCODE:
141 if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
143 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
152 /****************************************************************************
153 Utility function to decide what ttl to give a register/refresh request.
154 *****************************************************************************/
156 static int get_ttl_from_packet(struct nmb_packet *nmb)
158 int ttl = nmb->additional->ttl;
160 if(ttl < lp_min_wins_ttl() )
161 ttl = lp_min_wins_ttl();
163 if(ttl > lp_max_wins_ttl() )
164 ttl = lp_max_wins_ttl();
169 /****************************************************************************
170 Load or create the WINS database.
171 *****************************************************************************/
173 BOOL initialise_wins(void)
175 time_t time_now = time(NULL);
179 if(!lp_we_are_a_wins_server())
182 add_samba_names_to_subnet(wins_server_subnet);
184 if((fp = sys_fopen(lock_path(WINS_LIST),"r")) == NULL)
186 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
187 WINS_LIST, strerror(errno) ));
193 pstring name_str, ip_str, ttl_str, nb_flags_str;
194 unsigned int num_ips;
196 struct in_addr *ip_list;
208 /* Read a line from the wins.dat file. Strips whitespace
209 from the beginning and end of the line.
211 if (!fgets_slash(line,sizeof(pstring),fp))
217 if (strncmp(line,"VERSION ", 8) == 0) {
218 if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
219 version != WINS_VERSION ||
220 hash != wins_hash()) {
221 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
231 * Now we handle multiple IP addresses per name we need
232 * to iterate over the line twice. The first time to
233 * determine how many IP addresses there are, the second
234 * time to actually parse them into the ip_list array.
237 if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
239 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
243 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
245 DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
250 * Determine the number of IP addresses per line.
255 got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
258 if(got_token && strchr(ip_str, '.'))
263 } while( got_token && was_ip);
267 DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
273 DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
277 /* Allocate the space for the ip_list. */
278 if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
280 DEBUG(0,("initialise_wins: Malloc fail !\n"));
284 /* Reset and re-parse the line. */
286 next_token(&ptr,name_str,NULL,sizeof(name_str));
287 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
288 for(i = 0; i < num_ips; i++)
290 next_token(&ptr, ip_str, NULL, sizeof(ip_str));
291 ip_list[i] = *interpret_addr2(ip_str);
293 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
296 * Deal with SELF or REGISTER name encoding. Default is REGISTER
297 * for compatibility with old nmbds.
300 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
302 DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
303 free((char *)ip_list);
307 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
308 nb_flags_str[strlen(nb_flags_str)-1] = '\0';
310 /* Netbios name. # divides the name from the type (hex): netbios#xx */
311 pstrcpy(name,name_str);
313 if((p = strchr(name,'#')) != NULL)
316 sscanf(p+1,"%x",&type);
319 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
320 sscanf(nb_flags_str,"%x",&nb_flags);
321 sscanf(ttl_str,"%d",&ttl);
323 /* add all entries that have 60 seconds or more to live */
324 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
326 if(ttl != PERMANENT_TTL)
329 DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
330 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
332 (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
333 ttl, REGISTER_NAME, num_ips, ip_list );
338 DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
339 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
342 free((char *)ip_list);
349 /****************************************************************************
350 Send a WINS WACK (Wait ACKnowledgement) response.
351 **************************************************************************/
353 static void send_wins_wack_response(int ttl, struct packet_struct *p)
355 struct nmb_packet *nmb = &p->packet.nmb;
356 unsigned char rdata[2];
358 rdata[0] = rdata[1] = 0;
360 /* Taken from nmblib.c - we need to send back almost
361 identical bytes from the requesting packet header. */
363 rdata[0] = (nmb->header.opcode & 0xF) << 3;
364 if (nmb->header.nm_flags.authoritative &&
365 nmb->header.response) rdata[0] |= 0x4;
366 if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
367 if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
368 if (nmb->header.nm_flags.recursion_available &&
369 nmb->header.response) rdata[1] |= 0x80;
370 if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
372 reply_netbios_packet(p, /* Packet to reply to. */
373 0, /* Result code. */
374 NMB_WAIT_ACK, /* nmbd type code. */
375 NMB_WACK_OPCODE, /* opcode. */
377 (char *)rdata, /* data to send. */
378 2); /* data length. */
381 /****************************************************************************
382 Send a WINS name registration response.
383 **************************************************************************/
385 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
387 struct nmb_packet *nmb = &p->packet.nmb;
390 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
392 reply_netbios_packet(p, /* Packet to reply to. */
393 rcode, /* Result code. */
394 WINS_REG, /* nmbd type code. */
395 NMB_NAME_REG_OPCODE, /* opcode. */
397 rdata, /* data to send. */
398 6); /* data length. */
401 /***********************************************************************
402 Deal with a name refresh request to a WINS server.
403 ************************************************************************/
405 void wins_process_name_refresh_request(struct subnet_record *subrec,
406 struct packet_struct *p)
408 struct nmb_packet *nmb = &p->packet.nmb;
409 struct nmb_name *question = &nmb->question.question_name;
410 BOOL bcast = nmb->header.nm_flags.bcast;
411 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
412 BOOL group = (nb_flags & NB_GROUP) ? True : False;
413 struct name_record *namerec = NULL;
414 int ttl = get_ttl_from_packet(nmb);
415 struct in_addr from_ip;
417 putip((char *)&from_ip,&nmb->additional->rdata[2]);
422 * We should only get unicast name refresh packets here.
423 * Anyone trying to refresh broadcast should not be going to a WINS
424 * server. Log an error here.
427 DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
428 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
429 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
433 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
434 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
437 * See if the name already exists.
440 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
443 * If this is a refresh request and the name doesn't exist then
444 * treat it like a registration request. This allows us to recover
445 * from errors (tridge)
450 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
451 the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
452 wins_process_name_registration_request(subrec,p);
457 * Check that the group bits for the refreshing name and the
458 * name in our database match.
461 if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
463 DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
464 does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
465 send_wins_name_registration_response(RFS_ERR, 0, p);
470 * For a unique name check that the person refreshing the name is one of the registered IP
471 * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
472 * Just return success for unique 0x1d refreshes. For normal group names update the ttl
473 * and return success.
476 if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
481 update_name_ttl(namerec, ttl);
482 send_wins_name_registration_response(0, ttl, p);
483 wins_hook("refresh", namerec, ttl);
489 * Normal groups are all registered with an IP address of 255.255.255.255
490 * so we can't search for the IP address.
492 update_name_ttl(namerec, ttl);
493 send_wins_name_registration_response(0, ttl, p);
496 else if(!group && (question->name_type == 0x1d))
499 * Special name type - just pretend the refresh succeeded.
501 send_wins_name_registration_response(0, ttl, p);
510 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
511 is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
512 send_wins_name_registration_response(RFS_ERR, 0, p);
517 /***********************************************************************
518 Deal with a name registration request query success to a client that
521 We have a locked pointer to the original packet stashed away in the
522 userdata pointer. The success here is actually a failure as it means
523 the client we queried wants to keep the name, so we must return
524 a registration failure to the original requestor.
525 ************************************************************************/
527 static void wins_register_query_success(struct subnet_record *subrec,
528 struct userdata_struct *userdata,
529 struct nmb_name *question_name,
531 struct res_rec *answers)
533 struct packet_struct *orig_reg_packet;
535 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
537 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
538 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
540 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
542 orig_reg_packet->locked = False;
543 free_packet(orig_reg_packet);
546 /***********************************************************************
547 Deal with a name registration request query failure to a client that
550 We have a locked pointer to the original packet stashed away in the
551 userdata pointer. The failure here is actually a success as it means
552 the client we queried didn't want to keep the name, so we can remove
553 the old name record and then successfully add the new name.
554 ************************************************************************/
556 static void wins_register_query_fail(struct subnet_record *subrec,
557 struct response_record *rrec,
558 struct nmb_name *question_name,
561 struct userdata_struct *userdata = rrec->userdata;
562 struct packet_struct *orig_reg_packet;
563 struct name_record *namerec = NULL;
565 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
568 * We want to just add the name, as we now know the original owner
569 * didn't want it. But we can't just do that as an arbitary
570 * amount of time may have taken place between the name query
571 * request and this timeout/error response. So we check that
572 * the name still exists and is in the same state - if so
573 * we remove it and call wins_process_name_registration_request()
574 * as we know it will do the right thing now.
577 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
579 if( (namerec != NULL)
580 && (namerec->data.source == REGISTER_NAME)
581 && ip_equal(rrec->packet->ip, *namerec->data.ip) )
583 remove_name_from_namelist( subrec, namerec);
588 wins_process_name_registration_request(subrec, orig_reg_packet);
590 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
591 querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
593 orig_reg_packet->locked = False;
594 free_packet(orig_reg_packet);
597 /***********************************************************************
598 Deal with a name registration request to a WINS server.
600 Use the following pseudocode :
608 | +--- existing name is group
611 | | +--- add name (return).
614 | +--- exiting name is unique
617 | +--- query existing owner (return).
620 +--------name doesn't exist
623 +--- add name (return).
631 | +--- existing name is group
634 | | +--- fail add (return).
637 | +--- exiting name is unique
640 | +--- query existing owner (return).
643 +--------name doesn't exist
646 +--- add name (return).
648 As can be seen from the above, the two cases may be collapsed onto each
649 other with the exception of the case where the name already exists and
650 is a group name. This case we handle with an if statement.
652 ************************************************************************/
654 void wins_process_name_registration_request(struct subnet_record *subrec,
655 struct packet_struct *p)
657 struct nmb_packet *nmb = &p->packet.nmb;
658 struct nmb_name *question = &nmb->question.question_name;
659 BOOL bcast = nmb->header.nm_flags.bcast;
660 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
661 int ttl = get_ttl_from_packet(nmb);
662 struct name_record *namerec = NULL;
663 struct in_addr from_ip;
664 BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
666 putip((char *)&from_ip,&nmb->additional->rdata[2]);
671 * We should only get unicast name registration packets here.
672 * Anyone trying to register broadcast should not be going to a WINS
673 * server. Log an error here.
676 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
677 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
678 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
682 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
683 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
686 * See if the name already exists.
689 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
692 * Deal with the case where the name found was a dns entry.
693 * Remove it as we now have a NetBIOS client registering the
697 if( (namerec != NULL)
698 && ( (namerec->data.source == DNS_NAME)
699 || (namerec->data.source == DNSFAIL_NAME) ) )
701 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
702 a dns lookup - removing it.\n", nmb_namestr(question) ));
703 remove_name_from_namelist( subrec, namerec );
708 * Reject if the name exists and is not a REGISTER_NAME.
709 * (ie. Don't allow any static names to be overwritten.
712 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
714 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
715 to register name %s. Name already exists in WINS with source type %d.\n",
716 nmb_namestr(question), namerec->data.source ));
717 send_wins_name_registration_response(RFS_ERR, 0, p);
722 * Special policy decisions based on MS documentation.
723 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
724 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
728 * A group name is always added as the local broadcast address, except
729 * for group names ending in 0x1c.
730 * Group names with type 0x1c are registered with individual IP addresses.
733 if(registering_group_name && (question->name_type != 0x1c))
734 from_ip = *interpret_addr2("255.255.255.255");
737 * Ignore all attempts to register a unique 0x1d name, although return success.
740 if(!registering_group_name && (question->name_type == 0x1d))
742 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
743 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
744 send_wins_name_registration_response(0, ttl, p);
749 * Next two cases are the 'if statement' mentioned above.
752 if((namerec != NULL) && NAME_GROUP(namerec))
754 if(registering_group_name)
757 * If we are adding a group name, the name exists and is also a group entry just add this
758 * IP address to it and update the ttl.
761 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
762 inet_ntoa(from_ip), nmb_namestr(question) ));
764 * Check the ip address is not already in the group.
766 if(!find_ip_in_name_record(namerec, from_ip))
767 add_ip_to_name_record(namerec, from_ip);
768 update_name_ttl(namerec, ttl);
769 send_wins_name_registration_response(0, ttl, p);
775 * If we are adding a unique name, the name exists in the WINS db
776 * and is a group name then reject the registration.
779 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
780 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
781 send_wins_name_registration_response(RFS_ERR, 0, p);
787 * From here on down we know that if the name exists in the WINS db it is
788 * a unique name, not a group name.
792 * If the name exists and is one of our names then check the
793 * registering IP address. If it's not one of ours then automatically
794 * reject without doing the query - we know we will reject it.
797 if((namerec != NULL) && (is_myname(namerec->name.name)) )
801 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
802 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
803 send_wins_name_registration_response(RFS_ERR, 0, p);
809 * It's one of our names and one of our IP's - update the ttl.
811 update_name_ttl(namerec, ttl);
812 send_wins_name_registration_response(0, ttl, p);
813 wins_hook("refresh", namerec, ttl);
819 * If the name exists and it is a unique registration and the registering IP
820 * is the same as the the (single) already registered IP then just update the ttl.
823 if( !registering_group_name
825 && (namerec->data.num_ips == 1)
826 && ip_equal( namerec->data.ip[0], from_ip ) )
828 update_name_ttl( namerec, ttl );
829 send_wins_name_registration_response( 0, ttl, p );
830 wins_hook("refresh", namerec, ttl);
835 * Finally if the name exists do a query to the registering machine
836 * to see if they still claim to have the name.
839 if( namerec != NULL )
841 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
842 struct userdata_struct *userdata = (struct userdata_struct *)ud;
845 * First send a WACK to the registering machine.
848 send_wins_wack_response(60, p);
851 * When the reply comes back we need the original packet.
852 * Lock this so it won't be freed and then put it into
853 * the userdata structure.
858 userdata = (struct userdata_struct *)ud;
860 userdata->copy_fn = NULL;
861 userdata->free_fn = NULL;
862 userdata->userdata_len = sizeof(struct packet_struct *);
863 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
866 * Use the new call to send a query directly to an IP address.
867 * This sends the query directly to the IP address, and ensures
868 * the recursion desired flag is not set (you were right Luke :-).
869 * This function should *only* be called from the WINS server
873 query_name_from_wins_server( *namerec->data.ip,
876 wins_register_query_success,
877 wins_register_query_fail,
883 * Name did not exist - add it.
886 (void)add_name_to_subnet( subrec, question->name, question->name_type,
887 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
888 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
889 wins_hook("add", namerec, ttl);
892 send_wins_name_registration_response(0, ttl, p);
895 /***********************************************************************
896 Deal with a mutihomed name query success to the machine that
897 requested the multihomed name registration.
899 We have a locked pointer to the original packet stashed away in the
901 ************************************************************************/
903 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
904 struct userdata_struct *userdata,
905 struct nmb_name *question_name,
907 struct res_rec *answers)
909 struct packet_struct *orig_reg_packet;
910 struct nmb_packet *nmb;
911 struct name_record *namerec = NULL;
912 struct in_addr from_ip;
915 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
917 nmb = &orig_reg_packet->packet.nmb;
919 putip((char *)&from_ip,&nmb->additional->rdata[2]);
920 ttl = get_ttl_from_packet(nmb);
923 * We want to just add the new IP, as we now know the requesting
924 * machine claims to own it. But we can't just do that as an arbitary
925 * amount of time may have taken place between the name query
926 * request and this response. So we check that
927 * the name still exists and is in the same state - if so
928 * we just add the extra IP and update the ttl.
931 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
933 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
935 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
936 a subsequent IP addess.\n", nmb_namestr(question_name) ));
937 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
939 orig_reg_packet->locked = False;
940 free_packet(orig_reg_packet);
945 if(!find_ip_in_name_record(namerec, from_ip))
946 add_ip_to_name_record(namerec, from_ip);
947 update_name_ttl(namerec, ttl);
948 send_wins_name_registration_response(0, ttl, orig_reg_packet);
949 wins_hook("add", namerec, ttl);
951 orig_reg_packet->locked = False;
952 free_packet(orig_reg_packet);
955 /***********************************************************************
956 Deal with a name registration request query failure to a client that
959 We have a locked pointer to the original packet stashed away in the
961 ************************************************************************/
963 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
964 struct response_record *rrec,
965 struct nmb_name *question_name,
968 struct userdata_struct *userdata = rrec->userdata;
969 struct packet_struct *orig_reg_packet;
971 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
973 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
974 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
975 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
977 orig_reg_packet->locked = False;
978 free_packet(orig_reg_packet);
982 /***********************************************************************
983 Deal with a multihomed name registration request to a WINS server.
984 These cannot be group name registrations.
985 ***********************************************************************/
987 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
988 struct packet_struct *p)
990 struct nmb_packet *nmb = &p->packet.nmb;
991 struct nmb_name *question = &nmb->question.question_name;
992 BOOL bcast = nmb->header.nm_flags.bcast;
993 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
994 int ttl = get_ttl_from_packet(nmb);
995 struct name_record *namerec = NULL;
996 struct in_addr from_ip;
997 BOOL group = (nb_flags & NB_GROUP) ? True : False;;
999 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1004 * We should only get unicast name registration packets here.
1005 * Anyone trying to register broadcast should not be going to a WINS
1006 * server. Log an error here.
1009 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1010 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1011 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1016 * Only unique names should be registered multihomed.
1021 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1022 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1023 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1027 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1028 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1031 * Deal with policy regarding 0x1d names.
1034 if(question->name_type == 0x1d)
1036 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1037 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1038 send_wins_name_registration_response(0, ttl, p);
1043 * See if the name already exists.
1046 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1049 * Deal with the case where the name found was a dns entry.
1050 * Remove it as we now have a NetBIOS client registering the
1054 if( (namerec != NULL)
1055 && ( (namerec->data.source == DNS_NAME)
1056 || (namerec->data.source == DNSFAIL_NAME) ) )
1058 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1059 - removing it.\n", nmb_namestr(question) ));
1060 remove_name_from_namelist( subrec, namerec);
1065 * Reject if the name exists and is not a REGISTER_NAME.
1066 * (ie. Don't allow any static names to be overwritten.
1069 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1071 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1072 to register name %s. Name already exists in WINS with source type %d.\n",
1073 nmb_namestr(question), namerec->data.source ));
1074 send_wins_name_registration_response(RFS_ERR, 0, p);
1079 * Reject if the name exists and is a GROUP name.
1082 if((namerec != NULL) && NAME_GROUP(namerec))
1084 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1085 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1086 send_wins_name_registration_response(RFS_ERR, 0, p);
1091 * From here on down we know that if the name exists in the WINS db it is
1092 * a unique name, not a group name.
1096 * If the name exists and is one of our names then check the
1097 * registering IP address. If it's not one of ours then automatically
1098 * reject without doing the query - we know we will reject it.
1101 if((namerec != NULL) && (is_myname(namerec->name.name)) )
1103 if(!ismyip(from_ip))
1105 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1106 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1107 send_wins_name_registration_response(RFS_ERR, 0, p);
1113 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1116 if(!find_ip_in_name_record(namerec, from_ip)) {
1117 add_ip_to_name_record(namerec, from_ip);
1118 wins_hook("add", namerec, ttl);
1120 wins_hook("refresh", namerec, ttl);
1123 update_name_ttl(namerec, ttl);
1124 send_wins_name_registration_response(0, ttl, p);
1130 * If the name exists check if the IP address is already registered
1131 * to that name. If so then update the ttl and reply success.
1134 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1136 update_name_ttl(namerec, ttl);
1137 send_wins_name_registration_response(0, ttl, p);
1138 wins_hook("refresh", namerec, ttl);
1143 * If the name exists do a query to the owner
1144 * to see if they still want the name.
1149 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1150 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1153 * First send a WACK to the registering machine.
1156 send_wins_wack_response(60, p);
1159 * When the reply comes back we need the original packet.
1160 * Lock this so it won't be freed and then put it into
1161 * the userdata structure.
1166 userdata = (struct userdata_struct *)ud;
1168 userdata->copy_fn = NULL;
1169 userdata->free_fn = NULL;
1170 userdata->userdata_len = sizeof(struct packet_struct *);
1171 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1174 * Use the new call to send a query directly to an IP address.
1175 * This sends the query directly to the IP address, and ensures
1176 * the recursion desired flag is not set (you were right Luke :-).
1177 * This function should *only* be called from the WINS server
1180 * Note that this packet is sent to the current owner of the name,
1181 * not the person who sent the packet
1184 query_name_from_wins_server( namerec->data.ip[0],
1186 question->name_type,
1187 wins_multihomed_register_query_success,
1188 wins_multihomed_register_query_fail,
1195 * Name did not exist - add it.
1198 (void)add_name_to_subnet( subrec, question->name, question->name_type,
1199 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
1201 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1202 wins_hook("add", namerec, ttl);
1205 send_wins_name_registration_response(0, ttl, p);
1208 /***********************************************************************
1209 Deal with the special name query for *<1b>.
1210 ***********************************************************************/
1212 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1213 struct packet_struct *p)
1215 struct name_record *namerec = NULL;
1220 * Go through all the names in the WINS db looking for those
1221 * ending in <1b>. Use this to calculate the number of IP
1222 * addresses we need to return.
1226 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1228 namerec = (struct name_record *)ubi_trNext( namerec ) )
1230 if( namerec->name.name_type == 0x1b )
1231 num_ips += namerec->data.num_ips;
1237 * There are no 0x1b names registered. Return name query fail.
1239 send_wins_name_query_response(NAM_ERR, p, NULL);
1243 if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1245 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1250 * Go through all the names again in the WINS db looking for those
1251 * ending in <1b>. Add their IP addresses into the list we will
1256 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1258 namerec = (struct name_record *)ubi_trNext( namerec ) )
1260 if(namerec->name.name_type == 0x1b)
1263 for(i = 0; i < namerec->data.num_ips; i++)
1265 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1266 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1273 * Send back the reply containing the IP list.
1276 reply_netbios_packet(p, /* Packet to reply to. */
1277 0, /* Result code. */
1278 WINS_QUERY, /* nmbd type code. */
1279 NMB_NAME_QUERY_OPCODE, /* opcode. */
1280 lp_min_wins_ttl(), /* ttl. */
1281 prdata, /* data to send. */
1282 num_ips*6); /* data length. */
1287 /****************************************************************************
1288 Send a WINS name query response.
1289 **************************************************************************/
1291 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1292 struct name_record *namerec)
1295 char *prdata = rdata;
1296 int reply_data_len = 0;
1300 memset(rdata,'\0',6);
1304 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1305 namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1307 /* Copy all known ip addresses into the return data. */
1308 /* Optimise for the common case of one IP address so
1309 we don't need a malloc. */
1311 if( namerec->data.num_ips == 1 )
1315 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1317 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1322 for(i = 0; i < namerec->data.num_ips; i++)
1324 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1325 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1328 sort_query_replies(prdata, i, p->ip);
1330 reply_data_len = namerec->data.num_ips * 6;
1333 reply_netbios_packet(p, /* Packet to reply to. */
1334 rcode, /* Result code. */
1335 WINS_QUERY, /* nmbd type code. */
1336 NMB_NAME_QUERY_OPCODE, /* opcode. */
1338 prdata, /* data to send. */
1339 reply_data_len); /* data length. */
1341 if((prdata != rdata) && (prdata != NULL))
1345 /***********************************************************************
1346 Deal with a name query.
1347 ***********************************************************************/
1349 void wins_process_name_query_request(struct subnet_record *subrec,
1350 struct packet_struct *p)
1352 struct nmb_packet *nmb = &p->packet.nmb;
1353 struct nmb_name *question = &nmb->question.question_name;
1354 struct name_record *namerec = NULL;
1356 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1357 nmb_namestr(question), inet_ntoa(p->ip) ));
1360 * Special name code. If the queried name is *<1b> then search
1361 * the entire WINS database and return a list of all the IP addresses
1362 * registered to any <1b> name. This is to allow domain master browsers
1363 * to discover other domains that may not have a presence on their subnet.
1366 if(strequal( question->name, "*") && (question->name_type == 0x1b))
1368 process_wins_dmb_query_request( subrec, p);
1372 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1377 * If it's a DNSFAIL_NAME then reply name not found.
1380 if( namerec->data.source == DNSFAIL_NAME )
1382 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1383 nmb_namestr(question) ));
1384 send_wins_name_query_response(NAM_ERR, p, namerec);
1389 * If the name has expired then reply name not found.
1392 if( (namerec->data.death_time != PERMANENT_TTL)
1393 && (namerec->data.death_time < p->timestamp) )
1395 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1396 nmb_namestr(question) ));
1397 send_wins_name_query_response(NAM_ERR, p, namerec);
1401 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1402 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1404 send_wins_name_query_response(0, p, namerec);
1409 * Name not found in WINS - try a dns query if it's a 0x20 name.
1412 if(lp_dns_proxy() &&
1413 ((question->name_type == 0x20) || question->name_type == 0))
1416 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1417 nmb_namestr(question) ));
1419 queue_dns_query(p, question, &namerec);
1424 * Name not found - return error.
1427 send_wins_name_query_response(NAM_ERR, p, NULL);
1430 /****************************************************************************
1431 Send a WINS name release response.
1432 **************************************************************************/
1434 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1436 struct nmb_packet *nmb = &p->packet.nmb;
1439 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1441 reply_netbios_packet(p, /* Packet to reply to. */
1442 rcode, /* Result code. */
1443 NMB_REL, /* nmbd type code. */
1444 NMB_NAME_RELEASE_OPCODE, /* opcode. */
1446 rdata, /* data to send. */
1447 6); /* data length. */
1450 /***********************************************************************
1451 Deal with a name release.
1452 ***********************************************************************/
1454 void wins_process_name_release_request(struct subnet_record *subrec,
1455 struct packet_struct *p)
1457 struct nmb_packet *nmb = &p->packet.nmb;
1458 struct nmb_name *question = &nmb->question.question_name;
1459 BOOL bcast = nmb->header.nm_flags.bcast;
1460 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1461 struct name_record *namerec = NULL;
1462 struct in_addr from_ip;
1463 BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1465 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1470 * We should only get unicast name registration packets here.
1471 * Anyone trying to register broadcast should not be going to a WINS
1472 * server. Log an error here.
1475 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1476 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1477 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1481 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1482 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1485 * Deal with policy regarding 0x1d names.
1488 if(!releasing_group_name && (question->name_type == 0x1d))
1490 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1491 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1492 send_wins_name_release_response(0, p);
1497 * See if the name already exists.
1500 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1502 if( (namerec == NULL)
1503 || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1505 send_wins_name_release_response(NAM_ERR, p);
1510 * Check that the sending machine has permission to release this name.
1511 * If it's a group name not ending in 0x1c then just say yes and let
1512 * the group time out.
1515 if(releasing_group_name && (question->name_type != 0x1c))
1517 send_wins_name_release_response(0, p);
1522 * Check that the releasing node is on the list of IP addresses
1523 * for this name. Disallow the release if not.
1526 if(!find_ip_in_name_record(namerec, from_ip))
1528 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1529 release name %s as IP %s is not one of the known IP's for this name.\n",
1530 nmb_namestr(question), inet_ntoa(from_ip) ));
1531 send_wins_name_release_response(NAM_ERR, p);
1536 * Release the name and then remove the IP from the known list.
1539 send_wins_name_release_response(0, p);
1540 remove_ip_from_name_record(namerec, from_ip);
1542 wins_hook("delete", namerec, 0);
1545 * Remove the name entirely if no IP addresses left.
1547 if (namerec->data.num_ips == 0)
1548 remove_name_from_namelist(subrec, namerec);
1552 /*******************************************************************
1553 WINS time dependent processing.
1554 ******************************************************************/
1556 void initiate_wins_processing(time_t t)
1558 static time_t lasttime = 0;
1562 if (t - lasttime < 20)
1567 if(!lp_we_are_a_wins_server())
1570 expire_names_on_subnet(wins_server_subnet, t);
1572 if(wins_server_subnet->namelist_changed)
1573 wins_write_database(True);
1575 wins_server_subnet->namelist_changed = False;
1578 /*******************************************************************
1579 Write out the current WINS database.
1580 ******************************************************************/
1581 void wins_write_database(BOOL background)
1583 struct name_record *namerec;
1584 pstring fname, fnamenew;
1588 if(!lp_we_are_a_wins_server())
1591 /* we will do the writing in a child process to ensure that the parent
1592 doesn't block while this is done */
1600 slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
1601 all_string_sub(fname,"//", "/", 0);
1602 slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
1604 if((fp = sys_fopen(fnamenew,"w")) == NULL)
1606 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1613 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1615 fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
1618 = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1620 namerec = (struct name_record *)ubi_trNext( namerec ) )
1625 DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
1627 if( namerec->data.death_time != PERMANENT_TTL )
1631 tm = LocalTime(&namerec->data.death_time);
1633 nl = strrchr( ts, '\n' );
1636 DEBUGADD(4,("TTL = %s ", ts ));
1639 DEBUGADD(4,("TTL = PERMANENT "));
1641 for (i = 0; i < namerec->data.num_ips; i++)
1642 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1643 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1645 if( namerec->data.source == REGISTER_NAME )
1647 fprintf(fp, "\"%s#%02x\" %d ",
1648 namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1649 (int)namerec->data.death_time);
1651 for (i = 0; i < namerec->data.num_ips; i++)
1652 fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1653 fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1658 chmod(fnamenew,0644);
1660 rename(fnamenew,fname);