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