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