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