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