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), "%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), " %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)
176 time_t time_now = time(NULL);
180 if(!lp_we_are_a_wins_server())
183 add_samba_names_to_subnet(wins_server_subnet);
185 pstrcpy(fname,lp_lockdir());
186 trim_string(fname,NULL,"/");
188 pstrcat(fname,WINS_LIST);
190 if((fp = sys_fopen(fname,"r")) == NULL)
192 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
193 fname, strerror(errno) ));
199 pstring name_str, ip_str, ttl_str, nb_flags_str;
200 unsigned int num_ips;
202 struct in_addr *ip_list;
214 /* Read a line from the wins.dat file. Strips whitespace
215 from the beginning and end of the line.
217 if (!fgets_slash(line,sizeof(pstring),fp))
223 if (strncmp(line,"VERSION ", 8) == 0) {
224 if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
225 version != WINS_VERSION ||
226 hash != wins_hash()) {
227 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
237 * Now we handle multiple IP addresses per name we need
238 * to iterate over the line twice. The first time to
239 * determine how many IP addresses there are, the second
240 * time to actually parse them into the ip_list array.
243 if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
245 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
249 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
251 DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
256 * Determine the number of IP addresses per line.
261 got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
264 if(got_token && strchr(ip_str, '.'))
269 } while( got_token && was_ip);
273 DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
279 DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
283 /* Allocate the space for the ip_list. */
284 if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
286 DEBUG(0,("initialise_wins: Malloc fail !\n"));
290 /* Reset and re-parse the line. */
292 next_token(&ptr,name_str,NULL,sizeof(name_str));
293 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
294 for(i = 0; i < num_ips; i++)
296 next_token(&ptr, ip_str, NULL, sizeof(ip_str));
297 ip_list[i] = *interpret_addr2(ip_str);
299 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
302 * Deal with SELF or REGISTER name encoding. Default is REGISTER
303 * for compatibility with old nmbds.
306 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
308 DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
309 free((char *)ip_list);
313 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
314 nb_flags_str[strlen(nb_flags_str)-1] = '\0';
316 /* Netbios name. # divides the name from the type (hex): netbios#xx */
317 pstrcpy(name,name_str);
319 if((p = strchr(name,'#')) != NULL)
322 sscanf(p+1,"%x",&type);
325 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
326 sscanf(nb_flags_str,"%x",&nb_flags);
327 sscanf(ttl_str,"%d",&ttl);
329 /* add all entries that have 60 seconds or more to live */
330 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
332 if(ttl != PERMANENT_TTL)
335 DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
336 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
338 (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
339 ttl, REGISTER_NAME, num_ips, ip_list );
344 DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
345 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
348 free((char *)ip_list);
355 /****************************************************************************
356 Send a WINS WACK (Wait ACKnowledgement) response.
357 **************************************************************************/
359 static void send_wins_wack_response(int ttl, struct packet_struct *p)
361 struct nmb_packet *nmb = &p->packet.nmb;
362 unsigned char rdata[2];
364 rdata[0] = rdata[1] = 0;
366 /* Taken from nmblib.c - we need to send back almost
367 identical bytes from the requesting packet header. */
369 rdata[0] = (nmb->header.opcode & 0xF) << 3;
370 if (nmb->header.nm_flags.authoritative &&
371 nmb->header.response) rdata[0] |= 0x4;
372 if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
373 if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
374 if (nmb->header.nm_flags.recursion_available &&
375 nmb->header.response) rdata[1] |= 0x80;
376 if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
378 reply_netbios_packet(p, /* Packet to reply to. */
379 0, /* Result code. */
380 NMB_WAIT_ACK, /* nmbd type code. */
381 NMB_WACK_OPCODE, /* opcode. */
383 (char *)rdata, /* data to send. */
384 2); /* data length. */
387 /****************************************************************************
388 Send a WINS name registration response.
389 **************************************************************************/
391 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
393 struct nmb_packet *nmb = &p->packet.nmb;
396 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
398 reply_netbios_packet(p, /* Packet to reply to. */
399 rcode, /* Result code. */
400 WINS_REG, /* nmbd type code. */
401 NMB_NAME_REG_OPCODE, /* opcode. */
403 rdata, /* data to send. */
404 6); /* data length. */
407 /***********************************************************************
408 Deal with a name refresh request to a WINS server.
409 ************************************************************************/
411 void wins_process_name_refresh_request(struct subnet_record *subrec,
412 struct packet_struct *p)
414 struct nmb_packet *nmb = &p->packet.nmb;
415 struct nmb_name *question = &nmb->question.question_name;
416 BOOL bcast = nmb->header.nm_flags.bcast;
417 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
418 BOOL group = (nb_flags & NB_GROUP) ? True : False;
419 struct name_record *namerec = NULL;
420 int ttl = get_ttl_from_packet(nmb);
421 struct in_addr from_ip;
423 putip((char *)&from_ip,&nmb->additional->rdata[2]);
428 * We should only get unicast name refresh packets here.
429 * Anyone trying to refresh broadcast should not be going to a WINS
430 * server. Log an error here.
433 DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
434 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
435 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
439 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
440 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
443 * See if the name already exists.
446 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
449 * If this is a refresh request and the name doesn't exist then
450 * treat it like a registration request. This allows us to recover
451 * from errors (tridge)
456 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
457 the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
458 wins_process_name_registration_request(subrec,p);
463 * Check that the group bits for the refreshing name and the
464 * name in our database match.
467 if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
469 DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
470 does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
471 send_wins_name_registration_response(RFS_ERR, 0, p);
476 * For a unique name check that the person refreshing the name is one of the registered IP
477 * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
478 * Just return success for unique 0x1d refreshes. For normal group names update the ttl
479 * and return success.
482 if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
487 update_name_ttl(namerec, ttl);
488 send_wins_name_registration_response(0, ttl, p);
489 wins_hook("refresh", namerec, ttl);
495 * Normal groups are all registered with an IP address of 255.255.255.255
496 * so we can't search for the IP address.
498 update_name_ttl(namerec, ttl);
499 send_wins_name_registration_response(0, ttl, p);
502 else if(!group && (question->name_type == 0x1d))
505 * Special name type - just pretend the refresh succeeded.
507 send_wins_name_registration_response(0, ttl, p);
516 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
517 is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
518 send_wins_name_registration_response(RFS_ERR, 0, p);
523 /***********************************************************************
524 Deal with a name registration request query success to a client that
527 We have a locked pointer to the original packet stashed away in the
528 userdata pointer. The success here is actually a failure as it means
529 the client we queried wants to keep the name, so we must return
530 a registration failure to the original requestor.
531 ************************************************************************/
533 static void wins_register_query_success(struct subnet_record *subrec,
534 struct userdata_struct *userdata,
535 struct nmb_name *question_name,
537 struct res_rec *answers)
539 struct packet_struct *orig_reg_packet;
541 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
543 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
544 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
546 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
548 orig_reg_packet->locked = False;
549 free_packet(orig_reg_packet);
552 /***********************************************************************
553 Deal with a name registration request query failure to a client that
556 We have a locked pointer to the original packet stashed away in the
557 userdata pointer. The failure here is actually a success as it means
558 the client we queried didn't want to keep the name, so we can remove
559 the old name record and then successfully add the new name.
560 ************************************************************************/
562 static void wins_register_query_fail(struct subnet_record *subrec,
563 struct response_record *rrec,
564 struct nmb_name *question_name,
567 struct userdata_struct *userdata = rrec->userdata;
568 struct packet_struct *orig_reg_packet;
569 struct name_record *namerec = NULL;
571 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
574 * We want to just add the name, as we now know the original owner
575 * didn't want it. But we can't just do that as an arbitary
576 * amount of time may have taken place between the name query
577 * request and this timeout/error response. So we check that
578 * the name still exists and is in the same state - if so
579 * we remove it and call wins_process_name_registration_request()
580 * as we know it will do the right thing now.
583 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
585 if( (namerec != NULL)
586 && (namerec->data.source == REGISTER_NAME)
587 && ip_equal(rrec->packet->ip, *namerec->data.ip) )
589 remove_name_from_namelist( subrec, namerec);
594 wins_process_name_registration_request(subrec, orig_reg_packet);
596 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
597 querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
599 orig_reg_packet->locked = False;
600 free_packet(orig_reg_packet);
603 /***********************************************************************
604 Deal with a name registration request to a WINS server.
606 Use the following pseudocode :
614 | +--- existing name is group
617 | | +--- add name (return).
620 | +--- exiting name is unique
623 | +--- query existing owner (return).
626 +--------name doesn't exist
629 +--- add name (return).
637 | +--- existing name is group
640 | | +--- fail add (return).
643 | +--- exiting name is unique
646 | +--- query existing owner (return).
649 +--------name doesn't exist
652 +--- add name (return).
654 As can be seen from the above, the two cases may be collapsed onto each
655 other with the exception of the case where the name already exists and
656 is a group name. This case we handle with an if statement.
658 ************************************************************************/
660 void wins_process_name_registration_request(struct subnet_record *subrec,
661 struct packet_struct *p)
663 struct nmb_packet *nmb = &p->packet.nmb;
664 struct nmb_name *question = &nmb->question.question_name;
665 BOOL bcast = nmb->header.nm_flags.bcast;
666 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
667 int ttl = get_ttl_from_packet(nmb);
668 struct name_record *namerec = NULL;
669 struct in_addr from_ip;
670 BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
672 putip((char *)&from_ip,&nmb->additional->rdata[2]);
677 * We should only get unicast name registration packets here.
678 * Anyone trying to register broadcast should not be going to a WINS
679 * server. Log an error here.
682 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
683 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
684 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
688 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
689 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
692 * See if the name already exists.
695 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
698 * Deal with the case where the name found was a dns entry.
699 * Remove it as we now have a NetBIOS client registering the
703 if( (namerec != NULL)
704 && ( (namerec->data.source == DNS_NAME)
705 || (namerec->data.source == DNSFAIL_NAME) ) )
707 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
708 a dns lookup - removing it.\n", nmb_namestr(question) ));
709 remove_name_from_namelist( subrec, namerec );
714 * Reject if the name exists and is not a REGISTER_NAME.
715 * (ie. Don't allow any static names to be overwritten.
718 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
720 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
721 to register name %s. Name already exists in WINS with source type %d.\n",
722 nmb_namestr(question), namerec->data.source ));
723 send_wins_name_registration_response(RFS_ERR, 0, p);
728 * Special policy decisions based on MS documentation.
729 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
730 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
734 * A group name is always added as the local broadcast address, except
735 * for group names ending in 0x1c.
736 * Group names with type 0x1c are registered with individual IP addresses.
739 if(registering_group_name && (question->name_type != 0x1c))
740 from_ip = *interpret_addr2("255.255.255.255");
743 * Ignore all attempts to register a unique 0x1d name, although return success.
746 if(!registering_group_name && (question->name_type == 0x1d))
748 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
749 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
750 send_wins_name_registration_response(0, ttl, p);
755 * Next two cases are the 'if statement' mentioned above.
758 if((namerec != NULL) && NAME_GROUP(namerec))
760 if(registering_group_name)
763 * If we are adding a group name, the name exists and is also a group entry just add this
764 * IP address to it and update the ttl.
767 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
768 inet_ntoa(from_ip), nmb_namestr(question) ));
770 * Check the ip address is not already in the group.
772 if(!find_ip_in_name_record(namerec, from_ip))
773 add_ip_to_name_record(namerec, from_ip);
774 update_name_ttl(namerec, ttl);
775 send_wins_name_registration_response(0, ttl, p);
781 * If we are adding a unique name, the name exists in the WINS db
782 * and is a group name then reject the registration.
785 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
786 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
787 send_wins_name_registration_response(RFS_ERR, 0, p);
793 * From here on down we know that if the name exists in the WINS db it is
794 * a unique name, not a group name.
798 * If the name exists and is one of our names then check the
799 * registering IP address. If it's not one of ours then automatically
800 * reject without doing the query - we know we will reject it.
803 if((namerec != NULL) && (is_myname(namerec->name.name)) )
807 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
808 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
809 send_wins_name_registration_response(RFS_ERR, 0, p);
815 * It's one of our names and one of our IP's - update the ttl.
817 update_name_ttl(namerec, ttl);
818 send_wins_name_registration_response(0, ttl, p);
819 wins_hook("refresh", namerec, ttl);
825 * If the name exists and it is a unique registration and the registering IP
826 * is the same as the the (single) already registered IP then just update the ttl.
829 if( !registering_group_name
831 && (namerec->data.num_ips == 1)
832 && ip_equal( namerec->data.ip[0], from_ip ) )
834 update_name_ttl( namerec, ttl );
835 send_wins_name_registration_response( 0, ttl, p );
836 wins_hook("refresh", namerec, ttl);
841 * Finally if the name exists do a query to the registering machine
842 * to see if they still claim to have the name.
845 if( namerec != NULL )
847 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
848 struct userdata_struct *userdata = (struct userdata_struct *)ud;
851 * First send a WACK to the registering machine.
854 send_wins_wack_response(60, p);
857 * When the reply comes back we need the original packet.
858 * Lock this so it won't be freed and then put it into
859 * the userdata structure.
864 userdata = (struct userdata_struct *)ud;
866 userdata->copy_fn = NULL;
867 userdata->free_fn = NULL;
868 userdata->userdata_len = sizeof(struct packet_struct *);
869 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
872 * Use the new call to send a query directly to an IP address.
873 * This sends the query directly to the IP address, and ensures
874 * the recursion desired flag is not set (you were right Luke :-).
875 * This function should *only* be called from the WINS server
879 query_name_from_wins_server( *namerec->data.ip,
882 wins_register_query_success,
883 wins_register_query_fail,
889 * Name did not exist - add it.
892 (void)add_name_to_subnet( subrec, question->name, question->name_type,
893 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
894 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
895 wins_hook("add", namerec, ttl);
898 send_wins_name_registration_response(0, ttl, p);
901 /***********************************************************************
902 Deal with a mutihomed name query success to the machine that
903 requested the multihomed name registration.
905 We have a locked pointer to the original packet stashed away in the
907 ************************************************************************/
909 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
910 struct userdata_struct *userdata,
911 struct nmb_name *question_name,
913 struct res_rec *answers)
915 struct packet_struct *orig_reg_packet;
916 struct nmb_packet *nmb;
917 struct name_record *namerec = NULL;
918 struct in_addr from_ip;
921 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
923 nmb = &orig_reg_packet->packet.nmb;
925 putip((char *)&from_ip,&nmb->additional->rdata[2]);
926 ttl = get_ttl_from_packet(nmb);
929 * We want to just add the new IP, as we now know the requesting
930 * machine claims to own it. But we can't just do that as an arbitary
931 * amount of time may have taken place between the name query
932 * request and this response. So we check that
933 * the name still exists and is in the same state - if so
934 * we just add the extra IP and update the ttl.
937 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
939 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
941 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
942 a subsequent IP addess.\n", nmb_namestr(question_name) ));
943 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
945 orig_reg_packet->locked = False;
946 free_packet(orig_reg_packet);
951 if(!find_ip_in_name_record(namerec, from_ip))
952 add_ip_to_name_record(namerec, from_ip);
953 update_name_ttl(namerec, ttl);
954 send_wins_name_registration_response(0, ttl, orig_reg_packet);
955 wins_hook("add", namerec, ttl);
957 orig_reg_packet->locked = False;
958 free_packet(orig_reg_packet);
961 /***********************************************************************
962 Deal with a name registration request query failure to a client that
965 We have a locked pointer to the original packet stashed away in the
967 ************************************************************************/
969 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
970 struct response_record *rrec,
971 struct nmb_name *question_name,
974 struct userdata_struct *userdata = rrec->userdata;
975 struct packet_struct *orig_reg_packet;
977 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
979 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
980 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
981 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
983 orig_reg_packet->locked = False;
984 free_packet(orig_reg_packet);
988 /***********************************************************************
989 Deal with a multihomed name registration request to a WINS server.
990 These cannot be group name registrations.
991 ***********************************************************************/
993 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
994 struct packet_struct *p)
996 struct nmb_packet *nmb = &p->packet.nmb;
997 struct nmb_name *question = &nmb->question.question_name;
998 BOOL bcast = nmb->header.nm_flags.bcast;
999 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1000 int ttl = get_ttl_from_packet(nmb);
1001 struct name_record *namerec = NULL;
1002 struct in_addr from_ip;
1003 BOOL group = (nb_flags & NB_GROUP) ? True : False;;
1005 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1010 * We should only get unicast name registration packets here.
1011 * Anyone trying to register broadcast should not be going to a WINS
1012 * server. Log an error here.
1015 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1016 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1017 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1022 * Only unique names should be registered multihomed.
1027 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1028 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1029 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1033 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1034 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1037 * Deal with policy regarding 0x1d names.
1040 if(question->name_type == 0x1d)
1042 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1043 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1044 send_wins_name_registration_response(0, ttl, p);
1049 * See if the name already exists.
1052 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1055 * Deal with the case where the name found was a dns entry.
1056 * Remove it as we now have a NetBIOS client registering the
1060 if( (namerec != NULL)
1061 && ( (namerec->data.source == DNS_NAME)
1062 || (namerec->data.source == DNSFAIL_NAME) ) )
1064 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1065 - removing it.\n", nmb_namestr(question) ));
1066 remove_name_from_namelist( subrec, namerec);
1071 * Reject if the name exists and is not a REGISTER_NAME.
1072 * (ie. Don't allow any static names to be overwritten.
1075 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1077 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1078 to register name %s. Name already exists in WINS with source type %d.\n",
1079 nmb_namestr(question), namerec->data.source ));
1080 send_wins_name_registration_response(RFS_ERR, 0, p);
1085 * Reject if the name exists and is a GROUP name.
1088 if((namerec != NULL) && NAME_GROUP(namerec))
1090 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1091 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1092 send_wins_name_registration_response(RFS_ERR, 0, p);
1097 * From here on down we know that if the name exists in the WINS db it is
1098 * a unique name, not a group name.
1102 * If the name exists and is one of our names then check the
1103 * registering IP address. If it's not one of ours then automatically
1104 * reject without doing the query - we know we will reject it.
1107 if((namerec != NULL) && (is_myname(namerec->name.name)) )
1109 if(!ismyip(from_ip))
1111 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1112 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1113 send_wins_name_registration_response(RFS_ERR, 0, p);
1119 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1122 if(!find_ip_in_name_record(namerec, from_ip)) {
1123 add_ip_to_name_record(namerec, from_ip);
1124 wins_hook("add", namerec, ttl);
1126 wins_hook("refresh", namerec, ttl);
1129 update_name_ttl(namerec, ttl);
1130 send_wins_name_registration_response(0, ttl, p);
1136 * If the name exists check if the IP address is already registered
1137 * to that name. If so then update the ttl and reply success.
1140 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1142 update_name_ttl(namerec, ttl);
1143 send_wins_name_registration_response(0, ttl, p);
1144 wins_hook("refresh", namerec, ttl);
1149 * If the name exists do a query to the owner
1150 * to see if they still want the name.
1155 char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1156 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1159 * First send a WACK to the registering machine.
1162 send_wins_wack_response(60, p);
1165 * When the reply comes back we need the original packet.
1166 * Lock this so it won't be freed and then put it into
1167 * the userdata structure.
1172 userdata = (struct userdata_struct *)ud;
1174 userdata->copy_fn = NULL;
1175 userdata->free_fn = NULL;
1176 userdata->userdata_len = sizeof(struct packet_struct *);
1177 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1180 * Use the new call to send a query directly to an IP address.
1181 * This sends the query directly to the IP address, and ensures
1182 * the recursion desired flag is not set (you were right Luke :-).
1183 * This function should *only* be called from the WINS server
1187 query_name_from_wins_server( p->ip,
1189 question->name_type,
1190 wins_multihomed_register_query_success,
1191 wins_multihomed_register_query_fail,
1198 * Name did not exist - add it.
1201 (void)add_name_to_subnet( subrec, question->name, question->name_type,
1202 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
1204 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1205 wins_hook("add", namerec, ttl);
1208 send_wins_name_registration_response(0, ttl, p);
1211 /***********************************************************************
1212 Deal with the special name query for *<1b>.
1213 ***********************************************************************/
1215 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1216 struct packet_struct *p)
1218 struct name_record *namerec = NULL;
1223 * Go through all the names in the WINS db looking for those
1224 * ending in <1b>. Use this to calculate the number of IP
1225 * addresses we need to return.
1229 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1231 namerec = (struct name_record *)ubi_trNext( namerec ) )
1233 if( namerec->name.name_type == 0x1b )
1234 num_ips += namerec->data.num_ips;
1240 * There are no 0x1b names registered. Return name query fail.
1242 send_wins_name_query_response(NAM_ERR, p, NULL);
1246 if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1248 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1253 * Go through all the names again in the WINS db looking for those
1254 * ending in <1b>. Add their IP addresses into the list we will
1259 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1261 namerec = (struct name_record *)ubi_trNext( namerec ) )
1263 if(namerec->name.name_type == 0x1b)
1266 for(i = 0; i < namerec->data.num_ips; i++)
1268 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1269 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1276 * Send back the reply containing the IP list.
1279 reply_netbios_packet(p, /* Packet to reply to. */
1280 0, /* Result code. */
1281 WINS_QUERY, /* nmbd type code. */
1282 NMB_NAME_QUERY_OPCODE, /* opcode. */
1283 lp_min_wins_ttl(), /* ttl. */
1284 prdata, /* data to send. */
1285 num_ips*6); /* data length. */
1290 /****************************************************************************
1291 Send a WINS name query response.
1292 **************************************************************************/
1294 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1295 struct name_record *namerec)
1298 char *prdata = rdata;
1299 int reply_data_len = 0;
1303 memset(rdata,'\0',6);
1307 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1308 namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1310 /* Copy all known ip addresses into the return data. */
1311 /* Optimise for the common case of one IP address so
1312 we don't need a malloc. */
1314 if( namerec->data.num_ips == 1 )
1318 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1320 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1325 for(i = 0; i < namerec->data.num_ips; i++)
1327 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1328 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1331 sort_query_replies(prdata, i, p->ip);
1333 reply_data_len = namerec->data.num_ips * 6;
1336 reply_netbios_packet(p, /* Packet to reply to. */
1337 rcode, /* Result code. */
1338 WINS_QUERY, /* nmbd type code. */
1339 NMB_NAME_QUERY_OPCODE, /* opcode. */
1341 prdata, /* data to send. */
1342 reply_data_len); /* data length. */
1344 if((prdata != rdata) && (prdata != NULL))
1348 /***********************************************************************
1349 Deal with a name query.
1350 ***********************************************************************/
1352 void wins_process_name_query_request(struct subnet_record *subrec,
1353 struct packet_struct *p)
1355 struct nmb_packet *nmb = &p->packet.nmb;
1356 struct nmb_name *question = &nmb->question.question_name;
1357 struct name_record *namerec = NULL;
1359 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1360 nmb_namestr(question), inet_ntoa(p->ip) ));
1363 * Special name code. If the queried name is *<1b> then search
1364 * the entire WINS database and return a list of all the IP addresses
1365 * registered to any <1b> name. This is to allow domain master browsers
1366 * to discover other domains that may not have a presence on their subnet.
1369 if(strequal( question->name, "*") && (question->name_type == 0x1b))
1371 process_wins_dmb_query_request( subrec, p);
1375 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1380 * If it's a DNSFAIL_NAME then reply name not found.
1383 if( namerec->data.source == DNSFAIL_NAME )
1385 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1386 nmb_namestr(question) ));
1387 send_wins_name_query_response(NAM_ERR, p, namerec);
1392 * If the name has expired then reply name not found.
1395 if( (namerec->data.death_time != PERMANENT_TTL)
1396 && (namerec->data.death_time < p->timestamp) )
1398 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1399 nmb_namestr(question) ));
1400 send_wins_name_query_response(NAM_ERR, p, namerec);
1404 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1405 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1407 send_wins_name_query_response(0, p, namerec);
1412 * Name not found in WINS - try a dns query if it's a 0x20 name.
1415 if(lp_dns_proxy() &&
1416 ((question->name_type == 0x20) || question->name_type == 0))
1419 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1420 nmb_namestr(question) ));
1422 queue_dns_query(p, question, &namerec);
1427 * Name not found - return error.
1430 send_wins_name_query_response(NAM_ERR, p, NULL);
1433 /****************************************************************************
1434 Send a WINS name release response.
1435 **************************************************************************/
1437 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1439 struct nmb_packet *nmb = &p->packet.nmb;
1442 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1444 reply_netbios_packet(p, /* Packet to reply to. */
1445 rcode, /* Result code. */
1446 NMB_REL, /* nmbd type code. */
1447 NMB_NAME_RELEASE_OPCODE, /* opcode. */
1449 rdata, /* data to send. */
1450 6); /* data length. */
1453 /***********************************************************************
1454 Deal with a name release.
1455 ***********************************************************************/
1457 void wins_process_name_release_request(struct subnet_record *subrec,
1458 struct packet_struct *p)
1460 struct nmb_packet *nmb = &p->packet.nmb;
1461 struct nmb_name *question = &nmb->question.question_name;
1462 BOOL bcast = nmb->header.nm_flags.bcast;
1463 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1464 struct name_record *namerec = NULL;
1465 struct in_addr from_ip;
1466 BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1468 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1473 * We should only get unicast name registration packets here.
1474 * Anyone trying to register broadcast should not be going to a WINS
1475 * server. Log an error here.
1478 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1479 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1480 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1484 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1485 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1488 * Deal with policy regarding 0x1d names.
1491 if(!releasing_group_name && (question->name_type == 0x1d))
1493 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1494 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1495 send_wins_name_release_response(0, p);
1500 * See if the name already exists.
1503 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1505 if( (namerec == NULL)
1506 || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1508 send_wins_name_release_response(NAM_ERR, p);
1513 * Check that the sending machine has permission to release this name.
1514 * If it's a group name not ending in 0x1c then just say yes and let
1515 * the group time out.
1518 if(releasing_group_name && (question->name_type != 0x1c))
1520 send_wins_name_release_response(0, p);
1525 * Check that the releasing node is on the list of IP addresses
1526 * for this name. Disallow the release if not.
1529 if(!find_ip_in_name_record(namerec, from_ip))
1531 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1532 release name %s as IP %s is not one of the known IP's for this name.\n",
1533 nmb_namestr(question), inet_ntoa(from_ip) ));
1534 send_wins_name_release_response(NAM_ERR, p);
1539 * Release the name and then remove the IP from the known list.
1542 send_wins_name_release_response(0, p);
1543 remove_ip_from_name_record(namerec, from_ip);
1545 wins_hook("delete", namerec, 0);
1548 * Remove the name entirely if no IP addresses left.
1550 if (namerec->data.num_ips == 0)
1551 remove_name_from_namelist(subrec, namerec);
1555 /*******************************************************************
1556 WINS time dependent processing.
1557 ******************************************************************/
1559 void initiate_wins_processing(time_t t)
1561 static time_t lasttime = 0;
1565 if (t - lasttime < 20)
1570 if(!lp_we_are_a_wins_server())
1573 expire_names_on_subnet(wins_server_subnet, t);
1575 if(wins_server_subnet->namelist_changed)
1576 wins_write_database(True);
1578 wins_server_subnet->namelist_changed = False;
1581 /*******************************************************************
1582 Write out the current WINS database.
1583 ******************************************************************/
1584 void wins_write_database(BOOL background)
1586 struct name_record *namerec;
1587 pstring fname, fnamenew;
1591 if(!lp_we_are_a_wins_server())
1594 /* we will do the writing in a child process to ensure that the parent
1595 doesn't block while this is done */
1603 slprintf(fname,sizeof(fname),"%s/%s", lp_lockdir(), WINS_LIST);
1604 all_string_sub(fname,"//", "/", 0);
1605 slprintf(fnamenew,sizeof(fnamenew),"%s.%u", fname, (unsigned int)getpid());
1607 if((fp = sys_fopen(fnamenew,"w")) == NULL)
1609 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1616 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1618 fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
1621 = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1623 namerec = (struct name_record *)ubi_trNext( namerec ) )
1628 DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
1630 if( namerec->data.death_time != PERMANENT_TTL )
1634 tm = LocalTime(&namerec->data.death_time);
1636 nl = strrchr( ts, '\n' );
1639 DEBUGADD(4,("TTL = %s ", ts ));
1642 DEBUGADD(4,("TTL = PERMANENT "));
1644 for (i = 0; i < namerec->data.num_ips; i++)
1645 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1646 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1648 if( namerec->data.source == REGISTER_NAME )
1650 fprintf(fp, "\"%s#%02x\" %d ",
1651 namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1652 (int)namerec->data.death_time);
1654 for (i = 0; i < namerec->data.num_ips; i++)
1655 fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1656 fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1661 chmod(fnamenew,0644);
1663 rename(fnamenew,fname);