86446d5b75f73c91759aaeeb0d90155a44073c24
[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    Copyright (C) Michael Adam 2008
13    
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18    
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23    
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 #include "libnet/libnet.h"
56
57 bool in_client = False;         /* Not in the client by default */
58 bool bLoaded = False;
59
60 extern enum protocol_types Protocol;
61 extern userdom_struct current_user_info;
62
63 #ifndef GLOBAL_NAME
64 #define GLOBAL_NAME "global"
65 #endif
66
67 #ifndef PRINTERS_NAME
68 #define PRINTERS_NAME "printers"
69 #endif
70
71 #ifndef HOMES_NAME
72 #define HOMES_NAME "homes"
73 #endif
74
75 static uint64_t conf_last_seqnum = 0;
76 static struct libnet_conf_ctx *conf_ctx = NULL;
77
78 #define CONFIG_BACKEND_FILE 0
79 #define CONFIG_BACKEND_REGISTRY 1
80
81 static int config_backend = CONFIG_BACKEND_FILE;
82
83 /* some helpful bits */
84 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
85 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
86
87 #define USERSHARE_VALID 1
88 #define USERSHARE_PENDING_DELETE 2
89
90 extern int extra_time_offset;
91
92 static bool defaults_saved = False;
93
94 typedef struct _param_opt_struct param_opt_struct;
95 struct _param_opt_struct {
96         param_opt_struct *prev, *next;
97         char *key;
98         char *value;
99         char **list;
100 };
101
102 /* 
103  * This structure describes global (ie., server-wide) parameters.
104  */
105 typedef struct {
106         int ConfigBackend;
107         char *smb_ports;
108         char *dos_charset;
109         char *unix_charset;
110         char *display_charset;
111         char *szPrintcapname;
112         char *szAddPortCommand;
113         char *szEnumPortsCommand;
114         char *szAddPrinterCommand;
115         char *szDeletePrinterCommand;
116         char *szOs2DriverMap;
117         char *szLockDir;
118         char *szPidDir;
119         char *szRootdir;
120         char *szDefaultService;
121         char *szGetQuota;
122         char *szSetQuota;
123         char *szMsgCommand;
124         char *szServerString;
125         char *szAutoServices;
126         char *szPasswdProgram;
127         char *szPasswdChat;
128         char *szLogFile;
129         char *szConfigFile;
130         char *szSMBPasswdFile;
131         char *szPrivateDir;
132         char *szPassdbBackend;
133         char **szPreloadModules;
134         char *szPasswordServer;
135         char *szSocketOptions;
136         char *szRealm;
137         char *szAfsUsernameMap;
138         int iAfsTokenLifetime;
139         char *szLogNtTokenCommand;
140         char *szUsernameMap;
141         char *szLogonScript;
142         char *szLogonPath;
143         char *szLogonDrive;
144         char *szLogonHome;
145         char **szWINSservers;
146         char **szInterfaces;
147         char *szRemoteAnnounce;
148         char *szRemoteBrowseSync;
149         char *szSocketAddress;
150         char *szNISHomeMapName;
151         char *szAnnounceVersion;        /* This is initialised in init_globals */
152         char *szWorkgroup;
153         char *szNetbiosName;
154         char **szNetbiosAliases;
155         char *szNetbiosScope;
156         char *szNameResolveOrder;
157         char *szPanicAction;
158         char *szAddUserScript;
159         char *szRenameUserScript;
160         char *szDelUserScript;
161         char *szAddGroupScript;
162         char *szDelGroupScript;
163         char *szAddUserToGroupScript;
164         char *szDelUserFromGroupScript;
165         char *szSetPrimaryGroupScript;
166         char *szAddMachineScript;
167         char *szShutdownScript;
168         char *szAbortShutdownScript;
169         char *szUsernameMapScript;
170         char *szCheckPasswordScript;
171         char *szWINSHook;
172         char *szUtmpDir;
173         char *szWtmpDir;
174         bool bUtmp;
175         char *szIdmapUID;
176         char *szIdmapGID;
177         bool bPassdbExpandExplicit;
178         int AlgorithmicRidBase;
179         char *szTemplateHomedir;
180         char *szTemplateShell;
181         char *szWinbindSeparator;
182         bool bWinbindEnumUsers;
183         bool bWinbindEnumGroups;
184         bool bWinbindUseDefaultDomain;
185         bool bWinbindTrustedDomainsOnly;
186         bool bWinbindNestedGroups;
187         int  winbind_expand_groups;
188         bool bWinbindRefreshTickets;
189         bool bWinbindOfflineLogon;
190         bool bWinbindNormalizeNames;
191         bool bWinbindRpcOnly;
192         char **szIdmapDomains;
193         char **szIdmapBackend; /* deprecated */
194         char *szIdmapAllocBackend;
195         char *szAddShareCommand;
196         char *szChangeShareCommand;
197         char *szDeleteShareCommand;
198         char **szEventLogs;
199         char *szGuestaccount;
200         char *szManglingMethod;
201         char **szServicesList;
202         char *szUsersharePath;
203         char *szUsershareTemplateShare;
204         char **szUsersharePrefixAllowList;
205         char **szUsersharePrefixDenyList;
206         int mangle_prefix;
207         int max_log_size;
208         char *szLogLevel;
209         int max_xmit;
210         int max_mux;
211         int max_open_files;
212         int open_files_db_hash_size;
213         int pwordlevel;
214         int unamelevel;
215         int deadtime;
216         bool getwd_cache;
217         int maxprotocol;
218         int minprotocol;
219         int security;
220         char **AuthMethods;
221         bool paranoid_server_security;
222         int maxdisksize;
223         int lpqcachetime;
224         int iMaxSmbdProcesses;
225         bool bDisableSpoolss;
226         int syslog;
227         int os_level;
228         bool enhanced_browsing;
229         int max_ttl;
230         int max_wins_ttl;
231         int min_wins_ttl;
232         int lm_announce;
233         int lm_interval;
234         int announce_as;        /* This is initialised in init_globals */
235         int machine_password_timeout;
236         int map_to_guest;
237         int oplock_break_wait_time;
238         int winbind_cache_time;
239         int winbind_max_idle_children;
240         char **szWinbindNssInfo;
241         int iLockSpinTime;
242         char *szLdapMachineSuffix;
243         char *szLdapUserSuffix;
244         char *szLdapIdmapSuffix;
245         char *szLdapGroupSuffix;
246         int ldap_ssl;
247         char *szLdapSuffix;
248         char *szLdapAdminDn;
249         int ldap_debug_level;
250         int ldap_debug_threshold;
251         int iAclCompat;
252         char *szCupsServer;
253         char *szIPrintServer;
254         char *ctdbdSocket;
255         char **szClusterAddresses;
256         bool clustering;
257         int ldap_passwd_sync;
258         int ldap_replication_sleep;
259         int ldap_timeout; /* This is initialised in init_globals */
260         int ldap_page_size;
261         bool ldap_delete_dn;
262         bool bMsAddPrinterWizard;
263         bool bDNSproxy;
264         bool bWINSsupport;
265         bool bWINSproxy;
266         bool bLocalMaster;
267         int  iPreferredMaster;
268         int iDomainMaster;
269         bool bDomainLogons;
270         bool bEncryptPasswords;
271         bool bUpdateEncrypt;
272         int  clientSchannel;
273         int  serverSchannel;
274         bool bNullPasswords;
275         bool bObeyPamRestrictions;
276         bool bLoadPrinters;
277         int PrintcapCacheTime;
278         bool bLargeReadwrite;
279         bool bReadRaw;
280         bool bWriteRaw;
281         bool bSyslogOnly;
282         bool bBrowseList;
283         bool bNISHomeMap;
284         bool bTimeServer;
285         bool bBindInterfacesOnly;
286         bool bPamPasswordChange;
287         bool bUnixPasswdSync;
288         bool bPasswdChatDebug;
289         int iPasswdChatTimeout;
290         bool bTimestampLogs;
291         bool bNTSmbSupport;
292         bool bNTPipeSupport;
293         bool bNTStatusSupport;
294         bool bStatCache;
295         int iMaxStatCacheSize;
296         bool bKernelOplocks;
297         bool bAllowTrustedDomains;
298         bool bLanmanAuth;
299         bool bNTLMAuth;
300         bool bUseSpnego;
301         bool bClientLanManAuth;
302         bool bClientNTLMv2Auth;
303         bool bClientPlaintextAuth;
304         bool bClientUseSpnego;
305         bool bDebugPrefixTimestamp;
306         bool bDebugHiresTimestamp;
307         bool bDebugPid;
308         bool bDebugUid;
309         bool bDebugClass;
310         bool bEnableCoreFiles;
311         bool bHostMSDfs;
312         bool bUseMmap;
313         bool bHostnameLookups;
314         bool bUnixExtensions;
315         bool bDisableNetbios;
316         bool bUseKerberosKeytab;
317         bool bDeferSharingViolations;
318         bool bEnablePrivileges;
319         bool bASUSupport;
320         bool bUsershareOwnerOnly;
321         bool bUsershareAllowGuests;
322         bool bRegistryShares;
323         int restrict_anonymous;
324         int name_cache_timeout;
325         int client_signing;
326         int server_signing;
327         int client_ldap_sasl_wrapping;
328         int iUsershareMaxShares;
329         int iIdmapCacheTime;
330         int iIdmapNegativeCacheTime;
331
332         bool bResetOnZeroVC;
333         int iKeepalive;
334         int iminreceivefile;
335         param_opt_struct *param_opt;
336 } global;
337
338 static global Globals;
339
340 /* 
341  * This structure describes a single service. 
342  */
343 typedef struct {
344         bool valid;
345         bool autoloaded;
346         int usershare;
347         time_t usershare_last_mod;
348         char *szService;
349         char *szPath;
350         char *szUsername;
351         char **szInvalidUsers;
352         char **szValidUsers;
353         char **szAdminUsers;
354         char *szCopy;
355         char *szInclude;
356         char *szPreExec;
357         char *szPostExec;
358         char *szRootPreExec;
359         char *szRootPostExec;
360         char *szCupsOptions;
361         char *szPrintcommand;
362         char *szLpqcommand;
363         char *szLprmcommand;
364         char *szLppausecommand;
365         char *szLpresumecommand;
366         char *szQueuepausecommand;
367         char *szQueueresumecommand;
368         char *szPrintername;
369         char *szPrintjobUsername;
370         char *szDontdescend;
371         char **szHostsallow;
372         char **szHostsdeny;
373         char *szMagicScript;
374         char *szMagicOutput;
375         char *szVetoFiles;
376         char *szHideFiles;
377         char *szVetoOplockFiles;
378         char *comment;
379         char *force_user;
380         char *force_group;
381         char **readlist;
382         char **writelist;
383         char **printer_admin;
384         char *volume;
385         char *fstype;
386         char **szVfsObjects;
387         char *szMSDfsProxy;
388         char *szAioWriteBehind;
389         char *szDfree;
390         int iMinPrintSpace;
391         int iMaxPrintJobs;
392         int iMaxReportedPrintJobs;
393         int iWriteCacheSize;
394         int iCreate_mask;
395         int iCreate_force_mode;
396         int iSecurity_mask;
397         int iSecurity_force_mode;
398         int iDir_mask;
399         int iDir_force_mode;
400         int iDir_Security_mask;
401         int iDir_Security_force_mode;
402         int iMaxConnections;
403         int iDefaultCase;
404         int iPrinting;
405         int iOplockContentionLimit;
406         int iCSCPolicy;
407         int iBlock_size;
408         int iDfreeCacheTime;
409         bool bPreexecClose;
410         bool bRootpreexecClose;
411         int  iCaseSensitive;
412         bool bCasePreserve;
413         bool bShortCasePreserve;
414         bool bHideDotFiles;
415         bool bHideSpecialFiles;
416         bool bHideUnReadable;
417         bool bHideUnWriteableFiles;
418         bool bBrowseable;
419         bool bAvailable;
420         bool bRead_only;
421         bool bNo_set_dir;
422         bool bGuest_only;
423         bool bGuest_ok;
424         bool bPrint_ok;
425         bool bMap_system;
426         bool bMap_hidden;
427         bool bMap_archive;
428         bool bStoreDosAttributes;
429         bool bDmapiSupport;
430         bool bLocking;
431         int iStrictLocking;
432         bool bPosixLocking;
433         bool bShareModes;
434         bool bOpLocks;
435         bool bLevel2OpLocks;
436         bool bOnlyUser;
437         bool bMangledNames;
438         bool bWidelinks;
439         bool bSymlinks;
440         bool bSyncAlways;
441         bool bStrictAllocate;
442         bool bStrictSync;
443         char magic_char;
444         struct bitmap *copymap;
445         bool bDeleteReadonly;
446         bool bFakeOplocks;
447         bool bDeleteVetoFiles;
448         bool bDosFilemode;
449         bool bDosFiletimes;
450         bool bDosFiletimeResolution;
451         bool bFakeDirCreateTimes;
452         bool bBlockingLocks;
453         bool bInheritPerms;
454         bool bInheritACLS;
455         bool bInheritOwner;
456         bool bMSDfsRoot;
457         bool bUseClientDriver;
458         bool bDefaultDevmode;
459         bool bForcePrintername;
460         bool bNTAclSupport;
461         bool bForceUnknownAclUser;
462         bool bUseSendfile;
463         bool bProfileAcls;
464         bool bMap_acl_inherit;
465         bool bAfs_Share;
466         bool bEASupport;
467         bool bAclCheckPermissions;
468         bool bAclMapFullControl;
469         bool bAclGroupControl;
470         bool bChangeNotify;
471         bool bKernelChangeNotify;
472         int iallocation_roundup_size;
473         int iAioReadSize;
474         int iAioWriteSize;
475         int iMap_readonly;
476         int iDirectoryNameCacheSize;
477         int ismb_encrypt;
478         param_opt_struct *param_opt;
479
480         char dummy[3];          /* for alignment */
481 } service;
482
483
484 /* This is a default service used to prime a services structure */
485 static service sDefault = {
486         True,                   /* valid */
487         False,                  /* not autoloaded */
488         0,                      /* not a usershare */
489         (time_t)0,              /* No last mod time */
490         NULL,                   /* szService */
491         NULL,                   /* szPath */
492         NULL,                   /* szUsername */
493         NULL,                   /* szInvalidUsers */
494         NULL,                   /* szValidUsers */
495         NULL,                   /* szAdminUsers */
496         NULL,                   /* szCopy */
497         NULL,                   /* szInclude */
498         NULL,                   /* szPreExec */
499         NULL,                   /* szPostExec */
500         NULL,                   /* szRootPreExec */
501         NULL,                   /* szRootPostExec */
502         NULL,                   /* szCupsOptions */
503         NULL,                   /* szPrintcommand */
504         NULL,                   /* szLpqcommand */
505         NULL,                   /* szLprmcommand */
506         NULL,                   /* szLppausecommand */
507         NULL,                   /* szLpresumecommand */
508         NULL,                   /* szQueuepausecommand */
509         NULL,                   /* szQueueresumecommand */
510         NULL,                   /* szPrintername */
511         NULL,                   /* szPrintjobUsername */
512         NULL,                   /* szDontdescend */
513         NULL,                   /* szHostsallow */
514         NULL,                   /* szHostsdeny */
515         NULL,                   /* szMagicScript */
516         NULL,                   /* szMagicOutput */
517         NULL,                   /* szVetoFiles */
518         NULL,                   /* szHideFiles */
519         NULL,                   /* szVetoOplockFiles */
520         NULL,                   /* comment */
521         NULL,                   /* force user */
522         NULL,                   /* force group */
523         NULL,                   /* readlist */
524         NULL,                   /* writelist */
525         NULL,                   /* printer admin */
526         NULL,                   /* volume */
527         NULL,                   /* fstype */
528         NULL,                   /* vfs objects */
529         NULL,                   /* szMSDfsProxy */
530         NULL,                   /* szAioWriteBehind */
531         NULL,                   /* szDfree */
532         0,                      /* iMinPrintSpace */
533         1000,                   /* iMaxPrintJobs */
534         0,                      /* iMaxReportedPrintJobs */
535         0,                      /* iWriteCacheSize */
536         0744,                   /* iCreate_mask */
537         0000,                   /* iCreate_force_mode */
538         0777,                   /* iSecurity_mask */
539         0,                      /* iSecurity_force_mode */
540         0755,                   /* iDir_mask */
541         0000,                   /* iDir_force_mode */
542         0777,                   /* iDir_Security_mask */
543         0,                      /* iDir_Security_force_mode */
544         0,                      /* iMaxConnections */
545         CASE_LOWER,             /* iDefaultCase */
546         DEFAULT_PRINTING,       /* iPrinting */
547         2,                      /* iOplockContentionLimit */
548         0,                      /* iCSCPolicy */
549         1024,                   /* iBlock_size */
550         0,                      /* iDfreeCacheTime */
551         False,                  /* bPreexecClose */
552         False,                  /* bRootpreexecClose */
553         Auto,                   /* case sensitive */
554         True,                   /* case preserve */
555         True,                   /* short case preserve */
556         True,                   /* bHideDotFiles */
557         False,                  /* bHideSpecialFiles */
558         False,                  /* bHideUnReadable */
559         False,                  /* bHideUnWriteableFiles */
560         True,                   /* bBrowseable */
561         True,                   /* bAvailable */
562         True,                   /* bRead_only */
563         True,                   /* bNo_set_dir */
564         False,                  /* bGuest_only */
565         False,                  /* bGuest_ok */
566         False,                  /* bPrint_ok */
567         False,                  /* bMap_system */
568         False,                  /* bMap_hidden */
569         True,                   /* bMap_archive */
570         False,                  /* bStoreDosAttributes */
571         False,                  /* bDmapiSupport */
572         True,                   /* bLocking */
573         Auto,                   /* iStrictLocking */
574         True,                   /* bPosixLocking */
575         True,                   /* bShareModes */
576         True,                   /* bOpLocks */
577         True,                   /* bLevel2OpLocks */
578         False,                  /* bOnlyUser */
579         True,                   /* bMangledNames */
580         True,                   /* bWidelinks */
581         True,                   /* bSymlinks */
582         False,                  /* bSyncAlways */
583         False,                  /* bStrictAllocate */
584         False,                  /* bStrictSync */
585         '~',                    /* magic char */
586         NULL,                   /* copymap */
587         False,                  /* bDeleteReadonly */
588         False,                  /* bFakeOplocks */
589         False,                  /* bDeleteVetoFiles */
590         False,                  /* bDosFilemode */
591         True,                   /* bDosFiletimes */
592         False,                  /* bDosFiletimeResolution */
593         False,                  /* bFakeDirCreateTimes */
594         True,                   /* bBlockingLocks */
595         False,                  /* bInheritPerms */
596         False,                  /* bInheritACLS */
597         False,                  /* bInheritOwner */
598         False,                  /* bMSDfsRoot */
599         False,                  /* bUseClientDriver */
600         True,                   /* bDefaultDevmode */
601         False,                  /* bForcePrintername */
602         True,                   /* bNTAclSupport */
603         False,                  /* bForceUnknownAclUser */
604         False,                  /* bUseSendfile */
605         False,                  /* bProfileAcls */
606         False,                  /* bMap_acl_inherit */
607         False,                  /* bAfs_Share */
608         False,                  /* bEASupport */
609         True,                   /* bAclCheckPermissions */
610         True,                   /* bAclMapFullControl */
611         False,                  /* bAclGroupControl */
612         True,                   /* bChangeNotify */
613         True,                   /* bKernelChangeNotify */
614         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
615         0,                      /* iAioReadSize */
616         0,                      /* iAioWriteSize */
617         MAP_READONLY_YES,       /* iMap_readonly */
618 #ifdef BROKEN_DIRECTORY_HANDLING
619         0,                      /* iDirectoryNameCacheSize */
620 #else
621         100,                    /* iDirectoryNameCacheSize */
622 #endif
623         Auto,                   /* ismb_encrypt */
624         NULL,                   /* Parametric options */
625
626         ""                      /* dummy */
627 };
628
629 /* local variables */
630 static service **ServicePtrs = NULL;
631 static int iNumServices = 0;
632 static int iServiceIndex = 0;
633 static struct db_context *ServiceHash;
634 static int *invalid_services = NULL;
635 static int num_invalid_services = 0;
636 static bool bInGlobalSection = True;
637 static bool bGlobalOnly = False;
638 static int server_role;
639 static int default_server_announce;
640
641 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
642
643 /* prototypes for the special type handlers */
644 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
645 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
647 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
648 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
649 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
650 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
652 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
653 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
654 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
656
657 static void set_server_role(void);
658 static void set_default_server_announce_type(void);
659 static void set_allowed_client_auth(void);
660
661 static const struct enum_list enum_protocol[] = {
662         {PROTOCOL_NT1, "NT1"},
663         {PROTOCOL_LANMAN2, "LANMAN2"},
664         {PROTOCOL_LANMAN1, "LANMAN1"},
665         {PROTOCOL_CORE, "CORE"},
666         {PROTOCOL_COREPLUS, "COREPLUS"},
667         {PROTOCOL_COREPLUS, "CORE+"},
668         {-1, NULL}
669 };
670
671 static const struct enum_list enum_security[] = {
672         {SEC_SHARE, "SHARE"},
673         {SEC_USER, "USER"},
674         {SEC_SERVER, "SERVER"},
675         {SEC_DOMAIN, "DOMAIN"},
676 #ifdef HAVE_ADS
677         {SEC_ADS, "ADS"},
678 #endif
679         {-1, NULL}
680 };
681
682 static const struct enum_list enum_printing[] = {
683         {PRINT_SYSV, "sysv"},
684         {PRINT_AIX, "aix"},
685         {PRINT_HPUX, "hpux"},
686         {PRINT_BSD, "bsd"},
687         {PRINT_QNX, "qnx"},
688         {PRINT_PLP, "plp"},
689         {PRINT_LPRNG, "lprng"},
690         {PRINT_CUPS, "cups"},
691         {PRINT_IPRINT, "iprint"},
692         {PRINT_LPRNT, "nt"},
693         {PRINT_LPROS2, "os2"},
694 #ifdef DEVELOPER
695         {PRINT_TEST, "test"},
696         {PRINT_VLP, "vlp"},
697 #endif /* DEVELOPER */
698         {-1, NULL}
699 };
700
701 static const struct enum_list enum_ldap_sasl_wrapping[] = {
702         {0, "plain"},
703         {ADS_AUTH_SASL_SIGN, "sign"},
704         {ADS_AUTH_SASL_SEAL, "seal"},
705         {-1, NULL}
706 };
707
708 static const struct enum_list enum_ldap_ssl[] = {
709         {LDAP_SSL_OFF, "no"},
710         {LDAP_SSL_OFF, "No"},
711         {LDAP_SSL_OFF, "off"},
712         {LDAP_SSL_OFF, "Off"},
713         {LDAP_SSL_START_TLS, "start tls"},
714         {LDAP_SSL_START_TLS, "Start_tls"},
715         {-1, NULL}
716 };
717
718 static const struct enum_list enum_ldap_passwd_sync[] = {
719         {LDAP_PASSWD_SYNC_OFF, "no"},
720         {LDAP_PASSWD_SYNC_OFF, "No"},
721         {LDAP_PASSWD_SYNC_OFF, "off"},
722         {LDAP_PASSWD_SYNC_OFF, "Off"},
723         {LDAP_PASSWD_SYNC_ON, "Yes"},
724         {LDAP_PASSWD_SYNC_ON, "yes"},
725         {LDAP_PASSWD_SYNC_ON, "on"},
726         {LDAP_PASSWD_SYNC_ON, "On"},
727         {LDAP_PASSWD_SYNC_ONLY, "Only"},
728         {LDAP_PASSWD_SYNC_ONLY, "only"},
729         {-1, NULL}
730 };
731
732 /* Types of machine we can announce as. */
733 #define ANNOUNCE_AS_NT_SERVER 1
734 #define ANNOUNCE_AS_WIN95 2
735 #define ANNOUNCE_AS_WFW 3
736 #define ANNOUNCE_AS_NT_WORKSTATION 4
737
738 static const struct enum_list enum_announce_as[] = {
739         {ANNOUNCE_AS_NT_SERVER, "NT"},
740         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
741         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
742         {ANNOUNCE_AS_WIN95, "win95"},
743         {ANNOUNCE_AS_WFW, "WfW"},
744         {-1, NULL}
745 };
746
747 static const struct enum_list enum_map_readonly[] = {
748         {MAP_READONLY_NO, "no"},
749         {MAP_READONLY_NO, "false"},
750         {MAP_READONLY_NO, "0"},
751         {MAP_READONLY_YES, "yes"},
752         {MAP_READONLY_YES, "true"},
753         {MAP_READONLY_YES, "1"},
754         {MAP_READONLY_PERMISSIONS, "permissions"},
755         {MAP_READONLY_PERMISSIONS, "perms"},
756         {-1, NULL}
757 };
758
759 static const struct enum_list enum_case[] = {
760         {CASE_LOWER, "lower"},
761         {CASE_UPPER, "upper"},
762         {-1, NULL}
763 };
764
765 static const struct enum_list enum_bool_auto[] = {
766         {False, "No"},
767         {False, "False"},
768         {False, "0"},
769         {True, "Yes"},
770         {True, "True"},
771         {True, "1"},
772         {Auto, "Auto"},
773         {-1, NULL}
774 };
775
776 /* Client-side offline caching policy types */
777 #define CSC_POLICY_MANUAL 0
778 #define CSC_POLICY_DOCUMENTS 1
779 #define CSC_POLICY_PROGRAMS 2
780 #define CSC_POLICY_DISABLE 3
781
782 static const struct enum_list enum_csc_policy[] = {
783         {CSC_POLICY_MANUAL, "manual"},
784         {CSC_POLICY_DOCUMENTS, "documents"},
785         {CSC_POLICY_PROGRAMS, "programs"},
786         {CSC_POLICY_DISABLE, "disable"},
787         {-1, NULL}
788 };
789
790 /* SMB signing types. */
791 static const struct enum_list enum_smb_signing_vals[] = {
792         {False, "No"},
793         {False, "False"},
794         {False, "0"},
795         {False, "Off"},
796         {False, "disabled"},
797         {True, "Yes"},
798         {True, "True"},
799         {True, "1"},
800         {True, "On"},
801         {True, "enabled"},
802         {Auto, "auto"},
803         {Required, "required"},
804         {Required, "mandatory"},
805         {Required, "force"},
806         {Required, "forced"},
807         {Required, "enforced"},
808         {-1, NULL}
809 };
810
811 /* ACL compatibility options. */
812 static const struct enum_list enum_acl_compat_vals[] = {
813     { ACL_COMPAT_AUTO, "auto" },
814     { ACL_COMPAT_WINNT, "winnt" },
815     { ACL_COMPAT_WIN2K, "win2k" },
816     { -1, NULL}
817 };
818
819 /* 
820    Do you want session setups at user level security with a invalid
821    password to be rejected or allowed in as guest? WinNT rejects them
822    but it can be a pain as it means "net view" needs to use a password
823
824    You have 3 choices in the setting of map_to_guest:
825
826    "Never" means session setups with an invalid password
827    are rejected. This is the default.
828
829    "Bad User" means session setups with an invalid password
830    are rejected, unless the username does not exist, in which case it
831    is treated as a guest login
832
833    "Bad Password" means session setups with an invalid password
834    are treated as a guest login
835
836    Note that map_to_guest only has an effect in user or server
837    level security.
838 */
839
840 static const struct enum_list enum_map_to_guest[] = {
841         {NEVER_MAP_TO_GUEST, "Never"},
842         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
843         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
844         {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
845         {-1, NULL}
846 };
847
848 /* Config backend options */
849
850 static const struct enum_list enum_config_backend[] = {
851         {CONFIG_BACKEND_FILE, "file"},
852         {CONFIG_BACKEND_REGISTRY, "registry"},
853         {-1, NULL}
854 };
855
856 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
857  *
858  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
859  * screen in SWAT. This is used to exclude parameters as well as to squash all
860  * parameters that have been duplicated by pseudonyms.
861  *
862  * NOTE: To display a parameter in BASIC view set FLAG_BASIC
863  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
864  *       Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
865  *        respective views.
866  *
867  * NOTE2: Handling of duplicated (synonym) paramters:
868  *      Only the first occurance of a parameter should be enabled by FLAG_BASIC
869  *      and/or FLAG_ADVANCED. All duplicates following the first mention should be
870  *      set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
871  *      name first, and all synonyms must follow it with the FLAG_HIDE attribute.
872  */
873
874 static struct parm_struct parm_table[] = {
875         {N_("Base Options"), P_SEP, P_SEPARATOR}, 
876
877         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED}, 
878         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED}, 
879         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED}, 
880         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
881         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
882         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, 
883         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
884 #ifdef WITH_ADS
885         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
886 #endif
887         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
888         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases,  NULL, FLAG_ADVANCED}, 
889         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope,  NULL, FLAG_ADVANCED}, 
890         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED }, 
891         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
892         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
893
894         {"config backend", P_ENUM, P_GLOBAL, &Globals.ConfigBackend, NULL, enum_config_backend, FLAG_ADVANCED},
895
896         {N_("Security Options"), P_SEP, P_SEPARATOR}, 
897
898         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
899         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED}, 
900         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
901         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED}, 
902         {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
903         {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
904         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED}, 
905         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED}, 
906         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED}, 
907         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED}, 
908         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
909         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED}, 
910         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED}, 
911         {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
912         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED}, 
913         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED}, 
914         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
915         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
916         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
917         {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED}, 
918
919         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED}, 
920         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, 
921         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, 
922         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, 
923         {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED}, 
924         {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED}, 
925         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
926         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, 
927         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, 
928         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED}, 
929         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED}, 
930         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED}, 
931         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED}, 
932         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED}, 
933         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED}, 
934         {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED}, 
935
936         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
937         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
938         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
939
940         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
941         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
942         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
943         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
944         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
945         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED }, 
946         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
947         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
948         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED}, 
949
950         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, 
951         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
952         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
953         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
954
955         {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
956         {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
957         {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
958         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
959         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, 
960         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
961         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
962         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
963         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
964         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
965         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
966         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
967         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
968         {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
969         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
970         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
971         {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
972         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
973         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, 
974
975         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
976         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, 
977
978         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
979         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
980         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, 
981         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
982         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, 
983         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
984         {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED}, 
985
986         {N_("Logging Options"), P_SEP, P_SEPARATOR}, 
987
988         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED}, 
989         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, 
990         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED}, 
991         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED}, 
992         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED}, 
993
994         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED}, 
995         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
996         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
997         {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED}, 
998         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED}, 
999         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED}, 
1000         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED}, 
1001         {"debug class", P_BOOL, P_GLOBAL, &Globals.bDebugClass, NULL, NULL, FLAG_ADVANCED},
1002         {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
1003
1004         {N_("Protocol Options"), P_SEP, P_SEPARATOR}, 
1005
1006         {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, 
1007         {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED}, 
1008         {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED}, 
1009         {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1010         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, 
1011         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, 
1012         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
1013         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
1014         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
1015         {"min receivefile size", P_INTEGER, P_GLOBAL, &Globals.iminreceivefile, NULL, NULL, FLAG_ADVANCED}, 
1016         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED}, 
1017         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED}, 
1018         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED}, 
1019         {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED}, 
1020
1021         {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL,  enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1022         {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1023         {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1024         {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1025         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED}, 
1026         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED}, 
1027         {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
1028
1029         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED}, 
1030         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as,  FLAG_ADVANCED}, 
1031         {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1032         {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1033         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED}, 
1034         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED}, 
1035
1036         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
1037         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED}, 
1038         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
1039         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
1040         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED}, 
1041         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED}, 
1042         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
1043         {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
1044         {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
1045         {"smb encrypt", P_ENUM, P_LOCAL, &sDefault.ismb_encrypt, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1046         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
1047         {"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
1048         {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED}, 
1049         {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1050
1051         {N_("Tuning Options"), P_SEP, P_SEPARATOR}, 
1052
1053         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1054         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED}, 
1055         {"getwd cache", P_BOOL, P_GLOBAL, &Globals.getwd_cache, NULL, NULL, FLAG_ADVANCED},
1056         {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1057         {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1058         {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1059         {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1060
1061         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED}, 
1062         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED}, 
1063         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1064         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED}, 
1065         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED}, 
1066         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, 
1067         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1068
1069         {"socket options", P_STRING, P_GLOBAL, &Globals.szSocketOptions, NULL, NULL, FLAG_ADVANCED},
1070         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1071         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1072         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1073         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED}, 
1074         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1075         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED}, 
1076         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
1077
1078         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED}, 
1079         {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1080         {"cluster addresses", P_LIST, P_GLOBAL, &Globals.szClusterAddresses, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1081         {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1082
1083         {N_("Printing Options"), P_SEP, P_SEPARATOR}, 
1084
1085         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1086         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1087         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1088         {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1089         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1090         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, 
1091         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1092         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, 
1093         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1094         {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1095         {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1096         {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1097         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1098         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1099         {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE}, 
1100         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1101         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1102         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1103         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1104         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1105         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1106
1107         {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED}, 
1108         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED}, 
1109         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
1110         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
1111         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED}, 
1112         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED}, 
1113
1114         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1115         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, 
1116         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1117         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1118         {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1119         {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1120
1121         {N_("Filename Handling"), P_SEP, P_SEPARATOR}, 
1122         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED}, 
1123         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED}, 
1124
1125         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE}, 
1126         {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1127         {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE}, 
1128         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1129         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1130         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1131         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1132         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1133         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1134         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1135         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1136         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1137         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1138         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1139         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1140         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1141         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1142         {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1143         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1144         {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, 
1145         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, 
1146         {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1147         {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1148
1149
1150         {N_("Domain Options"), P_SEP, P_SEPARATOR}, 
1151
1152         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
1153
1154         {N_("Logon Options"), P_SEP, P_SEPARATOR}, 
1155
1156         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, 
1157         {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1158         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, 
1159         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1160         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1161         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1162         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1163         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1164         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED}, 
1165         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
1166         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
1167         {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED}, 
1168
1169         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED}, 
1170         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED}, 
1171         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED}, 
1172         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED}, 
1173         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED}, 
1174
1175         {N_("Browse Options"), P_SEP, P_SEPARATOR}, 
1176
1177         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
1178         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED}, 
1179         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED}, 
1180         {"preferred master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
1181         {"prefered master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, 
1182         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
1183         {"domain master", P_ENUM, P_GLOBAL, &Globals.iDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
1184         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED}, 
1185         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1186         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, 
1187         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED}, 
1188
1189         {N_("WINS Options"), P_SEP, P_SEPARATOR}, 
1190
1191         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED}, 
1192         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED}, 
1193
1194         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
1195         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
1196         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED}, 
1197
1198         {N_("Locking Options"), P_SEP, P_SEPARATOR}, 
1199
1200         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1201         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1202         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1203         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1204         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1205         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1206
1207         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1208         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1209         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1210         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1211         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1212         {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1213         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1214
1215         {N_("Ldap Options"), P_SEP, P_SEPARATOR}, 
1216
1217         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, 
1218         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, 
1219         {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, 
1220         {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, 
1221         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED}, 
1222         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, 
1223         {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE}, 
1224         {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1225         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, 
1226         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, 
1227         {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1228         {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1229         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, 
1230
1231         {"ldap debug level", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_level, handle_ldap_debug_level, NULL, FLAG_ADVANCED},
1232         {"ldap debug threshold", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_threshold, NULL, NULL, FLAG_ADVANCED},
1233
1234
1235         {N_("EventLog Options"), P_SEP, P_SEPARATOR}, 
1236         {"eventlog list",  P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
1237
1238         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, 
1239         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1240         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1241         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1242
1243         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 
1244         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
1245         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
1246         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED}, 
1247         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1248         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED}, 
1249 #ifdef WITH_UTMP
1250         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED}, 
1251         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED}, 
1252         {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED}, 
1253 #endif
1254
1255         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
1256         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
1257         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED}, 
1258         {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED}, 
1259         {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED}, 
1260         {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED}, 
1261         {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED}, 
1262         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED}, 
1263         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, 
1264         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, 
1265         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, 
1266         {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
1267         {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1268         {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1269         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, 
1270         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, 
1271         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, 
1272
1273         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, 
1274         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, 
1275         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1276         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED}, 
1277
1278         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1279         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1280         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1281         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1282         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1283         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1284         {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1285         {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1286         {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1287         {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED}, 
1288         {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1289         {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED}, 
1290         {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED}, 
1291         {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1292         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, 
1293         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1294         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1295         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1296         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1297         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1298         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1299         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1300         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1301         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1302         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1303         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1304
1305         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1306         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, 
1307
1308         {N_("VFS module options"), P_SEP, P_SEPARATOR}, 
1309
1310         {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1311         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE}, 
1312
1313
1314         {N_("MSDFS options"), P_SEP, P_SEPARATOR},
1315
1316         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1317         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1318         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED}, 
1319
1320         {N_("Winbind options"), P_SEP, P_SEPARATOR}, 
1321
1322         {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1323         {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED}, 
1324         {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED }, 
1325         {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED}, 
1326         {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED}, 
1327         {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED}, 
1328         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED }, 
1329         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE }, 
1330         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED }, 
1331         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE }, 
1332         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, 
1333         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, 
1334         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED}, 
1335         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED}, 
1336         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED}, 
1337         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED}, 
1338         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED}, 
1339         {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED}, 
1340         {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED}, 
1341         {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED}, 
1342         {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED}, 
1343         {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED}, 
1344         {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1345         {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1346         {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1347
1348         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
1349 };
1350
1351 /***************************************************************************
1352  Initialise the sDefault parameter structure for the printer values.
1353 ***************************************************************************/
1354
1355 static void init_printer_values(service *pService)
1356 {
1357         /* choose defaults depending on the type of printing */
1358         switch (pService->iPrinting) {
1359                 case PRINT_BSD:
1360                 case PRINT_AIX:
1361                 case PRINT_LPRNT:
1362                 case PRINT_LPROS2:
1363                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1364                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1365                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1366                         break;
1367
1368                 case PRINT_LPRNG:
1369                 case PRINT_PLP:
1370                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1371                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1372                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1373                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1374                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1375                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1376                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1377                         break;
1378
1379                 case PRINT_CUPS:
1380                 case PRINT_IPRINT:
1381 #ifdef HAVE_CUPS
1382                         /* set the lpq command to contain the destination printer
1383                            name only.  This is used by cups_queue_get() */
1384                         string_set(&pService->szLpqcommand, "%p");
1385                         string_set(&pService->szLprmcommand, "");
1386                         string_set(&pService->szPrintcommand, "");
1387                         string_set(&pService->szLppausecommand, "");
1388                         string_set(&pService->szLpresumecommand, "");
1389                         string_set(&pService->szQueuepausecommand, "");
1390                         string_set(&pService->szQueueresumecommand, "");
1391 #else
1392                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1393                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1394                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1395                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1396                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1397                         string_set(&pService->szQueuepausecommand, "disable '%p'");
1398                         string_set(&pService->szQueueresumecommand, "enable '%p'");
1399 #endif /* HAVE_CUPS */
1400                         break;
1401
1402                 case PRINT_SYSV:
1403                 case PRINT_HPUX:
1404                         string_set(&pService->szLpqcommand, "lpstat -o%p");
1405                         string_set(&pService->szLprmcommand, "cancel %p-%j");
1406                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1407                         string_set(&pService->szQueuepausecommand, "disable %p");
1408                         string_set(&pService->szQueueresumecommand, "enable %p");
1409 #ifndef HPUX
1410                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1411                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1412 #endif /* HPUX */
1413                         break;
1414
1415                 case PRINT_QNX:
1416                         string_set(&pService->szLpqcommand, "lpq -P%p");
1417                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
1418                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1419                         break;
1420
1421 #ifdef DEVELOPER
1422         case PRINT_TEST:
1423         case PRINT_VLP:
1424                 string_set(&pService->szPrintcommand, "vlp print %p %s");
1425                 string_set(&pService->szLpqcommand, "vlp lpq %p");
1426                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1427                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1428                 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1429                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1430                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1431                 break;
1432 #endif /* DEVELOPER */
1433
1434         }
1435 }
1436
1437 /***************************************************************************
1438  Initialise the global parameter structure.
1439 ***************************************************************************/
1440
1441 static void init_globals(bool first_time_only)
1442 {
1443         static bool done_init = False;
1444         char *s = NULL;
1445
1446         /* If requested to initialize only once and we've already done it... */
1447         if (first_time_only && done_init) {
1448                 /* ... then we have nothing more to do */
1449                 return;
1450         }
1451
1452         if (!done_init) {
1453                 int i;
1454
1455                 /* The logfile can be set before this is invoked. Free it if so. */
1456                 if (Globals.szLogFile != NULL) {
1457                         string_free(&Globals.szLogFile);
1458                         Globals.szLogFile = NULL;
1459                 }
1460
1461                 memset((void *)&Globals, '\0', sizeof(Globals));
1462
1463                 for (i = 0; parm_table[i].label; i++)
1464                         if ((parm_table[i].type == P_STRING ||
1465                              parm_table[i].type == P_USTRING) &&
1466                             parm_table[i].ptr)
1467                                 string_set((char **)parm_table[i].ptr, "");
1468
1469                 string_set(&sDefault.fstype, FSTYPE_STRING);
1470                 string_set(&sDefault.szPrintjobUsername, "%U");
1471
1472                 init_printer_values(&sDefault);
1473
1474                 done_init = True;
1475         }
1476
1477
1478         DEBUG(3, ("Initialising global parameters\n"));
1479
1480         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
1481         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
1482
1483         /* use the new 'hash2' method by default, with a prefix of 1 */
1484         string_set(&Globals.szManglingMethod, "hash2");
1485         Globals.mangle_prefix = 1;
1486
1487         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1488
1489         /* using UTF8 by default allows us to support all chars */
1490         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1491
1492 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1493         /* If the system supports nl_langinfo(), try to grab the value
1494            from the user's locale */
1495         string_set(&Globals.display_charset, "LOCALE");
1496 #else
1497         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1498 #endif
1499
1500         /* Use codepage 850 as a default for the dos character set */
1501         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1502
1503         /*
1504          * Allow the default PASSWD_CHAT to be overridden in local.h.
1505          */
1506         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1507
1508         set_global_myname(myhostname());
1509         string_set(&Globals.szNetbiosName,global_myname());
1510
1511         set_global_myworkgroup(WORKGROUP);
1512         string_set(&Globals.szWorkgroup, lp_workgroup());
1513
1514         string_set(&Globals.szPasswdProgram, "");
1515         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
1516         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
1517         string_set(&Globals.szSocketAddress, "0.0.0.0");
1518
1519         if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
1520                 smb_panic("init_globals: ENOMEM");
1521         }
1522         string_set(&Globals.szServerString, s);
1523         SAFE_FREE(s);
1524         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
1525                         DEFAULT_MINOR_VERSION) < 0) {
1526                 smb_panic("init_globals: ENOMEM");
1527         }
1528         string_set(&Globals.szAnnounceVersion, s);
1529         SAFE_FREE(s);
1530 #ifdef DEVELOPER
1531         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1532 #endif
1533
1534         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
1535
1536         string_set(&Globals.szLogonDrive, "");
1537         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1538         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1539         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1540
1541         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1542         string_set(&Globals.szPasswordServer, "*");
1543
1544         Globals.AlgorithmicRidBase = BASE_RID;
1545
1546         Globals.bLoadPrinters = True;
1547         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
1548
1549         Globals.ConfigBackend = config_backend;
1550
1551         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1552         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1553         Globals.max_xmit = 0x4104;
1554         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1555         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
1556         Globals.bDisableSpoolss = False;
1557         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1558         Globals.pwordlevel = 0;
1559         Globals.unamelevel = 0;
1560         Globals.deadtime = 0;
1561         Globals.getwd_cache = true;
1562         Globals.bLargeReadwrite = True;
1563         Globals.max_log_size = 5000;
1564         Globals.max_open_files = MAX_OPEN_FILES;
1565         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1566         Globals.maxprotocol = PROTOCOL_NT1;
1567         Globals.minprotocol = PROTOCOL_CORE;
1568         Globals.security = SEC_USER;
1569         Globals.paranoid_server_security = True;
1570         Globals.bEncryptPasswords = True;
1571         Globals.bUpdateEncrypt = False;
1572         Globals.clientSchannel = Auto;
1573         Globals.serverSchannel = Auto;
1574         Globals.bReadRaw = True;
1575         Globals.bWriteRaw = True;
1576         Globals.bNullPasswords = False;
1577         Globals.bObeyPamRestrictions = False;
1578         Globals.syslog = 1;
1579         Globals.bSyslogOnly = False;
1580         Globals.bTimestampLogs = True;
1581         string_set(&Globals.szLogLevel, "0");
1582         Globals.bDebugPrefixTimestamp = False;
1583         Globals.bDebugHiresTimestamp = False;
1584         Globals.bDebugPid = False;
1585         Globals.bDebugUid = False;
1586         Globals.bDebugClass = False;
1587         Globals.bEnableCoreFiles = True;
1588         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1589         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1590         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1591         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1592         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1593         Globals.lm_interval = 60;
1594         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1595 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1596         Globals.bNISHomeMap = False;
1597 #ifdef WITH_NISPLUS_HOME
1598         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1599 #else
1600         string_set(&Globals.szNISHomeMapName, "auto.home");
1601 #endif
1602 #endif
1603         Globals.bTimeServer = False;
1604         Globals.bBindInterfacesOnly = False;
1605         Globals.bUnixPasswdSync = False;
1606         Globals.bPamPasswordChange = False;
1607         Globals.bPasswdChatDebug = False;
1608         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1609         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1610         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1611         Globals.bStatCache = True;      /* use stat cache by default */
1612         Globals.iMaxStatCacheSize = 256; /* 256k by default */
1613         Globals.restrict_anonymous = 0;
1614         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
1615         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
1616         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
1617         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
1618         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1619         /* Note, that we will use NTLM2 session security (which is different), if it is available */
1620
1621         Globals.map_to_guest = 0;       /* By Default, "Never" */
1622         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1623         Globals.enhanced_browsing = true;
1624         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1625 #ifdef MMAP_BLACKLIST
1626         Globals.bUseMmap = False;
1627 #else
1628         Globals.bUseMmap = True;
1629 #endif
1630         Globals.bUnixExtensions = True;
1631         Globals.bResetOnZeroVC = False;
1632
1633         /* hostname lookups can be very expensive and are broken on
1634            a large number of sites (tridge) */
1635         Globals.bHostnameLookups = False;
1636
1637         string_set(&Globals.szPassdbBackend, "smbpasswd");
1638         string_set(&Globals.szLdapSuffix, "");
1639         string_set(&Globals.szLdapMachineSuffix, "");
1640         string_set(&Globals.szLdapUserSuffix, "");
1641         string_set(&Globals.szLdapGroupSuffix, "");
1642         string_set(&Globals.szLdapIdmapSuffix, "");
1643
1644         string_set(&Globals.szLdapAdminDn, "");
1645         Globals.ldap_ssl = LDAP_SSL_ON;
1646         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1647         Globals.ldap_delete_dn = False;
1648         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1649         Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1650         Globals.ldap_page_size = LDAP_PAGE_SIZE;
1651
1652         Globals.ldap_debug_level = 0;
1653         Globals.ldap_debug_threshold = 10;
1654
1655         /* This is what we tell the afs client. in reality we set the token 
1656          * to never expire, though, when this runs out the afs client will 
1657          * forget the token. Set to 0 to get NEVERDATE.*/
1658         Globals.iAfsTokenLifetime = 604800;
1659
1660 /* these parameters are set to defaults that are more appropriate
1661    for the increasing samba install base:
1662
1663    as a member of the workgroup, that will possibly become a
1664    _local_ master browser (lm = True).  this is opposed to a forced
1665    local master browser startup (pm = True).
1666
1667    doesn't provide WINS server service by default (wsupp = False),
1668    and doesn't provide domain master browser services by default, either.
1669
1670 */
1671
1672         Globals.bMsAddPrinterWizard = True;
1673         Globals.os_level = 20;
1674         Globals.bLocalMaster = True;
1675         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
1676         Globals.bDomainLogons = False;
1677         Globals.bBrowseList = True;
1678         Globals.bWINSsupport = False;
1679         Globals.bWINSproxy = False;
1680
1681         Globals.bDNSproxy = True;
1682
1683         /* this just means to use them if they exist */
1684         Globals.bKernelOplocks = True;
1685
1686         Globals.bAllowTrustedDomains = True;
1687
1688         string_set(&Globals.szTemplateShell, "/bin/false");
1689         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1690         string_set(&Globals.szWinbindSeparator, "\\");
1691
1692         string_set(&Globals.szCupsServer, "");
1693         string_set(&Globals.szIPrintServer, "");
1694
1695         string_set(&Globals.ctdbdSocket, "");
1696         Globals.szClusterAddresses = NULL;
1697         Globals.clustering = False;
1698
1699         Globals.winbind_cache_time = 300;       /* 5 minutes */
1700         Globals.bWinbindEnumUsers = False;
1701         Globals.bWinbindEnumGroups = False;
1702         Globals.bWinbindUseDefaultDomain = False;
1703         Globals.bWinbindTrustedDomainsOnly = False;
1704         Globals.bWinbindNestedGroups = True;
1705         Globals.winbind_expand_groups = 1;
1706         Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
1707         Globals.bWinbindRefreshTickets = False;
1708         Globals.bWinbindOfflineLogon = False;
1709
1710         Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1711         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1712
1713         Globals.bPassdbExpandExplicit = False;
1714
1715         Globals.name_cache_timeout = 660; /* In seconds */
1716
1717         Globals.bUseSpnego = True;
1718         Globals.bClientUseSpnego = True;
1719
1720         Globals.client_signing = Auto;
1721         Globals.server_signing = False;
1722
1723         Globals.bDeferSharingViolations = True;
1724         string_set(&Globals.smb_ports, SMB_PORTS);
1725
1726         Globals.bEnablePrivileges = True;
1727         Globals.bHostMSDfs        = True;
1728         Globals.bASUSupport       = False;
1729
1730         /* User defined shares. */
1731         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1732                 smb_panic("init_globals: ENOMEM");
1733         }
1734         string_set(&Globals.szUsersharePath, s);
1735         SAFE_FREE(s);
1736         string_set(&Globals.szUsershareTemplateShare, "");
1737         Globals.iUsershareMaxShares = 0;
1738         /* By default disallow sharing of directories not owned by the sharer. */
1739         Globals.bUsershareOwnerOnly = True;
1740         /* By default disallow guest access to usershares. */
1741         Globals.bUsershareAllowGuests = False;
1742
1743         Globals.iKeepalive = DEFAULT_KEEPALIVE;
1744
1745         /* By default no shares out of the registry */
1746         Globals.bRegistryShares = False;
1747
1748         Globals.iminreceivefile = 0;
1749 }
1750
1751 /*******************************************************************
1752  Convenience routine to grab string parameters into temporary memory
1753  and run standard_sub_basic on them. The buffers can be written to by
1754  callers without affecting the source string.
1755 ********************************************************************/
1756
1757 static char *lp_string(const char *s)
1758 {
1759         char *ret;
1760         TALLOC_CTX *ctx = talloc_tos();
1761
1762         /* The follow debug is useful for tracking down memory problems
1763            especially if you have an inner loop that is calling a lp_*()
1764            function that returns a string.  Perhaps this debug should be
1765            present all the time? */
1766
1767 #if 0
1768         DEBUG(10, ("lp_string(%s)\n", s));
1769 #endif
1770
1771         ret = talloc_sub_basic(ctx,
1772                         get_current_username(),
1773                         current_user_info.domain,
1774                         s);
1775         if (trim_char(ret, '\"', '\"')) {
1776                 if (strchr(ret,'\"') != NULL) {
1777                         TALLOC_FREE(ret);
1778                         ret = talloc_sub_basic(ctx,
1779                                         get_current_username(),
1780                                         current_user_info.domain,
1781                                         s);
1782                 }
1783         }
1784         return ret;
1785 }
1786
1787 /*
1788    In this section all the functions that are used to access the 
1789    parameters from the rest of the program are defined 
1790 */
1791
1792 #define FN_GLOBAL_STRING(fn_name,ptr) \
1793  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1794 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1795  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1796 #define FN_GLOBAL_LIST(fn_name,ptr) \
1797  const char **fn_name(void) {return(*(const char ***)(ptr));}
1798 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1799  bool fn_name(void) {return(*(bool *)(ptr));}
1800 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1801  char fn_name(void) {return(*(char *)(ptr));}
1802 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1803  int fn_name(void) {return(*(int *)(ptr));}
1804
1805 #define FN_LOCAL_STRING(fn_name,val) \
1806  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1807 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1808  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1809 #define FN_LOCAL_LIST(fn_name,val) \
1810  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1811 #define FN_LOCAL_BOOL(fn_name,val) \
1812  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1813 #define FN_LOCAL_INTEGER(fn_name,val) \
1814  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1815
1816 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1817  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1818 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1819  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1820 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1821  char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
1822 #define FN_LOCAL_CHAR(fn_name,val) \
1823  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1824
1825 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1826 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1827 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1828 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1829 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1830 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1831 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1832 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1833 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1834 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1835 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1836 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1837 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1838 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1839 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1840 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1841 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1842 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1843 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1844 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1845 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1846 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1847 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1848 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1849 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1850 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1851 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1852 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1853 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1854 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1855 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1856 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1857 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1858 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1859 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1860 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1861 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1862 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1863 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1864 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1865 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1866 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1867 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1868 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1869 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1870 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1871 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1872 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1873 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1874 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1875  * lp_passdb_backend() should be replace by the this macro again after
1876  * some releases.
1877  * */
1878 const char *lp_passdb_backend(void)
1879 {
1880         char *delim, *quote;
1881
1882         delim = strchr( Globals.szPassdbBackend, ' ');
1883         /* no space at all */
1884         if (delim == NULL) {
1885                 goto out;
1886         }
1887
1888         quote = strchr(Globals.szPassdbBackend, '"');
1889         /* no quote char or non in the first part */
1890         if (quote == NULL || quote > delim) {
1891                 *delim = '\0';
1892                 goto warn;
1893         }
1894
1895         quote = strchr(quote+1, '"');
1896         if (quote == NULL) {
1897                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1898                 goto out;
1899         } else if (*(quote+1) == '\0') {
1900                 /* space, fitting quote char, and one backend only */
1901                 goto out;
1902         } else {
1903                 /* terminate string after the fitting quote char */
1904                 *(quote+1) = '\0';
1905         }
1906
1907 warn:
1908         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
1909                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
1910                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
1911                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
1912
1913 out:
1914         return Globals.szPassdbBackend;
1915 }
1916 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1917 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1918 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1919 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1920 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1921
1922 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1923 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1924 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1925 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1926 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1927 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1928
1929 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1930
1931 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1932 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1933 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1934
1935 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1936
1937 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1938 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1939 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1940 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1941 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1942 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1943 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1944 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1945 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1946 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1947 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1948 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1949 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1950 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1951 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1952
1953 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1954 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1955 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1956 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1957 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1958 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1959 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1960
1961 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1962 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1963 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1964 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1965 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1966 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1967 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1968 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1969 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
1970 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
1971 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1972 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1973 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1974 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1975 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1976 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1977
1978 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1979
1980 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1981 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1982 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1983 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1984 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1985 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1986 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1987 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1988 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1989 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1990 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1991 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1992 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1993 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1994 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1995 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1996 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1997 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1998 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1999 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
2000 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
2001 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
2002 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
2003 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
2004 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
2005 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
2006 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
2007 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
2008 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
2009 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
2010 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
2011 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
2012 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
2013 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
2014 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
2015 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
2016 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
2017 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
2018 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
2019 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
2020 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
2021 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
2022 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
2023 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
2024 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
2025 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
2026 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
2027 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
2028 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
2029 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
2030 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
2031 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
2032 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
2033 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
2034 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
2035 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
2036 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2037 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2038 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2039 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2040 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2041 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2042 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2043 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2044 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2045 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2046 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2047 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2048 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2049 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2050 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2051 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2052 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2053 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2054 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2055 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
2056 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2057 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2058 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2059 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2060 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2061 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2062 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2063 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2064 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2065 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2066 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2067 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2068 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2069 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2070 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2071 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2072 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2073 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2074 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
2075 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
2076
2077 FN_LOCAL_STRING(lp_preexec, szPreExec)
2078 FN_LOCAL_STRING(lp_postexec, szPostExec)
2079 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2080 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2081 FN_LOCAL_STRING(lp_servicename, szService)
2082 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2083 FN_LOCAL_STRING(lp_pathname, szPath)
2084 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2085 FN_LOCAL_STRING(lp_username, szUsername)
2086 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2087 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2088 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2089 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2090 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2091 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2092 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2093 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2094 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
2095 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2096 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2097 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2098 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2099 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2100 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2101 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2102 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2103 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2104 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2105 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2106 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2107 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2108 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2109 FN_LOCAL_STRING(lp_comment, comment)
2110 FN_LOCAL_STRING(lp_force_user, force_user)
2111 FN_LOCAL_STRING(lp_force_group, force_group)
2112 FN_LOCAL_LIST(lp_readlist, readlist)
2113 FN_LOCAL_LIST(lp_writelist, writelist)
2114 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2115 FN_LOCAL_STRING(lp_fstype, fstype)
2116 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2117 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2118 static FN_LOCAL_STRING(lp_volume, volume)
2119 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2120 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2121 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2122 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2123 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2124 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2125 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2126 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2127 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2128 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2129 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2130 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2131 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2132 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2133 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2134 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2135 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2136 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2137 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2138 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2139 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2140 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2141 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2142 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2143 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2144 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2145 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2146 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2147 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2148 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2149 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2150 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2151 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2152 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2153 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2154 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2155 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2156 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2157 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2158 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2159 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2160 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2161 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2162 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2163 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2164 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2165 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2166 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2167 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2168 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2169 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2170 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2171 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2172 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2173 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2174 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2175 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2176 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2177 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2178 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2179 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2180 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2181 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2182 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2183 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2184 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2185 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2186 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2187 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2188 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2189 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2190 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2191 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2192 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2193 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2194 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2195 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2196 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2197 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2198 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2199 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2200 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2201 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2202 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2203 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2204 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2205 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2206 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
2207 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2208 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2209 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2210 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2211 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2212 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2213 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2214 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
2215
2216 /* local prototypes */
2217
2218 static int map_parameter(const char *pszParmName);
2219 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
2220 static bool set_boolean(bool *pb, const char *pszParmValue);
2221 static const char *get_boolean(bool bool_value);
2222 static int getservicebyname(const char *pszServiceName,
2223                             service * pserviceDest);
2224 static void copy_service(service * pserviceDest,
2225                          service * pserviceSource,
2226                          struct bitmap *pcopymapDest);
2227 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
2228 static bool do_section(const char *pszSectionName);
2229 static void init_copymap(service * pservice);
2230 static bool hash_a_service(const char *name, int number);
2231 static void free_service_byindex(int iService);
2232 static char * canonicalize_servicename(const char *name);
2233 static void show_parameter(int parmIndex);
2234 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
2235
2236 /* This is a helper function for parametrical options support. */
2237 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2238 /* Actual parametrical functions are quite simple */
2239 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2240 {
2241         bool global_section = False;
2242         char* param_key;
2243         param_opt_struct *data;
2244         
2245         if (snum >= iNumServices) return NULL;
2246         
2247         if (snum < 0) { 
2248                 data = Globals.param_opt;
2249                 global_section = True;
2250         } else {
2251                 data = ServicePtrs[snum]->param_opt;
2252         }
2253     
2254         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
2255                 DEBUG(0,("asprintf failed!\n"));
2256                 return NULL;
2257         }
2258
2259         while (data) {
2260                 if (strcmp(data->key, param_key) == 0) {
2261                         string_free(&param_key);
2262                         return data;
2263                 }
2264                 data = data->next;
2265         }
2266
2267         if (!global_section) {
2268                 /* Try to fetch the same option but from globals */
2269                 /* but only if we are not already working with Globals */
2270                 data = Globals.param_opt;
2271                 while (data) {
2272                         if (strcmp(data->key, param_key) == 0) {
2273                                 string_free(&param_key);
2274                                 return data;
2275                         }
2276                         data = data->next;
2277                 }
2278         }
2279
2280         string_free(&param_key);
2281         
2282         return NULL;
2283 }
2284
2285
2286 #define MISSING_PARAMETER(name) \
2287     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2288
2289 /*******************************************************************
2290 convenience routine to return int parameters.
2291 ********************************************************************/
2292 static int lp_int(const char *s)
2293 {
2294
2295         if (!s || !*s) {
2296                 MISSING_PARAMETER(lp_int);
2297                 return (-1);
2298         }
2299
2300         return (int)strtol(s, NULL, 0);
2301 }
2302
2303 /*******************************************************************
2304 convenience routine to return unsigned long parameters.
2305 ********************************************************************/
2306 static unsigned long lp_ulong(const char *s)
2307 {
2308
2309         if (!s || !*s) {
2310                 MISSING_PARAMETER(lp_ulong);
2311                 return (0);
2312         }
2313
2314         return strtoul(s, NULL, 0);
2315 }
2316
2317 /*******************************************************************
2318 convenience routine to return boolean parameters.
2319 ********************************************************************/
2320 static bool lp_bool(const char *s)
2321 {
2322         bool ret = False;
2323
2324         if (!s || !*s) {
2325                 MISSING_PARAMETER(lp_bool);
2326                 return False;
2327         }
2328         
2329         if (!set_boolean(&ret,s)) {
2330                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2331                 return False;
2332         }
2333
2334         return ret;
2335 }
2336
2337 /*******************************************************************
2338 convenience routine to return enum parameters.
2339 ********************************************************************/
2340 static int lp_enum(const char *s,const struct enum_list *_enum)
2341 {
2342         int i;
2343
2344         if (!s || !*s || !_enum) {
2345                 MISSING_PARAMETER(lp_enum);
2346                 return (-1);
2347         }
2348         
2349         for (i=0; _enum[i].name; i++) {
2350                 if (strequal(_enum[i].name,s))
2351                         return _enum[i].value;
2352         }
2353
2354         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2355         return (-1);
2356 }
2357
2358 #undef MISSING_PARAMETER
2359
2360 /* DO NOT USE lp_parm_string ANYMORE!!!!
2361  * use lp_parm_const_string or lp_parm_talloc_string
2362  *
2363  * lp_parm_string is only used to let old modules find this symbol
2364  */
2365 #undef lp_parm_string
2366  char *lp_parm_string(const char *servicename, const char *type, const char *option);
2367  char *lp_parm_string(const char *servicename, const char *type, const char *option)
2368 {
2369         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2370 }
2371
2372 /* Return parametric option from a given service. Type is a part of option before ':' */
2373 /* Parametric option has following syntax: 'Type: option = value' */
2374 /* the returned value is talloced on the talloc_tos() */
2375 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2376 {
2377         param_opt_struct *data = get_parametrics(snum, type, option);
2378         
2379         if (data == NULL||data->value==NULL) {
2380                 if (def) {
2381                         return lp_string(def);
2382                 } else {
2383                         return NULL;
2384                 }
2385         }
2386
2387         return lp_string(data->value);
2388 }
2389
2390 /* Return parametric option from a given service. Type is a part of option before ':' */
2391 /* Parametric option has following syntax: 'Type: option = value' */
2392 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2393 {
2394         param_opt_struct *data = get_parametrics(snum, type, option);
2395         
2396         if (data == NULL||data->value==NULL)
2397                 return def;
2398                 
2399         return data->value;
2400 }
2401
2402 /* Return parametric option from a given service. Type is a part of option before ':' */
2403 /* Parametric option has following syntax: 'Type: option = value' */
2404
2405 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2406 {
2407         param_opt_struct *data = get_parametrics(snum, type, option);
2408
2409         if (data == NULL||data->value==NULL)
2410                 return (const char **)def;
2411                 
2412         if (data->list==NULL) {
2413                 data->list = str_list_make(NULL, data->value, NULL);
2414         }
2415
2416         return (const char **)data->list;
2417 }
2418
2419 /* Return parametric option from a given service. Type is a part of option before ':' */
2420 /* Parametric option has following syntax: 'Type: option = value' */
2421
2422 int lp_parm_int(int snum, const char *type, const char *option, int def)
2423 {
2424         param_opt_struct *data = get_parametrics(snum, type, option);
2425         
2426         if (data && data->value && *data->value)
2427                 return lp_int(data->value);
2428
2429         return def;
2430 }
2431
2432 /* Return parametric option from a given service. Type is a part of option before ':' */
2433 /* Parametric option has following syntax: 'Type: option = value' */
2434
2435 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2436 {
2437         param_opt_struct *data = get_parametrics(snum, type, option);
2438         
2439         if (data && data->value && *data->value)
2440                 return lp_ulong(data->value);
2441
2442         return def;
2443 }
2444
2445 /* Return parametric option from a given service. Type is a part of option before ':' */
2446 /* Parametric option has following syntax: 'Type: option = value' */
2447
2448 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
2449 {
2450         param_opt_struct *data = get_parametrics(snum, type, option);
2451         
2452         if (data && data->value && *data->value)
2453                 return lp_bool(data->value);
2454
2455         return def;
2456 }
2457
2458 /* Return parametric option from a given service. Type is a part of option before ':' */
2459 /* Parametric option has following syntax: 'Type: option = value' */
2460
2461 int lp_parm_enum(int snum, const char *type, const char *option,
2462                  const struct enum_list *_enum, int def)
2463 {
2464         param_opt_struct *data = get_parametrics(snum, type, option);
2465         
2466         if (data && data->value && *data->value && _enum)
2467                 return lp_enum(data->value, _enum);
2468
2469         return def;
2470 }
2471
2472
2473 /***************************************************************************
2474  Initialise a service to the defaults.
2475 ***************************************************************************/
2476
2477 static void init_service(service * pservice)
2478 {
2479         memset((char *)pservice, '\0', sizeof(service));
2480         copy_service(pservice, &sDefault, NULL);
2481 }
2482
2483 /***************************************************************************
2484  Free the dynamically allocated parts of a service struct.
2485 ***************************************************************************/
2486
2487 static void free_service(service *pservice)
2488 {
2489         int i;
2490         param_opt_struct *data, *pdata;
2491         if (!pservice)
2492                 return;
2493
2494         if (pservice->szService)
2495                 DEBUG(5, ("free_service: Freeing service %s\n",
2496                        pservice->szService));
2497
2498         string_free(&pservice->szService);
2499         bitmap_free(pservice->copymap);
2500
2501         for (i = 0; parm_table[i].label; i++) {
2502                 if ((parm_table[i].type == P_STRING ||
2503                      parm_table[i].type == P_USTRING) &&
2504                     parm_table[i].p_class == P_LOCAL)
2505                         string_free((char **)
2506                                     (((char *)pservice) +
2507                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2508                 else if (parm_table[i].type == P_LIST &&
2509                          parm_table[i].p_class == P_LOCAL)
2510                              TALLOC_FREE(*((char ***)
2511                                            (((char *)pservice) +
2512                                             PTR_DIFF(parm_table[i].ptr,
2513                                                      &sDefault))));
2514         }
2515
2516         data = pservice->param_opt;
2517         if (data)
2518                 DEBUG(5,("Freeing parametrics:\n"));
2519         while (data) {
2520                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2521                 string_free(&data->key);
2522                 string_free(&data->value);
2523                 TALLOC_FREE(data->list);
2524                 pdata = data->next;
2525                 SAFE_FREE(data);
2526                 data = pdata;
2527         }
2528
2529         ZERO_STRUCTP(pservice);
2530 }
2531
2532
2533 /***************************************************************************
2534  remove a service indexed in the ServicePtrs array from the ServiceHash
2535  and free the dynamically allocated parts
2536 ***************************************************************************/
2537
2538 static void free_service_byindex(int idx)
2539 {
2540         if ( !LP_SNUM_OK(idx) ) 
2541                 return;
2542
2543         ServicePtrs[idx]->valid = False;
2544         invalid_services[num_invalid_services++] = idx;
2545
2546         /* we have to cleanup the hash record */
2547
2548         if (ServicePtrs[idx]->szService) {
2549                 char *canon_name = canonicalize_servicename(
2550                         ServicePtrs[idx]->szService );
2551                 
2552                 dbwrap_delete_bystring(ServiceHash, canon_name );
2553                 TALLOC_FREE(canon_name);
2554         }
2555
2556         free_service(ServicePtrs[idx]);
2557 }
2558
2559 /***************************************************************************
2560  Add a new service to the services array initialising it with the given 
2561  service. 
2562 ***************************************************************************/
2563
2564 static int add_a_service(const service *pservice, const char *name)
2565 {
2566         int i;
2567         service tservice;
2568         int num_to_alloc = iNumServices + 1;
2569         param_opt_struct *data, *pdata;
2570
2571         tservice = *pservice;
2572
2573         /* it might already exist */
2574         if (name) {
2575                 i = getservicebyname(name, NULL);
2576                 if (i >= 0) {
2577                         /* Clean all parametric options for service */
2578                         /* They will be added during parsing again */
2579                         data = ServicePtrs[i]->param_opt;
2580                         while (data) {
2581                                 string_free(&data->key);
2582                                 string_free(&data->value);
2583                                 TALLOC_FREE(data->list);
2584                                 pdata = data->next;
2585                                 SAFE_FREE(data);
2586                                 data = pdata;
2587                         }
2588                         ServicePtrs[i]->param_opt = NULL;
2589                         return (i);
2590                 }
2591         }
2592
2593         /* find an invalid one */
2594         i = iNumServices;
2595         if (num_invalid_services > 0) {
2596                 i = invalid_services[--num_invalid_services];
2597         }
2598
2599         /* if not, then create one */
2600         if (i == iNumServices) {
2601                 service **tsp;
2602                 int *tinvalid;
2603                 
2604                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2605                 if (tsp == NULL) {
2606                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2607                         return (-1);
2608                 }
2609                 ServicePtrs = tsp;
2610                 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2611                 if (!ServicePtrs[iNumServices]) {
2612                         DEBUG(0,("add_a_service: out of memory!\n"));
2613                         return (-1);
2614                 }
2615                 iNumServices++;
2616
2617                 /* enlarge invalid_services here for now... */
2618                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2619                                              num_to_alloc);
2620                 if (tinvalid == NULL) {
2621                         DEBUG(0,("add_a_service: failed to enlarge "
2622                                  "invalid_services!\n"));
2623                         return (-1);
2624                 }
2625                 invalid_services = tinvalid;
2626         } else {
2627                 free_service_byindex(i);
2628         }
2629
2630         ServicePtrs[i]->valid = True;
2631
2632         init_service(ServicePtrs[i]);
2633         copy_service(ServicePtrs[i], &tservice, NULL);
2634         if (name)
2635                 string_set(&ServicePtrs[i]->szService, name);
2636                 
2637         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
2638                 i, ServicePtrs[i]->szService));
2639
2640         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2641                 return (-1);
2642         }
2643                 
2644         return (i);
2645 }
2646
2647 /***************************************************************************
2648   Convert a string to uppercase and remove whitespaces.
2649 ***************************************************************************/
2650
2651 static char *canonicalize_servicename(const char *src)
2652 {
2653         char *result;
2654
2655         if ( !src ) {
2656                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2657                 return NULL;
2658         }
2659
2660         result = talloc_strdup(talloc_tos(), src);
2661         SMB_ASSERT(result != NULL);
2662
2663         strlower_m(result);
2664         return result;
2665 }
2666
2667 /***************************************************************************
2668   Add a name/index pair for the services array to the hash table.
2669 ***************************************************************************/
2670
2671 static bool hash_a_service(const char *name, int idx)
2672 {
2673         char *canon_name;
2674
2675         if ( !ServiceHash ) {
2676                 DEBUG(10,("hash_a_service: creating servicehash\n"));
2677                 ServiceHash = db_open_rbt(NULL);
2678                 if ( !ServiceHash ) {
2679                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2680                         return False;
2681                 }
2682         }
2683
2684         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2685                 idx, name));
2686
2687         canon_name = canonicalize_servicename( name );
2688
2689         dbwrap_store_bystring(ServiceHash, canon_name,
2690                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
2691                               TDB_REPLACE);
2692
2693         TALLOC_FREE(canon_name);
2694
2695         return True;
2696 }
2697
2698 /***************************************************************************
2699  Add a new home service, with the specified home directory, defaults coming
2700  from service ifrom.
2701 ***************************************************************************/
2702
2703 bool lp_add_home(const char *pszHomename, int iDefaultService,
2704                  const char *user, const char *pszHomedir)
2705 {
2706         int i;
2707
2708         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2709
2710         if (i < 0)
2711                 return (False);
2712
2713         if (!(*(ServicePtrs[iDefaultService]->szPath))
2714             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2715                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
2716         }
2717
2718         if (!(*(ServicePtrs[i]->comment))) {
2719                 char *comment = NULL;
2720                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
2721                         return false;
2722                 }
2723                 string_set(&ServicePtrs[i]->comment, comment);
2724                 SAFE_FREE(comment);
2725         }
2726
2727         /* set the browseable flag from the global default */
2728
2729         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2730
2731         ServicePtrs[i]->autoloaded = True;
2732
2733         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2734                user, ServicePtrs[i]->szPath ));
2735
2736         return (True);
2737 }
2738
2739 /***************************************************************************
2740  Add a new service, based on an old one.
2741 ***************************************************************************/
2742
2743 int lp_add_service(const char *pszService, int iDefaultService)
2744 {
2745         if (iDefaultService < 0) {
2746                 return add_a_service(&sDefault, pszService);
2747         }
2748
2749         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2750 }
2751
2752 /***************************************************************************
2753  Add the IPC service.
2754 ***************************************************************************/
2755
2756 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
2757 {
2758         char *comment = NULL;
2759         int i = add_a_service(&sDefault, ipc_name);
2760
2761         if (i < 0)
2762                 return (False);
2763
2764         if (asprintf(&comment, "IPC Service (%s)",
2765                                 Globals.szServerString) < 0) {
2766                 return (False);
2767         }
2768
2769         string_set(&ServicePtrs[i]->szPath, tmpdir());
2770         string_set(&ServicePtrs[i]->szUsername, "");
2771         string_set(&ServicePtrs[i]->comment, comment);
2772         string_set(&ServicePtrs[i]->fstype, "IPC");
2773         ServicePtrs[i]->iMaxConnections = 0;
2774         ServicePtrs[i]->bAvailable = True;
2775         ServicePtrs[i]->bRead_only = True;
2776         ServicePtrs[i]->bGuest_only = False;
2777         ServicePtrs[i]->bGuest_ok = guest_ok;
2778         ServicePtrs[i]->bPrint_ok = False;
2779         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2780
2781         DEBUG(3, ("adding IPC service\n"));
2782
2783         SAFE_FREE(comment);
2784         return (True);
2785 }
2786
2787 /***************************************************************************
2788  Add a new printer service, with defaults coming from service iFrom.
2789 ***************************************************************************/
2790
2791 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
2792 {
2793         const char *comment = "From Printcap";
2794         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2795
2796         if (i < 0)
2797                 return (False);
2798
2799         /* note that we do NOT default the availability flag to True - */
2800         /* we take it from the default service passed. This allows all */
2801         /* dynamic printers to be disabled by disabling the [printers] */
2802         /* entry (if/when the 'available' keyword is implemented!).    */
2803
2804         /* the printer name is set to the service name. */
2805         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2806         string_set(&ServicePtrs[i]->comment, comment);
2807
2808         /* set the browseable flag from the gloabl default */
2809         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2810
2811         /* Printers cannot be read_only. */
2812         ServicePtrs[i]->bRead_only = False;
2813         /* No share modes on printer services. */
2814         ServicePtrs[i]->bShareModes = False;
2815         /* No oplocks on printer services. */
2816         ServicePtrs[i]->bOpLocks = False;
2817         /* Printer services must be printable. */
2818         ServicePtrs[i]->bPrint_ok = True;
2819         
2820         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2821
2822         return (True);
2823 }
2824
2825
2826 /***************************************************************************
2827  Check whether the given parameter name is valid.
2828  Parametric options (names containing a colon) are considered valid.
2829 ***************************************************************************/
2830
2831 bool lp_parameter_is_valid(const char *pszParmName)
2832 {
2833         return ((map_parameter(pszParmName) != -1) ||
2834                 (strchr(pszParmName, ':') != NULL));
2835 }
2836
2837 /***************************************************************************
2838  Check whether the given name is the name of a global parameter.
2839  Returns True for strings belonging to parameters of class
2840  P_GLOBAL, False for all other strings, also for parametric options
2841  and strings not belonging to any option.
2842 ***************************************************************************/
2843
2844 bool lp_parameter_is_global(const char *pszParmName)
2845 {
2846         int num = map_parameter(pszParmName);
2847
2848         if (num >= 0) {
2849                 return (parm_table[num].p_class == P_GLOBAL);
2850         }
2851
2852         return False;
2853 }
2854
2855 /**************************************************************************
2856  Check whether the given name is the canonical name of a parameter.
2857  Returns False if it is not a valid parameter Name.
2858  For parametric options, True is returned.
2859 **************************************************************************/
2860
2861 bool lp_parameter_is_canonical(const char *parm_name)
2862 {
2863         if (!lp_parameter_is_valid(parm_name)) {
2864                 return False;
2865         }
2866
2867         return (map_parameter(parm_name) ==
2868                 map_parameter_canonical(parm_name, NULL));
2869 }
2870
2871 /**************************************************************************
2872  Determine the canonical name for a parameter.
2873  Indicate when it is an inverse (boolean) synonym instead of a
2874  "usual" synonym.
2875 **************************************************************************/
2876
2877 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
2878                                bool *inverse)
2879 {
2880         int num;
2881
2882         if (!lp_parameter_is_valid(parm_name)) {
2883                 *canon_parm = NULL;
2884                 return False;
2885         }
2886
2887         num = map_parameter_canonical(parm_name, inverse);
2888         if (num < 0) {
2889                 /* parametric option */
2890                 *canon_parm = parm_name;
2891         } else {
2892                 *canon_parm = parm_table[num].label;
2893         }
2894
2895         return True;
2896
2897 }
2898
2899 /**************************************************************************
2900  Determine the canonical name for a parameter.
2901  Turn the value given into the inverse boolean expression when
2902  the synonym is an invers boolean synonym.
2903
2904  Return True if parm_name is a valid parameter name and
2905  in case it is an invers boolean synonym, if the val string could
2906  successfully be converted to the reverse bool.
2907  Return false in all other cases.
2908 **************************************************************************/
2909
2910 bool lp_canonicalize_parameter_with_value(const char *parm_name,
2911                                           const char *val,
2912                                           const char **canon_parm,
2913                                           const char **canon_val)
2914 {
2915         int num;
2916         bool inverse;
2917
2918         if (!lp_parameter_is_valid(parm_name)) {
2919                 *canon_parm = NULL;
2920                 *canon_val = NULL;
2921                 return False;
2922         }
2923
2924         num = map_parameter_canonical(parm_name, &inverse);
2925         if (num < 0) {
2926                 /* parametric option */
2927                 *canon_parm = parm_name;
2928                 *canon_val = val;
2929         } else {
2930                 *canon_parm = parm_table[num].label;
2931                 if (inverse) {
2932                         if (!lp_invert_boolean(val, canon_val)) {
2933                                 *canon_val = NULL;
2934                                 return False;
2935                         }
2936                 } else {
2937                         *canon_val = val;
2938                 }
2939         }
2940
2941         return True;
2942 }
2943
2944 /***************************************************************************
2945  Map a parameter's string representation to something we can use. 
2946  Returns False if the parameter string is not recognised, else TRUE.
2947 ***************************************************************************/
2948
2949 static int map_parameter(const char *pszParmName)
2950 {
2951         int iIndex;
2952
2953         if (*pszParmName == '-')
2954                 return (-1);
2955
2956         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2957                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2958                         return (iIndex);
2959
2960         /* Warn only if it isn't parametric option */
2961         if (strchr(pszParmName, ':') == NULL)
2962                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2963         /* We do return 'fail' for parametric options as well because they are
2964            stored in different storage
2965          */
2966         return (-1);
2967 }
2968
2969 /***************************************************************************
2970  Map a parameter's string representation to the index of the canonical
2971  form of the parameter (it might be a synonym).
2972  Returns -1 if the parameter string is not recognised.
2973 ***************************************************************************/
2974
2975 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
2976 {
2977         int parm_num, canon_num;
2978         bool loc_inverse = False;
2979
2980         parm_num = map_parameter(pszParmName);
2981         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
2982                 /* invalid, parametric or no canidate for synonyms ... */
2983                 goto done;
2984         }
2985
2986         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
2987                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
2988                         parm_num = canon_num;
2989                         goto done;
2990                 }
2991         }
2992
2993 done:
2994         if (inverse != NULL) {
2995                 *inverse = loc_inverse;
2996         }
2997         return parm_num;
2998 }
2999
3000 /***************************************************************************
3001  return true if parameter number parm1 is a synonym of parameter
3002  number parm2 (parm2 being the principal name).
3003  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
3004  False otherwise.
3005 ***************************************************************************/
3006
3007 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
3008 {
3009         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
3010             (parm_table[parm1].flags & FLAG_HIDE) &&
3011             !(parm_table[parm2].flags & FLAG_HIDE))
3012         {
3013                 if (inverse != NULL) {
3014                         if ((parm_table[parm1].type == P_BOOLREV) &&
3015                             (parm_table[parm2].type == P_BOOL))
3016                         {
3017                                 *inverse = True;
3018                         } else {
3019                                 *inverse = False;
3020                         }
3021                 }
3022                 return True;
3023         }
3024         return False;
3025 }
3026
3027 /***************************************************************************
3028  Show one parameter's name, type, [values,] and flags.
3029  (helper functions for show_parameter_list)
3030 ***************************************************************************/
3031
3032 static void show_parameter(int parmIndex)
3033 {
3034         int enumIndex, flagIndex;
3035         int parmIndex2;
3036         bool hadFlag;
3037         bool hadSyn;
3038         bool inverse;
3039         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
3040                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
3041                 "P_ENUM", "P_SEP"};
3042         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
3043                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
3044                 FLAG_HIDE, FLAG_DOS_STRING};
3045         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
3046                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
3047                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
3048
3049         printf("%s=%s", parm_table[parmIndex].label,
3050                type[parm_table[parmIndex].type]);
3051         if (parm_table[parmIndex].type == P_ENUM) {
3052                 printf(",");
3053                 for (enumIndex=0;
3054                      parm_table[parmIndex].enum_list[enumIndex].name;
3055                      enumIndex++)
3056                 {
3057                         printf("%s%s",
3058                                enumIndex ? "|" : "",
3059                                parm_table[parmIndex].enum_list[enumIndex].name);
3060                 }
3061         }
3062         printf(",");
3063         hadFlag = False;
3064         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
3065                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
3066                         printf("%s%s",
3067                                 hadFlag ? "|" : "",
3068                                 flag_names[flagIndex]);
3069                         hadFlag = True;
3070                 }
3071         }
3072
3073         /* output synonyms */
3074         hadSyn = False;
3075         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
3076                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
3077                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
3078                                parm_table[parmIndex2].label);
3079                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
3080                         if (!hadSyn) {
3081                                 printf(" (synonyms: ");
3082                                 hadSyn = True;
3083                         } else {
3084                                 printf(", ");
3085                         }
3086                         printf("%s%s", parm_table[parmIndex2].label,
3087                                inverse ? "[i]" : "");
3088                 }
3089         }
3090         if (hadSyn) {
3091                 printf(")");
3092         }
3093
3094         printf("\n");
3095 }
3096
3097 /***************************************************************************
3098  Show all parameter's name, type, [values,] and flags.
3099 ***************************************************************************/
3100
3101 void show_parameter_list(void)
3102 {
3103         int classIndex, parmIndex;
3104         const char *section_names[] = { "local", "global", NULL};
3105
3106         for (classIndex=0; section_names[classIndex]; classIndex++) {
3107                 printf("[%s]\n", section_names[classIndex]);
3108                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
3109                         if (parm_table[parmIndex].p_class == classIndex) {
3110                                 show_parameter(parmIndex);
3111                         }
3112                 }
3113         }
3114 }
3115
3116 /***************************************************************************
3117  Set a boolean variable from the text value stored in the passed string.
3118  Returns True in success, False if the passed string does not correctly 
3119  represent a boolean.
3120 ***************************************************************************/
3121
3122 static bool set_boolean(bool *pb, const char *pszParmValue)
3123 {
3124         bool bRetval;
3125         bool value;
3126
3127         bRetval = True;
3128         value = False;
3129         if (strwicmp(pszParmValue, "yes") == 0 ||
3130             strwicmp(pszParmValue, "true") == 0 ||
3131             strwicmp(pszParmValue, "1") == 0)
3132                 value = True;
3133         else if (strwicmp(pszParmValue, "no") == 0 ||
3134                     strwicmp(pszParmValue, "False") == 0 ||
3135                     strwicmp(pszParmValue, "0") == 0)
3136                 value = False;
3137         else {
3138                 DEBUG(2,
3139                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
3140                        pszParmValue));
3141                 bRetval = False;
3142         }
3143
3144         if ((pb != NULL) && (bRetval != False)) {
3145                 *pb = value;
3146         }
3147
3148         return (bRetval);
3149 }
3150
3151
3152 /***************************************************************************
3153  Check if a given string correctly represents a boolean value.
3154 ***************************************************************************/
3155
3156 bool lp_string_is_valid_boolean(const char *parm_value)
3157 {
3158         return set_boolean(NULL, parm_value);
3159 }
3160
3161 /***************************************************************************
3162  Get the standard string representation of a boolean value ("yes" or "no")
3163 ***************************************************************************/
3164
3165 static const char *get_boolean(bool bool_value)
3166 {
3167         static const char *yes_str = "yes";
3168         static const char *no_str = "no";
3169
3170         return (bool_value ? yes_str : no_str);
3171 }
3172
3173 /***************************************************************************
3174  Provide the string of the negated boolean value associated to the boolean
3175  given as a string. Returns False if the passed string does not correctly
3176  represent a boolean.
3177 ***************************************************************************/
3178
3179 bool lp_invert_boolean(const char *str, const char **inverse_str)
3180 {
3181         bool val;
3182
3183         if (!set_boolean(&val, str)) {
3184                 return False;
3185         }
3186
3187         *inverse_str = get_boolean(!val);
3188         return True;
3189 }
3190
3191 /***************************************************************************
3192  Provide the canonical string representation of a boolean value given
3193  as a string. Return True on success, False if the string given does
3194  not correctly represent a boolean.
3195 ***************************************************************************/
3196
3197 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
3198 {
3199         bool val;
3200
3201         if (!set_boolean(&val, str)) {
3202                 return False;
3203         }
3204
3205         *canon_str = get_boolean(val);
3206         return True;
3207 }
3208
3209 /***************************************************************************
3210 Find a service by name. Otherwise works like get_service.
3211 ***************************************************************************/
3212
3213 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
3214 {
3215         int iService = -1;
3216         char *canon_name;
3217         TDB_DATA data;
3218
3219         if (ServiceHash == NULL) {
3220                 return -1;
3221         }
3222
3223         canon_name = canonicalize_servicename(pszServiceName);
3224
3225         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
3226
3227         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
3228                 iService = *(int *)data.dptr;
3229         }
3230
3231         TALLOC_FREE(canon_name);
3232
3233         if ((iService != -1) && (LP_SNUM_OK(iService))
3234             && (pserviceDest != NULL)) {
3235                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
3236         }
3237
3238         return (iService);
3239 }
3240
3241 /***************************************************************************
3242  Copy a service structure to another.
3243  If pcopymapDest is NULL then copy all fields
3244 ***************************************************************************/
3245
3246 static void copy_service(service * pserviceDest, service * pserviceSource,
3247                          struct bitmap *pcopymapDest)
3248 {
3249         int i;
3250         bool bcopyall = (pcopymapDest == NULL);
3251         param_opt_struct *data, *pdata, *paramo;
3252         bool not_added;
3253
3254         for (i = 0; parm_table[i].label; i++)
3255                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
3256                     (bcopyall || bitmap_query(pcopymapDest,i))) {
3257                         void *def_ptr = parm_table[i].ptr;
3258                         void *src_ptr =
3259                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
3260                                                                     &sDefault);
3261                         void *dest_ptr =
3262                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
3263                                                                   &sDefault);
3264
3265                         switch (parm_table[i].type) {
3266                                 case P_BOOL:
3267                                 case P_BOOLREV:
3268                                         *(bool *)dest_ptr = *(bool *)src_ptr;
3269                                         break;
3270
3271                                 case P_INTEGER:
3272                                 case P_ENUM:
3273                                 case P_OCTAL:
3274                                         *(int *)dest_ptr = *(int *)src_ptr;
3275                                         break;
3276
3277                                 case P_CHAR:
3278                                         *(char *)dest_ptr = *(char *)src_ptr;
3279                                         break;
3280
3281                                 case P_STRING:
3282                                         string_set((char **)dest_ptr,
3283                                                    *(char **)src_ptr);
3284                                         break;
3285
3286                                 case P_USTRING:
3287                                         string_set((char **)dest_ptr,
3288                                                    *(char **)src_ptr);
3289                                         strupper_m(*(char **)dest_ptr);
3290                                         break;
3291                                 case P_LIST:
3292                                         TALLOC_FREE(*((char ***)dest_ptr));
3293                                         str_list_copy(NULL, (char ***)dest_ptr,
3294                                                       *(const char ***)src_ptr);
3295                                         break;
3296                                 default:
3297                                         break;
3298                         }
3299                 }
3300
3301         if (bcopyall) {
3302                 init_copymap(pserviceDest);
3303                 if (pserviceSource->copymap)
3304                         bitmap_copy(pserviceDest->copymap,
3305                                     pserviceSource->copymap);
3306         }
3307         
3308         data = pserviceSource->param_opt;
3309         while (data) {
3310                 not_added = True;
3311                 pdata = pserviceDest->param_opt;
3312                 /* Traverse destination */
3313                 while (pdata) {
3314                         /* If we already have same option, override it */
3315                         if (strcmp(pdata->key, data->key) == 0) {
3316                                 string_free(&pdata->value);
3317                                 TALLOC_FREE(data->list);
3318                                 pdata->value = SMB_STRDUP(data->value);
3319                                 not_added = False;
3320                                 break;
3321                         }
3322                         pdata = pdata->next;
3323                 }
3324                 if (not_added) {
3325                     paramo = SMB_XMALLOC_P(param_opt_struct);
3326                     paramo->key = SMB_STRDUP(data->key);
3327                     paramo->value = SMB_STRDUP(data->value);
3328                     paramo->list = NULL;
3329                     DLIST_ADD(pserviceDest->param_opt, paramo);
3330                 }
3331                 data = data->next;
3332         }
3333 }
3334
3335 /***************************************************************************
3336 Check a service for consistency. Return False if the service is in any way
3337 incomplete or faulty, else True.
3338 ***************************************************************************/
3339
3340 bool service_ok(int iService)
3341 {
3342         bool bRetval;
3343
3344         bRetval = True;
3345         if (ServicePtrs[iService]->szService[0] == '\0') {
3346                 DEBUG(0, ("The following message indicates an internal error:\n"));
3347                 DEBUG(0, ("No service name in service entry.\n"));
3348                 bRetval = False;
3349         }
3350
3351         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3352         /* I can't see why you'd want a non-printable printer service...        */
3353         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3354                 if (!ServicePtrs[iService]->bPrint_ok) {
3355                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3356                                ServicePtrs[iService]->szService));
3357                         ServicePtrs[iService]->bPrint_ok = True;
3358                 }
3359                 /* [printers] service must also be non-browsable. */
3360                 if (ServicePtrs[iService]->bBrowseable)
3361                         ServicePtrs[iService]->bBrowseable = False;
3362         }
3363
3364         if (ServicePtrs[iService]->szPath[0] == '\0' &&
3365             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3366             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3367             ) {
3368                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3369                         ServicePtrs[iService]->szService));
3370                 ServicePtrs[iService]->bAvailable = False;
3371         }
3372
3373         /* If a service is flagged unavailable, log the fact at level 1. */
3374         if (!ServicePtrs[iService]->bAvailable)
3375                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3376                           ServicePtrs[iService]->szService));
3377
3378         return (bRetval);
3379 }
3380
3381 /*
3382  * process_registry_globals
3383  */
3384 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3385 {
3386         WERROR werr;
3387         char **param_names;
3388         char **param_values;
3389         uint32_t num_params;
3390         uint32_t count;
3391         TALLOC_CTX *mem_ctx = talloc_stackframe();
3392         bool ret = false;
3393
3394         if (conf_ctx == NULL) {
3395                 /* first time */
3396                 werr = libnet_conf_open(NULL, &conf_ctx);
3397                 if (!W_ERROR_IS_OK(werr)) {
3398                         goto done;
3399                 }
3400         }
3401
3402         werr = libnet_conf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME,
3403                                      &num_params, &param_names, &param_values);
3404         if (!W_ERROR_IS_OK(werr)) {
3405                 goto done;
3406         }
3407
3408         for (count = 0; count < num_params; count++) {
3409                 ret = pfunc(param_names[count], param_values[count]);
3410                 if (ret != true) {
3411                         goto done;
3412                 }
3413         }
3414
3415         ret = pfunc("registry shares", "yes");
3416         conf_last_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL);
3417
3418 done:
3419         TALLOC_FREE(mem_ctx);
3420         return ret;
3421 }
3422
3423 static struct file_lists {
3424         struct file_lists *next;
3425         char *name;
3426         char *subfname;
3427         time_t modtime;
3428 } *file_lists = NULL;
3429
3430 /*******************************************************************
3431  Keep a linked list of all config files so we know when one has changed 
3432  it's date and needs to be reloaded.
3433 ********************************************************************/
3434
3435 static void add_to_file_list(const char *fname, const char *subfname)
3436 {
3437         struct file_lists *f = file_lists;
3438
3439         while (f) {
3440                 if (f->name && !strcmp(f->name, fname))
3441                         break;
3442                 f = f->next;
3443         }
3444
3445         if (!f) {
3446                 f = SMB_MALLOC_P(struct file_lists);
3447                 if (!f)
3448                         return;
3449                 f->next = file_lists;
3450                 f->name = SMB_STRDUP(fname);
3451                 if (!f->name) {
3452                         SAFE_FREE(f);
3453                         return;
3454                 }
3455                 f->subfname = SMB_STRDUP(subfname);
3456                 if (!f->subfname) {
3457                         SAFE_FREE(f);
3458                         return;
3459                 }
3460                 file_lists = f;
3461                 f->modtime = file_modtime(subfname);
3462         } else {
3463                 time_t t = file_modtime(subfname);
3464                 if (t)
3465                         f->modtime = t;
3466         }
3467 }
3468
3469 /**
3470  * Utility function for outsiders to check if we're running on registry.
3471  */
3472 bool lp_config_backend_is_registry(void)
3473 {
3474         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
3475 }
3476
3477 /*******************************************************************
3478  Check if a config file has changed date.
3479 ********************************************************************/
3480
3481 bool lp_file_list_changed(void)
3482 {
3483         struct file_lists *f = file_lists;
3484
3485         DEBUG(6, ("lp_file_list_changed()\n"));
3486
3487         if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
3488                 if (conf_ctx == NULL) {
3489                         WERROR werr;
3490                         werr = libnet_conf_open(NULL, &conf_ctx);
3491                         if (!W_ERROR_IS_OK(werr)) {
3492                                 DEBUG(0, ("error opening configuration: %s\n",
3493                                           dos_errstr(werr)));
3494                                 return false;
3495                         }
3496                 }
3497                 if (conf_last_seqnum !=
3498                     libnet_conf_get_seqnum(conf_ctx, NULL, NULL))
3499                 {
3500                         DEBUGADD(6, ("regdb seqnum changed: old = %lu, "
3501                                      "new = %lu\n", conf_last_seqnum,
3502                                      libnet_conf_get_seqnum(conf_ctx, NULL, NULL)));
3503                         return true;
3504                 } else {
3505                         /*
3506                          * Don't check files when config_backend is registry.
3507                          * Remove this to obtain checking of files even with
3508                          * registry config backend. That would enable switching
3509                          * off registry configuration by changing smb.conf even
3510                          * without restarting smbd.
3511                          */
3512                         return false;
3513                 }
3514         }
3515
3516         while (f) {
3517                 char *n2 = NULL;
3518                 time_t mod_time;
3519
3520                 n2 = alloc_sub_basic(get_current_username(),
3521                                     current_user_info.domain,
3522                                     f->name);
3523                 if (!n2) {
3524                         return false;
3525                 }
3526                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
3527                              f->name, n2, ctime(&f->modtime)));
3528
3529                 mod_time = file_modtime(n2);
3530
3531                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3532                         DEBUGADD(6,
3533                                  ("file %s modified: %s\n", n2,
3534                                   ctime(&mod_time)));
3535                         f->modtime = mod_time;
3536                         SAFE_FREE(f->subfname);
3537                         f->subfname = n2; /* Passing ownership of
3538                                              return from alloc_sub_basic
3539                                              above. */
3540                         return true;
3541                 }
3542                 SAFE_FREE(n2);
3543                 f = f->next;
3544         }
3545         return (False);
3546 }
3547
3548
3549 /***************************************************************************
3550  Run standard_sub_basic on netbios name... needed because global_myname
3551  is not accessed through any lp_ macro.
3552  Note: We must *NOT* use string_set() here as ptr points to global_myname.
3553 ***************************************************************************/
3554
3555 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3556 {
3557         bool ret;
3558         char *netbios_name = alloc_sub_basic(get_current_username(),
3559                                         current_user_info.domain,
3560                                         pszParmValue);
3561
3562         ret = set_global_myname(netbios_name);
3563         SAFE_FREE(netbios_name);
3564         string_set(&Globals.szNetbiosName,global_myname());
3565
3566         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3567                global_myname()));
3568
3569         return ret;
3570 }
3571
3572 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
3573 {
3574         if (strcmp(*ptr, pszParmValue) != 0) {
3575                 string_set(ptr, pszParmValue);
3576                 init_iconv();
3577         }
3578         return True;
3579 }
3580
3581
3582
3583 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3584 {
3585         bool ret;
3586         
3587         ret = set_global_myworkgroup(pszParmValue);
3588         string_set(&Globals.szWorkgroup,lp_workgroup());
3589         
3590         return ret;
3591 }
3592
3593 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3594 {
3595         bool ret;
3596         
3597         ret = set_global_scope(pszParmValue);
3598         string_set(&Globals.szNetbiosScope,global_scope());
3599
3600         return ret;
3601 }
3602
3603 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3604 {
3605         TALLOC_FREE(Globals.szNetbiosAliases);
3606         Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
3607         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3608 }
3609
3610 /***************************************************************************
3611  Handle the include operation.
3612 ***************************************************************************/
3613
3614 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
3615 {
3616         char *fname;
3617
3618         fname = alloc_sub_basic(get_current_username(),
3619                                 current_user_info.domain,
3620                                 pszParmValue);
3621
3622         add_to_file_list(pszParmValue, fname);
3623
3624         string_set(ptr, fname);
3625
3626         if (file_exist(fname, NULL)) {
3627                 bool ret = pm_process(fname, do_section, do_parameter);
3628                 SAFE_FREE(fname);
3629                 return ret;
3630         }
3631
3632         DEBUG(2, ("Can't find include file %s\n", fname));
3633         SAFE_FREE(fname);
3634         return false;
3635 }
3636
3637 /***************************************************************************
3638  Handle the interpretation of the copy parameter.
3639 ***************************************************************************/
3640
3641 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
3642 {
3643         bool bRetval;
3644         int iTemp;
3645         service serviceTemp;
3646
3647         string_set(ptr, pszParmValue);
3648
3649         init_service(&serviceTemp);
3650
3651         bRetval = False;
3652
3653         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3654
3655         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3656                 if (iTemp == iServiceIndex) {
3657                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3658                 } else {
3659                         copy_service(ServicePtrs[iServiceIndex],
3660                                      &serviceTemp,
3661                                      ServicePtrs[iServiceIndex]->copymap);
3662                         bRetval = True;
3663                 }
3664         } else {
3665                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3666                 bRetval = False;
3667         }
3668
3669         free_service(&serviceTemp);
3670         return (bRetval);
3671 }
3672
3673 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
3674 {
3675         Globals.ldap_debug_level = lp_int(pszParmValue);
3676         init_ldap_debugging();
3677         return true;
3678 }
3679
3680 /***************************************************************************
3681  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
3682  parameters is:
3683
3684  [global]
3685
3686         idmap uid = 1000-1999
3687         idmap gid = 700-899
3688
3689  We only do simple parsing checks here.  The strings are parsed into useful
3690  structures in the idmap daemon code.
3691
3692 ***************************************************************************/
3693
3694 /* Some lp_ routines to return idmap [ug]id information */
3695
3696 static uid_t idmap_uid_low, idmap_uid_high;
3697 static gid_t idmap_gid_low, idmap_gid_high;
3698
3699 bool lp_idmap_uid(uid_t *low, uid_t *high)
3700 {
3701         if (idmap_uid_low == 0 || idmap_uid_high == 0)
3702                 return False;
3703
3704         if (low)
3705                 *low = idmap_uid_low;
3706
3707         if (high)
3708                 *high = idmap_uid_high;
3709
3710         return True;
3711 }
3712
3713 bool lp_idmap_gid(gid_t *low, gid_t *high)
3714 {
3715         if (idmap_gid_low == 0 || idmap_gid_high == 0)
3716                 return False;
3717
3718         if (low)
3719                 *low = idmap_gid_low;
3720
3721         if (high)
3722                 *high = idmap_gid_high;
3723
3724         return True;
3725 }
3726
3727 /* Do some simple checks on "idmap [ug]id" parameter values */
3728
3729 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3730 {
3731         uint32 low, high;
3732
3733         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3734                 return False;
3735
3736         /* Parse OK */
3737
3738         string_set(ptr, pszParmValue);
3739
3740         idmap_uid_low = low;
3741         idmap_uid_high = high;
3742
3743         return True;
3744 }
3745
3746 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3747 {
3748         uint32 low, high;
3749
3750         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3751                 return False;
3752
3753         /* Parse OK */
3754
3755         string_set(ptr, pszParmValue);
3756
3757         idmap_gid_low = low;
3758         idmap_gid_high = high;
3759
3760         return True;
3761 }
3762
3763 /***************************************************************************
3764  Handle the DEBUG level list.
3765 ***************************************************************************/
3766
3767 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3768 {
3769         string_set(ptr, pszParmValueIn);
3770         return debug_parse_levels(pszParmValueIn);
3771 }
3772
3773 /***************************************************************************
3774  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3775 ***************************************************************************/