2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
5 Copyright (C) Jeremy Allison 1994-2005
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Converted to store WINS data in a tdb. Dec 2005. JRA.
25 #define WINS_LIST "wins.dat"
26 #define WINS_VERSION 1
27 #define WINSDB_VERSION 1
29 /****************************************************************************
30 We don't store the NetBIOS scope in the wins.tdb. We key off the (utf8) netbios
31 name (65 bytes with the last byte being the name type).
32 *****************************************************************************/
34 TDB_CONTEXT *wins_tdb;
36 /****************************************************************************
37 Delete all the temporary name records on the in-memory linked list.
38 *****************************************************************************/
40 static void wins_delete_all_tmp_in_memory_records(void)
42 struct name_record *nr = NULL;
43 struct name_record *nrnext = NULL;
45 /* Delete all temporary name records on the wins subnet linked list. */
46 for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
48 DLIST_REMOVE(wins_server_subnet->namelist, nr);
49 SAFE_FREE(nr->data.ip);
54 /****************************************************************************
55 Convert a wins.tdb record to a struct name_record. Add in our global_scope().
56 *****************************************************************************/
58 static struct name_record *wins_record_to_name_record(TDB_DATA key, TDB_DATA data)
60 struct name_record *namerec = NULL;
63 uint32 death_time, refresh_time;
64 uint32 id_low, id_high;
71 if (data.dptr == NULL || data.dsize == 0) {
75 /* Min size is "wbddddddd" + 1 ip address (4). */
76 if (data.dsize < 2 + 1 + (7*4) + 4) {
80 len = tdb_unpack(data.dptr, data.dsize,
92 namerec = SMB_MALLOC_P(struct name_record);
96 ZERO_STRUCTP(namerec);
98 namerec->data.ip = SMB_MALLOC_ARRAY(struct in_addr, num_ips);
99 if (!namerec->data.ip) {
104 namerec->subnet = wins_server_subnet;
105 push_ascii_nstring(namerec->name.name, (const char *)key.dptr);
106 namerec->name.name_type = key.dptr[sizeof(unstring)];
108 push_ascii(namerec->name.scope, global_scope(), 64, STR_TERMINATE);
110 /* We're using a byte-by-byte compare, so we must be sure that
111 * unused space doesn't have garbage in it.
114 for( i = strlen( namerec->name.name ); i < sizeof( namerec->name.name ); i++ ) {
115 namerec->name.name[i] = '\0';
117 for( i = strlen( namerec->name.scope ); i < sizeof( namerec->name.scope ); i++ ) {
118 namerec->name.scope[i] = '\0';
121 namerec->data.nb_flags = nb_flags;
122 namerec->data.source = (enum name_source)nr_src;
123 namerec->data.death_time = (time_t)death_time;
124 namerec->data.refresh_time = (time_t)refresh_time;
125 namerec->data.id = id_low;
126 #if defined(HAVE_LONGLONG)
127 namerec->data.id |= ((uint64_t)id_high << 32);
129 namerec->data.wins_ip.s_addr = saddr;
130 namerec->data.wins_flags = wins_flags,
131 namerec->data.num_ips = num_ips;
133 for (i = 0; i < num_ips; i++) {
134 namerec->data.ip[i].s_addr = IVAL(data.dptr, len + (i*4));
140 /****************************************************************************
141 Convert a struct name_record to a wins.tdb record. Ignore the scope.
142 *****************************************************************************/
144 static TDB_DATA name_record_to_wins_record(const struct name_record *namerec)
149 uint32 id_low = (namerec->data.id & 0xFFFFFFFF);
150 #if defined(HAVE_LONGLONG)
151 uint32 id_high = (namerec->data.id >> 32) & 0xFFFFFFFF;
158 len = (2 + 1 + (7*4)); /* "wbddddddd" */
159 len += (namerec->data.num_ips * 4);
161 data.dptr = (uint8 *)SMB_MALLOC(len);
167 len = tdb_pack(data.dptr, data.dsize, "wbddddddd",
168 namerec->data.nb_flags,
169 (unsigned char)namerec->data.source,
170 (uint32)namerec->data.death_time,
171 (uint32)namerec->data.refresh_time,
174 (uint32)namerec->data.wins_ip.s_addr,
175 (uint32)namerec->data.wins_flags,
176 (uint32)namerec->data.num_ips );
178 for (i = 0; i < namerec->data.num_ips; i++) {
179 SIVAL(data.dptr, len + (i*4), namerec->data.ip[i].s_addr);
185 /****************************************************************************
186 Create key. Key is UNIX codepage namestring (usually utf8 64 byte len) with 1 byte type.
187 *****************************************************************************/
189 static TDB_DATA name_to_key(const struct nmb_name *nmbname)
191 static char keydata[sizeof(unstring) + 1];
194 memset(keydata, '\0', sizeof(keydata));
196 pull_ascii_nstring(keydata, sizeof(unstring), nmbname->name);
198 keydata[sizeof(unstring)] = nmbname->name_type;
199 key.dptr = (uint8 *)keydata;
200 key.dsize = sizeof(keydata);
205 /****************************************************************************
206 Lookup a given name in the wins.tdb and create a temporary malloc'ed data struct
207 on the linked list. We will free this later in XXXX().
208 *****************************************************************************/
210 struct name_record *find_name_on_wins_subnet(const struct nmb_name *nmbname, bool self_only)
213 struct name_record *nr = NULL;
214 struct name_record *namerec = NULL;
220 key = name_to_key(nmbname);
221 data = tdb_fetch(wins_tdb, key);
223 if (data.dsize == 0) {
227 namerec = wins_record_to_name_record(key, data);
229 /* done with the this */
231 SAFE_FREE( data.dptr );
237 /* Self names only - these include permanent names. */
238 if( self_only && (namerec->data.source != SELF_NAME) && (namerec->data.source != PERMANENT_NAME) ) {
239 DEBUG( 9, ( "find_name_on_wins_subnet: self name %s NOT FOUND\n", nmb_namestr(nmbname) ) );
240 SAFE_FREE(namerec->data.ip);
245 /* Search for this name record on the list. Replace it if found. */
247 for( nr = wins_server_subnet->namelist; nr; nr = nr->next) {
248 if (memcmp(nmbname->name, nr->name.name, 16) == 0) {
250 DLIST_REMOVE(wins_server_subnet->namelist, nr);
251 SAFE_FREE(nr->data.ip);
257 DLIST_ADD(wins_server_subnet->namelist, namerec);
261 /****************************************************************************
262 Overwrite or add a given name in the wins.tdb.
263 *****************************************************************************/
265 static bool store_or_replace_wins_namerec(const struct name_record *namerec, int tdb_flag)
274 key = name_to_key(&namerec->name);
275 data = name_record_to_wins_record(namerec);
277 if (data.dptr == NULL) {
281 ret = tdb_store(wins_tdb, key, data, tdb_flag);
283 SAFE_FREE(data.dptr);
284 return (ret == 0) ? True : False;
287 /****************************************************************************
288 Overwrite a given name in the wins.tdb.
289 *****************************************************************************/
291 bool wins_store_changed_namerec(const struct name_record *namerec)
293 return store_or_replace_wins_namerec(namerec, TDB_REPLACE);
296 /****************************************************************************
297 Primary interface into creating and overwriting records in the wins.tdb.
298 *****************************************************************************/
300 bool add_name_to_wins_subnet(const struct name_record *namerec)
302 return store_or_replace_wins_namerec(namerec, TDB_INSERT);
305 /****************************************************************************
306 Delete a given name in the tdb and remove the temporary malloc'ed data struct
308 *****************************************************************************/
310 bool remove_name_from_wins_namelist(struct name_record *namerec)
319 key = name_to_key(&namerec->name);
320 ret = tdb_delete(wins_tdb, key);
322 DLIST_REMOVE(wins_server_subnet->namelist, namerec);
324 /* namerec must be freed by the caller */
326 return (ret == 0) ? True : False;
329 /****************************************************************************
330 Dump out the complete namelist.
331 *****************************************************************************/
333 static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
335 struct name_record *namerec = NULL;
336 XFILE *fp = (XFILE *)state;
338 if (kbuf.dsize != sizeof(unstring) + 1) {
342 namerec = wins_record_to_name_record(kbuf, dbuf);
347 dump_name_record(namerec, fp);
349 SAFE_FREE(namerec->data.ip);
354 void dump_wins_subnet_namelist(XFILE *fp)
356 tdb_traverse(wins_tdb, traverse_fn, (void *)fp);
359 /****************************************************************************
360 Change the wins owner address in the record.
361 *****************************************************************************/
363 static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
365 namerec->data.wins_ip=wins_ip;
368 /****************************************************************************
369 Create the wins flags based on the nb flags and the input value.
370 *****************************************************************************/
372 static void update_wins_flag(struct name_record *namerec, int flags)
374 namerec->data.wins_flags=0x0;
376 /* if it's a group, it can be a normal or a special one */
377 if (namerec->data.nb_flags & NB_GROUP) {
378 if (namerec->name.name_type==0x1C) {
379 namerec->data.wins_flags|=WINS_SGROUP;
381 if (namerec->data.num_ips>1) {
382 namerec->data.wins_flags|=WINS_SGROUP;
384 namerec->data.wins_flags|=WINS_NGROUP;
388 /* can be unique or multi-homed */
389 if (namerec->data.num_ips>1) {
390 namerec->data.wins_flags|=WINS_MHOMED;
392 namerec->data.wins_flags|=WINS_UNIQUE;
396 /* the node type are the same bits */
397 namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
399 /* the static bit is elsewhere */
400 if (namerec->data.death_time == PERMANENT_TTL) {
401 namerec->data.wins_flags|=WINS_STATIC;
404 /* and add the given bits */
405 namerec->data.wins_flags|=flags;
407 DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
408 namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
411 /****************************************************************************
412 Return the general ID value and increase it if requested.
413 *****************************************************************************/
415 static void get_global_id_and_update(uint64_t *current_id, bool update)
418 * it's kept as a static here, to prevent people from messing
419 * with the value directly
422 static uint64_t general_id = 1;
424 DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
426 *current_id = general_id;
433 /****************************************************************************
434 Possibly call the WINS hook external program when a WINS change is made.
435 Also stores the changed record back in the wins_tdb.
436 *****************************************************************************/
438 static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
440 char *command = NULL;
441 char *cmd = lp_wins_hook();
444 TALLOC_CTX *ctx = talloc_tos();
446 wins_store_changed_namerec(namerec);
452 for (p=namerec->name.name; *p; p++) {
453 if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
454 DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
459 /* Use the name without the nametype (and scope) appended */
461 namestr = nmb_namestr(&namerec->name);
462 if ((p = strchr(namestr, '<'))) {
466 command = talloc_asprintf(ctx,
471 namerec->name.name_type,
477 for (i=0;i<namerec->data.num_ips;i++) {
478 command = talloc_asprintf_append(command,
480 inet_ntoa(namerec->data.ip[i]));
486 DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
487 smbrun(command, NULL);
488 TALLOC_FREE(command);
491 /****************************************************************************
492 Determine if this packet should be allocated to the WINS server.
493 *****************************************************************************/
495 bool packet_is_for_wins_server(struct packet_struct *packet)
497 struct nmb_packet *nmb = &packet->packet.nmb;
499 /* Only unicast packets go to a WINS server. */
500 if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
501 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
505 /* Check for node status requests. */
506 if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY) {
510 switch(nmb->header.opcode) {
512 * A WINS server issues WACKS, not receives them.
514 case NMB_WACK_OPCODE:
515 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
518 * A WINS server only processes registration and
519 * release requests, not responses.
521 case NMB_NAME_REG_OPCODE:
522 case NMB_NAME_MULTIHOMED_REG_OPCODE:
523 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
524 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
525 if(nmb->header.response) {
526 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
531 case NMB_NAME_RELEASE_OPCODE:
532 if(nmb->header.response) {
533 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
539 * Only process unicast name queries with rd = 1.
541 case NMB_NAME_QUERY_OPCODE:
542 if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
543 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
552 /****************************************************************************
553 Utility function to decide what ttl to give a register/refresh request.
554 *****************************************************************************/
556 static int get_ttl_from_packet(struct nmb_packet *nmb)
558 int ttl = nmb->additional->ttl;
560 if (ttl < lp_min_wins_ttl()) {
561 ttl = lp_min_wins_ttl();
564 if (ttl > lp_max_wins_ttl()) {
565 ttl = lp_max_wins_ttl();
571 /****************************************************************************
572 Load or create the WINS database.
573 *****************************************************************************/
575 bool initialise_wins(void)
577 time_t time_now = time(NULL);
581 if(!lp_we_are_a_wins_server()) {
585 /* Open the wins.tdb. */
586 wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
587 O_CREAT|O_RDWR, 0600);
589 DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
594 tdb_store_int32(wins_tdb, "WINSDB_VERSION", WINSDB_VERSION);
596 add_samba_names_to_subnet(wins_server_subnet);
598 if((fp = x_fopen(state_path(WINS_LIST),O_RDONLY,0)) == NULL) {
599 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
600 WINS_LIST, strerror(errno) ));
604 while (!x_feof(fp)) {
605 char *name_str = NULL;
607 char *ttl_str = NULL, *nb_flags_str = NULL;
608 unsigned int num_ips;
610 struct in_addr *ip_list = NULL;
621 TALLOC_CTX *frame = NULL;
623 /* Read a line from the wins.dat file. Strips whitespace
624 from the beginning and end of the line. */
625 if (!fgets_slash(line,sizeof(line),fp)) {
633 if (strncmp(line,"VERSION ", 8) == 0) {
634 if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
635 version != WINS_VERSION) {
636 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
646 * Now we handle multiple IP addresses per name we need
647 * to iterate over the line twice. The first time to
648 * determine how many IP addresses there are, the second
649 * time to actually parse them into the ip_list array.
652 frame = talloc_stackframe();
653 if (!next_token_talloc(frame,&ptr,&name_str,NULL)) {
654 DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
659 if (!next_token_talloc(frame,&ptr,&ttl_str,NULL)) {
660 DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
666 * Determine the number of IP addresses per line.
670 got_token = next_token_talloc(frame,&ptr,&ip_str,NULL);
673 if(got_token && strchr(ip_str, '.')) {
677 } while(got_token && was_ip);
680 DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
686 DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
691 /* Allocate the space for the ip_list. */
692 if((ip_list = SMB_MALLOC_ARRAY( struct in_addr, num_ips)) == NULL) {
693 DEBUG(0,("initialise_wins: Malloc fail !\n"));
699 /* Reset and re-parse the line. */
701 next_token_talloc(frame,&ptr,&name_str,NULL);
702 next_token_talloc(frame,&ptr,&ttl_str,NULL);
703 for(i = 0; i < num_ips; i++) {
704 next_token_talloc(frame,&ptr, &ip_str, NULL);
705 ip_list[i] = interpret_addr2(ip_str);
707 next_token_talloc(frame,&ptr,&nb_flags_str,NULL);
710 * Deal with SELF or REGISTER name encoding. Default is REGISTER
711 * for compatibility with old nmbds.
714 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
715 DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
721 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') {
722 nb_flags_str[strlen(nb_flags_str)-1] = '\0';
725 /* Netbios name. # divides the name from the type (hex): netbios#xx */
728 if((p = strchr(name,'#')) != NULL) {
730 sscanf(p+1,"%x",&type);
733 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
734 sscanf(nb_flags_str,"%x",&nb_flags);
735 sscanf(ttl_str,"%d",&ttl);
737 /* add all entries that have 60 seconds or more to live */
738 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
739 if(ttl != PERMANENT_TTL) {
743 DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
744 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
746 (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
747 ttl, REGISTER_NAME, num_ips, ip_list );
749 DEBUG(4, ("initialise_wins: not adding name (ttl problem) "
750 "%s#%02x ttl = %d first IP %s flags = %2x\n",
751 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
762 /****************************************************************************
763 Send a WINS WACK (Wait ACKnowledgement) response.
764 **************************************************************************/
766 static void send_wins_wack_response(int ttl, struct packet_struct *p)
768 struct nmb_packet *nmb = &p->packet.nmb;
769 unsigned char rdata[2];
771 rdata[0] = rdata[1] = 0;
773 /* Taken from nmblib.c - we need to send back almost
774 identical bytes from the requesting packet header. */
776 rdata[0] = (nmb->header.opcode & 0xF) << 3;
777 if (nmb->header.nm_flags.authoritative && nmb->header.response) {
780 if (nmb->header.nm_flags.trunc) {
783 if (nmb->header.nm_flags.recursion_desired) {
786 if (nmb->header.nm_flags.recursion_available && nmb->header.response) {
789 if (nmb->header.nm_flags.bcast) {
793 reply_netbios_packet(p, /* Packet to reply to. */
794 0, /* Result code. */
795 NMB_WAIT_ACK, /* nmbd type code. */
796 NMB_WACK_OPCODE, /* opcode. */
798 (char *)rdata, /* data to send. */
799 2); /* data length. */
802 /****************************************************************************
803 Send a WINS name registration response.
804 **************************************************************************/
806 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
808 struct nmb_packet *nmb = &p->packet.nmb;
811 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
813 reply_netbios_packet(p, /* Packet to reply to. */
814 rcode, /* Result code. */
815 WINS_REG, /* nmbd type code. */
816 NMB_NAME_REG_OPCODE, /* opcode. */
818 rdata, /* data to send. */
819 6); /* data length. */
822 /***********************************************************************
823 Deal with a name refresh request to a WINS server.
824 ************************************************************************/
826 void wins_process_name_refresh_request( struct subnet_record *subrec,
827 struct packet_struct *p )
829 struct nmb_packet *nmb = &p->packet.nmb;
830 struct nmb_name *question = &nmb->question.question_name;
831 bool bcast = nmb->header.nm_flags.bcast;
832 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
833 bool group = (nb_flags & NB_GROUP) ? True : False;
834 struct name_record *namerec = NULL;
835 int ttl = get_ttl_from_packet(nmb);
836 struct in_addr from_ip;
837 struct in_addr our_fake_ip;
839 our_fake_ip = interpret_addr2("0.0.0.0");
840 putip( (char *)&from_ip, &nmb->additional->rdata[2] );
844 * We should only get unicast name refresh packets here.
845 * Anyone trying to refresh broadcast should not be going
846 * to a WINS server. Log an error here.
848 if( DEBUGLVL( 0 ) ) {
849 dbgtext( "wins_process_name_refresh_request: " );
850 dbgtext( "Broadcast name refresh request received " );
851 dbgtext( "for name %s ", nmb_namestr(question) );
852 dbgtext( "from IP %s ", inet_ntoa(from_ip) );
853 dbgtext( "on subnet %s. ", subrec->subnet_name );
854 dbgtext( "Error - Broadcasts should not be sent " );
855 dbgtext( "to a WINS server\n" );
860 if( DEBUGLVL( 3 ) ) {
861 dbgtext( "wins_process_name_refresh_request: " );
862 dbgtext( "Name refresh for name %s IP %s\n",
863 nmb_namestr(question), inet_ntoa(from_ip) );
867 * See if the name already exists.
868 * If not, handle it as a name registration and return.
870 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
873 * If this is a refresh request and the name doesn't exist then
874 * treat it like a registration request. This allows us to recover
875 * from errors (tridge)
877 if(namerec == NULL) {
878 if( DEBUGLVL( 3 ) ) {
879 dbgtext( "wins_process_name_refresh_request: " );
880 dbgtext( "Name refresh for name %s ",
881 nmb_namestr( question ) );
882 dbgtext( "and the name does not exist. Treating " );
883 dbgtext( "as registration.\n" );
885 wins_process_name_registration_request(subrec,p);
890 * if the name is present but not active, simply remove it
891 * and treat the refresh request as a registration & return.
893 if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
894 if( DEBUGLVL( 5 ) ) {
895 dbgtext( "wins_process_name_refresh_request: " );
896 dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
897 dbgtext( "was not active - removing it.\n" );
899 remove_name_from_namelist( subrec, namerec );
901 wins_process_name_registration_request( subrec, p );
906 * Check that the group bits for the refreshing name and the
907 * name in our database match. If not, refuse the refresh.
908 * [crh: Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
910 if( (namerec != NULL) &&
911 ( (group && !NAME_GROUP(namerec))
912 || (!group && NAME_GROUP(namerec)) ) ) {
913 if( DEBUGLVL( 3 ) ) {
914 dbgtext( "wins_process_name_refresh_request: " );
915 dbgtext( "Name %s ", nmb_namestr(question) );
916 dbgtext( "group bit = %s does not match ",
917 group ? "True" : "False" );
918 dbgtext( "group bit in WINS for this name.\n" );
920 send_wins_name_registration_response(RFS_ERR, 0, p);
925 * For a unique name check that the person refreshing the name is
926 * one of the registered IP addresses. If not - fail the refresh.
927 * Do the same for group names with a type of 0x1c.
928 * Just return success for unique 0x1d refreshes. For normal group
929 * names update the ttl and return success.
931 if( (!group || (group && (question->name_type == 0x1c)))
932 && find_ip_in_name_record(namerec, from_ip) ) {
936 update_name_ttl(namerec, ttl);
939 * if the record is a replica:
940 * we take ownership and update the version ID.
942 if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
943 update_wins_owner(namerec, our_fake_ip);
944 get_global_id_and_update(&namerec->data.id, True);
947 send_wins_name_registration_response(0, ttl, p);
948 wins_hook("refresh", namerec, ttl);
950 } else if((group && (question->name_type == 0x1c))) {
952 * Added by crh for bug #1079.
953 * Fix from Bert Driehuis
955 if( DEBUGLVL( 3 ) ) {
956 dbgtext( "wins_process_name_refresh_request: " );
957 dbgtext( "Name refresh for name %s, ",
958 nmb_namestr(question) );
959 dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
960 dbgtext( "is not yet associated with " );
961 dbgtext( "that name. Treating as registration.\n" );
963 wins_process_name_registration_request(subrec,p);
967 * Normal groups are all registered with an IP address of
968 * 255.255.255.255 so we can't search for the IP address.
970 update_name_ttl(namerec, ttl);
971 wins_hook("refresh", namerec, ttl);
972 send_wins_name_registration_response(0, ttl, p);
974 } else if(!group && (question->name_type == 0x1d)) {
976 * Special name type - just pretend the refresh succeeded.
978 send_wins_name_registration_response(0, ttl, p);
984 if( DEBUGLVL( 3 ) ) {
985 dbgtext( "wins_process_name_refresh_request: " );
986 dbgtext( "Name refresh for name %s with IP %s ",
987 nmb_namestr(question), inet_ntoa(from_ip) );
988 dbgtext( "and is IP is not known to the name.\n" );
990 send_wins_name_registration_response(RFS_ERR, 0, p);
995 /***********************************************************************
996 Deal with a name registration request query success to a client that
999 We have a locked pointer to the original packet stashed away in the
1000 userdata pointer. The success here is actually a failure as it means
1001 the client we queried wants to keep the name, so we must return
1002 a registration failure to the original requestor.
1003 ************************************************************************/
1005 static void wins_register_query_success(struct subnet_record *subrec,
1006 struct userdata_struct *userdata,
1007 struct nmb_name *question_name,
1009 struct res_rec *answers)
1011 struct packet_struct *orig_reg_packet;
1013 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1015 DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
1016 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
1018 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1020 orig_reg_packet->locked = False;
1021 free_packet(orig_reg_packet);
1024 /***********************************************************************
1025 Deal with a name registration request query failure to a client that
1028 We have a locked pointer to the original packet stashed away in the
1029 userdata pointer. The failure here is actually a success as it means
1030 the client we queried didn't want to keep the name, so we can remove
1031 the old name record and then successfully add the new name.
1032 ************************************************************************/
1034 static void wins_register_query_fail(struct subnet_record *subrec,
1035 struct response_record *rrec,
1036 struct nmb_name *question_name,
1039 struct userdata_struct *userdata = rrec->userdata;
1040 struct packet_struct *orig_reg_packet;
1041 struct name_record *namerec = NULL;
1043 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1046 * We want to just add the name, as we now know the original owner
1047 * didn't want it. But we can't just do that as an arbitary
1048 * amount of time may have taken place between the name query
1049 * request and this timeout/error response. So we check that
1050 * the name still exists and is in the same state - if so
1051 * we remove it and call wins_process_name_registration_request()
1052 * as we know it will do the right thing now.
1055 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1057 if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
1058 ip_equal_v4(rrec->packet->ip, *namerec->data.ip)) {
1059 remove_name_from_namelist( subrec, namerec);
1063 if(namerec == NULL) {
1064 wins_process_name_registration_request(subrec, orig_reg_packet);
1066 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between "
1067 "querying for name %s in order to replace it and this reply.\n",
1068 nmb_namestr(question_name) ));
1071 orig_reg_packet->locked = False;
1072 free_packet(orig_reg_packet);
1075 /***********************************************************************
1076 Deal with a name registration request to a WINS server.
1078 Use the following pseudocode :
1083 +--------name exists
1086 | +--- existing name is group
1089 | | +--- add name (return).
1092 | +--- exiting name is unique
1095 | +--- query existing owner (return).
1098 +--------name doesn't exist
1101 +--- add name (return).
1106 +--------name exists
1109 | +--- existing name is group
1112 | | +--- fail add (return).
1115 | +--- exiting name is unique
1118 | +--- query existing owner (return).
1121 +--------name doesn't exist
1124 +--- add name (return).
1126 As can be seen from the above, the two cases may be collapsed onto each
1127 other with the exception of the case where the name already exists and
1128 is a group name. This case we handle with an if statement.
1130 ************************************************************************/
1132 void wins_process_name_registration_request(struct subnet_record *subrec,
1133 struct packet_struct *p)
1136 struct nmb_packet *nmb = &p->packet.nmb;
1137 struct nmb_name *question = &nmb->question.question_name;
1138 bool bcast = nmb->header.nm_flags.bcast;
1139 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1140 int ttl = get_ttl_from_packet(nmb);
1141 struct name_record *namerec = NULL;
1142 struct in_addr from_ip;
1143 bool registering_group_name = (nb_flags & NB_GROUP) ? True : False;
1144 struct in_addr our_fake_ip;
1146 our_fake_ip = interpret_addr2("0.0.0.0");
1147 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1151 * We should only get unicast name registration packets here.
1152 * Anyone trying to register broadcast should not be going to a WINS
1153 * server. Log an error here.
1156 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
1157 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1158 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1162 DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
1163 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1166 * See if the name already exists.
1169 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1172 * if the record exists but NOT in active state,
1175 if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1176 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
1177 not active - removing it.\n", nmb_namestr(question) ));
1178 remove_name_from_namelist( subrec, namerec );
1183 * Deal with the case where the name found was a dns entry.
1184 * Remove it as we now have a NetBIOS client registering the
1188 if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1189 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
1190 a dns lookup - removing it.\n", nmb_namestr(question) ));
1191 remove_name_from_namelist( subrec, namerec );
1196 * Reject if the name exists and is not a REGISTER_NAME.
1197 * (ie. Don't allow any static names to be overwritten.
1200 if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
1201 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
1202 to register name %s. Name already exists in WINS with source type %d.\n",
1203 nmb_namestr(question), namerec->data.source ));
1204 send_wins_name_registration_response(RFS_ERR, 0, p);
1209 * Special policy decisions based on MS documentation.
1210 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
1211 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
1215 * A group name is always added as the local broadcast address, except
1216 * for group names ending in 0x1c.
1217 * Group names with type 0x1c are registered with individual IP addresses.
1220 if(registering_group_name && (question->name_type != 0x1c)) {
1221 from_ip = interpret_addr2("255.255.255.255");
1225 * Ignore all attempts to register a unique 0x1d name, although return success.
1228 if(!registering_group_name && (question->name_type == 0x1d)) {
1229 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
1230 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
1231 send_wins_name_registration_response(0, ttl, p);
1236 * Next two cases are the 'if statement' mentioned above.
1239 if((namerec != NULL) && NAME_GROUP(namerec)) {
1240 if(registering_group_name) {
1242 * If we are adding a group name, the name exists and is also a group entry just add this
1243 * IP address to it and update the ttl.
1246 DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
1247 inet_ntoa(from_ip), nmb_namestr(question) ));
1250 * Check the ip address is not already in the group.
1253 if(!find_ip_in_name_record(namerec, from_ip)) {
1254 add_ip_to_name_record(namerec, from_ip);
1255 /* we need to update the record for replication */
1256 get_global_id_and_update(&namerec->data.id, True);
1259 * if the record is a replica, we must change
1260 * the wins owner to us to make the replication updates
1261 * it on the other wins servers.
1262 * And when the partner will receive this record,
1263 * it will update its own record.
1266 update_wins_owner(namerec, our_fake_ip);
1268 update_name_ttl(namerec, ttl);
1269 wins_hook("refresh", namerec, ttl);
1270 send_wins_name_registration_response(0, ttl, p);
1275 * If we are adding a unique name, the name exists in the WINS db
1276 * and is a group name then reject the registration.
1278 * explanation: groups have a higher priority than unique names.
1281 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
1282 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1283 send_wins_name_registration_response(RFS_ERR, 0, p);
1289 * From here on down we know that if the name exists in the WINS db it is
1290 * a unique name, not a group name.
1294 * If the name exists and is one of our names then check the
1295 * registering IP address. If it's not one of ours then automatically
1296 * reject without doing the query - we know we will reject it.
1299 if ( namerec != NULL ) {
1300 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
1301 if( is_myname(name) ) {
1302 if(!ismyip_v4(from_ip)) {
1303 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
1304 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1305 send_wins_name_registration_response(RFS_ERR, 0, p);
1309 * It's one of our names and one of our IP's - update the ttl.
1311 update_name_ttl(namerec, ttl);
1312 wins_hook("refresh", namerec, ttl);
1313 send_wins_name_registration_response(0, ttl, p);
1322 * If the name exists and it is a unique registration and the registering IP
1323 * is the same as the (single) already registered IP then just update the ttl.
1325 * But not if the record is an active replica. IF it's a replica, it means it can be
1326 * the same client which has moved and not yet expired. So we don't update
1327 * the ttl in this case and go beyond to do a WACK and query the old client
1330 if( !registering_group_name
1331 && (namerec != NULL)
1332 && (namerec->data.num_ips == 1)
1333 && ip_equal_v4( namerec->data.ip[0], from_ip )
1334 && ip_equal_v4(namerec->data.wins_ip, our_fake_ip) ) {
1335 update_name_ttl( namerec, ttl );
1336 wins_hook("refresh", namerec, ttl);
1337 send_wins_name_registration_response( 0, ttl, p );
1342 * Finally if the name exists do a query to the registering machine
1343 * to see if they still claim to have the name.
1346 if( namerec != NULL ) {
1347 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1348 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1351 * First send a WACK to the registering machine.
1354 send_wins_wack_response(60, p);
1357 * When the reply comes back we need the original packet.
1358 * Lock this so it won't be freed and then put it into
1359 * the userdata structure.
1364 userdata = (struct userdata_struct *)ud;
1366 userdata->copy_fn = NULL;
1367 userdata->free_fn = NULL;
1368 userdata->userdata_len = sizeof(struct packet_struct *);
1369 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1372 * Use the new call to send a query directly to an IP address.
1373 * This sends the query directly to the IP address, and ensures
1374 * the recursion desired flag is not set (you were right Luke :-).
1375 * This function should *only* be called from the WINS server
1379 pull_ascii_nstring(name, sizeof(name), question->name);
1380 query_name_from_wins_server( *namerec->data.ip,
1382 question->name_type,
1383 wins_register_query_success,
1384 wins_register_query_fail,
1390 * Name did not exist - add it.
1393 pull_ascii_nstring(name, sizeof(name), question->name);
1394 add_name_to_subnet( subrec, name, question->name_type,
1395 nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1397 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1398 get_global_id_and_update(&namerec->data.id, True);
1399 update_wins_owner(namerec, our_fake_ip);
1400 update_wins_flag(namerec, WINS_ACTIVE);
1401 wins_hook("add", namerec, ttl);
1404 send_wins_name_registration_response(0, ttl, p);
1407 /***********************************************************************
1408 Deal with a mutihomed name query success to the machine that
1409 requested the multihomed name registration.
1411 We have a locked pointer to the original packet stashed away in the
1413 ************************************************************************/
1415 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
1416 struct userdata_struct *userdata,
1417 struct nmb_name *question_name,
1419 struct res_rec *answers)
1421 struct packet_struct *orig_reg_packet;
1422 struct nmb_packet *nmb;
1423 struct name_record *namerec = NULL;
1424 struct in_addr from_ip;
1426 struct in_addr our_fake_ip;
1428 our_fake_ip = interpret_addr2("0.0.0.0");
1429 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1431 nmb = &orig_reg_packet->packet.nmb;
1433 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1434 ttl = get_ttl_from_packet(nmb);
1437 * We want to just add the new IP, as we now know the requesting
1438 * machine claims to own it. But we can't just do that as an arbitary
1439 * amount of time may have taken place between the name query
1440 * request and this response. So we check that
1441 * the name still exists and is in the same state - if so
1442 * we just add the extra IP and update the ttl.
1445 namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1447 if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
1448 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
1449 a subsequent IP address.\n", nmb_namestr(question_name) ));
1450 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1452 orig_reg_packet->locked = False;
1453 free_packet(orig_reg_packet);
1458 if(!find_ip_in_name_record(namerec, from_ip)) {
1459 add_ip_to_name_record(namerec, from_ip);
1462 get_global_id_and_update(&namerec->data.id, True);
1463 update_wins_owner(namerec, our_fake_ip);
1464 update_wins_flag(namerec, WINS_ACTIVE);
1465 update_name_ttl(namerec, ttl);
1466 wins_hook("add", namerec, ttl);
1467 send_wins_name_registration_response(0, ttl, orig_reg_packet);
1469 orig_reg_packet->locked = False;
1470 free_packet(orig_reg_packet);
1473 /***********************************************************************
1474 Deal with a name registration request query failure to a client that
1477 We have a locked pointer to the original packet stashed away in the
1479 ************************************************************************/
1481 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
1482 struct response_record *rrec,
1483 struct nmb_name *question_name,
1486 struct userdata_struct *userdata = rrec->userdata;
1487 struct packet_struct *orig_reg_packet;
1489 memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1491 DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
1492 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
1493 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1495 orig_reg_packet->locked = False;
1496 free_packet(orig_reg_packet);
1500 /***********************************************************************
1501 Deal with a multihomed name registration request to a WINS server.
1502 These cannot be group name registrations.
1503 ***********************************************************************/
1505 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
1506 struct packet_struct *p)
1508 struct nmb_packet *nmb = &p->packet.nmb;
1509 struct nmb_name *question = &nmb->question.question_name;
1510 bool bcast = nmb->header.nm_flags.bcast;
1511 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1512 int ttl = get_ttl_from_packet(nmb);
1513 struct name_record *namerec = NULL;
1514 struct in_addr from_ip;
1515 bool group = (nb_flags & NB_GROUP) ? True : False;
1516 struct in_addr our_fake_ip;
1519 our_fake_ip = interpret_addr2("0.0.0.0");
1520 putip((char *)&from_ip,&nmb->additional->rdata[2]);
1524 * We should only get unicast name registration packets here.
1525 * Anyone trying to register broadcast should not be going to a WINS
1526 * server. Log an error here.
1529 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1530 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1531 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1536 * Only unique names should be registered multihomed.
1540 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1541 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1542 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1546 DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1547 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1550 * Deal with policy regarding 0x1d names.
1553 if(question->name_type == 0x1d) {
1554 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1555 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1556 send_wins_name_registration_response(0, ttl, p);
1561 * See if the name already exists.
1564 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1567 * if the record exists but NOT in active state,
1571 if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1572 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
1573 remove_name_from_namelist(subrec, namerec);
1578 * Deal with the case where the name found was a dns entry.
1579 * Remove it as we now have a NetBIOS client registering the
1583 if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1584 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1585 - removing it.\n", nmb_namestr(question) ));
1586 remove_name_from_namelist( subrec, namerec);
1591 * Reject if the name exists and is not a REGISTER_NAME.
1592 * (ie. Don't allow any static names to be overwritten.
1595 if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
1596 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1597 to register name %s. Name already exists in WINS with source type %d.\n",
1598 nmb_namestr(question), namerec->data.source ));
1599 send_wins_name_registration_response(RFS_ERR, 0, p);
1604 * Reject if the name exists and is a GROUP name and is active.
1607 if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
1608 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1609 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1610 send_wins_name_registration_response(RFS_ERR, 0, p);
1615 * From here on down we know that if the name exists in the WINS db it is
1616 * a unique name, not a group name.
1620 * If the name exists and is one of our names then check the
1621 * registering IP address. If it's not one of ours then automatically
1622 * reject without doing the query - we know we will reject it.
1625 if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
1626 if(!ismyip_v4(from_ip)) {
1627 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1628 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1629 send_wins_name_registration_response(RFS_ERR, 0, p);
1633 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1634 * update the ttl. Update the version ID to force replication.
1636 update_name_ttl(namerec, ttl);
1638 if(!find_ip_in_name_record(namerec, from_ip)) {
1639 get_global_id_and_update(&namerec->data.id, True);
1640 update_wins_owner(namerec, our_fake_ip);
1641 update_wins_flag(namerec, WINS_ACTIVE);
1643 add_ip_to_name_record(namerec, from_ip);
1646 wins_hook("refresh", namerec, ttl);
1647 send_wins_name_registration_response(0, ttl, p);
1653 * If the name exists and is active, check if the IP address is already registered
1654 * to that name. If so then update the ttl and reply success.
1657 if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
1658 update_name_ttl(namerec, ttl);
1661 * If it's a replica, we need to become the wins owner
1662 * to force the replication
1664 if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
1665 get_global_id_and_update(&namerec->data.id, True);
1666 update_wins_owner(namerec, our_fake_ip);
1667 update_wins_flag(namerec, WINS_ACTIVE);
1670 wins_hook("refresh", namerec, ttl);
1671 send_wins_name_registration_response(0, ttl, p);
1676 * If the name exists do a query to the owner
1677 * to see if they still want the name.
1680 if(namerec != NULL) {
1681 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1682 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1685 * First send a WACK to the registering machine.
1688 send_wins_wack_response(60, p);
1691 * When the reply comes back we need the original packet.
1692 * Lock this so it won't be freed and then put it into
1693 * the userdata structure.
1698 userdata = (struct userdata_struct *)ud;
1700 userdata->copy_fn = NULL;
1701 userdata->free_fn = NULL;
1702 userdata->userdata_len = sizeof(struct packet_struct *);
1703 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1706 * Use the new call to send a query directly to an IP address.
1707 * This sends the query directly to the IP address, and ensures
1708 * the recursion desired flag is not set (you were right Luke :-).
1709 * This function should *only* be called from the WINS server
1712 * Note that this packet is sent to the current owner of the name,
1713 * not the person who sent the packet
1716 pull_ascii_nstring( qname, sizeof(qname), question->name);
1717 query_name_from_wins_server( namerec->data.ip[0],
1719 question->name_type,
1720 wins_multihomed_register_query_success,
1721 wins_multihomed_register_query_fail,
1728 * Name did not exist - add it.
1731 pull_ascii_nstring( qname, sizeof(qname), question->name);
1732 add_name_to_subnet( subrec, qname, question->name_type,
1733 nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1735 if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1736 get_global_id_and_update(&namerec->data.id, True);
1737 update_wins_owner(namerec, our_fake_ip);
1738 update_wins_flag(namerec, WINS_ACTIVE);
1739 wins_hook("add", namerec, ttl);
1742 send_wins_name_registration_response(0, ttl, p);
1745 /***********************************************************************
1746 Fetch all *<1b> names from the WINS db and store on the namelist.
1747 ***********************************************************************/
1749 static int fetch_1b_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
1751 struct name_record *namerec = NULL;
1753 if (kbuf.dsize != sizeof(unstring) + 1) {
1757 /* Filter out all non-1b names. */
1758 if (kbuf.dptr[sizeof(unstring)] != 0x1b) {
1762 namerec = wins_record_to_name_record(kbuf, dbuf);
1767 DLIST_ADD(wins_server_subnet->namelist, namerec);
1771 void fetch_all_active_wins_1b_names(void)
1773 tdb_traverse(wins_tdb, fetch_1b_traverse_fn, NULL);
1776 /***********************************************************************
1777 Deal with the special name query for *<1b>.
1778 ***********************************************************************/
1780 static void process_wins_dmb_query_request(struct subnet_record *subrec,
1781 struct packet_struct *p)
1783 struct name_record *namerec = NULL;
1788 * Go through all the ACTIVE names in the WINS db looking for those
1789 * ending in <1b>. Use this to calculate the number of IP
1790 * addresses we need to return.
1795 /* First, clear the in memory list - we're going to re-populate
1796 it with the tdb_traversal in fetch_all_active_wins_1b_names. */
1798 wins_delete_all_tmp_in_memory_records();
1800 fetch_all_active_wins_1b_names();
1802 for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
1803 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1804 num_ips += namerec->data.num_ips;
1810 * There are no 0x1b names registered. Return name query fail.
1812 send_wins_name_query_response(NAM_ERR, p, NULL);
1816 if((prdata = (char *)SMB_MALLOC( num_ips * 6 )) == NULL) {
1817 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1822 * Go through all the names again in the WINS db looking for those
1823 * ending in <1b>. Add their IP addresses into the list we will
1828 for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
1829 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1831 for(i = 0; i < namerec->data.num_ips; i++) {
1832 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1833 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1840 * Send back the reply containing the IP list.
1843 reply_netbios_packet(p, /* Packet to reply to. */
1844 0, /* Result code. */
1845 WINS_QUERY, /* nmbd type code. */
1846 NMB_NAME_QUERY_OPCODE, /* opcode. */
1847 lp_min_wins_ttl(), /* ttl. */
1848 prdata, /* data to send. */
1849 num_ips*6); /* data length. */
1854 /****************************************************************************
1855 Send a WINS name query response.
1856 **************************************************************************/
1858 void send_wins_name_query_response(int rcode, struct packet_struct *p,
1859 struct name_record *namerec)
1862 char *prdata = rdata;
1863 int reply_data_len = 0;
1867 memset(rdata,'\0',6);
1870 ttl = (namerec->data.death_time != PERMANENT_TTL) ? namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1872 /* Copy all known ip addresses into the return data. */
1873 /* Optimise for the common case of one IP address so we don't need a malloc. */
1875 if( namerec->data.num_ips == 1 ) {
1878 if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
1879 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1884 for(i = 0; i < namerec->data.num_ips; i++) {
1885 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1886 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1889 sort_query_replies(prdata, i, p->ip);
1890 reply_data_len = namerec->data.num_ips * 6;
1893 reply_netbios_packet(p, /* Packet to reply to. */
1894 rcode, /* Result code. */
1895 WINS_QUERY, /* nmbd type code. */
1896 NMB_NAME_QUERY_OPCODE, /* opcode. */
1898 prdata, /* data to send. */
1899 reply_data_len); /* data length. */
1901 if(prdata != rdata) {
1906 /***********************************************************************
1907 Deal with a name query.
1908 ***********************************************************************/
1910 void wins_process_name_query_request(struct subnet_record *subrec,
1911 struct packet_struct *p)
1913 struct nmb_packet *nmb = &p->packet.nmb;
1914 struct nmb_name *question = &nmb->question.question_name;
1915 struct name_record *namerec = NULL;
1918 DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1919 nmb_namestr(question), inet_ntoa(p->ip) ));
1922 * Special name code. If the queried name is *<1b> then search
1923 * the entire WINS database and return a list of all the IP addresses
1924 * registered to any <1b> name. This is to allow domain master browsers
1925 * to discover other domains that may not have a presence on their subnet.
1928 pull_ascii_nstring(qname, sizeof(qname), question->name);
1929 if(strequal( qname, "*") && (question->name_type == 0x1b)) {
1930 process_wins_dmb_query_request( subrec, p);
1934 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1936 if(namerec != NULL) {
1938 * If the name is not anymore in active state then reply not found.
1939 * it's fair even if we keep it in the cache for days.
1941 if (!WINS_STATE_ACTIVE(namerec)) {
1942 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1943 nmb_namestr(question) ));
1944 send_wins_name_query_response(NAM_ERR, p, namerec);
1949 * If it's a DNSFAIL_NAME then reply name not found.
1952 if( namerec->data.source == DNSFAIL_NAME ) {
1953 DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1954 nmb_namestr(question) ));
1955 send_wins_name_query_response(NAM_ERR, p, namerec);
1960 * If the name has expired then reply name not found.
1963 if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
1964 DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1965 nmb_namestr(question) ));
1966 send_wins_name_query_response(NAM_ERR, p, namerec);
1970 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1971 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1973 send_wins_name_query_response(0, p, namerec);
1978 * Name not found in WINS - try a dns query if it's a 0x20 name.
1981 if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
1982 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1983 nmb_namestr(question) ));
1985 queue_dns_query(p, question);
1990 * Name not found - return error.
1993 send_wins_name_query_response(NAM_ERR, p, NULL);
1996 /****************************************************************************
1997 Send a WINS name release response.
1998 **************************************************************************/
2000 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
2002 struct nmb_packet *nmb = &p->packet.nmb;
2005 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
2007 reply_netbios_packet(p, /* Packet to reply to. */
2008 rcode, /* Result code. */
2009 NMB_REL, /* nmbd type code. */
2010 NMB_NAME_RELEASE_OPCODE, /* opcode. */
2012 rdata, /* data to send. */
2013 6); /* data length. */
2016 /***********************************************************************
2017 Deal with a name release.
2018 ***********************************************************************/
2020 void wins_process_name_release_request(struct subnet_record *subrec,
2021 struct packet_struct *p)
2023 struct nmb_packet *nmb = &p->packet.nmb;
2024 struct nmb_name *question = &nmb->question.question_name;
2025 bool bcast = nmb->header.nm_flags.bcast;
2026 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
2027 struct name_record *namerec = NULL;
2028 struct in_addr from_ip;
2029 bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
2031 putip((char *)&from_ip,&nmb->additional->rdata[2]);
2035 * We should only get unicast name registration packets here.
2036 * Anyone trying to register broadcast should not be going to a WINS
2037 * server. Log an error here.
2040 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
2041 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
2042 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
2046 DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
2047 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
2050 * Deal with policy regarding 0x1d names.
2053 if(!releasing_group_name && (question->name_type == 0x1d)) {
2054 DEBUG(3,("wins_process_name_release_request: Ignoring request \
2055 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
2056 send_wins_name_release_response(0, p);
2061 * See if the name already exists.
2064 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
2066 if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
2067 send_wins_name_release_response(NAM_ERR, p);
2072 * Check that the sending machine has permission to release this name.
2073 * If it's a group name not ending in 0x1c then just say yes and let
2074 * the group time out.
2077 if(releasing_group_name && (question->name_type != 0x1c)) {
2078 send_wins_name_release_response(0, p);
2083 * Check that the releasing node is on the list of IP addresses
2084 * for this name. Disallow the release if not.
2087 if(!find_ip_in_name_record(namerec, from_ip)) {
2088 DEBUG(3,("wins_process_name_release_request: Refusing request to \
2089 release name %s as IP %s is not one of the known IP's for this name.\n",
2090 nmb_namestr(question), inet_ntoa(from_ip) ));
2091 send_wins_name_release_response(NAM_ERR, p);
2096 * Check if the record is active. IF it's already released
2097 * or tombstoned, refuse the release.
2100 if (!WINS_STATE_ACTIVE(namerec)) {
2101 DEBUG(3,("wins_process_name_release_request: Refusing request to \
2102 release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
2103 send_wins_name_release_response(NAM_ERR, p);
2108 * Check if the record is a 0x1c group
2109 * and has more then one ip
2110 * remove only this address.
2113 if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
2114 remove_ip_from_name_record(namerec, from_ip);
2115 DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
2116 inet_ntoa(from_ip),nmb_namestr(question)));
2117 wins_hook("delete", namerec, 0);
2118 send_wins_name_release_response(0, p);
2123 * Send a release response.
2124 * Flag the name as released and update the ttl
2127 namerec->data.wins_flags |= WINS_RELEASED;
2128 update_name_ttl(namerec, EXTINCTION_INTERVAL);
2130 wins_hook("delete", namerec, 0);
2131 send_wins_name_release_response(0, p);
2134 /*******************************************************************
2135 WINS time dependent processing.
2136 ******************************************************************/
2138 static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
2140 time_t t = *(time_t *)state;
2141 bool store_record = False;
2142 struct name_record *namerec = NULL;
2143 struct in_addr our_fake_ip;
2145 our_fake_ip = interpret_addr2("0.0.0.0");
2146 if (kbuf.dsize != sizeof(unstring) + 1) {
2150 namerec = wins_record_to_name_record(kbuf, dbuf);
2155 if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
2156 if( namerec->data.source == SELF_NAME ) {
2157 DEBUG( 3, ( "wins_processing_traverse_fn: Subnet %s not expiring SELF name %s\n",
2158 wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
2159 namerec->data.death_time += 300;
2160 store_record = True;
2162 } else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
2163 DEBUG(3,("wins_processing_traverse_fn: deleting timed out DNS name %s\n",
2164 nmb_namestr(&namerec->name)));
2165 remove_name_from_wins_namelist(namerec );
2169 /* handle records, samba is the wins owner */
2170 if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
2171 switch (namerec->data.wins_flags & WINS_STATE_MASK) {
2173 namerec->data.wins_flags&=~WINS_STATE_MASK;
2174 namerec->data.wins_flags|=WINS_RELEASED;
2175 namerec->data.death_time = t + EXTINCTION_INTERVAL;
2176 DEBUG(3,("wins_processing_traverse_fn: expiring %s\n",
2177 nmb_namestr(&namerec->name)));
2178 store_record = True;
2181 namerec->data.wins_flags&=~WINS_STATE_MASK;
2182 namerec->data.wins_flags|=WINS_TOMBSTONED;
2183 namerec->data.death_time = t + EXTINCTION_TIMEOUT;
2184 get_global_id_and_update(&namerec->data.id, True);
2185 DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
2186 nmb_namestr(&namerec->name)));
2187 store_record = True;
2189 case WINS_TOMBSTONED:
2190 DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
2191 nmb_namestr(&namerec->name)));
2192 remove_name_from_wins_namelist(namerec );
2196 switch (namerec->data.wins_flags & WINS_STATE_MASK) {
2198 /* that's not as MS says it should be */
2199 namerec->data.wins_flags&=~WINS_STATE_MASK;
2200 namerec->data.wins_flags|=WINS_TOMBSTONED;
2201 namerec->data.death_time = t + EXTINCTION_TIMEOUT;
2202 DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
2203 nmb_namestr(&namerec->name)));
2204 store_record = True;
2206 case WINS_TOMBSTONED:
2207 DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
2208 nmb_namestr(&namerec->name)));
2209 remove_name_from_wins_namelist(namerec );
2212 DEBUG(0,("wins_processing_traverse_fn: %s is in released state and\
2213 we are not the wins owner !\n", nmb_namestr(&namerec->name)));
2222 wins_store_changed_namerec(namerec);
2225 SAFE_FREE(namerec->data.ip);
2231 /*******************************************************************
2232 Time dependent wins processing.
2233 ******************************************************************/
2235 void initiate_wins_processing(time_t t)
2237 static time_t lasttime = 0;
2242 if (t - lasttime < 20) {
2246 if(!lp_we_are_a_wins_server()) {
2251 tdb_traverse(wins_tdb, wins_processing_traverse_fn, &t);
2253 wins_delete_all_tmp_in_memory_records();
2255 wins_write_database(t, True);
2260 /*******************************************************************
2261 Write out one record.
2262 ******************************************************************/
2264 void wins_write_name_record(struct name_record *namerec, XFILE *fp)
2269 DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
2271 if( namerec->data.death_time != PERMANENT_TTL ) {
2274 tm = localtime(&namerec->data.death_time);
2282 nl = strrchr( ts, '\n' );
2286 DEBUGADD(4,("TTL = %s ", ts ));
2288 DEBUGADD(4,("TTL = PERMANENT "));
2291 for (i = 0; i < namerec->data.num_ips; i++) {
2292 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
2294 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
2296 if( namerec->data.source == REGISTER_NAME ) {
2298 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
2299 x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
2300 (int)namerec->data.death_time);
2302 for (i = 0; i < namerec->data.num_ips; i++)
2303 x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
2304 x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
2308 /*******************************************************************
2309 Write out the current WINS database.
2310 ******************************************************************/
2312 static int wins_writedb_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
2314 struct name_record *namerec = NULL;
2315 XFILE *fp = (XFILE *)state;
2317 if (kbuf.dsize != sizeof(unstring) + 1) {
2321 namerec = wins_record_to_name_record(kbuf, dbuf);
2326 wins_write_name_record(namerec, fp);
2328 SAFE_FREE(namerec->data.ip);
2334 void wins_write_database(time_t t, bool background)
2336 static time_t last_write_time = 0;
2338 char *fnamenew = NULL;
2343 if (!last_write_time) {
2344 last_write_time = t;
2346 if (t - last_write_time < 120) {
2352 if(!lp_we_are_a_wins_server()) {
2356 /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
2362 if (tdb_reopen(wins_tdb)) {
2363 DEBUG(0,("wins_write_database: tdb_reopen failed. Error was %s\n",
2370 if (!(fname = state_path(WINS_LIST))) {
2373 /* This is safe as the 0 length means "don't expand". */
2374 all_string_sub(fname,"//", "/", 0);
2376 if (asprintf(&fnamenew, "%s.%u", fname, (unsigned int)sys_getpid()) < 0) {
2380 if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
2381 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
2385 DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
2387 x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
2389 tdb_traverse(wins_tdb, wins_writedb_traverse_fn, fp);
2392 chmod(fnamenew,0644);
2394 rename(fnamenew,fname);
2398 SAFE_FREE(fnamenew);
2407 Until winsrepl is done.
2408 /****************************************************************************
2409 Process a internal Samba message receiving a wins record.
2410 ***************************************************************************/
2412 void nmbd_wins_new_entry(struct messaging_context *msg,
2415 struct server_id server_id,
2418 WINS_RECORD *record;
2419 struct name_record *namerec = NULL;
2420 struct name_record *new_namerec = NULL;
2421 struct nmb_name question;
2422 bool overwrite=False;
2423 struct in_addr our_fake_ip;
2426 our_fake_ip = interpret_addr2("0.0.0.0");
2431 /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
2432 record=(WINS_RECORD *)buf;
2434 make_nmb_name(&question, record->name, record->type);
2436 namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
2438 /* record doesn't exist, add it */
2439 if (namerec == NULL) {
2440 DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
2441 record->name, record->type, inet_ntoa(record->wins_ip)));
2443 new_namerec=add_name_to_subnet( wins_server_subnet,
2447 EXTINCTION_INTERVAL,
2452 if (new_namerec!=NULL) {
2453 update_wins_owner(new_namerec, record->wins_ip);
2454 update_wins_flag(new_namerec, record->wins_flags);
2455 new_namerec->data.id=record->id;
2457 wins_server_subnet->namelist_changed = True;
2461 /* check if we have a conflict */
2462 if (namerec != NULL) {
2463 /* both records are UNIQUE */
2464 if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
2466 /* the database record is a replica */
2467 if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
2468 if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
2469 if (ip_equal_v4(namerec->data.wins_ip, record->wins_ip))
2474 /* we are the wins owner of the database record */
2475 /* the 2 records have the same IP address */
2476 if (ip_equal_v4(namerec->data.ip[0], record->ip[0])) {
2477 if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
2478 get_global_id_and_update(&namerec->data.id, True);
2483 /* the 2 records have different IP address */
2484 if (namerec->data.wins_flags&WINS_ACTIVE) {
2485 if (record->wins_flags&WINS_TOMBSTONED)
2486 get_global_id_and_update(&namerec->data.id, True);
2487 if (record->wins_flags&WINS_ACTIVE)
2488 /* send conflict challenge to the replica node */
2497 /* the replica is a standard group */
2498 if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
2499 /* if the database record is unique and active force a name release */
2500 if (namerec->data.wins_flags&WINS_UNIQUE)
2501 /* send a release name to the unique node */
2507 /* the replica is a special group */
2508 if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
2509 if (namerec->data.wins_flags&WINS_ACTIVE) {
2510 for (i=0; i<record->num_ips; i++)
2511 if(!find_ip_in_name_record(namerec, record->ip[i]))
2512 add_ip_to_name_record(namerec, record->ip[i]);
2518 /* the replica is a multihomed host */
2520 /* I'm giving up on multi homed. Too much complex to understand */
2522 if (record->wins_flags&WINS_MHOMED) {
2523 if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
2524 if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
2528 if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
2531 if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip))
2532 if (namerec->data.wins_flags&WINS_UNIQUE)
2533 get_global_id_and_update(&namerec->data.id, True);
2537 if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
2538 if (namerec->data.wins_flags&WINS_UNIQUE ||
2539 namerec->data.wins_flags&WINS_MHOMED)
2540 if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
2545 if (overwrite == False)
2546 DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n",
2547 record->name, record->type, inet_ntoa(record->wins_ip)));
2549 DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n",
2550 record->name, record->type, inet_ntoa(record->wins_ip)));
2552 /* remove the old record and add a new one */
2553 remove_name_from_namelist( wins_server_subnet, namerec );
2554 new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
2555 EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
2556 if (new_namerec!=NULL) {
2557 update_wins_owner(new_namerec, record->wins_ip);
2558 update_wins_flag(new_namerec, record->wins_flags);
2559 new_namerec->data.id=record->id;
2561 wins_server_subnet->namelist_changed = True;
2564 wins_server_subnet->namelist_changed = True;