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 struct in_addr ipzero;
31 /****************************************************************************
32 possibly call the WINS hook external program when a WINS change is made
33 *****************************************************************************/
34 static void wins_hook(char *operation, struct name_record *namerec, int ttl)
37 char *cmd = lp_wins_hook();
41 if (!cmd || !*cmd) return;
43 for (p=namerec->name.name; *p; p++) {
44 if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
45 DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
51 p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
55 namerec->name.name_type,
58 for (i=0;i<namerec->data.num_ips;i++) {
59 p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
62 DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
63 smbrun(command, NULL);
67 /****************************************************************************
68 hash our interfaces and netbios names settings
69 *****************************************************************************/
70 static unsigned wins_hash(void)
73 unsigned ret = iface_hash();
74 extern char **my_netbios_names;
76 for (i=0;my_netbios_names[i];i++)
77 ret ^= str_checksum(my_netbios_names[i]);
79 ret ^= str_checksum(lp_workgroup());
85 /****************************************************************************
86 Determine if this packet should be allocated to the WINS server.
87 *****************************************************************************/
89 BOOL packet_is_for_wins_server(struct packet_struct *packet)
91 struct nmb_packet *nmb = &packet->packet.nmb;
93 /* Only unicast packets go to a WINS server. */
94 if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
96 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
100 /* Check for node status requests. */
101 if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
104 switch(nmb->header.opcode)
107 * A WINS server issues WACKS, not receives them.
109 case NMB_WACK_OPCODE:
110 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
113 * A WINS server only processes registration and
114 * release requests, not responses.
116 case NMB_NAME_REG_OPCODE:
117 case NMB_NAME_MULTIHOMED_REG_OPCODE:
118 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
119 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
120 if(nmb->header.response)
122 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
127 case NMB_NAME_RELEASE_OPCODE:
128 if(nmb->header.response)
130 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
136 * Only process unicast name queries with rd = 1.
138 case NMB_NAME_QUERY_OPCODE:
139 if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
141 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
150 /****************************************************************************
151 Utility function to decide what ttl to give a register/refresh request.
152 *****************************************************************************/
154 static int get_ttl_from_packet(struct nmb_packet *nmb)
156 int ttl = nmb->additional->ttl;
158 if(ttl < lp_min_wins_ttl() )
159 ttl = lp_min_wins_ttl();
161 if(ttl > lp_max_wins_ttl() )
162 ttl = lp_max_wins_ttl();
167 /****************************************************************************
168 Load or create the WINS database.
169 *****************************************************************************/
171 BOOL initialise_wins(void)
173 time_t time_now = time(NULL);
177 if(!lp_we_are_a_wins_server())
180 add_samba_names_to_subnet(wins_server_subnet);
182 if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY, 0)) == NULL)
184 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
185 WINS_LIST, strerror(errno) ));
191 pstring name_str, ip_str, ttl_str, nb_flags_str;
192 unsigned int num_ips;
194 struct in_addr *ip_list;
206 /* Read a line from the wins.dat file. Strips whitespace
207 from the beginning and end of the line.
209 if (!fgets_slash(line,sizeof(pstring),fp))
215 if (strncmp(line,"VERSION ", 8) == 0) {
216 if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
217 version != WINS_VERSION ||
218 hash != wins_hash()) {
219 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
229 * Now we handle multiple IP addresses per name we need
230 * to iterate over the line twice. The first time to
231 * determine how many IP addresses there are, the second
232 * time to actually parse them into the ip_list array.
235 if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
237 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
241 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
243 DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
248 * Determine the number of IP addresses per line.
253 got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
256 if(got_token && strchr_m(ip_str, '.'))
261 } while( got_token && was_ip);
265 DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
271 DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
275 /* Allocate the space for the ip_list. */
276 if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
278 DEBUG(0,("initialise_wins: Malloc fail !\n"));
282 /* Reset and re-parse the line. */
284 next_token(&ptr,name_str,NULL,sizeof(name_str));
285 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
286 for(i = 0; i < num_ips; i++)
288 next_token(&ptr, ip_str, NULL, sizeof(ip_str));
289 ip_list[i] = *interpret_addr2(ip_str);
291 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
294 * Deal with SELF or REGISTER name encoding. Default is REGISTER
295 * for compatibility with old nmbds.
298 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
300 DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
305 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
306 nb_flags_str[strlen(nb_flags_str)-1] = '\0';
308 /* Netbios name. # divides the name from the type (hex): netbios#xx */
309 pstrcpy(name,name_str);
311 if((p = strchr_m(name,'#')) != NULL)
314 sscanf(p+1,"%x",&type);
317 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
318 sscanf(nb_flags_str,"%x",&nb_flags);
319 sscanf(ttl_str,"%d",&ttl);
321 /* add all entries that have 60 seconds or more to live */
322 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
324 if(ttl != PERMANENT_TTL)
327 DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
328 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
330 (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
331 ttl, REGISTER_NAME, num_ips, ip_list );
336 DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
337 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
347 /****************************************************************************
348 Send a WINS WACK (Wait ACKnowledgement) response.
349 **************************************************************************/
351 static void send_wins_wack_response(int ttl, struct packet_struct *p)
353 struct nmb_packet *nmb = &p->packet.nmb;
354 unsigned char rdata[2];
356 rdata[0] = rdata[1] = 0;
358 /* Taken from nmblib.c - we need to send back almost
359 identical bytes from the requesting packet header. */
361 rdata[0] = (nmb->header.opcode & 0xF) << 3;
362 if (nmb->header.nm_flags.authoritative &&
363 nmb->header.response) rdata[0] |= 0x4;
364 if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
365 if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
366 if (nmb->header.nm_flags.recursion_available &&
367 nmb->header.response) rdata[1] |= 0x80;
368 if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
370 reply_netbios_packet(p, /* Packet to reply to. */
371 0, /* Result code. */
372 NMB_WAIT_ACK, /* nmbd type code. */
373 NMB_WACK_OPCODE, /* opcode. */
375 (char *)rdata, /* data to send. */
376 2); /* data length. */
379 /****************************************************************************
380 Send a WINS name registration response.
381 **************************************************************************/
383 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
385 struct nmb_packet *nmb = &p->packet.nmb;
388 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
390 reply_netbios_packet(p, /* Packet to reply to. */
391 rcode, /* Result code. */
392 WINS_REG, /* nmbd type code. */
393 NMB_NAME_REG_OPCODE, /* opcode. */
395 rdata, /* data to send. */
396 6); /* data length. */
399 /***********************************************************************
400 Deal with a name refresh request to a WINS server.
401 ************************************************************************/
403 void wins_process_name_refresh_request(struct subnet_record *subrec,
404 struct packet_struct *p)
406 struct nmb_packet *nmb = &p->packet.nmb;
407 struct nmb_name *question = &nmb->question.question_name;
408 BOOL bcast = nmb->header.nm_flags.bcast;
409 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
410 BOOL group = (nb_flags & NB_GROUP) ? True : False;
411 struct name_record *namerec = NULL;
412 int ttl = get_ttl_from_packet(nmb);
413 struct in_addr from_ip;
415 putip((char *)&from_ip,&nmb->additional->rdata[2]);
420 * We should only get unicast name refresh packets here.
421 * Anyone trying to refresh broadcast should not be going to a WINS
422 * server. Log an error here.
425 DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
426 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
427 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
431 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
432 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
435 * See if the name already exists.
438 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
441 * If this is a refresh request and the name doesn't exist then
442 * treat it like a registration request. This allows us to recover
443 * from errors (tridge)
448 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
449 the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
450 wins_process_name_registration_request(subrec,p);
455 * Check that the group bits for the refreshing name and the
456 * name in our database match.
459 if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
461 DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
462 does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
463 send_wins_name_registration_response(RFS_ERR, 0, p);
468 * For a unique name check that the person refreshing the name is one of the registered IP
469 * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
470 * Just return success for unique 0x1d refreshes. For normal group names update the ttl
471 * and return success.
474 if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
479 update_name_ttl(namerec, ttl);
480 send_wins_name_registration_response(0, ttl, p);
481 wins_hook("refresh", namerec, ttl);
487 * Normal groups are all registered with an IP address of 255.255.255.255
488 * so we can't search for the IP address.
490 update_name_ttl(namerec, ttl);
491 send_wins_name_registration_response(0, ttl, p);
494 else if(!group && (question->name_type == 0x1d))
497 * Special name type - just pretend the refresh succeeded.
499 send_wins_name_registration_response(0, ttl, p);
508 DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
509 is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
510 send_wins_name_registration_response(RFS_ERR, 0, p);
515 /***********************************************************************
516 Deal with a name registration request query success to a client that
519 We have a locked pointer to the original packet stashed away in the
520 userdata pointer. The success here is actually a failure as it means
521 the client we queried wants to keep the name, so we must return
522 a registration failure to the original requestor.
523 ************************************************************************/
525 static void wins_register_query_success(struct subnet_record *subrec,
526 struct userdata_struct *userdata,
527 struct nmb_name *question_name,
529 struct res_rec *answers)
531 struct packet_struct *orig_reg_packet;
533 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
535 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
536 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
538 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
540 orig_reg_packet->locked = False;
541 free_packet(orig_reg_packet);
544 /***********************************************************************
545 Deal with a name registration request query failure to a client that
548 We have a locked pointer to the original packet stashed away in the
549 userdata pointer. The failure here is actually a success as it means
550 the client we queried didn't want to keep the name, so we can remove
551 the old name record and then successfully add the new name.
552 ************************************************************************/
554 static void wins_register_query_fail(struct subnet_record *subrec,
555 struct response_record *rrec,
556 struct nmb_name *question_name,
559 struct userdata_struct *userdata = rrec->userdata;
560 struct packet_struct *orig_reg_packet;
561 struct name_record *namerec = NULL;
563 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
566 * We want to just add the name, as we now know the original owner
567 * didn't want it. But we can't just do that as an arbitary
568 * amount of time may have taken place between the name query
569 * request and this timeout/error response. So we check that
570 * the name still exists and is in the same state - if so
571 * we remove it and call wins_process_name_registration_request()
572 * as we know it will do the right thing now.
575 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
577 if( (namerec != NULL)
578 && (namerec->data.source == REGISTER_NAME)
579 && ip_equal(rrec->packet->ip, *namerec->data.ip) )
581 remove_name_from_namelist( subrec, namerec);
586 wins_process_name_registration_request(subrec, orig_reg_packet);
588 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
589 querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
591 orig_reg_packet->locked = False;
592 free_packet(orig_reg_packet);
595 /***********************************************************************
596 Deal with a name registration request to a WINS server.
598 Use the following pseudocode :
606 | +--- existing name is group
609 | | +--- add name (return).
612 | +--- exiting name is unique
615 | +--- query existing owner (return).
618 +--------name doesn't exist
621 +--- add name (return).
629 | +--- existing name is group
632 | | +--- fail add (return).
635 | +--- exiting name is unique
638 | +--- query existing owner (return).
641 +--------name doesn't exist
644 +--- add name (return).
646 As can be seen from the above, the two cases may be collapsed onto each
647 other with the exception of the case where the name already exists and
648 is a group name. This case we handle with an if statement.
650 ************************************************************************/
652 void wins_process_name_registration_request(struct subnet_record *subrec,
653 struct packet_struct *p)
655 struct nmb_packet *nmb = &p->packet.nmb;
656 struct nmb_name *question = &nmb->question.question_name;
657 BOOL bcast = nmb->header.nm_flags.bcast;
658 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
659 int ttl = get_ttl_from_packet(nmb);
660 struct name_record *namerec = NULL;
661 struct in_addr from_ip;
662 BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
664 putip((char *)&from_ip,&nmb->additional->rdata[2]);
669 * We should only get unicast name registration packets here.
670 * Anyone trying to register broadcast should not be going to a WINS
671 * server. Log an error here.
674 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
675 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
676 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
680 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
681 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
684 * See if the name already exists.
687 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
690 * Deal with the case where the name found was a dns entry.
691 * Remove it as we now have a NetBIOS client registering the
695 if( (namerec != NULL)
696 && ( (namerec->data.source == DNS_NAME)
697 || (namerec->data.source == DNSFAIL_NAME) ) )
699 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
700 a dns lookup - removing it.\n", nmb_namestr(question) ));
701 remove_name_from_namelist( subrec, namerec );
706 * Reject if the name exists and is not a REGISTER_NAME.
707 * (ie. Don't allow any static names to be overwritten.
710 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
712 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
713 to register name %s. Name already exists in WINS with source type %d.\n",
714 nmb_namestr(question), namerec->data.source ));
715 send_wins_name_registration_response(RFS_ERR, 0, p);
720 * Special policy decisions based on MS documentation.
721 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
722 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
726 * A group name is always added as the local broadcast address, except
727 * for group names ending in 0x1c.
728 * Group names with type 0x1c are registered with individual IP addresses.
731 if(registering_group_name && (question->name_type != 0x1c))
732 from_ip = *interpret_addr2("255.255.255.255");
735 * Ignore all attempts to register a unique 0x1d name, although return success.
738 if(!registering_group_name && (question->name_type == 0x1d))
740 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
741 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
742 send_wins_name_registration_response(0, ttl, p);
747 * Next two cases are the 'if statement' mentioned above.
750 if((namerec != NULL) && NAME_GROUP(namerec))
752 if(registering_group_name)
755 * If we are adding a group name, the name exists and is also a group entry just add this
756 * IP address to it and update the ttl.
759 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
760 inet_ntoa(from_ip), nmb_namestr(question) ));
762 * Check the ip address is not already in the group.
764 if(!find_ip_in_name_record(namerec, from_ip))
765 add_ip_to_name_record(namerec, from_ip);
766 update_name_ttl(namerec, ttl);
767 send_wins_name_registration_response(0, ttl, p);
773 * If we are adding a unique name, the name exists in the WINS db
774 * and is a group name then reject the registration.
777 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
778 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
779 send_wins_name_registration_response(RFS_ERR, 0, p);
785 * From here on down we know that if the name exists in the WINS db it is
786 * a unique name, not a group name.
790 * If the name exists and is one of our names then check the
791 * registering IP address. If it's not one of ours then automatically
792 * reject without doing the query - we know we will reject it.
795 if((namerec != NULL) && (is_myname(namerec->name.name)) )
799 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
800 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
801 send_wins_name_registration_response(RFS_ERR, 0, p);
807 * It's one of our names and one of our IP's - update the ttl.
809 update_name_ttl(namerec, ttl);
810 send_wins_name_registration_response(0, ttl, p);
811 wins_hook("refresh", namerec, ttl);
817 * If the name exists and it is a unique registration and the registering IP
818 * is the same as the the (single) already registered IP then just update the ttl.
821 if( !registering_group_name
823 && (namerec->data.num_ips == 1)
824 && ip_equal( namerec->data.ip[0], from_ip ) )
826 update_name_ttl( namerec, ttl );
827 send_wins_name_registration_response( 0, ttl, p );
828 wins_hook("refresh", namerec, ttl);
833 * Finally if the name exists do a query to the registering machine
834 * to see if they still claim to have the name.
837 if( namerec != NULL )
839 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
840 struct userdata_struct *userdata = (struct userdata_struct *)ud;
843 * First send a WACK to the registering machine.
846 send_wins_wack_response(60, p);
849 * When the reply comes back we need the original packet.
850 * Lock this so it won't be freed and then put it into
851 * the userdata structure.
856 userdata = (struct userdata_struct *)ud;
858 userdata->copy_fn = NULL;
859 userdata->free_fn = NULL;
860 userdata->userdata_len = sizeof(struct packet_struct *);
861 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
864 * Use the new call to send a query directly to an IP address.
865 * This sends the query directly to the IP address, and ensures
866 * the recursion desired flag is not set (you were right Luke :-).
867 * This function should *only* be called from the WINS server
871 query_name_from_wins_server( *namerec->data.ip,
874 wins_register_query_success,
875 wins_register_query_fail,
881 * Name did not exist - add it.
884 (void)add_name_to_subnet( subrec, question->name, question->name_type,
885 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
886 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
887 wins_hook("add", namerec, ttl);
890 send_wins_name_registration_response(0, ttl, p);
893 /***********************************************************************
894 Deal with a mutihomed name query success to the machine that
895 requested the multihomed name registration.
897 We have a locked pointer to the original packet stashed away in the
899 ************************************************************************/
901 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
902 struct userdata_struct *userdata,
903 struct nmb_name *question_name,
905 struct res_rec *answers)
907 struct packet_struct *orig_reg_packet;
908 struct nmb_packet *nmb;
909 struct name_record *namerec = NULL;
910 struct in_addr from_ip;
913 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
915 nmb = &orig_reg_packet->packet.nmb;
917 putip((char *)&from_ip,&nmb->additional->rdata[2]);
918 ttl = get_ttl_from_packet(nmb);
921 * We want to just add the new IP, as we now know the requesting
922 * machine claims to own it. But we can't just do that as an arbitary
923 * amount of time may have taken place between the name query
924 * request and this response. So we check that
925 * the name still exists and is in the same state - if so
926 * we just add the extra IP and update the ttl.
929 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
931 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
933 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
934 a subsequent IP addess.\n", nmb_namestr(question_name) ));
935 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
937 orig_reg_packet->locked = False;
938 free_packet(orig_reg_packet);
943 if(!find_ip_in_name_record(namerec, from_ip))
944 add_ip_to_name_record(namerec, from_ip);
945 update_name_ttl(namerec, ttl);
946 send_wins_name_registration_response(0, ttl, orig_reg_packet);
947 wins_hook("add", namerec, ttl);
949 orig_reg_packet->locked = False;
950 free_packet(orig_reg_packet);
953 /***********************************************************************
954 Deal with a name registration request query failure to a client that
957 We have a locked pointer to the original packet stashed away in the
959 ************************************************************************/
961 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
962 struct response_record *rrec,
963 struct nmb_name *question_name,
966 struct userdata_struct *userdata = rrec->userdata;
967 struct packet_struct *orig_reg_packet;
969 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
971 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
972 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
973 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
975 orig_reg_packet->locked = False;
976 free_packet(orig_reg_packet);
980 /***********************************************************************
981 Deal with a multihomed name registration request to a WINS server.
982 These cannot be group name registrations.
983 ***********************************************************************/
985 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
986 struct packet_struct *p)
988 struct nmb_packet *nmb = &p->packet.nmb;
989 struct nmb_name *question = &nmb->question.question_name;
990 BOOL bcast = nmb->header.nm_flags.bcast;
991 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
992 int ttl = get_ttl_from_packet(nmb);
993 struct name_record *namerec = NULL;
994 struct in_addr from_ip;
995 BOOL group = (nb_flags & NB_GROUP) ? True : False;;
997 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1002 * We should only get unicast name registration packets here.
1003 * Anyone trying to register broadcast should not be going to a WINS
1004 * server. Log an error here.
1007 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1008 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1009 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1014 * Only unique names should be registered multihomed.
1019 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1020 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1021 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1025 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1026 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1029 * Deal with policy regarding 0x1d names.
1032 if(question->name_type == 0x1d)
1034 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1035 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1036 send_wins_name_registration_response(0, ttl, p);
1041 * See if the name already exists.
1044 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1047 * Deal with the case where the name found was a dns entry.
1048 * Remove it as we now have a NetBIOS client registering the
1052 if( (namerec != NULL)
1053 && ( (namerec->data.source == DNS_NAME)
1054 || (namerec->data.source == DNSFAIL_NAME) ) )
1056 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1057 - removing it.\n", nmb_namestr(question) ));
1058 remove_name_from_namelist( subrec, namerec);
1063 * Reject if the name exists and is not a REGISTER_NAME.
1064 * (ie. Don't allow any static names to be overwritten.
1067 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1069 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1070 to register name %s. Name already exists in WINS with source type %d.\n",
1071 nmb_namestr(question), namerec->data.source ));
1072 send_wins_name_registration_response(RFS_ERR, 0, p);
1077 * Reject if the name exists and is a GROUP name.
1080 if((namerec != NULL) && NAME_GROUP(namerec))
1082 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1083 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1084 send_wins_name_registration_response(RFS_ERR, 0, p);
1089 * From here on down we know that if the name exists in the WINS db it is
1090 * a unique name, not a group name.
1094 * If the name exists and is one of our names then check the
1095 * registering IP address. If it's not one of ours then automatically
1096 * reject without doing the query - we know we will reject it.
1099 if((namerec != NULL) && (is_myname(namerec->name.name)) )
1101 if(!ismyip(from_ip))
1103 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1104 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1105 send_wins_name_registration_response(RFS_ERR, 0, p);
1111 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1114 if(!find_ip_in_name_record(namerec, from_ip)) {
1115 add_ip_to_name_record(namerec, from_ip);
1116 wins_hook("add", namerec, ttl);
1118 wins_hook("refresh", namerec, ttl);
1121 update_name_ttl(namerec, ttl);
1122 send_wins_name_registration_response(0, ttl, p);
1128 * If the name exists check if the IP address is already registered
1129 * to that name. If so then update the ttl and reply success.
1132 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1134 update_name_ttl(namerec, ttl);
1135 send_wins_name_registration_response(0, ttl, p);
1136 wins_hook("refresh", namerec, ttl);
1141 * If the name exists do a query to the owner
1142 * to see if they still want the name.
1147 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1148 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1151 * First send a WACK to the registering machine.
1154 send_wins_wack_response(60, p);
1157 * When the reply comes back we need the original packet.
1158 * Lock this so it won't be freed and then put it into
1159 * the userdata structure.
1164 userdata = (struct userdata_struct *)ud;
1166 userdata->copy_fn = NULL;
1167 userdata->free_fn = NULL;
1168 userdata->userdata_len = sizeof(struct packet_struct *);
1169 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1172 * Use the new call to send a query directly to an IP address.
1173 * This sends the query directly to the IP address, and ensures
1174 * the recursion desired flag is not set (you were right Luke :-).
1175 * This function should *only* be called from the WINS server
1178 * Note that this packet is sent to the current owner of the name,
1179 * not the person who sent the packet
1182 query_name_from_wins_server( namerec->data.ip[0],
1184 question->name_type,
1185 wins_multihomed_register_query_success,
1186 wins_multihomed_register_query_fail,
1193 * Name did not exist - add it.
1196 (void)add_name_to_subnet( subrec, question->name, question->name_type,
1197 nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
1199 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1200 wins_hook("add", namerec, ttl);
1203 send_wins_name_registration_response(0, ttl, p);
1206 /***********************************************************************
1207 Deal with the special name query for *<1b>.
1208 ***********************************************************************/
1210 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1211 struct packet_struct *p)
1213 struct name_record *namerec = NULL;
1218 * Go through all the names in the WINS db looking for those
1219 * ending in <1b>. Use this to calculate the number of IP
1220 * addresses we need to return.
1224 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1226 namerec = (struct name_record *)ubi_trNext( namerec ) )
1228 if( namerec->name.name_type == 0x1b )
1229 num_ips += namerec->data.num_ips;
1235 * There are no 0x1b names registered. Return name query fail.
1237 send_wins_name_query_response(NAM_ERR, p, NULL);
1241 if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1243 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1248 * Go through all the names again in the WINS db looking for those
1249 * ending in <1b>. Add their IP addresses into the list we will
1254 for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1256 namerec = (struct name_record *)ubi_trNext( namerec ) )
1258 if(namerec->name.name_type == 0x1b)
1261 for(i = 0; i < namerec->data.num_ips; i++)
1263 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1264 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1271 * Send back the reply containing the IP list.
1274 reply_netbios_packet(p, /* Packet to reply to. */
1275 0, /* Result code. */
1276 WINS_QUERY, /* nmbd type code. */
1277 NMB_NAME_QUERY_OPCODE, /* opcode. */
1278 lp_min_wins_ttl(), /* ttl. */
1279 prdata, /* data to send. */
1280 num_ips*6); /* data length. */
1285 /****************************************************************************
1286 Send a WINS name query response.
1287 **************************************************************************/
1289 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1290 struct name_record *namerec)
1293 char *prdata = rdata;
1294 int reply_data_len = 0;
1298 memset(rdata,'\0',6);
1302 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1303 namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1305 /* Copy all known ip addresses into the return data. */
1306 /* Optimise for the common case of one IP address so
1307 we don't need a malloc. */
1309 if( namerec->data.num_ips == 1 )
1313 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1315 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1320 for(i = 0; i < namerec->data.num_ips; i++)
1322 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1323 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1326 sort_query_replies(prdata, i, p->ip);
1328 reply_data_len = namerec->data.num_ips * 6;
1331 reply_netbios_packet(p, /* Packet to reply to. */
1332 rcode, /* Result code. */
1333 WINS_QUERY, /* nmbd type code. */
1334 NMB_NAME_QUERY_OPCODE, /* opcode. */
1336 prdata, /* data to send. */
1337 reply_data_len); /* data length. */
1343 /***********************************************************************
1344 Deal with a name query.
1345 ***********************************************************************/
1347 void wins_process_name_query_request(struct subnet_record *subrec,
1348 struct packet_struct *p)
1350 struct nmb_packet *nmb = &p->packet.nmb;
1351 struct nmb_name *question = &nmb->question.question_name;
1352 struct name_record *namerec = NULL;
1354 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1355 nmb_namestr(question), inet_ntoa(p->ip) ));
1358 * Special name code. If the queried name is *<1b> then search
1359 * the entire WINS database and return a list of all the IP addresses
1360 * registered to any <1b> name. This is to allow domain master browsers
1361 * to discover other domains that may not have a presence on their subnet.
1364 if(strequal( question->name, "*") && (question->name_type == 0x1b))
1366 process_wins_dmb_query_request( subrec, p);
1370 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1375 * If it's a DNSFAIL_NAME then reply name not found.
1378 if( namerec->data.source == DNSFAIL_NAME )
1380 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1381 nmb_namestr(question) ));
1382 send_wins_name_query_response(NAM_ERR, p, namerec);
1387 * If the name has expired then reply name not found.
1390 if( (namerec->data.death_time != PERMANENT_TTL)
1391 && (namerec->data.death_time < p->timestamp) )
1393 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1394 nmb_namestr(question) ));
1395 send_wins_name_query_response(NAM_ERR, p, namerec);
1399 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1400 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1402 send_wins_name_query_response(0, p, namerec);
1407 * Name not found in WINS - try a dns query if it's a 0x20 name.
1410 if(lp_dns_proxy() &&
1411 ((question->name_type == 0x20) || question->name_type == 0))
1414 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1415 nmb_namestr(question) ));
1417 queue_dns_query(p, question, &namerec);
1422 * Name not found - return error.
1425 send_wins_name_query_response(NAM_ERR, p, NULL);
1428 /****************************************************************************
1429 Send a WINS name release response.
1430 **************************************************************************/
1432 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1434 struct nmb_packet *nmb = &p->packet.nmb;
1437 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1439 reply_netbios_packet(p, /* Packet to reply to. */
1440 rcode, /* Result code. */
1441 NMB_REL, /* nmbd type code. */
1442 NMB_NAME_RELEASE_OPCODE, /* opcode. */
1444 rdata, /* data to send. */
1445 6); /* data length. */
1448 /***********************************************************************
1449 Deal with a name release.
1450 ***********************************************************************/
1452 void wins_process_name_release_request(struct subnet_record *subrec,
1453 struct packet_struct *p)
1455 struct nmb_packet *nmb = &p->packet.nmb;
1456 struct nmb_name *question = &nmb->question.question_name;
1457 BOOL bcast = nmb->header.nm_flags.bcast;
1458 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1459 struct name_record *namerec = NULL;
1460 struct in_addr from_ip;
1461 BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1463 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1468 * We should only get unicast name registration packets here.
1469 * Anyone trying to register broadcast should not be going to a WINS
1470 * server. Log an error here.
1473 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1474 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1475 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1479 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1480 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1483 * Deal with policy regarding 0x1d names.
1486 if(!releasing_group_name && (question->name_type == 0x1d))
1488 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1489 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1490 send_wins_name_release_response(0, p);
1495 * See if the name already exists.
1498 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1500 if( (namerec == NULL)
1501 || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1503 send_wins_name_release_response(NAM_ERR, p);
1508 * Check that the sending machine has permission to release this name.
1509 * If it's a group name not ending in 0x1c then just say yes and let
1510 * the group time out.
1513 if(releasing_group_name && (question->name_type != 0x1c))
1515 send_wins_name_release_response(0, p);
1520 * Check that the releasing node is on the list of IP addresses
1521 * for this name. Disallow the release if not.
1524 if(!find_ip_in_name_record(namerec, from_ip))
1526 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1527 release name %s as IP %s is not one of the known IP's for this name.\n",
1528 nmb_namestr(question), inet_ntoa(from_ip) ));
1529 send_wins_name_release_response(NAM_ERR, p);
1534 * Release the name and then remove the IP from the known list.
1537 send_wins_name_release_response(0, p);
1538 remove_ip_from_name_record(namerec, from_ip);
1540 wins_hook("delete", namerec, 0);
1543 * Remove the name entirely if no IP addresses left.
1545 if (namerec->data.num_ips == 0)
1546 remove_name_from_namelist(subrec, namerec);
1550 /*******************************************************************
1551 WINS time dependent processing.
1552 ******************************************************************/
1554 void initiate_wins_processing(time_t t)
1556 static time_t lasttime = 0;
1560 if (t - lasttime < 20)
1565 if(!lp_we_are_a_wins_server())
1568 expire_names_on_subnet(wins_server_subnet, t);
1570 if(wins_server_subnet->namelist_changed)
1571 wins_write_database(True);
1573 wins_server_subnet->namelist_changed = False;
1576 /*******************************************************************
1577 Write out the current WINS database.
1578 ******************************************************************/
1579 void wins_write_database(BOOL background)
1581 struct name_record *namerec;
1582 pstring fname, fnamenew;
1585 if(!lp_we_are_a_wins_server())
1588 /* we will do the writing in a child process to ensure that the parent
1589 doesn't block while this is done */
1597 slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
1598 all_string_sub(fname,"//", "/", 0);
1599 slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
1601 if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644)) == NULL)
1603 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1610 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1612 x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
1615 = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1617 namerec = (struct name_record *)ubi_trNext( namerec ) )
1622 DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
1624 if( namerec->data.death_time != PERMANENT_TTL )
1628 tm = LocalTime(&namerec->data.death_time);
1630 nl = strrchr_m( ts, '\n' );
1633 DEBUGADD(4,("TTL = %s ", ts ));
1636 DEBUGADD(4,("TTL = PERMANENT "));
1638 for (i = 0; i < namerec->data.num_ips; i++)
1639 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1640 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1642 if( namerec->data.source == REGISTER_NAME )
1644 x_fprintf(fp, "\"%s#%02x\" %d ",
1645 namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1646 (int)namerec->data.death_time);
1648 for (i = 0; i < namerec->data.num_ips; i++)
1649 x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1650 x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1655 chmod(fnamenew,0644);
1657 rename(fnamenew,fname);