This is how combination of domain logons and security parameter best combine.
[tprouty/samba.git] / source / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Anthony Liguori 2003
12    
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17    
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22    
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55
56 BOOL in_client = False;         /* Not in the client by default */
57 BOOL bLoaded = False;
58
59 extern userdom_struct current_user_info;
60 extern pstring user_socket_options;
61
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
65
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
69
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
73
74 /* some helpful bits */
75 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
76 #define VALID(i) ServicePtrs[i]->valid
77
78 int keepalive = DEFAULT_KEEPALIVE;
79 BOOL use_getwd_cache = True;
80
81 extern int extra_time_offset;
82
83 static BOOL defaults_saved = False;
84
85 typedef struct _param_opt_struct param_opt_struct;
86 struct _param_opt_struct {
87         param_opt_struct *prev, *next;
88         char *key;
89         char *value;
90 };
91
92 /* 
93  * This structure describes global (ie., server-wide) parameters.
94  */
95 typedef struct
96 {
97         char *smb_ports;
98         char *dos_charset;
99         char *unix_charset;
100         char *display_charset;
101         char *szPrintcapname;
102         char *szEnumPortsCommand;
103         char *szAddPrinterCommand;
104         char *szDeletePrinterCommand;
105         char *szOs2DriverMap;
106         char *szLockDir;
107         char *szPidDir;
108         char *szRootdir;
109         char *szDefaultService;
110         char *szDfree;
111         char *szMsgCommand;
112         char *szHostsEquiv;
113         char *szServerString;
114         char *szAutoServices;
115         char *szPasswdProgram;
116         char *szPasswdChat;
117         char *szLogFile;
118         char *szConfigFile;
119         char *szSMBPasswdFile;
120         char *szPrivateDir;
121         char **szPassdbBackend;
122         char **szSamBackend;
123         char **szPreloadModules;
124         char *szPasswordServer;
125         char *szSocketOptions;
126         char *szRealm;
127         char *szADSserver;
128         char *szUsernameMap;
129         char *szLogonScript;
130         char *szLogonPath;
131         char *szLogonDrive;
132         char *szLogonHome;
133         char **szWINSservers;
134         char **szInterfaces;
135         char *szRemoteAnnounce;
136         char *szRemoteBrowseSync;
137         char *szSocketAddress;
138         char *szNISHomeMapName;
139         char *szAnnounceVersion;        /* This is initialised in init_globals */
140         char *szWorkgroup;
141         char *szNetbiosName;
142         char **szNetbiosAliases;
143         char *szNetbiosScope;
144         char *szDomainOtherSIDs;
145         char *szNameResolveOrder;
146         char *szPanicAction;
147         char *szAddUserScript;
148         char *szDelUserScript;
149         char *szAddGroupScript;
150         char *szDelGroupScript;
151         char *szAddUserToGroupScript;
152         char *szDelUserFromGroupScript;
153         char *szSetPrimaryGroupScript;
154         char *szAddMachineScript;
155         char *szShutdownScript;
156         char *szAbortShutdownScript;
157         char *szWINSHook;
158         char *szWINSPartners;
159 #ifdef WITH_UTMP
160         char *szUtmpDir;
161         char *szWtmpDir;
162         BOOL bUtmp;
163 #endif
164         char *szSourceEnv;
165         char *szWinbindUID;
166         char *szWinbindGID;
167         char *szNonUnixAccountRange;
168         int AlgorithmicRidBase;
169         char *szTemplateHomedir;
170         char *szTemplateShell;
171         char *szWinbindSeparator;
172         BOOL bWinbindEnumUsers;
173         BOOL bWinbindEnumGroups;
174         BOOL bWinbindUseDefaultDomain;
175         char *szIDMapBackend;
176         char *szAddShareCommand;
177         char *szChangeShareCommand;
178         char *szDeleteShareCommand;
179         char *szGuestaccount;
180         char *szManglingMethod;
181         int mangle_prefix;
182         int max_log_size;
183         char *szLogLevel;
184         int mangled_stack;
185         int max_xmit;
186         int max_mux;
187         int max_open_files;
188         int pwordlevel;
189         int unamelevel;
190         int deadtime;
191         int maxprotocol;
192         int minprotocol;
193         int security;
194         char **AuthMethods;
195         BOOL paranoid_server_security;
196         int maxdisksize;
197         int lpqcachetime;
198         int iMaxSmbdProcesses;
199         BOOL bDisableSpoolss;
200         int iTotalPrintJobs;
201         int syslog;
202         int os_level;
203         int enhanced_browsing;
204         int max_ttl;
205         int max_wins_ttl;
206         int min_wins_ttl;
207         int ReadSize;
208         int lm_announce;
209         int lm_interval;
210         int announce_as;        /* This is initialised in init_globals */
211         int machine_password_timeout;
212         int change_notify_timeout;
213         int stat_cache_size;
214         int map_to_guest;
215         int min_passwd_length;
216         int oplock_break_wait_time;
217         int winbind_cache_time;
218         int iLockSpinCount;
219         int iLockSpinTime;
220         char *szLdapMachineSuffix;
221         char *szLdapUserSuffix;
222 #ifdef WITH_LDAP_SAMCONFIG
223         int ldap_port;
224         char *szLdapServer;
225 #endif
226         int ldap_ssl;
227         char *szLdapSuffix;
228         char *szLdapFilter;
229         char *szLdapAdminDn;
230         BOOL ldap_trust_ids;
231         char *szAclCompat;
232         int ldap_passwd_sync; 
233         BOOL bMsAddPrinterWizard;
234         BOOL bDNSproxy;
235         BOOL bWINSsupport;
236         BOOL bWINSproxy;
237         BOOL bLocalMaster;
238         BOOL bPreferredMaster;
239         BOOL bDomainMaster;
240         BOOL bDomainLogons;
241         BOOL bEncryptPasswords;
242         BOOL bUpdateEncrypt;
243         BOOL bStripDot;
244         BOOL bNullPasswords;
245         BOOL bObeyPamRestrictions;
246         BOOL bLoadPrinters;
247         BOOL bLargeReadwrite;
248         BOOL bReadRaw;
249         BOOL bWriteRaw;
250         BOOL bReadPrediction;
251         BOOL bReadbmpx;
252         BOOL bSyslogOnly;
253         BOOL bBrowseList;
254         BOOL bNISHomeMap;
255         BOOL bTimeServer;
256         BOOL bBindInterfacesOnly;
257         BOOL bPamPasswordChange;
258         BOOL bUnixPasswdSync;
259         BOOL bPasswdChatDebug;
260         BOOL bTimestampLogs;
261         BOOL bNTSmbSupport;
262         BOOL bNTPipeSupport;
263         BOOL bNTStatusSupport;
264         BOOL bStatCache;
265         BOOL bKernelOplocks;
266         BOOL bAllowTrustedDomains;
267         BOOL bLanmanAuth;
268         BOOL bNTLMAuth;
269         BOOL bUseSpnego;
270         BOOL bClientLanManAuth;
271         BOOL bClientNTLMv2Auth;
272         BOOL bClientUseSpnego;
273         BOOL bDebugHiresTimestamp;
274         BOOL bDebugPid;
275         BOOL bDebugUid;
276         BOOL bHostMSDfs;
277         BOOL bHideLocalUsers;
278         BOOL bUnicode;
279         BOOL bUseMmap;
280         BOOL bHostnameLookups;
281         BOOL bUnixExtensions;
282         BOOL bDisableNetbios;
283         BOOL bKernelChangeNotify;
284         int restrict_anonymous;
285         int name_cache_timeout;
286         BOOL client_signing;
287         param_opt_struct *param_opt;
288 }
289 global;
290
291 static global Globals;
292
293 /* 
294  * This structure describes a single service. 
295  */
296 typedef struct
297 {
298         BOOL valid;
299         BOOL autoloaded;
300         char *szService;
301         char *szPath;
302         char *szUsername;
303         char **szInvalidUsers;
304         char **szValidUsers;
305         char **szAdminUsers;
306         char *szCopy;
307         char *szInclude;
308         char *szPreExec;
309         char *szPostExec;
310         char *szRootPreExec;
311         char *szRootPostExec;
312         char *szPrintcommand;
313         char *szLpqcommand;
314         char *szLprmcommand;
315         char *szLppausecommand;
316         char *szLpresumecommand;
317         char *szQueuepausecommand;
318         char *szQueueresumecommand;
319         char *szPrintername;
320         char *szDontdescend;
321         char **szHostsallow;
322         char **szHostsdeny;
323         char *szMagicScript;
324         char *szMagicOutput;
325         char *szMangledMap;
326         char *szVetoFiles;
327         char *szHideFiles;
328         char *szVetoOplockFiles;
329         char *comment;
330         char *force_user;
331         char *force_group;
332         char **readlist;
333         char **writelist;
334         char **printer_admin;
335         char *volume;
336         char *fstype;
337         char *szVfsObjectFile;
338         char *szVfsOptions;
339         char *szVfsPath;
340         char *szMSDfsProxy;
341         int iMinPrintSpace;
342         int iMaxPrintJobs;
343         int iMaxReportedPrintJobs;
344         int iWriteCacheSize;
345         int iCreate_mask;
346         int iCreate_force_mode;
347         int iSecurity_mask;
348         int iSecurity_force_mode;
349         int iDir_mask;
350         int iDir_force_mode;
351         int iDir_Security_mask;
352         int iDir_Security_force_mode;
353         int iMaxConnections;
354         int iDefaultCase;
355         int iPrinting;
356         int iOplockContentionLimit;
357         int iCSCPolicy;
358         int iBlock_size;
359         BOOL bPreexecClose;
360         BOOL bRootpreexecClose;
361         BOOL bCaseSensitive;
362         BOOL bCasePreserve;
363         BOOL bShortCasePreserve;
364         BOOL bCaseMangle;
365         BOOL bHideDotFiles;
366         BOOL bHideSpecialFiles;
367         BOOL bHideUnReadable;
368         BOOL bHideUnWriteableFiles;
369         BOOL bBrowseable;
370         BOOL bAvailable;
371         BOOL bRead_only;
372         BOOL bNo_set_dir;
373         BOOL bGuest_only;
374         BOOL bGuest_ok;
375         BOOL bPrint_ok;
376         BOOL bMap_system;
377         BOOL bMap_hidden;
378         BOOL bMap_archive;
379         BOOL bLocking;
380         BOOL bStrictLocking;
381         BOOL bPosixLocking;
382         BOOL bShareModes;
383         BOOL bOpLocks;
384         BOOL bLevel2OpLocks;
385         BOOL bOnlyUser;
386         BOOL bMangledNames;
387         BOOL bWidelinks;
388         BOOL bSymlinks;
389         BOOL bSyncAlways;
390         BOOL bStrictAllocate;
391         BOOL bStrictSync;
392         char magic_char;
393         BOOL *copymap;
394         BOOL bDeleteReadonly;
395         BOOL bFakeOplocks;
396         BOOL bDeleteVetoFiles;
397         BOOL bDosFilemode;
398         BOOL bDosFiletimes;
399         BOOL bDosFiletimeResolution;
400         BOOL bFakeDirCreateTimes;
401         BOOL bBlockingLocks;
402         BOOL bInheritPerms;
403         BOOL bInheritACLS;
404         BOOL bMSDfsRoot;
405         BOOL bUseClientDriver;
406         BOOL bDefaultDevmode;
407         BOOL bNTAclSupport;
408         BOOL bUseSendfile;
409         BOOL bProfileAcls;
410         param_opt_struct *param_opt;
411
412         char dummy[3];          /* for alignment */
413 }
414 service;
415
416
417 /* This is a default service used to prime a services structure */
418 static service sDefault = {
419         True,                   /* valid */
420         False,                  /* not autoloaded */
421         NULL,                   /* szService */
422         NULL,                   /* szPath */
423         NULL,                   /* szUsername */
424         NULL,                   /* szInvalidUsers */
425         NULL,                   /* szValidUsers */
426         NULL,                   /* szAdminUsers */
427         NULL,                   /* szCopy */
428         NULL,                   /* szInclude */
429         NULL,                   /* szPreExec */
430         NULL,                   /* szPostExec */
431         NULL,                   /* szRootPreExec */
432         NULL,                   /* szRootPostExec */
433         NULL,                   /* szPrintcommand */
434         NULL,                   /* szLpqcommand */
435         NULL,                   /* szLprmcommand */
436         NULL,                   /* szLppausecommand */
437         NULL,                   /* szLpresumecommand */
438         NULL,                   /* szQueuepausecommand */
439         NULL,                   /* szQueueresumecommand */
440         NULL,                   /* szPrintername */
441         NULL,                   /* szDontdescend */
442         NULL,                   /* szHostsallow */
443         NULL,                   /* szHostsdeny */
444         NULL,                   /* szMagicScript */
445         NULL,                   /* szMagicOutput */
446         NULL,                   /* szMangledMap */
447         NULL,                   /* szVetoFiles */
448         NULL,                   /* szHideFiles */
449         NULL,                   /* szVetoOplockFiles */
450         NULL,                   /* comment */
451         NULL,                   /* force user */
452         NULL,                   /* force group */
453         NULL,                   /* readlist */
454         NULL,                   /* writelist */
455         NULL,                   /* printer admin */
456         NULL,                   /* volume */
457         NULL,                   /* fstype */
458         NULL,                   /* vfs object */
459         NULL,                   /* vfs options */
460         NULL,                   /* vfs path */
461         NULL,                   /* szMSDfsProxy */
462         0,                      /* iMinPrintSpace */
463         1000,                   /* iMaxPrintJobs */
464         0,                      /* iMaxReportedPrintJobs */
465         0,                      /* iWriteCacheSize */
466         0744,                   /* iCreate_mask */
467         0000,                   /* iCreate_force_mode */
468         0777,                   /* iSecurity_mask */
469         0,                      /* iSecurity_force_mode */
470         0755,                   /* iDir_mask */
471         0000,                   /* iDir_force_mode */
472         0777,                   /* iDir_Security_mask */
473         0,                      /* iDir_Security_force_mode */
474         0,                      /* iMaxConnections */
475         CASE_LOWER,             /* iDefaultCase */
476         DEFAULT_PRINTING,       /* iPrinting */
477         2,                      /* iOplockContentionLimit */
478         0,                      /* iCSCPolicy */
479         1024,           /* iBlock_size */
480         False,                  /* bPreexecClose */
481         False,                  /* bRootpreexecClose */
482         False,                  /* case sensitive */
483         True,                   /* case preserve */
484         True,                   /* short case preserve */
485         False,                  /* case mangle */
486         True,                   /* bHideDotFiles */
487         False,                  /* bHideSpecialFiles */
488         False,                  /* bHideUnReadable */
489         False,                  /* bHideUnWriteableFiles */
490         True,                   /* bBrowseable */
491         True,                   /* bAvailable */
492         True,                   /* bRead_only */
493         True,                   /* bNo_set_dir */
494         False,                  /* bGuest_only */
495         False,                  /* bGuest_ok */
496         False,                  /* bPrint_ok */
497         False,                  /* bMap_system */
498         False,                  /* bMap_hidden */
499         True,                   /* bMap_archive */
500         True,                   /* bLocking */
501         True,                   /* bStrictLocking */
502         True,                   /* bPosixLocking */
503         True,                   /* bShareModes */
504         True,                   /* bOpLocks */
505         True,                   /* bLevel2OpLocks */
506         False,                  /* bOnlyUser */
507         True,                   /* bMangledNames */
508         True,                   /* bWidelinks */
509         True,                   /* bSymlinks */
510         False,                  /* bSyncAlways */
511         False,                  /* bStrictAllocate */
512         False,                  /* bStrictSync */
513         '~',                    /* magic char */
514         NULL,                   /* copymap */
515         False,                  /* bDeleteReadonly */
516         False,                  /* bFakeOplocks */
517         False,                  /* bDeleteVetoFiles */
518         False,                  /* bDosFilemode */
519         False,                  /* bDosFiletimes */
520         False,                  /* bDosFiletimeResolution */
521         False,                  /* bFakeDirCreateTimes */
522         True,                   /* bBlockingLocks */
523         False,                  /* bInheritPerms */
524         False,                  /* bInheritACLS */
525         False,                  /* bMSDfsRoot */
526         False,                  /* bUseClientDriver */
527         False,                  /* bDefaultDevmode */
528         True,                   /* bNTAclSupport */
529         False,                  /* bUseSendfile */
530         False,                  /* bProfileAcls */
531         
532         NULL,                   /* Parametric options */
533
534         ""                      /* dummy */
535 };
536
537 /* local variables */
538 static service **ServicePtrs = NULL;
539 static int iNumServices = 0;
540 static int iServiceIndex = 0;
541 static BOOL bInGlobalSection = True;
542 static BOOL bGlobalOnly = False;
543 static int server_role;
544 static int default_server_announce;
545
546 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
547
548 /* prototypes for the special type handlers */
549 static BOOL handle_include(const char *pszParmValue, char **ptr);
550 static BOOL handle_copy(const char *pszParmValue, char **ptr);
551 static BOOL handle_vfs_object(const char *pszParmValue, char **ptr);
552 static BOOL handle_source_env(const char *pszParmValue, char **ptr);
553 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
554 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
555 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
556 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
557 static BOOL handle_debug_list( const char *pszParmValue, char **ptr );
558 static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
559 static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
560 static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
561
562 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
563 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
564 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
565
566 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
567
568 static void set_server_role(void);
569 static void set_default_server_announce_type(void);
570
571 static const struct enum_list enum_protocol[] = {
572         {PROTOCOL_NT1, "NT1"},
573         {PROTOCOL_LANMAN2, "LANMAN2"},
574         {PROTOCOL_LANMAN1, "LANMAN1"},
575         {PROTOCOL_CORE, "CORE"},
576         {PROTOCOL_COREPLUS, "COREPLUS"},
577         {PROTOCOL_COREPLUS, "CORE+"},
578         {-1, NULL}
579 };
580
581 static const struct enum_list enum_security[] = {
582         {SEC_SHARE, "SHARE"},
583         {SEC_USER, "USER"},
584         {SEC_SERVER, "SERVER"},
585         {SEC_DOMAIN, "DOMAIN"},
586 #ifdef HAVE_ADS
587         {SEC_ADS, "ADS"},
588 #endif
589         {-1, NULL}
590 };
591
592 static const struct enum_list enum_printing[] = {
593         {PRINT_SYSV, "sysv"},
594         {PRINT_AIX, "aix"},
595         {PRINT_HPUX, "hpux"},
596         {PRINT_BSD, "bsd"},
597         {PRINT_QNX, "qnx"},
598         {PRINT_PLP, "plp"},
599         {PRINT_LPRNG, "lprng"},
600         {PRINT_SOFTQ, "softq"},
601         {PRINT_CUPS, "cups"},
602         {PRINT_LPRNT, "nt"},
603         {PRINT_LPROS2, "os2"},
604 #ifdef DEVELOPER
605         {PRINT_TEST, "test"},
606         {PRINT_VLP, "vlp"},
607 #endif /* DEVELOPER */
608         {-1, NULL}
609 };
610
611 static const struct enum_list enum_ldap_ssl[] = {
612 #ifdef WITH_LDAP_SAMCONFIG
613         {LDAP_SSL_ON, "Yes"},
614         {LDAP_SSL_ON, "yes"},
615         {LDAP_SSL_ON, "on"},
616         {LDAP_SSL_ON, "On"},
617 #endif
618         {LDAP_SSL_OFF, "no"},
619         {LDAP_SSL_OFF, "No"},
620         {LDAP_SSL_OFF, "off"},
621         {LDAP_SSL_OFF, "Off"},
622         {LDAP_SSL_START_TLS, "start tls"},
623         {LDAP_SSL_START_TLS, "Start_tls"},
624         {-1, NULL}
625 };
626
627 static const struct enum_list enum_ldap_passwd_sync[] = {
628         {LDAP_PASSWD_SYNC_ON, "Yes"},
629         {LDAP_PASSWD_SYNC_ON, "yes"},
630         {LDAP_PASSWD_SYNC_ON, "on"},
631         {LDAP_PASSWD_SYNC_ON, "On"},
632         {LDAP_PASSWD_SYNC_OFF, "no"},
633         {LDAP_PASSWD_SYNC_OFF, "No"},
634         {LDAP_PASSWD_SYNC_OFF, "off"},
635         {LDAP_PASSWD_SYNC_OFF, "Off"},
636 #ifdef LDAP_EXOP_X_MODIFY_PASSWD        
637         {LDAP_PASSWD_SYNC_ONLY, "Only"},
638         {LDAP_PASSWD_SYNC_ONLY, "only"},
639 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */  
640         {-1, NULL}
641 };
642
643 /* Types of machine we can announce as. */
644 #define ANNOUNCE_AS_NT_SERVER 1
645 #define ANNOUNCE_AS_WIN95 2
646 #define ANNOUNCE_AS_WFW 3
647 #define ANNOUNCE_AS_NT_WORKSTATION 4
648
649 static const struct enum_list enum_announce_as[] = {
650         {ANNOUNCE_AS_NT_SERVER, "NT"},
651         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
652         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
653         {ANNOUNCE_AS_WIN95, "win95"},
654         {ANNOUNCE_AS_WFW, "WfW"},
655         {-1, NULL}
656 };
657
658 static const struct enum_list enum_case[] = {
659         {CASE_LOWER, "lower"},
660         {CASE_UPPER, "upper"},
661         {-1, NULL}
662 };
663
664 static const struct enum_list enum_bool_auto[] = {
665         {False, "No"},
666         {False, "False"},
667         {False, "0"},
668         {True, "Yes"},
669         {True, "True"},
670         {True, "1"},
671         {Auto, "Auto"},
672         {-1, NULL}
673 };
674
675 /* Client-side offline caching policy types */
676 #define CSC_POLICY_MANUAL 0
677 #define CSC_POLICY_DOCUMENTS 1
678 #define CSC_POLICY_PROGRAMS 2
679 #define CSC_POLICY_DISABLE 3
680
681 static const struct enum_list enum_csc_policy[] = {
682         {CSC_POLICY_MANUAL, "manual"},
683         {CSC_POLICY_DOCUMENTS, "documents"},
684         {CSC_POLICY_PROGRAMS, "programs"},
685         {CSC_POLICY_DISABLE, "disable"},
686         {-1, NULL}
687 };
688
689 /* 
690    Do you want session setups at user level security with a invalid
691    password to be rejected or allowed in as guest? WinNT rejects them
692    but it can be a pain as it means "net view" needs to use a password
693
694    You have 3 choices in the setting of map_to_guest:
695
696    "Never" means session setups with an invalid password
697    are rejected. This is the default.
698
699    "Bad User" means session setups with an invalid password
700    are rejected, unless the username does not exist, in which case it
701    is treated as a guest login
702
703    "Bad Password" means session setups with an invalid password
704    are treated as a guest login
705
706    Note that map_to_guest only has an effect in user or server
707    level security.
708 */
709
710 static const struct enum_list enum_map_to_guest[] = {
711         {NEVER_MAP_TO_GUEST, "Never"},
712         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
713         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
714         {-1, NULL}
715 };
716
717 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
718  *
719  * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
720  * is implied in current control logic. This may change at some later time. A
721  * flag value of 0 means - show as development option only.
722  *
723  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
724  * screen in SWAT. This is used to exclude parameters as well as to squash all
725  * parameters that have been duplicated by pseudonyms.
726  */
727 static struct parm_struct parm_table[] = {
728         {"Base Options", P_SEP, P_SEPARATOR},
729
730         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
731         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
734         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
735         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
736         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
737         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
738         {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
739         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
740         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
741         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED  | FLAG_DEVELOPER},
743         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
744         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
745
746         {"Security Options", P_SEP, P_SEPARATOR},
747         
748         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
749         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
750         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
751         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
752         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753         {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
754         {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755         {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756         {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
758         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
761         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763         {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764         {"sam backend", P_LIST, P_GLOBAL, &Globals.szSamBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765         {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
770         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
771         
772         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEVELOPER},
777         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
781         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
783         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
784         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
785         
786         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
787         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
788         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
789         
790         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
791         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
792         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
793         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
794         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
795         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
796         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
797         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
798         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
799         
800         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
801         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
802         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
803         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
804         
805         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
806         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
807         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
808         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
809         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
810         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
811         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
812         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
813         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
814         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
815         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
816         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
817         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
818         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
819
820         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
821         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
822         
823         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
824         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
825         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
826         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
827         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
828         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
829
830         {"Logging Options", P_SEP, P_SEPARATOR},
831
832         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
833         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
834         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
835         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
836         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
837         
838         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
839         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
840         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER},
841         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER},
842         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER},
843         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER},
844         
845         {"Protocol Options", P_SEP, P_SEPARATOR},
846         
847         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
848         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER},
849         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
850         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
851         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
852         {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
853         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER},
854         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
855         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
856         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
857         
858         {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
859         {"nt acl support", P_BOOL,  P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
860         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
861         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
862         {"profile acls", P_BOOL,  P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE  | FLAG_ADVANCED | FLAG_WIZARD},
863         
864         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
865         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
866         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
867         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
868         
869         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
870         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
871         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
872         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
873         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
874         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
875         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
876         {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
877         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
878
879         {"Tuning Options", P_SEP, P_SEPARATOR},
880         
881         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
882         {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER},
883         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER},
884         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER},
885         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
886         {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER},
887         
888         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
889         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER},
890         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
891         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
892         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER},
893         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
894         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
895         {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER},
896         
897         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER},
898         {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, FLAG_DEVELOPER},
899         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
900         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
901         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
902         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
903         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
904         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
905         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
906
907         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
908
909         {"Printing Options", P_SEP, P_SEPARATOR},
910         
911         {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
912         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT},
913         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
914         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
915         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
916         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
917         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
918         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
919         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
920         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
921         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
922         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
923         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
924         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
925         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
926         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
927         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
928
929         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
930         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
931         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
932         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
933         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
934         
935         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
936         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
937         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
938         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
939
940         {"Filename Handling", P_SEP, P_SEPARATOR},
941         {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
942         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
943         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
944         
945         {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
946         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
947         {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
948         {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
949         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
950         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
951         {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
952         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
953         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
954         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
955         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
956         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
957         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
958         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
959         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
960         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
961         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
962         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
963         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
964         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
965         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
966         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER},
967
968         {"Domain Options", P_SEP, P_SEPARATOR},
969         
970         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
971
972         {"Logon Options", P_SEP, P_SEPARATOR},
973
974         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
975         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
976         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
977         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
978         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
979         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
980         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
981         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
982         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
983         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
984
985         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
986         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
987         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
988         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
989         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
990
991         {"Browse Options", P_SEP, P_SEPARATOR},
992         
993         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
994         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
995         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
996         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
997         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
998         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
999         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1000         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1001         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
1002         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1003         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
1004
1005         {"WINS Options", P_SEP, P_SEPARATOR},
1006         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1007         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1008         
1009         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1010         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1011         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1012         {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1013
1014         {"Locking Options", P_SEP, P_SEPARATOR},
1015         
1016         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1017         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
1018         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
1019         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
1020         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1021         {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
1022         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
1023         
1024         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1025         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1026         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
1027         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1028         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1029         {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1030         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
1031
1032         {"Ldap Options", P_SEP, P_SEPARATOR},
1033         
1034 #ifdef WITH_LDAP_SAMCONFIG
1035         {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
1036         {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 
1037 #endif
1038         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1039         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1040         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1041         {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1042         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1043         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
1044         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
1045         {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1046
1047         {"Miscellaneous Options", P_SEP, P_SEPARATOR},
1048         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1049         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1050         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1051         
1052         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1053         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1054         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1055         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1056         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1057         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
1058 #ifdef WITH_UTMP
1059         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1060         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1061         {"utmp",          P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1062 #endif
1063         
1064         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1065         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL,  FLAG_DEVELOPER},
1066         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1067         {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1068         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1069         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1070         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
1071         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1072         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1073         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1074         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1075         
1076         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1077         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1078         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1079         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1080         
1081         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
1082         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1083         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1084         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
1085         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1086         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1087         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
1088         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
1089         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
1090         {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1091         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1092         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1093         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
1094         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
1095         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
1096         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1097         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1098         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1099         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1100
1101         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1102         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1103         {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1104
1105         {"VFS module options", P_SEP, P_SEPARATOR},
1106         
1107         {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE},
1108         {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
1109         {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
1110
1111         
1112         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
1113         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
1114         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1115
1116         {"Winbind options", P_SEP, P_SEPARATOR},
1117
1118         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1119         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1120         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1121         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1122         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1123         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1124         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1125         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1126         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1127
1128         {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1129 };
1130
1131 /***************************************************************************
1132  Initialise the sDefault parameter structure for the printer values.
1133 ***************************************************************************/
1134
1135 static void init_printer_values(void)
1136 {
1137         /* choose defaults depending on the type of printing */
1138         switch (sDefault.iPrinting) {
1139                 case PRINT_BSD:
1140                 case PRINT_AIX:
1141                 case PRINT_LPRNT:
1142                 case PRINT_LPROS2:
1143                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1144                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1145                         string_set(&sDefault.szPrintcommand,
1146                                    "lpr -r -P'%p' %s");
1147                         break;
1148
1149                 case PRINT_LPRNG:
1150                 case PRINT_PLP:
1151                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1152                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1153                         string_set(&sDefault.szPrintcommand,
1154                                    "lpr -r -P'%p' %s");
1155                         string_set(&sDefault.szQueuepausecommand,
1156                                    "lpc stop '%p'");
1157                         string_set(&sDefault.szQueueresumecommand,
1158                                    "lpc start '%p'");
1159                         string_set(&sDefault.szLppausecommand,
1160                                    "lpc hold '%p' %j");
1161                         string_set(&sDefault.szLpresumecommand,
1162                                    "lpc release '%p' %j");
1163                         break;
1164
1165                 case PRINT_CUPS:
1166 #ifdef HAVE_CUPS
1167                         string_set(&sDefault.szLpqcommand, "");
1168                         string_set(&sDefault.szLprmcommand, "");
1169                         string_set(&sDefault.szPrintcommand, "");
1170                         string_set(&sDefault.szLppausecommand, "");
1171                         string_set(&sDefault.szLpresumecommand, "");
1172                         string_set(&sDefault.szQueuepausecommand, "");
1173                         string_set(&sDefault.szQueueresumecommand, "");
1174
1175                         string_set(&Globals.szPrintcapname, "cups");
1176 #else
1177                         string_set(&sDefault.szLpqcommand,
1178                                    "/usr/bin/lpstat -o '%p'");
1179                         string_set(&sDefault.szLprmcommand,
1180                                    "/usr/bin/cancel '%p-%j'");
1181                         string_set(&sDefault.szPrintcommand,
1182                                    "/usr/bin/lp -d '%p' %s; rm %s");
1183                         string_set(&sDefault.szLppausecommand,
1184                                    "lp -i '%p-%j' -H hold");
1185                         string_set(&sDefault.szLpresumecommand,
1186                                    "lp -i '%p-%j' -H resume");
1187                         string_set(&sDefault.szQueuepausecommand,
1188                                    "/usr/bin/disable '%p'");
1189                         string_set(&sDefault.szQueueresumecommand,
1190                                    "/usr/bin/enable '%p'");
1191                         string_set(&Globals.szPrintcapname, "lpstat");
1192 #endif /* HAVE_CUPS */
1193                         break;
1194
1195                 case PRINT_SYSV:
1196                 case PRINT_HPUX:
1197                         string_set(&sDefault.szLpqcommand, "lpstat -o%p");
1198                         string_set(&sDefault.szLprmcommand, "cancel %p-%j");
1199                         string_set(&sDefault.szPrintcommand,
1200                                    "lp -c -d%p %s; rm %s");
1201                         string_set(&sDefault.szQueuepausecommand,
1202                                    "disable %p");
1203                         string_set(&sDefault.szQueueresumecommand,
1204                                    "enable %p");
1205 #ifndef HPUX
1206                         string_set(&sDefault.szLppausecommand,
1207                                    "lp -i %p-%j -H hold");
1208                         string_set(&sDefault.szLpresumecommand,
1209                                    "lp -i %p-%j -H resume");
1210 #endif /* HPUX */
1211                         break;
1212
1213                 case PRINT_QNX:
1214                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1215                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1216                         string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
1217                         break;
1218
1219                 case PRINT_SOFTQ:
1220                         string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
1221                         string_set(&sDefault.szLprmcommand,
1222                                    "qstat -s -j%j -c");
1223                         string_set(&sDefault.szPrintcommand,
1224                                    "lp -d%p -s %s; rm %s");
1225                         string_set(&sDefault.szLppausecommand,
1226                                    "qstat -s -j%j -h");
1227                         string_set(&sDefault.szLpresumecommand,
1228                                    "qstat -s -j%j -r");
1229                         break;
1230 #ifdef DEVELOPER
1231         case PRINT_TEST:
1232         case PRINT_VLP:
1233                 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
1234                 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
1235                 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
1236                 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
1237                 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
1238                 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
1239                 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
1240                 break;
1241 #endif /* DEVELOPER */
1242
1243         }
1244 }
1245
1246 /***************************************************************************
1247  Initialise the global parameter structure.
1248 ***************************************************************************/
1249
1250 static void init_globals(void)
1251 {
1252         static BOOL done_init = False;
1253         pstring s;
1254
1255         if (!done_init) {
1256                 int i;
1257                 memset((void *)&Globals, '\0', sizeof(Globals));
1258
1259                 for (i = 0; parm_table[i].label; i++)
1260                         if ((parm_table[i].type == P_STRING ||
1261                              parm_table[i].type == P_USTRING) &&
1262                             parm_table[i].ptr)
1263                                 string_set(parm_table[i].ptr, "");
1264
1265                 string_set(&sDefault.fstype, FSTYPE_STRING);
1266
1267                 init_printer_values();
1268
1269                 done_init = True;
1270         }
1271
1272
1273         DEBUG(3, ("Initialising global parameters\n"));
1274
1275         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1276         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1277
1278         /* use the new 'hash2' method by default, with a prefix of 1 */
1279         string_set(&Globals.szManglingMethod, "hash2");
1280         Globals.mangle_prefix = 1;
1281
1282         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1283
1284         /* using UTF8 by default allows us to support all chars */
1285         string_set(&Globals.unix_charset, "UTF8");
1286
1287         /* Use codepage 850 as a default for the dos character set */
1288         string_set(&Globals.dos_charset, "CP850");
1289
1290         /*
1291          * Allow the default PASSWD_CHAT to be overridden in local.h.
1292          */
1293         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1294         
1295         set_global_myname(myhostname());
1296         string_set(&Globals.szNetbiosName,global_myname());
1297
1298         set_global_myworkgroup(WORKGROUP);
1299         string_set(&Globals.szWorkgroup, lp_workgroup());
1300         
1301         string_set(&Globals.szPasswdProgram, "");
1302         string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
1303         string_set(&Globals.szPidDir, dyn_PIDDIR);
1304         string_set(&Globals.szLockDir, dyn_LOCKDIR);
1305         string_set(&Globals.szSocketAddress, "0.0.0.0");
1306         pstrcpy(s, "Samba ");
1307         pstrcat(s, VERSION);
1308         string_set(&Globals.szServerString, s);
1309         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1310                  DEFAULT_MINOR_VERSION);
1311         string_set(&Globals.szAnnounceVersion, s);
1312
1313         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1314
1315         string_set(&Globals.szLogonDrive, "");
1316         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1317         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1318         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1319
1320         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1321         string_set(&Globals.szPasswordServer, "*");
1322
1323         Globals.AlgorithmicRidBase = BASE_RID;
1324
1325         Globals.bLoadPrinters = True;
1326         Globals.mangled_stack = 50;
1327         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1328         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1329         Globals.max_xmit = 0x4104;
1330         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1331         Globals.lpqcachetime = 10;
1332         Globals.bDisableSpoolss = False;
1333         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1334         Globals.iTotalPrintJobs = 0;  /* no limit specified */
1335         Globals.pwordlevel = 0;
1336         Globals.unamelevel = 0;
1337         Globals.deadtime = 0;
1338         Globals.bLargeReadwrite = True;
1339         Globals.max_log_size = 5000;
1340         Globals.max_open_files = MAX_OPEN_FILES;
1341         Globals.maxprotocol = PROTOCOL_NT1;
1342         Globals.minprotocol = PROTOCOL_CORE;
1343         Globals.security = SEC_USER;
1344         Globals.paranoid_server_security = True;
1345         Globals.bEncryptPasswords = True;
1346         Globals.bUpdateEncrypt = False;
1347         Globals.bReadRaw = True;
1348         Globals.bWriteRaw = True;
1349         Globals.bReadPrediction = False;
1350         Globals.bReadbmpx = False;
1351         Globals.bNullPasswords = False;
1352         Globals.bObeyPamRestrictions = False;
1353         Globals.bStripDot = False;
1354         Globals.syslog = 1;
1355         Globals.bSyslogOnly = False;
1356         Globals.bTimestampLogs = True;
1357         string_set(&Globals.szLogLevel, "0");
1358         Globals.bDebugHiresTimestamp = False;
1359         Globals.bDebugPid = False;
1360         Globals.bDebugUid = False;
1361         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1362         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1363         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1364         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1365         Globals.change_notify_timeout = 60;     /* 1 minute default. */
1366         Globals.bKernelChangeNotify = True;     /* On if we have it. */
1367         Globals.ReadSize = 16 * 1024;
1368         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1369         Globals.lm_interval = 60;
1370         Globals.stat_cache_size = 50;   /* Number of stat translations we'll keep */
1371         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1372 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1373         Globals.bNISHomeMap = False;
1374 #ifdef WITH_NISPLUS_HOME
1375         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1376 #else
1377         string_set(&Globals.szNISHomeMapName, "auto.home");
1378 #endif
1379 #endif
1380         Globals.bTimeServer = False;
1381         Globals.bBindInterfacesOnly = False;
1382         Globals.bUnixPasswdSync = False;
1383         Globals.bPamPasswordChange = False;
1384         Globals.bPasswdChatDebug = False;
1385         Globals.bUnicode = True;        /* Do unicode on the wire by default */
1386         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1387         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1388         Globals.bStatCache = True;      /* use stat cache by default */
1389         Globals.restrict_anonymous = 0;
1390         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
1391         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
1392         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1393         
1394         Globals.map_to_guest = 0;       /* By Default, "Never" */
1395         Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
1396         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1397         Globals.enhanced_browsing = True; 
1398         Globals.iLockSpinCount = 3; /* Try 2 times. */
1399         Globals.iLockSpinTime = 10; /* usec. */
1400 #ifdef MMAP_BLACKLIST
1401         Globals.bUseMmap = False;
1402 #else
1403         Globals.bUseMmap = True;
1404 #endif
1405         Globals.bUnixExtensions = False;
1406
1407         /* hostname lookups can be very expensive and are broken on
1408            a large number of sites (tridge) */
1409         Globals.bHostnameLookups = False;
1410
1411 #ifdef WITH_LDAP_SAMCONFIG
1412         string_set(&Globals.szLdapServer, "localhost");
1413         Globals.ldap_port = 636;
1414         Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1415 #else
1416         Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1417 #endif /* WITH_LDAP_SAMCONFIG */
1418
1419         string_set(&Globals.szLdapSuffix, "");
1420         string_set(&Globals.szLdapMachineSuffix, "");
1421         string_set(&Globals.szLdapUserSuffix, "");
1422
1423         string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1424         string_set(&Globals.szLdapAdminDn, "");
1425         Globals.ldap_ssl = LDAP_SSL_ON;
1426         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1427
1428 /* these parameters are set to defaults that are more appropriate
1429    for the increasing samba install base:
1430
1431    as a member of the workgroup, that will possibly become a
1432    _local_ master browser (lm = True).  this is opposed to a forced
1433    local master browser startup (pm = True).
1434
1435    doesn't provide WINS server service by default (wsupp = False),
1436    and doesn't provide domain master browser services by default, either.
1437
1438 */
1439
1440         Globals.bMsAddPrinterWizard = True;
1441         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1442         Globals.os_level = 20;
1443         Globals.bLocalMaster = True;
1444         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1445         Globals.bDomainLogons = False;
1446         Globals.bBrowseList = True;
1447         Globals.bWINSsupport = False;
1448         Globals.bWINSproxy = False;
1449
1450         Globals.bDNSproxy = True;
1451
1452         /* this just means to use them if they exist */
1453         Globals.bKernelOplocks = True;
1454
1455         Globals.bAllowTrustedDomains = True;
1456
1457         string_set(&Globals.szTemplateShell, "/bin/false");
1458         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1459         string_set(&Globals.szWinbindSeparator, "\\");
1460         string_set(&Globals.szAclCompat, "");
1461
1462         Globals.winbind_cache_time = 15;
1463         Globals.bWinbindEnumUsers = True;
1464         Globals.bWinbindEnumGroups = True;
1465         Globals.bWinbindUseDefaultDomain = False;
1466
1467         string_set(&Globals.szIDMapBackend, "tdb");
1468
1469         Globals.name_cache_timeout = 660; /* In seconds */
1470
1471         Globals.bUseSpnego = True;
1472         Globals.bClientUseSpnego = True;
1473
1474         string_set(&Globals.smb_ports, SMB_PORTS);
1475 }
1476
1477 static TALLOC_CTX *lp_talloc;
1478
1479 /******************************************************************* a
1480  Free up temporary memory - called from the main loop.
1481 ********************************************************************/
1482
1483 void lp_talloc_free(void)
1484 {
1485         if (!lp_talloc)
1486                 return;
1487         talloc_destroy(lp_talloc);
1488         lp_talloc = NULL;
1489 }
1490
1491 /*******************************************************************
1492  Convenience routine to grab string parameters into temporary memory
1493  and run standard_sub_basic on them. The buffers can be written to by
1494  callers without affecting the source string.
1495 ********************************************************************/
1496
1497 static char *lp_string(const char *s)
1498 {
1499         size_t len = s ? strlen(s) : 0;
1500         char *ret;
1501
1502         /* The follow debug is useful for tracking down memory problems
1503            especially if you have an inner loop that is calling a lp_*()
1504            function that returns a string.  Perhaps this debug should be
1505            present all the time? */
1506
1507 #if 0
1508         DEBUG(10, ("lp_string(%s)\n", s));
1509 #endif
1510
1511         if (!lp_talloc)
1512                 lp_talloc = talloc_init("lp_talloc");
1513
1514         ret = (char *)talloc(lp_talloc, len + 100);     /* leave room for substitution */
1515
1516         if (!ret)
1517                 return NULL;
1518
1519         /* Note: StrnCpy touches len+1 bytes, but we allocate 100
1520          * extra bytes so we're OK. */
1521
1522         if (!s)
1523                 *ret = 0;
1524         else
1525                 StrnCpy(ret, s, len);
1526
1527         if (trim_string(ret, "\"", "\"")) {
1528                 if (strchr(ret,'"') != NULL)
1529                         StrnCpy(ret, s, len);
1530         }
1531
1532         standard_sub_basic(current_user_info.smb_name,ret,len+100);
1533         return (ret);
1534 }
1535
1536 /*
1537    In this section all the functions that are used to access the 
1538    parameters from the rest of the program are defined 
1539 */
1540
1541 #define FN_GLOBAL_STRING(fn_name,ptr) \
1542  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1543 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1544  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1545 #define FN_GLOBAL_LIST(fn_name,ptr) \
1546  const char **fn_name(void) {return(*(const char ***)(ptr));}
1547 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1548  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1549 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1550  char fn_name(void) {return(*(char *)(ptr));}
1551 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1552  int fn_name(void) {return(*(int *)(ptr));}
1553
1554 #define FN_LOCAL_STRING(fn_name,val) \
1555  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1556 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1557  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1558 #define FN_LOCAL_LIST(fn_name,val) \
1559  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1560 #define FN_LOCAL_BOOL(fn_name,val) \
1561  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1562 #define FN_LOCAL_CHAR(fn_name,val) \
1563  char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1564 #define FN_LOCAL_INTEGER(fn_name,val) \
1565  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1566
1567 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1568 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1569 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1570 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1571 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1572 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1573 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1574 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1575 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1576 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1577 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1578 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1579 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1580 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1581 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1582 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1583 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1584 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1585 #ifdef WITH_UTMP
1586 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1587 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1588 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1589 #endif
1590 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1591 FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
1592 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1593 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1594 FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1595 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1596 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1597 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1598 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1599 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1600 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1601 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1602 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1603 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1604 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1605 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1606 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1607 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1608 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1609 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1610 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1611 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1612 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1613 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1614 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1615 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1616 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1617 FN_GLOBAL_LIST(lp_sam_backend, &Globals.szSamBackend)
1618 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1619 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1620 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1621 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1622
1623 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1624 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1625 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1626 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1627 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1628 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1629
1630 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1631
1632 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1633 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1634
1635 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1636 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1637 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1638 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1639 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1640 FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1641 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1642 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1643 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1644 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1645
1646 #ifdef WITH_LDAP_SAMCONFIG
1647 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1648 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1649 #endif
1650 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1651 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1652 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1653 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1654 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1655 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1656 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1657 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1658 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1659 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1660 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1661
1662 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1663 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1664 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1665 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1666 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1667 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1668 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1669 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1670 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1671 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
1672 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1673 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1674 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1675 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1676 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1677 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1678 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
1679 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1680 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1681 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1682 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1683 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1684 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1685 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1686 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1687 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1688 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1689 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1690 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1691 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1692 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1693 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1694 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1695 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1696 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1697 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1698 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1699 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1700 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1701 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1702 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1703 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1704 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1705 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1706 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1707 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1708 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1709 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1710 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1711 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1712 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1713 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1714 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1715 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1716 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1717 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1718 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1719 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1720 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1721 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1722 FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
1723 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1724 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1725 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1726 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1727 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1728 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1729 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1730 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1731 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1732 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1733 FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
1734 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1735 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1736 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1737 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1738 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1739 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1740 FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
1741 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1742 FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1743 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1744 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1745 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1746 FN_LOCAL_STRING(lp_preexec, szPreExec)
1747 FN_LOCAL_STRING(lp_postexec, szPostExec)
1748 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1749 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1750 FN_LOCAL_STRING(lp_servicename, szService)
1751 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1752 FN_LOCAL_STRING(lp_pathname, szPath)
1753 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1754 FN_LOCAL_STRING(lp_username, szUsername)
1755 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1756 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1757 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1758 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1759 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1760 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1761 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1762 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1763 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1764 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1765 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1766 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1767 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1768 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1769 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1770 FN_LOCAL_STRING(lp_comment, comment)
1771 FN_LOCAL_STRING(lp_force_user, force_user)
1772 FN_LOCAL_STRING(lp_force_group, force_group)
1773 FN_LOCAL_LIST(lp_readlist, readlist)
1774 FN_LOCAL_LIST(lp_writelist, writelist)
1775 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1776 FN_LOCAL_STRING(lp_fstype, fstype)
1777 FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
1778 FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
1779 FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
1780 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1781 static FN_LOCAL_STRING(lp_volume, volume)
1782 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1783 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1784 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1785 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1786 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1787 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1788 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1789 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1790 FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
1791 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1792 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1793 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
1794 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1795 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1796 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
1797 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
1798 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1799 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1800 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1801 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1802 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1803 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1804 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1805 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1806 FN_LOCAL_BOOL(lp_locking, bLocking)
1807 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1808 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1809 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1810 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1811 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1812 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1813 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1814 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1815 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1816 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1817 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
1818 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1819 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1820 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1821 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1822 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1823 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
1824 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1825 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1826 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1827 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1828 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1829 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
1830 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
1831 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
1832 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
1833 FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
1834 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
1835 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1836 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1837 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
1838 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
1839 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1840 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1841 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
1842 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
1843 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1844 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1845 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1846 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1847 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
1848 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1849 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1850 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1851 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
1852 FN_LOCAL_CHAR(lp_magicchar, magic_char)
1853 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1854 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1855 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1856 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1857 FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
1858
1859 /* local prototypes */
1860
1861 static int map_parameter(const char *pszParmName);
1862 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1863 static int getservicebyname(const char *pszServiceName,
1864                             service * pserviceDest);
1865 static void copy_service(service * pserviceDest,
1866                          service * pserviceSource, BOOL *pcopymapDest);
1867 static BOOL service_ok(int iService);
1868 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
1869 static BOOL do_section(const char *pszSectionName);
1870 static void init_copymap(service * pservice);
1871
1872 /* This is a helper function for parametrical options support. */
1873 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1874 /* Actual parametrical functions are quite simple */
1875 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1876 {
1877         char* vfskey;
1878         param_opt_struct *data;
1879         
1880         if (lookup_service >= iNumServices) return NULL;
1881         
1882         data = (lookup_service < 0) ? 
1883                 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1884     
1885         asprintf(&vfskey, "%s:%s", type, option);
1886         while (data) {
1887                 if (strcmp(data->key, vfskey) == 0) {
1888                         string_free(&vfskey);
1889                         return data->value;
1890                 }
1891                 data = data->next;
1892         }
1893
1894         if (lookup_service >= 0) {
1895                 /* Try to fetch the same option but from globals */
1896                 /* but only if we are not already working with Globals */
1897                 data = Globals.param_opt;
1898                 while (data) {
1899                         if (strcmp(data->key, vfskey) == 0) {
1900                                 string_free(&vfskey);
1901                                 return data->value;
1902                         }
1903                         data = data->next;
1904                 }
1905         }
1906
1907         string_free(&vfskey);
1908         
1909         return NULL;
1910 }
1911
1912
1913 /*******************************************************************
1914 convenience routine to return int parameters.
1915 ********************************************************************/
1916 static int lp_int(const char *s)
1917 {
1918
1919         if (!s) {
1920                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1921                 return (-1);
1922         }
1923
1924         return atoi(s); 
1925 }
1926
1927 /*******************************************************************
1928 convenience routine to return unsigned long parameters.
1929 ********************************************************************/
1930 static int lp_ulong(const char *s)
1931 {
1932
1933         if (!s) {
1934                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1935                 return (-1);
1936         }
1937
1938         return strtoul(s, NULL, 10);
1939 }
1940
1941 /*******************************************************************
1942 convenience routine to return boolean parameters.
1943 ********************************************************************/
1944 static BOOL lp_bool(const char *s)
1945 {
1946         BOOL ret = False;
1947
1948         if (!s) {
1949                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1950                 return False;
1951         }
1952         
1953         if (!set_boolean(&ret,s)) {
1954                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1955                 return False;
1956         }
1957
1958         return ret;
1959 }
1960
1961 /*******************************************************************
1962 convenience routine to return enum parameters.
1963 ********************************************************************/
1964 static int lp_enum(const char *s,const struct enum_list *_enum)
1965 {
1966         int i;
1967
1968         if (!s || !_enum) {
1969                 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1970                 return False;
1971         }
1972         
1973         for (i=0; _enum[i].name; i++) {
1974                 if (strcasecmp(_enum[i].name,s)==0)
1975                         return _enum[i].value;
1976         }
1977
1978         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1979         return (-1);
1980 }
1981
1982 /* Return parametric option from a given service. Type is a part of option before ':' */
1983 /* Parametric option has following syntax: 'Type: option = value' */
1984 /* Returned value is allocated in 'lp_talloc' context */
1985
1986 char *lp_parm_string(int lookup_service, const char *type, const char *option)
1987 {
1988         const char *value = get_parametrics(lookup_service, type, option);
1989         
1990         if (value)
1991                 return lp_string(value);
1992
1993         return NULL;
1994 }
1995
1996 /* Return parametric option from a given service. Type is a part of option before ':' */
1997 /* Parametric option has following syntax: 'Type: option = value' */
1998 /* Returned value is allocated in 'lp_talloc' context */
1999
2000 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
2001                            const char *separator)
2002 {
2003         const char *value = get_parametrics(lookup_service, type, option);
2004         
2005         if (value)
2006                 return str_list_make(value, separator);
2007
2008         return NULL;
2009 }
2010
2011 /* Return parametric option from a given service. Type is a part of option before ':' */
2012 /* Parametric option has following syntax: 'Type: option = value' */
2013
2014 int lp_parm_int(int lookup_service, const char *type, const char *option)
2015 {
2016         const char *value = get_parametrics(lookup_service, type, option);
2017         
2018         if (value)
2019                 return lp_int(value);
2020
2021         return (-1);
2022 }
2023
2024 /* Return parametric option from a given service. Type is a part of option before ':' */
2025 /* Parametric option has following syntax: 'Type: option = value' */
2026
2027 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
2028 {
2029         const char *value = get_parametrics(lookup_service, type, option);
2030         
2031         if (value)
2032                 return lp_ulong(value);
2033
2034         return (0);
2035 }
2036
2037 /* Return parametric option from a given service. Type is a part of option before ':' */
2038 /* Parametric option has following syntax: 'Type: option = value' */
2039
2040 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option)
2041 {
2042         const char *value = get_parametrics(lookup_service, type, option);
2043         
2044         if (value)
2045                 return lp_bool(value);
2046
2047         return False;
2048 }
2049
2050 /* Return parametric option from a given service. Type is a part of option before ':' */
2051 /* Parametric option has following syntax: 'Type: option = value' */
2052
2053 int lp_parm_enum(int lookup_service, const char *type, const char *option,
2054                  const struct enum_list *_enum)
2055 {
2056         const char *value = get_parametrics(lookup_service, type, option);
2057         
2058         if (value)
2059                 return lp_enum(value, _enum);
2060
2061         return (-1);
2062 }
2063
2064
2065 /***************************************************************************
2066  Initialise a service to the defaults.
2067 ***************************************************************************/
2068
2069 static void init_service(service * pservice)
2070 {
2071         memset((char *)pservice, '\0', sizeof(service));
2072         copy_service(pservice, &sDefault, NULL);
2073 }
2074
2075 /***************************************************************************
2076  Free the dynamically allocated parts of a service struct.
2077 ***************************************************************************/
2078
2079 static void free_service(service *pservice)
2080 {
2081         int i;
2082         param_opt_struct *data, *pdata;
2083         if (!pservice)
2084                 return;
2085
2086         if (pservice->szService)
2087                 DEBUG(5, ("free_service: Freeing service %s\n",
2088                        pservice->szService));
2089
2090         string_free(&pservice->szService);
2091         SAFE_FREE(pservice->copymap);
2092
2093         for (i = 0; parm_table[i].label; i++) {
2094                 if ((parm_table[i].type == P_STRING ||
2095                      parm_table[i].type == P_USTRING) &&
2096                     parm_table[i].class == P_LOCAL)
2097                         string_free((char **)
2098                                     (((char *)pservice) +
2099                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2100                 else if (parm_table[i].type == P_LIST &&
2101                          parm_table[i].class == P_LOCAL)
2102                              str_list_free((char ***)
2103                                             (((char *)pservice) +
2104                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
2105         }
2106                                 
2107         DEBUG(5,("Freeing parametrics:\n"));
2108         data = pservice->param_opt;
2109         while (data) {
2110                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2111                 string_free(&data->key);
2112                 string_free(&data->value);
2113                 pdata = data->next;
2114                 SAFE_FREE(data);
2115                 data = pdata;
2116         }
2117
2118         ZERO_STRUCTP(pservice);
2119 }
2120
2121 /***************************************************************************
2122  Add a new service to the services array initialising it with the given 
2123  service. 
2124 ***************************************************************************/
2125
2126 static int add_a_service(const service *pservice, const char *name)
2127 {
2128         int i;
2129         service tservice;
2130         int num_to_alloc = iNumServices + 1;
2131         param_opt_struct *data, *pdata;
2132
2133         tservice = *pservice;
2134
2135         /* it might already exist */
2136         if (name) {
2137                 i = getservicebyname(name, NULL);
2138                 if (i >= 0) {
2139                         /* Clean all parametric options for service */
2140                         /* They will be added during parsing again */
2141                         data = ServicePtrs[i]->param_opt;
2142                         while (data) {
2143                                 string_free(&data->key);
2144                                 string_free(&data->value);
2145                                 pdata = data->next;
2146                                 SAFE_FREE(data);
2147                                 data = pdata;
2148                         }
2149                         ServicePtrs[i]->param_opt = NULL;
2150                         return (i);
2151                 }
2152         }
2153
2154         /* find an invalid one */
2155         for (i = 0; i < iNumServices; i++)
2156                 if (!ServicePtrs[i]->valid)
2157                         break;
2158
2159         /* if not, then create one */
2160         if (i == iNumServices) {
2161                 service **tsp;
2162                 
2163                 tsp = (service **) Realloc(ServicePtrs,
2164                                            sizeof(service *) *
2165                                            num_to_alloc);
2166                                            
2167                 if (!tsp) {
2168                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2169                         return (-1);
2170                 }
2171                 else {
2172                         ServicePtrs = tsp;
2173                         ServicePtrs[iNumServices] =
2174                                 (service *) malloc(sizeof(service));
2175                 }
2176                 if (!ServicePtrs[iNumServices]) {
2177                         DEBUG(0,("add_a_service: out of memory!\n"));
2178                         return (-1);
2179                 }
2180
2181                 iNumServices++;
2182         } else
2183                 free_service(ServicePtrs[i]);
2184
2185         ServicePtrs[i]->valid = True;
2186
2187         init_service(ServicePtrs[i]);
2188         copy_service(ServicePtrs[i], &tservice, NULL);
2189         if (name)
2190                 string_set(&ServicePtrs[i]->szService, name);
2191         return (i);
2192 }
2193
2194 /***************************************************************************
2195  Add a new home service, with the specified home directory, defaults coming 
2196  from service ifrom.
2197 ***************************************************************************/
2198
2199 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
2200                  const char *user, const char *pszHomedir)
2201 {
2202         int i;
2203         pstring newHomedir;
2204
2205         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2206
2207         if (i < 0)
2208                 return (False);
2209
2210         if (!(*(ServicePtrs[iDefaultService]->szPath))
2211             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
2212                 pstrcpy(newHomedir, pszHomedir);
2213         } else {
2214                 pstrcpy(newHomedir, lp_pathname(iDefaultService));
2215                 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); 
2216         }
2217
2218         string_set(&ServicePtrs[i]->szPath, newHomedir);
2219
2220         if (!(*(ServicePtrs[i]->comment))) {
2221                 pstring comment;
2222                 slprintf(comment, sizeof(comment) - 1,
2223                          "Home directory of %s", user);
2224                 string_set(&ServicePtrs[i]->comment, comment);
2225         }
2226         ServicePtrs[i]->bAvailable = sDefault.bAvailable;
2227         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2228
2229         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2230                user, newHomedir));
2231         
2232         return (True);
2233 }
2234
2235 /***************************************************************************
2236  Add a new service, based on an old one.
2237 ***************************************************************************/
2238
2239 int lp_add_service(const char *pszService, int iDefaultService)
2240 {
2241         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2242 }
2243
2244 /***************************************************************************
2245  Add the IPC service.
2246 ***************************************************************************/
2247
2248 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2249 {
2250         pstring comment;
2251         int i = add_a_service(&sDefault, ipc_name);
2252
2253         if (i < 0)
2254                 return (False);
2255
2256         slprintf(comment, sizeof(comment) - 1,
2257                  "IPC Service (%s)", Globals.szServerString);
2258
2259         string_set(&ServicePtrs[i]->szPath, tmpdir());
2260         string_set(&ServicePtrs[i]->szUsername, "");
2261         string_set(&ServicePtrs[i]->comment, comment);
2262         string_set(&ServicePtrs[i]->fstype, "IPC");
2263         ServicePtrs[i]->iMaxConnections = 0;
2264         ServicePtrs[i]->bAvailable = True;
2265         ServicePtrs[i]->bRead_only = True;
2266         ServicePtrs[i]->bGuest_only = False;
2267         ServicePtrs[i]->bGuest_ok = guest_ok;
2268         ServicePtrs[i]->bPrint_ok = False;
2269         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2270
2271         DEBUG(3, ("adding IPC service\n"));
2272
2273         return (True);
2274 }
2275
2276 /***************************************************************************
2277  Add a new printer service, with defaults coming from service iFrom.
2278 ***************************************************************************/
2279
2280 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2281 {
2282         const char *comment = "From Printcap";
2283         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2284
2285         if (i < 0)
2286                 return (False);
2287
2288         /* note that we do NOT default the availability flag to True - */
2289         /* we take it from the default service passed. This allows all */
2290         /* dynamic printers to be disabled by disabling the [printers] */
2291         /* entry (if/when the 'available' keyword is implemented!).    */
2292
2293         /* the printer name is set to the service name. */
2294         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2295         string_set(&ServicePtrs[i]->comment, comment);
2296         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2297         /* Printers cannot be read_only. */
2298         ServicePtrs[i]->bRead_only = False;
2299         /* No share modes on printer services. */
2300         ServicePtrs[i]->bShareModes = False;
2301         /* No oplocks on printer services. */
2302         ServicePtrs[i]->bOpLocks = False;
2303         /* Printer services must be printable. */
2304         ServicePtrs[i]->bPrint_ok = True;
2305
2306         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2307
2308         update_server_announce_as_printserver();
2309
2310         return (True);
2311 }
2312
2313 /***************************************************************************
2314  Map a parameter's string representation to something we can use. 
2315  Returns False if the parameter string is not recognised, else TRUE.
2316 ***************************************************************************/
2317
2318 static int map_parameter(const char *pszParmName)
2319 {
2320         int iIndex;
2321
2322         if (*pszParmName == '-')
2323                 return (-1);
2324
2325         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2326                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2327                         return (iIndex);
2328
2329         /* Warn only if it isn't parametric option */
2330         if (strchr(pszParmName, ':') == NULL)
2331                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2332         /* We do return 'fail' for parametric options as well because they are
2333            stored in different storage
2334          */
2335         return (-1);
2336 }
2337
2338 /***************************************************************************
2339  Set a boolean variable from the text value stored in the passed string.
2340  Returns True in success, False if the passed string does not correctly 
2341  represent a boolean.
2342 ***************************************************************************/
2343
2344 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2345 {
2346         BOOL bRetval;
2347
2348         bRetval = True;
2349         if (strwicmp(pszParmValue, "yes") == 0 ||
2350             strwicmp(pszParmValue, "true") == 0 ||
2351             strwicmp(pszParmValue, "1") == 0)
2352                 *pb = True;
2353         else if (strwicmp(pszParmValue, "no") == 0 ||
2354                     strwicmp(pszParmValue, "False") == 0 ||
2355                     strwicmp(pszParmValue, "0") == 0)
2356                 *pb = False;
2357         else {
2358                 DEBUG(0,
2359                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2360                        pszParmValue));
2361                 bRetval = False;
2362         }
2363         return (bRetval);
2364 }
2365
2366 /***************************************************************************
2367 Find a service by name. Otherwise works like get_service.
2368 ***************************************************************************/
2369
2370 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2371 {
2372         int iService;
2373
2374         for (iService = iNumServices - 1; iService >= 0; iService--)
2375                 if (VALID(iService) &&
2376                     strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
2377                         if (pserviceDest != NULL)
2378                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2379                         break;
2380                 }
2381
2382         return (iService);
2383 }
2384
2385 /***************************************************************************
2386  Copy a service structure to another.
2387  If pcopymapDest is NULL then copy all fields
2388 ***************************************************************************/
2389
2390 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2391 {
2392         int i;
2393         BOOL bcopyall = (pcopymapDest == NULL);
2394         param_opt_struct *data, *pdata, *paramo;
2395         BOOL not_added;
2396
2397         for (i = 0; parm_table[i].label; i++)
2398                 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
2399                     (bcopyall || pcopymapDest[i])) {
2400                         void *def_ptr = parm_table[i].ptr;
2401                         void *src_ptr =
2402                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2403                                                                     &sDefault);
2404                         void *dest_ptr =
2405                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2406                                                                   &sDefault);
2407
2408                         switch (parm_table[i].type) {
2409                                 case P_BOOL:
2410                                 case P_BOOLREV:
2411                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2412                                         break;
2413
2414                                 case P_INTEGER:
2415                                 case P_ENUM:
2416                                 case P_OCTAL:
2417                                         *(int *)dest_ptr = *(int *)src_ptr;
2418                                         break;
2419
2420                                 case P_CHAR:
2421                                         *(char *)dest_ptr = *(char *)src_ptr;
2422                                         break;
2423
2424                                 case P_STRING:
2425                                         string_set(dest_ptr,
2426                                                    *(char **)src_ptr);
2427                                         break;
2428
2429                                 case P_USTRING:
2430                                         string_set(dest_ptr,
2431                                                    *(char **)src_ptr);
2432                                         strupper(*(char **)dest_ptr);
2433                                         break;
2434                                 case P_LIST:
2435                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2436                                         break;
2437                                 default:
2438                                         break;
2439                         }
2440                 }
2441
2442         if (bcopyall) {
2443                 init_copymap(pserviceDest);
2444                 if (pserviceSource->copymap)
2445                         memcpy((void *)pserviceDest->copymap,
2446                                (void *)pserviceSource->copymap,
2447                                sizeof(BOOL) * NUMPARAMETERS);
2448         }
2449         
2450         data = pserviceSource->param_opt;
2451         while (data) {
2452                 not_added = True;
2453                 pdata = pserviceDest->param_opt;
2454                 /* Traverse destination */
2455                 while (pdata) {
2456                         /* If we already have same option, override it */
2457                         if (strcmp(pdata->key, data->key) == 0) {
2458                                 string_free(&pdata->value);
2459                                 pdata->value = strdup(data->value);
2460                                 not_added = False;
2461                                 break;
2462                         }
2463                         pdata = pdata->next;
2464                 }
2465                 if (not_added) {
2466                     paramo = smb_xmalloc(sizeof(param_opt_struct));
2467                     paramo->key = strdup(data->key);
2468                     paramo->value = strdup(data->value);
2469                     DLIST_ADD(pserviceDest->param_opt, paramo);
2470                 }
2471                 data = data->next;
2472         }
2473 }
2474
2475 /***************************************************************************
2476 Check a service for consistency. Return False if the service is in any way
2477 incomplete or faulty, else True.
2478 ***************************************************************************/
2479
2480 static BOOL service_ok(int iService)
2481 {
2482         BOOL bRetval;
2483
2484         bRetval = True;
2485         if (ServicePtrs[iService]->szService[0] == '\0') {
2486                 DEBUG(0, ("The following message indicates an internal error:\n"));
2487                 DEBUG(0, ("No service name in service entry.\n"));
2488                 bRetval = False;
2489         }
2490
2491         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2492         /* I can't see why you'd want a non-printable printer service...        */
2493         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2494                 if (!ServicePtrs[iService]->bPrint_ok) {
2495                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2496                                ServicePtrs[iService]->szService));
2497                         ServicePtrs[iService]->bPrint_ok = True;
2498                 }
2499                 /* [printers] service must also be non-browsable. */
2500                 if (ServicePtrs[iService]->bBrowseable)
2501                         ServicePtrs[iService]->bBrowseable = False;
2502         }
2503
2504         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2505             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2506                 DEBUG(0, ("No path in service %s - using %s\n",
2507                        ServicePtrs[iService]->szService, tmpdir()));
2508                 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2509         }
2510
2511         /* If a service is flagged unavailable, log the fact at level 0. */
2512         if (!ServicePtrs[iService]->bAvailable)
2513                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2514                           ServicePtrs[iService]->szService));
2515
2516         return (bRetval);
2517 }
2518
2519 static struct file_lists {
2520         struct file_lists *next;
2521         char *name;
2522         char *subfname;
2523         time_t modtime;
2524 } *file_lists = NULL;
2525
2526 /*******************************************************************
2527  Keep a linked list of all config files so we know when one has changed 
2528  it's date and needs to be reloaded.
2529 ********************************************************************/
2530
2531 static void add_to_file_list(const char *fname, const char *subfname)
2532 {
2533         struct file_lists *f = file_lists;
2534
2535         while (f) {
2536                 if (f->name && !strcmp(f->name, fname))
2537                         break;
2538                 f = f->next;
2539         }
2540
2541         if (!f) {
2542                 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2543                 if (!f)
2544                         return;
2545                 f->next = file_lists;
2546                 f->name = strdup(fname);
2547                 if (!f->name) {
2548                         SAFE_FREE(f);
2549                         return;
2550                 }
2551                 f->subfname = strdup(subfname);
2552                 if (!f->subfname) {
2553                         SAFE_FREE(f);
2554                         return;
2555                 }
2556                 file_lists = f;
2557                 f->modtime = file_modtime(subfname);
2558         } else {
2559                 time_t t = file_modtime(subfname);
2560                 if (t)
2561                         f->modtime = t;
2562         }
2563 }
2564
2565 /*******************************************************************
2566  Check if a config file has changed date.
2567 ********************************************************************/
2568
2569 BOOL lp_file_list_changed(void)
2570 {
2571         struct file_lists *f = file_lists;
2572         DEBUG(6, ("lp_file_list_changed()\n"));
2573
2574         while (f) {
2575                 pstring n2;
2576                 time_t mod_time;
2577
2578                 pstrcpy(n2, f->name);
2579                 standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
2580
2581                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2582                              f->name, n2, ctime(&f->modtime)));
2583
2584                 mod_time = file_modtime(n2);
2585
2586                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2587                         DEBUGADD(6,
2588                                  ("file %s modified: %s\n", n2,
2589                                   ctime(&mod_time)));
2590                         f->modtime = mod_time;
2591                         SAFE_FREE(f->subfname);
2592                         f->subfname = strdup(n2);
2593                         return (True);
2594                 }
2595                 f = f->next;
2596         }
2597         return (False);
2598 }
2599
2600 /***************************************************************************
2601  Run standard_sub_basic on netbios name... needed because global_myname
2602  is not accessed through any lp_ macro.
2603  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2604 ***************************************************************************/
2605
2606 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
2607 {
2608         BOOL ret;
2609         pstring netbios_name;
2610
2611         pstrcpy(netbios_name, pszParmValue);
2612
2613         standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
2614
2615
2616         ret = set_global_myname(netbios_name);
2617         string_set(&Globals.szNetbiosName,global_myname());
2618         
2619         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2620                global_myname()));
2621
2622         return ret;
2623 }
2624
2625 static BOOL handle_workgroup(const char *pszParmValue, char **ptr)
2626 {
2627         BOOL ret;
2628         
2629         ret = set_global_myworkgroup(pszParmValue);
2630         string_set(&Globals.szWorkgroup,lp_workgroup());
2631         
2632         return ret;
2633 }
2634
2635 static BOOL handle_netbios_scope(const char *pszParmValue, char **ptr)
2636 {
2637         BOOL ret;
2638         
2639         ret = set_global_scope(pszParmValue);
2640         string_set(&Globals.szNetbiosScope,global_scope());
2641
2642         return ret;
2643 }
2644
2645 static BOOL handle_netbios_aliases(const char *pszParmValue, char **ptr)
2646 {
2647         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2648         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2649 }
2650
2651 /***************************************************************************
2652  Do the work of sourcing in environment variable/value pairs.
2653 ***************************************************************************/
2654
2655 static BOOL source_env(char **lines)
2656 {
2657         char *varval;
2658         size_t len;
2659         int i;
2660         char *p;
2661
2662         for (i = 0; lines[i]; i++) {
2663                 char *line = lines[i];
2664
2665                 if ((len = strlen(line)) == 0)
2666                         continue;
2667
2668                 if (line[len - 1] == '\n')
2669                         line[--len] = '\0';
2670
2671                 if ((varval = malloc(len + 1)) == NULL) {
2672                         DEBUG(0, ("source_env: Not enough memory!\n"));
2673                         return (False);
2674                 }
2675
2676                 DEBUG(4, ("source_env: Adding to environment: %s\n", line));
2677                 strncpy(varval, line, len);
2678                 varval[len] = '\0';
2679
2680                 p = strchr_m(line, (int)'=');
2681                 if (p == NULL) {
2682                         DEBUG(4, ("source_env: missing '=': %s\n", line));
2683                         continue;
2684                 }
2685
2686                 if (putenv(varval)) {
2687                         DEBUG(0, ("source_env: Failed to put environment variable %s\n",
2688                                varval));
2689                         continue;
2690                 }
2691
2692                 *p = '\0';
2693                 p++;
2694                 DEBUG(4, ("source_env: getting var %s = %s\n", line, getenv(line)));
2695         }
2696
2697         DEBUG(4, ("source_env: returning successfully\n"));
2698         return (True);
2699 }
2700
2701 /***************************************************************************
2702  Handle the source environment operation.
2703 ***************************************************************************/
2704
2705 static BOOL handle_source_env(const char *pszParmValue, char **ptr)
2706 {
2707         pstring fname;
2708         char *p = fname;
2709         BOOL result;
2710         char **lines;
2711
2712         pstrcpy(fname, pszParmValue);
2713
2714         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2715
2716         string_set(ptr, pszParmValue);
2717
2718         DEBUG(4, ("handle_source_env: checking env type\n"));
2719
2720         /*
2721          * Filename starting with '|' means popen and read from stdin.
2722          */
2723
2724         if (*p == '|')
2725                 lines = file_lines_pload(p + 1, NULL);
2726         else
2727                 lines = file_lines_load(fname, NULL);
2728
2729         if (!lines) {
2730                 DEBUG(0, ("handle_source_env: Failed to open file %s, Error was %s\n",
2731                        fname, strerror(errno)));
2732                 return (False);
2733         }
2734
2735         result = source_env(lines);
2736         file_lines_free(lines);
2737
2738         return (result);
2739 }
2740
2741 /***************************************************************************
2742  Handle the interpretation of the vfs object parameter.
2743 *************************************************************************/
2744
2745 static BOOL handle_vfs_object(const char *pszParmValue, char **ptr)
2746 {
2747         /* Set string value */
2748
2749         string_set(ptr, pszParmValue);
2750
2751         /* Do any other initialisation required for vfs.  Note that
2752            anything done here may have linking repercussions in nmbd. */
2753
2754         return True;
2755 }
2756
2757 /***************************************************************************
2758  Handle the include operation.
2759 ***************************************************************************/
2760
2761 static BOOL handle_include(const char *pszParmValue, char **ptr)
2762 {
2763         pstring fname;
2764         pstrcpy(fname, pszParmValue);
2765
2766         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2767
2768         add_to_file_list(pszParmValue, fname);
2769
2770         string_set(ptr, fname);
2771
2772         if (file_exist(fname, NULL))
2773                 return (pm_process(fname, do_section, do_parameter));
2774
2775         DEBUG(2, ("Can't find include file %s\n", fname));
2776
2777         return (False);
2778 }
2779
2780 /***************************************************************************
2781  Handle the interpretation of the copy parameter.
2782 ***************************************************************************/
2783
2784 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2785 {
2786         BOOL bRetval;
2787         int iTemp;
2788         service serviceTemp;
2789
2790         string_set(ptr, pszParmValue);
2791
2792         init_service(&serviceTemp);
2793
2794         bRetval = False;
2795
2796         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2797
2798         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2799                 if (iTemp == iServiceIndex) {
2800                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2801                 } else {
2802                         copy_service(ServicePtrs[iServiceIndex],
2803                                      &serviceTemp,
2804                                      ServicePtrs[iServiceIndex]->copymap);
2805                         bRetval = True;
2806                 }
2807         } else {
2808                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2809                 bRetval = False;
2810         }
2811
2812         free_service(&serviceTemp);
2813         return (bRetval);
2814 }
2815
2816 /***************************************************************************
2817  Handle winbind/non unix account uid and gid allocation parameters.  The format of these
2818  parameters is:
2819
2820  [global]
2821
2822         winbind uid = 1000-1999
2823         winbind gid = 700-899
2824
2825  We only do simple parsing checks here.  The strings are parsed into useful
2826  structures in the winbind daemon code.
2827
2828 ***************************************************************************/
2829
2830 /* Some lp_ routines to return winbind [ug]id information */
2831
2832 static uid_t winbind_uid_low, winbind_uid_high;
2833 static gid_t winbind_gid_low, winbind_gid_high;
2834 static uint32 non_unix_account_low, non_unix_account_high;
2835
2836 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2837 {
2838         if (winbind_uid_low == 0 || winbind_uid_high == 0)
2839                 return False;
2840
2841         if (low)
2842                 *low = winbind_uid_low;
2843
2844         if (high)
2845                 *high = winbind_uid_high;
2846
2847         return True;
2848 }
2849
2850 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2851 {
2852         if (winbind_gid_low == 0 || winbind_gid_high == 0)
2853                 return False;
2854
2855         if (low)
2856                 *low = winbind_gid_low;
2857
2858         if (high)
2859                 *high = winbind_gid_high;
2860
2861         return True;
2862 }
2863
2864 BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
2865 {
2866         if (non_unix_account_low == 0 || non_unix_account_high == 0)
2867                 return False;
2868
2869         if (low)
2870                 *low = non_unix_account_low;
2871
2872         if (high)
2873                 *high = non_unix_account_high;
2874
2875         return True;
2876 }
2877
2878 /* Do some simple checks on "winbind [ug]id" parameter values */
2879
2880 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2881 {
2882         uint32 low, high;
2883
2884         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2885                 return False;
2886
2887         /* Parse OK */
2888
2889         string_set(ptr, pszParmValue);
2890
2891         winbind_uid_low = low;
2892         winbind_uid_high = high;
2893
2894         return True;
2895 }
2896
2897 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2898 {
2899         uint32 low, high;
2900
2901         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2902                 return False;
2903
2904         /* Parse OK */
2905
2906         string_set(ptr, pszParmValue);
2907
2908         winbind_gid_low = low;
2909         winbind_gid_high = high;
2910
2911         return True;
2912 }
2913
2914 /***************************************************************************
2915  Do some simple checks on "non unix account range" parameter values.
2916 ***************************************************************************/
2917
2918 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2919 {
2920         uint32 low, high;
2921
2922         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2923                 return False;
2924
2925         /* Parse OK */
2926
2927         string_set(ptr, pszParmValue);
2928
2929         non_unix_account_low = low;
2930         non_unix_account_high = high;
2931
2932         return True;
2933 }
2934
2935 /***************************************************************************
2936  Handle the DEBUG level list.
2937 ***************************************************************************/
2938
2939 static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
2940 {
2941         pstring pszParmValue;
2942
2943         pstrcpy(pszParmValue, pszParmValueIn);
2944         string_set(ptr, pszParmValueIn);
2945         return debug_parse_levels( pszParmValue );
2946 }
2947
2948 /***************************************************************************
2949  Handle the ldap machine suffix option.
2950 ***************************************************************************/
2951
2952 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2953 {
2954        pstring suffix;
2955        
2956        pstrcpy(suffix, pszParmValue);
2957
2958        if (! *Globals.szLdapSuffix ) {
2959                string_set( ptr, suffix );
2960                return True;
2961        }
2962
2963        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2964                if ( *pszParmValue )
2965                        pstrcat(suffix, ",");
2966                pstrcat(suffix, Globals.szLdapSuffix);
2967        }
2968        string_set( ptr, suffix );
2969        return True;
2970 }
2971
2972 /***************************************************************************
2973  Handle the ldap user suffix option.
2974 ***************************************************************************/
2975
2976 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2977 {
2978        pstring suffix;
2979        
2980        pstrcpy(suffix, pszParmValue);
2981
2982        if (! *Globals.szLdapSuffix ) {
2983                string_set( ptr, suffix );
2984                return True;
2985        }
2986        
2987        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2988                if ( *pszParmValue )
2989                        pstrcat(suffix, ",");
2990                pstrcat(suffix, Globals.szLdapSuffix);
2991        }
2992        string_set( ptr, suffix );
2993        return True;
2994 }
2995
2996 /***************************************************************************
2997  Handle setting ldap suffix and determines whether ldap machine suffix needs
2998  to be set as well.
2999 ***************************************************************************/
3000
3001 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
3002 {
3003        pstring suffix;
3004        pstring user_suffix;
3005        pstring machine_suffix;
3006                
3007        pstrcpy(suffix, pszParmValue);
3008
3009        if (! *Globals.szLdapMachineSuffix )
3010                string_set(&Globals.szLdapMachineSuffix, suffix);
3011        if (! *Globals.szLdapUserSuffix ) 
3012                string_set(&Globals.szLdapUserSuffix, suffix);
3013        
3014        if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
3015                pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
3016                if ( *Globals.szLdapMachineSuffix )
3017                        pstrcat(machine_suffix, ",");
3018                pstrcat(machine_suffix, suffix);
3019                string_set(&Globals.szLdapMachineSuffix, machine_suffix);       
3020        }
3021
3022        if (! strstr(Globals.szLdapUserSuffix, suffix)) {
3023                pstrcpy(user_suffix, Globals.szLdapUserSuffix);
3024                if ( *Globals.szLdapUserSuffix )
3025                        pstrcat(user_suffix, ",");
3026                pstrcat(user_suffix, suffix);   
3027                string_set(&Globals.szLdapUserSuffix, user_suffix);
3028        } 
3029
3030        string_set(ptr, suffix); 
3031        return True;
3032 }
3033
3034 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
3035 {
3036         if (strequal(pszParmValue, "auto"))
3037                 string_set(ptr, "");
3038         else if (strequal(pszParmValue, "winnt"))
3039                 string_set(ptr, "winnt");
3040         else if (strequal(pszParmValue, "win2k"))
3041                 string_set(ptr, "win2k");
3042         else
3043                 return False;
3044
3045         return True;
3046 }
3047 /***************************************************************************
3048  Initialise a copymap.
3049 ***************************************************************************/
3050
3051 static void init_copymap(service * pservice)
3052 {
3053         int i;
3054         SAFE_FREE(pservice->copymap);
3055         pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
3056         if (!pservice->copymap)
3057                 DEBUG(0,
3058                       ("Couldn't allocate copymap!! (size %d)\n",
3059                        (int)NUMPARAMETERS));
3060         else
3061                 for (i = 0; i < NUMPARAMETERS; i++)
3062                         pservice->copymap[i] = True;
3063 }
3064
3065 /***************************************************************************
3066  Return the local pointer to a parameter given the service number and the 
3067  pointer into the default structure.
3068 ***************************************************************************/
3069
3070 void *lp_local_ptr(int snum, void *ptr)
3071 {
3072         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3073 }
3074
3075 /***************************************************************************
3076  Process a parameter for a particular service number. If snum < 0
3077  then assume we are in the globals.
3078 ***************************************************************************/
3079
3080 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3081 {
3082         int parmnum, i, slen;
3083         void *parm_ptr = NULL;  /* where we are going to store the result */
3084         void *def_ptr = NULL;
3085         pstring vfskey;
3086         char *sep;
3087         param_opt_struct *paramo, *data;
3088         BOOL not_added;
3089
3090         parmnum = map_parameter(pszParmName);
3091
3092         if (parmnum < 0) {
3093                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3094                         *sep = 0;
3095                         ZERO_STRUCT(vfskey);
3096                         pstr_sprintf(vfskey, "%s:", pszParmName);
3097                         slen = strlen(vfskey);
3098                         safe_strcat(vfskey, sep+1, sizeof(pstring));
3099                         trim_string(vfskey+slen, " ", " ");
3100                         not_added = True;
3101                         data = (snum < 0) ? Globals.param_opt : 
3102                                 ServicePtrs[snum]->param_opt;
3103                         /* Traverse destination */
3104                         while (data) {
3105                                 /* If we already have same option, override it */
3106                                 if (strcmp(data->key, vfskey) == 0) {
3107                                         string_free(&data->value);
3108                                         data->value = strdup(pszParmValue);
3109                                         not_added = False;
3110                                         break;
3111                                 }
3112                                 data = data->next;
3113                         }
3114                         if (not_added) {
3115                                 paramo = smb_xmalloc(sizeof(param_opt_struct));
3116                                 paramo->key = strdup(vfskey);
3117                                 paramo->value = strdup(pszParmValue);
3118                                 if (snum < 0) {
3119                                         DLIST_ADD(Globals.param_opt, paramo);
3120                                 } else {
3121                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3122                                 }
3123                         }
3124
3125                         *sep = ':';
3126                         return (True);
3127                 }
3128                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3129                 return (True);
3130         }
3131
3132         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3133                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3134                           pszParmName));
3135         }
3136
3137         def_ptr = parm_table[parmnum].ptr;
3138
3139         /* we might point at a service, the default service or a global */
3140         if (snum < 0) {
3141                 parm_ptr = def_ptr;
3142         } else {
3143                 if (parm_table[parmnum].class == P_GLOBAL) {
3144                         DEBUG(0,
3145                               ("Global parameter %s found in service section!\n",
3146                                pszParmName));
3147                         return (True);
3148                 }
3149                 parm_ptr =
3150                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3151                                                             &sDefault);
3152         }
3153
3154         if (snum >= 0) {
3155                 if (!ServicePtrs[snum]->copymap)
3156                         init_copymap(ServicePtrs[snum]);
3157
3158                 /* this handles the aliases - set the copymap for other entries with
3159                    the same data pointer */
3160                 for (i = 0; parm_table[i].label; i++)
3161                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
3162                                 ServicePtrs[snum]->copymap[i] = False;
3163         }
3164
3165         /* if it is a special case then go ahead */
3166         if (parm_table[parmnum].special) {
3167                 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
3168                 return (True);
3169         }
3170
3171         /* now switch on the type of variable it is */
3172         switch (parm_table[parmnum].type)
3173         {
3174                 case P_BOOL:
3175                         set_boolean(parm_ptr, pszParmValue);
3176                         break;
3177
3178                 case P_BOOLREV:
3179                         set_boolean(parm_ptr, pszParmValue);
3180                         *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3181                         break;
3182
3183                 case P_INTEGER:
3184                         *(int *)parm_ptr = atoi(pszParmValue);
3185                         break;
3186
3187                 case P_CHAR:
3188                         *(char *)parm_ptr = *pszParmValue;
3189                         break;
3190
3191                 case P_OCTAL:
3192                         sscanf(pszParmValue, "%o", (int *)parm_ptr);
3193                         break;
3194
3195                 case P_LIST:
3196                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3197                         break;
3198
3199                 case P_STRING:
3200                         string_set(parm_ptr, pszParmValue);
3201                         break;
3202
3203                 case P_USTRING:
3204                         string_set(parm_ptr, pszParmValue);
3205                         strupper(*(char **)parm_ptr);
3206                         break;
3207
3208                 case P_GSTRING:
3209                         pstrcpy((char *)parm_ptr, pszParmValue);
3210                         break;
3211
3212                 case P_UGSTRING:
3213                         pstrcpy((char *)parm_ptr, pszParmValue);
3214                         strupper((char *)parm_ptr);
3215                         break;
3216
3217                 case P_ENUM:
3218                         for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
3219                                 if (strequal
3220                                     (pszParmValue,
3221                                      parm_table[parmnum].enum_list[i].name)) {
3222                                         *(int *)parm_ptr =
3223                                                 parm_table[parmnum].
3224                                                 enum_list[i].value;
3225                                         break;
3226                                 }
3227                         }
3228                         break;
3229                 case P_SEP:
3230                         break;
3231         }
3232
3233         return (True);
3234 }
3235
3236 /***************************************************************************
3237  Process a parameter.
3238 ***************************************************************************/
3239
3240 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3241 {
3242         if (!bInGlobalSection && bGlobalOnly)
3243                 return (True);
3244
3245         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3246
3247         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3248                                 pszParmName, pszParmValue));
3249 }
3250
3251 /***************************************************************************
3252  Print a parameter of the specified type.
3253 ***************************************************************************/
3254
3255 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3256 {
3257         int i;
3258         switch (p->type)
3259         {
3260                 case P_ENUM:
3261                         for (i = 0; p->enum_list[i].name; i++) {
3262                                 if (*(int *)ptr == p->enum_list[i].value) {
3263                                         fprintf(f, "%s",
3264                                                 p->enum_list[i].name);
3265                                         break;
3266                                 }
3267                         }
3268                         break;
3269
3270                 case P_BOOL:
3271                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3272                         break;
3273
3274                 case P_BOOLREV:
3275                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3276                         break;
3277
3278                 case P_INTEGER:
3279                         fprintf(f, "%d", *(int *)ptr);
3280                         break;
3281
3282                 case P_CHAR:
3283                         fprintf(f, "%c", *(char *)ptr);
3284                         break;
3285
3286                 case P_OCTAL:
3287                         fprintf(f, "%s", octal_string(*(int *)ptr));
3288                         break;
3289
3290                 case P_LIST:
3291                         if ((char ***)ptr && *(char ***)ptr) {
3292                                 char **list = *(char ***)ptr;
3293                                 
3294                                 for (; *list; list++)
3295                                         fprintf(f, "%s%s", *list,
3296                                                 ((*(list+1))?", ":""));
3297                         }
3298                         break;
3299
3300                 case P_GSTRING:
3301                 case P_UGSTRING:
3302                         if ((char *)ptr) {
3303                                 fprintf(f, "%s", (char *)ptr);
3304                         }
3305                         break;
3306
3307                 case P_STRING:
3308                 case P_USTRING:
3309                         if (*(char **)ptr) {
3310                                 fprintf(f, "%s", *(char **)ptr);
3311                         }
3312                         break;
3313                 case P_SEP:
3314                         break;
3315         }
3316 }
3317
3318 /***************************************************************************
3319  Check if two parameters are equal.
3320 ***************************************************************************/
3321
3322 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3323 {
3324         switch (type) {
3325                 case P_BOOL:
3326                 case P_BOOLREV:
3327                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3328
3329                 case P_INTEGER:
3330                 case P_ENUM:
3331                 case P_OCTAL:
3332                         return (*((int *)ptr1) == *((int *)ptr2));
3333
3334                 case P_CHAR:
3335                         return (*((char *)ptr1) == *((char *)ptr2));
3336                 
3337                 case P_LIST:
3338                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3339
3340                 case P_GSTRING:
3341                 case P_UGSTRING:
3342                 {
3343                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3344                         if (p1 && !*p1)
3345                                 p1 = NULL;
3346                         if (p2 && !*p2)
3347                                 p2 = NULL;
3348                         return (p1 == p2 || strequal(p1, p2));
3349                 }
3350                 case P_STRING:
3351                 case P_USTRING:
3352                 {
3353                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3354                         if (p1 && !*p1)
3355                                 p1 = NULL;
3356                         if (p2 && !*p2)
3357                                 p2 = NULL;
3358                         return (p1 == p2 || strequal(p1, p2));
3359                 }
3360                 case P_SEP:
3361                         break;
3362         }
3363         return (False);
3364 }
3365
3366 /***************************************************************************
3367  Initialize any local varients in the sDefault table.
3368 ***************************************************************************/
3369
3370 void init_locals(void)
3371 {
3372         /* None as yet. */
3373 }
3374
3375 /***************************************************************************
3376  Process a new section (service). At this stage all sections are services.
3377  Later we'll have special sections that permit server parameters to be set.
3378  Returns True on success, False on failure. 
3379 ***************************************************************************/
3380
3381 static BOOL do_section(const char *pszSectionName)
3382 {
3383         BOOL bRetval;
3384         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3385                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3386         bRetval = False;
3387
3388         /* if we were in a global section then do the local inits */
3389         if (bInGlobalSection && !isglobal)
3390                 init_locals();
3391
3392         /* if we've just struck a global section, note the fact. */
3393         bInGlobalSection = isglobal;
3394
3395         /* check for multiple global sections */
3396         if (bInGlobalSection) {
3397                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3398                 return (True);
3399         }
3400
3401         if (!bInGlobalSection && bGlobalOnly)
3402                 return (True);
3403
3404         /* if we have a current service, tidy it up before moving on */
3405         bRetval = True;
3406
3407         if (iServiceIndex >= 0)
3408                 bRetval = service_ok(iServiceIndex);
3409
3410         /* if all is still well, move to the next record in the services array */
3411         if (bRetval) {
3412                 /* We put this here to avoid an odd message order if messages are */
3413                 /* issued by the post-processing of a previous section. */
3414                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3415
3416                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3417                     < 0) {
3418                         DEBUG(0, ("Failed to add a new service\n"));
3419                         return (False);
3420                 }
3421         }
3422
3423         return (bRetval);
3424 }
3425
3426
3427 /***************************************************************************
3428  Determine if a partcular base parameter is currentl set to the default value.
3429 ***************************************************************************/
3430
3431 static BOOL is_default(int i)
3432 {
3433         if (!defaults_saved)
3434                 return False;
3435         switch (parm_table[i].type) {
3436                 case P_LIST:
3437                         return str_list_compare (parm_table[i].def.lvalue, 
3438                                                 *(char ***)parm_table[i].ptr);
3439                 case P_STRING:
3440                 case P_USTRING:
3441                         return strequal(parm_table[i].def.svalue,
3442                                         *(char **)parm_table[i].ptr);
3443                 case P_GSTRING:
3444                 case P_UGSTRING:
3445                         return strequal(parm_table[i].def.svalue,
3446                                         (char *)parm_table[i].ptr);
3447                 case P_BOOL:
3448                 case P_BOOLREV:
3449                         return parm_table[i].def.bvalue ==
3450                                 *(BOOL *)parm_table[i].ptr;
3451                 case P_CHAR:
3452                         return parm_table[i].def.cvalue ==
3453                                 *(char *)parm_table[i].ptr;
3454                 case P_INTEGER:
3455                 case P_OCTAL:
3456                 case P_ENUM:
3457                         return parm_table[i].def.ivalue ==
3458                                 *(int *)parm_table[i].ptr;
3459                 case P_SEP:
3460                         break;
3461         }
3462         return False;
3463 }
3464
3465 /***************************************************************************
3466 Display the contents of the global structure.
3467 ***************************************************************************/
3468
3469 static void dump_globals(FILE *f)
3470 {
3471         int i;
3472         param_opt_struct *data;
3473         
3474         fprintf(f, "# Global parameters\n[global]\n");
3475
3476         for (i = 0; parm_table[i].label; i++)
3477                 if (parm_table[i].class == P_GLOBAL &&
3478                     parm_table[i].ptr &&
3479                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3480                         if (defaults_saved && is_default(i))
3481                                 continue;
3482                         fprintf(f, "\t%s = ", parm_table[i].label);
3483                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
3484                         fprintf(f, "\n");
3485         }
3486         if (Globals.param_opt != NULL) {
3487                 data = Globals.param_opt;
3488                 while(data) {
3489                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3490                         data = data->next;
3491                 }
3492         }
3493
3494 }
3495
3496 /***************************************************************************
3497  Return True if a local parameter is currently set to the global default.
3498 ***************************************************************************/
3499
3500 BOOL lp_is_default(int snum, struct parm_struct *parm)
3501 {
3502         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3503
3504         return equal_parameter(parm->type,
3505                                ((char *)ServicePtrs[snum]) + pdiff,
3506                                ((char *)&sDefault) + pdiff);
3507 }
3508
3509 /***************************************************************************
3510  Display the contents of a single services record.
3511 ***************************************************************************/
3512
3513 static void dump_a_service(service * pService, FILE * f)
3514 {
3515         int i;
3516         param_opt_struct *data;
3517         
3518         if (pService != &sDefault)
3519                 fprintf(f, "\n[%s]\n", pService->szService);
3520
3521         for (i = 0; parm_table[i].label; i++)
3522                 if (parm_table[i].class == P_LOCAL &&
3523                     parm_table[i].ptr &&
3524                     (*parm_table[i].label != '-') &&
3525                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3526                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3527
3528                         if (pService == &sDefault) {
3529                                 if (defaults_saved && is_default(i))
3530                                         continue;
3531                         } else {
3532                                 if (equal_parameter(parm_table[i].type,
3533                                                     ((char *)pService) +
3534                                                     pdiff,
3535                                                     ((char *)&sDefault) +
3536                                                     pdiff))
3537                                         continue;
3538                         }
3539
3540                         fprintf(f, "\t%s = ", parm_table[i].label);
3541                         print_parameter(&parm_table[i],
3542                                         ((char *)pService) + pdiff, f);
3543                         fprintf(f, "\n");
3544         }
3545         if (pService->param_opt != NULL) {
3546                 data = pService->param_opt;
3547                 while(data) {
3548                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3549                         data = data->next;
3550                 }
3551         }
3552 }
3553
3554
3555 /***************************************************************************
3556  Return info about the next service  in a service. snum==-1 gives the globals.
3557  Return NULL when out of parameters.
3558 ***************************************************************************/
3559
3560 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3561 {
3562         if (snum == -1) {
3563                 /* do the globals */
3564                 for (; parm_table[*i].label; (*i)++) {
3565                         if (parm_table[*i].class == P_SEPARATOR)
3566                                 return &parm_table[(*i)++];
3567
3568                         if (!parm_table[*i].ptr
3569                             || (*parm_table[*i].label == '-'))
3570                                 continue;
3571
3572                         if ((*i) > 0
3573                             && (parm_table[*i].ptr ==
3574                                 parm_table[(*i) - 1].ptr))
3575                                 continue;
3576
3577                         return &parm_table[(*i)++];
3578                 }
3579         } else {
3580                 service *pService = ServicePtrs[snum];
3581
3582                 for (; parm_table[*i].label; (*i)++) {
3583                         if (parm_table[*i].class == P_SEPARATOR)
3584                                 return &parm_table[(*i)++];
3585
3586                         if (parm_table[*i].class == P_LOCAL &&
3587                             parm_table[*i].ptr &&
3588                             (*parm_table[*i].label != '-') &&
3589                             ((*i) == 0 ||
3590                              (parm_table[*i].ptr !=
3591                               parm_table[(*i) - 1].ptr)))
3592                         {
3593                                 int pdiff =
3594                                         PTR_DIFF(parm_table[*i].ptr,
3595                                                  &sDefault);
3596
3597                                 if (allparameters ||
3598                                     !equal_parameter(parm_table[*i].type,
3599                                                      ((char *)pService) +
3600                                                      pdiff,
3601                                                      ((char *)&sDefault) +
3602                                                      pdiff))
3603                                 {
3604                                         return &parm_table[(*i)++];
3605                                 }
3606                         }
3607                 }
3608         }
3609
3610         return NULL;
3611 }
3612
3613
3614 #if 0
3615 /***************************************************************************
3616  Display the contents of a single copy structure.
3617 ***************************************************************************/
3618 static void dump_copy_map(BOOL *pcopymap)
3619 {
3620         int i;
3621         if (!pcopymap)
3622                 return;
3623
3624         printf("\n\tNon-Copied parameters:\n");
3625
3626         for (i = 0; parm_table[i].label; i++)
3627                 if (parm_table[i].class == P_LOCAL &&
3628                     parm_table[i].ptr && !pcopymap[i] &&
3629                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3630                 {
3631                         printf("\t\t%s\n", parm_table[i].label);
3632                 }
3633 }
3634 #endif
3635
3636 /***************************************************************************
3637  Return TRUE if the passed service number is within range.
3638 ***************************************************************************/
3639
3640 BOOL lp_snum_ok(int iService)
3641 {
3642         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3643 }
3644
3645 /***************************************************************************
3646  Auto-load some home services.
3647 ***************************************************************************/
3648
3649 static void lp_add_auto_services(char *str)
3650 {
3651         char *s;
3652         char *p;
3653         int homes;
3654
3655         if (!str)
3656                 return;
3657
3658         s = strdup(str);
3659         if (!s)
3660                 return;
3661
3662         homes = lp_servicenumber(HOMES_NAME);
3663
3664         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
3665                 char *home = get_user_home_dir(p);
3666
3667                 if (lp_servicenumber(p) >= 0)
3668                         continue;
3669
3670                 if (home && homes >= 0)
3671                         lp_add_home(p, homes, p, home);
3672         }
3673         SAFE_FREE(s);
3674 }
3675
3676 /***************************************************************************
3677  Auto-load one printer.
3678 ***************************************************************************/
3679
3680 void lp_add_one_printer(char *name, char *comment)
3681 {
3682         int printers = lp_servicenumber(PRINTERS_NAME);
3683         int i;
3684
3685         if (lp_servicenumber(name) < 0) {
3686                 lp_add_printer(name, printers);
3687                 if ((i = lp_servicenumber(name)) >= 0) {
3688                         string_set(&ServicePtrs[i]->comment, comment);
3689                         ServicePtrs[i]->autoloaded = True;
3690                 }
3691         }
3692 }
3693
3694 /***************************************************************************
3695  Announce ourselves as a print server.
3696 ***************************************************************************/
3697
3698 void update_server_announce_as_printserver(void)
3699 {
3700         default_server_announce |= SV_TYPE_PRINTQ_SERVER;       
3701 }
3702
3703 /***************************************************************************
3704  Have we loaded a services file yet?
3705 ***************************************************************************/
3706
3707 BOOL lp_loaded(void)
3708 {
3709         return (bLoaded);
3710 }
3711
3712 /***************************************************************************
3713  Unload unused services.
3714 ***************************************************************************/
3715
3716 void lp_killunused(BOOL (*snumused) (int))
3717 {
3718         int i;
3719         for (i = 0; i < iNumServices; i++) {
3720                 if (!VALID(i))
3721                         continue;
3722
3723                 if (!snumused || !snumused(i)) {
3724                         ServicePtrs[i]->valid = False;
3725                         free_service(ServicePtrs[i]);
3726                 }
3727         }
3728 }
3729
3730 /***************************************************************************
3731  Unload a service.
3732 ***************************************************************************/
3733
3734 void lp_killservice(int iServiceIn)
3735 {
3736         if (VALID(iServiceIn)) {
3737                 ServicePtrs[iServiceIn]->valid = False;
3738                 free_service(ServicePtrs[iServiceIn]);
3739         }
3740 }
3741
3742 /***************************************************************************
3743  Save the curent values of all global and sDefault parameters into the 
3744  defaults union. This allows swat and testparm to show only the
3745  changed (ie. non-default) parameters.
3746 ***************************************************************************/
3747
3748 static void lp_save_defaults(void)
3749 {
3750         int i;
3751         for (i = 0; parm_table[i].label; i++) {
3752                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3753                         continue;
3754                 switch (parm_table[i].type) {
3755                         case P_LIST:
3756                                 str_list_copy(&(parm_table[i].def.lvalue),
3757                                             *(const char ***)parm_table[i].ptr);
3758                                 break;
3759                         case P_STRING:
3760                         case P_USTRING:
3761                                 if (parm_table[i].ptr) {
3762                                         parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3763                                 } else {
3764                                         parm_table[i].def.svalue = NULL;
3765                                 }
3766                                 break;
3767                         case P_GSTRING:
3768                         case P_UGSTRING:
3769                                 if (parm_table[i].ptr) {
3770                                         parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
3771                                 } else {
3772                                         parm_table[i].def.svalue = NULL;
3773                                 }
3774                                 break;
3775                         case P_BOOL:
3776                         case P_BOOLREV:
3777                                 parm_table[i].def.bvalue =
3778                                         *(BOOL *)parm_table[i].ptr;
3779                                 break;
3780                         case P_CHAR:
3781                                 parm_table[i].def.cvalue =
3782                                         *(char *)parm_table[i].ptr;
3783                                 break;
3784                         case P_INTEGER:
3785                         case P_OCTAL:
3786                         case P_ENUM:
3787                                 parm_table[i].def.ivalue =
3788                                         *(int *)parm_table[i].ptr;
3789                                 break;
3790                         case P_SEP:
3791                                 break;
3792                 }
3793         }
3794         defaults_saved = True;
3795 }
3796
3797 /*******************************************************************
3798  Set the server type we will announce as via nmbd.
3799 ********************************************************************/
3800
3801 static void set_server_role(void)
3802 {
3803         server_role = ROLE_STANDALONE;
3804
3805         switch (lp_security()) {
3806                 case SEC_SHARE:
3807                 case SEC_SERVER:
3808                 case SEC_ADS:
3809                         if (lp_domain_logons())
3810                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3811                         break;
3812                 case SEC_DOMAIN:
3813                         if (lp_domain_logons()) {
3814                                 server_role = ROLE_DOMAIN_BDC;
3815                                 break;
3816                         }
3817                         server_role = ROLE_DOMAIN_MEMBER;
3818                         break;
3819                 case SEC_USER:
3820                         if (lp_domain_logons()) {
3821
3822                                 if (Globals.bDomainMaster) /* auto or yes */ 
3823                                         server_role = ROLE_DOMAIN_PDC;
3824                                 else
3825                                         server_role = ROLE_DOMAIN_BDC;
3826                         }
3827                         break;
3828                 default:
3829                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3830                         break;
3831         }
3832
3833         DEBUG(10, ("set_server_role: role = "));
3834
3835         switch(server_role) {
3836         case ROLE_STANDALONE:
3837                 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3838                 break;
3839         case ROLE_DOMAIN_MEMBER:
3840                 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3841                 break;
3842         case ROLE_DOMAIN_BDC:
3843                 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3844                 break;
3845         case ROLE_DOMAIN_PDC:
3846                 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3847                 break;
3848         }
3849 }
3850
3851 /***************************************************************************
3852  Load the services array from the services file. Return True on success, 
3853  False on failure.
3854 ***************************************************************************/
3855
3856 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3857              BOOL add_ipc)
3858 {
3859         pstring n2;
3860         BOOL bRetval;
3861         param_opt_struct *data, *pdata;
3862
3863         pstrcpy(n2, pszFname);
3864         standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
3865
3866         add_to_file_list(pszFname, n2);
3867
3868         bRetval = False;
3869
3870         DEBUG(3, ("lp_load: refreshing parameters\n"));
3871         
3872         bInGlobalSection = True;
3873         bGlobalOnly = global_only;
3874
3875         init_globals();
3876         debug_init();
3877
3878         if (save_defaults)
3879         {
3880                 init_locals();
3881                 lp_save_defaults();
3882         }
3883
3884         if (Globals.param_opt != NULL) {
3885                 data = Globals.param_opt;
3886                 while (data) {
3887                         string_free(&data->key);
3888                         string_free(&data->value);
3889                         pdata = data->next;
3890                         SAFE_FREE(data);
3891                         data = pdata;
3892                 }
3893                 Globals.param_opt = NULL;
3894         }
3895         
3896         /* We get sections first, so have to start 'behind' to make up */
3897         iServiceIndex = -1;
3898         bRetval = pm_process(n2, do_section, do_parameter);
3899
3900         /* finish up the last section */
3901         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3902         if (bRetval)
3903                 if (iServiceIndex >= 0)
3904                         bRetval = service_ok(iServiceIndex);
3905
3906         lp_add_auto_services(lp_auto_services());
3907
3908         if (add_ipc) {
3909                 /* When 'restrict anonymous = 2' guest connections to ipc$
3910                    are denied */
3911                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3912                 lp_add_ipc("ADMIN$", False);
3913         }
3914
3915         set_server_role();
3916         set_default_server_announce_type();
3917
3918         bLoaded = True;
3919
3920         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3921         /* if bWINSsupport is true and we are in the client            */
3922         if (in_client && Globals.bWINSsupport) {
3923                 lp_do_parameter(-1, "wins server", "127.0.0.1");
3924         }
3925
3926         init_iconv();
3927
3928         return (bRetval);
3929 }
3930
3931 /***************************************************************************
3932  Reset the max number of services.
3933 ***************************************************************************/
3934
3935 void lp_resetnumservices(void)
3936 {
3937         iNumServices = 0;
3938 }
3939
3940 /***************************************************************************
3941  Return the max number of services.
3942 ***************************************************************************/
3943
3944 int lp_numservices(void)
3945 {
3946         return (iNumServices);
3947 }
3948
3949 /***************************************************************************
3950 Display the contents of the services array in human-readable form.
3951 ***************************************************************************/
3952
3953 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3954 {
3955         int iService;
3956
3957         if (show_defaults)
3958                 defaults_saved = False;
3959
3960         dump_globals(f);
3961
3962         dump_a_service(&sDefault, f);
3963
3964         for (iService = 0; iService < maxtoprint; iService++)
3965                 lp_dump_one(f, show_defaults, iService);
3966 }
3967
3968 /***************************************************************************
3969 Display the contents of one service in human-readable form.
3970 ***************************************************************************/
3971
3972 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3973 {
3974         if (VALID(snum)) {
3975                 if (ServicePtrs[snum]->szService[0] == '\0')
3976                         return;
3977                 dump_a_service(ServicePtrs[snum], f);
3978         }
3979 }
3980
3981 /***************************************************************************
3982 Return the number of the service with the given name, or -1 if it doesn't
3983 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3984 getservicebyname()! This works ONLY if all services have been loaded, and
3985 does not copy the found service.
3986 ***************************************************************************/
3987
3988 int lp_servicenumber(const char *pszServiceName)
3989 {
3990         int iService;
3991         fstring serviceName;
3992  
3993  
3994         for (iService = iNumServices - 1; iService >= 0; iService--) {
3995                 if (VALID(iService) && ServicePtrs[iService]->szService) {
3996                         /*
3997                          * The substitution here is used to support %U is
3998                          * service names
3999                          */
4000                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4001                         standard_sub_basic(current_user_info.smb_name, serviceName,sizeof(serviceName));
4002                         if (strequal(serviceName, pszServiceName))
4003                                 break;
4004                 }
4005         }
4006
4007         if (iService < 0)
4008                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4009
4010         return (iService);
4011 }
4012
4013 /*******************************************************************
4014  A useful volume label function. 
4015 ********************************************************************/
4016
4017 char *volume_label(int snum)
4018 {
4019         char *ret = lp_volume(snum);
4020         if (!*ret)
4021                 return lp_servicename(snum);
4022         return (ret);
4023 }
4024
4025
4026 /*******************************************************************
4027  Set the server type we will announce as via nmbd.
4028 ********************************************************************/
4029
4030 static void set_default_server_announce_type(void)
4031 {
4032         default_server_announce = 0;
4033         default_server_announce |= SV_TYPE_WORKSTATION;
4034         default_server_announce |= SV_TYPE_SERVER;
4035         default_server_announce |= SV_TYPE_SERVER_UNIX;
4036
4037         switch (lp_announce_as()) {
4038                 case ANNOUNCE_AS_NT_SERVER:
4039                         default_server_announce |= SV_TYPE_SERVER_NT;
4040                         /* fall through... */
4041                 case ANNOUNCE_AS_NT_WORKSTATION:
4042                         default_server_announce |= SV_TYPE_NT;
4043                         break;
4044                 case ANNOUNCE_AS_WIN95:
4045                         default_server_announce |= SV_TYPE_WIN95_PLUS;
4046                         break;
4047                 case ANNOUNCE_AS_WFW:
4048                         default_server_announce |= SV_TYPE_WFW;
4049                         break;
4050                 default:
4051                         break;
4052         }
4053
4054         switch (lp_server_role()) {
4055                 case ROLE_DOMAIN_MEMBER:
4056                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4057                         break;
4058                 case ROLE_DOMAIN_PDC:
4059                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4060                         break;
4061                 case ROLE_DOMAIN_BDC:
4062                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4063                         break;
4064                 case ROLE_STANDALONE:
4065                 default:
4066                         break;
4067         }
4068         if (lp_time_server())
4069                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4070
4071         if (lp_host_msdfs())
4072                 default_server_announce |= SV_TYPE_DFS_SERVER;
4073 }
4074
4075 /***********************************************************
4076  returns role of Samba server
4077 ************************************************************/
4078
4079 int lp_server_role(void)
4080 {
4081         return server_role;
4082 }
4083
4084 /***********************************************************
4085  If we are PDC then prefer us as DMB
4086 ************************************************************/
4087
4088 BOOL lp_domain_master(void)
4089 {
4090         if (Globals.bDomainMaster == Auto)
4091                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4092
4093         return Globals.bDomainMaster;
4094 }
4095
4096 /***********************************************************
4097  If we are DMB then prefer us as LMB
4098 ************************************************************/
4099
4100 BOOL lp_preferred_master(void)
4101 {
4102         if (Globals.bPreferredMaster == Auto)
4103                 return (lp_local_master() && lp_domain_master());
4104
4105         return Globals.bPreferredMaster;
4106 }
4107
4108 /*******************************************************************
4109  Remove a service.
4110 ********************************************************************/
4111
4112 void lp_remove_service(int snum)
4113 {
4114         ServicePtrs[snum]->valid = False;
4115 }
4116
4117 /*******************************************************************
4118  Copy a service.
4119 ********************************************************************/
4120
4121 void lp_copy_service(int snum, const char *new_name)
4122 {
4123         char *oldname = lp_servicename(snum);
4124         do_section(new_name);
4125         if (snum >= 0) {
4126                 snum = lp_servicenumber(new_name);
4127                 if (snum >= 0)
4128                         lp_do_parameter(snum, "copy", oldname);
4129         }
4130 }
4131
4132
4133 /*******************************************************************
4134  Get the default server type we will announce as via nmbd.
4135 ********************************************************************/
4136
4137 int lp_default_server_announce(void)
4138 {
4139         return default_server_announce;
4140 }
4141
4142 /*******************************************************************
4143  Split the announce version into major and minor numbers.
4144 ********************************************************************/
4145
4146 int lp_major_announce_version(void)
4147 {
4148         static BOOL got_major = False;
4149         static int major_version = DEFAULT_MAJOR_VERSION;
4150         char *vers;
4151         char *p;
4152
4153         if (got_major)
4154                 return major_version;
4155
4156         got_major = True;
4157         if ((vers = lp_announce_version()) == NULL)
4158                 return major_version;
4159
4160         if ((p = strchr_m(vers, '.')) == 0)
4161                 return major_version;
4162
4163         *p = '\0';
4164         major_version = atoi(vers);
4165         return major_version;
4166 }
4167
4168 int lp_minor_announce_version(void)
4169 {
4170         static BOOL got_minor = False;
4171         static int minor_version = DEFAULT_MINOR_VERSION;
4172         char *vers;
4173         char *p;
4174
4175         if (got_minor)
4176                 return minor_version;
4177
4178         got_minor = True;
4179         if ((vers = lp_announce_version()) == NULL)
4180                 return minor_version;
4181
4182         if ((p = strchr_m(vers, '.')) == 0)
4183                 return minor_version;
4184
4185         p++;
4186         minor_version = atoi(p);
4187         return minor_version;
4188 }
4189
4190 /***********************************************************
4191  Set the global name resolution order (used in smbclient).
4192 ************************************************************/
4193
4194 void lp_set_name_resolve_order(char *new_order)
4195 {
4196         Globals.szNameResolveOrder = new_order;
4197 }
4198
4199 const char *lp_printername(int snum)
4200 {
4201         const char *ret = _lp_printername(snum);
4202         if (ret == NULL || (ret != NULL && *ret == '\0'))
4203                 ret = lp_const_servicename(snum);
4204
4205         return ret;
4206 }
4207
4208
4209 /****************************************************************
4210  Compatibility fn. for 2.2.2 code.....
4211 *****************************************************************/
4212
4213 void get_private_directory(pstring privdir)
4214 {
4215         pstrcpy (privdir, lp_private_dir());
4216 }
4217
4218 /***********************************************************
4219  Allow daemons such as winbindd to fix their logfile name.
4220 ************************************************************/
4221
4222 void lp_set_logfile(const char *name)
4223 {
4224         extern pstring debugf;
4225         string_set(&Globals.szLogFile, name);
4226         pstrcpy(debugf, name);
4227 }
4228
4229 /*******************************************************************
4230  Return the NetBIOS called name.
4231 ********************************************************************/
4232
4233 const char *get_called_name(void)
4234 {
4235         extern fstring local_machine;
4236         static fstring called_name;
4237
4238         if (! *local_machine)
4239                 return global_myname();
4240
4241         /*
4242          * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
4243          * arrggg!!! but we've already rewritten the client's
4244          * netbios name at this point...
4245          */
4246
4247         if (*local_machine) {
4248                 if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) {
4249                         fstrcpy(called_name, get_my_primary_ip());
4250                         DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
4251                                 called_name));
4252                         return called_name;
4253                 }
4254         }
4255
4256         return local_machine;
4257 }
4258
4259 /*******************************************************************
4260  Return the max print jobs per queue.
4261 ********************************************************************/
4262
4263 int lp_maxprintjobs(int snum)
4264 {
4265         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4266         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4267                 maxjobs = PRINT_MAX_JOBID - 1;
4268
4269         return maxjobs;
4270 }