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