first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[nivanova/samba-autobuild/.git] / source / nmbd / nmbd_winsserver.c
index 35ca5af62c4774ee5e3e9e360f1e769422e3b259..45e93351674289924ea277c96f72dda5b0c83e9c 100644 (file)
@@ -30,6 +30,41 @@ extern int DEBUGLEVEL;
 extern struct in_addr ipzero;
 
 
+/****************************************************************************
+possibly call the WINS hook external program when a WINS change is made
+*****************************************************************************/
+static void wins_hook(char *operation, struct name_record *namerec, int ttl)
+{
+       pstring command;
+       char *cmd = lp_wins_hook();
+       char *p;
+       int i;
+
+       if (!cmd || !*cmd) return;
+
+       for (p=namerec->name.name; *p; p++) {
+               if (!(isalnum((int)*p) || strchr("._-",*p))) {
+                       DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
+                       return;
+               }
+       }
+       
+       p = command;
+       p += slprintf(p, sizeof(command), "%s %s %s %02x %d", 
+                     cmd,
+                     operation, 
+                     namerec->name.name,
+                     namerec->name.name_type,
+                     ttl);
+
+       for (i=0;i<namerec->data.num_ips;i++) {
+               p += slprintf(p, sizeof(command) - (p-command), " %s", inet_ntoa(namerec->data.ip[i]));
+       }
+
+       DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
+       smbrun(command, NULL, False);
+}
+
 
 /****************************************************************************
 hash our interfaces and netbios names settings
@@ -147,11 +182,6 @@ BOOL initialise_wins(void)
 
   add_samba_names_to_subnet(wins_server_subnet);
 
-#ifndef SYNC_DNS
-  /* Setup the async dns. */
-  start_async_dns();
-#endif
-
   pstrcpy(fname,lp_lockdir());
   trim_string(fname,NULL,"/");
   pstrcat(fname,"/");
@@ -456,6 +486,7 @@ does not match group bit in WINS for this name.\n", nmb_namestr(question), group
      */
     update_name_ttl(namerec, ttl);
     send_wins_name_registration_response(0, ttl, p);
+    wins_hook("refresh", namerec, ttl);
     return;
   }
   else if(group)
@@ -636,7 +667,7 @@ void wins_process_name_registration_request(struct subnet_record *subrec,
   int ttl = get_ttl_from_packet(nmb);
   struct name_record *namerec = NULL;
   struct in_addr from_ip;
-  BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
+  BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
 
   putip((char *)&from_ip,&nmb->additional->rdata[2]);
 
@@ -715,7 +746,7 @@ to register name %s. Name already exists in WINS with source type %d.\n",
   if(!registering_group_name && (question->name_type == 0x1d))
   {
     DEBUG(3,("wins_process_name_registration_request: Ignoring request \
-to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
+to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
     send_wins_name_registration_response(0, ttl, p);
     return;
   }
@@ -785,6 +816,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
        */
       update_name_ttl(namerec, ttl);
       send_wins_name_registration_response(0, ttl, p);
+      wins_hook("refresh", namerec, ttl);
       return;
     }
   }
@@ -801,6 +833,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   {
     update_name_ttl( namerec, ttl );
     send_wins_name_registration_response( 0, ttl, p );
+    wins_hook("refresh", namerec, ttl);
     return;
   }
 
@@ -858,6 +891,9 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
 
   (void)add_name_to_subnet( subrec, question->name, question->name_type,
                             nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
+  if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+         wins_hook("add", namerec, ttl);
+  }
 
   send_wins_name_registration_response(0, ttl, p);
 }
@@ -916,6 +952,7 @@ a subsequent IP addess.\n", nmb_namestr(question_name) ));
     add_ip_to_name_record(namerec, from_ip);
   update_name_ttl(namerec, ttl);
   send_wins_name_registration_response(0, ttl, orig_reg_packet);
+  wins_hook("add", namerec, ttl);
 
   orig_reg_packet->locked = False;
   free_packet(orig_reg_packet);
@@ -1082,11 +1119,16 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
        * It's one of our names and one of our IP's. Ensure the IP is in the record and
        *  update the ttl.
        */
-      if(!find_ip_in_name_record(namerec, from_ip))
-        add_ip_to_name_record(namerec, from_ip);
-      update_name_ttl(namerec, ttl);
-      send_wins_name_registration_response(0, ttl, p);
-      return;
+           if(!find_ip_in_name_record(namerec, from_ip)) {
+                   add_ip_to_name_record(namerec, from_ip);
+                   wins_hook("add", namerec, ttl);
+           } else {
+                   wins_hook("refresh", namerec, ttl);
+           }
+
+           update_name_ttl(namerec, ttl);
+           send_wins_name_registration_response(0, ttl, p);
+           return;
     }
   }
 
@@ -1099,6 +1141,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   {
     update_name_ttl(namerec, ttl);
     send_wins_name_registration_response(0, ttl, p);
+    wins_hook("refresh", namerec, ttl);
     return;
   }
 
@@ -1158,6 +1201,10 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   (void)add_name_to_subnet( subrec, question->name, question->name_type,
                             nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
 
+  if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+         wins_hook("add", namerec, ttl);
+  }
+
   send_wins_name_registration_response(0, ttl, p);
 }
 
@@ -1253,7 +1300,7 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
   int ttl = 0;
   int i;
 
-  bzero(rdata,6);
+  memset(rdata,'\0',6);
 
   if(rcode == 0)
   {
@@ -1495,6 +1542,8 @@ release name %s as IP %s is not one of the known IP's for this name.\n",
   send_wins_name_release_response(0, p);
   remove_ip_from_name_record(namerec, from_ip);
 
+  wins_hook("delete", namerec, 0);
+
   /* 
    * Remove the name entirely if no IP addresses left.
    */
@@ -1552,7 +1601,7 @@ void wins_write_database(BOOL background)
   }
 
   slprintf(fname,sizeof(fname),"%s/%s", lp_lockdir(), WINS_LIST);
-  string_sub(fname,"//", "/");
+  all_string_sub(fname,"//", "/", 0);
   slprintf(fnamenew,sizeof(fnamenew),"%s.%u", fname, (unsigned int)getpid());
 
   if((fp = sys_fopen(fnamenew,"w")) == NULL)