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