loadparm: remove unneeded include.
[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
56 bool bLoaded = False;
57
58 extern enum protocol_types Protocol;
59 extern userdom_struct current_user_info;
60
61 #ifndef GLOBAL_NAME
62 #define GLOBAL_NAME "global"
63 #endif
64
65 #ifndef PRINTERS_NAME
66 #define PRINTERS_NAME "printers"
67 #endif
68
69 #ifndef HOMES_NAME
70 #define HOMES_NAME "homes"
71 #endif
72
73 static bool in_client = False;          /* Not in the client by default */
74 static uint64_t conf_last_seqnum = 0;
75 static struct smbconf_ctx *conf_ctx = NULL;
76
77 #define CONFIG_BACKEND_FILE 0
78 #define CONFIG_BACKEND_REGISTRY 1
79
80 static int config_backend = CONFIG_BACKEND_FILE;
81
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
84 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
85
86 #define USERSHARE_VALID 1
87 #define USERSHARE_PENDING_DELETE 2
88
89 extern int extra_time_offset;
90
91 static bool defaults_saved = False;
92
93 typedef struct _param_opt_struct param_opt_struct;
94 struct _param_opt_struct {
95         param_opt_struct *prev, *next;
96         char *key;
97         char *value;
98         char **list;
99 };
100
101 /*
102  * This structure describes global (ie., server-wide) parameters.
103  */
104 struct global {
105         int ConfigBackend;
106         char *smb_ports;
107         char *dos_charset;
108         char *unix_charset;
109         char *display_charset;
110         char *szPrintcapname;
111         char *szAddPortCommand;
112         char *szEnumPortsCommand;
113         char *szAddPrinterCommand;
114         char *szDeletePrinterCommand;
115         char *szOs2DriverMap;
116         char *szLockDir;
117         char *szPidDir;
118         char *szRootdir;
119         char *szDefaultService;
120         char *szGetQuota;
121         char *szSetQuota;
122         char *szMsgCommand;
123         char *szServerString;
124         char *szAutoServices;
125         char *szPasswdProgram;
126         char *szPasswdChat;
127         char *szLogFile;
128         char *szConfigFile;
129         char *szSMBPasswdFile;
130         char *szPrivateDir;
131         char *szPassdbBackend;
132         char **szPreloadModules;
133         char *szPasswordServer;
134         char *szSocketOptions;
135         char *szRealm;
136         char *szAfsUsernameMap;
137         int iAfsTokenLifetime;
138         char *szLogNtTokenCommand;
139         char *szUsernameMap;
140         char *szLogonScript;
141         char *szLogonPath;
142         char *szLogonDrive;
143         char *szLogonHome;
144         char **szWINSservers;
145         char **szInterfaces;
146         char *szRemoteAnnounce;
147         char *szRemoteBrowseSync;
148         char *szSocketAddress;
149         char *szNISHomeMapName;
150         char *szAnnounceVersion;        /* This is initialised in init_globals */
151         char *szWorkgroup;
152         char *szNetbiosName;
153         char **szNetbiosAliases;
154         char *szNetbiosScope;
155         char *szNameResolveOrder;
156         char *szPanicAction;
157         char *szAddUserScript;
158         char *szRenameUserScript;
159         char *szDelUserScript;
160         char *szAddGroupScript;
161         char *szDelGroupScript;
162         char *szAddUserToGroupScript;
163         char *szDelUserFromGroupScript;
164         char *szSetPrimaryGroupScript;
165         char *szAddMachineScript;
166         char *szShutdownScript;
167         char *szAbortShutdownScript;
168         char *szUsernameMapScript;
169         char *szCheckPasswordScript;
170         char *szWINSHook;
171         char *szUtmpDir;
172         char *szWtmpDir;
173         bool bUtmp;
174         char *szIdmapUID;
175         char *szIdmapGID;
176         bool bPassdbExpandExplicit;
177         int AlgorithmicRidBase;
178         char *szTemplateHomedir;
179         char *szTemplateShell;
180         char *szWinbindSeparator;
181         bool bWinbindEnumUsers;
182         bool bWinbindEnumGroups;
183         bool bWinbindUseDefaultDomain;
184         bool bWinbindTrustedDomainsOnly;
185         bool bWinbindNestedGroups;
186         int  winbind_expand_groups;
187         bool bWinbindRefreshTickets;
188         bool bWinbindOfflineLogon;
189         bool bWinbindNormalizeNames;
190         bool bWinbindRpcOnly;
191         char **szIdmapDomains;
192         char **szIdmapBackend; /* deprecated */
193         char *szIdmapAllocBackend;
194         char *szAddShareCommand;
195         char *szChangeShareCommand;
196         char *szDeleteShareCommand;
197         char **szEventLogs;
198         char *szGuestaccount;
199         char *szManglingMethod;
200         char **szServicesList;
201         char *szUsersharePath;
202         char *szUsershareTemplateShare;
203         char **szUsersharePrefixAllowList;
204         char **szUsersharePrefixDenyList;
205         int mangle_prefix;
206         int max_log_size;
207         char *szLogLevel;
208         int max_xmit;
209         int max_mux;
210         int max_open_files;
211         int open_files_db_hash_size;
212         int pwordlevel;
213         int unamelevel;
214         int deadtime;
215         bool getwd_cache;
216         int maxprotocol;
217         int minprotocol;
218         int security;
219         char **AuthMethods;
220         bool paranoid_server_security;
221         int maxdisksize;
222         int lpqcachetime;
223         int iMaxSmbdProcesses;
224         bool bDisableSpoolss;
225         int syslog;
226         int os_level;
227         bool enhanced_browsing;
228         int max_ttl;
229         int max_wins_ttl;
230         int min_wins_ttl;
231         int lm_announce;
232         int lm_interval;
233         int announce_as;        /* This is initialised in init_globals */
234         int machine_password_timeout;
235         int map_to_guest;
236         int oplock_break_wait_time;
237         int winbind_cache_time;
238         int winbind_max_idle_children;
239         char **szWinbindNssInfo;
240         int iLockSpinTime;
241         char *szLdapMachineSuffix;
242         char *szLdapUserSuffix;
243         char *szLdapIdmapSuffix;
244         char *szLdapGroupSuffix;
245         int ldap_ssl;
246         char *szLdapSuffix;
247         char *szLdapAdminDn;
248         int ldap_debug_level;
249         int ldap_debug_threshold;
250         int iAclCompat;
251         char *szCupsServer;
252         char *szIPrintServer;
253         char *ctdbdSocket;
254         char **szClusterAddresses;
255         bool clustering;
256         int ldap_passwd_sync;
257         int ldap_replication_sleep;
258         int ldap_timeout; /* This is initialised in init_globals */
259         int ldap_page_size;
260         bool ldap_delete_dn;
261         bool bMsAddPrinterWizard;
262         bool bDNSproxy;
263         bool bWINSsupport;
264         bool bWINSproxy;
265         bool bLocalMaster;
266         int  iPreferredMaster;
267         int iDomainMaster;
268         bool bDomainLogons;
269         bool bEncryptPasswords;
270         bool bUpdateEncrypt;
271         int  clientSchannel;
272         int  serverSchannel;
273         bool bNullPasswords;
274         bool bObeyPamRestrictions;
275         bool bLoadPrinters;
276         int PrintcapCacheTime;
277         bool bLargeReadwrite;
278         bool bReadRaw;
279         bool bWriteRaw;
280         bool bSyslogOnly;
281         bool bBrowseList;
282         bool bNISHomeMap;
283         bool bTimeServer;
284         bool bBindInterfacesOnly;
285         bool bPamPasswordChange;
286         bool bUnixPasswdSync;
287         bool bPasswdChatDebug;
288         int iPasswdChatTimeout;
289         bool bTimestampLogs;
290         bool bNTSmbSupport;
291         bool bNTPipeSupport;
292         bool bNTStatusSupport;
293         bool bStatCache;
294         int iMaxStatCacheSize;
295         bool bKernelOplocks;
296         bool bAllowTrustedDomains;
297         bool bLanmanAuth;
298         bool bNTLMAuth;
299         bool bUseSpnego;
300         bool bClientLanManAuth;
301         bool bClientNTLMv2Auth;
302         bool bClientPlaintextAuth;
303         bool bClientUseSpnego;
304         bool bDebugPrefixTimestamp;
305         bool bDebugHiresTimestamp;
306         bool bDebugPid;
307         bool bDebugUid;
308         bool bDebugClass;
309         bool bEnableCoreFiles;
310         bool bHostMSDfs;
311         bool bUseMmap;
312         bool bHostnameLookups;
313         bool bUnixExtensions;
314         bool bDisableNetbios;
315         bool bUseKerberosKeytab;
316         bool bDeferSharingViolations;
317         bool bEnablePrivileges;
318         bool bASUSupport;
319         bool bUsershareOwnerOnly;
320         bool bUsershareAllowGuests;
321         bool bRegistryShares;
322         int restrict_anonymous;
323         int name_cache_timeout;
324         int client_signing;
325         int server_signing;
326         int client_ldap_sasl_wrapping;
327         int iUsershareMaxShares;
328         int iIdmapCacheTime;
329         int iIdmapNegativeCacheTime;
330         bool bResetOnZeroVC;
331         int iKeepalive;
332         int iminreceivefile;
333         param_opt_struct *param_opt;
334 };
335
336 static struct global Globals;
337
338 /*
339  * This structure describes a single service.
340  */
341 struct service {
342         bool valid;
343         bool autoloaded;
344         int usershare;
345         time_t usershare_last_mod;
346         char *szService;
347         char *szPath;
348         char *szUsername;
349         char **szInvalidUsers;
350         char **szValidUsers;
351         char **szAdminUsers;
352         char *szCopy;
353         char *szInclude;
354         char *szPreExec;
355         char *szPostExec;
356         char *szRootPreExec;
357         char *szRootPostExec;
358         char *szCupsOptions;
359         char *szPrintcommand;
360         char *szLpqcommand;
361         char *szLprmcommand;
362         char *szLppausecommand;
363         char *szLpresumecommand;
364         char *szQueuepausecommand;
365         char *szQueueresumecommand;
366         char *szPrintername;
367         char *szPrintjobUsername;
368         char *szDontdescend;
369         char **szHostsallow;
370         char **szHostsdeny;
371         char *szMagicScript;
372         char *szMagicOutput;
373         char *szVetoFiles;
374         char *szHideFiles;
375         char *szVetoOplockFiles;
376         char *comment;
377         char *force_user;
378         char *force_group;
379         char **readlist;
380         char **writelist;
381         char **printer_admin;
382         char *volume;
383         char *fstype;
384         char **szVfsObjects;
385         char *szMSDfsProxy;
386         char *szAioWriteBehind;
387         char *szDfree;
388         int iMinPrintSpace;
389         int iMaxPrintJobs;
390         int iMaxReportedPrintJobs;
391         int iWriteCacheSize;
392         int iCreate_mask;
393         int iCreate_force_mode;
394         int iSecurity_mask;
395         int iSecurity_force_mode;
396         int iDir_mask;
397         int iDir_force_mode;
398         int iDir_Security_mask;
399         int iDir_Security_force_mode;
400         int iMaxConnections;
401         int iDefaultCase;
402         int iPrinting;
403         int iOplockContentionLimit;
404         int iCSCPolicy;
405         int iBlock_size;
406         int iDfreeCacheTime;
407         bool bPreexecClose;
408         bool bRootpreexecClose;
409         int  iCaseSensitive;
410         bool bCasePreserve;
411         bool bShortCasePreserve;
412         bool bHideDotFiles;
413         bool bHideSpecialFiles;
414         bool bHideUnReadable;
415         bool bHideUnWriteableFiles;
416         bool bBrowseable;
417         bool bAvailable;
418         bool bRead_only;
419         bool bNo_set_dir;
420         bool bGuest_only;
421         bool bAdministrative_share;
422         bool bGuest_ok;
423         bool bPrint_ok;
424         bool bMap_system;
425         bool bMap_hidden;
426         bool bMap_archive;
427         bool bStoreDosAttributes;
428         bool bDmapiSupport;
429         bool bLocking;
430         int iStrictLocking;
431         bool bPosixLocking;
432         bool bShareModes;
433         bool bOpLocks;
434         bool bLevel2OpLocks;
435         bool bOnlyUser;
436         bool bMangledNames;
437         bool bWidelinks;
438         bool bSymlinks;
439         bool bSyncAlways;
440         bool bStrictAllocate;
441         bool bStrictSync;
442         char magic_char;
443         struct bitmap *copymap;
444         bool bDeleteReadonly;
445         bool bFakeOplocks;
446         bool bDeleteVetoFiles;
447         bool bDosFilemode;
448         bool bDosFiletimes;
449         bool bDosFiletimeResolution;
450         bool bFakeDirCreateTimes;
451         bool bBlockingLocks;
452         bool bInheritPerms;
453         bool bInheritACLS;
454         bool bInheritOwner;
455         bool bMSDfsRoot;
456         bool bUseClientDriver;
457         bool bDefaultDevmode;
458         bool bForcePrintername;
459         bool bNTAclSupport;
460         bool bForceUnknownAclUser;
461         bool bUseSendfile;
462         bool bProfileAcls;
463         bool bMap_acl_inherit;
464         bool bAfs_Share;
465         bool bEASupport;
466         bool bAclCheckPermissions;
467         bool bAclMapFullControl;
468         bool bAclGroupControl;
469         bool bChangeNotify;
470         bool bKernelChangeNotify;
471         int iallocation_roundup_size;
472         int iAioReadSize;
473         int iAioWriteSize;
474         int iMap_readonly;
475         int iDirectoryNameCacheSize;
476         int ismb_encrypt;
477         param_opt_struct *param_opt;
478
479         char dummy[3];          /* for alignment */
480 };
481
482
483 /* This is a default service used to prime a services structure */
484 static struct service sDefault = {
485         True,                   /* valid */
486         False,                  /* not autoloaded */
487         0,                      /* not a usershare */
488         (time_t)0,              /* No last mod time */
489         NULL,                   /* szService */
490         NULL,                   /* szPath */
491         NULL,                   /* szUsername */
492         NULL,                   /* szInvalidUsers */
493         NULL,                   /* szValidUsers */
494         NULL,                   /* szAdminUsers */
495         NULL,                   /* szCopy */
496         NULL,                   /* szInclude */
497         NULL,                   /* szPreExec */
498         NULL,                   /* szPostExec */
499         NULL,                   /* szRootPreExec */
500         NULL,                   /* szRootPostExec */
501         NULL,                   /* szCupsOptions */
502         NULL,                   /* szPrintcommand */
503         NULL,                   /* szLpqcommand */
504         NULL,                   /* szLprmcommand */
505         NULL,                   /* szLppausecommand */
506         NULL,                   /* szLpresumecommand */
507         NULL,                   /* szQueuepausecommand */
508         NULL,                   /* szQueueresumecommand */
509         NULL,                   /* szPrintername */
510         NULL,                   /* szPrintjobUsername */
511         NULL,                   /* szDontdescend */
512         NULL,                   /* szHostsallow */
513         NULL,                   /* szHostsdeny */
514         NULL,                   /* szMagicScript */
515         NULL,                   /* szMagicOutput */
516         NULL,                   /* szVetoFiles */
517         NULL,                   /* szHideFiles */
518         NULL,                   /* szVetoOplockFiles */
519         NULL,                   /* comment */
520         NULL,                   /* force user */
521         NULL,                   /* force group */
522         NULL,                   /* readlist */
523         NULL,                   /* writelist */
524         NULL,                   /* printer admin */
525         NULL,                   /* volume */
526         NULL,                   /* fstype */
527         NULL,                   /* vfs objects */
528         NULL,                   /* szMSDfsProxy */
529         NULL,                   /* szAioWriteBehind */
530         NULL,                   /* szDfree */
531         0,                      /* iMinPrintSpace */
532         1000,                   /* iMaxPrintJobs */
533         0,                      /* iMaxReportedPrintJobs */
534         0,                      /* iWriteCacheSize */
535         0744,                   /* iCreate_mask */
536         0000,                   /* iCreate_force_mode */
537         0777,                   /* iSecurity_mask */
538         0,                      /* iSecurity_force_mode */
539         0755,                   /* iDir_mask */
540         0000,                   /* iDir_force_mode */
541         0777,                   /* iDir_Security_mask */
542         0,                      /* iDir_Security_force_mode */
543         0,                      /* iMaxConnections */
544         CASE_LOWER,             /* iDefaultCase */
545         DEFAULT_PRINTING,       /* iPrinting */
546         2,                      /* iOplockContentionLimit */
547         0,                      /* iCSCPolicy */
548         1024,                   /* iBlock_size */
549         0,                      /* iDfreeCacheTime */
550         False,                  /* bPreexecClose */
551         False,                  /* bRootpreexecClose */
552         Auto,                   /* case sensitive */
553         True,                   /* case preserve */
554         True,                   /* short case preserve */
555         True,                   /* bHideDotFiles */
556         False,                  /* bHideSpecialFiles */
557         False,                  /* bHideUnReadable */
558         False,                  /* bHideUnWriteableFiles */
559         True,                   /* bBrowseable */
560         True,                   /* bAvailable */
561         True,                   /* bRead_only */
562         True,                   /* bNo_set_dir */
563         False,                  /* bGuest_only */
564         False,                  /* bAdministrative_share */
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 struct 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         {
878                 .label          = "dos charset",
879                 .type           = P_STRING,
880                 .p_class        = P_GLOBAL,
881                 .ptr            = &Globals.dos_charset,
882                 .special        = handle_charset,
883                 .enum_list      = NULL,
884                 .flags          = FLAG_ADVANCED
885         },
886         {
887                 .label          = "unix charset",
888                 .type           = P_STRING,
889                 .p_class        = P_GLOBAL,
890                 .ptr            = &Globals.unix_charset,
891                 .special        = handle_charset,
892                 .enum_list      = NULL,
893                 .flags          = FLAG_ADVANCED
894         },
895         {
896                 .label          = "display charset",
897                 .type           = P_STRING,
898                 .p_class        = P_GLOBAL,
899                 .ptr            = &Globals.display_charset,
900                 .special        = handle_charset,
901                 .enum_list      = NULL,
902                 .flags          = FLAG_ADVANCED
903         },
904         {
905                 .label          = "comment",
906                 .type           = P_STRING,
907                 .p_class        = P_LOCAL,
908                 .ptr            = &sDefault.comment,
909                 .special        = NULL,
910                 .enum_list      = NULL,
911                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
912         },
913         {
914                 .label          = "path",
915                 .type           = P_STRING,
916                 .p_class        = P_LOCAL,
917                 .ptr            = &sDefault.szPath,
918                 .special        = NULL,
919                 .enum_list      = NULL,
920                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
921         },
922         {
923                 .label          = "directory",
924                 .type           = P_STRING,
925                 .p_class        = P_LOCAL,
926                 .ptr            = &sDefault.szPath,
927                 .special        = NULL,
928                 .enum_list      = NULL,
929                 .flags          = FLAG_HIDE,
930         },
931         {
932                 .label          = "workgroup",
933                 .type           = P_USTRING,
934                 .p_class        = P_GLOBAL,
935                 .ptr            = &Globals.szWorkgroup,
936                 .special        = handle_workgroup,
937                 .enum_list      = NULL,
938                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
939         },
940 #ifdef WITH_ADS
941         {
942                 .label          = "realm",
943                 .type           = P_USTRING,
944                 .p_class        = P_GLOBAL,
945                 .ptr            = &Globals.szRealm,
946                 .special        = NULL,
947                 .enum_list      = NULL,
948                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
949         },
950 #endif
951         {
952                 .label          = "netbios name",
953                 .type           = P_USTRING,
954                 .p_class        = P_GLOBAL,
955                 .ptr            = &Globals.szNetbiosName,
956                 .special        = handle_netbios_name,
957                 .enum_list      = NULL,
958                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
959         },
960         {
961                 .label          = "netbios aliases",
962                 .type           = P_LIST,
963                 .p_class        = P_GLOBAL,
964                 .ptr            = &Globals.szNetbiosAliases,
965                 .special        = handle_netbios_aliases,
966                 .enum_list      = NULL,
967                 .flags          = FLAG_ADVANCED,
968         },
969         {
970                 .label          = "netbios scope",
971                 .type           = P_USTRING,
972                 .p_class        = P_GLOBAL,
973                 .ptr            = &Globals.szNetbiosScope,
974                 .special        = handle_netbios_scope,
975                 .enum_list      = NULL,
976                 .flags          = FLAG_ADVANCED,
977         },
978         {
979                 .label          = "server string",
980                 .type           = P_STRING,
981                 .p_class        = P_GLOBAL,
982                 .ptr            = &Globals.szServerString,
983                 .special        = NULL,
984                 .enum_list      = NULL,
985                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
986         },
987         {
988                 .label          = "interfaces",
989                 .type           = P_LIST,
990                 .p_class        = P_GLOBAL,
991                 .ptr            = &Globals.szInterfaces,
992                 .special        = NULL,
993                 .enum_list      = NULL,
994                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
995         },
996         {
997                 .label          = "bind interfaces only",
998                 .type           = P_BOOL,
999                 .p_class        = P_GLOBAL,
1000                 .ptr            = &Globals.bBindInterfacesOnly,
1001                 .special        = NULL,
1002                 .enum_list      = NULL,
1003                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1004         },
1005         {
1006                 .label          = "config backend",
1007                 .type           = P_ENUM,
1008                 .p_class        = P_GLOBAL,
1009                 .ptr            = &Globals.ConfigBackend,
1010                 .special        = NULL,
1011                 .enum_list      = enum_config_backend,
1012                 .flags          = FLAG_ADVANCED,
1013         },
1014
1015         {N_("Security Options"), P_SEP, P_SEPARATOR},
1016
1017         {
1018                 .label          = "security",
1019                 .type           = P_ENUM,
1020                 .p_class        = P_GLOBAL,
1021                 .ptr            = &Globals.security,
1022                 .special        = NULL,
1023                 .enum_list      = enum_security,
1024                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1025         },
1026         {
1027                 .label          = "auth methods",
1028                 .type           = P_LIST,
1029                 .p_class        = P_GLOBAL,
1030                 .ptr            = &Globals.AuthMethods,
1031                 .special        = NULL,
1032                 .enum_list      = NULL,
1033                 .flags          = FLAG_ADVANCED,
1034         },
1035         {
1036                 .label          = "encrypt passwords",
1037                 .type           = P_BOOL,
1038                 .p_class        = P_GLOBAL,
1039                 .ptr            = &Globals.bEncryptPasswords,
1040                 .special        = NULL,
1041                 .enum_list      = NULL,
1042                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1043         },
1044         {
1045                 .label          = "update encrypted",
1046                 .type           = P_BOOL,
1047                 .p_class        = P_GLOBAL,
1048                 .ptr            = &Globals.bUpdateEncrypt,
1049                 .special        = NULL,
1050                 .enum_list      = NULL,
1051                 .flags          = FLAG_ADVANCED,
1052         },
1053         {
1054                 .label          = "client schannel",
1055                 .type           = P_ENUM,
1056                 .p_class        = P_GLOBAL,
1057                 .ptr            = &Globals.clientSchannel,
1058                 .special        = NULL,
1059                 .enum_list      = enum_bool_auto,
1060                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1061         },
1062         {
1063                 .label          = "server schannel",
1064                 .type           = P_ENUM,
1065                 .p_class        = P_GLOBAL,
1066                 .ptr            = &Globals.serverSchannel,
1067                 .special        = NULL,
1068                 .enum_list      = enum_bool_auto,
1069                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1070         },
1071         {
1072                 .label          = "allow trusted domains",
1073                 .type           = P_BOOL,
1074                 .p_class        = P_GLOBAL,
1075                 .ptr            = &Globals.bAllowTrustedDomains,
1076                 .special        = NULL,
1077                 .enum_list      = NULL,
1078                 .flags          = FLAG_ADVANCED,
1079         },
1080         {
1081                 .label          = "map to guest",
1082                 .type           = P_ENUM,
1083                 .p_class        = P_GLOBAL,
1084                 .ptr            = &Globals.map_to_guest,
1085                 .special        = NULL,
1086                 .enum_list      = enum_map_to_guest,
1087                 .flags          = FLAG_ADVANCED,
1088         },
1089         {
1090                 .label          = "null passwords",
1091                 .type           = P_BOOL,
1092                 .p_class        = P_GLOBAL,
1093                 .ptr            = &Globals.bNullPasswords,
1094                 .special        = NULL,
1095                 .enum_list      = NULL,
1096                 .flags          = FLAG_ADVANCED,
1097         },
1098         {
1099                 .label          = "obey pam restrictions",
1100                 .type           = P_BOOL,
1101                 .p_class        = P_GLOBAL,
1102                 .ptr            = &Globals.bObeyPamRestrictions,
1103                 .special        = NULL,
1104                 .enum_list      = NULL,
1105                 .flags          = FLAG_ADVANCED,
1106         },
1107         {
1108                 .label          = "password server",
1109                 .type           = P_STRING,
1110                 .p_class        = P_GLOBAL,
1111                 .ptr            = &Globals.szPasswordServer,
1112                 .special        = NULL,
1113                 .enum_list      = NULL,
1114                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1115         },
1116         {
1117                 .label          = "smb passwd file",
1118                 .type           = P_STRING,
1119                 .p_class        = P_GLOBAL,
1120                 .ptr            = &Globals.szSMBPasswdFile,
1121                 .special        = NULL,
1122                 .enum_list      = NULL,
1123                 .flags          = FLAG_ADVANCED,
1124         },
1125         {
1126                 .label          = "private dir",
1127                 .type           = P_STRING,
1128                 .p_class        = P_GLOBAL,
1129                 .ptr            = &Globals.szPrivateDir,
1130                 .special        = NULL,
1131                 .enum_list      = NULL,
1132                 .flags          = FLAG_ADVANCED,
1133         },
1134         {
1135                 .label          = "passdb backend",
1136                 .type           = P_STRING,
1137                 .p_class        = P_GLOBAL,
1138                 .ptr            = &Globals.szPassdbBackend,
1139                 .special        = NULL,
1140                 .enum_list      = NULL,
1141                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1142         },
1143         {
1144                 .label          = "algorithmic rid base",
1145                 .type           = P_INTEGER,
1146                 .p_class        = P_GLOBAL,
1147                 .ptr            = &Globals.AlgorithmicRidBase,
1148                 .special        = NULL,
1149                 .enum_list      = NULL,
1150                 .flags          = FLAG_ADVANCED,
1151         },
1152         {
1153                 .label          = "root directory",
1154                 .type           = P_STRING,
1155                 .p_class        = P_GLOBAL,
1156                 .ptr            = &Globals.szRootdir,
1157                 .special        = NULL,
1158                 .enum_list      = NULL,
1159                 .flags          = FLAG_ADVANCED,
1160         },
1161         {
1162                 .label          = "root dir",
1163                 .type           = P_STRING,
1164                 .p_class        = P_GLOBAL,
1165                 .ptr            = &Globals.szRootdir,
1166                 .special        = NULL,
1167                 .enum_list      = NULL,
1168                 .flags          = FLAG_HIDE,
1169         },
1170         {
1171                 .label          = "root",
1172                 .type           = P_STRING,
1173                 .p_class        = P_GLOBAL,
1174                 .ptr            = &Globals.szRootdir,
1175                 .special        = NULL,
1176                 .enum_list      = NULL,
1177                 .flags          = FLAG_HIDE,
1178         },
1179         {
1180                 .label          = "guest account",
1181                 .type           = P_STRING,
1182                 .p_class        = P_GLOBAL,
1183                 .ptr            = &Globals.szGuestaccount,
1184                 .special        = NULL,
1185                 .enum_list      = NULL,
1186                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1187         },
1188         {
1189                 .label          = "enable privileges",
1190                 .type           = P_BOOL,
1191                 .p_class        = P_GLOBAL,
1192                 .ptr            = &Globals.bEnablePrivileges,
1193                 .special        = NULL,
1194                 .enum_list      = NULL,
1195                 .flags          = FLAG_ADVANCED,
1196         },
1197
1198         {
1199                 .label          = "pam password change",
1200                 .type           = P_BOOL,
1201                 .p_class        = P_GLOBAL,
1202                 .ptr            = &Globals.bPamPasswordChange,
1203                 .special        = NULL,
1204                 .enum_list      = NULL,
1205                 .flags          = FLAG_ADVANCED,
1206         },
1207         {
1208                 .label          = "passwd program",
1209                 .type           = P_STRING,
1210                 .p_class        = P_GLOBAL,
1211                 .ptr            = &Globals.szPasswdProgram,
1212                 .special        = NULL,
1213                 .enum_list      = NULL,
1214                 .flags          = FLAG_ADVANCED,
1215         },
1216         {
1217                 .label          = "passwd chat",
1218                 .type           = P_STRING,
1219                 .p_class        = P_GLOBAL,
1220                 .ptr            = &Globals.szPasswdChat,
1221                 .special        = NULL,
1222                 .enum_list      = NULL,
1223                 .flags          = FLAG_ADVANCED,
1224         },
1225         {
1226                 .label          = "passwd chat debug",
1227                 .type           = P_BOOL,
1228                 .p_class        = P_GLOBAL,
1229                 .ptr            = &Globals.bPasswdChatDebug,
1230                 .special        = NULL,
1231                 .enum_list      = NULL,
1232                 .flags          = FLAG_ADVANCED,
1233         },
1234         {
1235                 .label          = "passwd chat timeout",
1236                 .type           = P_INTEGER,
1237                 .p_class        = P_GLOBAL,
1238                 .ptr            = &Globals.iPasswdChatTimeout,
1239                 .special        = NULL,
1240                 .enum_list      = NULL,
1241                 .flags          = FLAG_ADVANCED,
1242         },
1243         {
1244                 .label          = "check password script",
1245                 .type           = P_STRING,
1246                 .p_class        = P_GLOBAL,
1247                 .ptr            = &Globals.szCheckPasswordScript,
1248                 .special        = NULL,
1249                 .enum_list      = NULL,
1250                 .flags          = FLAG_ADVANCED,
1251         },
1252         {
1253                 .label          = "username map",
1254                 .type           = P_STRING,
1255                 .p_class        = P_GLOBAL,
1256                 .ptr            = &Globals.szUsernameMap,
1257                 .special        = NULL,
1258                 .enum_list      = NULL,
1259                 .flags          = FLAG_ADVANCED,
1260         },
1261         {
1262                 .label          = "password level",
1263                 .type           = P_INTEGER,
1264                 .p_class        = P_GLOBAL,
1265                 .ptr            = &Globals.pwordlevel,
1266                 .special        = NULL,
1267                 .enum_list      = NULL,
1268                 .flags          = FLAG_ADVANCED,
1269         },
1270         {
1271                 .label          = "username level",
1272                 .type           = P_INTEGER,
1273                 .p_class        = P_GLOBAL,
1274                 .ptr            = &Globals.unamelevel,
1275                 .special        = NULL,
1276                 .enum_list      = NULL,
1277                 .flags          = FLAG_ADVANCED,
1278         },
1279         {
1280                 .label          = "unix password sync",
1281                 .type           = P_BOOL,
1282                 .p_class        = P_GLOBAL,
1283                 .ptr            = &Globals.bUnixPasswdSync,
1284                 .special        = NULL,
1285                 .enum_list      = NULL,
1286                 .flags          = FLAG_ADVANCED,
1287         },
1288         {
1289                 .label          = "restrict anonymous",
1290                 .type           = P_INTEGER,
1291                 .p_class        = P_GLOBAL,
1292                 .ptr            = &Globals.restrict_anonymous,
1293                 .special        = NULL,
1294                 .enum_list      = NULL,
1295                 .flags          = FLAG_ADVANCED,
1296         },
1297         {
1298                 .label          = "lanman auth",
1299                 .type           = P_BOOL,
1300                 .p_class        = P_GLOBAL,
1301                 .ptr            = &Globals.bLanmanAuth,
1302                 .special        = NULL,
1303                 .enum_list      = NULL,
1304                 .flags          = FLAG_ADVANCED,
1305         },
1306         {
1307                 .label          = "ntlm auth",
1308                 .type           = P_BOOL,
1309                 .p_class        = P_GLOBAL,
1310                 .ptr            = &Globals.bNTLMAuth,
1311                 .special        = NULL,
1312                 .enum_list      = NULL,
1313                 .flags          = FLAG_ADVANCED,
1314         },
1315         {
1316                 .label          = "client NTLMv2 auth",
1317                 .type           = P_BOOL,
1318                 .p_class        = P_GLOBAL,
1319                 .ptr            = &Globals.bClientNTLMv2Auth,
1320                 .special        = NULL,
1321                 .enum_list      = NULL,
1322                 .flags          = FLAG_ADVANCED,
1323         },
1324         {
1325                 .label          = "client lanman auth",
1326                 .type           = P_BOOL,
1327                 .p_class        = P_GLOBAL,
1328                 .ptr            = &Globals.bClientLanManAuth,
1329                 .special        = NULL,
1330                 .enum_list      = NULL,
1331                 .flags          = FLAG_ADVANCED,
1332         },
1333         {
1334                 .label          = "client plaintext auth",
1335                 .type           = P_BOOL,
1336                 .p_class        = P_GLOBAL,
1337                 .ptr            = &Globals.bClientPlaintextAuth,
1338                 .special        = NULL,
1339                 .enum_list      = NULL,
1340                 .flags          = FLAG_ADVANCED,
1341         },
1342         {
1343                 .label          = "username",
1344                 .type           = P_STRING,
1345                 .p_class        = P_LOCAL,
1346                 .ptr            = &sDefault.szUsername,
1347                 .special        = NULL,
1348                 .enum_list      = NULL,
1349                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1350         },
1351         {
1352                 .label          = "user",
1353                 .type           = P_STRING,
1354                 .p_class        = P_LOCAL,
1355                 .ptr            = &sDefault.szUsername,
1356                 .special        = NULL,
1357                 .enum_list      = NULL,
1358                 .flags          = FLAG_HIDE,
1359         },
1360         {
1361                 .label          = "users",
1362                 .type           = P_STRING,
1363                 .p_class        = P_LOCAL,
1364                 .ptr            = &sDefault.szUsername,
1365                 .special        = NULL,
1366                 .enum_list      = NULL,
1367                 .flags          = FLAG_HIDE,
1368         },
1369         {
1370                 .label          = "invalid users",
1371                 .type           = P_LIST,
1372                 .p_class        = P_LOCAL,
1373                 .ptr            = &sDefault.szInvalidUsers,
1374                 .special        = NULL,
1375                 .enum_list      = NULL,
1376                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1377         },
1378         {
1379                 .label          = "valid users",
1380                 .type           = P_LIST,
1381                 .p_class        = P_LOCAL,
1382                 .ptr            = &sDefault.szValidUsers,
1383                 .special        = NULL,
1384                 .enum_list      = NULL,
1385                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1386         },
1387         {
1388                 .label          = "admin users",
1389                 .type           = P_LIST,
1390                 .p_class        = P_LOCAL,
1391                 .ptr            = &sDefault.szAdminUsers,
1392                 .special        = NULL,
1393                 .enum_list      = NULL,
1394                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1395         },
1396         {
1397                 .label          = "read list",
1398                 .type           = P_LIST,
1399                 .p_class        = P_LOCAL,
1400                 .ptr            = &sDefault.readlist,
1401                 .special        = NULL,
1402                 .enum_list      = NULL,
1403                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1404         },
1405         {
1406                 .label          = "write list",
1407                 .type           = P_LIST,
1408                 .p_class        = P_LOCAL,
1409                 .ptr            = &sDefault.writelist,
1410                 .special        = NULL,
1411                 .enum_list      = NULL,
1412                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1413         },
1414         {
1415                 .label          = "printer admin",
1416                 .type           = P_LIST,
1417                 .p_class        = P_LOCAL,
1418                 .ptr            = &sDefault.printer_admin,
1419                 .special        = NULL,
1420                 .enum_list      = NULL,
1421                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1422         },
1423         {
1424                 .label          = "force user",
1425                 .type           = P_STRING,
1426                 .p_class        = P_LOCAL,
1427                 .ptr            = &sDefault.force_user,
1428                 .special        = NULL,
1429                 .enum_list      = NULL,
1430                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1431         },
1432         {
1433                 .label          = "force group",
1434                 .type           = P_STRING,
1435                 .p_class        = P_LOCAL,
1436                 .ptr            = &sDefault.force_group,
1437                 .special        = NULL,
1438                 .enum_list      = NULL,
1439                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1440         },
1441         {
1442                 .label          = "group",
1443                 .type           = P_STRING,
1444                 .p_class        = P_LOCAL,
1445                 .ptr            = &sDefault.force_group,
1446                 .special        = NULL,
1447                 .enum_list      = NULL,
1448                 .flags          = FLAG_ADVANCED,
1449         },
1450         {
1451                 .label          = "read only",
1452                 .type           = P_BOOL,
1453                 .p_class        = P_LOCAL,
1454                 .ptr            = &sDefault.bRead_only,
1455                 .special        = NULL,
1456                 .enum_list      = NULL,
1457                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1458         },
1459         {
1460                 .label          = "write ok",
1461                 .type           = P_BOOLREV,
1462                 .p_class        = P_LOCAL,
1463                 .ptr            = &sDefault.bRead_only,
1464                 .special        = NULL,
1465                 .enum_list      = NULL,
1466                 .flags          = FLAG_HIDE,
1467         },
1468         {
1469                 .label          = "writeable",
1470                 .type           = P_BOOLREV,
1471                 .p_class        = P_LOCAL,
1472                 .ptr            = &sDefault.bRead_only,
1473                 .special        = NULL,
1474                 .enum_list      = NULL,
1475                 .flags          = FLAG_HIDE,
1476         },
1477         {
1478                 .label          = "writable",
1479                 .type           = P_BOOLREV,
1480                 .p_class        = P_LOCAL,
1481                 .ptr            = &sDefault.bRead_only,
1482                 .special        = NULL,
1483                 .enum_list      = NULL,
1484                 .flags          = FLAG_HIDE,
1485         },
1486         {
1487                 .label          = "acl check permissions",
1488                 .type           = P_BOOL,
1489                 .p_class        = P_LOCAL,
1490                 .ptr            = &sDefault.bAclCheckPermissions,
1491                 .special        = NULL,
1492                 .enum_list      = NULL,
1493                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1494         },
1495         {
1496                 .label          = "acl group control",
1497                 .type           = P_BOOL,
1498                 .p_class        = P_LOCAL,
1499                 .ptr            = &sDefault.bAclGroupControl,
1500                 .special        = NULL,
1501                 .enum_list      = NULL,
1502                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1503         },
1504         {
1505                 .label          = "acl map full control",
1506                 .type           = P_BOOL,
1507                 .p_class        = P_LOCAL,
1508                 .ptr            = &sDefault.bAclMapFullControl,
1509                 .special        = NULL,
1510                 .enum_list      = NULL,
1511                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1512         },
1513         {
1514                 .label          = "create mask",
1515                 .type           = P_OCTAL,
1516                 .p_class        = P_LOCAL,
1517                 .ptr            = &sDefault.iCreate_mask,
1518                 .special        = NULL,
1519                 .enum_list      = NULL,
1520                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1521         },
1522         {
1523                 .label          = "create mode",
1524                 .type           = P_OCTAL,
1525                 .p_class        = P_LOCAL,
1526                 .ptr            = &sDefault.iCreate_mask,
1527                 .special        = NULL,
1528                 .enum_list      = NULL,
1529                 .flags          = FLAG_HIDE,
1530         },
1531         {
1532                 .label          = "force create mode",
1533                 .type           = P_OCTAL,
1534                 .p_class        = P_LOCAL,
1535                 .ptr            = &sDefault.iCreate_force_mode,
1536                 .special        = NULL,
1537                 .enum_list      = NULL,
1538                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1539         },
1540         {
1541                 .label          = "security mask",
1542                 .type           = P_OCTAL,
1543                 .p_class        = P_LOCAL,
1544                 .ptr            = &sDefault.iSecurity_mask,
1545                 .special        = NULL,
1546                 .enum_list      = NULL,
1547                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1548         },
1549         {
1550                 .label          = "force security mode",
1551                 .type           = P_OCTAL,
1552                 .p_class        = P_LOCAL,
1553                 .ptr            = &sDefault.iSecurity_force_mode,
1554                 .special        = NULL,
1555                 .enum_list      = NULL,
1556                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1557         },
1558         {
1559                 .label          = "directory mask",
1560                 .type           = P_OCTAL,
1561                 .p_class        = P_LOCAL,
1562                 .ptr            = &sDefault.iDir_mask,
1563                 .special        = NULL,
1564                 .enum_list      = NULL,
1565                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1566         },
1567         {
1568                 .label          = "directory mode",
1569                 .type           = P_OCTAL,
1570                 .p_class        = P_LOCAL,
1571                 .ptr            = &sDefault.iDir_mask,
1572                 .special        = NULL,
1573                 .enum_list      = NULL,
1574                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
1575         },
1576         {
1577                 .label          = "force directory mode",
1578                 .type           = P_OCTAL,
1579                 .p_class        = P_LOCAL,
1580                 .ptr            = &sDefault.iDir_force_mode,
1581                 .special        = NULL,
1582                 .enum_list      = NULL,
1583                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1584         },
1585         {
1586                 .label          = "directory security mask",
1587                 .type           = P_OCTAL,
1588                 .p_class        = P_LOCAL,
1589                 .ptr            = &sDefault.iDir_Security_mask,
1590                 .special        = NULL,
1591                 .enum_list      = NULL,
1592                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1593         },
1594         {
1595                 .label          = "force directory security mode",
1596                 .type           = P_OCTAL,
1597                 .p_class        = P_LOCAL,
1598                 .ptr            = &sDefault.iDir_Security_force_mode,
1599                 .special        = NULL,
1600                 .enum_list      = NULL,
1601                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1602         },
1603         {
1604                 .label          = "force unknown acl user",
1605                 .type           = P_BOOL,
1606                 .p_class        = P_LOCAL,
1607                 .ptr            = &sDefault.bForceUnknownAclUser,
1608                 .special        = NULL,
1609                 .enum_list      = NULL,
1610                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1611         },
1612         {
1613                 .label          = "inherit permissions",
1614                 .type           = P_BOOL,
1615                 .p_class        = P_LOCAL,
1616                 .ptr            = &sDefault.bInheritPerms,
1617                 .special        = NULL,
1618                 .enum_list      = NULL,
1619                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1620         },
1621         {
1622                 .label          = "inherit acls",
1623                 .type           = P_BOOL,
1624                 .p_class        = P_LOCAL,
1625                 .ptr            = &sDefault.bInheritACLS,
1626                 .special        = NULL,
1627                 .enum_list      = NULL,
1628                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1629         },
1630         {
1631                 .label          = "inherit owner",
1632                 .type           = P_BOOL,
1633                 .p_class        = P_LOCAL,
1634                 .ptr            = &sDefault.bInheritOwner,
1635                 .special        = NULL,
1636                 .enum_list      = NULL,
1637                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1638         },
1639         {
1640                 .label          = "guest only",
1641                 .type           = P_BOOL,
1642                 .p_class        = P_LOCAL,
1643                 .ptr            = &sDefault.bGuest_only,
1644                 .special        = NULL,
1645                 .enum_list      = NULL,
1646                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1647         },
1648         {
1649                 .label          = "only guest",
1650                 .type           = P_BOOL,
1651                 .p_class        = P_LOCAL,
1652                 .ptr            = &sDefault.bGuest_only,
1653                 .special        = NULL,
1654                 .enum_list      = NULL,
1655                 .flags          = FLAG_HIDE,
1656         },
1657         {
1658                 .label          = "administrative share",
1659                 .type           = P_BOOL,
1660                 .p_class        = P_LOCAL,
1661                 .ptr            = &sDefault.bAdministrative_share,
1662                 .special        = NULL,
1663                 .enum_list      = NULL,
1664                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1665         },
1666
1667         {
1668                 .label          = "guest ok",
1669                 .type           = P_BOOL,
1670                 .p_class        = P_LOCAL,
1671                 .ptr            = &sDefault.bGuest_ok,
1672                 .special        = NULL,
1673                 .enum_list      = NULL,
1674                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1675         },
1676         {
1677                 .label          = "public",
1678                 .type           = P_BOOL,
1679                 .p_class        = P_LOCAL,
1680                 .ptr            = &sDefault.bGuest_ok,
1681                 .special        = NULL,
1682                 .enum_list      = NULL,
1683                 .flags          = FLAG_HIDE,
1684         },
1685         {
1686                 .label          = "only user",
1687                 .type           = P_BOOL,
1688                 .p_class        = P_LOCAL,
1689                 .ptr            = &sDefault.bOnlyUser,
1690                 .special        = NULL,
1691                 .enum_list      = NULL,
1692                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1693         },
1694         {
1695                 .label          = "hosts allow",
1696                 .type           = P_LIST,
1697                 .p_class        = P_LOCAL,
1698                 .ptr            = &sDefault.szHostsallow,
1699                 .special        = NULL,
1700                 .enum_list      = NULL,
1701                 .flags          = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1702         },
1703         {
1704                 .label          = "allow hosts",
1705                 .type           = P_LIST,
1706                 .p_class        = P_LOCAL,
1707                 .ptr            = &sDefault.szHostsallow,
1708                 .special        = NULL,
1709                 .enum_list      = NULL,
1710                 .flags          = FLAG_HIDE,
1711         },
1712         {
1713                 .label          = "hosts deny",
1714                 .type           = P_LIST,
1715                 .p_class        = P_LOCAL,
1716                 .ptr            = &sDefault.szHostsdeny,
1717                 .special        = NULL,
1718                 .enum_list      = NULL,
1719                 .flags          = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1720         },
1721         {
1722                 .label          = "deny hosts",
1723                 .type           = P_LIST,
1724                 .p_class        = P_LOCAL,
1725                 .ptr            = &sDefault.szHostsdeny,
1726                 .special        = NULL,
1727                 .enum_list      = NULL,
1728                 .flags          = FLAG_HIDE,
1729         },
1730         {
1731                 .label          = "preload modules",
1732                 .type           = P_LIST,
1733                 .p_class        = P_GLOBAL,
1734                 .ptr            = &Globals.szPreloadModules,
1735                 .special        = NULL,
1736                 .enum_list      = NULL,
1737                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
1738         },
1739         {
1740                 .label          = "use kerberos keytab",
1741                 .type           = P_BOOL,
1742                 .p_class        = P_GLOBAL,
1743                 .ptr            = &Globals.bUseKerberosKeytab,
1744                 .special        = NULL,
1745                 .enum_list      = NULL,
1746                 .flags          = FLAG_ADVANCED,
1747         },
1748
1749         {N_("Logging Options"), P_SEP, P_SEPARATOR},
1750
1751         {
1752                 .label          = "log level",
1753                 .type           = P_STRING,
1754                 .p_class        = P_GLOBAL,
1755                 .ptr            = &Globals.szLogLevel,
1756                 .special        = handle_debug_list,
1757                 .enum_list      = NULL,
1758                 .flags          = FLAG_ADVANCED,
1759         },
1760         {
1761                 .label          = "debuglevel",
1762                 .type           = P_STRING,
1763                 .p_class        = P_GLOBAL,
1764                 .ptr            = &Globals.szLogLevel,
1765                 .special        = handle_debug_list,
1766                 .enum_list      = NULL,
1767                 .flags          = FLAG_HIDE,
1768         },
1769         {
1770                 .label          = "syslog",
1771                 .type           = P_INTEGER,
1772                 .p_class        = P_GLOBAL,
1773                 .ptr            = &Globals.syslog,
1774                 .special        = NULL,
1775                 .enum_list      = NULL,
1776                 .flags          = FLAG_ADVANCED,
1777         },
1778         {
1779                 .label          = "syslog only",
1780                 .type           = P_BOOL,
1781                 .p_class        = P_GLOBAL,
1782                 .ptr            = &Globals.bSyslogOnly,
1783                 .special        = NULL,
1784                 .enum_list      = NULL,
1785                 .flags          = FLAG_ADVANCED,
1786         },
1787         {
1788                 .label          = "log file",
1789                 .type           = P_STRING,
1790                 .p_class        = P_GLOBAL,
1791                 .ptr            = &Globals.szLogFile,
1792                 .special        = NULL,
1793                 .enum_list      = NULL,
1794                 .flags          = FLAG_ADVANCED,
1795         },
1796         {
1797                 .label          = "max log size",
1798                 .type           = P_INTEGER,
1799                 .p_class        = P_GLOBAL,
1800                 .ptr            = &Globals.max_log_size,
1801                 .special        = NULL,
1802                 .enum_list      = NULL,
1803                 .flags          = FLAG_ADVANCED,
1804         },
1805         {
1806                 .label          = "debug timestamp",
1807                 .type           = P_BOOL,
1808                 .p_class        = P_GLOBAL,
1809                 .ptr            = &Globals.bTimestampLogs,
1810                 .special        = NULL,
1811                 .enum_list      = NULL,
1812                 .flags          = FLAG_ADVANCED,
1813         },
1814         {
1815                 .label          = "timestamp logs",
1816                 .type           = P_BOOL,
1817                 .p_class        = P_GLOBAL,
1818                 .ptr            = &Globals.bTimestampLogs,
1819                 .special        = NULL,
1820                 .enum_list      = NULL,
1821                 .flags          = FLAG_ADVANCED,
1822         },
1823         {
1824                 .label          = "debug prefix timestamp",
1825                 .type           = P_BOOL,
1826                 .p_class        = P_GLOBAL,
1827                 .ptr            = &Globals.bDebugPrefixTimestamp,
1828                 .special        = NULL,
1829                 .enum_list      = NULL,
1830                 .flags          = FLAG_ADVANCED,
1831         },
1832         {
1833                 .label          = "debug hires timestamp",
1834                 .type           = P_BOOL,
1835                 .p_class        = P_GLOBAL,
1836                 .ptr            = &Globals.bDebugHiresTimestamp,
1837                 .special        = NULL,
1838                 .enum_list      = NULL,
1839                 .flags          = FLAG_ADVANCED,
1840         },
1841         {
1842                 .label          = "debug pid",
1843                 .type           = P_BOOL,
1844                 .p_class        = P_GLOBAL,
1845                 .ptr            = &Globals.bDebugPid,
1846                 .special        = NULL,
1847                 .enum_list      = NULL,
1848                 .flags          = FLAG_ADVANCED,
1849         },
1850         {
1851                 .label          = "debug uid",
1852                 .type           = P_BOOL,
1853                 .p_class        = P_GLOBAL,
1854                 .ptr            = &Globals.bDebugUid,
1855                 .special        = NULL,
1856                 .enum_list      = NULL,
1857                 .flags          = FLAG_ADVANCED,
1858         },
1859         {
1860                 .label          = "debug class",
1861                 .type           = P_BOOL,
1862                 .p_class        = P_GLOBAL,
1863                 .ptr            = &Globals.bDebugClass,
1864                 .special        = NULL,
1865                 .enum_list      = NULL,
1866                 .flags          = FLAG_ADVANCED,
1867         },
1868         {
1869                 .label          = "enable core files",
1870                 .type           = P_BOOL,
1871                 .p_class        = P_GLOBAL,
1872                 .ptr            = &Globals.bEnableCoreFiles,
1873                 .special        = NULL,
1874                 .enum_list      = NULL,
1875                 .flags          = FLAG_ADVANCED,
1876         },
1877
1878         {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1879
1880         {
1881                 .label          = "allocation roundup size",
1882                 .type           = P_INTEGER,
1883                 .p_class        = P_LOCAL,
1884                 .ptr            = &sDefault.iallocation_roundup_size,
1885                 .special        = NULL,
1886                 .enum_list      = NULL,
1887                 .flags          = FLAG_ADVANCED,
1888         },
1889         {
1890                 .label          = "aio read size",
1891                 .type           = P_INTEGER,
1892                 .p_class        = P_LOCAL,
1893                 .ptr            = &sDefault.iAioReadSize,
1894                 .special        = NULL,
1895                 .enum_list      = NULL,
1896                 .flags          = FLAG_ADVANCED,
1897         },
1898         {
1899                 .label          = "aio write size",
1900                 .type           = P_INTEGER,
1901                 .p_class        = P_LOCAL,
1902                 .ptr            = &sDefault.iAioWriteSize,
1903                 .special        = NULL,
1904                 .enum_list      = NULL,
1905                 .flags          = FLAG_ADVANCED,
1906         },
1907         {
1908                 .label          = "aio write behind",
1909                 .type           = P_STRING,
1910                 .p_class        = P_LOCAL,
1911                 .ptr            = &sDefault.szAioWriteBehind,
1912                 .special        = NULL,
1913                 .enum_list      = NULL,
1914                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1915         },
1916         {
1917                 .label          = "smb ports",
1918                 .type           = P_STRING,
1919                 .p_class        = P_GLOBAL,
1920                 .ptr            = &Globals.smb_ports,
1921                 .special        = NULL,
1922                 .enum_list      = NULL,
1923                 .flags          = FLAG_ADVANCED,
1924         },
1925         {
1926                 .label          = "large readwrite",
1927                 .type           = P_BOOL,
1928                 .p_class        = P_GLOBAL,
1929                 .ptr            = &Globals.bLargeReadwrite,
1930                 .special        = NULL,
1931                 .enum_list      = NULL,
1932                 .flags          = FLAG_ADVANCED,
1933         },
1934         {
1935                 .label          = "max protocol",
1936                 .type           = P_ENUM,
1937                 .p_class        = P_GLOBAL,
1938                 .ptr            = &Globals.maxprotocol,
1939                 .special        = NULL,
1940                 .enum_list      = enum_protocol,
1941                 .flags          = FLAG_ADVANCED,
1942         },
1943         {
1944                 .label          = "protocol",
1945                 .type           = P_ENUM,
1946                 .p_class        = P_GLOBAL,
1947                 .ptr            = &Globals.maxprotocol,
1948                 .special        = NULL,
1949                 .enum_list      = enum_protocol,
1950                 .flags          = FLAG_ADVANCED,
1951         },
1952         {
1953                 .label          = "min protocol",
1954                 .type           = P_ENUM,
1955                 .p_class        = P_GLOBAL,
1956                 .ptr            = &Globals.minprotocol,
1957                 .special        = NULL,
1958                 .enum_list      = enum_protocol,
1959                 .flags          = FLAG_ADVANCED,
1960         },
1961         {
1962                 .label          = "min receivefile size",
1963                 .type           = P_INTEGER,
1964                 .p_class        = P_GLOBAL,
1965                 .ptr            = &Globals.iminreceivefile,
1966                 .special        = NULL,
1967                 .enum_list      = NULL,
1968                 .flags          = FLAG_ADVANCED,
1969         },
1970         {
1971                 .label          = "read raw",
1972                 .type           = P_BOOL,
1973                 .p_class        = P_GLOBAL,
1974                 .ptr            = &Globals.bReadRaw,
1975                 .special        = NULL,
1976                 .enum_list      = NULL,
1977                 .flags          = FLAG_ADVANCED,
1978         },
1979         {
1980                 .label          = "write raw",
1981                 .type           = P_BOOL,
1982                 .p_class        = P_GLOBAL,
1983                 .ptr            = &Globals.bWriteRaw,
1984                 .special        = NULL,
1985                 .enum_list      = NULL,
1986                 .flags          = FLAG_ADVANCED,
1987         },
1988         {
1989                 .label          = "disable netbios",
1990                 .type           = P_BOOL,
1991                 .p_class        = P_GLOBAL,
1992                 .ptr            = &Globals.bDisableNetbios,
1993                 .special        = NULL,
1994                 .enum_list      = NULL,
1995                 .flags          = FLAG_ADVANCED,
1996         },
1997         {
1998                 .label          = "reset on zero vc",
1999                 .type           = P_BOOL,
2000                 .p_class        = P_GLOBAL,
2001                 .ptr            = &Globals.bResetOnZeroVC,
2002                 .special        = NULL,
2003                 .enum_list      = NULL,
2004                 .flags          = FLAG_ADVANCED,
2005         },
2006         {
2007                 .label          = "acl compatibility",
2008                 .type           = P_ENUM,
2009                 .p_class        = P_GLOBAL,
2010                 .ptr            = &Globals.iAclCompat,
2011                 .special        = NULL,
2012                 .enum_list      = enum_acl_compat_vals,
2013                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2014         },
2015         {
2016                 .label          = "defer sharing violations",
2017                 .type           = P_BOOL,
2018                 .p_class        = P_GLOBAL,
2019                 .ptr            = &Globals.bDeferSharingViolations,
2020                 .special        = NULL,
2021                 .enum_list      = NULL,
2022                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2023         },
2024         {
2025                 .label          = "ea support",
2026                 .type           = P_BOOL,
2027                 .p_class        = P_LOCAL,
2028                 .ptr            = &sDefault.bEASupport,
2029                 .special        = NULL,
2030                 .enum_list      = NULL,
2031                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2032         },
2033         {
2034                 .label          = "nt acl support",
2035                 .type           = P_BOOL,
2036                 .p_class        = P_LOCAL,
2037                 .ptr            = &sDefault.bNTAclSupport,
2038                 .special        = NULL,
2039                 .enum_list      = NULL,
2040                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2041         },
2042         {
2043                 .label          = "nt pipe support",
2044                 .type           = P_BOOL,
2045                 .p_class        = P_GLOBAL,
2046                 .ptr            = &Globals.bNTPipeSupport,
2047                 .special        = NULL,
2048                 .enum_list      = NULL,
2049                 .flags          = FLAG_ADVANCED,
2050         },
2051         {
2052                 .label          = "nt status support",
2053                 .type           = P_BOOL,
2054                 .p_class        = P_GLOBAL,
2055                 .ptr            = &Globals.bNTStatusSupport,
2056                 .special        = NULL,
2057                 .enum_list      = NULL,
2058                 .flags          = FLAG_ADVANCED,
2059         },
2060         {
2061                 .label          = "profile acls",
2062                 .type           = P_BOOL,
2063                 .p_class        = P_LOCAL,
2064                 .ptr            = &sDefault.bProfileAcls,
2065                 .special        = NULL,
2066                 .enum_list      = NULL,
2067                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2068         },
2069         {
2070                 .label          = "announce version",
2071                 .type           = P_STRING,
2072                 .p_class        = P_GLOBAL,
2073                 .ptr            = &Globals.szAnnounceVersion,
2074                 .special        = NULL,
2075                 .enum_list      = NULL,
2076                 .flags          = FLAG_ADVANCED,
2077         },
2078         {
2079                 .label          = "announce as",
2080                 .type           = P_ENUM,
2081                 .p_class        = P_GLOBAL,
2082                 .ptr            = &Globals.announce_as,
2083                 .special        = NULL,
2084                 .enum_list      = enum_announce_as,
2085                 .flags          = FLAG_ADVANCED,
2086         },
2087         {
2088                 .label          = "map acl inherit",
2089                 .type           = P_BOOL,
2090                 .p_class        = P_LOCAL,
2091                 .ptr            = &sDefault.bMap_acl_inherit,
2092                 .special        = NULL,
2093                 .enum_list      = NULL,
2094                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2095         },
2096         {
2097                 .label          = "afs share",
2098                 .type           = P_BOOL,
2099                 .p_class        = P_LOCAL,
2100                 .ptr            = &sDefault.bAfs_Share,
2101                 .special        = NULL,
2102                 .enum_list      = NULL,
2103                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2104         },
2105         {
2106                 .label          = "max mux",
2107                 .type           = P_INTEGER,
2108                 .p_class        = P_GLOBAL,
2109                 .ptr            = &Globals.max_mux,
2110                 .special        = NULL,
2111                 .enum_list      = NULL,
2112                 .flags          = FLAG_ADVANCED,
2113         },
2114         {
2115                 .label          = "max xmit",
2116                 .type           = P_INTEGER,
2117                 .p_class        = P_GLOBAL,
2118                 .ptr            = &Globals.max_xmit,
2119                 .special        = NULL,
2120                 .enum_list      = NULL,
2121                 .flags          = FLAG_ADVANCED,
2122         },
2123         {
2124                 .label          = "name resolve order",
2125                 .type           = P_STRING,
2126                 .p_class        = P_GLOBAL,
2127                 .ptr            = &Globals.szNameResolveOrder,
2128                 .special        = NULL,
2129                 .enum_list      = NULL,
2130                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
2131         },
2132         {
2133                 .label          = "max ttl",
2134                 .type           = P_INTEGER,
2135                 .p_class        = P_GLOBAL,
2136                 .ptr            = &Globals.max_ttl,
2137                 .special        = NULL,
2138                 .enum_list      = NULL,
2139                 .flags          = FLAG_ADVANCED,
2140         },
2141         {
2142                 .label          = "max wins ttl",
2143                 .type           = P_INTEGER,
2144                 .p_class        = P_GLOBAL,
2145                 .ptr            = &Globals.max_wins_ttl,
2146                 .special        = NULL,
2147                 .enum_list      = NULL,
2148                 .flags          = FLAG_ADVANCED,
2149         },
2150         {
2151                 .label          = "min wins ttl",
2152                 .type           = P_INTEGER,
2153                 .p_class        = P_GLOBAL,
2154                 .ptr            = &Globals.min_wins_ttl,
2155                 .special        = NULL,
2156                 .enum_list      = NULL,
2157                 .flags          = FLAG_ADVANCED,
2158         },
2159         {
2160                 .label          = "time server",
2161                 .type           = P_BOOL,
2162                 .p_class        = P_GLOBAL,
2163                 .ptr            = &Globals.bTimeServer,
2164                 .special        = NULL,
2165                 .enum_list      = NULL,
2166                 .flags          = FLAG_ADVANCED,
2167         },
2168         {
2169                 .label          = "unix extensions",
2170                 .type           = P_BOOL,
2171                 .p_class        = P_GLOBAL,
2172                 .ptr            = &Globals.bUnixExtensions,
2173                 .special        = NULL,
2174                 .enum_list      = NULL,
2175                 .flags          = FLAG_ADVANCED,
2176         },
2177         {
2178                 .label          = "use spnego",
2179                 .type           = P_BOOL,
2180                 .p_class        = P_GLOBAL,
2181                 .ptr            = &Globals.bUseSpnego,
2182                 .special        = NULL,
2183                 .enum_list      = NULL,
2184                 .flags          = FLAG_ADVANCED,
2185         },
2186         {
2187                 .label          = "client signing",
2188                 .type           = P_ENUM,
2189                 .p_class        = P_GLOBAL,
2190                 .ptr            = &Globals.client_signing,
2191                 .special        = NULL,
2192                 .enum_list      = enum_smb_signing_vals,
2193                 .flags          = FLAG_ADVANCED,
2194         },
2195         {
2196                 .label          = "server signing",
2197                 .type           = P_ENUM,
2198                 .p_class        = P_GLOBAL,
2199                 .ptr            = &Globals.server_signing,
2200                 .special        = NULL,
2201                 .enum_list      = enum_smb_signing_vals,
2202                 .flags          = FLAG_ADVANCED,
2203         },
2204         {
2205                 .label          = "smb encrypt",
2206                 .type           = P_ENUM,
2207                 .p_class        = P_LOCAL,
2208                 .ptr            = &sDefault.ismb_encrypt,
2209                 .special        = NULL,
2210                 .enum_list      = enum_smb_signing_vals,
2211                 .flags          = FLAG_ADVANCED,
2212         },
2213         {
2214                 .label          = "client use spnego",
2215                 .type           = P_BOOL,
2216                 .p_class        = P_GLOBAL,
2217                 .ptr            = &Globals.bClientUseSpnego,
2218                 .special        = NULL,
2219                 .enum_list      = NULL,
2220                 .flags          = FLAG_ADVANCED,
2221         },
2222         {
2223                 .label          = "client ldap sasl wrapping",
2224                 .type           = P_ENUM,
2225                 .p_class        = P_GLOBAL,
2226                 .ptr            = &Globals.client_ldap_sasl_wrapping,
2227                 .special        = NULL,
2228                 .enum_list      = enum_ldap_sasl_wrapping,
2229                 .flags          = FLAG_ADVANCED,
2230         },
2231         {
2232                 .label          = "enable asu support",
2233                 .type           = P_BOOL,
2234                 .p_class        = P_GLOBAL,
2235                 .ptr            = &Globals.bASUSupport,
2236                 .special        = NULL,
2237                 .enum_list      = NULL,
2238                 .flags          = FLAG_ADVANCED,
2239         },
2240         {
2241                 .label          = "svcctl list",
2242                 .type           = P_LIST,
2243                 .p_class        = P_GLOBAL,
2244                 .ptr            = &Globals.szServicesList,
2245                 .special        = NULL,
2246                 .enum_list      = NULL,
2247                 .flags          = FLAG_ADVANCED,
2248         },
2249
2250         {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2251
2252         {
2253                 .label          = "block size",
2254                 .type           = P_INTEGER,
2255                 .p_class        = P_LOCAL,
2256                 .ptr            = &sDefault.iBlock_size,
2257                 .special        = NULL,
2258                 .enum_list      = NULL,
2259                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2260         },
2261         {
2262                 .label          = "deadtime",
2263                 .type           = P_INTEGER,
2264                 .p_class        = P_GLOBAL,
2265                 .ptr            = &Globals.deadtime,
2266                 .special        = NULL,
2267                 .enum_list      = NULL,
2268                 .flags          = FLAG_ADVANCED,
2269         },
2270         {
2271                 .label          = "getwd cache",
2272                 .type           = P_BOOL,
2273                 .p_class        = P_GLOBAL,
2274                 .ptr            = &Globals.getwd_cache,
2275                 .special        = NULL,
2276                 .enum_list      = NULL,
2277                 .flags          = FLAG_ADVANCED,
2278         },
2279         {
2280                 .label          = "keepalive",
2281                 .type           = P_INTEGER,
2282                 .p_class        = P_GLOBAL,
2283                 .ptr            = &Globals.iKeepalive,
2284                 .special        = NULL,
2285                 .enum_list      = NULL,
2286                 .flags          = FLAG_ADVANCED,
2287         },
2288         {
2289                 .label          = "change notify",
2290                 .type           = P_BOOL,
2291                 .p_class        = P_LOCAL,
2292                 .ptr            = &sDefault.bChangeNotify,
2293                 .special        = NULL,
2294                 .enum_list      = NULL,
2295                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2296         },
2297         {
2298                 .label          = "directory name cache size",
2299                 .type           = P_INTEGER,
2300                 .p_class        = P_LOCAL,
2301                 .ptr            = &sDefault.iDirectoryNameCacheSize,
2302                 .special        = NULL,
2303                 .enum_list      = NULL,
2304                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2305         },
2306         {
2307                 .label          = "kernel change notify",
2308                 .type           = P_BOOL,
2309                 .p_class        = P_LOCAL,
2310                 .ptr            = &sDefault.bKernelChangeNotify,
2311                 .special        = NULL,
2312                 .enum_list      = NULL,
2313                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2314         },
2315         {
2316                 .label          = "lpq cache time",
2317                 .type           = P_INTEGER,
2318                 .p_class        = P_GLOBAL,
2319                 .ptr            = &Globals.lpqcachetime,
2320                 .special        = NULL,
2321                 .enum_list      = NULL,
2322                 .flags          = FLAG_ADVANCED,
2323         },
2324         {
2325                 .label          = "max smbd processes",
2326                 .type           = P_INTEGER,
2327                 .p_class        = P_GLOBAL,
2328                 .ptr            = &Globals.iMaxSmbdProcesses,
2329                 .special        = NULL,
2330                 .enum_list      = NULL,
2331                 .flags          = FLAG_ADVANCED,
2332         },
2333         {
2334                 .label          = "max connections",
2335                 .type           = P_INTEGER,
2336                 .p_class        = P_LOCAL,
2337                 .ptr            = &sDefault.iMaxConnections,
2338                 .special        = NULL,
2339                 .enum_list      = NULL,
2340                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2341         },
2342         {
2343                 .label          = "paranoid server security",
2344                 .type           = P_BOOL,
2345                 .p_class        = P_GLOBAL,
2346                 .ptr            = &Globals.paranoid_server_security,
2347                 .special        = NULL,
2348                 .enum_list      = NULL,
2349                 .flags          = FLAG_ADVANCED,
2350         },
2351         {
2352                 .label          = "max disk size",
2353                 .type           = P_INTEGER,
2354                 .p_class        = P_GLOBAL,
2355                 .ptr            = &Globals.maxdisksize,
2356                 .special        = NULL,
2357                 .enum_list      = NULL,
2358                 .flags          = FLAG_ADVANCED,
2359         },
2360         {
2361                 .label          = "max open files",
2362                 .type           = P_INTEGER,
2363                 .p_class        = P_GLOBAL,
2364                 .ptr            = &Globals.max_open_files,
2365                 .special        = NULL,
2366                 .enum_list      = NULL,
2367                 .flags          = FLAG_ADVANCED,
2368         },
2369         {
2370                 .label          = "min print space",
2371                 .type           = P_INTEGER,
2372                 .p_class        = P_LOCAL,
2373                 .ptr            = &sDefault.iMinPrintSpace,
2374                 .special        = NULL,
2375                 .enum_list      = NULL,
2376                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2377         },
2378         {
2379                 .label          = "socket options",
2380                 .type           = P_STRING,
2381                 .p_class        = P_GLOBAL,
2382                 .ptr            = &Globals.szSocketOptions,
2383                 .special        = NULL,
2384                 .enum_list      = NULL,
2385                 .flags          = FLAG_ADVANCED,
2386         },
2387         {
2388                 .label          = "strict allocate",
2389                 .type           = P_BOOL,
2390                 .p_class        = P_LOCAL,
2391                 .ptr            = &sDefault.bStrictAllocate,
2392                 .special        = NULL,
2393                 .enum_list      = NULL,
2394                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2395         },
2396         {
2397                 .label          = "strict sync",
2398                 .type           = P_BOOL,
2399                 .p_class        = P_LOCAL,
2400                 .ptr            = &sDefault.bStrictSync,
2401                 .special        = NULL,
2402                 .enum_list      = NULL,
2403                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2404         },
2405         {
2406                 .label          = "sync always",
2407                 .type           = P_BOOL,
2408                 .p_class        = P_LOCAL,
2409                 .ptr            = &sDefault.bSyncAlways,
2410                 .special        = NULL,
2411                 .enum_list      = NULL,
2412                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2413         },
2414         {
2415                 .label          = "use mmap",
2416                 .type           = P_BOOL,
2417                 .p_class        = P_GLOBAL,
2418                 .ptr            = &Globals.bUseMmap,
2419                 .special        = NULL,
2420                 .enum_list      = NULL,
2421                 .flags          = FLAG_ADVANCED,
2422         },
2423         {
2424                 .label          = "use sendfile",
2425                 .type           = P_BOOL,
2426                 .p_class        = P_LOCAL,
2427                 .ptr            = &sDefault.bUseSendfile,
2428                 .special        = NULL,
2429                 .enum_list      = NULL,
2430                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2431         },
2432         {
2433                 .label          = "hostname lookups",
2434                 .type           = P_BOOL,
2435                 .p_class        = P_GLOBAL,
2436                 .ptr            = &Globals.bHostnameLookups,
2437                 .special        = NULL,
2438                 .enum_list      = NULL,
2439                 .flags          = FLAG_ADVANCED,
2440         },
2441         {
2442                 .label          = "write cache size",
2443                 .type           = P_INTEGER,
2444                 .p_class        = P_LOCAL,
2445                 .ptr            = &sDefault.iWriteCacheSize,
2446                 .special        = NULL,
2447                 .enum_list      = NULL,
2448                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2449         },
2450         {
2451                 .label          = "name cache timeout",
2452                 .type           = P_INTEGER,
2453                 .p_class        = P_GLOBAL,
2454                 .ptr            = &Globals.name_cache_timeout,
2455                 .special        = NULL,
2456                 .enum_list      = NULL,
2457                 .flags          = FLAG_ADVANCED,
2458         },
2459         {
2460                 .label          = "ctdbd socket",
2461                 .type           = P_STRING,
2462                 .p_class        = P_GLOBAL,
2463                 .ptr            = &Globals.ctdbdSocket,
2464                 .special        = NULL,
2465                 .enum_list      = NULL,
2466                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2467         },
2468         {
2469                 .label          = "cluster addresses",
2470                 .type           = P_LIST,
2471                 .p_class        = P_GLOBAL,
2472                 .ptr            = &Globals.szClusterAddresses,
2473                 .special        = NULL,
2474                 .enum_list      = NULL,
2475                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2476         },
2477         {
2478                 .label          = "clustering",
2479                 .type           = P_BOOL,
2480                 .p_class        = P_GLOBAL,
2481                 .ptr            = &Globals.clustering,
2482                 .special        = NULL,
2483                 .enum_list      = NULL,
2484                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2485         },
2486
2487         {N_("Printing Options"), P_SEP, P_SEPARATOR},
2488
2489         {
2490                 .label          = "max reported print jobs",
2491                 .type           = P_INTEGER,
2492                 .p_class        = P_LOCAL,
2493                 .ptr            = &sDefault.iMaxReportedPrintJobs,
2494                 .special        = NULL,
2495                 .enum_list      = NULL,
2496                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2497         },
2498         {
2499                 .label          = "max print jobs",
2500                 .type           = P_INTEGER,
2501                 .p_class        = P_LOCAL,
2502                 .ptr            = &sDefault.iMaxPrintJobs,
2503                 .special        = NULL,
2504                 .enum_list      = NULL,
2505                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2506         },
2507         {
2508                 .label          = "load printers",
2509                 .type           = P_BOOL,
2510                 .p_class        = P_GLOBAL,
2511                 .ptr            = &Globals.bLoadPrinters,
2512                 .special        = NULL,
2513                 .enum_list      = NULL,
2514                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2515         },
2516         {
2517                 .label          = "printcap cache time",
2518                 .type           = P_INTEGER,
2519                 .p_class        = P_GLOBAL,
2520                 .ptr            = &Globals.PrintcapCacheTime,
2521                 .special        = NULL,
2522                 .enum_list      = NULL,
2523                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2524         },
2525         {
2526                 .label          = "printcap name",
2527                 .type           = P_STRING,
2528                 .p_class        = P_GLOBAL,
2529                 .ptr            = &Globals.szPrintcapname,
2530                 .special        = NULL,
2531                 .enum_list      = NULL,
2532                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2533         },
2534         {
2535                 .label          = "printcap",
2536                 .type           = P_STRING,
2537                 .p_class        = P_GLOBAL,
2538                 .ptr            = &Globals.szPrintcapname,
2539                 .special        = NULL,
2540                 .enum_list      = NULL,
2541                 .flags          = FLAG_HIDE,
2542         },
2543         {
2544                 .label          = "printable",
2545                 .type           = P_BOOL,
2546                 .p_class        = P_LOCAL,
2547                 .ptr            = &sDefault.bPrint_ok,
2548                 .special        = NULL,
2549                 .enum_list      = NULL,
2550                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2551         },
2552         {
2553                 .label          = "print ok",
2554                 .type           = P_BOOL,
2555                 .p_class        = P_LOCAL,
2556                 .ptr            = &sDefault.bPrint_ok,
2557                 .special        = NULL,
2558                 .enum_list      = NULL,
2559                 .flags          = FLAG_HIDE,
2560         },
2561         {
2562                 .label          = "printing",
2563                 .type           = P_ENUM,
2564                 .p_class        = P_LOCAL,
2565                 .ptr            = &sDefault.iPrinting,
2566                 .special        = handle_printing,
2567                 .enum_list      = enum_printing,
2568                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2569         },
2570         {
2571                 .label          = "cups options",
2572                 .type           = P_STRING,
2573                 .p_class        = P_LOCAL,
2574                 .ptr            = &sDefault.szCupsOptions,
2575                 .special        = NULL,
2576                 .enum_list      = NULL,
2577                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2578         },
2579         {
2580                 .label          = "cups server",
2581                 .type           = P_STRING,
2582                 .p_class        = P_GLOBAL,
2583                 .ptr            = &Globals.szCupsServer,
2584                 .special        = NULL,
2585                 .enum_list      = NULL,
2586                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2587         },
2588         {
2589                 .label          = "iprint server",
2590                 .type           = P_STRING,
2591                 .p_class        = P_GLOBAL,
2592                 .ptr            = &Globals.szIPrintServer,
2593                 .special        = NULL,
2594                 .enum_list      = NULL,
2595                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2596         },
2597         {
2598                 .label          = "print command",
2599                 .type           = P_STRING,
2600                 .p_class        = P_LOCAL,
2601                 .ptr            = &sDefault.szPrintcommand,
2602                 .special        = NULL,
2603                 .enum_list      = NULL,
2604                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2605         },
2606         {
2607                 .label          = "disable spoolss",
2608                 .type           = P_BOOL,
2609                 .p_class        = P_GLOBAL,
2610                 .ptr            = &Globals.bDisableSpoolss,
2611                 .special        = NULL,
2612                 .enum_list      = NULL,
2613                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2614         },
2615         {
2616                 .label          = "enable spoolss",
2617                 .type           = P_BOOLREV,
2618                 .p_class        = P_GLOBAL,
2619                 .ptr            = &Globals.bDisableSpoolss,
2620                 .special        = NULL,
2621                 .enum_list      = NULL,
2622                 .flags          = FLAG_HIDE,
2623         },
2624         {
2625                 .label          = "lpq command",
2626                 .type           = P_STRING,
2627                 .p_class        = P_LOCAL,
2628                 .ptr            = &sDefault.szLpqcommand,
2629                 .special        = NULL,
2630                 .enum_list      = NULL,
2631                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2632         },
2633         {
2634                 .label          = "lprm command",
2635                 .type           = P_STRING,
2636                 .p_class        = P_LOCAL,
2637                 .ptr            = &sDefault.szLprmcommand,
2638                 .special        = NULL,
2639                 .enum_list      = NULL,
2640                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2641         },
2642         {
2643                 .label          = "lppause command",
2644                 .type           = P_STRING,
2645                 .p_class        = P_LOCAL,
2646                 .ptr            = &sDefault.szLppausecommand,
2647                 .special        = NULL,
2648                 .enum_list      = NULL,
2649                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2650         },
2651         {
2652                 .label          = "lpresume command",
2653                 .type           = P_STRING,
2654                 .p_class        = P_LOCAL,
2655                 .ptr            = &sDefault.szLpresumecommand,
2656                 .special        = NULL,
2657                 .enum_list      = NULL,
2658                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2659         },
2660         {
2661                 .label          = "queuepause command",
2662                 .type           = P_STRING,
2663                 .p_class        = P_LOCAL,
2664                 .ptr            = &sDefault.szQueuepausecommand,
2665                 .special        = NULL,
2666                 .enum_list      = NULL,
2667                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2668         },
2669         {
2670                 .label          = "queueresume command",
2671                 .type           = P_STRING,
2672                 .p_class        = P_LOCAL,
2673                 .ptr            = &sDefault.szQueueresumecommand,
2674                 .special        = NULL,
2675                 .enum_list      = NULL,
2676                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2677         },
2678         {
2679                 .label          = "addport command",
2680                 .type           = P_STRING,
2681                 .p_class        = P_GLOBAL,
2682                 .ptr            = &Globals.szAddPortCommand,
2683                 .special        = NULL,
2684                 .enum_list      = NULL,
2685                 .flags          = FLAG_ADVANCED,
2686         },
2687         {
2688                 .label          = "enumports command",
2689                 .type           = P_STRING,
2690                 .p_class        = P_GLOBAL,
2691                 .ptr            = &Globals.szEnumPortsCommand,
2692                 .special        = NULL,
2693                 .enum_list      = NULL,
2694                 .flags          = FLAG_ADVANCED,
2695         },
2696         {
2697                 .label          = "addprinter command",
2698                 .type           = P_STRING,
2699                 .p_class        = P_GLOBAL,
2700                 .ptr            = &Globals.szAddPrinterCommand,
2701                 .special        = NULL,
2702                 .enum_list      = NULL,
2703                 .flags          = FLAG_ADVANCED,
2704         },
2705         {
2706                 .label          = "deleteprinter command",
2707                 .type           = P_STRING,
2708                 .p_class        = P_GLOBAL,
2709                 .ptr            = &Globals.szDeletePrinterCommand,
2710                 .special        = NULL,
2711                 .enum_list      = NULL,
2712                 .flags          = FLAG_ADVANCED,
2713         },
2714         {
2715                 .label          = "show add printer wizard",
2716                 .type           = P_BOOL,
2717                 .p_class        = P_GLOBAL,
2718                 .ptr            = &Globals.bMsAddPrinterWizard,
2719                 .special        = NULL,
2720                 .enum_list      = NULL,
2721                 .flags          = FLAG_ADVANCED,
2722         },
2723         {
2724                 .label          = "os2 driver map",
2725                 .type           = P_STRING,
2726                 .p_class        = P_GLOBAL,
2727                 .ptr            = &Globals.szOs2DriverMap,
2728                 .special        = NULL,
2729                 .enum_list      = NULL,
2730                 .flags          = FLAG_ADVANCED,
2731         },
2732
2733         {
2734                 .label          = "printer name",
2735                 .type           = P_STRING,
2736                 .p_class        = P_LOCAL,
2737                 .ptr            = &sDefault.szPrintername,
2738                 .special        = NULL,
2739                 .enum_list      = NULL,
2740                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2741         },
2742         {
2743                 .label          = "printer",
2744                 .type           = P_STRING,
2745                 .p_class        = P_LOCAL,
2746                 .ptr            = &sDefault.szPrintername,
2747                 .special        = NULL,
2748                 .enum_list      = NULL,
2749                 .flags          = FLAG_HIDE,
2750         },
2751         {
2752                 .label          = "use client driver",
2753                 .type           = P_BOOL,
2754                 .p_class        = P_LOCAL,
2755                 .ptr            = &sDefault.bUseClientDriver,
2756                 .special        = NULL,
2757                 .enum_list      = NULL,
2758                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2759         },
2760         {
2761                 .label          = "default devmode",
2762                 .type           = P_BOOL,
2763                 .p_class        = P_LOCAL,
2764                 .ptr            = &sDefault.bDefaultDevmode,
2765                 .special        = NULL,
2766                 .enum_list      = NULL,
2767                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2768         },
2769         {
2770                 .label          = "force printername",
2771                 .type           = P_BOOL,
2772                 .p_class        = P_LOCAL,
2773                 .ptr            = &sDefault.bForcePrintername,
2774                 .special        = NULL,
2775                 .enum_list      = NULL,
2776                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2777         },
2778         {
2779                 .label          = "printjob username",
2780                 .type           = P_STRING,
2781                 .p_class        = P_LOCAL,
2782                 .ptr            = &sDefault.szPrintjobUsername,
2783                 .special        = NULL,
2784                 .enum_list      = NULL,
2785                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2786         },
2787
2788         {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2789
2790         {
2791                 .label          = "mangling method",
2792                 .type           = P_STRING,
2793                 .p_class        = P_GLOBAL,
2794                 .ptr            = &Globals.szManglingMethod,
2795                 .special        = NULL,
2796                 .enum_list      = NULL,
2797                 .flags          = FLAG_ADVANCED,
2798         },
2799         {
2800                 .label          = "mangle prefix",
2801                 .type           = P_INTEGER,
2802                 .p_class        = P_GLOBAL,
2803                 .ptr            = &Globals.mangle_prefix,
2804                 .special        = NULL,
2805                 .enum_list      = NULL,
2806                 .flags          = FLAG_ADVANCED,
2807         },
2808
2809         {
2810                 .label          = "default case",
2811                 .type           = P_ENUM,
2812                 .p_class        = P_LOCAL,
2813                 .ptr            = &sDefault.iDefaultCase,
2814                 .special        = NULL,
2815                 .enum_list      = enum_case,
2816                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2817         },
2818         {
2819                 .label          = "case sensitive",
2820                 .type           = P_ENUM,
2821                 .p_class        = P_LOCAL,
2822                 .ptr            = &sDefault.iCaseSensitive,
2823                 .special        = NULL,
2824                 .enum_list      = enum_bool_auto,
2825                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2826         },
2827         {
2828                 .label          = "casesignames",
2829                 .type           = P_ENUM,
2830                 .p_class        = P_LOCAL,
2831                 .ptr            = &sDefault.iCaseSensitive,
2832                 .special        = NULL,
2833                 .enum_list      = enum_bool_auto,
2834                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2835         },
2836         {
2837                 .label          = "preserve case",
2838                 .type           = P_BOOL,
2839                 .p_class        = P_LOCAL,
2840                 .ptr            = &sDefault.bCasePreserve,
2841                 .special        = NULL,
2842                 .enum_list      = NULL,
2843                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2844         },
2845         {
2846                 .label          = "short preserve case",
2847                 .type           = P_BOOL,
2848                 .p_class        = P_LOCAL,
2849                 .ptr            = &sDefault.bShortCasePreserve,
2850                 .special        = NULL,
2851                 .enum_list      = NULL,
2852                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2853         },
2854         {
2855                 .label          = "mangling char",
2856                 .type           = P_CHAR,
2857                 .p_class        = P_LOCAL,
2858                 .ptr            = &sDefault.magic_char,
2859                 .special        = NULL,
2860                 .enum_list      = NULL,
2861                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2862         },
2863         {
2864                 .label          = "hide dot files",
2865                 .type           = P_BOOL,
2866                 .p_class        = P_LOCAL,
2867                 .ptr            = &sDefault.bHideDotFiles,
2868                 .special        = NULL,
2869                 .enum_list      = NULL,
2870                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2871         },
2872         {
2873                 .label          = "hide special files",
2874                 .type           = P_BOOL,
2875                 .p_class        = P_LOCAL,
2876                 .ptr            = &sDefault.bHideSpecialFiles,
2877                 .special        = NULL,
2878                 .enum_list      = NULL,
2879                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2880         },
2881         {
2882                 .label          = "hide unreadable",
2883                 .type           = P_BOOL,
2884                 .p_class        = P_LOCAL,
2885                 .ptr            = &sDefault.bHideUnReadable,
2886                 .special        = NULL,
2887                 .enum_list      = NULL,
2888                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2889         },
2890         {
2891                 .label          = "hide unwriteable files",
2892                 .type           = P_BOOL,
2893                 .p_class        = P_LOCAL,
2894                 .ptr            = &sDefault.bHideUnWriteableFiles,
2895                 .special        = NULL,
2896                 .enum_list      = NULL,
2897                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2898         },
2899         {
2900                 .label          = "delete veto files",
2901                 .type           = P_BOOL,
2902                 .p_class        = P_LOCAL,
2903                 .ptr            = &sDefault.bDeleteVetoFiles,
2904                 .special        = NULL,
2905                 .enum_list      = NULL,
2906                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2907         },
2908         {
2909                 .label          = "veto files",
2910                 .type           = P_STRING,
2911                 .p_class        = P_LOCAL,
2912                 .ptr            = &sDefault.szVetoFiles,
2913                 .special        = NULL,
2914                 .enum_list      = NULL,
2915                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2916         },
2917         {
2918                 .label          = "hide files",
2919                 .type           = P_STRING,
2920                 .p_class        = P_LOCAL,
2921                 .ptr            = &sDefault.szHideFiles,
2922                 .special        = NULL,
2923                 .enum_list      = NULL,
2924                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2925         },
2926         {
2927                 .label          = "veto oplock files",
2928                 .type           = P_STRING,
2929                 .p_class        = P_LOCAL,
2930                 .ptr            = &sDefault.szVetoOplockFiles,
2931                 .special        = NULL,
2932                 .enum_list      = NULL,
2933                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2934         },
2935         {
2936                 .label          = "map archive",
2937                 .type           = P_BOOL,
2938                 .p_class        = P_LOCAL,
2939                 .ptr            = &sDefault.bMap_archive,
2940                 .special        = NULL,
2941                 .enum_list      = NULL,
2942                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2943         },
2944         {
2945                 .label          = "map hidden",
2946                 .type           = P_BOOL,
2947                 .p_class        = P_LOCAL,
2948                 .ptr            = &sDefault.bMap_hidden,
2949                 .special        = NULL,
2950                 .enum_list      = NULL,
2951                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2952         },
2953         {
2954                 .label          = "map system",
2955                 .type           = P_BOOL,
2956                 .p_class        = P_LOCAL,
2957                 .ptr            = &sDefault.bMap_system,
2958                 .special        = NULL,
2959                 .enum_list      = NULL,
2960                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2961         },
2962         {
2963                 .label          = "map readonly",
2964                 .type           = P_ENUM,
2965                 .p_class        = P_LOCAL,
2966                 .ptr            = &sDefault.iMap_readonly,
2967                 .special        = NULL,
2968                 .enum_list      = enum_map_readonly,
2969                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2970         },
2971         {
2972                 .label          = "mangled names",
2973                 .type           = P_BOOL,
2974                 .p_class        = P_LOCAL,
2975                 .ptr            = &sDefault.bMangledNames,
2976                 .special        = NULL,
2977                 .enum_list      = NULL,
2978                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2979         },
2980         {
2981                 .label          = "max stat cache size",
2982                 .type           = P_INTEGER,
2983                 .p_class        = P_GLOBAL,
2984                 .ptr            = &Globals.iMaxStatCacheSize,
2985                 .special        = NULL,
2986                 .enum_list      = NULL,
2987                 .flags          = FLAG_ADVANCED,
2988         },
2989         {
2990                 .label          = "stat cache",
2991                 .type           = P_BOOL,
2992                 .p_class        = P_GLOBAL,
2993                 .ptr            = &Globals.bStatCache,
2994                 .special        = NULL,
2995                 .enum_list      = NULL,
2996                 .flags          = FLAG_ADVANCED,
2997         },
2998         {
2999                 .label          = "store dos attributes",
3000                 .type           = P_BOOL,
3001                 .p_class        = P_LOCAL,
3002                 .ptr            = &sDefault.bStoreDosAttributes,
3003                 .special        = NULL,
3004                 .enum_list      = NULL,
3005                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3006         },
3007         {
3008                 .label          = "dmapi support",
3009                 .type           = P_BOOL,
3010                 .p_class        = P_LOCAL,
3011                 .ptr            = &sDefault.bDmapiSupport,
3012                 .special        = NULL,
3013                 .enum_list      = NULL,
3014                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3015         },
3016
3017
3018         {N_("Domain Options"), P_SEP, P_SEPARATOR},
3019
3020         {
3021                 .label          = "machine password timeout",
3022                 .type           = P_INTEGER,
3023                 .p_class        = P_GLOBAL,
3024                 .ptr            = &Globals.machine_password_timeout,
3025                 .special        = NULL,
3026                 .enum_list      = NULL,
3027                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
3028         },
3029
3030         {N_("Logon Options"), P_SEP, P_SEPARATOR},
3031
3032         {
3033                 .label          = "add user script",
3034                 .type           = P_STRING,
3035                 .p_class        = P_GLOBAL,
3036                 .ptr            = &Globals.szAddUserScript,
3037                 .special        = NULL,
3038                 .enum_list      = NULL,
3039                 .flags          = FLAG_ADVANCED,
3040         },
3041         {
3042                 .label          = "rename user script",
3043                 .type           = P_STRING,
3044                 .p_class        = P_GLOBAL,
3045                 .ptr            = &Globals.szRenameUserScript,
3046                 .special        = NULL,
3047                 .enum_list      = NULL,
3048                 .flags          = FLAG_ADVANCED,
3049         },
3050         {
3051                 .label          = "delete user script",
3052                 .type           = P_STRING,
3053                 .p_class        = P_GLOBAL,
3054                 .ptr            = &Globals.szDelUserScript,
3055                 .special        = NULL,
3056                 .enum_list      = NULL,
3057                 .flags          = FLAG_ADVANCED,
3058         },
3059         {
3060                 .label          = "add group script",
3061                 .type           = P_STRING,
3062                 .p_class        = P_GLOBAL,
3063                 .ptr            = &Globals.szAddGroupScript,
3064                 .special        = NULL,
3065                 .enum_list      = NULL,
3066                 .flags          = FLAG_ADVANCED,
3067         },
3068         {
3069                 .label          = "delete group script",
3070                 .type           = P_STRING,
3071                 .p_class        = P_GLOBAL,
3072                 .ptr            = &Globals.szDelGroupScript,
3073                 .special        = NULL,
3074                 .enum_list      = NULL,
3075                 .flags          = FLAG_ADVANCED,
3076         },
3077         {
3078                 .label          = "add user to group script",
3079                 .type           = P_STRING,
3080                 .p_class        = P_GLOBAL,
3081                 .ptr            = &Globals.szAddUserToGroupScript,
3082                 .special        = NULL,
3083                 .enum_list      = NULL,
3084                 .flags          = FLAG_ADVANCED,
3085         },
3086         {
3087                 .label          = "delete user from group script",
3088                 .type           = P_STRING,
3089                 .p_class        = P_GLOBAL,
3090                 .ptr            = &Globals.szDelUserFromGroupScript,
3091                 .special        = NULL,
3092                 .enum_list      = NULL,
3093                 .flags          = FLAG_ADVANCED,
3094         },
3095         {
3096                 .label          = "set primary group script",
3097                 .type           = P_STRING,
3098                 .p_class        = P_GLOBAL,
3099                 .ptr            = &Globals.szSetPrimaryGroupScript,
3100                 .special        = NULL,
3101                 .enum_list      = NULL,
3102                 .flags          = FLAG_ADVANCED,
3103         },
3104         {
3105                 .label          = "add machine script",
3106                 .type           = P_STRING,
3107                 .p_class        = P_GLOBAL,
3108                 .ptr            = &Globals.szAddMachineScript,
3109                 .special        = NULL,
3110                 .enum_list      = NULL,
3111                 .flags          = FLAG_ADVANCED,
3112         },
3113         {
3114                 .label          = "shutdown script",
3115                 .type           = P_STRING,
3116                 .p_class        = P_GLOBAL,
3117                 .ptr            = &Globals.szShutdownScript,
3118                 .special        = NULL,
3119                 .enum_list      = NULL,
3120                 .flags          = FLAG_ADVANCED,
3121         },
3122         {
3123                 .label          = "abort shutdown script",
3124                 .type           = P_STRING,
3125                 .p_class        = P_GLOBAL,
3126                 .ptr            = &Globals.szAbortShutdownScript,
3127                 .special        = NULL,
3128                 .enum_list      = NULL,
3129                 .flags          = FLAG_ADVANCED,
3130         },
3131         {
3132                 .label          = "username map script",
3133                 .type           = P_STRING,
3134                 .p_class        = P_GLOBAL,
3135                 .ptr            = &Globals.szUsernameMapScript,
3136                 .special        = NULL,
3137                 .enum_list      = NULL,
3138                 .flags          = FLAG_ADVANCED,
3139         },
3140         {
3141                 .label          = "logon script",
3142                 .type           = P_STRING,
3143                 .p_class        = P_GLOBAL,
3144                 .ptr            = &Globals.szLogonScript,
3145                 .special        = NULL,
3146                 .enum_list      = NULL,
3147                 .flags          = FLAG_ADVANCED,
3148         },
3149         {
3150                 .label          = "logon path",
3151                 .type           = P_STRING,
3152                 .p_class        = P_GLOBAL,
3153                 .ptr            = &Globals.szLogonPath,
3154                 .special        = NULL,
3155                 .enum_list      = NULL,
3156                 .flags          = FLAG_ADVANCED,
3157         },
3158         {
3159                 .label          = "logon drive",
3160                 .type           = P_STRING,
3161                 .p_class        = P_GLOBAL,
3162                 .ptr            = &Globals.szLogonDrive,
3163                 .special        = NULL,
3164                 .enum_list      = NULL,
3165                 .flags          = FLAG_ADVANCED,
3166         },
3167         {
3168                 .label          = "logon home",
3169                 .type           = P_STRING,
3170                 .p_class        = P_GLOBAL,
3171                 .ptr            = &Globals.szLogonHome,
3172                 .special        = NULL,
3173                 .enum_list      = NULL,
3174                 .flags          = FLAG_ADVANCED,
3175         },
3176         {
3177                 .label          = "domain logons",
3178                 .type           = P_BOOL,
3179                 .p_class        = P_GLOBAL,
3180                 .ptr            = &Globals.bDomainLogons,
3181                 .special        = NULL,
3182                 .enum_list      = NULL,
3183                 .flags          = FLAG_ADVANCED,
3184         },
3185
3186         {N_("Browse Options"), P_SEP, P_SEPARATOR},
3187
3188         {
3189                 .label          = "os level",
3190                 .type           = P_INTEGER,
3191                 .p_class        = P_GLOBAL,
3192                 .ptr            = &Globals.os_level,
3193                 .special        = NULL,
3194                 .enum_list      = NULL,
3195                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3196         },
3197         {
3198                 .label          = "lm announce",
3199                 .type           = P_ENUM,
3200                 .p_class        = P_GLOBAL,
3201                 .ptr            = &Globals.lm_announce,
3202                 .special        = NULL,
3203                 .enum_list      = enum_bool_auto,
3204                 .flags          = FLAG_ADVANCED,
3205         },
3206         {
3207                 .label          = "lm interval",
3208                 .type           = P_INTEGER,
3209                 .p_class        = P_GLOBAL,
3210                 .ptr            = &Globals.lm_interval,
3211                 .special        = NULL,
3212                 .enum_list      = NULL,
3213                 .flags          = FLAG_ADVANCED,
3214         },
3215         {
3216                 .label          = "preferred master",
3217                 .type           = P_ENUM,
3218                 .p_class        = P_GLOBAL,
3219                 .ptr            = &Globals.iPreferredMaster,
3220                 .special        = NULL,
3221                 .enum_list      = enum_bool_auto,
3222                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3223         },
3224         {
3225                 .label          = "prefered master",
3226                 .type           = P_ENUM,
3227                 .p_class        = P_GLOBAL,
3228                 .ptr            = &Globals.iPreferredMaster,
3229                 .special        = NULL,
3230                 .enum_list      = enum_bool_auto,
3231                 .flags          = FLAG_HIDE,
3232         },
3233         {
3234                 .label          = "local master",
3235                 .type           = P_BOOL,
3236                 .p_class        = P_GLOBAL,
3237                 .ptr            = &Globals.bLocalMaster,
3238                 .special        = NULL,
3239                 .enum_list      = NULL,
3240                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3241         },
3242         {
3243                 .label          = "domain master",
3244                 .type           = P_ENUM,
3245                 .p_class        = P_GLOBAL,
3246                 .ptr            = &Globals.iDomainMaster,
3247                 .special        = NULL,
3248                 .enum_list      = enum_bool_auto,
3249                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3250         },
3251         {
3252                 .label          = "browse list",
3253                 .type           = P_BOOL,
3254                 .p_class        = P_GLOBAL,
3255                 .ptr            = &Globals.bBrowseList,
3256                 .special        = NULL,
3257                 .enum_list      = NULL,
3258                 .flags          = FLAG_ADVANCED,
3259         },
3260         {
3261                 .label          = "browseable",
3262                 .type           = P_BOOL,
3263                 .p_class        = P_LOCAL,
3264                 .ptr            = &sDefault.bBrowseable,
3265                 .special        = NULL,
3266                 .enum_list      = NULL,
3267                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3268         },
3269         {
3270                 .label          = "browsable",
3271                 .type           = P_BOOL,
3272                 .p_class        = P_LOCAL,
3273                 .ptr            = &sDefault.bBrowseable,
3274                 .special        = NULL,
3275                 .enum_list      = NULL,
3276                 .flags          = FLAG_HIDE,
3277         },
3278         {
3279                 .label          = "enhanced browsing",
3280                 .type           = P_BOOL,
3281                 .p_class        = P_GLOBAL,
3282                 .ptr            = &Globals.enhanced_browsing,
3283                 .special        = NULL,
3284                 .enum_list      = NULL,
3285                 .flags          = FLAG_ADVANCED,
3286         },
3287
3288         {N_("WINS Options"), P_SEP, P_SEPARATOR},
3289
3290         {
3291                 .label          = "dns proxy",
3292                 .type           = P_BOOL,
3293                 .p_class        = P_GLOBAL,
3294                 .ptr            = &Globals.bDNSproxy,
3295                 .special        = NULL,
3296                 .enum_list      = NULL,
3297                 .flags          = FLAG_ADVANCED,
3298         },
3299         {
3300                 .label          = "wins proxy",
3301                 .type           = P_BOOL,
3302                 .p_class        = P_GLOBAL,
3303                 .ptr            = &Globals.bWINSproxy,
3304                 .special        = NULL,
3305                 .enum_list      = NULL,
3306                 .flags          = FLAG_ADVANCED,
3307         },
3308         {
3309                 .label          = "wins server",
3310                 .type           = P_LIST,
3311                 .p_class        = P_GLOBAL,
3312                 .ptr            = &Globals.szWINSservers,
3313                 .special        = NULL,
3314                 .enum_list      = NULL,
3315                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3316         },
3317         {
3318                 .label          = "wins support",
3319                 .type           = P_BOOL,
3320                 .p_class        = P_GLOBAL,
3321                 .ptr            = &Globals.bWINSsupport,
3322                 .special        = NULL,
3323                 .enum_list      = NULL,
3324                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3325         },
3326         {
3327                 .label          = "wins hook",
3328                 .type           = P_STRING,
3329                 .p_class        = P_GLOBAL,
3330                 .ptr            = &Globals.szWINSHook,
3331                 .special        = NULL,
3332                 .enum_list      = NULL,
3333                 .flags          = FLAG_ADVANCED,
3334         },
3335
3336         {N_("Locking Options"), P_SEP, P_SEPARATOR},
3337
3338         {
3339                 .label          = "blocking locks",
3340                 .type           = P_BOOL,
3341                 .p_class        = P_LOCAL,
3342                 .ptr            = &sDefault.bBlockingLocks,
3343                 .special        = NULL,
3344                 .enum_list      = NULL,
3345                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3346         },
3347         {
3348                 .label          = "csc policy",
3349                 .type           = P_ENUM,
3350                 .p_class        = P_LOCAL,
3351                 .ptr            = &sDefault.iCSCPolicy,
3352                 .special        = NULL,
3353                 .enum_list      = enum_csc_policy,
3354                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3355         },
3356         {
3357                 .label          = "fake oplocks",
3358                 .type           = P_BOOL,
3359                 .p_class        = P_LOCAL,
3360                 .ptr            = &sDefault.bFakeOplocks,
3361                 .special        = NULL,
3362                 .enum_list      = NULL,
3363                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3364         },
3365         {
3366                 .label          = "kernel oplocks",
3367                 .type           = P_BOOL,
3368                 .p_class        = P_GLOBAL,
3369                 .ptr            = &Globals.bKernelOplocks,
3370                 .special        = NULL,
3371                 .enum_list      = NULL,
3372                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3373         },
3374         {
3375                 .label          = "locking",
3376                 .type           = P_BOOL,
3377                 .p_class        = P_LOCAL,
3378                 .ptr            = &sDefault.bLocking,
3379                 .special        = NULL,
3380                 .enum_list      = NULL,
3381                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3382         },
3383         {
3384                 .label          = "lock spin time",
3385                 .type           = P_INTEGER,
3386                 .p_class        = P_GLOBAL,
3387                 .ptr            = &Globals.iLockSpinTime,
3388                 .special        = NULL,
3389                 .enum_list      = NULL,
3390                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3391         },
3392         {
3393                 .label          = "oplocks",
3394                 .type           = P_BOOL,
3395                 .p_class        = P_LOCAL,
3396                 .ptr            = &sDefault.bOpLocks,
3397                 .special        = NULL,
3398                 .enum_list      = NULL,
3399                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3400         },
3401         {
3402                 .label          = "level2 oplocks",
3403                 .type           = P_BOOL,
3404                 .p_class        = P_LOCAL,
3405                 .ptr            = &sDefault.bLevel2OpLocks,
3406                 .special        = NULL,
3407                 .enum_list      = NULL,
3408                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3409         },
3410         {
3411                 .label          = "oplock break wait time",
3412                 .type           = P_INTEGER,
3413                 .p_class        = P_GLOBAL,
3414                 .ptr            = &Globals.oplock_break_wait_time,
3415                 .special        = NULL,
3416                 .enum_list      = NULL,
3417                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3418         },
3419         {
3420                 .label          = "oplock contention limit",
3421                 .type           = P_INTEGER,
3422                 .p_class        = P_LOCAL,
3423                 .ptr            = &sDefault.iOplockContentionLimit,
3424                 .special        = NULL,
3425                 .enum_list      = NULL,
3426                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3427         },
3428         {
3429                 .label          = "posix locking",
3430                 .type           = P_BOOL,
3431                 .p_class        = P_LOCAL,
3432                 .ptr            = &sDefault.bPosixLocking,
3433                 .special        = NULL,
3434                 .enum_list      = NULL,
3435                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3436         },
3437         {
3438                 .label          = "strict locking",
3439                 .type           = P_ENUM,
3440                 .p_class        = P_LOCAL,
3441                 .ptr            = &sDefault.iStrictLocking,
3442                 .special        = NULL,
3443                 .enum_list      = enum_bool_auto,
3444                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3445         },
3446         {
3447                 .label          = "share modes",
3448                 .type           = P_BOOL,
3449                 .p_class        = P_LOCAL,
3450                 .ptr            = &sDefault.bShareModes,
3451                 .special        = NULL,
3452                 .enum_list      = NULL,
3453                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3454         },
3455
3456         {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3457
3458         {
3459                 .label          = "ldap admin dn",
3460                 .type           = P_STRING,
3461                 .p_class        = P_GLOBAL,
3462                 .ptr            = &Globals.szLdapAdminDn,
3463                 .special        = NULL,
3464                 .enum_list      = NULL,
3465                 .flags          = FLAG_ADVANCED,
3466         },
3467         {
3468                 .label          = "ldap delete dn",
3469                 .type           = P_BOOL,
3470                 .p_class        = P_GLOBAL,
3471                 .ptr            = &Globals.ldap_delete_dn,
3472                 .special        = NULL,
3473                 .enum_list      = NULL,
3474                 .flags          = FLAG_ADVANCED,
3475         },
3476         {
3477                 .label          = "ldap group suffix",
3478                 .type           = P_STRING,
3479                 .p_class        = P_GLOBAL,
3480                 .ptr            = &Globals.szLdapGroupSuffix,
3481                 .special        = NULL,
3482                 .enum_list      = NULL,
3483                 .flags          = FLAG_ADVANCED,
3484         },
3485         {
3486                 .label          = "ldap idmap suffix",
3487                 .type           = P_STRING,
3488                 .p_class        = P_GLOBAL,
3489                 .ptr            = &Globals.szLdapIdmapSuffix,
3490                 .special        = NULL,
3491                 .enum_list      = NULL,
3492                 .flags          = FLAG_ADVANCED,
3493         },
3494         {
3495                 .label          = "ldap machine suffix",
3496                 .type           = P_STRING,
3497                 .p_class        = P_GLOBAL,
3498                 .ptr            = &Globals.szLdapMachineSuffix,
3499                 .special        = NULL,
3500                 .enum_list      = NULL,
3501                 .flags          = FLAG_ADVANCED,
3502         },
3503         {
3504                 .label          = "ldap passwd sync",
3505                 .type           = P_ENUM,
3506                 .p_class        = P_GLOBAL,
3507                 .ptr            = &Globals.ldap_passwd_sync,
3508                 .special        = NULL,
3509                 .enum_list      = enum_ldap_passwd_sync,
3510                 .flags          = FLAG_ADVANCED,
3511         },
3512         {
3513                 .label          = "ldap password sync",
3514                 .type           = P_ENUM,
3515                 .p_class        = P_GLOBAL,
3516                 .ptr            = &Globals.ldap_passwd_sync,
3517                 .special        = NULL,
3518                 .enum_list      = enum_ldap_passwd_sync,
3519                 .flags          = FLAG_HIDE,
3520         },
3521         {
3522                 .label          = "ldap replication sleep",
3523                 .type           = P_INTEGER,
3524                 .p_class        = P_GLOBAL,
3525                 .ptr            = &Globals.ldap_replication_sleep,
3526                 .special        = NULL,
3527                 .enum_list      = NULL,
3528                 .flags          = FLAG_ADVANCED,
3529         },
3530         {
3531                 .label          = "ldap suffix",
3532                 .type           = P_STRING,
3533                 .p_class        = P_GLOBAL,
3534                 .ptr            = &Globals.szLdapSuffix,
3535                 .special        = NULL,
3536                 .enum_list      = NULL,
3537                 .flags          = FLAG_ADVANCED,
3538         },
3539         {
3540                 .label          = "ldap ssl",
3541                 .type           = P_ENUM,
3542                 .p_class        = P_GLOBAL,
3543                 .ptr            = &Globals.ldap_ssl,
3544                 .special        = NULL,
3545                 .enum_list      = enum_ldap_ssl,
3546                 .flags          = FLAG_ADVANCED,
3547         },
3548         {
3549                 .label          = "ldap timeout",
3550                 .type           = P_INTEGER,
3551                 .p_class        = P_GLOBAL,
3552                 .ptr            = &Globals.ldap_timeout,
3553                 .special        = NULL,
3554                 .enum_list      = NULL,
3555                 .flags          = FLAG_ADVANCED,
3556         },
3557         {
3558                 .label          = "ldap page size",
3559                 .type           = P_INTEGER,
3560                 .p_class        = P_GLOBAL,
3561                 .ptr            = &Globals.ldap_page_size,
3562                 .special        = NULL,
3563                 .enum_list      = NULL,
3564                 .flags          = FLAG_ADVANCED,
3565         },
3566         {
3567                 .label          = "ldap user suffix",
3568                 .type           = P_STRING,
3569                 .p_class        = P_GLOBAL,
3570                 .ptr            = &Globals.szLdapUserSuffix,
3571                 .special        = NULL,
3572                 .enum_list      = NULL,
3573                 .flags          = FLAG_ADVANCED,
3574         },
3575         {
3576                 .label          = "ldap debug level",
3577                 .type           = P_INTEGER,
3578                 .p_class        = P_GLOBAL,
3579                 .ptr            = &Globals.ldap_debug_level,
3580                 .special        = handle_ldap_debug_level,
3581                 .enum_list      = NULL,
3582                 .flags          = FLAG_ADVANCED,
3583         },
3584         {
3585                 .label          = "ldap debug threshold",
3586                 .type           = P_INTEGER,
3587                 .p_class        = P_GLOBAL,
3588                 .ptr            = &Globals.ldap_debug_threshold,
3589                 .special        = NULL,
3590                 .enum_list      = NULL,
3591                 .flags          = FLAG_ADVANCED,
3592         },
3593
3594         {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3595
3596         {
3597                 .label          = "eventlog list",
3598                 .type           = P_LIST,
3599                 .p_class        = P_GLOBAL,
3600                 .ptr            = &Globals.szEventLogs,
3601                 .special        = NULL,
3602                 .enum_list      = NULL,
3603                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3604         },
3605
3606         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3607
3608         {
3609                 .label          = "add share command",
3610                 .type           = P_STRING,
3611                 .p_class        = P_GLOBAL,
3612                 .ptr            = &Globals.szAddShareCommand,
3613                 .special        = NULL,
3614                 .enum_list      = NULL,
3615                 .flags          = FLAG_ADVANCED,
3616         },
3617         {
3618                 .label          = "change share command",
3619                 .type           = P_STRING,
3620                 .p_class        = P_GLOBAL,
3621                 .ptr            = &Globals.szChangeShareCommand,
3622                 .special        = NULL,
3623                 .enum_list      = NULL,
3624                 .flags          = FLAG_ADVANCED,
3625         },
3626         {
3627                 .label          = "delete share command",
3628                 .type           = P_STRING,
3629                 .p_class        = P_GLOBAL,
3630                 .ptr            = &Globals.szDeleteShareCommand,
3631                 .special        = NULL,
3632                 .enum_list      = NULL,
3633                 .flags          = FLAG_ADVANCED,
3634         },
3635         {
3636                 .label          = "config file",
3637                 .type           = P_STRING,
3638                 .p_class        = P_GLOBAL,
3639                 .ptr            = &Globals.szConfigFile,
3640                 .special        = NULL,
3641                 .enum_list      = NULL,
3642                 .flags          = FLAG_HIDE,
3643         },
3644         {
3645                 .label          = "preload",
3646                 .type           = P_STRING,
3647                 .p_class        = P_GLOBAL,
3648                 .ptr            = &Globals.szAutoServices,
3649                 .special        = NULL,
3650                 .enum_list      = NULL,
3651                 .flags          = FLAG_ADVANCED,
3652         },
3653         {
3654                 .label          = "auto services",
3655                 .type           = P_STRING,
3656                 .p_class        = P_GLOBAL,
3657                 .ptr            = &Globals.szAutoServices,
3658                 .special        = NULL,
3659                 .enum_list      = NULL,
3660                 .flags          = FLAG_ADVANCED,
3661         },
3662         {
3663                 .label          = "lock directory",
3664                 .type           = P_STRING,
3665                 .p_class        = P_GLOBAL,
3666                 .ptr            = &Globals.szLockDir,
3667                 .special        = NULL,
3668                 .enum_list      = NULL,
3669                 .flags          = FLAG_ADVANCED,
3670         },
3671         {
3672                 .label          = "lock dir",
3673                 .type           = P_STRING,
3674                 .p_class        = P_GLOBAL,
3675                 .ptr            = &Globals.szLockDir,
3676                 .special        = NULL,
3677                 .enum_list      = NULL,
3678                 .flags          = FLAG_HIDE,
3679         },
3680         {
3681                 .label          = "pid directory",
3682                 .type           = P_STRING,
3683                 .p_class        = P_GLOBAL,
3684                 .ptr            = &Globals.szPidDir,
3685                 .special        = NULL,
3686                 .enum_list      = NULL,
3687                 .flags          = FLAG_ADVANCED,
3688         },
3689 #ifdef WITH_UTMP
3690         {
3691                 .label          = "utmp directory",
3692                 .type           = P_STRING,
3693                 .p_class        = P_GLOBAL,
3694                 .ptr            = &Globals.szUtmpDir,
3695                 .special        = NULL,
3696                 .enum_list      = NULL,
3697                 .flags          = FLAG_ADVANCED,
3698         },
3699         {
3700                 .label          = "wtmp directory",
3701                 .type           = P_STRING,
3702                 .p_class        = P_GLOBAL,
3703                 .ptr            = &Globals.szWtmpDir,
3704                 .special        = NULL,
3705                 .enum_list      = NULL,
3706                 .flags          = FLAG_ADVANCED,
3707         },
3708         {
3709                 .label          = "utmp",
3710                 .type           = P_BOOL,
3711                 .p_class        = P_GLOBAL,
3712                 .ptr            = &Globals.bUtmp,
3713                 .special        = NULL,
3714                 .enum_list      = NULL,
3715                 .flags          = FLAG_ADVANCED,
3716         },
3717 #endif
3718         {
3719                 .label          = "default service",
3720                 .type           = P_STRING,
3721                 .p_class        = P_GLOBAL,
3722                 .ptr            = &Globals.szDefaultService,
3723                 .special        = NULL,
3724                 .enum_list      = NULL,
3725                 .flags          = FLAG_ADVANCED,
3726         },
3727         {
3728                 .label          = "default",
3729                 .type           = P_STRING,
3730                 .p_class        = P_GLOBAL,
3731                 .ptr            = &Globals.szDefaultService,
3732                 .special        = NULL,
3733                 .enum_list      = NULL,
3734                 .flags          = FLAG_ADVANCED,
3735         },
3736         {
3737                 .label          = "message command",
3738                 .type           = P_STRING,
3739                 .p_class        = P_GLOBAL,
3740                 .ptr            = &Globals.szMsgCommand,
3741                 .special        = NULL,
3742                 .enum_list      = NULL,
3743                 .flags          = FLAG_ADVANCED,
3744         },
3745         {
3746                 .label          = "dfree cache time",
3747                 .type           = P_INTEGER,
3748                 .p_class        = P_LOCAL,
3749                 .ptr            = &sDefault.iDfreeCacheTime,
3750                 .special        = NULL,
3751                 .enum_list      = NULL,
3752                 .flags          = FLAG_ADVANCED,
3753         },
3754         {
3755                 .label          = "dfree command",
3756                 .type           = P_STRING,
3757                 .p_class        = P_LOCAL,
3758                 .ptr            = &sDefault.szDfree,
3759                 .special        = NULL,
3760                 .enum_list      = NULL,
3761                 .flags          = FLAG_ADVANCED,
3762         },
3763         {
3764                 .label          = "get quota command",
3765                 .type           = P_STRING,
3766                 .p_class        = P_GLOBAL,
3767                 .ptr            = &Globals.szGetQuota,
3768                 .special        = NULL,
3769                 .enum_list      = NULL,
3770                 .flags          = FLAG_ADVANCED,
3771         },
3772         {
3773                 .label          = "set quota command",
3774                 .type           = P_STRING,
3775                 .p_class        = P_GLOBAL,
3776                 .ptr            = &Globals.szSetQuota,
3777                 .special        = NULL,
3778                 .enum_list      = NULL,
3779                 .flags          = FLAG_ADVANCED,
3780         },
3781         {
3782                 .label          = "remote announce",
3783                 .type           = P_STRING,
3784                 .p_class        = P_GLOBAL,
3785                 .ptr            = &Globals.szRemoteAnnounce,
3786                 .special        = NULL,
3787                 .enum_list      = NULL,
3788                 .flags          = FLAG_ADVANCED,
3789         },
3790         {
3791                 .label          = "remote browse sync",
3792                 .type           = P_STRING,
3793                 .p_class        = P_GLOBAL,
3794                 .ptr            = &Globals.szRemoteBrowseSync,
3795                 .special        = NULL,
3796                 .enum_list      = NULL,
3797                 .flags          = FLAG_ADVANCED,
3798         },
3799         {
3800                 .label          = "socket address",
3801                 .type           = P_STRING,
3802                 .p_class        = P_GLOBAL,
3803                 .ptr            = &Globals.szSocketAddress,
3804                 .special        = NULL,
3805                 .enum_list      = NULL,
3806                 .flags          = FLAG_ADVANCED,
3807         },
3808         {
3809                 .label          = "homedir map",
3810                 .type           = P_STRING,
3811                 .p_class        = P_GLOBAL,
3812                 .ptr            = &Globals.szNISHomeMapName,
3813                 .special        = NULL,
3814                 .enum_list      = NULL,
3815                 .flags          = FLAG_ADVANCED,
3816         },
3817         {
3818                 .label          = "afs username map",
3819                 .type           = P_STRING,
3820                 .p_class        = P_GLOBAL,
3821                 .ptr            = &Globals.szAfsUsernameMap,
3822                 .special        = NULL,
3823                 .enum_list      = NULL,
3824                 .flags          = FLAG_ADVANCED,
3825         },
3826         {
3827                 .label          = "afs token lifetime",
3828                 .type           = P_INTEGER,
3829                 .p_class        = P_GLOBAL,
3830                 .ptr            = &Globals.iAfsTokenLifetime,
3831                 .special        = NULL,
3832                 .enum_list      = NULL,
3833                 .flags          = FLAG_ADVANCED,
3834         },
3835         {
3836                 .label          = "log nt token command",
3837                 .type           = P_STRING,
3838                 .p_class        = P_GLOBAL,
3839                 .ptr            = &Globals.szLogNtTokenCommand,
3840                 .special        = NULL,
3841                 .enum_list      = NULL,
3842                 .flags          = FLAG_ADVANCED,
3843         },
3844         {
3845                 .label          = "time offset",
3846                 .type           = P_INTEGER,
3847                 .p_class        = P_GLOBAL,
3848                 .ptr            = &extra_time_offset,
3849                 .special        = NULL,
3850                 .enum_list      = NULL,
3851                 .flags          = FLAG_ADVANCED,
3852         },
3853         {
3854                 .label          = "NIS homedir",
3855                 .type           = P_BOOL,
3856                 .p_class        = P_GLOBAL,
3857                 .ptr            = &Globals.bNISHomeMap,
3858                 .special        = NULL,
3859                 .enum_list      = NULL,
3860                 .flags          = FLAG_ADVANCED,
3861         },
3862         {
3863                 .label          = "-valid",
3864                 .type           = P_BOOL,
3865                 .p_class        = P_LOCAL,
3866                 .ptr            = &sDefault.valid,
3867                 .special        = NULL,
3868                 .enum_list      = NULL,
3869                 .flags          = FLAG_HIDE,
3870         },
3871         {
3872                 .label          = "copy",
3873                 .type           = P_STRING,
3874                 .p_class        = P_LOCAL,
3875                 .ptr            = &sDefault.szCopy,
3876                 .special        = handle_copy,
3877                 .enum_list      = NULL,
3878                 .flags          = FLAG_HIDE,
3879         },
3880         {
3881                 .label          = "include",
3882                 .type           = P_STRING,
3883                 .p_class        = P_LOCAL,
3884                 .ptr            = &sDefault.szInclude,
3885                 .special        = handle_include,
3886                 .enum_list      = NULL,
3887                 .flags          = FLAG_HIDE,
3888         },
3889         {
3890                 .label          = "preexec",
3891                 .type           = P_STRING,
3892                 .p_class        = P_LOCAL,
3893                 .ptr            = &sDefault.szPreExec,
3894                 .special        = NULL,
3895                 .enum_list      = NULL,
3896                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3897         },
3898         {
3899                 .label          = "exec",
3900                 .type           = P_STRING,
3901                 .p_class        = P_LOCAL,
3902                 .ptr            = &sDefault.szPreExec,
3903                 .special        = NULL,
3904                 .enum_list      = NULL,
3905                 .flags          = FLAG_ADVANCED,
3906         },
3907         {
3908                 .label          = "preexec close",
3909                 .type           = P_BOOL,
3910                 .p_class        = P_LOCAL,
3911                 .ptr            = &sDefault.bPreexecClose,
3912                 .special        = NULL,
3913                 .enum_list      = NULL,
3914                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3915         },
3916         {
3917                 .label          = "postexec",
3918                 .type           = P_STRING,
3919                 .p_class        = P_LOCAL,
3920                 .ptr            = &sDefault.szPostExec,
3921                 .special        = NULL,
3922                 .enum_list      = NULL,
3923                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3924         },
3925         {
3926                 .label          = "root preexec",
3927                 .type           = P_STRING,
3928                 .p_class        = P_LOCAL,
3929                 .ptr            = &sDefault.szRootPreExec,
3930                 .special        = NULL,
3931                 .enum_list      = NULL,
3932                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3933         },
3934         {
3935                 .label          = "root preexec close",
3936                 .type           = P_BOOL,
3937                 .p_class        = P_LOCAL,
3938                 .ptr            = &sDefault.bRootpreexecClose,
3939                 .special        = NULL,
3940                 .enum_list      = NULL,
3941                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3942         },
3943         {
3944                 .label          = "root postexec",
3945                 .type           = P_STRING,
3946                 .p_class        = P_LOCAL,
3947                 .ptr            = &sDefault.szRootPostExec,
3948                 .special        = NULL,
3949                 .enum_list      = NULL,
3950                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3951         },
3952         {
3953                 .label          = "available",
3954                 .type           = P_BOOL,
3955                 .p_class        = P_LOCAL,
3956                 .ptr            = &sDefault.bAvailable,
3957                 .special        = NULL,
3958                 .enum_list      = NULL,
3959                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3960         },
3961         {
3962                 .label          = "registry shares",
3963                 .type           = P_BOOL,
3964                 .p_class        = P_GLOBAL,
3965                 .ptr            = &Globals.bRegistryShares,
3966                 .special        = NULL,
3967                 .enum_list      = NULL,
3968                 .flags          = FLAG_ADVANCED,
3969         },
3970         {
3971                 .label          = "usershare allow guests",
3972                 .type           = P_BOOL,
3973                 .p_class        = P_GLOBAL,
3974                 .ptr            = &Globals.bUsershareAllowGuests,
3975                 .special        = NULL,
3976                 .enum_list      = NULL,
3977                 .flags          = FLAG_ADVANCED,
3978         },
3979         {
3980                 .label          = "usershare max shares",
3981                 .type           = P_INTEGER,
3982                 .p_class        = P_GLOBAL,
3983                 .ptr            = &Globals.iUsershareMaxShares,
3984                 .special        = NULL,
3985                 .enum_list      = NULL,
3986                 .flags          = FLAG_ADVANCED,
3987         },
3988         {
3989                 .label          = "usershare owner only",
3990                 .type           = P_BOOL,
3991                 .p_class        = P_GLOBAL,
3992                 .ptr            = &Globals.bUsershareOwnerOnly,
3993                 .special        = NULL,
3994                 .enum_list      = NULL,
3995                 .flags          = FLAG_ADVANCED,
3996         },
3997         {
3998                 .label          = "usershare path",
3999                 .type           = P_STRING,
4000                 .p_class        = P_GLOBAL,
4001                 .ptr            = &Globals.szUsersharePath,
4002                 .special        = NULL,
4003                 .enum_list      = NULL,
4004                 .flags          = FLAG_ADVANCED,
4005         },
4006         {
4007                 .label          = "usershare prefix allow list",
4008                 .type           = P_LIST,
4009                 .p_class        = P_GLOBAL,
4010                 .ptr            = &Globals.szUsersharePrefixAllowList,
4011                 .special        = NULL,
4012                 .enum_list      = NULL,
4013                 .flags          = FLAG_ADVANCED,
4014         },
4015         {
4016                 .label          = "usershare prefix deny list",
4017                 .type           = P_LIST,
4018                 .p_class        = P_GLOBAL,
4019                 .ptr            = &Globals.szUsersharePrefixDenyList,
4020                 .special        = NULL,
4021                 .enum_list      = NULL,
4022                 .flags          = FLAG_ADVANCED,
4023         },
4024         {
4025                 .label          = "usershare template share",
4026                 .type           = P_STRING,
4027                 .p_class        = P_GLOBAL,
4028                 .ptr            = &Globals.szUsershareTemplateShare,
4029                 .special        = NULL,
4030                 .enum_list      = NULL,
4031                 .flags          = FLAG_ADVANCED,
4032         },
4033         {
4034                 .label          = "volume",
4035                 .type           = P_STRING,
4036                 .p_class        = P_LOCAL,
4037                 .ptr            = &sDefault.volume,
4038                 .special        = NULL,
4039                 .enum_list      = NULL,
4040                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4041         },
4042         {
4043                 .label          = "fstype",
4044                 .type           = P_STRING,
4045                 .p_class        = P_LOCAL,
4046                 .ptr            = &sDefault.fstype,
4047                 .special        = NULL,
4048                 .enum_list      = NULL,
4049                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4050         },
4051         {
4052                 .label          = "set directory",
4053                 .type           = P_BOOLREV,
4054                 .p_class        = P_LOCAL,
4055                 .ptr            = &sDefault.bNo_set_dir,
4056                 .special        = NULL,
4057                 .enum_list      = NULL,
4058                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4059         },
4060         {
4061                 .label          = "wide links",
4062                 .type           = P_BOOL,
4063                 .p_class        = P_LOCAL,
4064                 .ptr            = &sDefault.bWidelinks,
4065                 .special        = NULL,
4066                 .enum_list      = NULL,
4067                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4068         },
4069         {
4070                 .label          = "follow symlinks",
4071                 .type           = P_BOOL,
4072                 .p_class        = P_LOCAL,
4073                 .ptr            = &sDefault.bSymlinks,
4074                 .special        = NULL,
4075                 .enum_list      = NULL,
4076                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4077         },
4078         {
4079                 .label          = "dont descend",
4080                 .type           = P_STRING,
4081                 .p_class        = P_LOCAL,
4082                 .ptr            = &sDefault.szDontdescend,
4083                 .special        = NULL,
4084                 .enum_list      = NULL,
4085                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4086         },
4087         {
4088                 .label          = "magic script",
4089                 .type           = P_STRING,
4090                 .p_class        = P_LOCAL,
4091                 .ptr            = &sDefault.szMagicScript,
4092                 .special        = NULL,
4093                 .enum_list      = NULL,
4094                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4095         },
4096         {
4097                 .label          = "magic output",
4098                 .type           = P_STRING,
4099                 .p_class        = P_LOCAL,
4100                 .ptr            = &sDefault.szMagicOutput,
4101                 .special        = NULL,
4102                 .enum_list      = NULL,
4103                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4104         },
4105         {
4106                 .label          = "delete readonly",
4107                 .type           = P_BOOL,
4108                 .p_class        = P_LOCAL,
4109                 .ptr            = &sDefault.bDeleteReadonly,
4110                 .special        = NULL,
4111                 .enum_list      = NULL,
4112                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4113         },
4114         {
4115                 .label          = "dos filemode",
4116                 .type           = P_BOOL,
4117                 .p_class        = P_LOCAL,
4118                 .ptr            = &sDefault.bDosFilemode,
4119                 .special        = NULL,
4120                 .enum_list      = NULL,
4121                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4122         },
4123         {
4124                 .label          = "dos filetimes",
4125                 .type           = P_BOOL,
4126                 .p_class        = P_LOCAL,
4127                 .ptr            = &sDefault.bDosFiletimes,
4128                 .special        = NULL,
4129                 .enum_list      = NULL,
4130                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4131         },
4132         {
4133                 .label          = "dos filetime resolution",
4134                 .type           = P_BOOL,
4135                 .p_class        = P_LOCAL,
4136                 .ptr            = &sDefault.bDosFiletimeResolution,
4137                 .special        = NULL,
4138                 .enum_list      = NULL,
4139                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4140         },
4141         {
4142                 .label          = "fake directory create times",
4143                 .type           = P_BOOL,
4144                 .p_class        = P_LOCAL,
4145                 .ptr            = &sDefault.bFakeDirCreateTimes,
4146                 .special        = NULL,
4147                 .enum_list      = NULL,
4148                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4149         },
4150         {
4151                 .label          = "panic action",
4152                 .type           = P_STRING,
4153                 .p_class        = P_GLOBAL,
4154                 .ptr            = &Globals.szPanicAction,
4155                 .special        = NULL,
4156                 .enum_list      = NULL,
4157                 .flags          = FLAG_ADVANCED,
4158         },
4159
4160         {N_("VFS module options"), P_SEP, P_SEPARATOR},
4161
4162         {
4163                 .label          = "vfs objects",
4164                 .type           = P_LIST,
4165                 .p_class        = P_LOCAL,
4166                 .ptr            = &sDefault.szVfsObjects,
4167                 .special        = NULL,
4168                 .enum_list      = NULL,
4169                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4170         },
4171         {
4172                 .label          = "vfs object",
4173                 .type           = P_LIST,
4174                 .p_class        = P_LOCAL,
4175                 .ptr            = &sDefault.szVfsObjects,
4176                 .special        = NULL,
4177                 .enum_list      = NULL,
4178                 .flags          = FLAG_HIDE,
4179         },
4180
4181
4182         {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4183
4184         {
4185                 .label          = "msdfs root",
4186                 .type           = P_BOOL,
4187                 .p_class        = P_LOCAL,
4188                 .ptr            = &sDefault.bMSDfsRoot,
4189                 .special        = NULL,
4190                 .enum_list      = NULL,
4191                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4192         },
4193         {
4194                 .label          = "msdfs proxy",
4195                 .type           = P_STRING,
4196                 .p_class        = P_LOCAL,
4197                 .ptr            = &sDefault.szMSDfsProxy,
4198                 .special        = NULL,
4199                 .enum_list      = NULL,
4200                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4201         },
4202         {
4203                 .label          = "host msdfs",
4204                 .type           = P_BOOL,
4205                 .p_class        = P_GLOBAL,
4206                 .ptr            = &Globals.bHostMSDfs,
4207                 .special        = NULL,
4208                 .enum_list      = NULL,
4209                 .flags          = FLAG_ADVANCED,
4210         },
4211
4212         {N_("Winbind options"), P_SEP, P_SEPARATOR},
4213
4214         {
4215                 .label          = "passdb expand explicit",
4216                 .type           = P_BOOL,
4217                 .p_class        = P_GLOBAL,
4218                 .ptr            = &Globals.bPassdbExpandExplicit,
4219                 .special        = NULL,
4220                 .enum_list      = NULL,
4221                 .flags          = FLAG_ADVANCED,
4222         },
4223         {
4224                 .label          = "idmap domains",
4225                 .type           = P_LIST,
4226                 .p_class        = P_GLOBAL,
4227                 .ptr            = &Globals.szIdmapDomains,
4228                 .special        = NULL,
4229                 .enum_list      = NULL,
4230                 .flags          = FLAG_ADVANCED,
4231         },
4232         {
4233                 .label          = "idmap backend",
4234                 .type           = P_LIST,
4235                 .p_class        = P_GLOBAL,
4236                 .ptr            = &Globals.szIdmapBackend,
4237                 .special        = NULL,
4238                 .enum_list      = NULL,
4239                 .flags          = FLAG_ADVANCED,
4240         },
4241         {
4242                 .label          = "idmap alloc backend",
4243                 .type           = P_STRING,
4244                 .p_class        = P_GLOBAL,
4245                 .ptr            = &Globals.szIdmapAllocBackend,
4246                 .special        = NULL,
4247                 .enum_list      = NULL,
4248                 .flags          = FLAG_ADVANCED,
4249         },
4250         {
4251                 .label          = "idmap cache time",
4252                 .type           = P_INTEGER,
4253                 .p_class        = P_GLOBAL,
4254                 .ptr            = &Globals.iIdmapCacheTime,
4255                 .special        = NULL,
4256                 .enum_list      = NULL,
4257                 .flags          = FLAG_ADVANCED,
4258         },
4259         {
4260                 .label          = "idmap negative cache time",
4261                 .type           = P_INTEGER,
4262                 .p_class        = P_GLOBAL,
4263                 .ptr            = &Globals.iIdmapNegativeCacheTime,
4264                 .special        = NULL,
4265                 .enum_list      = NULL,
4266                 .flags          = FLAG_ADVANCED,
4267         },
4268         {
4269                 .label          = "idmap uid",
4270                 .type           = P_STRING,
4271                 .p_class        = P_GLOBAL,
4272                 .ptr            = &Globals.szIdmapUID,
4273                 .special        = handle_idmap_uid,
4274                 .enum_list      = NULL,
4275                 .flags          = FLAG_ADVANCED,
4276         },
4277         {
4278                 .label          = "winbind uid",
4279                 .type           = P_STRING,
4280                 .p_class        = P_GLOBAL,
4281                 .ptr            = &Globals.szIdmapUID,
4282                 .special        = handle_idmap_uid,
4283                 .enum_list      = NULL,
4284                 .flags          = FLAG_HIDE,
4285         },
4286         {
4287                 .label          = "idmap gid",
4288                 .type           = P_STRING,
4289                 .p_class        = P_GLOBAL,
4290                 .ptr            = &Globals.szIdmapGID,
4291                 .special        = handle_idmap_gid,
4292                 .enum_list      = NULL,
4293                 .flags          = FLAG_ADVANCED,
4294         },
4295         {
4296                 .label          = "winbind gid",
4297                 .type           = P_STRING,
4298                 .p_class        = P_GLOBAL,
4299                 .ptr            = &Globals.szIdmapGID,
4300                 .special        = handle_idmap_gid,
4301                 .enum_list      = NULL,
4302                 .flags          = FLAG_HIDE,
4303         },
4304         {
4305                 .label          = "template homedir",
4306                 .type           = P_STRING,
4307                 .p_class        = P_GLOBAL,
4308                 .ptr            = &Globals.szTemplateHomedir,
4309                 .special        = NULL,
4310                 .enum_list      = NULL,
4311                 .flags          = FLAG_ADVANCED,
4312         },
4313         {
4314                 .label          = "template shell",
4315                 .type           = P_STRING,
4316                 .p_class        = P_GLOBAL,
4317                 .ptr            = &Globals.szTemplateShell,
4318                 .special        = NULL,
4319                 .enum_list      = NULL,
4320                 .flags          = FLAG_ADVANCED,
4321         },
4322         {
4323                 .label          = "winbind separator",
4324                 .type           = P_STRING,
4325                 .p_class        = P_GLOBAL,
4326                 .ptr            = &Globals.szWinbindSeparator,
4327                 .special        = NULL,
4328                 .enum_list      = NULL,
4329                 .flags          = FLAG_ADVANCED,
4330         },
4331         {
4332                 .label          = "winbind cache time",
4333                 .type           = P_INTEGER,
4334                 .p_class        = P_GLOBAL,
4335                 .ptr            = &Globals.winbind_cache_time,
4336                 .special        = NULL,
4337                 .enum_list      = NULL,
4338                 .flags          = FLAG_ADVANCED,
4339         },
4340         {
4341                 .label          = "winbind enum users",
4342                 .type           = P_BOOL,
4343                 .p_class        = P_GLOBAL,
4344                 .ptr            = &Globals.bWinbindEnumUsers,
4345                 .special        = NULL,
4346                 .enum_list      = NULL,
4347                 .flags          = FLAG_ADVANCED,
4348         },
4349         {
4350                 .label          = "winbind enum groups",
4351                 .type           = P_BOOL,
4352                 .p_class        = P_GLOBAL,
4353                 .ptr            = &Globals.bWinbindEnumGroups,
4354                 .special        = NULL,
4355                 .enum_list      = NULL,
4356                 .flags          = FLAG_ADVANCED,
4357         },
4358         {
4359                 .label          = "winbind use default domain",
4360                 .type           = P_BOOL,
4361                 .p_class        = P_GLOBAL,
4362                 .ptr            = &Globals.bWinbindUseDefaultDomain,
4363                 .special        = NULL,
4364                 .enum_list      = NULL,
4365                 .flags          = FLAG_ADVANCED,
4366         },
4367         {
4368                 .label          = "winbind trusted domains only",
4369                 .type           = P_BOOL,
4370                 .p_class        = P_GLOBAL,
4371                 .ptr            = &Globals.bWinbindTrustedDomainsOnly,
4372                 .special        = NULL,
4373                 .enum_list      = NULL,
4374                 .flags          = FLAG_ADVANCED,
4375         },
4376         {
4377                 .label          = "winbind nested groups",
4378                 .type           = P_BOOL,
4379                 .p_class        = P_GLOBAL,
4380                 .ptr            = &Globals.bWinbindNestedGroups,
4381                 .special        = NULL,
4382                 .enum_list      = NULL,
4383                 .flags          = FLAG_ADVANCED,
4384         },
4385         {
4386                 .label          = "winbind expand groups",
4387                 .type           = P_INTEGER,
4388                 .p_class        = P_GLOBAL,
4389                 .ptr            = &Globals.winbind_expand_groups,
4390                 .special        = NULL,
4391                 .enum_list      = NULL,
4392                 .flags          = FLAG_ADVANCED,
4393         },
4394         {
4395                 .label          = "winbind nss info",
4396                 .type           = P_LIST,
4397                 .p_class        = P_GLOBAL,
4398                 .ptr            = &Globals.szWinbindNssInfo,
4399                 .special        = NULL,
4400                 .enum_list      = NULL,
4401                 .flags          = FLAG_ADVANCED,
4402         },
4403         {
4404                 .label          = "winbind refresh tickets",
4405                 .type           = P_BOOL,
4406                 .p_class        = P_GLOBAL,
4407                 .ptr            = &Globals.bWinbindRefreshTickets,
4408                 .special        = NULL,
4409                 .enum_list      = NULL,
4410                 .flags          = FLAG_ADVANCED,
4411         },
4412         {
4413                 .label          = "winbind offline logon",
4414                 .type           = P_BOOL,
4415                 .p_class        = P_GLOBAL,
4416                 .ptr            = &Globals.bWinbindOfflineLogon,
4417                 .special        = NULL,
4418                 .enum_list      = NULL,
4419                 .flags          = FLAG_ADVANCED,
4420         },
4421         {
4422                 .label          = "winbind normalize names",
4423                 .type           = P_BOOL,
4424                 .p_class        = P_GLOBAL,
4425                 .ptr            = &Globals.bWinbindNormalizeNames,
4426                 .special        = NULL,
4427                 .enum_list      = NULL,
4428                 .flags          = FLAG_ADVANCED,
4429         },
4430         {
4431                 .label          = "winbind rpc only",
4432                 .type           = P_BOOL,
4433                 .p_class        = P_GLOBAL,
4434                 .ptr            = &Globals.bWinbindRpcOnly,
4435                 .special        = NULL,
4436                 .enum_list      = NULL,
4437                 .flags          = FLAG_ADVANCED,
4438         },
4439
4440         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
4441 };
4442
4443 /***************************************************************************
4444  Initialise the sDefault parameter structure for the printer values.
4445 ***************************************************************************/
4446
4447 static void init_printer_values(struct service *pService)
4448 {
4449         /* choose defaults depending on the type of printing */
4450         switch (pService->iPrinting) {
4451                 case PRINT_BSD:
4452                 case PRINT_AIX:
4453                 case PRINT_LPRNT:
4454                 case PRINT_LPROS2:
4455                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4456                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4457                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4458                         break;
4459
4460                 case PRINT_LPRNG:
4461                 case PRINT_PLP:
4462                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4463                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4464                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4465                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4466                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4467                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4468                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4469                         break;
4470
4471                 case PRINT_CUPS:
4472                 case PRINT_IPRINT:
4473 #ifdef HAVE_CUPS
4474                         /* set the lpq command to contain the destination printer
4475                            name only.  This is used by cups_queue_get() */
4476                         string_set(&pService->szLpqcommand, "%p");
4477                         string_set(&pService->szLprmcommand, "");
4478                         string_set(&pService->szPrintcommand, "");
4479                         string_set(&pService->szLppausecommand, "");
4480                         string_set(&pService->szLpresumecommand, "");
4481                         string_set(&pService->szQueuepausecommand, "");
4482                         string_set(&pService->szQueueresumecommand, "");
4483 #else
4484                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4485                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4486                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4487                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4488                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4489                         string_set(&pService->szQueuepausecommand, "disable '%p'");
4490                         string_set(&pService->szQueueresumecommand, "enable '%p'");
4491 #endif /* HAVE_CUPS */
4492                         break;
4493
4494                 case PRINT_SYSV:
4495                 case PRINT_HPUX:
4496                         string_set(&pService->szLpqcommand, "lpstat -o%p");
4497                         string_set(&pService->szLprmcommand, "cancel %p-%j");
4498                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4499                         string_set(&pService->szQueuepausecommand, "disable %p");
4500                         string_set(&pService->szQueueresumecommand, "enable %p");
4501 #ifndef HPUX
4502                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4503                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4504 #endif /* HPUX */
4505                         break;
4506
4507                 case PRINT_QNX:
4508                         string_set(&pService->szLpqcommand, "lpq -P%p");
4509                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
4510                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4511                         break;
4512
4513 #ifdef DEVELOPER
4514         case PRINT_TEST:
4515         case PRINT_VLP:
4516                 string_set(&pService->szPrintcommand, "vlp print %p %s");
4517                 string_set(&pService->szLpqcommand, "vlp lpq %p");
4518                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4519                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4520                 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4521                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4522                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4523                 break;
4524 #endif /* DEVELOPER */
4525
4526         }
4527 }
4528
4529 /***************************************************************************
4530  Initialise the global parameter structure.
4531 ***************************************************************************/
4532
4533 static void init_globals(bool first_time_only)
4534 {
4535         static bool done_init = False;
4536         char *s = NULL;
4537         int i;
4538
4539         /* If requested to initialize only once and we've already done it... */
4540         if (first_time_only && done_init) {
4541                 /* ... then we have nothing more to do */
4542                 return;
4543         }
4544
4545         if (!done_init) {
4546                 /* The logfile can be set before this is invoked. Free it if so. */
4547                 if (Globals.szLogFile != NULL) {
4548                         string_free(&Globals.szLogFile);
4549                         Globals.szLogFile = NULL;
4550                 }
4551                 done_init = True;
4552         } else {
4553                 for (i = 0; parm_table[i].label; i++) {
4554                         if ((parm_table[i].type == P_STRING ||
4555                              parm_table[i].type == P_USTRING) &&
4556                             parm_table[i].ptr)
4557                         {
4558                                 string_free((char **)parm_table[i].ptr);
4559                         }
4560                 }
4561         }
4562
4563         memset((void *)&Globals, '\0', sizeof(Globals));
4564
4565         for (i = 0; parm_table[i].label; i++) {
4566                 if ((parm_table[i].type == P_STRING ||
4567                      parm_table[i].type == P_USTRING) &&
4568                     parm_table[i].ptr)
4569                 {
4570                         string_set((char **)parm_table[i].ptr, "");
4571                 }
4572         }
4573
4574         string_set(&sDefault.fstype, FSTYPE_STRING);
4575         string_set(&sDefault.szPrintjobUsername, "%U");
4576
4577         init_printer_values(&sDefault);
4578
4579
4580         DEBUG(3, ("Initialising global parameters\n"));
4581
4582         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4583         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4584
4585         /* use the new 'hash2' method by default, with a prefix of 1 */
4586         string_set(&Globals.szManglingMethod, "hash2");
4587         Globals.mangle_prefix = 1;
4588
4589         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4590
4591         /* using UTF8 by default allows us to support all chars */
4592         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4593
4594 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4595         /* If the system supports nl_langinfo(), try to grab the value
4596            from the user's locale */
4597         string_set(&Globals.display_charset, "LOCALE");
4598 #else
4599         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4600 #endif
4601
4602         /* Use codepage 850 as a default for the dos character set */
4603         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4604
4605         /*
4606          * Allow the default PASSWD_CHAT to be overridden in local.h.
4607          */
4608         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4609
4610         set_global_myname(myhostname());
4611         string_set(&Globals.szNetbiosName,global_myname());
4612
4613         set_global_myworkgroup(WORKGROUP);
4614         string_set(&Globals.szWorkgroup, lp_workgroup());
4615
4616         string_set(&Globals.szPasswdProgram, "");
4617         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4618         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4619         string_set(&Globals.szSocketAddress, "0.0.0.0");
4620
4621         if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4622                 smb_panic("init_globals: ENOMEM");
4623         }
4624         string_set(&Globals.szServerString, s);
4625         SAFE_FREE(s);
4626         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4627                         DEFAULT_MINOR_VERSION) < 0) {
4628                 smb_panic("init_globals: ENOMEM");
4629         }
4630         string_set(&Globals.szAnnounceVersion, s);
4631         SAFE_FREE(s);
4632 #ifdef DEVELOPER
4633         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4634 #endif
4635
4636         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4637
4638         string_set(&Globals.szLogonDrive, "");
4639         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4640         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4641         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4642
4643         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4644         string_set(&Globals.szPasswordServer, "*");
4645
4646         Globals.AlgorithmicRidBase = BASE_RID;
4647
4648         Globals.bLoadPrinters = True;
4649         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
4650
4651         Globals.ConfigBackend = config_backend;
4652
4653         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4654         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4655         Globals.max_xmit = 0x4104;
4656         Globals.max_mux = 50;   /* This is *needed* for profile support. */
4657         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
4658         Globals.bDisableSpoolss = False;
4659         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4660         Globals.pwordlevel = 0;
4661         Globals.unamelevel = 0;
4662         Globals.deadtime = 0;
4663         Globals.getwd_cache = true;
4664         Globals.bLargeReadwrite = True;
4665         Globals.max_log_size = 5000;
4666         Globals.max_open_files = MAX_OPEN_FILES;
4667         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4668         Globals.maxprotocol = PROTOCOL_NT1;
4669         Globals.minprotocol = PROTOCOL_CORE;
4670         Globals.security = SEC_USER;
4671         Globals.paranoid_server_security = True;
4672         Globals.bEncryptPasswords = True;
4673         Globals.bUpdateEncrypt = False;
4674         Globals.clientSchannel = Auto;
4675         Globals.serverSchannel = Auto;
4676         Globals.bReadRaw = True;
4677         Globals.bWriteRaw = True;
4678         Globals.bNullPasswords = False;
4679         Globals.bObeyPamRestrictions = False;
4680         Globals.syslog = 1;
4681         Globals.bSyslogOnly = False;
4682         Globals.bTimestampLogs = True;
4683         string_set(&Globals.szLogLevel, "0");
4684         Globals.bDebugPrefixTimestamp = False;
4685         Globals.bDebugHiresTimestamp = False;
4686         Globals.bDebugPid = False;
4687         Globals.bDebugUid = False;
4688         Globals.bDebugClass = False;
4689         Globals.bEnableCoreFiles = True;
4690         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
4691         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
4692         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
4693         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
4694         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
4695         Globals.lm_interval = 60;
4696         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4697 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4698         Globals.bNISHomeMap = False;
4699 #ifdef WITH_NISPLUS_HOME
4700         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4701 #else
4702         string_set(&Globals.szNISHomeMapName, "auto.home");
4703 #endif
4704 #endif
4705         Globals.bTimeServer = False;
4706         Globals.bBindInterfacesOnly = False;
4707         Globals.bUnixPasswdSync = False;
4708         Globals.bPamPasswordChange = False;
4709         Globals.bPasswdChatDebug = False;
4710         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4711         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
4712         Globals.bNTStatusSupport = True; /* Use NT status by default. */
4713         Globals.bStatCache = True;      /* use stat cache by default */
4714         Globals.iMaxStatCacheSize = 256; /* 256k by default */
4715         Globals.restrict_anonymous = 0;
4716         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
4717         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
4718         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
4719         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4720         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4721         /* Note, that we will use NTLM2 session security (which is different), if it is available */
4722
4723         Globals.map_to_guest = 0;       /* By Default, "Never" */
4724         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
4725         Globals.enhanced_browsing = true;
4726         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4727 #ifdef MMAP_BLACKLIST
4728         Globals.bUseMmap = False;
4729 #else
4730         Globals.bUseMmap = True;
4731 #endif
4732         Globals.bUnixExtensions = True;
4733         Globals.bResetOnZeroVC = False;
4734
4735         /* hostname lookups can be very expensive and are broken on
4736            a large number of sites (tridge) */
4737         Globals.bHostnameLookups = False;
4738
4739         string_set(&Globals.szPassdbBackend, "smbpasswd");
4740         string_set(&Globals.szLdapSuffix, "");
4741         string_set(&Globals.szLdapMachineSuffix, "");
4742         string_set(&Globals.szLdapUserSuffix, "");
4743         string_set(&Globals.szLdapGroupSuffix, "");
4744         string_set(&Globals.szLdapIdmapSuffix, "");
4745
4746         string_set(&Globals.szLdapAdminDn, "");
4747         Globals.ldap_ssl = LDAP_SSL_ON;
4748         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4749         Globals.ldap_delete_dn = False;
4750         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4751         Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
4752         Globals.ldap_page_size = LDAP_PAGE_SIZE;
4753
4754         Globals.ldap_debug_level = 0;
4755         Globals.ldap_debug_threshold = 10;
4756
4757         /* This is what we tell the afs client. in reality we set the token 
4758          * to never expire, though, when this runs out the afs client will 
4759          * forget the token. Set to 0 to get NEVERDATE.*/
4760         Globals.iAfsTokenLifetime = 604800;
4761
4762 /* these parameters are set to defaults that are more appropriate
4763    for the increasing samba install base:
4764
4765    as a member of the workgroup, that will possibly become a
4766    _local_ master browser (lm = True).  this is opposed to a forced
4767    local master browser startup (pm = True).
4768
4769    doesn't provide WINS server service by default (wsupp = False),
4770    and doesn't provide domain master browser services by default, either.
4771
4772 */
4773
4774         Globals.bMsAddPrinterWizard = True;
4775         Globals.os_level = 20;
4776         Globals.bLocalMaster = True;
4777         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
4778         Globals.bDomainLogons = False;
4779         Globals.bBrowseList = True;
4780         Globals.bWINSsupport = False;
4781         Globals.bWINSproxy = False;
4782
4783         Globals.bDNSproxy = True;
4784
4785         /* this just means to use them if they exist */
4786         Globals.bKernelOplocks = True;
4787
4788         Globals.bAllowTrustedDomains = True;
4789
4790         string_set(&Globals.szTemplateShell, "/bin/false");
4791         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4792         string_set(&Globals.szWinbindSeparator, "\\");
4793
4794         string_set(&Globals.szCupsServer, "");
4795         string_set(&Globals.szIPrintServer, "");
4796
4797         string_set(&Globals.ctdbdSocket, "");
4798         Globals.szClusterAddresses = NULL;
4799         Globals.clustering = False;
4800
4801         Globals.winbind_cache_time = 300;       /* 5 minutes */
4802         Globals.bWinbindEnumUsers = False;
4803         Globals.bWinbindEnumGroups = False;
4804         Globals.bWinbindUseDefaultDomain = False;
4805         Globals.bWinbindTrustedDomainsOnly = False;
4806         Globals.bWinbindNestedGroups = True;
4807         Globals.winbind_expand_groups = 1;
4808         Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4809         Globals.bWinbindRefreshTickets = False;
4810         Globals.bWinbindOfflineLogon = False;
4811
4812         Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4813         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4814
4815         Globals.bPassdbExpandExplicit = False;
4816
4817         Globals.name_cache_timeout = 660; /* In seconds */
4818
4819         Globals.bUseSpnego = True;
4820         Globals.bClientUseSpnego = True;
4821
4822         Globals.client_signing = Auto;
4823         Globals.server_signing = False;
4824
4825         Globals.bDeferSharingViolations = True;
4826         string_set(&Globals.smb_ports, SMB_PORTS);
4827
4828         Globals.bEnablePrivileges = True;
4829         Globals.bHostMSDfs        = True;
4830         Globals.bASUSupport       = False;
4831
4832         /* User defined shares. */
4833         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4834                 smb_panic("init_globals: ENOMEM");
4835         }
4836         string_set(&Globals.szUsersharePath, s);
4837         SAFE_FREE(s);
4838         string_set(&Globals.szUsershareTemplateShare, "");
4839         Globals.iUsershareMaxShares = 0;
4840         /* By default disallow sharing of directories not owned by the sharer. */
4841         Globals.bUsershareOwnerOnly = True;
4842         /* By default disallow guest access to usershares. */
4843         Globals.bUsershareAllowGuests = False;
4844
4845         Globals.iKeepalive = DEFAULT_KEEPALIVE;
4846
4847         /* By default no shares out of the registry */
4848         Globals.bRegistryShares = False;
4849
4850         Globals.iminreceivefile = 0;
4851 }
4852
4853 /*******************************************************************
4854  Convenience routine to grab string parameters into temporary memory
4855  and run standard_sub_basic on them. The buffers can be written to by
4856  callers without affecting the source string.
4857 ********************************************************************/
4858
4859 static char *lp_string(const char *s)
4860 {
4861         char *ret;
4862         TALLOC_CTX *ctx = talloc_tos();
4863
4864         /* The follow debug is useful for tracking down memory problems
4865            especially if you have an inner loop that is calling a lp_*()
4866            function that returns a string.  Perhaps this debug should be
4867            present all the time? */
4868
4869 #if 0
4870         DEBUG(10, ("lp_string(%s)\n", s));
4871 #endif
4872
4873         ret = talloc_sub_basic(ctx,
4874                         get_current_username(),
4875                         current_user_info.domain,
4876                         s);
4877         if (trim_char(ret, '\"', '\"')) {
4878                 if (strchr(ret,'\"') != NULL) {
4879                         TALLOC_FREE(ret);
4880                         ret = talloc_sub_basic(ctx,
4881                                         get_current_username(),
4882                                         current_user_info.domain,
4883                                         s);
4884                 }
4885         }
4886         return ret;
4887 }
4888
4889 /*
4890    In this section all the functions that are used to access the 
4891    parameters from the rest of the program are defined 
4892 */
4893
4894 #define FN_GLOBAL_STRING(fn_name,ptr) \
4895  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4896 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4897  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4898 #define FN_GLOBAL_LIST(fn_name,ptr) \
4899  const char **fn_name(void) {return(*(const char ***)(ptr));}
4900 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4901  bool fn_name(void) {return(*(bool *)(ptr));}
4902 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4903  char fn_name(void) {return(*(char *)(ptr));}
4904 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4905  int fn_name(void) {return(*(int *)(ptr));}
4906
4907 #define FN_LOCAL_STRING(fn_name,val) \
4908  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4909 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4910  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4911 #define FN_LOCAL_LIST(fn_name,val) \
4912  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4913 #define FN_LOCAL_BOOL(fn_name,val) \
4914  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4915 #define FN_LOCAL_INTEGER(fn_name,val) \
4916  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4917
4918 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4919  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4920 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4921  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4922 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4923  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));}
4924 #define FN_LOCAL_CHAR(fn_name,val) \
4925  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4926
4927 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4928 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4929 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4930 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4931 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4932 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4933 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4934 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4935 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4936 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4937 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4938 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4939 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4940 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4941 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4942 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4943 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4944 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4945 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4946 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4947 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4948 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4949 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4950 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4951 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4952 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4953 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4954 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4955 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4956 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4957 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4958 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4959 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4960 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4961 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4962 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4963 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4964 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4965 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4966 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4967 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4968 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4969 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4970 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4971 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4972 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4973 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4974 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4975 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4976 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4977  * lp_passdb_backend() should be replace by the this macro again after
4978  * some releases.
4979  * */
4980 const char *lp_passdb_backend(void)
4981 {
4982         char *delim, *quote;
4983
4984         delim = strchr( Globals.szPassdbBackend, ' ');
4985         /* no space at all */
4986         if (delim == NULL) {
4987                 goto out;
4988         }
4989
4990         quote = strchr(Globals.szPassdbBackend, '"');
4991         /* no quote char or non in the first part */
4992         if (quote == NULL || quote > delim) {
4993                 *delim = '\0';
4994                 goto warn;
4995         }
4996
4997         quote = strchr(quote+1, '"');
4998         if (quote == NULL) {
4999                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5000                 goto out;
5001         } else if (*(quote+1) == '\0') {
5002                 /* space, fitting quote char, and one backend only */
5003                 goto out;
5004         } else {
5005                 /* terminate string after the fitting quote char */
5006                 *(quote+1) = '\0';
5007         }
5008
5009 warn:
5010         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5011                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5012                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5013                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5014
5015 out:
5016         return Globals.szPassdbBackend;
5017 }
5018 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5019 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5020 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5021 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5022 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5023
5024 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5025 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5026 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5027 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5028 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5029 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5030
5031 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5032
5033 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5034 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5035 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5036
5037 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5038
5039 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5040 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5041 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5042 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5043 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5044 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5045 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5046 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5047 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5048 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5049 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5050 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5051 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5052 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5053 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5054
5055 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5056 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5057 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5058 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5059 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5060 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5061 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5062
5063 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5064 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5065 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5066 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5067 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5068 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5069 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5070 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5071 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5072 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5073 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5074 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5075 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5076 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5077 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5078 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5079
5080 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5081
5082 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5083 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5084 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5085 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5086 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5087 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5088 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5089 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5090 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5091 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5092 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5093 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5094 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5095 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5096 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5097 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5098 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5099 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5100 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5101 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5102 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5103 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5104 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5105 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5106 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5107 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5108 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5109 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5110 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5111 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5112 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5113 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5114 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5115 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5116 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5117 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5118 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5119 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5120 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5121 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5122 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5123 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5124 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5125 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5126 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5127 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5128 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5129 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5130 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5131 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5132 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5133 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5134 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5135 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5136 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5137 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5138 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5139 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5140 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5141 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5142 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5143 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5144 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5145 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5146 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5147 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5148 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5149 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5150 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5151 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5152 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5153 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5154 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5155 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5156 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5157 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5158 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5159 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5160 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5161 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5162 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5163 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5164 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5165 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5166 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5167 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5168 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5169 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5170 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5171 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5172 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5173 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5174 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5175 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5176 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5177 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
5178
5179 FN_LOCAL_STRING(lp_preexec, szPreExec)
5180 FN_LOCAL_STRING(lp_postexec, szPostExec)
5181 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5182 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5183 FN_LOCAL_STRING(lp_servicename, szService)
5184 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5185 FN_LOCAL_STRING(lp_pathname, szPath)
5186 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5187 FN_LOCAL_STRING(lp_username, szUsername)
5188 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5189 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5190 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5191 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5192 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5193 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5194 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5195 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5196 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5197 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
5198 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5199 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5200 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5201 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5202 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5203 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5204 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5205 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5206 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5207 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5208 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5209 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5210 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5211 FN_LOCAL_STRING(lp_comment, comment)
5212 FN_LOCAL_STRING(lp_force_user, force_user)
5213 FN_LOCAL_STRING(lp_force_group, force_group)
5214 FN_LOCAL_LIST(lp_readlist, readlist)
5215 FN_LOCAL_LIST(lp_writelist, writelist)
5216 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5217 FN_LOCAL_STRING(lp_fstype, fstype)
5218 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5219 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5220 static FN_LOCAL_STRING(lp_volume, volume)
5221 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5222 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5223 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5224 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5225 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5226 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5227 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5228 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5229 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5230 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5231 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5232 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5233 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5234 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5235 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5236 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5237 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5238 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5239 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5240 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5241 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5242 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5243 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5244 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5245 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5246 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5247 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5248 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5249 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5250 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5251 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5252 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5253 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5254 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5255 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5256 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5257 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5258 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5259 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5260 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5261 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5262 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5263 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5264 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5265 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5266 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5267 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5268 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5269 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5270 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5271 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5272 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5273 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5274 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5275 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5276 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5277 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5278 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5279 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5280 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5281 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5282 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5283 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5284 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5285 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5286 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5287 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5288 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5289 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5290 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5291 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5292 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5293 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5294 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5295 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5296 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5297 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5298 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5299 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5300 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5301 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5302 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5303 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5304 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5305 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5306 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5307 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5308 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5309 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5310 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5311 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5312 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5313 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5314 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5315 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5316 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5317 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5318
5319 /* local prototypes */
5320
5321 static int map_parameter(const char *pszParmName);
5322 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5323 static bool set_boolean(bool *pb, const char *pszParmValue);
5324 static const char *get_boolean(bool bool_value);
5325 static int getservicebyname(const char *pszServiceName,
5326                             struct service *pserviceDest);
5327 static void copy_service(struct service *pserviceDest,
5328                          struct service *pserviceSource,
5329                          struct bitmap *pcopymapDest);
5330 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
5331 static bool do_section(const char *pszSectionName);
5332 static void init_copymap(struct service *pservice);
5333 static bool hash_a_service(const char *name, int number);
5334 static void free_service_byindex(int iService);
5335 static char * canonicalize_servicename(const char *name);
5336 static void show_parameter(int parmIndex);
5337 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5338
5339 /* This is a helper function for parametrical options support. */
5340 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5341 /* Actual parametrical functions are quite simple */
5342 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5343 {
5344         bool global_section = False;
5345         char* param_key;
5346         param_opt_struct *data;
5347         
5348         if (snum >= iNumServices) return NULL;
5349         
5350         if (snum < 0) { 
5351                 data = Globals.param_opt;
5352                 global_section = True;
5353         } else {
5354                 data = ServicePtrs[snum]->param_opt;
5355         }
5356     
5357         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5358                 DEBUG(0,("asprintf failed!\n"));
5359                 return NULL;
5360         }
5361
5362         while (data) {
5363                 if (strcmp(data->key, param_key) == 0) {
5364                         string_free(&param_key);
5365                         return data;
5366                 }
5367                 data = data->next;
5368         }
5369
5370         if (!global_section) {
5371                 /* Try to fetch the same option but from globals */
5372                 /* but only if we are not already working with Globals */
5373                 data = Globals.param_opt;
5374                 while (data) {
5375                         if (strcmp(data->key, param_key) == 0) {
5376                                 string_free(&param_key);
5377                                 return data;
5378                         }
5379                         data = data->next;
5380                 }
5381         }
5382
5383         string_free(&param_key);
5384         
5385         return NULL;
5386 }
5387
5388
5389 #define MISSING_PARAMETER(name) \
5390     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5391
5392 /*******************************************************************
5393 convenience routine to return int parameters.
5394 ********************************************************************/
5395 static int lp_int(const char *s)
5396 {
5397
5398         if (!s || !*s) {
5399                 MISSING_PARAMETER(lp_int);
5400                 return (-1);
5401         }
5402
5403         return (int)strtol(s, NULL, 0);
5404 }
5405
5406 /*******************************************************************
5407 convenience routine to return unsigned long parameters.
5408 ********************************************************************/
5409 static unsigned long lp_ulong(const char *s)
5410 {
5411
5412         if (!s || !*s) {
5413                 MISSING_PARAMETER(lp_ulong);
5414                 return (0);
5415         }
5416
5417         return strtoul(s, NULL, 0);
5418 }
5419
5420 /*******************************************************************
5421 convenience routine to return boolean parameters.
5422 ********************************************************************/
5423 static bool lp_bool(const char *s)
5424 {
5425         bool ret = False;
5426
5427         if (!s || !*s) {
5428                 MISSING_PARAMETER(lp_bool);
5429                 return False;
5430         }
5431         
5432         if (!set_boolean(&ret,s)) {
5433                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5434                 return False;
5435         }
5436
5437         return ret;
5438 }
5439
5440 /*******************************************************************
5441 convenience routine to return enum parameters.
5442 ********************************************************************/
5443 static int lp_enum(const char *s,const struct enum_list *_enum)
5444 {
5445         int i;
5446
5447         if (!s || !*s || !_enum) {
5448                 MISSING_PARAMETER(lp_enum);
5449                 return (-1);
5450         }
5451         
5452         for (i=0; _enum[i].name; i++) {
5453                 if (strequal(_enum[i].name,s))
5454                         return _enum[i].value;
5455         }
5456
5457         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5458         return (-1);
5459 }
5460
5461 #undef MISSING_PARAMETER
5462
5463 /* DO NOT USE lp_parm_string ANYMORE!!!!
5464  * use lp_parm_const_string or lp_parm_talloc_string
5465  *
5466  * lp_parm_string is only used to let old modules find this symbol
5467  */
5468 #undef lp_parm_string
5469  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5470  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5471 {
5472         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5473 }
5474
5475 /* Return parametric option from a given service. Type is a part of option before ':' */
5476 /* Parametric option has following syntax: 'Type: option = value' */
5477 /* the returned value is talloced on the talloc_tos() */
5478 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5479 {
5480         param_opt_struct *data = get_parametrics(snum, type, option);
5481         
5482         if (data == NULL||data->value==NULL) {
5483                 if (def) {
5484                         return lp_string(def);
5485                 } else {
5486                         return NULL;
5487                 }
5488         }
5489
5490         return lp_string(data->value);
5491 }
5492
5493 /* Return parametric option from a given service. Type is a part of option before ':' */
5494 /* Parametric option has following syntax: 'Type: option = value' */
5495 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5496 {
5497         param_opt_struct *data = get_parametrics(snum, type, option);
5498         
5499         if (data == NULL||data->value==NULL)
5500                 return def;
5501                 
5502         return data->value;
5503 }
5504
5505 /* Return parametric option from a given service. Type is a part of option before ':' */
5506 /* Parametric option has following syntax: 'Type: option = value' */
5507
5508 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5509 {
5510         param_opt_struct *data = get_parametrics(snum, type, option);
5511
5512         if (data == NULL||data->value==NULL)
5513                 return (const char **)def;
5514                 
5515         if (data->list==NULL) {
5516                 data->list = str_list_make(NULL, data->value, NULL);
5517         }
5518
5519         return (const char **)data->list;
5520 }
5521
5522 /* Return parametric option from a given service. Type is a part of option before ':' */
5523 /* Parametric option has following syntax: 'Type: option = value' */
5524
5525 int lp_parm_int(int snum, const char *type, const char *option, int def)
5526 {
5527         param_opt_struct *data = get_parametrics(snum, type, option);
5528         
5529         if (data && data->value && *data->value)
5530                 return lp_int(data->value);
5531
5532         return def;
5533 }
5534
5535 /* Return parametric option from a given service. Type is a part of option before ':' */
5536 /* Parametric option has following syntax: 'Type: option = value' */
5537
5538 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5539 {
5540         param_opt_struct *data = get_parametrics(snum, type, option);
5541         
5542         if (data && data->value && *data->value)
5543                 return lp_ulong(data->value);
5544
5545         return def;
5546 }
5547
5548 /* Return parametric option from a given service. Type is a part of option before ':' */
5549 /* Parametric option has following syntax: 'Type: option = value' */
5550
5551 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5552 {
5553         param_opt_struct *data = get_parametrics(snum, type, option);
5554         
5555         if (data && data->value && *data->value)
5556                 return lp_bool(data->value);
5557
5558         return def;
5559 }
5560
5561 /* Return parametric option from a given service. Type is a part of option before ':' */
5562 /* Parametric option has following syntax: 'Type: option = value' */
5563
5564 int lp_parm_enum(int snum, const char *type, const char *option,
5565                  const struct enum_list *_enum, int def)
5566 {
5567         param_opt_struct *data = get_parametrics(snum, type, option);
5568         
5569         if (data && data->value && *data->value && _enum)
5570                 return lp_enum(data->value, _enum);
5571
5572         return def;
5573 }
5574
5575
5576 /***************************************************************************
5577  Initialise a service to the defaults.
5578 ***************************************************************************/
5579
5580 static void init_service(struct service *pservice)
5581 {
5582         memset((char *)pservice, '\0', sizeof(struct service));
5583         copy_service(pservice, &sDefault, NULL);
5584 }
5585
5586 /***************************************************************************
5587  Free the dynamically allocated parts of a service struct.
5588 ***************************************************************************/
5589
5590 static void free_service(struct service *pservice)
5591 {
5592         int i;
5593         param_opt_struct *data, *pdata;
5594         if (!pservice)
5595                 return;
5596
5597         if (pservice->szService)
5598                 DEBUG(5, ("free_service: Freeing service %s\n",
5599                        pservice->szService));
5600
5601         string_free(&pservice->szService);
5602         bitmap_free(pservice->copymap);
5603
5604         for (i = 0; parm_table[i].label; i++) {
5605                 if ((parm_table[i].type == P_STRING ||
5606                      parm_table[i].type == P_USTRING) &&
5607                     parm_table[i].p_class == P_LOCAL)
5608                         string_free((char **)
5609                                     (((char *)pservice) +
5610                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
5611                 else if (parm_table[i].type == P_LIST &&
5612                          parm_table[i].p_class == P_LOCAL)
5613                              TALLOC_FREE(*((char ***)
5614                                            (((char *)pservice) +
5615                                             PTR_DIFF(parm_table[i].ptr,
5616                                                      &sDefault))));
5617         }
5618
5619         data = pservice->param_opt;
5620         if (data)
5621                 DEBUG(5,("Freeing parametrics:\n"));
5622         while (data) {
5623                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5624                 string_free(&data->key);
5625                 string_free(&data->value);
5626                 TALLOC_FREE(data->list);
5627                 pdata = data->next;
5628                 SAFE_FREE(data);
5629                 data = pdata;
5630         }
5631
5632         ZERO_STRUCTP(pservice);
5633 }
5634
5635
5636 /***************************************************************************
5637  remove a service indexed in the ServicePtrs array from the ServiceHash
5638  and free the dynamically allocated parts
5639 ***************************************************************************/
5640
5641 static void free_service_byindex(int idx)
5642 {
5643         if ( !LP_SNUM_OK(idx) ) 
5644                 return;
5645
5646         ServicePtrs[idx]->valid = False;
5647         invalid_services[num_invalid_services++] = idx;
5648
5649         /* we have to cleanup the hash record */
5650
5651         if (ServicePtrs[idx]->szService) {
5652                 char *canon_name = canonicalize_servicename(
5653                         ServicePtrs[idx]->szService );
5654                 
5655                 dbwrap_delete_bystring(ServiceHash, canon_name );
5656                 TALLOC_FREE(canon_name);
5657         }
5658
5659         free_service(ServicePtrs[idx]);
5660 }
5661
5662 /***************************************************************************
5663  Add a new service to the services array initialising it with the given 
5664  service. 
5665 ***************************************************************************/
5666
5667 static int add_a_service(const struct service *pservice, const char *name)
5668 {
5669         int i;
5670         struct service tservice;
5671         int num_to_alloc = iNumServices + 1;
5672         param_opt_struct *data, *pdata;
5673
5674         tservice = *pservice;
5675
5676         /* it might already exist */
5677         if (name) {
5678                 i = getservicebyname(name, NULL);
5679                 if (i >= 0) {
5680                         /* Clean all parametric options for service */
5681                         /* They will be added during parsing again */
5682                         data = ServicePtrs[i]->param_opt;
5683                         while (data) {
5684                                 string_free(&data->key);
5685                                 string_free(&data->value);
5686                                 TALLOC_FREE(data->list);
5687                                 pdata = data->next;
5688                                 SAFE_FREE(data);
5689                                 data = pdata;
5690                         }
5691                         ServicePtrs[i]->param_opt = NULL;
5692                         return (i);
5693                 }
5694         }
5695
5696         /* find an invalid one */
5697         i = iNumServices;
5698         if (num_invalid_services > 0) {
5699                 i = invalid_services[--num_invalid_services];
5700         }
5701
5702         /* if not, then create one */
5703         if (i == iNumServices) {
5704                 struct service **tsp;
5705                 int *tinvalid;
5706                 
5707                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5708                 if (tsp == NULL) {
5709                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5710                         return (-1);
5711                 }
5712                 ServicePtrs = tsp;
5713                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5714                 if (!ServicePtrs[iNumServices]) {
5715                         DEBUG(0,("add_a_service: out of memory!\n"));
5716                         return (-1);
5717                 }
5718                 iNumServices++;
5719
5720                 /* enlarge invalid_services here for now... */
5721                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5722                                              num_to_alloc);
5723                 if (tinvalid == NULL) {
5724                         DEBUG(0,("add_a_service: failed to enlarge "
5725                                  "invalid_services!\n"));
5726                         return (-1);
5727                 }
5728                 invalid_services = tinvalid;
5729         } else {
5730                 free_service_byindex(i);
5731         }
5732
5733         ServicePtrs[i]->valid = True;
5734
5735         init_service(ServicePtrs[i]);
5736         copy_service(ServicePtrs[i], &tservice, NULL);
5737         if (name)
5738                 string_set(&ServicePtrs[i]->szService, name);
5739                 
5740         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
5741                 i, ServicePtrs[i]->szService));
5742
5743         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5744                 return (-1);
5745         }
5746                 
5747         return (i);
5748 }
5749
5750 /***************************************************************************
5751   Convert a string to uppercase and remove whitespaces.
5752 ***************************************************************************/
5753
5754 static char *canonicalize_servicename(const char *src)
5755 {
5756         char *result;
5757
5758         if ( !src ) {
5759                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5760                 return NULL;
5761         }
5762
5763         result = talloc_strdup(talloc_tos(), src);
5764         SMB_ASSERT(result != NULL);
5765
5766         strlower_m(result);
5767         return result;
5768 }
5769
5770 /***************************************************************************
5771   Add a name/index pair for the services array to the hash table.
5772 ***************************************************************************/
5773
5774 static bool hash_a_service(const char *name, int idx)
5775 {
5776         char *canon_name;
5777
5778         if ( !ServiceHash ) {
5779                 DEBUG(10,("hash_a_service: creating servicehash\n"));
5780                 ServiceHash = db_open_rbt(NULL);
5781                 if ( !ServiceHash ) {
5782                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5783                         return False;
5784                 }
5785         }
5786
5787         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5788                 idx, name));
5789
5790         canon_name = canonicalize_servicename( name );
5791
5792         dbwrap_store_bystring(ServiceHash, canon_name,
5793                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
5794                               TDB_REPLACE);
5795
5796         TALLOC_FREE(canon_name);
5797
5798         return True;
5799 }
5800
5801 /***************************************************************************
5802  Add a new home service, with the specified home directory, defaults coming
5803  from service ifrom.
5804 ***************************************************************************/
5805
5806 bool lp_add_home(const char *pszHomename, int iDefaultService,
5807                  const char *user, const char *pszHomedir)
5808 {
5809         int i;
5810
5811         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5812
5813         if (i < 0)
5814                 return (False);
5815
5816         if (!(*(ServicePtrs[iDefaultService]->szPath))
5817             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5818                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5819         }
5820
5821         if (!(*(ServicePtrs[i]->comment))) {
5822                 char *comment = NULL;
5823                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5824                         return false;
5825                 }
5826                 string_set(&ServicePtrs[i]->comment, comment);
5827                 SAFE_FREE(comment);
5828         }
5829
5830         /* set the browseable flag from the global default */
5831
5832         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5833
5834         ServicePtrs[i]->autoloaded = True;
5835
5836         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
5837                user, ServicePtrs[i]->szPath ));
5838
5839         return (True);
5840 }
5841
5842 /***************************************************************************
5843  Add a new service, based on an old one.
5844 ***************************************************************************/
5845
5846 int lp_add_service(const char *pszService, int iDefaultService)
5847 {
5848         if (iDefaultService < 0) {
5849                 return add_a_service(&sDefault, pszService);
5850         }
5851
5852         return (add_a_service(ServicePtrs[iDefaultService], pszService));
5853 }
5854
5855 /***************************************************************************
5856  Add the IPC service.
5857 ***************************************************************************/
5858
5859 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5860 {
5861         char *comment = NULL;
5862         int i = add_a_service(&sDefault, ipc_name);
5863
5864         if (i < 0)
5865                 return (False);
5866
5867         if (asprintf(&comment, "IPC Service (%s)",
5868                                 Globals.szServerString) < 0) {
5869                 return (False);
5870         }
5871
5872         string_set(&ServicePtrs[i]->szPath, tmpdir());
5873         string_set(&ServicePtrs[i]->szUsername, "");
5874         string_set(&ServicePtrs[i]->comment, comment);
5875         string_set(&ServicePtrs[i]->fstype, "IPC");
5876         ServicePtrs[i]->iMaxConnections = 0;
5877         ServicePtrs[i]->bAvailable = True;
5878         ServicePtrs[i]->bRead_only = True;
5879         ServicePtrs[i]->bGuest_only = False;
5880         ServicePtrs[i]->bAdministrative_share = True;
5881         ServicePtrs[i]->bGuest_ok = guest_ok;
5882         ServicePtrs[i]->bPrint_ok = False;
5883         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5884
5885         DEBUG(3, ("adding IPC service\n"));
5886
5887         SAFE_FREE(comment);
5888         return (True);
5889 }
5890
5891 /***************************************************************************
5892  Add a new printer service, with defaults coming from service iFrom.
5893 ***************************************************************************/
5894
5895 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5896 {
5897         const char *comment = "From Printcap";
5898         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5899
5900         if (i < 0)
5901                 return (False);
5902
5903         /* note that we do NOT default the availability flag to True - */
5904         /* we take it from the default service passed. This allows all */
5905         /* dynamic printers to be disabled by disabling the [printers] */
5906         /* entry (if/when the 'available' keyword is implemented!).    */
5907
5908         /* the printer name is set to the service name. */
5909         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5910         string_set(&ServicePtrs[i]->comment, comment);
5911
5912         /* set the browseable flag from the gloabl default */
5913         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5914
5915         /* Printers cannot be read_only. */
5916         ServicePtrs[i]->bRead_only = False;
5917         /* No share modes on printer services. */
5918         ServicePtrs[i]->bShareModes = False;
5919         /* No oplocks on printer services. */
5920         ServicePtrs[i]->bOpLocks = False;
5921         /* Printer services must be printable. */
5922         ServicePtrs[i]->bPrint_ok = True;
5923         
5924         DEBUG(3, ("adding printer service %s\n", pszPrintername));
5925
5926         return (True);
5927 }
5928
5929
5930 /***************************************************************************
5931  Check whether the given parameter name is valid.
5932  Parametric options (names containing a colon) are considered valid.
5933 ***************************************************************************/
5934
5935 bool lp_parameter_is_valid(const char *pszParmName)
5936 {
5937         return ((map_parameter(pszParmName) != -1) ||
5938                 (strchr(pszParmName, ':') != NULL));
5939 }
5940
5941 /***************************************************************************
5942  Check whether the given name is the name of a global parameter.
5943  Returns True for strings belonging to parameters of class
5944  P_GLOBAL, False for all other strings, also for parametric options
5945  and strings not belonging to any option.
5946 ***************************************************************************/
5947
5948 bool lp_parameter_is_global(const char *pszParmName)
5949 {
5950         int num = map_parameter(pszParmName);
5951
5952         if (num >= 0) {
5953                 return (parm_table[num].p_class == P_GLOBAL);
5954         }
5955
5956         return False;
5957 }
5958
5959 /**************************************************************************
5960  Check whether the given name is the canonical name of a parameter.
5961  Returns False if it is not a valid parameter Name.
5962  For parametric options, True is returned.
5963 **************************************************************************/
5964
5965 bool lp_parameter_is_canonical(const char *parm_name)
5966 {
5967         if (!lp_parameter_is_valid(parm_name)) {
5968                 return False;
5969         }
5970
5971         return (map_parameter(parm_name) ==
5972                 map_parameter_canonical(parm_name, NULL));
5973 }
5974
5975 /**************************************************************************
5976  Determine the canonical name for a parameter.
5977  Indicate when it is an inverse (boolean) synonym instead of a
5978  "usual" synonym.
5979 **************************************************************************/
5980
5981 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5982                                bool *inverse)
5983 {
5984         int num;
5985
5986         if (!lp_parameter_is_valid(parm_name)) {
5987                 *canon_parm = NULL;
5988                 return False;
5989         }
5990
5991         num = map_parameter_canonical(parm_name, inverse);
5992         if (num < 0) {
5993                 /* parametric option */
5994                 *canon_parm = parm_name;
5995         } else {
5996                 *canon_parm = parm_table[num].label;
5997         }
5998
5999         return True;
6000
6001 }
6002
6003 /**************************************************************************
6004  Determine the canonical name for a parameter.
6005  Turn the value given into the inverse boolean expression when
6006  the synonym is an invers boolean synonym.
6007
6008  Return True if parm_name is a valid parameter name and
6009  in case it is an invers boolean synonym, if the val string could
6010  successfully be converted to the reverse bool.
6011  Return false in all other cases.
6012 **************************************************************************/
6013
6014 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6015                                           const char *val,
6016                                           const char **canon_parm,
6017                                           const char **canon_val)
6018 {
6019         int num;
6020         bool inverse;
6021
6022         if (!lp_parameter_is_valid(parm_name)) {
6023                 *canon_parm = NULL;
6024                 *canon_val = NULL;
6025                 return False;
6026         }
6027
6028         num = map_parameter_canonical(parm_name, &inverse);
6029         if (num < 0) {
6030                 /* parametric option */
6031                 *canon_parm = parm_name;
6032                 *canon_val = val;
6033         } else {
6034                 *canon_parm = parm_table[num].label;
6035                 if (inverse) {
6036                         if (!lp_invert_boolean(val, canon_val)) {
6037                                 *canon_val = NULL;
6038                                 return False;
6039                         }
6040                 } else {
6041                         *canon_val = val;
6042                 }
6043         }
6044
6045         return True;
6046 }
6047
6048 /***************************************************************************
6049  Map a parameter's string representation to something we can use. 
6050  Returns False if the parameter string is not recognised, else TRUE.
6051 ***************************************************************************/
6052
6053 static int map_parameter(const char *pszParmName)
6054 {
6055         int iIndex;
6056
6057         if (*pszParmName == '-')
6058                 return (-1);
6059
6060         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6061                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6062                         return (iIndex);
6063
6064         /* Warn only if it isn't parametric option */
6065         if (strchr(pszParmName, ':') == NULL)
6066                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6067         /* We do return 'fail' for parametric options as well because they are
6068            stored in different storage
6069          */
6070         return (-1);
6071 }
6072
6073 /***************************************************************************
6074  Map a parameter's string representation to the index of the canonical
6075  form of the parameter (it might be a synonym).
6076  Returns -1 if the parameter string is not recognised.
6077 ***************************************************************************/
6078
6079 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6080 {
6081         int parm_num, canon_num;
6082         bool loc_inverse = False;
6083
6084         parm_num = map_parameter(pszParmName);
6085         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6086                 /* invalid, parametric or no canidate for synonyms ... */
6087                 goto done;
6088         }
6089
6090         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6091                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6092                         parm_num = canon_num;
6093                         goto done;
6094                 }
6095         }
6096
6097 done:
6098         if (inverse != NULL) {
6099                 *inverse = loc_inverse;
6100         }
6101         return parm_num;
6102 }
6103
6104 /***************************************************************************
6105  return true if parameter number parm1 is a synonym of parameter
6106  number parm2 (parm2 being the principal name).
6107  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6108  False otherwise.
6109 ***************************************************************************/
6110
6111 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6112 {
6113         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6114             (parm_table[parm1].flags & FLAG_HIDE) &&
6115             !(parm_table[parm2].flags & FLAG_HIDE))
6116         {
6117                 if (inverse != NULL) {
6118                         if ((parm_table[parm1].type == P_BOOLREV) &&
6119                             (parm_table[parm2].type == P_BOOL))
6120                         {
6121                                 *inverse = True;
6122                         } else {
6123                                 *inverse = False;
6124                         }
6125                 }
6126                 return True;
6127         }
6128         return False;
6129 }
6130
6131 /***************************************************************************
6132  Show one parameter's name, type, [values,] and flags.
6133  (helper functions for show_parameter_list)
6134 ***************************************************************************/
6135
6136 static void show_parameter(int parmIndex)
6137 {
6138         int enumIndex, flagIndex;
6139         int parmIndex2;
6140         bool hadFlag;
6141         bool hadSyn;
6142         bool inverse;
6143         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6144                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6145                 "P_ENUM", "P_SEP"};
6146         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6147                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6148                 FLAG_HIDE, FLAG_DOS_STRING};
6149         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6150                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6151                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6152
6153         printf("%s=%s", parm_table[parmIndex].label,
6154                type[parm_table[parmIndex].type]);
6155         if (parm_table[parmIndex].type == P_ENUM) {
6156                 printf(",");
6157                 for (enumIndex=0;
6158                      parm_table[parmIndex].enum_list[enumIndex].name;
6159                      enumIndex++)
6160                 {
6161                         printf("%s%s",
6162                                enumIndex ? "|" : "",
6163                                parm_table[parmIndex].enum_list[enumIndex].name);
6164                 }
6165         }
6166         printf(",");
6167         hadFlag = False;
6168         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6169                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6170                         printf("%s%s",
6171                                 hadFlag ? "|" : "",
6172                                 flag_names[flagIndex]);
6173                         hadFlag = True;
6174                 }
6175         }
6176
6177         /* output synonyms */
6178         hadSyn = False;
6179         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6180                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6181                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6182                                parm_table[parmIndex2].label);
6183                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6184                         if (!hadSyn) {
6185                                 printf(" (synonyms: ");
6186                                 hadSyn = True;
6187                         } else {
6188                                 printf(", ");
6189                         }
6190                         printf("%s%s", parm_table[parmIndex2].label,
6191                                inverse ? "[i]" : "");
6192                 }
6193         }
6194         if (hadSyn) {
6195                 printf(")");
6196         }
6197
6198         printf("\n");
6199 }
6200
6201 /***************************************************************************
6202  Show all parameter's name, type, [values,] and flags.
6203 ***************************************************************************/
6204
6205 void show_parameter_list(void)
6206 {
6207         int classIndex, parmIndex;
6208         const char *section_names[] = { "local", "global", NULL};
6209
6210         for (classIndex=0; section_names[classIndex]; classIndex++) {
6211                 printf("[%s]\n", section_names[classIndex]);
6212                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6213                         if (parm_table[parmIndex].p_class == classIndex) {
6214                                 show_parameter(parmIndex);
6215                         }
6216                 }
6217         }
6218 }
6219
6220 /***************************************************************************
6221  Set a boolean variable from the text value stored in the passed string.
6222  Returns True in success, False if the passed string does not correctly 
6223  represent a boolean.
6224 ***************************************************************************/
6225
6226 static bool set_boolean(bool *pb, const char *pszParmValue)
6227 {
6228         bool bRetval;
6229         bool value;
6230
6231         bRetval = True;
6232         value = False;
6233         if (strwicmp(pszParmValue, "yes") == 0 ||
6234             strwicmp(pszParmValue, "true") == 0 ||
6235             strwicmp(pszParmValue, "1") == 0)
6236                 value = True;
6237         else if (strwicmp(pszParmValue, "no") == 0 ||
6238                     strwicmp(pszParmValue, "False") == 0 ||
6239                     strwicmp(pszParmValue, "0") == 0)
6240                 value = False;
6241         else {
6242                 DEBUG(2,
6243                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6244                        pszParmValue));
6245                 bRetval = False;
6246         }
6247
6248         if ((pb != NULL) && (bRetval != False)) {
6249                 *pb = value;
6250         }
6251
6252         return (bRetval);
6253 }
6254
6255
6256 /***************************************************************************
6257  Check if a given string correctly represents a boolean value.
6258 ***************************************************************************/
6259
6260 bool lp_string_is_valid_boolean(const char *parm_value)
6261 {
6262         return set_boolean(NULL, parm_value);
6263 }
6264
6265 /***************************************************************************
6266  Get the standard string representation of a boolean value ("yes" or "no")
6267 ***************************************************************************/
6268
6269 static const char *get_boolean(bool bool_value)
6270 {
6271         static const char *yes_str = "yes";
6272         static const char *no_str = "no";
6273
6274         return (bool_value ? yes_str : no_str);
6275 }
6276
6277 /***************************************************************************
6278  Provide the string of the negated boolean value associated to the boolean
6279  given as a string. Returns False if the passed string does not correctly
6280  represent a boolean.
6281 ***************************************************************************/
6282
6283 bool lp_invert_boolean(const char *str, const char **inverse_str)
6284 {
6285         bool val;
6286
6287         if (!set_boolean(&val, str)) {
6288                 return False;
6289         }
6290
6291         *inverse_str = get_boolean(!val);
6292         return True;
6293 }
6294
6295 /***************************************************************************
6296  Provide the canonical string representation of a boolean value given
6297  as a string. Return True on success, False if the string given does
6298  not correctly represent a boolean.
6299 ***************************************************************************/
6300
6301 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6302 {
6303         bool val;
6304
6305         if (!set_boolean(&val, str)) {
6306                 return False;
6307         }
6308
6309         *canon_str = get_boolean(val);
6310         return True;
6311 }
6312
6313 /***************************************************************************
6314 Find a service by name. Otherwise works like get_service.
6315 ***************************************************************************/
6316
6317 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6318 {
6319         int iService = -1;
6320         char *canon_name;
6321         TDB_DATA data;
6322
6323         if (ServiceHash == NULL) {
6324                 return -1;
6325         }
6326
6327         canon_name = canonicalize_servicename(pszServiceName);
6328
6329         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6330
6331         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6332                 iService = *(int *)data.dptr;
6333         }
6334
6335         TALLOC_FREE(canon_name);
6336
6337         if ((iService != -1) && (LP_SNUM_OK(iService))
6338             && (pserviceDest != NULL)) {
6339                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6340         }
6341
6342         return (iService);
6343 }
6344
6345 /***************************************************************************
6346  Copy a service structure to another.
6347  If pcopymapDest is NULL then copy all fields
6348 ***************************************************************************/
6349
6350 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6351                          struct bitmap *pcopymapDest)
6352 {
6353         int i;
6354         bool bcopyall = (pcopymapDest == NULL);
6355         param_opt_struct *data, *pdata, *paramo;
6356         bool not_added;
6357
6358         for (i = 0; parm_table[i].label; i++)
6359                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6360                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6361                         void *def_ptr = parm_table[i].ptr;
6362                         void *src_ptr =
6363                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6364                                                                     &sDefault);
6365                         void *dest_ptr =
6366                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6367                                                                   &sDefault);
6368
6369                         switch (parm_table[i].type) {
6370                                 case P_BOOL:
6371                                 case P_BOOLREV:
6372                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6373                                         break;
6374
6375                                 case P_INTEGER:
6376                                 case P_ENUM:
6377                                 case P_OCTAL:
6378                                         *(int *)dest_ptr = *(int *)src_ptr;
6379                                         break;
6380
6381                                 case P_CHAR:
6382                                         *(char *)dest_ptr = *(char *)src_ptr;
6383                                         break;
6384
6385                                 case P_STRING:
6386                                         string_set((char **)dest_ptr,
6387                                                    *(char **)src_ptr);
6388                                         break;
6389
6390                                 case P_USTRING:
6391                                         string_set((char **)dest_ptr,
6392                                                    *(char **)src_ptr);
6393                                         strupper_m(*(char **)dest_ptr);
6394                                         break;
6395                                 case P_LIST:
6396                                         TALLOC_FREE(*((char ***)dest_ptr));
6397                                         str_list_copy(NULL, (char ***)dest_ptr,
6398                                                       *(const char ***)src_ptr);
6399                                         break;
6400                                 default:
6401                                         break;
6402                         }
6403                 }
6404
6405         if (bcopyall) {
6406                 init_copymap(pserviceDest);
6407                 if (pserviceSource->copymap)
6408                         bitmap_copy(pserviceDest->copymap,
6409                                     pserviceSource->copymap);
6410         }
6411         
6412         data = pserviceSource->param_opt;
6413         while (data) {
6414                 not_added = True;
6415                 pdata = pserviceDest->param_opt;
6416                 /* Traverse destination */
6417                 while (pdata) {
6418                         /* If we already have same option, override it */
6419                         if (strcmp(pdata->key, data->key) == 0) {
6420                                 string_free(&pdata->value);
6421                                 TALLOC_FREE(data->list);
6422                                 pdata->value = SMB_STRDUP(data->value);
6423                                 not_added = False;
6424                                 break;
6425                         }
6426                         pdata = pdata->next;
6427                 }
6428                 if (not_added) {
6429                     paramo = SMB_XMALLOC_P(param_opt_struct);
6430                     paramo->key = SMB_STRDUP(data->key);
6431                     paramo->value = SMB_STRDUP(data->value);
6432                     paramo->list = NULL;
6433                     DLIST_ADD(pserviceDest->param_opt, paramo);
6434                 }
6435                 data = data->next;
6436         }
6437 }
6438
6439 /***************************************************************************
6440 Check a service for consistency. Return False if the service is in any way
6441 incomplete or faulty, else True.
6442 ***************************************************************************/
6443
6444 bool service_ok(int iService)
6445 {
6446         bool bRetval;
6447
6448         bRetval = True;
6449         if (ServicePtrs[iService]->szService[0] == '\0') {
6450                 DEBUG(0, ("The following message indicates an internal error:\n"));
6451                 DEBUG(0, ("No service name in service entry.\n"));
6452                 bRetval = False;
6453         }
6454
6455         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6456         /* I can't see why you'd want a non-printable printer service...        */
6457         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6458                 if (!ServicePtrs[iService]->bPrint_ok) {
6459                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6460                                ServicePtrs[iService]->szService));
6461                         ServicePtrs[iService]->bPrint_ok = True;
6462                 }
6463                 /* [printers] service must also be non-browsable. */
6464                 if (ServicePtrs[iService]->bBrowseable)
6465                         ServicePtrs[iService]->bBrowseable = False;
6466         }
6467
6468         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6469             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6470             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6471             ) {
6472                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6473                         ServicePtrs[iService]->szService));
6474                 ServicePtrs[iService]->bAvailable = False;
6475         }
6476
6477         /* If a service is flagged unavailable, log the fact at level 1. */
6478         if (!ServicePtrs[iService]->bAvailable)
6479                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6480                           ServicePtrs[iService]->szService));
6481
6482         return (bRetval);
6483 }
6484
6485 /*
6486  * process_registry_globals
6487  */
6488 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
6489 {
6490         WERROR werr;
6491         char **param_names;
6492         char **param_values;
6493         uint32_t num_params;
6494         uint32_t count;
6495         TALLOC_CTX *mem_ctx = talloc_stackframe();
6496         bool ret = false;
6497
6498         if (conf_ctx == NULL) {
6499                 /* first time */
6500                 werr = smbconf_open(NULL, &conf_ctx);
6501                 if (!W_ERROR_IS_OK(werr)) {
6502                         goto done;
6503                 }
6504         }
6505
6506         if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6507                 /* nothing to read from the registry yet but make sure lp_load
6508                  * doesn't return false */
6509                 ret = true;
6510                 goto done;
6511         }
6512
6513         werr = smbconf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME,
6514                                  &num_params, &param_names, &param_values);
6515         if (!W_ERROR_IS_OK(werr)) {
6516                 goto done;
6517         }
6518
6519         for (count = 0; count < num_params; count++) {
6520                 ret = pfunc(param_names[count], param_values[count]);
6521                 if (ret != true) {
6522                         goto done;
6523                 }
6524         }
6525
6526         ret = pfunc("registry shares", "yes");
6527         conf_last_seqnum = smbconf_get_seqnum(conf_ctx, NULL, NULL);
6528
6529 done:
6530         TALLOC_FREE(mem_ctx);
6531         return ret;
6532 }
6533
6534 static struct file_lists {
6535         struct file_lists *next;
6536         char *name;
6537         char *subfname;
6538         time_t modtime;
6539 } *file_lists = NULL;
6540
6541 /*******************************************************************
6542  Keep a linked list of all config files so we know when one has changed 
6543  it's date and needs to be reloaded.
6544 ********************************************************************/
6545
6546 static void add_to_file_list(const char *fname, const char *subfname)
6547 {
6548         struct file_lists *f = file_lists;
6549
6550         while (f) {
6551                 if (f->name && !strcmp(f->name, fname))
6552                         break;
6553                 f = f->next;
6554         }
6555
6556         if (!f) {
6557                 f = SMB_MALLOC_P(struct file_lists);
6558                 if (!f)
6559                         return;
6560                 f->next = file_lists;
6561                 f->name = SMB_STRDUP(fname);
6562                 if (!f->name) {
6563                         SAFE_FREE(f);
6564                         return;
6565                 }
6566                 f->subfname = SMB_STRDUP(subfname);
6567                 if (!f->subfname) {
6568                         SAFE_FREE(f);
6569                         return;
6570                 }
6571                 file_lists = f;
6572                 f->modtime = file_modtime(subfname);
6573         } else {
6574                 time_t t = file_modtime(subfname);
6575                 if (t)
6576                         f->modtime = t;
6577         }
6578 }
6579
6580 /**
6581  * Utility function for outsiders to check if we're running on registry.
6582  */
6583 bool lp_config_backend_is_registry(void)
6584 {
6585         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6586 }
6587
6588 /**
6589  * Utility function to check if the config backend is FILE.
6590  */
6591 bool lp_config_backend_is_file(void)
6592 {
6593         return (lp_config_backend() == CONFIG_BACKEND_FILE);
6594 }
6595
6596 /*******************************************************************
6597  Check if a config file has changed date.
6598 ********************************************************************/
6599
6600 bool lp_file_list_changed(void)
6601 {
6602         struct file_lists *f = file_lists;
6603
6604         DEBUG(6, ("lp_file_list_changed()\n"));
6605
6606         if (lp_config_backend_is_registry()) {
6607                 uint64_t conf_cur_seqnum;
6608                 if (conf_ctx == NULL) {
6609                         WERROR werr;
6610                         werr = smbconf_open(NULL, &conf_ctx);
6611                         if (!W_ERROR_IS_OK(werr)) {
6612                                 DEBUG(0, ("error opening configuration: %s\n",
6613                                           dos_errstr(werr)));
6614                                 return false;
6615                         }
6616                 }
6617                 conf_cur_seqnum = smbconf_get_seqnum(conf_ctx, NULL, NULL);
6618                 if (conf_last_seqnum != conf_cur_seqnum) {
6619                         DEBUGADD(6, ("regdb seqnum changed: old = %llu, "
6620                                      "new = %llu\n",
6621                                      (unsigned long long)conf_last_seqnum,
6622                                      (unsigned long long)conf_cur_seqnum));
6623                         return true;
6624                 } else {
6625                         /*
6626                          * Don't check files when config_backend is registry.
6627                          * Remove this to obtain checking of files even with
6628                          * registry config backend. That would enable switching
6629                          * off registry configuration by changing smb.conf even
6630                          * without restarting smbd.
6631                          */
6632                         return false;
6633                 }
6634         }
6635
6636         while (f) {
6637                 char *n2 = NULL;
6638                 time_t mod_time;
6639
6640                 n2 = alloc_sub_basic(get_current_username(),
6641                                     current_user_info.domain,
6642                                     f->name);
6643                 if (!n2) {
6644                         return false;
6645                 }
6646                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
6647                              f->name, n2, ctime(&f->modtime)));
6648
6649                 mod_time = file_modtime(n2);
6650
6651                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6652                         DEBUGADD(6,
6653                                  ("file %s modified: %s\n", n2,
6654                                   ctime(&mod_time)));
6655                         f->modtime = mod_time;
6656                         SAFE_FREE(f->subfname);
6657                         f->subfname = n2; /* Passing ownership of
6658                                              return from alloc_sub_basic
6659                                              above. */
6660                         return true;
6661                 }
6662                 SAFE_FREE(n2);
6663                 f = f->next;
6664         }
6665         return (False);
6666 }
6667
6668
6669 /***************************************************************************
6670  Run standard_sub_basic on netbios name... needed because global_myname
6671  is not accessed through any lp_ macro.
6672  Note: We must *NOT* use string_set() here as ptr points to global_myname.
6673 ***************************************************************************/
6674
6675 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6676 {
6677         bool ret;
6678         char *netbios_name = alloc_sub_basic(get_current_username(),
6679                                         current_user_info.domain,
6680                                         pszParmValue);
6681
6682         ret = set_global_myname(netbios_name);
6683         SAFE_FREE(netbios_name);
6684         string_set(&Globals.szNetbiosName,global_myname());
6685
6686         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6687                global_myname()));
6688
6689         return ret;
6690 }
6691
6692 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6693 {
6694         if (strcmp(*ptr, pszParmValue) != 0) {
6695                 string_set(ptr, pszParmValue);
6696                 init_iconv();
6697         }
6698         return True;
6699 }
6700
6701
6702
6703 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6704 {
6705         bool ret;
6706         
6707         ret = set_global_myworkgroup(pszParmValue);
6708         string_set(&Globals.szWorkgroup,lp_workgroup());
6709         
6710         return ret;
6711 }
6712
6713 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6714 {
6715         bool ret;
6716         
6717         ret = set_global_scope(pszParmValue);
6718         string_set(&Globals.szNetbiosScope,global_scope());
6719
6720         return ret;
6721 }
6722
6723 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6724 {
6725         TALLOC_FREE(Globals.szNetbiosAliases);
6726         Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6727         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6728 }
6729
6730 /***************************************************************************
6731  Handle the include operation.
6732 ***************************************************************************/
6733
6734 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6735 {
6736         char *fname;
6737
6738         fname = alloc_sub_basic(get_current_username(),
6739                                 current_user_info.domain,
6740                                 pszParmValue);
6741
6742         add_to_file_list(pszParmValue, fname);
6743
6744         string_set(ptr, fname);
6745
6746         if (file_exist(fname, NULL)) {
6747                 bool ret = pm_process(fname, do_section, do_parameter);
6748                 SAFE_FREE(fname);
6749                 return ret;
6750         }
6751
6752         DEBUG(2, ("Can't find include file %s\n", fname));
6753         SAFE_FREE(fname);
6754         return false;
6755 }
6756
6757 /***************************************************************************
6758  Handle the interpretation of the copy parameter.
6759 ***************************************************************************/
6760
6761 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6762 {
6763         bool bRetval;
6764         int iTemp;
6765         struct service serviceTemp;
6766
6767         string_set(ptr, pszParmValue);
6768
6769         init_service(&serviceTemp);
6770
6771         bRetval = False;
6772
6773         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6774
6775         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6776                 if (iTemp == iServiceIndex) {
6777                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6778                 } else {
6779                         copy_service(ServicePtrs[iServiceIndex],
6780                                      &serviceTemp,
6781                                      ServicePtrs[iServiceIndex]->copymap);
6782                         bRetval = True;
6783                 }
6784         } else {
6785                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6786                 bRetval = False;
6787         }
6788
6789         free_service(&serviceTemp);
6790         return (bRetval);
6791 }
6792
6793 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6794 {
6795         Globals.ldap_debug_level = lp_int(pszParmValue);
6796         init_ldap_debugging();
6797         return true;
6798 }
6799
6800 /***************************************************************************
6801  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
6802  parameters is:
6803
6804  [global]
6805
6806         idmap uid = 1000-1999
6807         idmap gid = 700-899
6808
6809  We only do simple parsing checks here.  The strings are parsed into useful
6810  structures in the idmap daemon code.
6811
6812 ***************************************************************************/
6813
6814 /* Some lp_ routines to return idmap [ug]id information */
6815
6816 static uid_t idmap_uid_low, idmap_uid_high;
6817 static gid_t idmap_gid_low, idmap_gid_high;
6818
6819 bool lp_idmap_uid(uid_t *low, uid_t *high)
6820 {
6821         if (idmap_uid_low == 0 || idmap_uid_high == 0)
6822                 return False;
6823
6824         if (low)
6825                 *low = idmap_uid_low;
6826
6827         if (high)
6828                 *high = idmap_uid_high;
6829
6830         return True;
6831 }
6832
6833 bool lp_idmap_gid(gid_t *low, gid_t *high)
6834 {
6835         if (idmap_gid_low == 0 || idmap_gid_high == 0)
6836                 return False;
6837
6838         if (low)
6839                 *low = idmap_gid_low;
6840
6841         if (high)
6842                 *high = idmap_gid_high;
6843
6844         return True;
6845 }
6846
6847 /* Do some simple checks on "idmap [ug]id" parameter values */
6848
6849 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6850 {
6851         uint32 low, high;
6852
6853         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6854                 return False;
6855
6856         /* Parse OK */
6857
6858         string_set(ptr, pszParmValue);
6859
6860         idmap_uid_low = low;
6861         idmap_uid_high = high;
6862
6863         return True;
6864 }
6865
6866 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6867 {
6868         uint32 low, high;
6869
6870         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6871                 return False;
6872
6873         /* Parse OK */
6874
6875         string_set(ptr, pszParmValue);
6876
6877         idmap_gid_low = low;
6878         idmap_gid_high = high;
6879
6880         return True;
6881 }
6882
6883 /***************************************************************************
6884  Handle the DEBUG level list.
6885 ***************************************************************************/
6886
6887 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6888 {
6889         string_set(ptr, pszParmValueIn);
6890         return debug_parse_levels(pszParmValueIn);
6891 }
6892
6893 /***************************************************************************
6894  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6895 ***************************************************************************/
6896
6897 static const char *append_ldap_suffix( const char *str )
6898 {
6899         const char *suffix_string;
6900
6901
6902         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6903                                         Globals.szLdapSuffix );
6904         if ( !suffix_string ) {
6905                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6906                 return "";
6907         }
6908
6909         return suffix_string;
6910 }
6911
6912 const char *lp_ldap_machine_suffix(void)
6913 {
6914         if (Globals.szLdapMachineSuffix[0])
6915                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6916
6917         return lp_string(Globals.szLdapSuffix);
6918 }
6919
6920 const char *lp_ldap_user_suffix(void)
6921 {
6922         if (Globals.szLdapUserSuffix[0])
6923                 return append_ldap_suffix(Globals.szLdapUserSuffix);
6924
6925         return lp_string(Globals.szLdapSuffix);
6926 }
6927
6928 const char *lp_ldap_group_suffix(void)
6929 {
6930         if (Globals.szLdapGroupSuffix[0])
6931                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6932
6933         return lp_string(Globals.szLdapSuffix);
6934 }
6935
6936 const char *lp_ldap_idmap_suffix(void)
6937 {
6938         if (Globals.szLdapIdmapSuffix[0])
6939                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6940
6941         return lp_string(Globals.szLdapSuffix);
6942 }
6943
6944 /****************************************************************************
6945  set the value for a P_ENUM
6946  ***************************************************************************/
6947
6948 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6949                               int *ptr )
6950 {
6951         int i;
6952
6953         for (i = 0; parm->enum_list[i].name; i++) {
6954                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6955                         *ptr = parm->enum_list[i].value;
6956                         break;
6957                 }
6958         }
6959 }
6960
6961 /***************************************************************************
6962 ***************************************************************************/
6963
6964 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
6965 {
6966         static int parm_num = -1;
6967         struct service *s;
6968
6969         if ( parm_num == -1 )
6970                 parm_num = map_parameter( "printing" );
6971
6972         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
6973
6974         if ( snum < 0 )
6975                 s = &sDefault;
6976         else
6977                 s = ServicePtrs[snum];
6978
6979         init_printer_values( s );
6980
6981         return True;
6982 }
6983
6984
6985 /***************************************************************************
6986  Initialise a copymap.
6987 ***************************************************************************/
6988
6989 static void init_copymap(struct service *pservice)
6990 {
6991         int i;
6992         if (pservice->copymap) {
6993                 bitmap_free(pservice->copymap);
6994         }
6995         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
6996         if (!pservice->copymap)
6997                 DEBUG(0,
6998                       ("Couldn't allocate copymap!! (size %d)\n",
6999                        (int)NUMPARAMETERS));
7000         else
7001                 for (i = 0; i < NUMPARAMETERS; i++)
7002                         bitmap_set(pservice->copymap, i);
7003 }
7004
7005 /***************************************************************************
7006  Return the local pointer to a parameter given the service number and the 
7007  pointer into the default structure.
7008 ***************************************************************************/
7009
7010 void *lp_local_ptr(int snum, void *ptr)
7011 {
7012         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7013 }
7014
7015 /***************************************************************************
7016  Process a parameter for a particular service number. If snum < 0
7017  then assume we are in the globals.
7018 ***************************************************************************/
7019
7020 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7021 {
7022         int parmnum, i, slen;
7023         void *parm_ptr = NULL;  /* where we are going to store the result */
7024         void *def_ptr = NULL;
7025         char *param_key = NULL;
7026         char *sep;
7027         param_opt_struct *paramo, *data;
7028         bool not_added;
7029
7030         parmnum = map_parameter(pszParmName);
7031
7032         if (parmnum < 0) {
7033                 if ((sep=strchr(pszParmName, ':')) != NULL) {
7034                         TALLOC_CTX *frame = talloc_stackframe();
7035
7036                         *sep = '\0';
7037                         param_key = talloc_asprintf(frame, "%s:", pszParmName);
7038                         if (!param_key) {
7039                                 TALLOC_FREE(frame);
7040                                 return false;
7041                         }
7042                         slen = strlen(param_key);
7043                         param_key = talloc_asprintf_append(param_key, sep+1);
7044                         if (!param_key) {
7045                                 TALLOC_FREE(frame);
7046                                 return false;
7047                         }
7048                         trim_char(param_key+slen, ' ', ' ');
7049                         not_added = True;
7050                         data = (snum < 0) ? Globals.param_opt :
7051                                 ServicePtrs[snum]->param_opt;
7052                         /* Traverse destination */
7053                         while (data) {
7054                                 /* If we already have same option, override it */
7055                                 if (strcmp(data->key, param_key) == 0) {
7056                                         string_free(&data->value);
7057                                         TALLOC_FREE(data->list);
7058                                         data->value = SMB_STRDUP(pszParmValue);
7059                                         not_added = False;
7060                                         break;
7061                                 }
7062                                 data = data->next;
7063                         }
7064                         if (not_added) {
7065                                 paramo = SMB_XMALLOC_P(param_opt_struct);
7066                                 paramo->key = SMB_STRDUP(param_key);
7067                                 paramo->value = SMB_STRDUP(pszParmValue);
7068                                 paramo->list = NULL;
7069                                 if (snum < 0) {
7070                                         DLIST_ADD(Globals.param_opt, paramo);
7071                                 } else {
7072                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7073                                 }
7074                         }
7075
7076                         *sep = ':';
7077                         TALLOC_FREE(frame);
7078                         return (True);
7079                 }
7080                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7081                 return (True);
7082         }
7083
7084         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7085                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7086                           pszParmName));
7087         }
7088
7089         def_ptr = parm_table[parmnum].ptr;
7090
7091         /* we might point at a service, the default service or a global */
7092         if (snum < 0) {
7093                 parm_ptr = def_ptr;
7094         } else {
7095                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7096                         DEBUG(0,
7097                               ("Global parameter %s found in service section!\n",
7098                                pszParmName));
7099                         return (True);
7100                 }
7101                 parm_ptr =
7102                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7103                                                             &sDefault);
7104         }
7105
7106         if (snum >= 0) {
7107                 if (!ServicePtrs[snum]->copymap)
7108                         init_copymap(ServicePtrs[snum]);
7109
7110                 /* this handles the aliases - set the copymap for other entries with
7111                    the same data pointer */
7112                 for (i = 0; parm_table[i].label; i++)
7113                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7114                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7115         }
7116
7117         /* if it is a special case then go ahead */
7118         if (parm_table[parmnum].special) {
7119                 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7120                 return (True);
7121         }
7122
7123         /* now switch on the type of variable it is */
7124         switch (parm_table[parmnum].type)
7125         {
7126                 case P_BOOL:
7127                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7128                         break;
7129
7130                 case P_BOOLREV:
7131                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7132                         break;
7133
7134                 case P_INTEGER:
7135                         *(int *)parm_ptr = lp_int(pszParmValue);
7136                         break;
7137
7138                 case P_CHAR:
7139                         *(char *)parm_ptr = *pszParmValue;
7140                         break;
7141
7142                 case P_OCTAL:
7143                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7144                         if ( i != 1 ) {
7145                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7146                         }
7147                         break;
7148
7149                 case P_LIST:
7150                         TALLOC_FREE(*((char ***)parm_ptr));
7151                         *(char ***)parm_ptr = str_list_make(
7152                                 NULL, pszParmValue, NULL);
7153                         break;
7154
7155                 case P_STRING:
7156                         string_set((char **)parm_ptr, pszParmValue);
7157                         break;
7158
7159                 case P_USTRING:
7160                         string_set((char **)parm_ptr, pszParmValue);
7161                         strupper_m(*(char **)parm_ptr);
7162                         break;
7163
7164                 case P_ENUM:
7165                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7166                         break;
7167                 case P_SEP:
7168                         break;
7169         }
7170
7171         return (True);
7172 }
7173
7174 /***************************************************************************
7175  Process a parameter.
7176 ***************************************************************************/
7177
7178 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
7179 {
7180         if (!bInGlobalSection && bGlobalOnly)
7181                 return (True);
7182
7183         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7184
7185         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7186                                 pszParmName, pszParmValue));
7187 }
7188
7189 /***************************************************************************
7190  Print a parameter of the specified type.
7191 ***************************************************************************/
7192
7193 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7194 {
7195         int i;
7196         switch (p->type)
7197         {
7198                 case P_ENUM:
7199                         for (i = 0; p->enum_list[i].name; i++) {
7200                                 if (*(int *)ptr == p->enum_list[i].value) {
7201                                         fprintf(f, "%s",
7202                                                 p->enum_list[i].name);
7203                                         break;
7204                                 }
7205                         }
7206                         break;
7207
7208                 case P_BOOL:
7209                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7210                         break;
7211
7212                 case P_BOOLREV:
7213                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7214                         break;
7215
7216                 case P_INTEGER:
7217                         fprintf(f, "%d", *(int *)ptr);
7218                         break;
7219
7220                 case P_CHAR:
7221                         fprintf(f, "%c", *(char *)ptr);
7222                         break;
7223
7224                 case P_OCTAL: {
7225                         char *o = octal_string(*(int *)ptr);
7226                         fprintf(f, "%s", o);
7227                         TALLOC_FREE(o);
7228                         break;
7229                 }
7230
7231                 case P_LIST:
7232                         if ((char ***)ptr && *(char ***)ptr) {
7233                                 char **list = *(char ***)ptr;
7234                                 for (; *list; list++) {
7235                                         /* surround strings with whitespace in double quotes */
7236                                         if ( strchr_m( *list, ' ' ) )
7237                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7238                                         else
7239                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7240                                 }
7241                         }
7242                         break;
7243
7244                 case P_STRING:
7245                 case P_USTRING:
7246                         if (*(char **)ptr) {
7247                                 fprintf(f, "%s", *(char **)ptr);
7248                         }
7249                         break;
7250                 case P_SEP:
7251                         break;
7252         }
7253 }
7254
7255 /***************************************************************************
7256  Check if two parameters are equal.
7257 ***************************************************************************/
7258
7259 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7260 {
7261         switch (type) {
7262                 case P_BOOL:
7263                 case P_BOOLREV:
7264                         return (*((bool *)ptr1) == *((bool *)ptr2));
7265
7266                 case P_INTEGER:
7267                 case P_ENUM:
7268                 case P_OCTAL:
7269                         return (*((int *)ptr1) == *((int *)ptr2));
7270
7271                 case P_CHAR:
7272                         return (*((char *)ptr1) == *((char *)ptr2));
7273
7274                 case P_LIST:
7275                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7276
7277                 case P_STRING:
7278                 case P_USTRING:
7279                 {
7280                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7281                         if (p1 && !*p1)
7282                                 p1 = NULL;
7283                         if (p2 && !*p2)
7284                                 p2 = NULL;
7285                         return (p1 == p2 || strequal(p1, p2));
7286                 }
7287                 case P_SEP:
7288                         break;
7289         }
7290         return (False);
7291 }
7292
7293 /***************************************************************************
7294  Initialize any local varients in the sDefault table.
7295 ***************************************************************************/
7296
7297 void init_locals(void)
7298 {
7299         /* None as yet. */
7300 }
7301
7302 /***************************************************************************
7303  Process a new section (service). At this stage all sections are services.
7304  Later we'll have special sections that permit server parameters to be set.
7305  Returns True on success, False on failure. 
7306 ***************************************************************************/
7307
7308 static bool do_section(const char *pszSectionName)
7309 {
7310         bool bRetval;
7311         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7312                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7313         bRetval = False;
7314
7315         /* if we were in a global section then do the local inits */
7316         if (bInGlobalSection && !isglobal)
7317                 init_locals();
7318
7319         /* if we've just struck a global section, note the fact. */
7320         bInGlobalSection = isglobal;
7321
7322         /* check for multiple global sections */
7323         if (bInGlobalSection) {
7324                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7325                 return (True);
7326         }
7327
7328         if (!bInGlobalSection && bGlobalOnly)
7329                 return (True);
7330
7331         /* if we have a current service, tidy it up before moving on */
7332         bRetval = True;
7333
7334         if (iServiceIndex >= 0)
7335                 bRetval = service_ok(iServiceIndex);
7336
7337         /* if all is still well, move to the next record in the services array */
7338         if (bRetval) {
7339                 /* We put this here to avoid an odd message order if messages are */
7340                 /* issued by the post-processing of a previous section. */
7341                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7342
7343                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7344                     < 0) {
7345                         DEBUG(0, ("Failed to add a new service\n"));
7346                         return (False);
7347                 }
7348         }
7349
7350         return (bRetval);
7351 }
7352
7353
7354 /***************************************************************************
7355  Determine if a partcular base parameter is currentl set to the default value.
7356 ***************************************************************************/
7357
7358 static bool is_default(int i)
7359 {
7360         if (!defaults_saved)
7361                 return False;
7362         switch (parm_table[i].type) {
7363                 case P_LIST:
7364                         return str_list_compare (parm_table[i].def.lvalue, 
7365                                                 *(char ***)parm_table[i].ptr);
7366                 case P_STRING:
7367                 case P_USTRING:
7368                         return strequal(parm_table[i].def.svalue,
7369                                         *(char **)parm_table[i].ptr);
7370                 case P_BOOL:
7371                 case P_BOOLREV:
7372                         return parm_table[i].def.bvalue ==
7373                                 *(bool *)parm_table[i].ptr;
7374                 case P_CHAR:
7375                         return parm_table[i].def.cvalue ==
7376                                 *(char *)parm_table[i].ptr;
7377                 case P_INTEGER:
7378                 case P_OCTAL:
7379                 case P_ENUM:
7380                         return parm_table[i].def.ivalue ==
7381                                 *(int *)parm_table[i].ptr;
7382                 case P_SEP:
7383                         break;
7384         }
7385         return False;
7386 }
7387
7388 /***************************************************************************
7389 Display the contents of the global structure.
7390 ***************************************************************************/
7391
7392 static void dump_globals(FILE *f)
7393 {
7394         int i;
7395         param_opt_struct *data;
7396         
7397         fprintf(f, "[global]\n");
7398
7399         for (i = 0; parm_table[i].label; i++)
7400                 if (parm_table[i].p_class == P_GLOBAL &&
7401                     parm_table[i].ptr &&
7402                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7403                         if (defaults_saved && is_default(i))
7404                                 continue;
7405                         fprintf(f, "\t%s = ", parm_table[i].label);
7406                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7407                         fprintf(f, "\n");
7408         }
7409         if (Globals.param_opt != NULL) {
7410                 data = Globals.param_opt;
7411                 while(data) {
7412                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7413                         data = data->next;
7414                 }
7415         }
7416
7417 }
7418
7419 /***************************************************************************
7420  Return True if a local parameter is currently set to the global default.
7421 ***************************************************************************/
7422
7423 bool lp_is_default(int snum, struct parm_struct *parm)
7424 {
7425         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7426
7427         return equal_parameter(parm->type,
7428                                ((char *)ServicePtrs[snum]) + pdiff,
7429                                ((char *)&sDefault) + pdiff);
7430 }
7431
7432 /***************************************************************************
7433  Display the contents of a single services record.
7434 ***************************************************************************/
7435
7436 static void dump_a_service(struct service *pService, FILE * f)
7437 {
7438         int i;
7439         param_opt_struct *data;
7440         
7441         if (pService != &sDefault)
7442                 fprintf(f, "[%s]\n", pService->szService);
7443
7444         for (i = 0; parm_table[i].label; i++) {
7445
7446                 if (parm_table[i].p_class == P_LOCAL &&
7447                     parm_table[i].ptr &&
7448                     (*parm_table[i].label != '-') &&
7449                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7450                 {
7451                 
7452                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7453
7454                         if (pService == &sDefault) {
7455                                 if (defaults_saved && is_default(i))
7456                                         continue;
7457                         } else {
7458                                 if (equal_parameter(parm_table[i].type,
7459                                                     ((char *)pService) +
7460                                                     pdiff,
7461                                                     ((char *)&sDefault) +
7462                                                     pdiff))
7463                                         continue;
7464                         }
7465
7466                         fprintf(f, "\t%s = ", parm_table[i].label);
7467                         print_parameter(&parm_table[i],
7468                                         ((char *)pService) + pdiff, f);
7469                         fprintf(f, "\n");
7470                 }
7471         }
7472
7473                 if (pService->param_opt != NULL) {
7474                         data = pService->param_opt;
7475                         while(data) {
7476                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7477                                 data = data->next;
7478                         }
7479                 }
7480 }
7481
7482 /***************************************************************************
7483  Display the contents of a parameter of a single services record.
7484 ***************************************************************************/
7485
7486 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7487 {
7488         int i;
7489         bool result = False;
7490         parm_class p_class;
7491         unsigned flag = 0;
7492         fstring local_parm_name;
7493         char *parm_opt;
7494         const char *parm_opt_value;
7495
7496         /* check for parametrical option */
7497         fstrcpy( local_parm_name, parm_name);
7498         parm_opt = strchr( local_parm_name, ':');
7499
7500         if (parm_opt) {
7501                 *parm_opt = '\0';
7502                 parm_opt++;
7503                 if (strlen(parm_opt)) {
7504                         parm_opt_value = lp_parm_const_string( snum,
7505                                 local_parm_name, parm_opt, NULL);
7506                         if (parm_opt_value) {
7507                                 printf( "%s\n", parm_opt_value);
7508                                 result = True;
7509                         }
7510                 }
7511                 return result;
7512         }
7513
7514         /* check for a key and print the value */
7515         if (isGlobal) {
7516                 p_class = P_GLOBAL;
7517                 flag = FLAG_GLOBAL;
7518         } else
7519                 p_class = P_LOCAL;
7520
7521         for (i = 0; parm_table[i].label; i++) {
7522                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7523                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7524                     parm_table[i].ptr &&
7525                     (*parm_table[i].label != '-') &&
7526                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7527                 {
7528                         void *ptr;
7529
7530                         if (isGlobal) {
7531                                 ptr = parm_table[i].ptr;
7532                         } else {
7533                                 struct service *pService = ServicePtrs[snum];
7534                                 ptr = ((char *)pService) +
7535                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7536                         }
7537
7538                         print_parameter(&parm_table[i],
7539                                         ptr, f);
7540                         fprintf(f, "\n");
7541                         result = True;
7542                         break;
7543                 }
7544         }
7545
7546         return result;
7547 }
7548
7549 /***************************************************************************
7550  Return info about the requested parameter (given as a string).
7551  Return NULL when the string is not a valid parameter name.
7552 ***************************************************************************/
7553
7554 struct parm_struct *lp_get_parameter(const char *param_name)
7555 {
7556         int num = map_parameter(param_name);
7557
7558         if (num < 0) {
7559                 return NULL;
7560         }
7561
7562         return &parm_table[num];
7563 }
7564
7565 /***************************************************************************
7566  Return info about the next parameter in a service.
7567  snum==GLOBAL_SECTION_SNUM gives the globals.
7568  Return NULL when out of parameters.
7569 ***************************************************************************/
7570
7571 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7572 {
7573         if (snum < 0) {
7574                 /* do the globals */
7575                 for (; parm_table[*i].label; (*i)++) {
7576                         if (parm_table[*i].p_class == P_SEPARATOR)
7577                                 return &parm_table[(*i)++];
7578
7579                         if (!parm_table[*i].ptr
7580                             || (*parm_table[*i].label == '-'))
7581                                 continue;
7582
7583                         if ((*i) > 0
7584                             && (parm_table[*i].ptr ==
7585                                 parm_table[(*i) - 1].ptr))
7586                                 continue;
7587                         
7588                         if (is_default(*i) && !allparameters)
7589                                 continue;
7590
7591                         return &parm_table[(*i)++];
7592                 }
7593         } else {
7594                 struct service *pService = ServicePtrs[snum];
7595
7596                 for (; parm_table[*i].label; (*i)++) {
7597                         if (parm_table[*i].p_class == P_SEPARATOR)
7598                                 return &parm_table[(*i)++];
7599
7600                         if (parm_table[*i].p_class == P_LOCAL &&
7601                             parm_table[*i].ptr &&
7602                             (*parm_table[*i].label != '-') &&
7603                             ((*i) == 0 ||
7604                              (parm_table[*i].ptr !=
7605                               parm_table[(*i) - 1].ptr)))
7606                         {
7607                                 int pdiff =
7608                                         PTR_DIFF(parm_table[*i].ptr,
7609                                                  &sDefault);
7610
7611                                 if (allparameters ||
7612                                     !equal_parameter(parm_table[*i].type,
7613                                                      ((char *)pService) +
7614                                                      pdiff,
7615                                                      ((char *)&sDefault) +
7616                                                      pdiff))
7617                                 {
7618                                         return &parm_table[(*i)++];
7619                                 }
7620                         }
7621                 }
7622         }
7623
7624         return NULL;
7625 }
7626
7627
7628 #if 0
7629 /***************************************************************************
7630  Display the contents of a single copy structure.
7631 ***************************************************************************/
7632 static void dump_copy_map(bool *pcopymap)
7633 {
7634         int i;
7635         if (!pcopymap)
7636                 return;
7637
7638         printf("\n\tNon-Copied parameters:\n");
7639
7640         for (i = 0; parm_table[i].label; i++)
7641                 if (parm_table[i].p_class == P_LOCAL &&
7642                     parm_table[i].ptr && !pcopymap[i] &&
7643                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7644                 {
7645                         printf("\t\t%s\n", parm_table[i].label);
7646                 }
7647 }
7648 #endif
7649
7650 /***************************************************************************
7651  Return TRUE if the passed service number is within range.
7652 ***************************************************************************/
7653
7654 bool lp_snum_ok(int iService)
7655 {
7656         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7657 }
7658
7659 /***************************************************************************
7660  Auto-load some home services.
7661 ***************************************************************************/
7662
7663 static void lp_add_auto_services(char *str)
7664 {
7665         char *s;
7666         char *p;
7667         int homes;
7668         char *saveptr;
7669
7670         if (!str)
7671                 return;
7672
7673         s = SMB_STRDUP(str);
7674         if (!s)
7675                 return;
7676
7677         homes = lp_servicenumber(HOMES_NAME);
7678
7679         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7680              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7681                 char *home;
7682
7683                 if (lp_servicenumber(p) >= 0)
7684                         continue;
7685
7686                 home = get_user_home_dir(talloc_tos(), p);
7687
7688                 if (home && homes >= 0)
7689                         lp_add_home(p, homes, p, home);
7690
7691                 TALLOC_FREE(home);
7692         }
7693         SAFE_FREE(s);
7694 }
7695
7696 /***************************************************************************
7697  Auto-load one printer.
7698 ***************************************************************************/
7699
7700 void lp_add_one_printer(char *name, char *comment)
7701 {
7702         int printers = lp_servicenumber(PRINTERS_NAME);
7703         int i;
7704
7705         if (lp_servicenumber(name) < 0) {
7706                 lp_add_printer(name, printers);
7707                 if ((i = lp_servicenumber(name)) >= 0) {
7708                         string_set(&ServicePtrs[i]->comment, comment);
7709                         ServicePtrs[i]->autoloaded = True;
7710                 }
7711         }
7712 }
7713
7714 /***************************************************************************
7715  Have we loaded a services file yet?
7716 ***************************************************************************/
7717
7718 bool lp_loaded(void)
7719 {
7720         return (bLoaded);
7721 }
7722
7723 /***************************************************************************
7724  Unload unused services.
7725 ***************************************************************************/
7726
7727 void lp_killunused(bool (*snumused) (int))
7728 {
7729         int i;
7730         for (i = 0; i < iNumServices; i++) {
7731                 if (!VALID(i))
7732                         continue;
7733
7734                 /* don't kill autoloaded or usershare services */
7735                 if ( ServicePtrs[i]->autoloaded ||
7736                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7737                         continue;
7738                 }
7739
7740                 if (!snumused || !snumused(i)) {
7741                         free_service_byindex(i);
7742                 }
7743         }
7744 }
7745
7746 /**
7747  * Kill all except autoloaded and usershare services - convenience wrapper
7748  */
7749 void lp_kill_all_services(void)
7750 {
7751         lp_killunused(NULL);
7752 }
7753
7754 /***************************************************************************
7755  Unload a service.
7756 ***************************************************************************/
7757
7758 void lp_killservice(int iServiceIn)
7759 {
7760         if (VALID(iServiceIn)) {
7761                 free_service_byindex(iServiceIn);
7762         }
7763 }
7764
7765 /***************************************************************************
7766  Save the curent values of all global and sDefault parameters into the 
7767  defaults union. This allows swat and testparm to show only the
7768  changed (ie. non-default) parameters.
7769 ***************************************************************************/
7770
7771 static void lp_save_defaults(void)
7772 {
7773         int i;
7774         for (i = 0; parm_table[i].label; i++) {
7775                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7776                         continue;
7777                 switch (parm_table[i].type) {
7778                         case P_LIST:
7779                                 str_list_copy(
7780                                         NULL, &(parm_table[i].def.lvalue),
7781                                         *(const char ***)parm_table[i].ptr);
7782                                 break;
7783                         case P_STRING:
7784                         case P_USTRING:
7785                                 if (parm_table[i].ptr) {
7786                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7787                                 } else {
7788                                         parm_table[i].def.svalue = NULL;
7789                                 }
7790                                 break;
7791                         case P_BOOL:
7792                         case P_BOOLREV:
7793                                 parm_table[i].def.bvalue =
7794                                         *(bool *)parm_table[i].ptr;
7795                                 break;
7796                         case P_CHAR:
7797                                 parm_table[i].def.cvalue =
7798                                         *(char *)parm_table[i].ptr;
7799                                 break;
7800                         case P_INTEGER:
7801                         case P_OCTAL:
7802                         case P_ENUM:
7803                                 parm_table[i].def.ivalue =
7804                                         *(int *)parm_table[i].ptr;
7805                                 break;
7806                         case P_SEP:
7807                                 break;
7808                 }
7809         }
7810         defaults_saved = True;
7811 }
7812
7813 /*******************************************************************
7814  Set the server type we will announce as via nmbd.
7815 ********************************************************************/
7816
7817 static const struct srv_role_tab {
7818         uint32 role;
7819         const char *role_str;
7820 } srv_role_tab [] = {
7821         { ROLE_STANDALONE, "ROLE_STANDALONE" },
7822         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7823         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7824         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7825         { 0, NULL }
7826 };
7827
7828 const char* server_role_str(uint32 role)
7829 {
7830         int i = 0;
7831         for (i=0; srv_role_tab[i].role_str; i++) {
7832                 if (role == srv_role_tab[i].role) {
7833                         return srv_role_tab[i].role_str;
7834                 }
7835         }
7836         return NULL;
7837 }
7838
7839 static void set_server_role(void)
7840 {
7841         server_role = ROLE_STANDALONE;
7842
7843         switch (lp_security()) {
7844                 case SEC_SHARE:
7845                         if (lp_domain_logons())
7846                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7847                         break;
7848                 case SEC_SERVER:
7849                         if (lp_domain_logons())
7850                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7851                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7852                         server_role = ROLE_STANDALONE;
7853                         break;
7854                 case SEC_DOMAIN:
7855                         if (lp_domain_logons()) {
7856                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7857                                 server_role = ROLE_DOMAIN_BDC;
7858                                 break;
7859                         }
7860                         server_role = ROLE_DOMAIN_MEMBER;
7861                         break;
7862                 case SEC_ADS:
7863                         if (lp_domain_logons()) {
7864                                 server_role = ROLE_DOMAIN_PDC;
7865                                 break;
7866                         }
7867                         server_role = ROLE_DOMAIN_MEMBER;
7868                         break;
7869                 case SEC_USER:
7870                         if (lp_domain_logons()) {
7871
7872                                 if (Globals.iDomainMaster) /* auto or yes */ 
7873                                         server_role = ROLE_DOMAIN_PDC;
7874                                 else
7875                                         server_role = ROLE_DOMAIN_BDC;
7876                         }
7877                         break;
7878                 default:
7879                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7880                         break;
7881         }
7882
7883         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7884 }
7885
7886 /***********************************************************
7887  If we should send plaintext/LANMAN passwords in the clinet
7888 ************************************************************/
7889
7890 static void set_allowed_client_auth(void)
7891 {
7892         if (Globals.bClientNTLMv2Auth) {
7893                 Globals.bClientLanManAuth = False;
7894         }
7895         if (!Globals.bClientLanManAuth) {
7896                 Globals.bClientPlaintextAuth = False;
7897         }
7898 }
7899
7900 /***************************************************************************
7901  JRA.
7902  The following code allows smbd to read a user defined share file.
7903  Yes, this is my intent. Yes, I'm comfortable with that...
7904
7905  THE FOLLOWING IS SECURITY CRITICAL CODE.
7906
7907  It washes your clothes, it cleans your house, it guards you while you sleep...
7908  Do not f%^k with it....
7909 ***************************************************************************/
7910
7911 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7912
7913 /***************************************************************************
7914  Check allowed stat state of a usershare file.
7915  Ensure we print out who is dicking with us so the admin can
7916  get their sorry ass fired.
7917 ***************************************************************************/
7918
7919 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
7920 {
7921         if (!S_ISREG(psbuf->st_mode)) {
7922                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7923                         "not a regular file\n",
7924                         fname, (unsigned int)psbuf->st_uid ));
7925                 return False;
7926         }
7927
7928         /* Ensure this doesn't have the other write bit set. */
7929         if (psbuf->st_mode & S_IWOTH) {
7930                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
7931                         "public write. Refusing to allow as a usershare file.\n",
7932                         fname, (unsigned int)psbuf->st_uid ));
7933                 return False;
7934         }
7935
7936         /* Should be 10k or less. */
7937         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
7938                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7939                         "too large (%u) to be a user share file.\n",
7940                         fname, (unsigned int)psbuf->st_uid,
7941                         (unsigned int)psbuf->st_size ));
7942                 return False;
7943         }
7944
7945         return True;
7946 }
7947
7948 /***************************************************************************
7949  Parse the contents of a usershare file.
7950 ***************************************************************************/
7951
7952 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
7953                         SMB_STRUCT_STAT *psbuf,
7954                         const char *servicename,
7955                         int snum,
7956                         char **lines,
7957                         int numlines,
7958                         char **pp_sharepath,
7959                         char **pp_comment,
7960                         SEC_DESC **ppsd,
7961                         bool *pallow_guest)
7962 {
7963         const char **prefixallowlist = lp_usershare_prefix_allow_list();
7964         const char **prefixdenylist = lp_usershare_prefix_deny_list();
7965         int us_vers;
7966         SMB_STRUCT_DIR *dp;
7967         SMB_STRUCT_STAT sbuf;
7968         char *sharepath = NULL;
7969         char *comment = NULL;
7970
7971         *pp_sharepath = NULL;
7972         *pp_comment = NULL;
7973
7974         *pallow_guest = False;
7975
7976         if (numlines < 4) {
7977                 return USERSHARE_MALFORMED_FILE;
7978         }
7979
7980         if (strcmp(lines[0], "#VERSION 1") == 0) {
7981                 us_vers = 1;
7982         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
7983                 us_vers = 2;
7984                 if (numlines < 5) {
7985                         return USERSHARE_MALFORMED_FILE;
7986                 }
7987         } else {
7988                 return USERSHARE_BAD_VERSION;
7989         }
7990
7991         if (strncmp(lines[1], "path=", 5) != 0) {
7992                 return USERSHARE_MALFORMED_PATH;
7993         }
7994
7995         sharepath = talloc_strdup(ctx, &lines[1][5]);
7996         if (!sharepath) {
7997                 return USERSHARE_POSIX_ERR;
7998         }
7999         trim_string(sharepath, " ", " ");
8000
8001         if (strncmp(lines[2], "comment=", 8) != 0) {
8002                 return USERSHARE_MALFORMED_COMMENT_DEF;
8003         }
8004
8005         comment = talloc_strdup(ctx, &lines[2][8]);
8006         if (!comment) {
8007                 return USERSHARE_POSIX_ERR;
8008         }
8009         trim_string(comment, " ", " ");
8010         trim_char(comment, '"', '"');
8011
8012         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8013                 return USERSHARE_MALFORMED_ACL_DEF;
8014         }
8015
8016         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8017                 return USERSHARE_ACL_ERR;
8018         }
8019
8020         if (us_vers == 2) {
8021                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8022                         return USERSHARE_MALFORMED_ACL_DEF;
8023                 }
8024                 if (lines[4][9] == 'y') {
8025                         *pallow_guest = True;
8026                 }
8027         }
8028
8029         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8030                 /* Path didn't change, no checks needed. */
8031                 *pp_sharepath = sharepath;
8032                 *pp_comment = comment;
8033                 return USERSHARE_OK;
8034         }
8035
8036         /* The path *must* be absolute. */
8037         if (sharepath[0] != '/') {
8038                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8039                         servicename, sharepath));
8040                 return USERSHARE_PATH_NOT_ABSOLUTE;
8041         }
8042
8043         /* If there is a usershare prefix deny list ensure one of these paths
8044            doesn't match the start of the user given path. */
8045         if (prefixdenylist) {
8046                 int i;
8047                 for ( i=0; prefixdenylist[i]; i++ ) {
8048                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8049                                 servicename, i, prefixdenylist[i], sharepath ));
8050                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8051                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8052                                         "usershare prefix deny list entries.\n",
8053                                         servicename, sharepath));
8054                                 return USERSHARE_PATH_IS_DENIED;
8055                         }
8056                 }
8057         }
8058
8059         /* If there is a usershare prefix allow list ensure one of these paths
8060            does match the start of the user given path. */
8061
8062         if (prefixallowlist) {
8063                 int i;
8064                 for ( i=0; prefixallowlist[i]; i++ ) {
8065                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8066                                 servicename, i, prefixallowlist[i], sharepath ));
8067                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8068                                 break;
8069                         }
8070                 }
8071                 if (prefixallowlist[i] == NULL) {
8072                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8073                                 "usershare prefix allow list entries.\n",
8074                                 servicename, sharepath));
8075                         return USERSHARE_PATH_NOT_ALLOWED;
8076                 }
8077         }
8078
8079         /* Ensure this is pointing to a directory. */
8080         dp = sys_opendir(sharepath);
8081
8082         if (!dp) {
8083                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8084                         servicename, sharepath));
8085                 return USERSHARE_PATH_NOT_DIRECTORY;
8086         }
8087
8088         /* Ensure the owner of the usershare file has permission to share
8089            this directory. */
8090
8091         if (sys_stat(sharepath, &sbuf) == -1) {
8092                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8093                         servicename, sharepath, strerror(errno) ));
8094                 sys_closedir(dp);
8095                 return USERSHARE_POSIX_ERR;
8096         }
8097
8098         sys_closedir(dp);
8099
8100         if (!S_ISDIR(sbuf.st_mode)) {
8101                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8102                         servicename, sharepath ));
8103                 return USERSHARE_PATH_NOT_DIRECTORY;
8104         }
8105
8106         /* Check if sharing is restricted to owner-only. */
8107         /* psbuf is the stat of the usershare definition file,
8108            sbuf is the stat of the target directory to be shared. */
8109
8110         if (lp_usershare_owner_only()) {
8111                 /* root can share anything. */
8112                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8113                         return USERSHARE_PATH_NOT_ALLOWED;
8114                 }
8115         }
8116
8117         *pp_sharepath = sharepath;
8118         *pp_comment = comment;
8119         return USERSHARE_OK;
8120 }
8121
8122 /***************************************************************************
8123  Deal with a usershare file.
8124  Returns:
8125         >= 0 - snum
8126         -1 - Bad name, invalid contents.
8127            - service name already existed and not a usershare, problem
8128             with permissions to share directory etc.
8129 ***************************************************************************/
8130
8131 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8132 {
8133         SMB_STRUCT_STAT sbuf;
8134         SMB_STRUCT_STAT lsbuf;
8135         char *fname = NULL;
8136         char *sharepath = NULL;
8137         char *comment = NULL;
8138         fstring service_name;
8139         char **lines = NULL;
8140         int numlines = 0;
8141         int fd = -1;
8142         int iService = -1;
8143         TALLOC_CTX *ctx = NULL;
8144         SEC_DESC *psd = NULL;
8145         bool guest_ok = False;
8146
8147         /* Ensure share name doesn't contain invalid characters. */
8148         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8149                 DEBUG(0,("process_usershare_file: share name %s contains "
8150                         "invalid characters (any of %s)\n",
8151                         file_name, INVALID_SHARENAME_CHARS ));
8152                 return -1;
8153         }
8154
8155         fstrcpy(service_name, file_name);
8156
8157         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8158         }
8159
8160         /* Minimize the race condition by doing an lstat before we
8161            open and fstat. Ensure this isn't a symlink link. */
8162
8163         if (sys_lstat(fname, &lsbuf) != 0) {
8164                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8165                         fname, strerror(errno) ));
8166                 SAFE_FREE(fname);
8167                 return -1;
8168         }
8169
8170         /* This must be a regular file, not a symlink, directory or
8171            other strange filetype. */
8172         if (!check_usershare_stat(fname, &lsbuf)) {
8173                 SAFE_FREE(fname);
8174                 return -1;
8175         }
8176
8177         {
8178                 char *canon_name = canonicalize_servicename(service_name);
8179                 TDB_DATA data = dbwrap_fetch_bystring(
8180                         ServiceHash, canon_name, canon_name);
8181
8182                 iService = -1;
8183
8184                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8185                         iService = *(int *)data.dptr;
8186                 }
8187                 TALLOC_FREE(canon_name);
8188         }
8189
8190         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8191                 /* Nothing changed - Mark valid and return. */
8192                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8193                         service_name ));
8194                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8195                 SAFE_FREE(fname);
8196                 return iService;
8197         }
8198
8199         /* Try and open the file read only - no symlinks allowed. */
8200 #ifdef O_NOFOLLOW
8201         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8202 #else
8203         fd = sys_open(fname, O_RDONLY, 0);
8204 #endif
8205
8206         if (fd == -1) {
8207                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8208                         fname, strerror(errno) ));
8209                 SAFE_FREE(fname);
8210                 return -1;
8211         }
8212
8213         /* Now fstat to be *SURE* it's a regular file. */
8214         if (sys_fstat(fd, &sbuf) != 0) {
8215                 close(fd);
8216                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8217                         fname, strerror(errno) ));
8218                 SAFE_FREE(fname);
8219                 return -1;
8220         }
8221
8222         /* Is it the same dev/inode as was lstated ? */
8223         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8224                 close(fd);
8225                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8226                         "Symlink spoofing going on ?\n", fname ));
8227                 SAFE_FREE(fname);
8228                 return -1;
8229         }
8230
8231         /* This must be a regular file, not a symlink, directory or
8232            other strange filetype. */
8233         if (!check_usershare_stat(fname, &sbuf)) {
8234                 SAFE_FREE(fname);
8235                 return -1;
8236         }
8237
8238         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8239
8240         close(fd);
8241         if (lines == NULL) {
8242                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8243                         fname, (unsigned int)sbuf.st_uid ));
8244                 SAFE_FREE(fname);
8245                 return -1;
8246         }
8247
8248         SAFE_FREE(fname);
8249
8250         /* Should we allow printers to be shared... ? */
8251         ctx = talloc_init("usershare_sd_xctx");
8252         if (!ctx) {
8253                 file_lines_free(lines);
8254                 return 1;
8255         }
8256
8257         if (parse_usershare_file(ctx, &sbuf, service_name,
8258                         iService, lines, numlines, &sharepath,
8259                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8260                 talloc_destroy(ctx);
8261                 file_lines_free(lines);
8262                 return -1;
8263         }
8264
8265         file_lines_free(lines);
8266
8267         /* Everything ok - add the service possibly using a template. */
8268         if (iService < 0) {
8269                 const struct service *sp = &sDefault;
8270                 if (snum_template != -1) {
8271                         sp = ServicePtrs[snum_template];
8272                 }
8273
8274                 if ((iService = add_a_service(sp, service_name)) < 0) {
8275                         DEBUG(0, ("process_usershare_file: Failed to add "
8276                                 "new service %s\n", service_name));
8277                         talloc_destroy(ctx);
8278                         return -1;
8279                 }
8280
8281                 /* Read only is controlled by usershare ACL below. */
8282                 ServicePtrs[iService]->bRead_only = False;
8283         }
8284
8285         /* Write the ACL of the new/modified share. */
8286         if (!set_share_security(service_name, psd)) {
8287                  DEBUG(0, ("process_usershare_file: Failed to set share "
8288                         "security for user share %s\n",
8289                         service_name ));
8290                 lp_remove_service(iService);
8291                 talloc_destroy(ctx);
8292                 return -1;
8293         }
8294
8295         /* If from a template it may be marked invalid. */
8296         ServicePtrs[iService]->valid = True;
8297
8298         /* Set the service as a valid usershare. */
8299         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8300
8301         /* Set guest access. */
8302         if (lp_usershare_allow_guests()) {
8303                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8304         }
8305
8306         /* And note when it was loaded. */
8307         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8308         string_set(&ServicePtrs[iService]->szPath, sharepath);
8309         string_set(&ServicePtrs[iService]->comment, comment);
8310
8311         talloc_destroy(ctx);
8312
8313         return iService;
8314 }
8315
8316 /***************************************************************************
8317  Checks if a usershare entry has been modified since last load.
8318 ***************************************************************************/
8319
8320 static bool usershare_exists(int iService, time_t *last_mod)
8321 {
8322         SMB_STRUCT_STAT lsbuf;
8323         const char *usersharepath = Globals.szUsersharePath;
8324         char *fname;
8325
8326         if (asprintf(&fname, "%s/%s",
8327                                 usersharepath,
8328                                 ServicePtrs[iService]->szService) < 0) {
8329                 return false;
8330         }
8331
8332         if (sys_lstat(fname, &lsbuf) != 0) {
8333                 SAFE_FREE(fname);
8334                 return false;
8335         }
8336
8337         if (!S_ISREG(lsbuf.st_mode)) {
8338                 SAFE_FREE(fname);
8339                 return false;
8340         }
8341
8342         SAFE_FREE(fname);
8343         *last_mod = lsbuf.st_mtime;
8344         return true;
8345 }
8346
8347 /***************************************************************************
8348  Load a usershare service by name. Returns a valid servicenumber or -1.
8349 ***************************************************************************/
8350
8351 int load_usershare_service(const char *servicename)
8352 {
8353         SMB_STRUCT_STAT sbuf;
8354         const char *usersharepath = Globals.szUsersharePath;
8355         int max_user_shares = Globals.iUsershareMaxShares;
8356         int snum_template = -1;
8357
8358         if (*usersharepath == 0 ||  max_user_shares == 0) {
8359                 return -1;
8360         }
8361
8362         if (sys_stat(usersharepath, &sbuf) != 0) {
8363                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8364                         usersharepath, strerror(errno) ));
8365                 return -1;
8366         }
8367
8368         if (!S_ISDIR(sbuf.st_mode)) {
8369                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8370                         usersharepath ));
8371                 return -1;
8372         }
8373
8374         /*
8375          * This directory must be owned by root, and have the 't' bit set.
8376          * It also must not be writable by "other".
8377          */
8378
8379 #ifdef S_ISVTX
8380         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8381 #else
8382         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8383 #endif
8384                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8385                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8386                         usersharepath ));
8387                 return -1;
8388         }
8389
8390         /* Ensure the template share exists if it's set. */
8391         if (Globals.szUsershareTemplateShare[0]) {
8392                 /* We can't use lp_servicenumber here as we are recommending that
8393                    template shares have -valid=False set. */
8394                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8395                         if (ServicePtrs[snum_template]->szService &&
8396                                         strequal(ServicePtrs[snum_template]->szService,
8397                                                 Globals.szUsershareTemplateShare)) {
8398                                 break;
8399                         }
8400                 }
8401
8402                 if (snum_template == -1) {
8403                         DEBUG(0,("load_usershare_service: usershare template share %s "
8404                                 "does not exist.\n",
8405                                 Globals.szUsershareTemplateShare ));
8406                         return -1;
8407                 }
8408         }
8409
8410         return process_usershare_file(usersharepath, servicename, snum_template);
8411 }
8412
8413 /***************************************************************************
8414  Load all user defined shares from the user share directory.
8415  We only do this if we're enumerating the share list.
8416  This is the function that can delete usershares that have
8417  been removed.
8418 ***************************************************************************/
8419
8420 int load_usershare_shares(void)
8421 {
8422         SMB_STRUCT_DIR *dp;
8423         SMB_STRUCT_STAT sbuf;
8424         SMB_STRUCT_DIRENT *de;
8425         int num_usershares = 0;
8426         int max_user_shares = Globals.iUsershareMaxShares;
8427         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8428         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8429         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8430         int iService;
8431         int snum_template = -1;
8432         const char *usersharepath = Globals.szUsersharePath;
8433         int ret = lp_numservices();
8434
8435         if (max_user_shares == 0 || *usersharepath == '\0') {
8436                 return lp_numservices();
8437         }
8438
8439         if (sys_stat(usersharepath, &sbuf) != 0) {
8440                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8441                         usersharepath, strerror(errno) ));
8442                 return ret;
8443         }
8444
8445         /*
8446          * This directory must be owned by root, and have the 't' bit set.
8447          * It also must not be writable by "other".
8448          */
8449
8450 #ifdef S_ISVTX
8451         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8452 #else
8453         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8454 #endif
8455                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8456                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8457                         usersharepath ));
8458                 return ret;
8459         }
8460
8461         /* Ensure the template share exists if it's set. */
8462         if (Globals.szUsershareTemplateShare[0]) {
8463                 /* We can't use lp_servicenumber here as we are recommending that
8464                    template shares have -valid=False set. */
8465                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8466                         if (ServicePtrs[snum_template]->szService &&
8467                                         strequal(ServicePtrs[snum_template]->szService,
8468                                                 Globals.szUsershareTemplateShare)) {
8469                                 break;
8470                         }
8471                 }
8472
8473                 if (snum_template == -1) {
8474                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8475                                 "does not exist.\n",
8476                                 Globals.szUsershareTemplateShare ));
8477                         return ret;
8478                 }
8479         }
8480
8481         /* Mark all existing usershares as pending delete. */
8482         for (iService = iNumServices - 1; iService >= 0; iService--) {
8483                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8484                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8485                 }
8486         }
8487
8488         dp = sys_opendir(usersharepath);
8489         if (!dp) {
8490                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8491                         usersharepath, strerror(errno) ));
8492                 return ret;
8493         }
8494
8495         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8496                         (de = sys_readdir(dp));
8497                         num_dir_entries++ ) {
8498                 int r;
8499                 const char *n = de->d_name;
8500
8501                 /* Ignore . and .. */
8502                 if (*n == '.') {
8503                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8504                                 continue;
8505                         }
8506                 }
8507
8508                 if (n[0] == ':') {
8509                         /* Temporary file used when creating a share. */
8510                         num_tmp_dir_entries++;
8511                 }
8512
8513                 /* Allow 20% tmp entries. */
8514                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8515                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8516                                 "in directory %s\n",
8517                                 num_tmp_dir_entries, usersharepath));
8518                         break;
8519                 }
8520
8521                 r = process_usershare_file(usersharepath, n, snum_template);
8522                 if (r == 0) {
8523                         /* Update the services count. */
8524                         num_usershares++;
8525                         if (num_usershares >= max_user_shares) {
8526                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8527                                         "on file %s in directory %s\n",
8528                                         n, usersharepath ));
8529                                 break;
8530                         }
8531                 } else if (r == -1) {
8532                         num_bad_dir_entries++;
8533                 }
8534
8535                 /* Allow 20% bad entries. */
8536                 if (num_bad_dir_entries > allowed_bad_entries) {
8537                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8538                                 "in directory %s\n",
8539                                 num_bad_dir_entries, usersharepath));
8540                         break;
8541                 }
8542
8543                 /* Allow 20% bad entries. */
8544                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8545                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8546                         "in directory %s\n",
8547                         num_dir_entries, usersharepath));
8548                         break;
8549                 }
8550         }
8551
8552         sys_closedir(dp);
8553
8554         /* Sweep through and delete any non-refreshed usershares that are
8555            not currently in use. */
8556         for (iService = iNumServices - 1; iService >= 0; iService--) {
8557                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8558                         if (conn_snum_used(iService)) {
8559                                 continue;
8560                         }
8561                         /* Remove from the share ACL db. */
8562                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8563                                 lp_servicename(iService) ));
8564                         delete_share_security(lp_servicename(iService));
8565                         free_service_byindex(iService);
8566                 }
8567         }
8568
8569         return lp_numservices();
8570 }
8571
8572 /********************************************************
8573  Destroy global resources allocated in this file
8574 ********************************************************/
8575
8576 void gfree_loadparm(void)
8577 {
8578         struct file_lists *f;
8579         struct file_lists *next;
8580         int i;
8581
8582         /* Free the file lists */
8583
8584         f = file_lists;
8585         while( f ) {
8586                 next = f->next;
8587                 SAFE_FREE( f->name );
8588                 SAFE_FREE( f->subfname );
8589                 SAFE_FREE( f );
8590                 f = next;
8591         }
8592
8593         /* Free resources allocated to services */
8594
8595         for ( i = 0; i < iNumServices; i++ ) {
8596                 if ( VALID(i) ) {
8597                         free_service_byindex(i);
8598                 }
8599         }
8600
8601         SAFE_FREE( ServicePtrs );
8602         iNumServices = 0;
8603
8604         /* Now release all resources allocated to global
8605            parameters and the default service */
8606
8607         for (i = 0; parm_table[i].label; i++) 
8608         {
8609                 if ( parm_table[i].type == P_STRING 
8610                         || parm_table[i].type == P_USTRING ) 
8611                 {
8612                         string_free( (char**)parm_table[i].ptr );
8613                 }
8614                 else if (parm_table[i].type == P_LIST) {
8615                         TALLOC_FREE( *((char***)parm_table[i].ptr) );
8616                 }
8617         }
8618 }
8619
8620
8621 /***************************************************************************
8622  Allow client apps to specify that they are a client
8623 ***************************************************************************/
8624 void lp_set_in_client(bool b)
8625 {
8626     in_client = b;
8627 }
8628
8629
8630 /***************************************************************************
8631  Determine if we're running in a client app
8632 ***************************************************************************/
8633 bool lp_is_in_client(void)
8634 {
8635     return in_client;
8636 }
8637
8638
8639
8640
8641 /***************************************************************************
8642  Load the services array from the services file. Return True on success, 
8643  False on failure.
8644 ***************************************************************************/
8645
8646 bool lp_load(const char *pszFname,
8647              bool global_only,
8648              bool save_defaults,
8649              bool add_ipc,
8650              bool initialize_globals)
8651 {
8652         char *n2 = NULL;
8653         bool bRetval;
8654         param_opt_struct *data, *pdata;
8655
8656         bRetval = False;
8657
8658         DEBUG(3, ("lp_load: refreshing parameters\n"));
8659
8660         bInGlobalSection = True;
8661         bGlobalOnly = global_only;
8662
8663         init_globals(! initialize_globals);
8664         debug_init();
8665
8666         if (save_defaults) {
8667                 init_locals();
8668                 lp_save_defaults();
8669         }
8670
8671         if (Globals.param_opt != NULL) {
8672                 data = Globals.param_opt;
8673                 while (data) {
8674                         string_free(&data->key);
8675                         string_free(&data->value);
8676                         TALLOC_FREE(data->list);
8677                         pdata = data->next;
8678                         SAFE_FREE(data);
8679                         data = pdata;
8680                 }
8681                 Globals.param_opt = NULL;
8682         }
8683
8684         if (lp_config_backend_is_file()) {
8685                 n2 = alloc_sub_basic(get_current_username(),
8686                                         current_user_info.domain,
8687                                         pszFname);
8688                 if (!n2) {
8689                         smb_panic("lp_load: out of memory");
8690                 }
8691
8692                 add_to_file_list(pszFname, n2);
8693
8694                 /* We get sections first, so have to start 'behind' to make up */
8695                 iServiceIndex = -1;
8696                 bRetval = pm_process(n2, do_section, do_parameter);
8697                 SAFE_FREE(n2);
8698
8699                 /* finish up the last section */
8700                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8701                 if (bRetval) {
8702                         if (iServiceIndex >= 0) {
8703                                 bRetval = service_ok(iServiceIndex);
8704                         }
8705                 }
8706
8707                 if (lp_config_backend_is_registry()) {
8708                         /* config backend changed to registry in config file */
8709                         /*
8710                          * We need to use this extra global variable here to
8711                          * survive restart: init_globals uses this as a default
8712                          * for ConfigBackend. Otherwise, init_globals would
8713                          *  send us into an endless loop here.
8714                          */
8715                         config_backend = CONFIG_BACKEND_REGISTRY;
8716                         /* start over */
8717                         DEBUG(1, ("lp_load: changing to config backend "
8718                                   "registry\n"));
8719                         init_globals(false);
8720                         lp_kill_all_services();
8721                         return lp_load(pszFname, global_only, save_defaults,
8722                                        add_ipc, initialize_globals);
8723                 }
8724         } else if (lp_config_backend_is_registry()) {
8725                 bRetval = process_registry_globals(do_parameter);
8726         } else {
8727                 DEBUG(0, ("Illegal config  backend given: %d\n",
8728                           lp_config_backend()));
8729                 bRetval = false;
8730         }
8731
8732         lp_add_auto_services(lp_auto_services());
8733
8734         if (add_ipc) {
8735                 /* When 'restrict anonymous = 2' guest connections to ipc$
8736                    are denied */
8737                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8738                 if ( lp_enable_asu_support() ) {
8739                         lp_add_ipc("ADMIN$", false);
8740                 }
8741         }
8742
8743         set_server_role();
8744         set_default_server_announce_type();
8745         set_allowed_client_auth();
8746
8747         bLoaded = True;
8748
8749         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8750         /* if bWINSsupport is true and we are in the client            */
8751         if (lp_is_in_client() && Globals.bWINSsupport) {
8752                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8753         }
8754
8755         init_iconv();
8756
8757         return (bRetval);
8758 }
8759
8760 /***************************************************************************
8761  Reset the max number of services.
8762 ***************************************************************************/
8763
8764 void lp_resetnumservices(void)
8765 {
8766         iNumServices = 0;
8767 }
8768
8769 /***************************************************************************
8770  Return the max number of services.
8771 ***************************************************************************/
8772
8773 int lp_numservices(void)
8774 {
8775         return (iNumServices);
8776 }
8777
8778 /***************************************************************************
8779 Display the contents of the services array in human-readable form.
8780 ***************************************************************************/
8781
8782 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8783 {
8784         int iService;
8785
8786         if (show_defaults)
8787                 defaults_saved = False;
8788
8789         dump_globals(f);
8790
8791         dump_a_service(&sDefault, f);
8792
8793         for (iService = 0; iService < maxtoprint; iService++) {
8794                 fprintf(f,"\n");
8795                 lp_dump_one(f, show_defaults, iService);
8796         }
8797 }
8798
8799 /***************************************************************************
8800 Display the contents of one service in human-readable form.
8801 ***************************************************************************/
8802
8803 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8804 {
8805         if (VALID(snum)) {
8806                 if (ServicePtrs[snum]->szService[0] == '\0')
8807                         return;
8808                 dump_a_service(ServicePtrs[snum], f);
8809         }
8810 }
8811
8812 /***************************************************************************
8813 Return the number of the service with the given name, or -1 if it doesn't
8814 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8815 getservicebyname()! This works ONLY if all services have been loaded, and
8816 does not copy the found service.
8817 ***************************************************************************/
8818
8819 int lp_servicenumber(const char *pszServiceName)
8820 {
8821         int iService;
8822         fstring serviceName;
8823         
8824         if (!pszServiceName) {
8825                 return GLOBAL_SECTION_SNUM;
8826         }
8827         
8828         for (iService = iNumServices - 1; iService >= 0; iService--) {
8829                 if (VALID(iService) && ServicePtrs[iService]->szService) {
8830                         /*
8831                          * The substitution here is used to support %U is
8832                          * service names
8833                          */
8834                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
8835                         standard_sub_basic(get_current_username(),
8836                                            current_user_info.domain,
8837                                            serviceName,sizeof(serviceName));
8838                         if (strequal(serviceName, pszServiceName)) {
8839                                 break;
8840                         }
8841                 }
8842         }
8843
8844         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8845                 time_t last_mod;
8846
8847                 if (!usershare_exists(iService, &last_mod)) {
8848                         /* Remove the share security tdb entry for it. */
8849                         delete_share_security(lp_servicename(iService));
8850                         /* Remove it from the array. */
8851                         free_service_byindex(iService);
8852                         /* Doesn't exist anymore. */
8853                         return GLOBAL_SECTION_SNUM;
8854                 }
8855
8856                 /* Has it been modified ? If so delete and reload. */
8857                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8858                         /* Remove it from the array. */
8859                         free_service_byindex(iService);
8860                         /* and now reload it. */
8861                         iService = load_usershare_service(pszServiceName);
8862                 }
8863         }
8864
8865         if (iService < 0) {
8866                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8867                 return GLOBAL_SECTION_SNUM;
8868         }
8869
8870         return (iService);
8871 }
8872
8873 bool share_defined(const char *service_name)
8874 {
8875         return (lp_servicenumber(service_name) != -1);
8876 }
8877
8878 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
8879                                       const char *sharename)
8880 {
8881         struct share_params *result;
8882         char *sname;
8883         int snum;
8884
8885         if (!(sname = SMB_STRDUP(sharename))) {
8886                 return NULL;
8887         }
8888
8889         snum = find_service(sname);
8890         SAFE_FREE(sname);
8891
8892         if (snum < 0) {
8893                 return NULL;
8894         }
8895
8896         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
8897                 DEBUG(0, ("talloc failed\n"));
8898                 return NULL;
8899         }
8900
8901         result->service = snum;
8902         return result;
8903 }
8904
8905 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
8906 {
8907         struct share_iterator *result;
8908
8909         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
8910                 DEBUG(0, ("talloc failed\n"));
8911                 return NULL;
8912         }
8913
8914         result->next_id = 0;
8915         return result;
8916 }
8917
8918 struct share_params *next_share(struct share_iterator *list)
8919 {
8920         struct share_params *result;
8921
8922         while (!lp_snum_ok(list->next_id) &&
8923                (list->next_id < lp_numservices())) {
8924                 list->next_id += 1;
8925         }
8926
8927         if (list->next_id >= lp_numservices()) {
8928                 return NULL;
8929         }
8930
8931         if (!(result = TALLOC_P(list, struct share_params))) {
8932                 DEBUG(0, ("talloc failed\n"));
8933                 return NULL;
8934         }
8935
8936         result->service = list->next_id;
8937         list->next_id += 1;
8938         return result;
8939 }
8940
8941 struct share_params *next_printer(struct share_iterator *list)
8942 {
8943         struct share_params *result;
8944
8945         while ((result = next_share(list)) != NULL) {
8946                 if (lp_print_ok(result->service)) {
8947                         break;
8948                 }
8949         }
8950         return result;
8951 }
8952
8953 /*
8954  * This is a hack for a transition period until we transformed all code from
8955  * service numbers to struct share_params.
8956  */
8957
8958 struct share_params *snum2params_static(int snum)
8959 {
8960         static struct share_params result;
8961         result.service = snum;
8962         return &result;
8963 }
8964
8965 /*******************************************************************
8966  A useful volume label function. 
8967 ********************************************************************/
8968
8969 const char *volume_label(int snum)
8970 {
8971         char *ret;
8972         const char *label = lp_volume(snum);
8973         if (!*label) {
8974                 label = lp_servicename(snum);
8975         }
8976                 
8977         /* This returns a 33 byte guarenteed null terminated string. */
8978         ret = talloc_strndup(talloc_tos(), label, 32);
8979         if (!ret) {
8980                 return "";
8981         }               
8982         return ret;
8983 }
8984
8985 /*******************************************************************
8986  Set the server type we will announce as via nmbd.
8987 ********************************************************************/
8988
8989 static void set_default_server_announce_type(void)
8990 {
8991         default_server_announce = 0;
8992         default_server_announce |= SV_TYPE_WORKSTATION;
8993         default_server_announce |= SV_TYPE_SERVER;
8994         default_server_announce |= SV_TYPE_SERVER_UNIX;
8995
8996         /* note that the flag should be set only if we have a 
8997            printer service but nmbd doesn't actually load the 
8998            services so we can't tell   --jerry */
8999
9000         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9001
9002         switch (lp_announce_as()) {
9003                 case ANNOUNCE_AS_NT_SERVER:
9004                         default_server_announce |= SV_TYPE_SERVER_NT;
9005                         /* fall through... */
9006                 case ANNOUNCE_AS_NT_WORKSTATION:
9007                         default_server_announce |= SV_TYPE_NT;
9008                         break;
9009                 case ANNOUNCE_AS_WIN95:
9010                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9011                         break;
9012                 case ANNOUNCE_AS_WFW:
9013                         default_server_announce |= SV_TYPE_WFW;
9014                         break;
9015                 default:
9016                         break;
9017         }
9018
9019         switch (lp_server_role()) {
9020                 case ROLE_DOMAIN_MEMBER:
9021                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9022                         break;
9023                 case ROLE_DOMAIN_PDC:
9024                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9025                         break;
9026                 case ROLE_DOMAIN_BDC:
9027                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9028                         break;
9029                 case ROLE_STANDALONE:
9030                 default:
9031                         break;
9032         }
9033         if (lp_time_server())
9034                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9035
9036         if (lp_host_msdfs())
9037                 default_server_announce |= SV_TYPE_DFS_SERVER;
9038 }
9039
9040 /***********************************************************
9041  returns role of Samba server
9042 ************************************************************/
9043
9044 int lp_server_role(void)
9045 {
9046         return server_role;
9047 }
9048
9049 /***********************************************************
9050  If we are PDC then prefer us as DMB
9051 ************************************************************/
9052
9053 bool lp_domain_master(void)
9054 {
9055         if (Globals.iDomainMaster == Auto)
9056                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9057
9058         return (bool)Globals.iDomainMaster;
9059 }
9060
9061 /***********************************************************
9062  If we are DMB then prefer us as LMB
9063 ************************************************************/
9064
9065 bool lp_preferred_master(void)
9066 {
9067         if (Globals.iPreferredMaster == Auto)
9068                 return (lp_local_master() && lp_domain_master());
9069
9070         return (bool)Globals.iPreferredMaster;
9071 }
9072
9073 /*******************************************************************
9074  Remove a service.
9075 ********************************************************************/
9076
9077 void lp_remove_service(int snum)
9078 {
9079         ServicePtrs[snum]->valid = False;
9080         invalid_services[num_invalid_services++] = snum;
9081 }
9082
9083 /*******************************************************************
9084  Copy a service.
9085 ********************************************************************/
9086
9087 void lp_copy_service(int snum, const char *new_name)
9088 {
9089         do_section(new_name);
9090         if (snum >= 0) {
9091                 snum = lp_servicenumber(new_name);
9092                 if (snum >= 0)
9093                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9094         }
9095 }
9096
9097
9098 /*******************************************************************
9099  Get the default server type we will announce as via nmbd.
9100 ********************************************************************/
9101
9102 int lp_default_server_announce(void)
9103 {
9104         return default_server_announce;
9105 }
9106
9107 /*******************************************************************
9108  Split the announce version into major and minor numbers.
9109 ********************************************************************/
9110
9111 int lp_major_announce_version(void)
9112 {
9113         static bool got_major = False;
9114         static int major_version = DEFAULT_MAJOR_VERSION;
9115         char *vers;
9116         char *p;
9117
9118         if (got_major)
9119                 return major_version;
9120
9121         got_major = True;
9122         if ((vers = lp_announce_version()) == NULL)
9123                 return major_version;
9124
9125         if ((p = strchr_m(vers, '.')) == 0)
9126                 return major_version;
9127
9128         *p = '\0';
9129         major_version = atoi(vers);
9130         return major_version;
9131 }
9132
9133 int lp_minor_announce_version(void)
9134 {
9135         static bool got_minor = False;
9136         static int minor_version = DEFAULT_MINOR_VERSION;
9137         char *vers;
9138         char *p;
9139
9140         if (got_minor)
9141                 return minor_version;
9142
9143         got_minor = True;
9144         if ((vers = lp_announce_version()) == NULL)
9145                 return minor_version;
9146
9147         if ((p = strchr_m(vers, '.')) == 0)
9148                 return minor_version;
9149
9150         p++;
9151         minor_version = atoi(p);
9152         return minor_version;
9153 }
9154
9155 /***********************************************************
9156  Set the global name resolution order (used in smbclient).
9157 ************************************************************/
9158
9159 void lp_set_name_resolve_order(const char *new_order)
9160 {
9161         string_set(&Globals.szNameResolveOrder, new_order);
9162 }
9163
9164 const char *lp_printername(int snum)
9165 {
9166         const char *ret = _lp_printername(snum);
9167         if (ret == NULL || (ret != NULL && *ret == '\0'))
9168                 ret = lp_const_servicename(snum);
9169
9170         return ret;
9171 }
9172
9173
9174 /***********************************************************
9175  Allow daemons such as winbindd to fix their logfile name.
9176 ************************************************************/
9177
9178 void lp_set_logfile(const char *name)
9179 {
9180         string_set(&Globals.szLogFile, name);
9181         debug_set_logfile(name);
9182 }
9183
9184 /*******************************************************************
9185  Return the max print jobs per queue.
9186 ********************************************************************/
9187
9188 int lp_maxprintjobs(int snum)
9189 {
9190         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9191         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9192                 maxjobs = PRINT_MAX_JOBID - 1;
9193
9194         return maxjobs;
9195 }
9196
9197 const char *lp_printcapname(void)
9198 {
9199         if ((Globals.szPrintcapname != NULL) &&
9200             (Globals.szPrintcapname[0] != '\0'))
9201                 return Globals.szPrintcapname;
9202
9203         if (sDefault.iPrinting == PRINT_CUPS) {
9204 #ifdef HAVE_CUPS
9205                 return "cups";
9206 #else
9207                 return "lpstat";
9208 #endif
9209         }
9210
9211         if (sDefault.iPrinting == PRINT_BSD)
9212                 return "/etc/printcap";
9213
9214         return PRINTCAP_NAME;
9215 }
9216
9217 /*******************************************************************
9218  Ensure we don't use sendfile if server smb signing is active.
9219 ********************************************************************/
9220
9221 static uint32 spoolss_state;
9222
9223 bool lp_disable_spoolss( void )
9224 {
9225         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9226                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9227
9228         return spoolss_state == SVCCTL_STOPPED ? True : False;
9229 }
9230
9231 void lp_set_spoolss_state( uint32 state )
9232 {
9233         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9234
9235         spoolss_state = state;
9236 }
9237
9238 uint32 lp_get_spoolss_state( void )
9239 {
9240         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9241 }
9242
9243 /*******************************************************************
9244  Ensure we don't use sendfile if server smb signing is active.
9245 ********************************************************************/
9246
9247 bool lp_use_sendfile(int snum)
9248 {
9249         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9250         if (Protocol < PROTOCOL_NT1) {
9251                 return False;
9252         }
9253         return (_lp_use_sendfile(snum) &&
9254                         (get_remote_arch() != RA_WIN95) &&
9255                         !srv_is_signing_active());
9256 }
9257
9258 /*******************************************************************
9259  Turn off sendfile if we find the underlying OS doesn't support it.
9260 ********************************************************************/
9261
9262 void set_use_sendfile(int snum, bool val)
9263 {
9264         if (LP_SNUM_OK(snum))
9265                 ServicePtrs[snum]->bUseSendfile = val;
9266         else
9267                 sDefault.bUseSendfile = val;
9268 }
9269
9270 /*******************************************************************
9271  Turn off storing DOS attributes if this share doesn't support it.
9272 ********************************************************************/
9273
9274 void set_store_dos_attributes(int snum, bool val)
9275 {
9276         if (!LP_SNUM_OK(snum))
9277                 return;
9278         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9279 }
9280
9281 void lp_set_mangling_method(const char *new_method)
9282 {
9283         string_set(&Globals.szManglingMethod, new_method);
9284 }
9285
9286 /*******************************************************************
9287  Global state for POSIX pathname processing.
9288 ********************************************************************/
9289
9290 static bool posix_pathnames;
9291
9292 bool lp_posix_pathnames(void)
9293 {
9294         return posix_pathnames;
9295 }
9296
9297 /*******************************************************************
9298  Change everything needed to ensure POSIX pathname processing (currently
9299  not much).
9300 ********************************************************************/
9301
9302 void lp_set_posix_pathnames(void)
9303 {
9304         posix_pathnames = True;
9305 }
9306
9307 /*******************************************************************
9308  Global state for POSIX lock processing - CIFS unix extensions.
9309 ********************************************************************/
9310
9311 bool posix_default_lock_was_set;
9312 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9313
9314 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9315 {
9316         if (posix_default_lock_was_set) {
9317                 return posix_cifsx_locktype;
9318         } else {
9319                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9320         }
9321 }
9322
9323 /*******************************************************************
9324 ********************************************************************/
9325
9326 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9327 {
9328         posix_default_lock_was_set = True;
9329         posix_cifsx_locktype = val;
9330 }
9331
9332 int lp_min_receive_file_size(void)
9333 {
9334         if (Globals.iminreceivefile < 0) {
9335                 return 0;
9336         }
9337         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9338 }