This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[sfrench/samba-autobuild/.git] / source / 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
188 void release_my_names(void)
189 {
190 #if 0 /*JRR: do WINS server only, otherwise clients ignore us when we come back up*/
191   struct subnet_record *subrec;
192
193   for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
194 #else
195   struct subnet_record *subrec = unicast_subnet;
196 #endif
197   {
198     struct name_record *namerec, *nextnamerec;
199
200     for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
201          namerec;
202          namerec = nextnamerec)
203     {
204       nextnamerec = (struct name_record *)ubi_trNext( namerec );
205       if( (namerec->data.source == SELF_NAME)
206        && !NAME_IS_DEREGISTERING(namerec) )
207         release_name( subrec, namerec, standard_success_release,
208                       NULL, NULL);
209     }
210   }
211 }
212
213 /*******************************************************************
214   Refresh our registered names.
215   ******************************************************************/
216
217 void refresh_my_names(time_t t)
218 {
219   struct subnet_record *subrec;
220
221   for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
222   {
223     struct name_record *namerec;
224           
225     /* B nodes don't send out name refresh requests, see RFC 1001, 15.5.1 */
226     if (subrec != unicast_subnet)
227       continue;
228           
229     for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
230          namerec;
231          namerec = (struct name_record *)ubi_trNext( namerec ) )
232     {
233       /* Each SELF name has an individual time to be refreshed. */
234       if( (namerec->data.source == SELF_NAME)
235        && (namerec->data.refresh_time < t)
236        && ( namerec->data.death_time != PERMANENT_TTL) )
237       {
238         /* We cheat here and pretend the refresh is going to be
239            successful & update the refresh times. This stops
240            multiple refresh calls being done. We actually
241            deal with refresh failure in the fail_fn.
242          */
243         if( !is_refresh_already_queued( subrec, namerec) )
244           refresh_name( subrec, namerec, NULL, NULL, NULL );
245         namerec->data.death_time = t + lp_max_ttl();
246         namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
247       }
248     }
249   }
250 }