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,sizeof(name_str)))
216 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
220 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
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,sizeof(ip_str));
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,sizeof(name_str));
264 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
265 for(i = 0; i < num_ips; i++)
267 next_token(&ptr, ip_str, NULL, sizeof(ip_str));
268 ip_list[i] = *interpret_addr2(ip_str);
269 if (ip_equal(ip_list[i], ipzero))
272 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
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
423 * treat it like a registration request. This allows us to recover
424 * from errors (tridge)
429 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
430 the name does not exist. Treating as registration.\n", namestr(question) ));
431 wins_process_name_registration_request(subrec,p);
436 * Check that the group bits for the refreshing name and the
437 * name in our database match.
440 if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
442 DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
443 does not match group bit in WINS for this name.\n", namestr(question), group ? "True" : "False" ));
444 send_wins_name_registration_response(RFS_ERR, 0, p);
449 * For a unique name check that the person refreshing the name is one of the registered IP
450 * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
451 * Just return success for unique 0x1d refreshes. For normal group names update the ttl
452 * and return success.
455 if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
460 update_name_ttl(namerec, ttl);
461 send_wins_name_registration_response(0, ttl, p);
467 * Normal groups are all registered with an IP address of 255.255.255.255
468 * so we can't search for the IP address.
470 update_name_ttl(namerec, ttl);
471 send_wins_name_registration_response(0, ttl, p);
474 else if(!group && (question->name_type == 0x1d))
477 * Special name type - just pretend the refresh succeeded.
479 send_wins_name_registration_response(0, ttl, p);
488 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
489 is IP is not known to the name.\n", namestr(question), inet_ntoa(from_ip) ));
490 send_wins_name_registration_response(RFS_ERR, 0, p);
495 /***********************************************************************
496 Deal with a name registration request query success to a client that
499 We have a locked pointer to the original packet stashed away in the
500 userdata pointer. The success here is actually a failure as it means
501 the client we queried wants to keep the name, so we must return
502 a registration failure to the original requestor.
503 ************************************************************************/
505 static void wins_register_query_success(struct subnet_record *subrec,
506 struct userdata_struct *userdata,
507 struct nmb_name *question_name,
509 struct res_rec *answers)
511 struct packet_struct *orig_reg_packet;
513 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
515 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
516 name %s. Rejecting registration request.\n", inet_ntoa(ip), namestr(question_name) ));
518 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
520 orig_reg_packet->locked = False;
521 free_packet(orig_reg_packet);
524 /***********************************************************************
525 Deal with a name registration request query failure to a client that
528 We have a locked pointer to the original packet stashed away in the
529 userdata pointer. The failure here is actually a success as it means
530 the client we queried didn't want to keep the name, so we can remove
531 the old name record and then successfully add the new name.
532 ************************************************************************/
534 static void wins_register_query_fail(struct subnet_record *subrec,
535 struct response_record *rrec,
536 struct nmb_name *question_name,
539 struct userdata_struct *userdata = rrec->userdata;
540 struct packet_struct *orig_reg_packet;
541 struct nmb_packet *nmb;
542 struct name_record *namerec = NULL;
546 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
548 nmb = &orig_reg_packet->packet.nmb;
550 nb_flags = get_nb_flags(nmb->additional->rdata);
551 group = (nb_flags & NB_GROUP) ? True : False;
554 * We want to just add the name, as we now know the original owner
555 * didn't want it. But we can't just do that as an arbitary
556 * amount of time may have taken place between the name query
557 * request and this timeout/error response. So we check that
558 * the name still exists and is in the same state - if so
559 * we remove it and call wins_process_name_registration_request()
560 * as we know it will do the right thing now.
563 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
565 if( (namerec != NULL)
566 && (namerec->data.source == REGISTER_NAME)
567 && ip_equal(rrec->packet->ip, *namerec->data.ip) )
569 remove_name_from_namelist( subrec, namerec);
574 wins_process_name_registration_request(subrec, orig_reg_packet);
576 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
577 querying for name %s in order to replace it and this reply.\n", namestr(question_name) ));
579 orig_reg_packet->locked = False;
580 free_packet(orig_reg_packet);
583 /***********************************************************************
584 Deal with a name registration request to a WINS server.
586 Use the following pseudocode :
594 | +--- existing name is group
597 | | +--- add name (return).
600 | +--- exiting name is unique
603 | +--- query existing owner (return).
606 +--------name doesn't exist
609 +--- add name (return).
617 | +--- existing name is group
620 | | +--- fail add (return).
623 | +--- exiting name is unique
626 | +--- query existing owner (return).
629 +--------name doesn't exist
632 +--- add name (return).
634 As can be seen from the above, the two cases may be collapsed onto each
635 other with the exception of the case where the name already exists and
636 is a group name. This case we handle with an if statement.
638 ************************************************************************/
640 void wins_process_name_registration_request(struct subnet_record *subrec,
641 struct packet_struct *p)
643 struct nmb_packet *nmb = &p->packet.nmb;
644 struct nmb_name *question = &nmb->question.question_name;
645 BOOL bcast = nmb->header.nm_flags.bcast;
646 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
647 int ttl = get_ttl_from_packet(nmb);
648 struct name_record *namerec = NULL;
649 struct in_addr from_ip;
650 BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
652 putip((char *)&from_ip,&nmb->additional->rdata[2]);
657 * We should only get unicast name registration packets here.
658 * Anyone trying to register broadcast should not be going to a WINS
659 * server. Log an error here.
662 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
663 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
664 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
668 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
669 IP %s\n", registering_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
672 * See if the name already exists.
675 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
678 * Deal with the case where the name found was a dns entry.
679 * Remove it as we now have a NetBIOS client registering the
683 if( (namerec != NULL)
684 && ( (namerec->data.source == DNS_NAME)
685 || (namerec->data.source == DNSFAIL_NAME) ) )
687 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
688 a dns lookup - removing it.\n", namestr(question) ));
689 remove_name_from_namelist( subrec, namerec );
694 * Reject if the name exists and is not a REGISTER_NAME.
695 * (ie. Don't allow any static names to be overwritten.
698 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
700 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
701 to register name %s. Name already exists in WINS with source type %d.\n",
702 namestr(question), namerec->data.source ));
703 send_wins_name_registration_response(RFS_ERR, 0, p);
708 * Special policy decisions based on MS documentation.
709 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
710 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
714 * A group name is always added as the local broadcast address, except
715 * for group names ending in 0x1c.
716 * Group names with type 0x1c are registered with individual IP addresses.
719 if(registering_group_name && (question->name_type != 0x1c))
720 from_ip = *interpret_addr2("255.255.255.255");
723 * Ignore all attempts to register a unique 0x1d name, although return success.
726 if(!registering_group_name && (question->name_type == 0x1d))
728 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
729 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
730 send_wins_name_registration_response(0, ttl, p);
735 * Next two cases are the 'if statement' mentioned above.
738 if((namerec != NULL) && NAME_GROUP(namerec))
740 if(registering_group_name)
743 * If we are adding a group name, the name exists and is also a group entry just add this
744 * IP address to it and update the ttl.
747 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
748 inet_ntoa(from_ip), namestr(question) ));
750 * Check the ip address is not already in the group.
752 if(!find_ip_in_name_record(namerec, from_ip))
753 add_ip_to_name_record(namerec, from_ip);
754 update_name_ttl(namerec, ttl);
755 send_wins_name_registration_response(0, ttl, p);
761 * If we are adding a unique name, the name exists in the WINS db
762 * and is a group name then reject the registration.
765 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
766 already exists in WINS as a GROUP name.\n", namestr(question) ));
767 send_wins_name_registration_response(RFS_ERR, 0, p);
773 * From here on down we know that if the name exists in the WINS db it is
774 * a unique name, not a group name.
778 * If the name exists and is one of our names then check the
779 * registering IP address. If it's not one of ours then automatically
780 * reject without doing the query - we know we will reject it.
783 if((namerec != NULL) && (is_myname(namerec->name.name)) )
787 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
788 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
789 send_wins_name_registration_response(RFS_ERR, 0, p);
795 * It's one of our names and one of our IP's - update the ttl.
797 update_name_ttl(namerec, ttl);
798 send_wins_name_registration_response(0, ttl, p);
804 * If the name exists and it is a unique registration and the registering IP
805 * is the same as the the (single) already registered IP then just update the ttl.
808 if( !registering_group_name
810 && (namerec->data.num_ips == 1)
811 && ip_equal( namerec->data.ip[0], from_ip ) )
813 update_name_ttl( namerec, ttl );
814 send_wins_name_registration_response( 0, ttl, p );
819 * Finally if the name exists do a query to the registering machine
820 * to see if they still claim to have the name.
823 if( namerec != NULL )
825 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
826 struct userdata_struct *userdata = (struct userdata_struct *)ud;
829 * First send a WACK to the registering machine.
832 send_wins_wack_response(60, p);
835 * When the reply comes back we need the original packet.
836 * Lock this so it won't be freed and then put it into
837 * the userdata structure.
842 userdata = (struct userdata_struct *)ud;
844 userdata->copy_fn = NULL;
845 userdata->free_fn = NULL;
846 userdata->userdata_len = sizeof(struct packet_struct *);
847 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
850 * Use the new call to send a query directly to an IP address.
851 * This sends the query directly to the IP address, and ensures
852 * the recursion desired flag is not set (you were right Luke :-).
853 * This function should *only* be called from the WINS server
857 query_name_from_wins_server( *namerec->data.ip,
860 wins_register_query_success,
861 wins_register_query_fail,
867 * Name did not exist - add it.
870 (void)add_name_to_subnet( subrec, question->name, question->name_type,
871 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
873 send_wins_name_registration_response(0, ttl, p);
876 /***********************************************************************
877 Deal with a mutihomed name query success to the machine that
878 requested the multihomed name registration.
880 We have a locked pointer to the original packet stashed away in the
882 ************************************************************************/
884 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
885 struct userdata_struct *userdata,
886 struct nmb_name *question_name,
888 struct res_rec *answers)
890 struct packet_struct *orig_reg_packet;
891 struct nmb_packet *nmb;
892 struct name_record *namerec = NULL;
893 struct in_addr from_ip;
896 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
898 nmb = &orig_reg_packet->packet.nmb;
900 putip((char *)&from_ip,&nmb->additional->rdata[2]);
901 ttl = get_ttl_from_packet(nmb);
904 * We want to just add the new IP, as we now know the requesting
905 * machine claims to own it. But we can't just do that as an arbitary
906 * amount of time may have taken place between the name query
907 * request and this response. So we check that
908 * the name still exists and is in the same state - if so
909 * we just add the extra IP and update the ttl.
912 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
914 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
916 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
917 a subsequent IP addess.\n", namestr(question_name) ));
918 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
920 orig_reg_packet->locked = False;
921 free_packet(orig_reg_packet);
926 if(!find_ip_in_name_record(namerec, from_ip))
927 add_ip_to_name_record(namerec, from_ip);
928 update_name_ttl(namerec, ttl);
929 send_wins_name_registration_response(0, ttl, orig_reg_packet);
931 orig_reg_packet->locked = False;
932 free_packet(orig_reg_packet);
935 /***********************************************************************
936 Deal with a name registration request query failure to a client that
939 We have a locked pointer to the original packet stashed away in the
941 ************************************************************************/
943 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
944 struct response_record *rrec,
945 struct nmb_name *question_name,
948 struct userdata_struct *userdata = rrec->userdata;
949 struct packet_struct *orig_reg_packet;
951 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
953 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
954 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), namestr(question_name) ));
955 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
957 orig_reg_packet->locked = False;
958 free_packet(orig_reg_packet);
962 /***********************************************************************
963 Deal with a multihomed name registration request to a WINS server.
964 These cannot be group name registrations.
965 ***********************************************************************/
967 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
968 struct packet_struct *p)
970 struct nmb_packet *nmb = &p->packet.nmb;
971 struct nmb_name *question = &nmb->question.question_name;
972 BOOL bcast = nmb->header.nm_flags.bcast;
973 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
974 int ttl = get_ttl_from_packet(nmb);
975 struct name_record *namerec = NULL;
976 struct in_addr from_ip;
977 BOOL group = (nb_flags & NB_GROUP) ? True : False;;
979 putip((char *)&from_ip,&nmb->additional->rdata[2]);
984 * We should only get unicast name registration packets here.
985 * Anyone trying to register broadcast should not be going to a WINS
986 * server. Log an error here.
989 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
990 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
991 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
996 * Only unique names should be registered multihomed.
1001 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1002 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1003 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1007 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1008 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
1011 * Deal with policy regarding 0x1d names.
1014 if(question->name_type == 0x1d)
1016 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1017 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1018 send_wins_name_registration_response(0, ttl, p);
1023 * See if the name already exists.
1026 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1029 * Deal with the case where the name found was a dns entry.
1030 * Remove it as we now have a NetBIOS client registering the
1034 if( (namerec != NULL)
1035 && ( (namerec->data.source == DNS_NAME)
1036 || (namerec->data.source == DNSFAIL_NAME) ) )
1038 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1039 - removing it.\n", namestr(question) ));
1040 remove_name_from_namelist( subrec, namerec);
1045 * Reject if the name exists and is not a REGISTER_NAME.
1046 * (ie. Don't allow any static names to be overwritten.
1049 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1051 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1052 to register name %s. Name already exists in WINS with source type %d.\n",
1053 namestr(question), namerec->data.source ));
1054 send_wins_name_registration_response(RFS_ERR, 0, p);
1059 * Reject if the name exists and is a GROUP name.
1062 if((namerec != NULL) && NAME_GROUP(namerec))
1064 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1065 already exists in WINS as a GROUP name.\n", namestr(question) ));
1066 send_wins_name_registration_response(RFS_ERR, 0, p);
1071 * From here on down we know that if the name exists in the WINS db it is
1072 * a unique name, not a group name.
1076 * If the name exists and is one of our names then check the
1077 * registering IP address. If it's not one of ours then automatically
1078 * reject without doing the query - we know we will reject it.
1081 if((namerec != NULL) && (is_myname(namerec->name.name)) )
1083 if(!ismyip(from_ip))
1085 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1086 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
1087 send_wins_name_registration_response(RFS_ERR, 0, p);
1093 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1096 if(!find_ip_in_name_record(namerec, from_ip))
1097 add_ip_to_name_record(namerec, from_ip);
1098 update_name_ttl(namerec, ttl);
1099 send_wins_name_registration_response(0, ttl, p);
1105 * If the name exists check if the IP address is already registered
1106 * to that name. If so then update the ttl and reply success.
1109 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1111 update_name_ttl(namerec, ttl);
1112 send_wins_name_registration_response(0, ttl, p);
1117 * If the name exists do a query to the owner
1118 * to see if they still want the name.
1123 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1124 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1127 * First send a WACK to the registering machine.
1130 send_wins_wack_response(60, p);
1133 * When the reply comes back we need the original packet.
1134 * Lock this so it won't be freed and then put it into
1135 * the userdata structure.
1140 userdata = (struct userdata_struct *)ud;
1142 userdata->copy_fn = NULL;
1143 userdata->free_fn = NULL;
1144 userdata->userdata_len = sizeof(struct packet_struct *);
1145 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1148 * Use the new call to send a query directly to an IP address.
1149 * This sends the query directly to the IP address, and ensures
1150 * the recursion desired flag is not set (you were right Luke :-).
1151 * This function should *only* be called from the WINS server
1155 query_name_from_wins_server( p->ip,
1157 question->name_type,
1158 wins_multihomed_register_query_success,
1159 wins_multihomed_register_query_fail,
1166 * Name did not exist - add it.
1169 (void)add_name_to_subnet( subrec, question->name, question->name_type,
1170 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
1172 send_wins_name_registration_response(0, ttl, p);
1175 /***********************************************************************
1176 Deal with the special name query for *<1b>.
1177 ***********************************************************************/
1179 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1180 struct packet_struct *p)
1182 struct name_record *namerec = NULL;
1187 * Go through all the names in the WINS db looking for those
1188 * ending in <1b>. Use this to calculate the number of IP
1189 * addresses we need to return.
1193 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1195 namerec = (struct name_record *)ubi_trNext( namerec ) )
1197 if( namerec->name.name_type == 0x1b )
1198 num_ips += namerec->data.num_ips;
1204 * There are no 0x1b names registered. Return name query fail.
1206 send_wins_name_query_response(NAM_ERR, p, NULL);
1210 if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1212 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1217 * Go through all the names again in the WINS db looking for those
1218 * ending in <1b>. Add their IP addresses into the list we will
1223 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1225 namerec = (struct name_record *)ubi_trNext( namerec ) )
1227 if(namerec->name.name_type == 0x1b)
1230 for(i = 0; i < namerec->data.num_ips; i++)
1232 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1233 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1240 * Send back the reply containing the IP list.
1243 reply_netbios_packet(p, /* Packet to reply to. */
1244 0, /* Result code. */
1245 WINS_QUERY, /* nmbd type code. */
1246 NMB_NAME_QUERY_OPCODE, /* opcode. */
1247 lp_min_wins_ttl(), /* ttl. */
1248 prdata, /* data to send. */
1249 num_ips*6); /* data length. */
1254 /****************************************************************************
1255 Send a WINS name query response.
1256 **************************************************************************/
1258 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1259 struct name_record *namerec)
1262 char *prdata = rdata;
1263 int reply_data_len = 0;
1271 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1272 namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1274 /* Copy all known ip addresses into the return data. */
1275 /* Optimise for the common case of one IP address so
1276 we don't need a malloc. */
1278 if( namerec->data.num_ips == 1 )
1282 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1284 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1289 for(i = 0; i < namerec->data.num_ips; i++)
1291 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1292 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1295 sort_query_replies(prdata, i, p->ip);
1297 reply_data_len = namerec->data.num_ips * 6;
1300 reply_netbios_packet(p, /* Packet to reply to. */
1301 rcode, /* Result code. */
1302 WINS_QUERY, /* nmbd type code. */
1303 NMB_NAME_QUERY_OPCODE, /* opcode. */
1305 prdata, /* data to send. */
1306 reply_data_len); /* data length. */
1308 if((prdata != rdata) && (prdata != NULL))
1312 /***********************************************************************
1313 Deal with a name query.
1314 ***********************************************************************/
1316 void wins_process_name_query_request(struct subnet_record *subrec,
1317 struct packet_struct *p)
1319 struct nmb_packet *nmb = &p->packet.nmb;
1320 struct nmb_name *question = &nmb->question.question_name;
1321 struct name_record *namerec = NULL;
1323 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1324 namestr(question), inet_ntoa(p->ip) ));
1327 * Special name code. If the queried name is *<1b> then search
1328 * the entire WINS database and return a list of all the IP addresses
1329 * registered to any <1b> name. This is to allow domain master browsers
1330 * to discover other domains that may not have a presence on their subnet.
1333 if(strequal( question->name, "*") && (question->name_type == 0x1b))
1335 process_wins_dmb_query_request( subrec, p);
1339 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1344 * If it's a DNSFAIL_NAME then reply name not found.
1347 if( namerec->data.source == DNSFAIL_NAME )
1349 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1350 namestr(question) ));
1351 send_wins_name_query_response(NAM_ERR, p, namerec);
1356 * If the name has expired then reply name not found.
1359 if( (namerec->data.death_time != PERMANENT_TTL)
1360 && (namerec->data.death_time < p->timestamp) )
1362 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1363 namestr(question) ));
1364 send_wins_name_query_response(NAM_ERR, p, namerec);
1368 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1369 namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1371 send_wins_name_query_response(0, p, namerec);
1376 * Name not found in WINS - try a dns query if it's a 0x20 name.
1379 if(lp_dns_proxy() &&
1380 ((question->name_type == 0x20) || question->name_type == 0))
1383 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1384 namestr(question) ));
1386 queue_dns_query(p, question, &namerec);
1391 * Name not found - return error.
1394 send_wins_name_query_response(NAM_ERR, p, NULL);
1397 /****************************************************************************
1398 Send a WINS name release response.
1399 **************************************************************************/
1401 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1403 struct nmb_packet *nmb = &p->packet.nmb;
1406 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1408 reply_netbios_packet(p, /* Packet to reply to. */
1409 rcode, /* Result code. */
1410 NMB_REL, /* nmbd type code. */
1411 NMB_NAME_RELEASE_OPCODE, /* opcode. */
1413 rdata, /* data to send. */
1414 6); /* data length. */
1417 /***********************************************************************
1418 Deal with a name release.
1419 ***********************************************************************/
1421 void wins_process_name_release_request(struct subnet_record *subrec,
1422 struct packet_struct *p)
1424 struct nmb_packet *nmb = &p->packet.nmb;
1425 struct nmb_name *question = &nmb->question.question_name;
1426 BOOL bcast = nmb->header.nm_flags.bcast;
1427 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1428 struct name_record *namerec = NULL;
1429 struct in_addr from_ip;
1430 BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1432 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1437 * We should only get unicast name registration packets here.
1438 * Anyone trying to register broadcast should not be going to a WINS
1439 * server. Log an error here.
1442 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1443 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1444 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1448 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1449 IP %s\n", releasing_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
1452 * Deal with policy regarding 0x1d names.
1455 if(!releasing_group_name && (question->name_type == 0x1d))
1457 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1458 to release name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1459 send_wins_name_release_response(0, p);
1464 * See if the name already exists.
1467 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1469 if( (namerec == NULL)
1470 || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1472 send_wins_name_release_response(NAM_ERR, p);
1477 * Check that the sending machine has permission to release this name.
1478 * If it's a group name not ending in 0x1c then just say yes and let
1479 * the group time out.
1482 if(releasing_group_name && (question->name_type != 0x1c))
1484 send_wins_name_release_response(0, p);
1489 * Check that the releasing node is on the list of IP addresses
1490 * for this name. Disallow the release if not.
1493 if(!find_ip_in_name_record(namerec, from_ip))
1495 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1496 release name %s as IP %s is not one of the known IP's for this name.\n",
1497 namestr(question), inet_ntoa(from_ip) ));
1498 send_wins_name_release_response(NAM_ERR, p);
1503 * Release the name and then remove the IP from the known list.
1506 send_wins_name_release_response(0, p);
1507 remove_ip_from_name_record(namerec, from_ip);
1510 * Remove the name entirely if no IP addresses left.
1512 if (namerec->data.num_ips == 0)
1513 remove_name_from_namelist(subrec, namerec);
1517 /*******************************************************************
1518 WINS time dependent processing.
1519 ******************************************************************/
1521 void initiate_wins_processing(time_t t)
1523 static time_t lasttime = 0;
1527 if (t - lasttime < 20)
1532 if(!lp_we_are_a_wins_server())
1535 expire_names_on_subnet(wins_server_subnet, t);
1537 if(wins_server_subnet->namelist_changed)
1538 wins_write_database(True);
1540 wins_server_subnet->namelist_changed = False;
1543 /*******************************************************************
1544 Write out the current WINS database.
1545 ******************************************************************/
1546 void wins_write_database(BOOL background)
1548 struct name_record *namerec;
1549 pstring fname, fnamenew;
1550 static int child_pid;
1554 if(!lp_we_are_a_wins_server())
1557 /* we will do the writing in a child process to ensure that the parent
1558 doesn't block while this is done */
1561 if ((child_pid=fork())) {
1566 slprintf(fname,sizeof(fname),"%s/%s", lp_lockdir(), WINS_LIST);
1567 string_sub(fname,"//", "/");
1568 slprintf(fnamenew,sizeof(fnamenew),"%s.%u", fname, (unsigned int)getpid());
1570 if((fp = fopen(fnamenew,"w")) == NULL)
1572 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1579 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1581 fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
1584 = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1586 namerec = (struct name_record *)ubi_trNext( namerec ) )
1591 DEBUGADD(4,("%-19s ", namestr(&namerec->name) ));
1593 if( namerec->data.death_time != PERMANENT_TTL )
1595 tm = LocalTime(&namerec->data.death_time);
1596 DEBUGADD(4,("TTL = %s", asctime(tm) ));
1599 DEBUGADD(4,("TTL = PERMANENT\t"));
1601 for (i = 0; i < namerec->data.num_ips; i++)
1602 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1603 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1605 if( namerec->data.source == REGISTER_NAME )
1607 fprintf(fp, "\"%s#%02x\" %d ",
1608 namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1609 (int)namerec->data.death_time);
1611 for (i = 0; i < namerec->data.num_ips; i++)
1612 fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1613 fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1618 chmod(fnamenew,0644);
1620 rename(fnamenew,fname);