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