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