First cut toward adding WINS server failover.
[kai/samba.git] / source / param / loadparm.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Parameter loading functions
5    Copyright (C) Karl Auer 1993-1998
6
7    Largely re-written by Andrew Tridgell, September 1994
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25  *  Load parameters.
26  *
27  *  This module provides suitable callback functions for the params
28  *  module. It builds the internal table of service details which is
29  *  then used by the rest of the server.
30  *
31  * To add a parameter:
32  *
33  * 1) add it to the global or service structure definition
34  * 2) add it to the parm_table
35  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
36  * 4) If it's a global then initialise it in init_globals. If a local
37  *    (ie. service) parameter then initialise it in the sDefault structure
38  *  
39  *
40  * Notes:
41  *   The configuration file is processed sequentially for speed. It is NOT
42  *   accessed randomly as happens in 'real' Windows. For this reason, there
43  *   is a fair bit of sequence-dependent code here - ie., code which assumes
44  *   that certain things happen before others. In particular, the code which
45  *   happens at the boundary between sections is delicately poised, so be
46  *   careful!
47  *
48  */
49
50 #include "includes.h"
51
52 /* Set default coding system for KANJI if none specified in Makefile. */
53 /* 
54  * We treat KANJI specially due to historical precedent (it was the
55  * first non-english codepage added to Samba). With the new dynamic
56  * codepage support this is not needed anymore.
57  *
58  * The define 'KANJI' is being overloaded to mean 'use kanji codepage
59  * by default' and also 'this is the filename-to-disk conversion 
60  * method to use'. This really should be removed and all control
61  * over this left in the smb.conf parameters 'client codepage'
62  * and 'coding system'.
63  */
64 #ifndef KANJI
65 #define KANJI "sbcs"
66 #endif /* KANJI */
67
68 BOOL in_client = False;         /* Not in the client by default */
69 BOOL bLoaded = False;
70
71 extern int DEBUGLEVEL;
72 extern pstring user_socket_options;
73 extern pstring global_myname;
74 pstring global_scope = "";
75
76 #ifndef GLOBAL_NAME
77 #define GLOBAL_NAME "global"
78 #endif
79
80 #ifndef PRINTERS_NAME
81 #define PRINTERS_NAME "printers"
82 #endif
83
84 #ifndef HOMES_NAME
85 #define HOMES_NAME "homes"
86 #endif
87
88 /* some helpful bits */
89 #define pSERVICE(i) ServicePtrs[i]
90 #define iSERVICE(i) (*pSERVICE(i))
91 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
92 #define VALID(i) iSERVICE(i).valid
93
94 int keepalive = DEFAULT_KEEPALIVE;
95 extern BOOL use_getwd_cache;
96
97 extern int extra_time_offset;
98
99 static BOOL defaults_saved = False;
100
101 /* 
102  * This structure describes global (ie., server-wide) parameters.
103  */
104 typedef struct
105 {
106         char *szPrintcapname;
107         char *szLockDir;
108         char *szRootdir;
109         char *szDefaultService;
110         char *szDfree;
111         char *szMsgCommand;
112         char *szHostsEquiv;
113         char *szServerString;
114         char *szAutoServices;
115         char *szPasswdProgram;
116         char *szPasswdChat;
117         char *szLogFile;
118         char *szConfigFile;
119         char *szSMBPasswdFile;
120         char *szPasswordServer;
121         char *szSocketOptions;
122         char *szValidChars;
123         char *szWorkGroup;
124         char *szDomainAdminGroup;
125         char *szDomainGuestGroup;
126         char *szDomainAdminUsers;
127         char *szDomainGuestUsers;
128         char *szDomainHostsallow;
129         char *szDomainHostsdeny;
130         char *szUsernameMap;
131 #ifdef USING_GROUPNAME_MAP
132         char *szGroupnameMap;
133 #endif                          /* USING_GROUPNAME_MAP */
134         char *szCharacterSet;
135         char *szLogonScript;
136         char *szLogonPath;
137         char *szLogonDrive;
138         char *szLogonHome;
139         char *szSmbrun;
140         char *szWINSserver;
141         char *szCodingSystem;
142         char *szInterfaces;
143         char *szRemoteAnnounce;
144         char *szRemoteBrowseSync;
145         char *szSocketAddress;
146         char *szNISHomeMapName;
147         char *szAnnounceVersion;        /* This is initialised in init_globals */
148         char *szNetbiosAliases;
149         char *szDomainOtherSIDs;
150         char *szDomainGroups;
151         char *szNameResolveOrder;
152         char *szLdapServer;
153         char *szLdapSuffix;
154         char *szLdapFilter;
155         char *szLdapRoot;
156         char *szLdapRootPassword;
157         char *szPanicAction;
158         char *szAddUserScript;
159         char *szDelUserScript;
160         char *szWINSHook;
161 #ifdef WITH_UTMP
162         char *szUtmpDir;
163 #endif                          /* WITH_UTMP */
164         char *szSourceEnv;
165         char *szWinbindUID;
166         char *szWinbindGID;
167         char *szTemplateHomedir;
168         char *szTemplateShell;
169         char *szWinbindSeparator;
170         int max_log_size;
171         int mangled_stack;
172         int max_xmit;
173         int max_mux;
174         int max_open_files;
175         int max_packet;
176         int pwordlevel;
177         int unamelevel;
178         int deadtime;
179         int maxprotocol;
180         int security;
181         int maxdisksize;
182         int lpqcachetime;
183         int syslog;
184         int os_level;
185         int max_ttl;
186         int max_wins_ttl;
187         int min_wins_ttl;
188         int ReadSize;
189         int lm_announce;
190         int lm_interval;
191         int client_code_page;
192         int announce_as;        /* This is initialised in init_globals */
193         int machine_password_timeout;
194         int change_notify_timeout;
195         int stat_cache_size;
196         int map_to_guest;
197         int min_passwd_length;
198         int oplock_break_wait_time;
199         int winbind_cache_time;
200 #ifdef WITH_LDAP
201         int ldap_port;
202 #endif                          /* WITH_LDAP */
203 #ifdef WITH_SSL
204         int sslVersion;
205         char *sslHostsRequire;
206         char *sslHostsResign;
207         char *sslCaCertDir;
208         char *sslCaCertFile;
209         char *sslCert;
210         char *sslPrivKey;
211         char *sslClientCert;
212         char *sslClientPrivKey;
213         char *sslCiphers;
214         BOOL sslEnabled;
215         BOOL sslReqClientCert;
216         BOOL sslReqServerCert;
217         BOOL sslCompatibility;
218 #endif                          /* WITH_SSL */
219         BOOL bDNSproxy;
220         BOOL bWINSsupport;
221         BOOL bWINSproxy;
222         BOOL bLocalMaster;
223         BOOL bPreferredMaster;
224         BOOL bDomainMaster;
225         BOOL bDomainLogons;
226         BOOL bEncryptPasswords;
227         BOOL bUpdateEncrypt;
228         BOOL bStripDot;
229         BOOL bNullPasswords;
230         BOOL bLoadPrinters;
231         BOOL bUseRhosts;
232         BOOL bReadRaw;
233         BOOL bWriteRaw;
234         BOOL bReadPrediction;
235         BOOL bReadbmpx;
236         BOOL bSyslogOnly;
237         BOOL bBrowseList;
238         BOOL bUnixRealname;
239         BOOL bNISHomeMap;
240         BOOL bTimeServer;
241         BOOL bBindInterfacesOnly;
242         BOOL bUnixPasswdSync;
243         BOOL bPasswdChatDebug;
244         BOOL bTimestampLogs;
245         BOOL bNTSmbSupport;
246         BOOL bNTPipeSupport;
247         BOOL bNTAclSupport;
248         BOOL bStatCache;
249         BOOL bKernelOplocks;
250         BOOL bAllowTrustedDomains;
251         BOOL bRestrictAnonymous;
252         BOOL bDebugHiresTimestamp;
253         BOOL bDebugPid;
254         BOOL bDebugUid;
255         BOOL bHostMSDfs;
256 }
257 global;
258
259 static global Globals;
260
261
262
263 /* 
264  * This structure describes a single service. 
265  */
266 typedef struct
267 {
268         BOOL valid;
269         BOOL autoloaded;
270         char *szService;
271         char *szPath;
272         char *szUsername;
273         char *szGuestaccount;
274         char *szInvalidUsers;
275         char *szValidUsers;
276         char *szAdminUsers;
277         char *szCopy;
278         char *szInclude;
279         char *szPreExec;
280         char *szPostExec;
281         char *szRootPreExec;
282         char *szRootPostExec;
283         char *szPrintcommand;
284         char *szLpqcommand;
285         char *szLprmcommand;
286         char *szLppausecommand;
287         char *szLpresumecommand;
288         char *szQueuepausecommand;
289         char *szQueueresumecommand;
290         char *szPrintername;
291         char *szPrinterDriver;
292         char *szPrinterDriverLocation;
293         char *szDriverFile;
294         char *szDontdescend;
295         char *szHostsallow;
296         char *szHostsdeny;
297         char *szMagicScript;
298         char *szMagicOutput;
299         char *szMangledMap;
300         char *szVetoFiles;
301         char *szHideFiles;
302         char *szVetoOplockFiles;
303         char *comment;
304         char *force_user;
305         char *force_group;
306         char *readlist;
307         char *writelist;
308         char *volume;
309         char *fstype;
310         char *szVfsObjectFile;
311         char *szVfsOptions;
312         int iMinPrintSpace;
313         int iWriteCacheSize;
314         int iCreate_mask;
315         int iCreate_force_mode;
316         int iSecurity_mask;
317         int iSecurity_force_mode;
318         int iDir_mask;
319         int iDir_force_mode;
320         int iDir_Security_mask;
321         int iDir_Security_force_mode;
322         int iMaxConnections;
323         int iDefaultCase;
324         int iPrinting;
325         int iOplockContentionLimit;
326         BOOL bAlternatePerm;
327         BOOL bPreexecClose;
328         BOOL bRootpreexecClose;
329         BOOL bCaseSensitive;
330         BOOL bCasePreserve;
331         BOOL bShortCasePreserve;
332         BOOL bCaseMangle;
333         BOOL status;
334         BOOL bHideDotFiles;
335         BOOL bBrowseable;
336         BOOL bAvailable;
337         BOOL bRead_only;
338         BOOL bNo_set_dir;
339         BOOL bGuest_only;
340         BOOL bGuest_ok;
341         BOOL bPrint_ok;
342         BOOL bPostscript;
343         BOOL bMap_system;
344         BOOL bMap_hidden;
345         BOOL bMap_archive;
346         BOOL bLocking;
347         BOOL bStrictLocking;
348         BOOL bPosixLocking;
349 #ifdef WITH_UTMP
350         BOOL bUtmp;
351 #endif
352         BOOL bShareModes;
353         BOOL bOpLocks;
354         BOOL bLevel2OpLocks;
355         BOOL bOnlyUser;
356         BOOL bMangledNames;
357         BOOL bWidelinks;
358         BOOL bSymlinks;
359         BOOL bSyncAlways;
360         BOOL bStrictSync;
361         char magic_char;
362         BOOL *copymap;
363         BOOL bDeleteReadonly;
364         BOOL bFakeOplocks;
365         BOOL bDeleteVetoFiles;
366         BOOL bDosFiletimes;
367         BOOL bDosFiletimeResolution;
368         BOOL bFakeDirCreateTimes;
369         BOOL bBlockingLocks;
370         BOOL bInheritPerms;
371         BOOL bMSDfsRoot;
372
373         char dummy[3];          /* for alignment */
374 }
375 service;
376
377
378 /* This is a default service used to prime a services structure */
379 static service sDefault = {
380         True,                   /* valid */
381         False,                  /* not autoloaded */
382         NULL,                   /* szService */
383         NULL,                   /* szPath */
384         NULL,                   /* szUsername */
385         NULL,                   /* szGuestAccount  - this is set in init_globals() */
386         NULL,                   /* szInvalidUsers */
387         NULL,                   /* szValidUsers */
388         NULL,                   /* szAdminUsers */
389         NULL,                   /* szCopy */
390         NULL,                   /* szInclude */
391         NULL,                   /* szPreExec */
392         NULL,                   /* szPostExec */
393         NULL,                   /* szRootPreExec */
394         NULL,                   /* szRootPostExec */
395         NULL,                   /* szPrintcommand */
396         NULL,                   /* szLpqcommand */
397         NULL,                   /* szLprmcommand */
398         NULL,                   /* szLppausecommand */
399         NULL,                   /* szLpresumecommand */
400         NULL,                   /* szQueuepausecommand */
401         NULL,                   /* szQueueresumecommand */
402         NULL,                   /* szPrintername */
403         NULL,                   /* szPrinterDriver - this is set in init_globals() */
404         NULL,                   /* szPrinterDriverLocation */
405         NULL,                   /* szDriverFile */
406         NULL,                   /* szDontdescend */
407         NULL,                   /* szHostsallow */
408         NULL,                   /* szHostsdeny */
409         NULL,                   /* szMagicScript */
410         NULL,                   /* szMagicOutput */
411         NULL,                   /* szMangledMap */
412         NULL,                   /* szVetoFiles */
413         NULL,                   /* szHideFiles */
414         NULL,                   /* szVetoOplockFiles */
415         NULL,                   /* comment */
416         NULL,                   /* force user */
417         NULL,                   /* force group */
418         NULL,                   /* readlist */
419         NULL,                   /* writelist */
420         NULL,                   /* volume */
421         NULL,                   /* fstype */
422         NULL,                   /* vfs object */
423         NULL,                   /* vfs options */
424         0,                      /* iMinPrintSpace */
425         0,                      /* iWriteCacheSize */
426         0744,                   /* iCreate_mask */
427         0000,                   /* iCreate_force_mode */
428         -1,                     /* iSecurity_mask */
429         -1,                     /* iSecurity_force_mode */
430         0755,                   /* iDir_mask */
431         0000,                   /* iDir_force_mode */
432         -1,                     /* iDir_Security_mask */
433         -1,                     /* iDir_Security_force_mode */
434         0,                      /* iMaxConnections */
435         CASE_LOWER,             /* iDefaultCase */
436         DEFAULT_PRINTING,       /* iPrinting */
437         2,                      /* iOplockContentionLimit */
438         False,                  /* bAlternatePerm */
439         False,                  /* bPreexecClose */
440         False,                  /* bRootpreexecClose */
441         False,                  /* case sensitive */
442         True,                   /* case preserve */
443         True,                   /* short case preserve */
444         False,                  /* case mangle */
445         True,                   /* status */
446         True,                   /* bHideDotFiles */
447         True,                   /* bBrowseable */
448         True,                   /* bAvailable */
449         True,                   /* bRead_only */
450         True,                   /* bNo_set_dir */
451         False,                  /* bGuest_only */
452         False,                  /* bGuest_ok */
453         False,                  /* bPrint_ok */
454         False,                  /* bPostscript */
455         False,                  /* bMap_system */
456         False,                  /* bMap_hidden */
457         True,                   /* bMap_archive */
458         True,                   /* bLocking */
459         False,                  /* bStrictLocking */
460         True,                   /* bPosixLocking */
461 #ifdef WITH_UTMP
462         False,                  /* bUtmp */
463 #endif
464         True,                   /* bShareModes */
465         True,                   /* bOpLocks */
466         True,                   /* bLevel2OpLocks */
467         False,                  /* bOnlyUser */
468         True,                   /* bMangledNames */
469         True,                   /* bWidelinks */
470         True,                   /* bSymlinks */
471         False,                  /* bSyncAlways */
472         False,                  /* bStrictSync */
473         '~',                    /* magic char */
474         NULL,                   /* copymap */
475         False,                  /* bDeleteReadonly */
476         False,                  /* bFakeOplocks */
477         False,                  /* bDeleteVetoFiles */
478         False,                  /* bDosFiletimes */
479         False,                  /* bDosFiletimeResolution */
480         False,                  /* bFakeDirCreateTimes */
481         True,                   /* bBlockingLocks */
482         False,                  /* bInheritPerms */
483         False,                  /* bMSDfsRoot */
484
485         ""                      /* dummy */
486 };
487
488
489
490 /* local variables */
491 static service **ServicePtrs = NULL;
492 static int iNumServices = 0;
493 static int iServiceIndex = 0;
494 static BOOL bInGlobalSection = True;
495 static BOOL bGlobalOnly = False;
496 static int server_role;
497 static int default_server_announce;
498
499 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
500
501 /* prototypes for the special type handlers */
502 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
503 static BOOL handle_include(char *pszParmValue, char **ptr);
504 static BOOL handle_copy(char *pszParmValue, char **ptr);
505 static BOOL handle_character_set(char *pszParmValue, char **ptr);
506 static BOOL handle_coding_system(char *pszParmValue, char **ptr);
507 static BOOL handle_client_code_page(char *pszParmValue, char **ptr);
508 static BOOL handle_vfs_object(char *pszParmValue, char **ptr);
509 static BOOL handle_source_env(char *pszParmValue, char **ptr);
510 static BOOL handle_netbios_name(char *pszParmValue, char **ptr);
511 static BOOL handle_winbind_id(char *pszParmValue, char **ptr);
512 static BOOL handle_wins_server_list(char *pszParmValue, char **ptr);
513
514 static void set_server_role(void);
515 static void set_default_server_announce_type(void);
516
517 static struct enum_list enum_protocol[] = {
518         {PROTOCOL_NT1, "NT1"},
519         {PROTOCOL_LANMAN2, "LANMAN2"},
520         {PROTOCOL_LANMAN1, "LANMAN1"},
521         {PROTOCOL_CORE, "CORE"},
522         {PROTOCOL_COREPLUS, "COREPLUS"},
523         {PROTOCOL_COREPLUS, "CORE+"},
524         {-1, NULL}
525 };
526
527 static struct enum_list enum_security[] = {
528         {SEC_SHARE, "SHARE"},
529         {SEC_USER, "USER"},
530         {SEC_SERVER, "SERVER"},
531         {SEC_DOMAIN, "DOMAIN"},
532         {-1, NULL}
533 };
534
535 static struct enum_list enum_printing[] = {
536         {PRINT_SYSV, "sysv"},
537         {PRINT_AIX, "aix"},
538         {PRINT_HPUX, "hpux"},
539         {PRINT_BSD, "bsd"},
540         {PRINT_QNX, "qnx"},
541         {PRINT_PLP, "plp"},
542         {PRINT_LPRNG, "lprng"},
543         {PRINT_SOFTQ, "softq"},
544         {PRINT_CUPS, "cups"},
545         {-1, NULL}
546 };
547
548 /* Types of machine we can announce as. */
549 #define ANNOUNCE_AS_NT_SERVER 1
550 #define ANNOUNCE_AS_WIN95 2
551 #define ANNOUNCE_AS_WFW 3
552 #define ANNOUNCE_AS_NT_WORKSTATION 4
553
554 static struct enum_list enum_announce_as[] = {
555         {ANNOUNCE_AS_NT_SERVER, "NT"},
556         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
557         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
558         {ANNOUNCE_AS_WIN95, "win95"},
559         {ANNOUNCE_AS_WFW, "WfW"},
560         {-1, NULL}
561 };
562
563 static struct enum_list enum_case[] = {
564         {CASE_LOWER, "lower"},
565         {CASE_UPPER, "upper"},
566         {-1, NULL}
567 };
568
569 static struct enum_list enum_bool_auto[] = {
570         {False, "False"},
571         {True, "True"},
572         {Auto, "Auto"},
573         {-1, NULL}
574 };
575
576 /* 
577    Do you want session setups at user level security with a invalid
578    password to be rejected or allowed in as guest? WinNT rejects them
579    but it can be a pain as it means "net view" needs to use a password
580
581    You have 3 choices in the setting of map_to_guest:
582
583    "Never" means session setups with an invalid password
584    are rejected. This is the default.
585
586    "Bad User" means session setups with an invalid password
587    are rejected, unless the username does not exist, in which case it
588    is treated as a guest login
589
590    "Bad Password" means session setups with an invalid password
591    are treated as a guest login
592
593    Note that map_to_guest only has an effect in user or server
594    level security.
595 */
596
597 static struct enum_list enum_map_to_guest[] = {
598         {NEVER_MAP_TO_GUEST, "Never"},
599         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
600         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
601         {-1, NULL}
602 };
603
604 #ifdef WITH_SSL
605 static struct enum_list enum_ssl_version[] = {
606         {SMB_SSL_V2, "ssl2"},
607         {SMB_SSL_V3, "ssl3"},
608         {SMB_SSL_V23, "ssl2or3"},
609         {SMB_SSL_TLS1, "tls1"},
610         {-1, NULL}
611 };
612 #endif
613
614 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
615 static struct parm_struct parm_table[] = {
616         {"Base Options", P_SEP, P_SEPARATOR},
617         
618         {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
619         {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page, NULL, 0},
620         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_DOS_STRING},
621         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_DOS_STRING},
622         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING},
623         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING},
624         {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC | FLAG_DOS_STRING},
625         {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING},
626         {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING},
627         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING},
628         {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
629         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, 0},
630
631         {"Security Options", P_SEP, P_SEPARATOR},
632         
633         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
634         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
635         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
636         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0},
637         {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL | FLAG_DEPRECATED},
638         {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
639         {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
640         {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
641         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0},
642         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
643         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
644         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
645         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
646         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
647         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
648         
649         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
650         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
651         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
652         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
653         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
654         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
655         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
656         {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0},
657         {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
658         
659         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
660         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
661         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
662         
663         {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_GLOBAL},
664         {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
665         {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
666         {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
667         {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
668         {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
669         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
670         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
671         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
672         
673         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE},
674         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
675         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
676         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
677         
678         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
679         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
680         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
681         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
682         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
683         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
684         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
685         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
686         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
687         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
688         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
689         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
690         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
691
692         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
693         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
694         
695         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
696         {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
697         {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
698         {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
699         {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
700
701 #ifdef WITH_SSL
702         {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
703         {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0},
704         
705         {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0},
706         {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0},
707         {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0},
708         {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0},
709         {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0},
710         {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0},
711         {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0},
712         {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0},
713         {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0},
714         {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0},
715         {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0},
716         {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
717         {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0},
718 #endif /* WITH_SSL */
719
720         {"Logging Options", P_SEP, P_SEPARATOR},
721         {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
722         {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
723         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
724         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
725         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
726         
727         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
728         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
729         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
730         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0},
731         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0},
732         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0},
733         
734         {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_PRINT},
735
736         {"Protocol Options", P_SEP, P_SEPARATOR},
737         
738         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
739         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
740         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
741         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
742         
743         {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
744         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
745         {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0},
746         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
747         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
748         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
749         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
750         
751         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
752         {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
753         {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
754         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0}, 
755         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
756         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
757         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
758
759         {"Tuning Options", P_SEP, P_SEPARATOR},
760         
761         {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
762         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
763         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
764         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
765         
766         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
767         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
768         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
769         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
770         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
771         {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
772         
773         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
774         {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
775         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
776         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
777         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
778
779         {"Printing Options", P_SEP, P_SEPARATOR},
780         
781         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
782         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT},
783         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
784         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
785         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
786         {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
787         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
788         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
789         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
790         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
791         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
792         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
793         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
794         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
795
796         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
797         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
798         {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT},
799         {"printer driver file", P_STRING, P_LOCAL, &sDefault.szDriverFile, NULL, NULL, FLAG_PRINT},
800         {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
801
802         {"Filename Handling", P_SEP, P_SEPARATOR},
803         {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
804         
805         {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
806         {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
807         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
808         {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
809         {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
810         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
811         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
812         {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
813         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
814         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
815         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
816         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
817         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
818         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
819         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
820         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
821         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
822         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
823         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
824         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
825
826         {"Domain Options", P_SEP, P_SEPARATOR},
827         
828         {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
829         {"domain admin group", P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
830         {"domain guest group", P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
831         {"domain admin users", P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
832         {"domain guest users", P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
833 #ifdef USING_GROUPNAME_MAP
834         
835         {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
836 #endif /* USING_GROUPNAME_MAP */
837         
838         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
839
840         {"Logon Options", P_SEP, P_SEPARATOR},
841         
842         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0},
843         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0},
844         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_DOS_STRING},
845         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_DOS_STRING},
846         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
847         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_DOS_STRING},
848         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
849
850         {"Browse Options", P_SEP, P_SEPARATOR},
851         
852         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
853         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0},
854         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
855         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC},
856         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
857         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
858         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC},
859         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
860         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
861         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
862
863         {"WINS Options", P_SEP, P_SEPARATOR},
864         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
865         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
866         
867         {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, handle_wins_server_list, NULL, FLAG_BASIC},
868         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
869         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0},
870
871         {"Locking Options", P_SEP, P_SEPARATOR},
872         
873         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
874         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
875         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
876         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
877 #ifdef WITH_UTMP
878         {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
879 #endif
880         
881         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
882         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
883         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
884         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
885         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
886         {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
887         {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
888
889 #ifdef WITH_LDAP
890         {"Ldap Options", P_SEP, P_SEPARATOR},
891         
892         {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
893         {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 
894         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
895         {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
896         {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
897         {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword, NULL, NULL, 0},
898 #endif /* WITH_LDAP */
899
900         {"Miscellaneous Options", P_SEP, P_SEPARATOR},
901         {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
902         
903         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
904         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
905         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
906         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, 
907         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
908 #ifdef WITH_UTMP
909         {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
910         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
911 #endif /* WITH_UTMP */
912         
913         {"default service", P_STRING, P_GLOBAL,
914          &Globals.szDefaultService, NULL, NULL, 0},
915         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
916         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
917         {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
918         {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
919         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
920         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0},
921         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
922         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
923         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
924         {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
925         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
926         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
927         
928         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
929         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
930         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
931         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
932         
933         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
934         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
935         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
936         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
937         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
938         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
939         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE},
940         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
941         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
942         {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, 0},
943         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
944         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
945         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
946         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
947         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
948         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
949         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
950         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
951
952         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
953         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
954
955         {"VFS options", P_SEP, P_SEPARATOR},
956         
957         {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, 0},
958         {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, 0},
959
960         
961         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
962         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_GLOBAL},
963
964         {"Winbind options", P_SEP, P_SEPARATOR},
965
966         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_id, NULL, 0},
967         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_id, NULL, 0},
968         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, 0},
969         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, 0},
970         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, 0},
971         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0},
972
973         {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
974 };
975
976
977
978 /***************************************************************************
979 Initialise the global parameter structure.
980 ***************************************************************************/
981 static void init_globals(void)
982 {
983         static BOOL done_init = False;
984         pstring s;
985
986         if (!done_init)
987         {
988                 int i;
989                 memset((void *)&Globals, '\0', sizeof(Globals));
990
991                 for (i = 0; parm_table[i].label; i++)
992                         if ((parm_table[i].type == P_STRING ||
993                              parm_table[i].type == P_USTRING) &&
994                             parm_table[i].ptr)
995                                 string_set(parm_table[i].ptr, "");
996
997                 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
998                 string_set(&sDefault.szPrinterDriver, "");
999                 string_set(&sDefault.fstype, FSTYPE_STRING);
1000
1001                 done_init = True;
1002         }
1003
1004
1005         DEBUG(3, ("Initialising global parameters\n"));
1006
1007         string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
1008         /*
1009          * Allow the default PASSWD_CHAT to be overridden in local.h.
1010          */
1011         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1012         string_set(&Globals.szWorkGroup, WORKGROUP);
1013         string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
1014         string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
1015         string_set(&Globals.szLockDir, LOCKDIR);
1016 #ifdef WITH_UTMP
1017         string_set(&Globals.szUtmpDir, "");
1018 #endif /* WITH_UTMP */
1019         string_set(&Globals.szSmbrun, SMBRUN);
1020         string_set(&Globals.szSocketAddress, "0.0.0.0");
1021         pstrcpy(s, "Samba ");
1022         pstrcat(s, VERSION);
1023         string_set(&Globals.szServerString, s);
1024         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1025                  DEFAULT_MINOR_VERSION);
1026         string_set(&Globals.szAnnounceVersion, s);
1027
1028         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1029
1030         string_set(&Globals.szLogonDrive, "");
1031         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1032         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1033         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1034
1035         string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
1036
1037         Globals.bLoadPrinters = True;
1038         Globals.bUseRhosts = False;
1039         Globals.max_packet = 65535;
1040         Globals.mangled_stack = 50;
1041         Globals.max_xmit = 65535;
1042         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1043         Globals.lpqcachetime = 10;
1044         Globals.pwordlevel = 0;
1045         Globals.unamelevel = 0;
1046         Globals.deadtime = 0;
1047         Globals.max_log_size = 5000;
1048         Globals.max_open_files = MAX_OPEN_FILES;
1049         Globals.maxprotocol = PROTOCOL_NT1;
1050         Globals.security = SEC_USER;
1051         Globals.bEncryptPasswords = False;
1052         Globals.bUpdateEncrypt = False;
1053         Globals.bReadRaw = True;
1054         Globals.bWriteRaw = True;
1055         Globals.bReadPrediction = False;
1056         Globals.bReadbmpx = False;
1057         Globals.bNullPasswords = False;
1058         Globals.bStripDot = False;
1059         Globals.syslog = 1;
1060         Globals.bSyslogOnly = False;
1061         Globals.bTimestampLogs = False;
1062         Globals.bDebugHiresTimestamp = False;
1063         Globals.bDebugPid = False;
1064         Globals.bDebugUid = False;
1065         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1066         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1067         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1068         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1069         Globals.change_notify_timeout = 60;     /* 1 minute default. */
1070         Globals.ReadSize = 16 * 1024;
1071         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1072         Globals.lm_interval = 60;
1073         Globals.stat_cache_size = 50;   /* Number of stat translations we'll keep */
1074         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1075         Globals.bUnixRealname = True;
1076 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1077         Globals.bNISHomeMap = False;
1078 #ifdef WITH_NISPLUS_HOME
1079         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1080 #else
1081         string_set(&Globals.szNISHomeMapName, "auto.home");
1082 #endif
1083 #endif
1084         Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
1085         Globals.bTimeServer = False;
1086         Globals.bBindInterfacesOnly = False;
1087         Globals.bUnixPasswdSync = False;
1088         Globals.bPasswdChatDebug = False;
1089         Globals.bNTSmbSupport = True;   /* Do NT SMB's by default. */
1090         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1091         Globals.bNTAclSupport = True;   /* Use NT ACLs by default. */
1092         Globals.bStatCache = True;      /* use stat cache by default */
1093         Globals.bRestrictAnonymous = False;
1094         Globals.map_to_guest = 0;       /* By Default, "Never" */
1095         Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
1096         Globals.oplock_break_wait_time = 10;    /* By Default, 10 msecs. */
1097
1098 #ifdef WITH_LDAP
1099         /* default values for ldap */
1100         string_set(&Globals.szLdapServer, "localhost");
1101         Globals.ldap_port = 389;
1102 #endif /* WITH_LDAP */
1103
1104 #ifdef WITH_SSL
1105         Globals.sslVersion = SMB_SSL_V23;
1106         string_set(&Globals.sslHostsRequire, "");
1107         string_set(&Globals.sslHostsResign, "");
1108         string_set(&Globals.sslCaCertDir, "");
1109         string_set(&Globals.sslCaCertFile, "");
1110         string_set(&Globals.sslCert, "");
1111         string_set(&Globals.sslPrivKey, "");
1112         string_set(&Globals.sslClientCert, "");
1113         string_set(&Globals.sslClientPrivKey, "");
1114         string_set(&Globals.sslCiphers, "");
1115         Globals.sslEnabled = False;
1116         Globals.sslReqClientCert = False;
1117         Globals.sslReqServerCert = False;
1118         Globals.sslCompatibility = False;
1119 #endif /* WITH_SSL */
1120
1121 /* these parameters are set to defaults that are more appropriate
1122    for the increasing samba install base:
1123
1124    as a member of the workgroup, that will possibly become a
1125    _local_ master browser (lm = True).  this is opposed to a forced
1126    local master browser startup (pm = True).
1127
1128    doesn't provide WINS server service by default (wsupp = False),
1129    and doesn't provide domain master browser services by default, either.
1130
1131 */
1132
1133         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1134         Globals.os_level = 20;
1135         Globals.bLocalMaster = True;
1136         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1137         Globals.bDomainLogons = False;
1138         Globals.bBrowseList = True;
1139         Globals.bWINSsupport = False;
1140         Globals.bWINSproxy = False;
1141
1142         Globals.bDNSproxy = True;
1143
1144         /* this just means to use them if they exist */
1145         Globals.bKernelOplocks = True;
1146
1147         Globals.bAllowTrustedDomains = True;
1148
1149         string_set(&Globals.szTemplateShell, "/bin/false");
1150         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1151         string_set(&Globals.szWinbindSeparator, "\\");
1152         Globals.winbind_cache_time = 15;
1153
1154         /*
1155          * This must be done last as it checks the value in 
1156          * client_code_page.
1157          */
1158
1159         interpret_coding_system(KANJI);
1160 }
1161
1162 /***************************************************************************
1163 Initialise the sDefault parameter structure.
1164 ***************************************************************************/
1165 static void init_locals(void)
1166 {
1167         string_set(&sDefault.szDriverFile, DRIVERFILE);
1168
1169         /* choose defaults depending on the type of printing */
1170         switch (sDefault.iPrinting)
1171         {
1172                 case PRINT_BSD:
1173                 case PRINT_AIX:
1174                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1175                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1176                         string_set(&sDefault.szPrintcommand,
1177                                    "lpr -r -P%p %s");
1178                         break;
1179
1180                 case PRINT_LPRNG:
1181                 case PRINT_PLP:
1182                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1183                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1184                         string_set(&sDefault.szPrintcommand,
1185                                    "lpr -r -P%p %s");
1186                         string_set(&sDefault.szQueuepausecommand,
1187                                    "lpc stop %p");
1188                         string_set(&sDefault.szQueueresumecommand,
1189                                    "lpc start %p");
1190                         string_set(&sDefault.szLppausecommand,
1191                                    "lpc hold %p %j");
1192                         string_set(&sDefault.szLpresumecommand,
1193                                    "lpc release %p %j");
1194                         break;
1195
1196                 case PRINT_CUPS:
1197                         string_set(&sDefault.szLpqcommand,
1198                                    "/usr/bin/lpstat -o%p");
1199                         string_set(&sDefault.szLprmcommand,
1200                                    "/usr/bin/cancel %p-%j");
1201                         string_set(&sDefault.szPrintcommand,
1202                                    "/usr/bin/lp -d%p -oraw %s; rm %s");
1203                         string_set(&sDefault.szQueuepausecommand,
1204                                    "/usr/bin/disable %p");
1205                         string_set(&sDefault.szQueueresumecommand,
1206                                    "/usr/bin/enable %p");
1207                         break;
1208
1209                 case PRINT_SYSV:
1210                 case PRINT_HPUX:
1211                         string_set(&sDefault.szLpqcommand, "lpstat -o%p");
1212                         string_set(&sDefault.szLprmcommand, "cancel %p-%j");
1213                         string_set(&sDefault.szPrintcommand,
1214                                    "lp -c -d%p %s; rm %s");
1215                         string_set(&sDefault.szQueuepausecommand,
1216                                    "disable %p");
1217                         string_set(&sDefault.szQueueresumecommand,
1218                                    "enable %p");
1219 #ifndef HPUX
1220                         string_set(&sDefault.szLppausecommand,
1221                                    "lp -i %p-%j -H hold");
1222                         string_set(&sDefault.szLpresumecommand,
1223                                    "lp -i %p-%j -H resume");
1224 #endif /* SYSV */
1225                         break;
1226
1227                 case PRINT_QNX:
1228                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1229                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1230                         string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
1231                         break;
1232
1233                 case PRINT_SOFTQ:
1234                         string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
1235                         string_set(&sDefault.szLprmcommand,
1236                                    "qstat -s -j%j -c");
1237                         string_set(&sDefault.szPrintcommand,
1238                                    "lp -d%p -s %s; rm %s");
1239                         string_set(&sDefault.szLppausecommand,
1240                                    "qstat -s -j%j -h");
1241                         string_set(&sDefault.szLpresumecommand,
1242                                    "qstat -s -j%j -r");
1243                         break;
1244
1245         }
1246 }
1247
1248 static TALLOC_CTX *lp_talloc;
1249
1250 /******************************************************************* a
1251 free up temporary memory - called from the main loop
1252 ********************************************************************/
1253 void lp_talloc_free(void)
1254 {
1255         if (!lp_talloc)
1256                 return;
1257         talloc_destroy(lp_talloc);
1258         lp_talloc = NULL;
1259 }
1260
1261 /*******************************************************************
1262 convenience routine to grab string parameters into temporary memory
1263 and run standard_sub_basic on them. The buffers can be written to by
1264 callers without affecting the source string.
1265 ********************************************************************/
1266 static char *lp_string(const char *s)
1267 {
1268         size_t len = s ? strlen(s) : 0;
1269         char *ret;
1270
1271         if (!lp_talloc)
1272                 lp_talloc = talloc_init();
1273
1274         ret = (char *)talloc(lp_talloc, len + 100);     /* leave room for substitution */
1275
1276         if (!ret)
1277                 return NULL;
1278
1279         if (!s)
1280                 *ret = 0;
1281         else
1282                 StrnCpy(ret, s, len);
1283
1284         trim_string(ret, "\"", "\"");
1285
1286         standard_sub_basic(ret);
1287         return (ret);
1288 }
1289
1290
1291 /*
1292    In this section all the functions that are used to access the 
1293    parameters from the rest of the program are defined 
1294 */
1295
1296 #define FN_GLOBAL_STRING(fn_name,ptr) \
1297  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1298 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1299  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1300 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1301  char fn_name(void) {return(*(char *)(ptr));}
1302 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1303  int fn_name(void) {return(*(int *)(ptr));}
1304
1305 #define FN_LOCAL_STRING(fn_name,val) \
1306  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1307 #define FN_LOCAL_BOOL(fn_name,val) \
1308  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1309 #define FN_LOCAL_CHAR(fn_name,val) \
1310  char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1311 #define FN_LOCAL_INTEGER(fn_name,val) \
1312  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1313
1314 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1315 FN_GLOBAL_STRING(lp_smbrun, &Globals.szSmbrun)
1316 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1317 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1318 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1319 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1320 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1321 #ifdef WITH_UTMP
1322 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1323 #endif /* WITH_UTMP */
1324 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1325 FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
1326 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1327 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1328 FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1329 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1330 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1331 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1332 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1333 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1334 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1335 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup)
1336 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1337 #ifdef USING_GROUPNAME_MAP
1338 FN_GLOBAL_STRING(lp_groupname_map, &Globals.szGroupnameMap)
1339 #endif /* USING_GROUPNAME_MAP */
1340 FN_GLOBAL_STRING(lp_logon_script, &Globals.szLogonScript)
1341 FN_GLOBAL_STRING(lp_logon_path, &Globals.szLogonPath)
1342 FN_GLOBAL_STRING(lp_logon_drive, &Globals.szLogonDrive)
1343 FN_GLOBAL_STRING(lp_logon_home, &Globals.szLogonHome)
1344 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1345 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1346 FN_GLOBAL_STRING(lp_wins_server, &Globals.szWINSserver)
1347 FN_GLOBAL_STRING(lp_interfaces, &Globals.szInterfaces)
1348 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1349 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1350 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1351 FN_GLOBAL_STRING(lp_netbios_aliases, &Globals.szNetbiosAliases)
1352 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1353 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1354 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1355 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1356 FN_GLOBAL_STRING(lp_domain_groups, &Globals.szDomainGroups)
1357 FN_GLOBAL_STRING(lp_domain_admin_group, &Globals.szDomainAdminGroup)
1358 FN_GLOBAL_STRING(lp_domain_guest_group, &Globals.szDomainGuestGroup)
1359 FN_GLOBAL_STRING(lp_domain_admin_users, &Globals.szDomainAdminUsers)
1360 FN_GLOBAL_STRING(lp_domain_guest_users, &Globals.szDomainGuestUsers)
1361 FN_GLOBAL_STRING(lp_winbind_uid, &Globals.szWinbindUID)
1362 FN_GLOBAL_STRING(lp_winbind_gid, &Globals.szWinbindGID)
1363 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1364 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1365 FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1366 #ifdef WITH_LDAP
1367 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer);
1368 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix);
1369 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter);
1370 FN_GLOBAL_STRING(lp_ldap_root, &Globals.szLdapRoot);
1371 FN_GLOBAL_STRING(lp_ldap_rootpasswd, &Globals.szLdapRootPassword);
1372 #endif /* WITH_LDAP */
1373
1374 #ifdef WITH_SSL
1375 FN_GLOBAL_INTEGER(lp_ssl_version, &Globals.sslVersion);
1376 FN_GLOBAL_STRING(lp_ssl_hosts, &Globals.sslHostsRequire);
1377 FN_GLOBAL_STRING(lp_ssl_hosts_resign, &Globals.sslHostsResign);
1378 FN_GLOBAL_STRING(lp_ssl_cacertdir, &Globals.sslCaCertDir);
1379 FN_GLOBAL_STRING(lp_ssl_cacertfile, &Globals.sslCaCertFile);
1380 FN_GLOBAL_STRING(lp_ssl_cert, &Globals.sslCert);
1381 FN_GLOBAL_STRING(lp_ssl_privkey, &Globals.sslPrivKey);
1382 FN_GLOBAL_STRING(lp_ssl_client_cert, &Globals.sslClientCert);
1383 FN_GLOBAL_STRING(lp_ssl_client_privkey, &Globals.sslClientPrivKey);
1384 FN_GLOBAL_STRING(lp_ssl_ciphers, &Globals.sslCiphers);
1385 FN_GLOBAL_BOOL(lp_ssl_enabled, &Globals.sslEnabled);
1386 FN_GLOBAL_BOOL(lp_ssl_reqClientCert, &Globals.sslReqClientCert);
1387 FN_GLOBAL_BOOL(lp_ssl_reqServerCert, &Globals.sslReqServerCert);
1388 FN_GLOBAL_BOOL(lp_ssl_compatibility, &Globals.sslCompatibility);
1389 #endif /* WITH_SSL */
1390
1391 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1392 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1393 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1394 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1395 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1396 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1397 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1398 FN_GLOBAL_BOOL(lp_use_rhosts, &Globals.bUseRhosts)
1399 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
1400 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1401 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1402 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1403 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1404 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
1405 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1406 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1407 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1408 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1409 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1410 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1411 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1412 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1413 FN_GLOBAL_BOOL(lp_unix_realname, &Globals.bUnixRealname)
1414 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1415 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1416 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1417 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1418 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1419 FN_GLOBAL_BOOL(lp_nt_smb_support, &Globals.bNTSmbSupport)
1420 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1421 FN_GLOBAL_BOOL(lp_nt_acl_support, &Globals.bNTAclSupport)
1422 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1423 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1424 FN_GLOBAL_BOOL(lp_restrict_anonymous, &Globals.bRestrictAnonymous)
1425 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1426 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1427 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1428 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1429 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1430 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.max_wins_ttl)
1431 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1432 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1433 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1434 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1435 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1436 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1437 FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
1438 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1439 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1440 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1441 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1442 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1443 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1444 FN_GLOBAL_INTEGER(lp_client_code_page, &Globals.client_code_page)
1445 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1446 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1447 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1448 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1449 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1450 FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
1451 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1452 FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1453 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1454 #ifdef WITH_LDAP
1455 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1456 #endif                          /* WITH_LDAP */
1457 FN_LOCAL_STRING(lp_preexec, szPreExec)
1458 FN_LOCAL_STRING(lp_postexec, szPostExec)
1459 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1460 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1461 FN_LOCAL_STRING(lp_servicename, szService)
1462 FN_LOCAL_STRING(lp_pathname, szPath)
1463 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1464 FN_LOCAL_STRING(lp_username, szUsername)
1465 FN_LOCAL_STRING(lp_guestaccount, szGuestaccount)
1466 FN_LOCAL_STRING(lp_invalid_users, szInvalidUsers)
1467 FN_LOCAL_STRING(lp_valid_users, szValidUsers)
1468 FN_LOCAL_STRING(lp_admin_users, szAdminUsers)
1469 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1470 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1471 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1472 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1473 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1474 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1475 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1476 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1477 FN_LOCAL_STRING(lp_driverfile, szDriverFile)
1478 FN_LOCAL_STRING(lp_printerdriver, szPrinterDriver)
1479 FN_LOCAL_STRING(lp_hostsallow, szHostsallow)
1480 FN_LOCAL_STRING(lp_hostsdeny, szHostsdeny)
1481 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1482 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1483 FN_LOCAL_STRING(lp_comment, comment)
1484 FN_LOCAL_STRING(lp_force_user, force_user)
1485 FN_LOCAL_STRING(lp_force_group, force_group)
1486 FN_LOCAL_STRING(lp_readlist, readlist)
1487 FN_LOCAL_STRING(lp_writelist, writelist)
1488 FN_LOCAL_STRING(lp_fstype, fstype)
1489 FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
1490 static FN_LOCAL_STRING(lp_volume, volume)
1491 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1492 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1493 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1494 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1495 FN_LOCAL_STRING(lp_driverlocation, szPrinterDriverLocation)
1496 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1497 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1498 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1499 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1500 FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
1501 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1502 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1503 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
1504 FN_LOCAL_BOOL(lp_status, status)
1505 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1506 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1507 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1508 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1509 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1510 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1511 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1512 FN_LOCAL_BOOL(lp_postscript, bPostscript)
1513 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1514 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1515 FN_LOCAL_BOOL(lp_locking, bLocking)
1516 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1517 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1518 #ifdef WITH_UTMP
1519 FN_LOCAL_BOOL(lp_utmp, bUtmp)
1520 #endif
1521 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1522 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1523 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1524 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1525 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1526 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1527 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1528 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1529 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1530 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1531 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1532 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1533 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1534 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1535 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1536 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1537 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1538 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1539 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1540 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1541 FN_LOCAL_INTEGER(_lp_security_mask, iSecurity_mask)
1542 FN_LOCAL_INTEGER(_lp_force_security_mode, iSecurity_force_mode)
1543 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1544 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1545 FN_LOCAL_INTEGER(_lp_dir_security_mask, iDir_Security_mask)
1546 FN_LOCAL_INTEGER(_lp_force_dir_security_mode, iDir_Security_force_mode)
1547 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1548 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1549 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1550 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1551 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1552 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1553 FN_LOCAL_CHAR(lp_magicchar, magic_char)
1554 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1555 /* local prototypes */
1556 static int strwicmp(char *psz1, char *psz2);
1557 static int map_parameter(char *pszParmName);
1558 static BOOL set_boolean(BOOL *pb, char *pszParmValue);
1559 static int getservicebyname(char *pszServiceName,
1560                          service * pserviceDest);
1561 static void copy_service(service * pserviceDest,
1562                       service * pserviceSource, BOOL *pcopymapDest);
1563 static BOOL service_ok(int iService);
1564 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1565 static BOOL do_section(char *pszSectionName);
1566 static void init_copymap(service * pservice);
1567
1568
1569 /***************************************************************************
1570 initialise a service to the defaults
1571 ***************************************************************************/
1572 static void init_service(service * pservice)
1573 {
1574         memset((char *)pservice, '\0', sizeof(service));
1575         copy_service(pservice, &sDefault, NULL);
1576 }
1577
1578
1579 /***************************************************************************
1580 free the dynamically allocated parts of a service struct
1581 ***************************************************************************/
1582 static void free_service(service * pservice)
1583 {
1584         int i;
1585         if (!pservice)
1586                 return;
1587
1588         if (pservice->szService)
1589                 DEBUG(5,
1590                       ("free_service: Freeing service %s\n",
1591                        pservice->szService));
1592
1593         string_free(&pservice->szService);
1594         if (pservice->copymap)
1595         {
1596                 free(pservice->copymap);
1597                 pservice->copymap = NULL;
1598         }
1599
1600         for (i = 0; parm_table[i].label; i++)
1601                 if ((parm_table[i].type == P_STRING ||
1602                      parm_table[i].type == P_USTRING) &&
1603                     parm_table[i].class == P_LOCAL)
1604                         string_free((char **)
1605                                     (((char *)pservice) +
1606                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
1607 }
1608
1609 /***************************************************************************
1610 add a new service to the services array initialising it with the given 
1611 service
1612 ***************************************************************************/
1613 static int add_a_service(service * pservice, char *name)
1614 {
1615         int i;
1616         service tservice;
1617         int num_to_alloc = iNumServices + 1;
1618
1619         tservice = *pservice;
1620
1621         /* it might already exist */
1622         if (name)
1623         {
1624                 i = getservicebyname(name, NULL);
1625                 if (i >= 0)
1626                         return (i);
1627         }
1628
1629         /* find an invalid one */
1630         for (i = 0; i < iNumServices; i++)
1631                 if (!pSERVICE(i)->valid)
1632                         break;
1633
1634         /* if not, then create one */
1635         if (i == iNumServices)
1636         {
1637                 ServicePtrs =
1638                         (service **) Realloc(ServicePtrs,
1639                                              sizeof(service *) *
1640                                              num_to_alloc);
1641                 if (ServicePtrs)
1642                         pSERVICE(iNumServices) =
1643                                 (service *) malloc(sizeof(service));
1644
1645                 if (!ServicePtrs || !pSERVICE(iNumServices))
1646                         return (-1);
1647
1648                 iNumServices++;
1649         }
1650         else
1651                 free_service(pSERVICE(i));
1652
1653         pSERVICE(i)->valid = True;
1654
1655         init_service(pSERVICE(i));
1656         copy_service(pSERVICE(i), &tservice, NULL);
1657         if (name)
1658         {
1659                 string_set(&iSERVICE(i).szService, name);
1660                 unix_to_dos(iSERVICE(i).szService, True);
1661         }
1662         return (i);
1663 }
1664
1665 /***************************************************************************
1666 add a new home service, with the specified home directory, defaults coming 
1667 from service ifrom
1668 ***************************************************************************/
1669 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1670 {
1671         int i = add_a_service(pSERVICE(iDefaultService), pszHomename);
1672
1673         if (i < 0)
1674                 return (False);
1675
1676         if (!(*(iSERVICE(i).szPath))
1677             || strequal(iSERVICE(i).szPath, lp_pathname(-1)))
1678                 string_set(&iSERVICE(i).szPath, pszHomedir);
1679         if (!(*(iSERVICE(i).comment)))
1680         {
1681                 pstring comment;
1682                 slprintf(comment, sizeof(comment) - 1,
1683                          "Home directory of %s", pszHomename);
1684                 string_set(&iSERVICE(i).comment, comment);
1685         }
1686         iSERVICE(i).bAvailable = sDefault.bAvailable;
1687         iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1688
1689         DEBUG(3,
1690               ("adding home directory %s at %s\n", pszHomename, pszHomedir));
1691
1692         return (True);
1693 }
1694
1695 /***************************************************************************
1696 add a new service, based on an old one
1697 ***************************************************************************/
1698 int lp_add_service(char *pszService, int iDefaultService)
1699 {
1700         return (add_a_service(pSERVICE(iDefaultService), pszService));
1701 }
1702
1703
1704 /***************************************************************************
1705 add the IPC service
1706 ***************************************************************************/
1707 static BOOL lp_add_ipc(void)
1708 {
1709         pstring comment;
1710         int i = add_a_service(&sDefault, "IPC$");
1711
1712         if (i < 0)
1713                 return (False);
1714
1715         slprintf(comment, sizeof(comment) - 1,
1716                  "IPC Service (%s)", Globals.szServerString);
1717
1718         string_set(&iSERVICE(i).szPath, tmpdir());
1719         string_set(&iSERVICE(i).szUsername, "");
1720         string_set(&iSERVICE(i).comment, comment);
1721         string_set(&iSERVICE(i).fstype, "IPC");
1722         iSERVICE(i).status = False;
1723         iSERVICE(i).iMaxConnections = 0;
1724         iSERVICE(i).bAvailable = True;
1725         iSERVICE(i).bRead_only = True;
1726         iSERVICE(i).bGuest_only = False;
1727         iSERVICE(i).bGuest_ok = True;
1728         iSERVICE(i).bPrint_ok = False;
1729         iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1730
1731         DEBUG(3, ("adding IPC service\n"));
1732
1733         return (True);
1734 }
1735
1736
1737 /***************************************************************************
1738 add a new printer service, with defaults coming from service iFrom
1739 ***************************************************************************/
1740 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1741 {
1742         char *comment = "From Printcap";
1743         int i = add_a_service(pSERVICE(iDefaultService), pszPrintername);
1744
1745         if (i < 0)
1746                 return (False);
1747
1748         /* note that we do NOT default the availability flag to True - */
1749         /* we take it from the default service passed. This allows all */
1750         /* dynamic printers to be disabled by disabling the [printers] */
1751         /* entry (if/when the 'available' keyword is implemented!).    */
1752
1753         /* the printer name is set to the service name. */
1754         string_set(&iSERVICE(i).szPrintername, pszPrintername);
1755         string_set(&iSERVICE(i).comment, comment);
1756         iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1757         /* Printers cannot be read_only. */
1758         iSERVICE(i).bRead_only = False;
1759         /* No share modes on printer services. */
1760         iSERVICE(i).bShareModes = False;
1761         /* No oplocks on printer services. */
1762         iSERVICE(i).bOpLocks = False;
1763         /* Printer services must be printable. */
1764         iSERVICE(i).bPrint_ok = True;
1765
1766         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1767
1768         return (True);
1769 }
1770
1771
1772 /***************************************************************************
1773 Do a case-insensitive, whitespace-ignoring string compare.
1774 ***************************************************************************/
1775 static int strwicmp(char *psz1, char *psz2)
1776 {
1777         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1778         /* appropriate value. */
1779         if (psz1 == psz2)
1780                 return (0);
1781         else if (psz1 == NULL)
1782                 return (-1);
1783         else if (psz2 == NULL)
1784                 return (1);
1785
1786         /* sync the strings on first non-whitespace */
1787         while (1)
1788         {
1789                 while (isspace(*psz1))
1790                         psz1++;
1791                 while (isspace(*psz2))
1792                         psz2++;
1793                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
1794                     || *psz2 == '\0')
1795                         break;
1796                 psz1++;
1797                 psz2++;
1798         }
1799         return (*psz1 - *psz2);
1800 }
1801
1802 /***************************************************************************
1803 Map a parameter's string representation to something we can use. 
1804 Returns False if the parameter string is not recognised, else TRUE.
1805 ***************************************************************************/
1806 static int map_parameter(char *pszParmName)
1807 {
1808         int iIndex;
1809
1810         if (*pszParmName == '-')
1811                 return (-1);
1812
1813         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1814                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1815                         return (iIndex);
1816
1817         DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1818         return (-1);
1819 }
1820
1821
1822 /***************************************************************************
1823 Set a boolean variable from the text value stored in the passed string.
1824 Returns True in success, False if the passed string does not correctly 
1825 represent a boolean.
1826 ***************************************************************************/
1827 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1828 {
1829         BOOL bRetval;
1830
1831         bRetval = True;
1832         if (strwicmp(pszParmValue, "yes") == 0 ||
1833             strwicmp(pszParmValue, "true") == 0 ||
1834             strwicmp(pszParmValue, "1") == 0)
1835                 *pb = True;
1836         else
1837                 if (strwicmp(pszParmValue, "no") == 0 ||
1838                     strwicmp(pszParmValue, "False") == 0 ||
1839                     strwicmp(pszParmValue, "0") == 0)
1840                 *pb = False;
1841         else
1842         {
1843                 DEBUG(0,
1844                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1845                        pszParmValue));
1846                 bRetval = False;
1847         }
1848         return (bRetval);
1849 }
1850
1851 /***************************************************************************
1852 Find a service by name. Otherwise works like get_service.
1853 ***************************************************************************/
1854 static int getservicebyname(char *pszServiceName, service * pserviceDest)
1855 {
1856         int iService;
1857
1858         for (iService = iNumServices - 1; iService >= 0; iService--)
1859                 if (VALID(iService) &&
1860                     strwicmp(iSERVICE(iService).szService,
1861                              pszServiceName) == 0)
1862                 {
1863                         if (pserviceDest != NULL)
1864                                 copy_service(pserviceDest, pSERVICE(iService),
1865                                              NULL);
1866                         break;
1867                 }
1868
1869         return (iService);
1870 }
1871
1872
1873
1874 /***************************************************************************
1875 Copy a service structure to another
1876
1877 If pcopymapDest is NULL then copy all fields
1878 ***************************************************************************/
1879 static void copy_service(service * pserviceDest,
1880                          service * pserviceSource, BOOL *pcopymapDest)
1881 {
1882         int i;
1883         BOOL bcopyall = (pcopymapDest == NULL);
1884
1885         for (i = 0; parm_table[i].label; i++)
1886                 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1887                     (bcopyall || pcopymapDest[i]))
1888                 {
1889                         void *def_ptr = parm_table[i].ptr;
1890                         void *src_ptr =
1891                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1892                                                                     &sDefault);
1893                         void *dest_ptr =
1894                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1895                                                                   &sDefault);
1896
1897                         switch (parm_table[i].type)
1898                         {
1899                                 case P_BOOL:
1900                                 case P_BOOLREV:
1901                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1902                                         break;
1903
1904                                 case P_INTEGER:
1905                                 case P_ENUM:
1906                                 case P_OCTAL:
1907                                         *(int *)dest_ptr = *(int *)src_ptr;
1908                                         break;
1909
1910                                 case P_CHAR:
1911                                         *(char *)dest_ptr = *(char *)src_ptr;
1912                                         break;
1913
1914                                 case P_STRING:
1915                                         string_set(dest_ptr,
1916                                                    *(char **)src_ptr);
1917                                         break;
1918
1919                                 case P_USTRING:
1920                                         string_set(dest_ptr,
1921                                                    *(char **)src_ptr);
1922                                         strupper(*(char **)dest_ptr);
1923                                         break;
1924                                 default:
1925                                         break;
1926                         }
1927                 }
1928
1929         if (bcopyall)
1930         {
1931                 init_copymap(pserviceDest);
1932                 if (pserviceSource->copymap)
1933                         memcpy((void *)pserviceDest->copymap,
1934                                (void *)pserviceSource->copymap,
1935                                sizeof(BOOL) * NUMPARAMETERS);
1936         }
1937 }
1938
1939 /***************************************************************************
1940 Check a service for consistency. Return False if the service is in any way
1941 incomplete or faulty, else True.
1942 ***************************************************************************/
1943 static BOOL service_ok(int iService)
1944 {
1945         BOOL bRetval;
1946
1947         bRetval = True;
1948         if (iSERVICE(iService).szService[0] == '\0')
1949         {
1950                 DEBUG(0,
1951                       ("The following message indicates an internal error:\n"));
1952                 DEBUG(0, ("No service name in service entry.\n"));
1953                 bRetval = False;
1954         }
1955
1956         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1957         /* I can't see why you'd want a non-printable printer service...        */
1958         if (strwicmp(iSERVICE(iService).szService, PRINTERS_NAME) == 0) {
1959                 if (!iSERVICE(iService).bPrint_ok) {
1960                         DEBUG(0,
1961                               ("WARNING: [%s] service MUST be printable!\n",
1962                                iSERVICE(iService).szService));
1963                         iSERVICE(iService).bPrint_ok = True;
1964                 }
1965                 /* [printers] service must also be non-browsable. */
1966                 if (iSERVICE(iService).bBrowseable)
1967                         iSERVICE(iService).bBrowseable = False;
1968         }
1969
1970         if (iSERVICE(iService).szPath[0] == '\0' &&
1971             strwicmp(iSERVICE(iService).szService, HOMES_NAME) != 0)
1972         {
1973                 DEBUG(0,
1974                       ("No path in service %s - using %s\n",
1975                        iSERVICE(iService).szService, tmpdir()));
1976                 string_set(&iSERVICE(iService).szPath, tmpdir());
1977         }
1978
1979         /* If a service is flagged unavailable, log the fact at level 0. */
1980         if (!iSERVICE(iService).bAvailable)
1981                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1982                           iSERVICE(iService).szService));
1983
1984         return (bRetval);
1985 }
1986
1987 static struct file_lists
1988 {
1989         struct file_lists *next;
1990         char *name;
1991         time_t modtime;
1992 }
1993  *file_lists = NULL;
1994
1995 /*******************************************************************
1996 keep a linked list of all config files so we know when one has changed 
1997 it's date and needs to be reloaded
1998 ********************************************************************/
1999 static void add_to_file_list(char *fname)
2000 {
2001         struct file_lists *f = file_lists;
2002
2003         while (f)
2004         {
2005                 if (f->name && !strcmp(f->name, fname))
2006                         break;
2007                 f = f->next;
2008         }
2009
2010         if (!f)
2011         {
2012                 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2013                 if (!f)
2014                         return;
2015                 f->next = file_lists;
2016                 f->name = strdup(fname);
2017                 if (!f->name)
2018                 {
2019                         free(f);
2020                         return;
2021                 }
2022                 file_lists = f;
2023         }
2024
2025         {
2026                 pstring n2;
2027                 pstrcpy(n2, fname);
2028                 standard_sub_basic(n2);
2029                 f->modtime = file_modtime(n2);
2030         }
2031
2032 }
2033
2034 /*******************************************************************
2035 check if a config file has changed date
2036 ********************************************************************/
2037 BOOL lp_file_list_changed(void)
2038 {
2039         struct file_lists *f = file_lists;
2040         DEBUG(6, ("lp_file_list_changed()\n"));
2041
2042         while (f)
2043         {
2044                 pstring n2;
2045                 time_t mod_time;
2046
2047                 pstrcpy(n2, f->name);
2048                 standard_sub_basic(n2);
2049
2050                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2051                              f->name, n2, ctime(&f->modtime)));
2052
2053                 mod_time = file_modtime(n2);
2054
2055                 if (f->modtime != mod_time)
2056                 {
2057                         DEBUGADD(6,
2058                                  ("file %s modified: %s\n", n2,
2059                                   ctime(&mod_time)));
2060                         f->modtime = mod_time;
2061                         return (True);
2062                 }
2063                 f = f->next;
2064         }
2065         return (False);
2066 }
2067
2068 /***************************************************************************
2069  Run standard_sub_basic on netbios name... needed because global_myname
2070  is not accessed through any lp_ macro.
2071  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2072 ***************************************************************************/
2073
2074 static BOOL handle_netbios_name(char *pszParmValue, char **ptr)
2075 {
2076         pstring netbios_name;
2077
2078         pstrcpy(netbios_name, pszParmValue);
2079
2080         standard_sub_basic(netbios_name);
2081         strupper(netbios_name);
2082
2083         /*
2084          * Convert from UNIX to DOS string - the UNIX to DOS converter
2085          * isn't called on the special handlers.
2086          */
2087         unix_to_dos(netbios_name, True);
2088         pstrcpy(global_myname, netbios_name);
2089
2090         DEBUG(4,
2091               ("handle_netbios_name: set global_myname to: %s\n",
2092                global_myname));
2093
2094         return (True);
2095 }
2096
2097 /***************************************************************************
2098  Do the work of sourcing in environment variable/value pairs.
2099 ***************************************************************************/
2100
2101 static BOOL source_env(char **lines)
2102 {
2103         char *varval;
2104         size_t len;
2105         int i;
2106         char *p;
2107
2108         for (i = 0; lines[i]; i++)
2109         {
2110                 char *line = lines[i];
2111
2112                 if ((len = strlen(line)) == 0)
2113                         continue;
2114
2115                 if (line[len - 1] == '\n')
2116                         line[--len] = '\0';
2117
2118                 if ((varval = malloc(len + 1)) == NULL)
2119                 {
2120                         DEBUG(0, ("source_env: Not enough memory!\n"));
2121                         return (False);
2122                 }
2123
2124                 DEBUG(4, ("source_env: Adding to environment: %s\n", line));
2125                 strncpy(varval, line, len);
2126                 varval[len] = '\0';
2127
2128                 p = strchr(line, (int)'=');
2129                 if (p == NULL)
2130                 {
2131                         DEBUG(4, ("source_env: missing '=': %s\n", line));
2132                         continue;
2133                 }
2134
2135                 if (putenv(varval))
2136                 {
2137                         DEBUG(0,
2138                               ("source_env: Failed to put environment variable %s\n",
2139                                varval));
2140                         continue;
2141                 }
2142
2143                 *p = '\0';
2144                 p++;
2145                 DEBUG(4,
2146                       ("source_env: getting var %s = %s\n", line,
2147                        getenv(line)));
2148         }
2149
2150         DEBUG(4, ("source_env: returning successfully\n"));
2151         return (True);
2152 }
2153
2154 /***************************************************************************
2155  Handle the source environment operation
2156 ***************************************************************************/
2157
2158 static BOOL handle_source_env(char *pszParmValue, char **ptr)
2159 {
2160         pstring fname;
2161         char *p = fname;
2162         BOOL result;
2163         char **lines;
2164
2165         pstrcpy(fname, pszParmValue);
2166
2167         standard_sub_basic(fname);
2168
2169         string_set(ptr, pszParmValue);
2170
2171         DEBUG(4, ("handle_source_env: checking env type\n"));
2172
2173         /*
2174          * Filename starting with '|' means popen and read from stdin.
2175          */
2176
2177         if (*p == '|')
2178         {
2179                 lines = file_lines_pload(p + 1, NULL);
2180         }
2181         else
2182         {
2183                 lines = file_lines_load(fname, NULL);
2184         }
2185
2186         if (!lines)
2187         {
2188                 DEBUG(0,
2189                       ("handle_source_env: Failed to open file %s, Error was %s\n",
2190                        fname, strerror(errno)));
2191                 return (False);
2192         }
2193
2194         result = source_env(lines);
2195         file_lines_free(lines);
2196
2197         return (result);
2198 }
2199
2200 /***************************************************************************
2201   handle the interpretation of the vfs object parameter
2202   *************************************************************************/
2203 static BOOL handle_vfs_object(char *pszParmValue, char **ptr)
2204 {
2205         /* Set string value */
2206
2207         string_set(ptr, pszParmValue);
2208
2209         /* Do any other initialisation required for vfs.  Note that
2210            anything done here may have linking repercussions in nmbd. */
2211
2212         return True;
2213 }
2214
2215 /***************************************************************************
2216   handle the interpretation of the coding system parameter
2217   *************************************************************************/
2218 static BOOL handle_coding_system(char *pszParmValue, char **ptr)
2219 {
2220         string_set(ptr, pszParmValue);
2221         interpret_coding_system(pszParmValue);
2222         return (True);
2223 }
2224
2225 /***************************************************************************
2226  Handle the interpretation of the character set system parameter.
2227 ***************************************************************************/
2228
2229 static char *saved_character_set = NULL;
2230
2231 static BOOL handle_character_set(char *pszParmValue, char **ptr)
2232 {
2233         /* A dependency here is that the parameter client code page should be
2234            set before this is called.
2235          */
2236         string_set(ptr, pszParmValue);
2237         strupper(*ptr);
2238         saved_character_set = strdup(*ptr);
2239         interpret_character_set(*ptr, lp_client_code_page());
2240         return (True);
2241 }
2242
2243 /***************************************************************************
2244  Handle the interpretation of the client code page parameter.
2245  We handle this separately so that we can reset the character set
2246  parameter in case this came before 'client code page' in the smb.conf.
2247 ***************************************************************************/
2248
2249 static BOOL handle_client_code_page(char *pszParmValue, char **ptr)
2250 {
2251         Globals.client_code_page = atoi(pszParmValue);
2252         if (saved_character_set != NULL)
2253                 interpret_character_set(saved_character_set,
2254                                         lp_client_code_page());
2255         return (True);
2256 }
2257
2258 /***************************************************************************
2259 handle the valid chars lines
2260 ***************************************************************************/
2261
2262 static BOOL handle_valid_chars(char *pszParmValue, char **ptr)
2263 {
2264         string_set(ptr, pszParmValue);
2265
2266         /* A dependency here is that the parameter client code page must be
2267            set before this is called - as calling codepage_initialise()
2268            would overwrite the valid char lines.
2269          */
2270         codepage_initialise(lp_client_code_page());
2271
2272         add_char_string(pszParmValue);
2273         return (True);
2274 }
2275
2276 /***************************************************************************
2277 handle the include operation
2278 ***************************************************************************/
2279
2280 static BOOL handle_include(char *pszParmValue, char **ptr)
2281 {
2282         pstring fname;
2283         pstrcpy(fname, pszParmValue);
2284
2285         add_to_file_list(fname);
2286
2287         standard_sub_basic(fname);
2288
2289         string_set(ptr, fname);
2290
2291         if (file_exist(fname, NULL))
2292                 return (pm_process(fname, do_section, do_parameter));
2293
2294         DEBUG(2, ("Can't find include file %s\n", fname));
2295
2296         return (False);
2297 }
2298
2299
2300 /***************************************************************************
2301 handle the interpretation of the copy parameter
2302 ***************************************************************************/
2303 static BOOL handle_copy(char *pszParmValue, char **ptr)
2304 {
2305         BOOL bRetval;
2306         int iTemp;
2307         service serviceTemp;
2308
2309         string_set(ptr, pszParmValue);
2310
2311         init_service(&serviceTemp);
2312
2313         bRetval = False;
2314
2315         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2316
2317         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
2318         {
2319                 if (iTemp == iServiceIndex)
2320                 {
2321                         DEBUG(0,
2322                               ("Can't copy service %s - unable to copy self!\n",
2323                                pszParmValue));
2324                 }
2325                 else
2326                 {
2327                         copy_service(pSERVICE(iServiceIndex),
2328                                      &serviceTemp,
2329                                      iSERVICE(iServiceIndex).copymap);
2330                         bRetval = True;
2331                 }
2332         }
2333         else
2334         {
2335                 DEBUG(0, ("Unable to copy service - source not found: %s\n",
2336                           pszParmValue));
2337                 bRetval = False;
2338         }
2339
2340         free_service(&serviceTemp);
2341         return (bRetval);
2342 }
2343
2344 /***************************************************************************
2345  Handle winbind uid and gid allocation parameters.  The format of these
2346  parameters is:
2347
2348  [global]
2349
2350         winbind uid = 1000-1999
2351         winbind gid = 700-899
2352
2353  We only do simple parsing checks here.  The strings are parsed into useful
2354  structures in the winbind daemon code.
2355
2356 ***************************************************************************/
2357
2358 /* Do some simple checks on "winbind [ug]id" parameter value */
2359
2360 static BOOL handle_winbind_id(char *pszParmValue, char **ptr)
2361 {
2362         int low, high;
2363
2364         if (sscanf(pszParmValue, "%d-%d", &low, &high) != 2)
2365         {
2366                 return False;
2367         }
2368
2369         /* Parse OK */
2370
2371         string_set(ptr, pszParmValue);
2372
2373         return True;
2374 }
2375
2376 /***************************************************************************
2377  Handle the WINS SERVER list
2378 ***************************************************************************/
2379 static BOOL handle_wins_server_list( char *pszParmValue, char **ptr )
2380   {
2381   if( !wins_srv_load_list( pszParmValue ) )
2382     return( False );  /* Parse failed. */
2383
2384   string_set( ptr, pszParmValue );
2385   return( True );
2386   }
2387
2388
2389 /***************************************************************************
2390 initialise a copymap
2391 ***************************************************************************/
2392 static void init_copymap(service * pservice)
2393 {
2394         int i;
2395         if (pservice->copymap)
2396                 free(pservice->copymap);
2397         pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2398         if (!pservice->copymap)
2399                 DEBUG(0,
2400                       ("Couldn't allocate copymap!! (size %d)\n",
2401                        (int)NUMPARAMETERS));
2402         else
2403                 for (i = 0; i < NUMPARAMETERS; i++)
2404                         pservice->copymap[i] = True;
2405 }
2406
2407
2408 /***************************************************************************
2409  return the local pointer to a parameter given the service number and the 
2410  pointer into the default structure
2411 ***************************************************************************/
2412 void *lp_local_ptr(int snum, void *ptr)
2413 {
2414         return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr, &sDefault));
2415 }
2416
2417 /***************************************************************************
2418 Process a parameter for a particular service number. If snum < 0
2419 then assume we are in the globals
2420 ***************************************************************************/
2421 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
2422 {
2423         int parmnum, i;
2424         void *parm_ptr = NULL;  /* where we are going to store the result */
2425         void *def_ptr = NULL;
2426
2427         parmnum = map_parameter(pszParmName);
2428
2429         if (parmnum < 0)
2430         {
2431                 DEBUG(0,
2432                       ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2433                 return (True);
2434         }
2435
2436         if (parm_table[parmnum].flags & FLAG_DEPRECATED)
2437         {
2438                 DEBUG(1, ("WARNING: The \"%s\"option is deprecated\n",
2439                           pszParmName));
2440         }
2441
2442         def_ptr = parm_table[parmnum].ptr;
2443
2444         /* we might point at a service, the default service or a global */
2445         if (snum < 0)
2446         {
2447                 parm_ptr = def_ptr;
2448         }
2449         else
2450         {
2451                 if (parm_table[parmnum].class == P_GLOBAL)
2452                 {
2453                         DEBUG(0,
2454                               ("Global parameter %s found in service section!\n",
2455                                pszParmName));
2456                         return (True);
2457                 }
2458                 parm_ptr =
2459                         ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,
2460                                                             &sDefault);
2461         }
2462
2463         if (snum >= 0)
2464         {
2465                 if (!iSERVICE(snum).copymap)
2466                         init_copymap(pSERVICE(snum));
2467
2468                 /* this handles the aliases - set the copymap for other entries with
2469                    the same data pointer */
2470                 for (i = 0; parm_table[i].label; i++)
2471                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
2472                                 iSERVICE(snum).copymap[i] = False;
2473         }
2474
2475         /* if it is a special case then go ahead */
2476         if (parm_table[parmnum].special)
2477         {
2478                 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2479                 return (True);
2480         }
2481
2482         /* now switch on the type of variable it is */
2483         switch (parm_table[parmnum].type)
2484         {
2485                 case P_BOOL:
2486                         set_boolean(parm_ptr, pszParmValue);
2487                         break;
2488
2489                 case P_BOOLREV:
2490                         set_boolean(parm_ptr, pszParmValue);
2491                         *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2492                         break;
2493
2494                 case P_INTEGER:
2495                         *(int *)parm_ptr = atoi(pszParmValue);
2496                         break;
2497
2498                 case P_CHAR:
2499                         *(char *)parm_ptr = *pszParmValue;
2500                         break;
2501
2502                 case P_OCTAL:
2503                         sscanf(pszParmValue, "%o", (int *)parm_ptr);
2504                         break;
2505
2506                 case P_STRING:
2507                         string_set(parm_ptr, pszParmValue);
2508                         if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2509                                 unix_to_dos(*(char **)parm_ptr, True);
2510                         break;
2511
2512                 case P_USTRING:
2513                         string_set(parm_ptr, pszParmValue);
2514                         if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2515                                 unix_to_dos(*(char **)parm_ptr, True);
2516                         strupper(*(char **)parm_ptr);
2517                         break;
2518
2519                 case P_GSTRING:
2520                         pstrcpy((char *)parm_ptr, pszParmValue);
2521                         if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2522                                 unix_to_dos((char *)parm_ptr, True);
2523                         break;
2524
2525                 case P_UGSTRING:
2526                         pstrcpy((char *)parm_ptr, pszParmValue);
2527                         if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2528                                 unix_to_dos((char *)parm_ptr, True);
2529                         strupper((char *)parm_ptr);
2530                         break;
2531
2532                 case P_ENUM:
2533                         for (i = 0; parm_table[parmnum].enum_list[i].name;
2534                              i++)
2535                         {
2536                                 if (strequal
2537                                     (pszParmValue,
2538                                      parm_table[parmnum].enum_list[i].name))
2539                                 {
2540                                         *(int *)parm_ptr =
2541                                                 parm_table[parmnum].
2542                                                 enum_list[i].value;
2543                                         break;
2544                                 }
2545                         }
2546                         break;
2547                 case P_SEP:
2548                         break;
2549         }
2550
2551         return (True);
2552 }
2553
2554 /***************************************************************************
2555 Process a parameter.
2556 ***************************************************************************/
2557 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
2558 {
2559         if (!bInGlobalSection && bGlobalOnly)
2560                 return (True);
2561
2562         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2563
2564         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2565                                 pszParmName, pszParmValue));
2566 }
2567
2568
2569 /***************************************************************************
2570 print a parameter of the specified type
2571 ***************************************************************************/
2572 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2573 {
2574         int i;
2575         switch (p->type)
2576         {
2577                 case P_ENUM:
2578                         for (i = 0; p->enum_list[i].name; i++)
2579                         {
2580                                 if (*(int *)ptr == p->enum_list[i].value)
2581                                 {
2582                                         fprintf(f, "%s",
2583                                                 p->enum_list[i].name);
2584                                         break;
2585                                 }
2586                         }
2587                         break;
2588
2589                 case P_BOOL:
2590                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2591                         break;
2592
2593                 case P_BOOLREV:
2594                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2595                         break;
2596
2597                 case P_INTEGER:
2598                         fprintf(f, "%d", *(int *)ptr);
2599                         break;
2600
2601                 case P_CHAR:
2602                         fprintf(f, "%c", *(char *)ptr);
2603                         break;
2604
2605                 case P_OCTAL:
2606                         fprintf(f, "%s", octal_string(*(int *)ptr));
2607                         break;
2608
2609                 case P_GSTRING:
2610                 case P_UGSTRING:
2611                         if ((char *)ptr)
2612                                 fprintf(f, "%s", (char *)ptr);
2613                         break;
2614
2615                 case P_STRING:
2616                 case P_USTRING:
2617                         if (*(char **)ptr)
2618                                 fprintf(f, "%s", *(char **)ptr);
2619                         break;
2620                 case P_SEP:
2621                         break;
2622         }
2623 }
2624
2625
2626 /***************************************************************************
2627 check if two parameters are equal
2628 ***************************************************************************/
2629 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2630 {
2631         switch (type)
2632         {
2633                 case P_BOOL:
2634                 case P_BOOLREV:
2635                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2636
2637                 case P_INTEGER:
2638                 case P_ENUM:
2639                 case P_OCTAL:
2640                         return (*((int *)ptr1) == *((int *)ptr2));
2641
2642                 case P_CHAR:
2643                         return (*((char *)ptr1) == *((char *)ptr2));
2644
2645                 case P_GSTRING:
2646                 case P_UGSTRING:
2647                 {
2648                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2649                         if (p1 && !*p1)
2650                                 p1 = NULL;
2651                         if (p2 && !*p2)
2652                                 p2 = NULL;
2653                         return (p1 == p2 || strequal(p1, p2));
2654                 }
2655                 case P_STRING:
2656                 case P_USTRING:
2657                 {
2658                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2659                         if (p1 && !*p1)
2660                                 p1 = NULL;
2661                         if (p2 && !*p2)
2662                                 p2 = NULL;
2663                         return (p1 == p2 || strequal(p1, p2));
2664                 }
2665                 case P_SEP:
2666                         break;
2667         }
2668         return (False);
2669 }
2670
2671 /***************************************************************************
2672 Process a new section (service). At this stage all sections are services.
2673 Later we'll have special sections that permit server parameters to be set.
2674 Returns True on success, False on failure.
2675 ***************************************************************************/
2676 static BOOL do_section(char *pszSectionName)
2677 {
2678         BOOL bRetval;
2679         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2680                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2681         bRetval = False;
2682
2683         /* if we were in a global section then do the local inits */
2684         if (bInGlobalSection && !isglobal)
2685                 init_locals();
2686
2687         /* if we've just struck a global section, note the fact. */
2688         bInGlobalSection = isglobal;
2689
2690         /* check for multiple global sections */
2691         if (bInGlobalSection)
2692         {
2693                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2694                 return (True);
2695         }
2696
2697         if (!bInGlobalSection && bGlobalOnly)
2698                 return (True);
2699
2700         /* if we have a current service, tidy it up before moving on */
2701         bRetval = True;
2702
2703         if (iServiceIndex >= 0)
2704                 bRetval = service_ok(iServiceIndex);
2705
2706         /* if all is still well, move to the next record in the services array */
2707         if (bRetval)
2708         {
2709                 /* We put this here to avoid an odd message order if messages are */
2710                 /* issued by the post-processing of a previous section. */
2711                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2712
2713                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2714                     < 0)
2715                 {
2716                         DEBUG(0, ("Failed to add a new service\n"));
2717                         return (False);
2718                 }
2719         }
2720
2721         return (bRetval);
2722 }
2723
2724
2725 /***************************************************************************
2726 determine if a partcular base parameter is currently set to the default value.
2727 ***************************************************************************/
2728 static BOOL is_default(int i)
2729 {
2730         if (!defaults_saved)
2731                 return False;
2732         switch (parm_table[i].type)
2733         {
2734                 case P_STRING:
2735                 case P_USTRING:
2736                         return strequal(parm_table[i].def.svalue,
2737                                         *(char **)parm_table[i].ptr);
2738                 case P_GSTRING:
2739                 case P_UGSTRING:
2740                         return strequal(parm_table[i].def.svalue,
2741                                         (char *)parm_table[i].ptr);
2742                 case P_BOOL:
2743                 case P_BOOLREV:
2744                         return parm_table[i].def.bvalue ==
2745                                 *(BOOL *)parm_table[i].ptr;
2746                 case P_CHAR:
2747                         return parm_table[i].def.cvalue ==
2748                                 *(char *)parm_table[i].ptr;
2749                 case P_INTEGER:
2750                 case P_OCTAL:
2751                 case P_ENUM:
2752                         return parm_table[i].def.ivalue ==
2753                                 *(int *)parm_table[i].ptr;
2754                 case P_SEP:
2755                         break;
2756         }
2757         return False;
2758 }
2759
2760
2761 /***************************************************************************
2762 Display the contents of the global structure.
2763 ***************************************************************************/
2764 static void dump_globals(FILE * f)
2765 {
2766         int i;
2767         fprintf(f, "# Global parameters\n[global]\n");
2768
2769         for (i = 0; parm_table[i].label; i++)
2770                 if (parm_table[i].class == P_GLOBAL &&
2771                     parm_table[i].ptr &&
2772                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2773                 {
2774                         if (defaults_saved && is_default(i))
2775                                 continue;
2776                         fprintf(f, "\t%s = ", parm_table[i].label);
2777                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
2778                         fprintf(f, "\n");
2779                 }
2780 }
2781
2782 /***************************************************************************
2783 return True if a local parameter is currently set to the global default
2784 ***************************************************************************/
2785 BOOL lp_is_default(int snum, struct parm_struct *parm)
2786 {
2787         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2788
2789         return equal_parameter(parm->type,
2790                                ((char *)pSERVICE(snum)) + pdiff,
2791                                ((char *)&sDefault) + pdiff);
2792 }
2793
2794
2795 /***************************************************************************
2796 Display the contents of a single services record.
2797 ***************************************************************************/
2798 static void dump_a_service(service * pService, FILE * f)
2799 {
2800         int i;
2801         if (pService != &sDefault)
2802                 fprintf(f, "\n[%s]\n", pService->szService);
2803
2804         for (i = 0; parm_table[i].label; i++)
2805                 if (parm_table[i].class == P_LOCAL &&
2806                     parm_table[i].ptr &&
2807                     (*parm_table[i].label != '-') &&
2808                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2809                 {
2810                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2811
2812                         if (pService == &sDefault)
2813                         {
2814                                 if (defaults_saved && is_default(i))
2815                                         continue;
2816                         }
2817                         else
2818                         {
2819                                 if (equal_parameter(parm_table[i].type,
2820                                                     ((char *)pService) +
2821                                                     pdiff,
2822                                                     ((char *)&sDefault) +
2823                                                     pdiff))
2824                                         continue;
2825                         }
2826
2827                         fprintf(f, "\t%s = ", parm_table[i].label);
2828                         print_parameter(&parm_table[i],
2829                                         ((char *)pService) + pdiff, f);
2830                         fprintf(f, "\n");
2831                 }
2832 }
2833
2834
2835 /***************************************************************************
2836 return info about the next service  in a service. snum==-1 gives the globals
2837
2838 return NULL when out of parameters
2839 ***************************************************************************/
2840 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2841 {
2842         if (snum == -1)
2843         {
2844                 /* do the globals */
2845                 for (; parm_table[*i].label; (*i)++)
2846                 {
2847                         if (parm_table[*i].class == P_SEPARATOR)
2848                                 return &parm_table[(*i)++];
2849
2850                         if (!parm_table[*i].ptr
2851                             || (*parm_table[*i].label == '-'))
2852                                 continue;
2853
2854                         if ((*i) > 0
2855                             && (parm_table[*i].ptr ==
2856                                 parm_table[(*i) - 1].ptr))
2857                                 continue;
2858
2859                         return &parm_table[(*i)++];
2860                 }
2861         }
2862         else
2863         {
2864                 service *pService = pSERVICE(snum);
2865
2866                 for (; parm_table[*i].label; (*i)++)
2867                 {
2868                         if (parm_table[*i].class == P_SEPARATOR)
2869                                 return &parm_table[(*i)++];
2870
2871                         if (parm_table[*i].class == P_LOCAL &&
2872                             parm_table[*i].ptr &&
2873                             (*parm_table[*i].label != '-') &&
2874                             ((*i) == 0 ||
2875                              (parm_table[*i].ptr !=
2876                               parm_table[(*i) - 1].ptr)))
2877                         {
2878                                 int pdiff =
2879                                         PTR_DIFF(parm_table[*i].ptr,
2880                                                  &sDefault);
2881
2882                                 if (allparameters ||
2883                                     !equal_parameter(parm_table[*i].type,
2884                                                      ((char *)pService) +
2885                                                      pdiff,
2886                                                      ((char *)&sDefault) +
2887                                                      pdiff))
2888                                 {
2889                                         return &parm_table[(*i)++];
2890                                 }
2891                         }
2892                 }
2893         }
2894
2895         return NULL;
2896 }
2897
2898
2899 #if 0
2900 /***************************************************************************
2901 Display the contents of a single copy structure.
2902 ***************************************************************************/
2903 static void dump_copy_map(BOOL *pcopymap)
2904 {
2905         int i;
2906         if (!pcopymap)
2907                 return;
2908
2909         printf("\n\tNon-Copied parameters:\n");
2910
2911         for (i = 0; parm_table[i].label; i++)
2912                 if (parm_table[i].class == P_LOCAL &&
2913                     parm_table[i].ptr && !pcopymap[i] &&
2914                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2915                 {
2916                         printf("\t\t%s\n", parm_table[i].label);
2917                 }
2918 }
2919 #endif
2920
2921 /***************************************************************************
2922 Return TRUE if the passed service number is within range.
2923 ***************************************************************************/
2924 BOOL lp_snum_ok(int iService)
2925 {
2926         return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2927 }
2928
2929
2930 /***************************************************************************
2931 auto-load some home services
2932 ***************************************************************************/
2933 static void lp_add_auto_services(char *str)
2934 {
2935         char *s;
2936         char *p;
2937         int homes;
2938
2939         if (!str)
2940                 return;
2941
2942         s = strdup(str);
2943         if (!s)
2944                 return;
2945
2946         homes = lp_servicenumber(HOMES_NAME);
2947
2948         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP))
2949         {
2950                 char *home = get_user_home_dir(p);
2951
2952                 if (lp_servicenumber(p) >= 0)
2953                         continue;
2954
2955                 if (home && homes >= 0)
2956                 {
2957                         lp_add_home(p, homes, home);
2958                 }
2959         }
2960         free(s);
2961 }
2962
2963 /***************************************************************************
2964 auto-load one printer
2965 ***************************************************************************/
2966 void lp_add_one_printer(char *name, char *comment)
2967 {
2968         int printers = lp_servicenumber(PRINTERS_NAME);
2969         int i;
2970
2971         if (lp_servicenumber(name) < 0)
2972         {
2973                 lp_add_printer(name, printers);
2974                 if ((i = lp_servicenumber(name)) >= 0)
2975                 {
2976                         string_set(&iSERVICE(i).comment, comment);
2977                         iSERVICE(i).autoloaded = True;
2978                 }
2979         }
2980 }
2981
2982 /***************************************************************************
2983 have we loaded a services file yet?
2984 ***************************************************************************/
2985 BOOL lp_loaded(void)
2986 {
2987         return (bLoaded);
2988 }
2989
2990 /***************************************************************************
2991 unload unused services
2992 ***************************************************************************/
2993 void lp_killunused(BOOL (*snumused) (int))
2994 {
2995         int i;
2996         for (i = 0; i < iNumServices; i++)
2997         {
2998                 if (!VALID(i))
2999                         continue;
3000
3001                 if (!snumused || !snumused(i))
3002                 {
3003                         iSERVICE(i).valid = False;
3004                         free_service(pSERVICE(i));
3005                 }
3006         }
3007 }
3008
3009
3010 /***************************************************************************
3011 save the curent values of all global and sDefault parameters into the 
3012 defaults union. This allows swat and testparm to show only the
3013 changed (ie. non-default) parameters.
3014 ***************************************************************************/
3015 static void lp_save_defaults(void)
3016 {
3017         int i;
3018         for (i = 0; parm_table[i].label; i++)
3019         {
3020                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3021                         continue;
3022                 switch (parm_table[i].type)
3023                 {
3024                         case P_STRING:
3025                         case P_USTRING:
3026                                 parm_table[i].def.svalue =
3027                                         strdup(*(char **)parm_table[i].ptr);
3028                                 break;
3029                         case P_GSTRING:
3030                         case P_UGSTRING:
3031                                 parm_table[i].def.svalue =
3032                                         strdup((char *)parm_table[i].ptr);
3033                                 break;
3034                         case P_BOOL:
3035                         case P_BOOLREV:
3036                                 parm_table[i].def.bvalue =
3037                                         *(BOOL *)parm_table[i].ptr;
3038                                 break;
3039                         case P_CHAR:
3040                                 parm_table[i].def.cvalue =
3041                                         *(char *)parm_table[i].ptr;
3042                                 break;
3043                         case P_INTEGER:
3044                         case P_OCTAL:
3045                         case P_ENUM:
3046                                 parm_table[i].def.ivalue =
3047                                         *(int *)parm_table[i].ptr;
3048                                 break;
3049                         case P_SEP:
3050                                 break;
3051                 }
3052         }
3053         defaults_saved = True;
3054 }
3055
3056 /*******************************************************************
3057  Set the server type we will announce as via nmbd.
3058 ********************************************************************/
3059 static void set_server_role(void)
3060 {
3061         server_role = ROLE_STANDALONE;
3062
3063         switch (lp_security())
3064         {
3065                 case SEC_SHARE:
3066                 {
3067                         if (lp_domain_logons())
3068                         {
3069                                 DEBUG(0,
3070                                       ("Server's Role (logon server) conflicts with share-level security\n"));
3071                         }
3072                         break;
3073                 }
3074                 case SEC_SERVER:
3075                 case SEC_DOMAIN:
3076                 {
3077                         if (lp_domain_logons())
3078                         {
3079                                 server_role = ROLE_DOMAIN_BDC;
3080                                 break;
3081                         }
3082                         server_role = ROLE_DOMAIN_MEMBER;
3083                         break;
3084                 }
3085                 case SEC_USER:
3086                 {
3087                         if (lp_domain_logons())
3088                         {
3089                                 server_role = ROLE_DOMAIN_PDC;
3090                                 break;
3091                         }
3092                         break;
3093                 }
3094                 default:
3095                 {
3096                         DEBUG(0,
3097                               ("Server's Role undefined due to unknown security mode\n"));
3098                 }
3099         }
3100 }
3101
3102
3103 /***************************************************************************
3104 Load the services array from the services file. Return True on success, 
3105 False on failure.
3106 ***************************************************************************/
3107 BOOL lp_load(char *pszFname, BOOL global_only, BOOL save_defaults,
3108              BOOL add_ipc)
3109 {
3110         pstring n2;
3111         BOOL bRetval;
3112
3113         add_to_file_list(pszFname);
3114
3115         bRetval = False;
3116
3117         bInGlobalSection = True;
3118         bGlobalOnly = global_only;
3119
3120         init_globals();
3121
3122         if (save_defaults)
3123         {
3124                 init_locals();
3125                 lp_save_defaults();
3126         }
3127
3128         pstrcpy(n2, pszFname);
3129         standard_sub_basic(n2);
3130
3131         /* We get sections first, so have to start 'behind' to make up */
3132         iServiceIndex = -1;
3133         bRetval = pm_process(n2, do_section, do_parameter);
3134
3135         /* finish up the last section */
3136         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3137         if (bRetval)
3138                 if (iServiceIndex >= 0)
3139                         bRetval = service_ok(iServiceIndex);
3140
3141         lp_add_auto_services(lp_auto_services());
3142
3143         if (add_ipc)
3144                 lp_add_ipc();
3145
3146         set_server_role();
3147         set_default_server_announce_type();
3148
3149         bLoaded = True;
3150
3151         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3152         /* if bWINSsupport is true and we are in the client            */
3153
3154         if (in_client && Globals.bWINSsupport)
3155         {
3156
3157                 string_set(&Globals.szWINSserver, "127.0.0.1");
3158
3159         }
3160
3161         return (bRetval);
3162 }
3163
3164
3165 /***************************************************************************
3166 reset the max number of services
3167 ***************************************************************************/
3168 void lp_resetnumservices(void)
3169 {
3170         iNumServices = 0;
3171 }
3172
3173 /***************************************************************************
3174 return the max number of services
3175 ***************************************************************************/
3176 int lp_numservices(void)
3177 {
3178         return (iNumServices);
3179 }
3180
3181 /***************************************************************************
3182 Display the contents of the services array in human-readable form.
3183 ***************************************************************************/
3184 void lp_dump(FILE * f, BOOL show_defaults, int maxtoprint)
3185 {
3186         int iService;
3187
3188         if (show_defaults)
3189         {
3190                 defaults_saved = False;
3191         }
3192
3193         dump_globals(f);
3194
3195         dump_a_service(&sDefault, f);
3196
3197         for (iService = 0; iService < maxtoprint; iService++)
3198                 lp_dump_one(f, show_defaults, iService);
3199 }
3200
3201 /***************************************************************************
3202 Display the contents of one service in human-readable form.
3203 ***************************************************************************/
3204 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3205 {
3206         if (VALID(snum))
3207         {
3208                 if (iSERVICE(snum).szService[0] == '\0')
3209                         return;
3210                 dump_a_service(pSERVICE(snum), f);
3211         }
3212 }
3213
3214
3215 /***************************************************************************
3216 Return the number of the service with the given name, or -1 if it doesn't
3217 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3218 getservicebyname()! This works ONLY if all services have been loaded, and
3219 does not copy the found service.
3220 ***************************************************************************/
3221 int lp_servicenumber(char *pszServiceName)
3222 {
3223         int iService;
3224
3225         for (iService = iNumServices - 1; iService >= 0; iService--)
3226                 if (VALID(iService) &&
3227                     strequal(lp_servicename(iService), pszServiceName))
3228                         break;
3229
3230         if (iService < 0)
3231                 DEBUG(7,
3232                       ("lp_servicenumber: couldn't find %s\n",
3233                        pszServiceName));
3234
3235         return (iService);
3236 }
3237
3238 /*******************************************************************
3239   a useful volume label function
3240   ******************************************************************/
3241 char *volume_label(int snum)
3242 {
3243         char *ret = lp_volume(snum);
3244         if (!*ret)
3245                 return (lp_servicename(snum));
3246         return (ret);
3247 }
3248
3249
3250 /*******************************************************************
3251  Set the server type we will announce as via nmbd.
3252 ********************************************************************/
3253 static void set_default_server_announce_type(void)
3254 {
3255         default_server_announce = 0;
3256         default_server_announce |= SV_TYPE_WORKSTATION;
3257         default_server_announce |= SV_TYPE_SERVER;
3258         default_server_announce |= SV_TYPE_SERVER_UNIX;
3259         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3260
3261         switch (lp_announce_as())
3262         {
3263                 case ANNOUNCE_AS_NT_SERVER:
3264                 {
3265                         default_server_announce |= SV_TYPE_SERVER_NT;
3266                         /* fall through... */
3267                 }
3268                 case ANNOUNCE_AS_NT_WORKSTATION:
3269                 {
3270                         default_server_announce |= SV_TYPE_NT;
3271                         break;
3272                 }
3273                 case ANNOUNCE_AS_WIN95:
3274                 {
3275                         default_server_announce |= SV_TYPE_WIN95_PLUS;
3276                         break;
3277                 }
3278                 case ANNOUNCE_AS_WFW:
3279                 {
3280                         default_server_announce |= SV_TYPE_WFW;
3281                         break;
3282                 }
3283                 default:
3284                 {
3285                         break;
3286                 }
3287         }
3288
3289         switch (lp_server_role())
3290         {
3291                 case ROLE_DOMAIN_MEMBER:
3292                 {
3293                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3294                         break;
3295                 }
3296                 case ROLE_DOMAIN_PDC:
3297                 {
3298                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3299                         break;
3300                 }
3301                 case ROLE_DOMAIN_BDC:
3302                 {
3303                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3304                         break;
3305                 }
3306                 case ROLE_STANDALONE:
3307                 default:
3308                 {
3309                         break;
3310                 }
3311         }
3312
3313         if (lp_time_server())
3314         {
3315                 default_server_announce |= SV_TYPE_TIME_SOURCE;
3316         }
3317
3318         if (lp_host_msdfs())
3319         {
3320                 default_server_announce |= SV_TYPE_DFS_SERVER;
3321         }
3322 }
3323
3324 /***********************************************************
3325  returns role of Samba server
3326 ************************************************************/
3327
3328 int lp_server_role(void)
3329 {
3330         return server_role;
3331 }
3332
3333 /***********************************************************
3334  If we are PDC then prefer us as DMB
3335 ************************************************************/
3336
3337 BOOL lp_domain_master(void)
3338 {
3339         if (Globals.bDomainMaster == Auto)
3340         {
3341                 return (lp_server_role() == ROLE_DOMAIN_PDC);
3342         }
3343
3344         return Globals.bDomainMaster;
3345 }
3346
3347 /***********************************************************
3348  If we are DMB then prefer us as LMB
3349 ************************************************************/
3350
3351 BOOL lp_preferred_master(void)
3352 {
3353         if (Globals.bPreferredMaster == Auto)
3354         {
3355                 return (lp_local_master() && lp_domain_master());
3356         }
3357
3358         return Globals.bPreferredMaster;
3359 }
3360
3361
3362
3363 /*******************************************************************
3364 remove a service
3365 ********************************************************************/
3366 void lp_remove_service(int snum)
3367 {
3368         pSERVICE(snum)->valid = False;
3369 }
3370
3371 /*******************************************************************
3372 copy a service
3373 ********************************************************************/
3374 void lp_copy_service(int snum, char *new_name)
3375 {
3376         char *oldname = lp_servicename(snum);
3377         do_section(new_name);
3378         if (snum >= 0)
3379         {
3380                 snum = lp_servicenumber(new_name);
3381                 if (snum >= 0)
3382                         lp_do_parameter(snum, "copy", oldname);
3383         }
3384 }
3385
3386
3387 /*******************************************************************
3388  Get the default server type we will announce as via nmbd.
3389 ********************************************************************/
3390 int lp_default_server_announce(void)
3391 {
3392         return default_server_announce;
3393 }
3394
3395 /*******************************************************************
3396  Split the announce version into major and minor numbers.
3397 ********************************************************************/
3398 int lp_major_announce_version(void)
3399 {
3400         static BOOL got_major = False;
3401         static int major_version = DEFAULT_MAJOR_VERSION;
3402         char *vers;
3403         char *p;
3404
3405         if (got_major)
3406                 return major_version;
3407
3408         got_major = True;
3409         if ((vers = lp_announce_version()) == NULL)
3410                 return major_version;
3411
3412         if ((p = strchr(vers, '.')) == 0)
3413                 return major_version;
3414
3415         *p = '\0';
3416         major_version = atoi(vers);
3417         return major_version;
3418 }
3419
3420 int lp_minor_announce_version(void)
3421 {
3422         static BOOL got_minor = False;
3423         static int minor_version = DEFAULT_MINOR_VERSION;
3424         char *vers;
3425         char *p;
3426
3427         if (got_minor)
3428                 return minor_version;
3429
3430         got_minor = True;
3431         if ((vers = lp_announce_version()) == NULL)
3432                 return minor_version;
3433
3434         if ((p = strchr(vers, '.')) == 0)
3435                 return minor_version;
3436
3437         p++;
3438         minor_version = atoi(p);
3439         return minor_version;
3440 }
3441
3442 /***********************************************************
3443  Set the global name resolution order (used in smbclient).
3444 ************************************************************/
3445
3446 void lp_set_name_resolve_order(char *new_order)
3447 {
3448         Globals.szNameResolveOrder = new_order;
3449 }
3450
3451 /***********************************************************
3452  Functions to return the current security masks/modes. If
3453  set to -1 then return the create mask/mode instead.
3454 ************************************************************/
3455
3456 int lp_security_mask(int snum)
3457 {
3458         int val = _lp_security_mask(snum);
3459         if (val == -1)
3460                 return lp_create_mask(snum);
3461         return val;
3462 }
3463
3464 int lp_force_security_mode(int snum)
3465 {
3466         int val = _lp_force_security_mode(snum);
3467         if (val == -1)
3468                 return lp_force_create_mode(snum);
3469         return val;
3470 }
3471
3472 int lp_dir_security_mask(int snum)
3473 {
3474         int val = _lp_dir_security_mask(snum);
3475         if (val == -1)
3476                 return lp_dir_mask(snum);
3477         return val;
3478 }
3479
3480 int lp_force_dir_security_mode(int snum)
3481 {
3482         int val = _lp_force_dir_security_mode(snum);
3483         if (val == -1)
3484                 return lp_force_dir_mode(snum);
3485         return val;
3486 }
3487
3488 char *lp_printername(int snum)
3489 {
3490         char *ret = _lp_printername(snum);
3491         if (ret == NULL || (ret != NULL && *ret == '\0'))
3492                 ret = lp_servicename(snum);
3493
3494         return ret;
3495 }