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