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