fix minor nits in nmbd from adtam@cup.hp.com
[samba.git] / source3 / nmbd / nmbd_mynames.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6    Copyright (C) Jeremy Allison 1994-1998
7    
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.
12    
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.
17    
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.
21    
22 */
23
24 #include "includes.h"
25
26 extern char **my_netbios_names;
27 extern fstring global_myworkgroup;
28
29 extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
30
31 /****************************************************************************
32  Fail funtion when registering my netbios names.
33   **************************************************************************/
34
35 static void my_name_register_failed(struct subnet_record *subrec,
36                               struct response_record *rrec, struct nmb_name *nmbname)
37 {
38   DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
39             nmb_namestr(nmbname), subrec->subnet_name));
40 }
41
42
43 /****************************************************************************
44   Add my workgroup and my given names to one subnet
45   Also add the magic Samba names.
46   **************************************************************************/
47 void register_my_workgroup_one_subnet(struct subnet_record *subrec)
48 {
49         int i;
50
51         struct work_record *work;
52
53         /* Create the workgroup on the subnet. */
54         if((work = create_workgroup_on_subnet(subrec, global_myworkgroup, 
55                                               PERMANENT_TTL)) == NULL) {
56                 DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
57 Exiting.\n", global_myworkgroup, subrec->subnet_name));
58                 return;
59         }
60
61         /* Each subnet entry, except for the wins_server_subnet has
62            the magic Samba names. */
63         add_samba_names_to_subnet(subrec);
64
65         /* Register all our names including aliases. */
66         for (i=0; my_netbios_names[i]; i++) {
67                 register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
68                               NULL,
69                               my_name_register_failed, NULL);
70                 register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
71                               NULL,
72                               my_name_register_failed, NULL);
73                 register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
74                               NULL,
75                               my_name_register_failed, NULL);
76         }
77         
78         /* Initiate election processing, register the workgroup names etc. */
79         initiate_myworkgroup_startup(subrec, work);
80 }
81
82 /*******************************************************************
83  Utility function to add a name to the unicast subnet, or add in
84  our IP address if it already exists.
85 ******************************************************************/
86
87 static void insert_refresh_name_into_unicast( struct subnet_record *subrec,
88                                                 struct nmb_name *nmbname, uint16 nb_type )
89 {
90   struct name_record *namerec;
91
92   if (!we_are_a_wins_client()) {
93     insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
94     return;
95   }
96
97   if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
98   {
99     /* The name needs to be created on the unicast subnet. */
100     (void)add_name_to_subnet( unicast_subnet, nmbname->name,
101                               nmbname->name_type, nb_type,
102                               MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
103   }
104   else
105   {
106     /* The name already exists on the unicast subnet. Add our local
107        IP for the given broadcast subnet to the name. */
108     add_ip_to_name_record( namerec, subrec->myip);
109   }
110 }
111
112 /****************************************************************************
113   Add my workgroup and my given names to the subnet lists.
114   Also add the magic Samba names.
115   **************************************************************************/
116
117 BOOL register_my_workgroup_and_names(void)
118 {
119   struct subnet_record *subrec;
120   int i;
121
122   for(subrec = FIRST_SUBNET; 
123       subrec; 
124       subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
125   {
126           register_my_workgroup_one_subnet(subrec);
127   }
128
129   /* We still need to add the magic Samba
130      names and the netbios names to the unicast subnet directly. This is
131      to allow unicast node status requests and queries to still work
132      in a broadcast only environment. */
133
134   add_samba_names_to_subnet(unicast_subnet);
135
136   for (i=0; my_netbios_names[i]; i++)
137   {
138     for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
139     {
140       /*
141        * Ensure all the IP addresses are added if we are multihomed.
142        */
143       struct nmb_name nmbname;
144
145       make_nmb_name(&nmbname, my_netbios_names[i],0x20);
146       insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
147
148       make_nmb_name(&nmbname, my_netbios_names[i],0x3);
149       insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
150
151       make_nmb_name(&nmbname, my_netbios_names[i],0x0);
152       insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
153     }
154   }
155
156   /*
157    * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
158    * also for the same reasons.
159    */
160
161   for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
162   {
163     /*
164      * Ensure all the IP addresses are added if we are multihomed.
165      */
166     struct nmb_name nmbname;
167
168     make_nmb_name(&nmbname, global_myworkgroup, 0x0);
169     insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
170
171     make_nmb_name(&nmbname, global_myworkgroup, 0x1e);
172     insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
173   }
174
175   /*
176    * We need to add the Samba names to the remote broadcast subnet,
177    * as NT 4.x does directed broadcast requests to the *<0x0> name.
178    */
179   add_samba_names_to_subnet(remote_broadcast_subnet);
180
181   return True;
182 }
183
184 /****************************************************************************
185   Remove all the names we registered.
186 **************************************************************************/
187 void release_wins_names(void)
188 {
189         struct subnet_record *subrec = unicast_subnet;
190         struct name_record *namerec, *nextnamerec;
191
192         for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
193              namerec;
194              namerec = nextnamerec) {
195                 nextnamerec = (struct name_record *)ubi_trNext( namerec );
196                 if( (namerec->data.source == SELF_NAME)
197                     && !NAME_IS_DEREGISTERING(namerec) )
198                         release_name( subrec, namerec, standard_success_release,
199                                       NULL, NULL);
200         }
201 }
202
203 /*******************************************************************
204   Refresh our registered names with WINS
205   ******************************************************************/
206 void refresh_my_names(time_t t)
207 {
208         struct name_record *namerec;
209
210         if (wins_srv_count() < 1) return;
211
212         for (namerec = (struct name_record *)ubi_trFirst(unicast_subnet->namelist);
213              namerec;
214              namerec = (struct name_record *)ubi_trNext(namerec)) {
215                 /* Each SELF name has an individual time to be refreshed. */
216                 if ((namerec->data.source == SELF_NAME) &&
217                     (namerec->data.refresh_time < t) &&
218                     (namerec->data.death_time != PERMANENT_TTL)) {
219                         /* We cheat here and pretend the refresh is going to be
220                            successful & update the refresh times. This stops
221                            multiple refresh calls being done. We actually
222                            deal with refresh failure in the fail_fn.
223                         */
224                         if (!is_refresh_already_queued(unicast_subnet, namerec)) {
225                                 wins_refresh_name(namerec);
226                         }
227                         namerec->data.death_time = t + lp_max_ttl();
228                         namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
229                 }
230         }
231 }