preparing for release of 1.9.16p5
[samba.git] / source3 / nameconf.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) David Chappell 1996
6    
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 2 of the License, or
10    (at your option) any later version.
11    
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.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    30 July 96: David.Chappell@mail.trincoll.edu
24    Expanded multiple workgroup domain master browser support.
25
26 */
27
28 /*
29 ** nameconf.c
30 ** These functions dispense information from smbbrowse.conf.
31 **
32 **
33 */
34
35 #include "includes.h"
36 extern int DEBUGLEVEL;
37
38 #if 0
39 struct smbbrowse_parms
40     {
41     char *name;
42     BOOL (*reader)(char *string, void *toset);
43     } smbbrowse_table[] =
44 {
45     {"preferred master", NULL},
46     {"local master", NULL},
47     {"domain master", NULL}
48 } ;
49 #endif
50
51 /*
52 ** Structure for the list of workgroups from smbbrowse.conf.  This 
53 ** structure should only be manipulated thru the functions in this file.
54 ** That is why it is not defined in a header file.
55 */
56 struct smbbrowse
57 {
58     char work_name[16];               /* workgroup name */
59     char browsing_alias[16];          /* alias for our role in this workgroup */
60     struct server_identity *my_names; /* a list of server name we should appear here as */
61     BOOL should_workgroup_member;     /* should we try to become a member of this workgroup? */
62     BOOL should_local_master;         /* should we try to become a master browser? */
63     BOOL should_domain_master;        /* should we try to become the domain master browser? */
64 } ;
65
66 /* The whole list */
67 static struct smbbrowse *smbbrowse_workgroups = (struct smbbrowse*)NULL;
68
69 /* The size of the list */
70 static int array_size = 0;
71
72 /* The next available space in the list */
73 static int nexttoken = 0;
74
75 int get_num_workgroups(void)
76 {
77     return nexttoken;
78 }
79
80 /*
81 ** This makes a new workgroup structure, possibly taking an 
82 ** old one as a model.
83 */
84 static struct smbbrowse *new_workgroup(struct smbbrowse *model,
85                                        char *workgroup_name,
86                                        char *default_name)
87 {
88     struct smbbrowse *new;
89
90     if( ! (array_size > nexttoken) )
91     {
92     array_size += 10;
93     smbbrowse_workgroups = (struct smbbrowse*)realloc(smbbrowse_workgroups,
94                 array_size * sizeof(struct smbbrowse));
95     }
96
97     new = &smbbrowse_workgroups[nexttoken];
98
99     if(model != (struct smbbrowse *)NULL )
100     memcpy(new, model, sizeof(struct smbbrowse));
101     else
102         memset(new, 0, sizeof(struct smbbrowse));
103
104     StrnCpy(new->work_name, workgroup_name, 15);
105     strupper(new->work_name);
106         
107         if (strequal(lp_workgroup(), workgroup_name))
108       StrnCpy(new->browsing_alias, default_name, 15);
109     else
110       sprintf(new->browsing_alias, "%.14s%x", default_name, nexttoken);
111     strupper(new->browsing_alias);
112
113         DEBUG(4,("wg: %s alias: %s token: %x\n",
114                 new->work_name, new->browsing_alias, nexttoken));
115
116     nexttoken++;
117     return new;
118 }
119
120 /*
121 ** If fed a workgroup name, this function returns its token number.
122 ** If the workgroup does not exist a new token is assigned unless
123 ** new workgroups are not allowed.
124 */
125 int conf_workgroup_name_to_token(char *workgroup_name,char *default_name)
126 {
127     int idx;
128     
129     /* Look for an existing instance. */
130     for(idx=0; idx < nexttoken; idx++)
131     {
132         if(strequal(workgroup_name, smbbrowse_workgroups[idx].work_name))
133         {
134             return idx;
135         }
136     }
137     
138     /* See if creating new ones in admissable. */
139     for(idx=0; idx < nexttoken; idx++)
140     {
141         if(strequal("*", smbbrowse_workgroups[idx].work_name))
142         {
143             struct smbbrowse *w = new_workgroup(&smbbrowse_workgroups[idx],
144                                                 workgroup_name, default_name);
145             w->should_workgroup_member = False;
146
147             return (nexttoken - 1);
148         }
149     }
150
151     /* Not allowed */
152     DEBUG(4, ("refusing to allow new workgroup\n"));
153     return -1;
154 }
155
156 /*
157 ** This is a workgroups array bounds checker.
158 */
159 static int range_check(int token)
160 {
161     if(token < 0 || token >= nexttoken)
162     {
163     DEBUG(0, ("range_check(): failed\n"));
164         return True;
165         }
166         
167     return False;
168 }
169
170 /*
171 ** Given a token, return the name.
172 */
173 char *conf_workgroup_name(int token)
174 {
175     if(range_check(token))
176         return (char*)NULL;
177     
178     return smbbrowse_workgroups[token].work_name;
179 }
180
181 /*
182 ** Given a token, return True if we should try
183 ** to become a master browser.
184 */
185 int conf_should_workgroup_member(int token)
186     {
187
188     if(range_check(token))
189         return False;
190     
191     return smbbrowse_workgroups[token].should_workgroup_member;
192     }
193
194 /*
195 ** Given a token, return True if we should try
196 ** to become a master browser.
197 */
198 int conf_should_local_master(int token)
199     {
200     if(range_check(token))
201         return False;
202     
203     return smbbrowse_workgroups[token].should_local_master;
204     }
205
206 /*
207 ** Given a token, return True if we should try
208 ** to become a domain master browser.
209 */
210 int conf_should_domain_master(int token)
211     {
212     if(range_check(token))
213         return False;
214     
215     return smbbrowse_workgroups[token].should_domain_master;
216     }
217
218 /*
219 ** Given a token, return the name.
220 */
221 char *conf_browsing_alias(int token)
222     {
223     if(range_check(token))
224         return (char*)NULL;
225
226     return smbbrowse_workgroups[token].browsing_alias;
227     }
228
229 /*
230 ** Return the server comment which should be used with the
231 ** browsing alias.
232 */
233 char *conf_browsing_alias_comment(int token)
234 {
235     if(range_check(token))
236         return (char*) NULL;
237         
238     return "Browser";
239     }       
240
241 /*
242 ** Given an alias name for this server, return the name of the workgroup 
243 ** for which it is the browsing alias.
244 */
245 char *conf_alias_to_workgroup(char *alias)
246 {
247     int x;
248     
249         DEBUG(4,("alias_to_workgroup: %s", alias));
250
251     for(x=0; x < nexttoken; x++)
252     {
253                 DEBUG(4,("%s ", smbbrowse_workgroups[x].browsing_alias));
254
255         if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
256         {
257                         DEBUG(4,("OK\n"));
258             return smbbrowse_workgroups[x].work_name;
259         }
260     }
261         DEBUG(4,("not found\n"));
262     return (char*)NULL;
263 }
264
265 /*
266 ** Given an alias name for this server, return the name of the workgroup 
267 ** for which it is the browsing alias.
268 */
269 int conf_alias_to_token(char *alias)
270 {
271     int x;
272     
273     for(x=0; x < nexttoken; x++)
274     {
275         if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
276         {
277             return x;
278         }
279     }
280     return -1;
281 }
282
283 /*
284 ** Since there is no smbbrowse.conf file, we will fill in 
285 ** the structures with information from the smb.conf file.
286 */
287 static void default_smbbrowse_conf(char *default_name)
288 {
289     struct smbbrowse *w;
290     
291     /* The workgroup specified in smb.conf */
292     w = new_workgroup((struct smbbrowse *)NULL, lp_workgroup(), default_name);
293     w->should_local_master = lp_preferred_master();
294     w->should_domain_master = lp_domain_master();
295     w->should_workgroup_member = True;
296
297     /* default action: allow any new workgroup to be added */
298     w = new_workgroup((struct smbbrowse *)NULL, "*", default_name);
299     w->should_local_master = False;
300     w->should_domain_master = False;
301     w->should_workgroup_member = False;
302 }
303
304 /*
305 ** This function is called from main().
306 */
307 void read_smbbrowse_conf(char *default_name)
308 {
309   FILE *f = fopen(BROWSEFILE,"r");
310   if (f)
311   {
312     while (!feof(f))
313     {
314       pstring line;
315       char *ptr;
316       int count = 0;
317   
318       pstring work_name;
319       struct smbbrowse *w;
320
321       if (!fgets_slash(line,sizeof(pstring),f)) continue;
322   
323       if (*line == '#') continue;
324   
325       strcpy(work_name,"");
326         
327       ptr = line;
328         
329       if (next_token(&ptr, work_name, NULL)) ++count;
330         
331       if (count <= 0) continue;
332         
333       w = new_workgroup((struct smbbrowse *)NULL, work_name, default_name);
334       w->should_local_master = lp_local_master();
335       w->should_domain_master = lp_domain_master();
336       w->should_workgroup_member = True;
337     }
338
339     fclose(f);
340   }
341   else
342   {
343     DEBUG(2,("Can't open browse configuration file %s\n",BROWSEFILE));
344   }
345   default_smbbrowse_conf(default_name);    
346 }
347
348