Revert "Wrap security_token_has_privilege() with a check for lp_enable_privileges...
[kai/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56 #include "lib/smbconf/smbconf.h"
57 #include "lib/smbconf/smbconf_init.h"
58 #include "lib/smbconf/smbconf_reg.h"
59
60 #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 = NULL;
4987         for (entry = stored_options; entry != NULL; entry = entry->next) {
4988                 if (strcmp(pszParmName, entry->label) == 0) {
4989                         DLIST_REMOVE(stored_options, entry);
4990                         talloc_free(entry);
4991                         break;
4992                 }
4993         }
4994
4995         entry = talloc(NULL, struct lp_stored_option);
4996         if (!entry) {
4997                 return false;
4998         }
4999
5000         entry->label = talloc_strdup(entry, pszParmName);
5001         if (!entry->label) {
5002                 talloc_free(entry);
5003                 return false;
5004         }
5005
5006         entry->value = talloc_strdup(entry, pszParmValue);
5007         if (!entry->value) {
5008                 talloc_free(entry);
5009                 return false;
5010         }
5011
5012         DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5013
5014         return true;
5015 }
5016
5017 static bool apply_lp_set_cmdline(void)
5018 {
5019         struct lp_stored_option *entry = NULL;
5020         for (entry = stored_options; entry != NULL; entry = entry->next) {
5021                 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5022                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5023                                   entry->label, entry->value));
5024                         return false;
5025                 }
5026         }
5027         return true;
5028 }
5029
5030 /***************************************************************************
5031  Initialise the global parameter structure.
5032 ***************************************************************************/
5033
5034 static void init_globals(bool reinit_globals)
5035 {
5036         static bool done_init = False;
5037         char *s = NULL;
5038         int i;
5039
5040         /* If requested to initialize only once and we've already done it... */
5041         if (!reinit_globals && done_init) {
5042                 /* ... then we have nothing more to do */
5043                 return;
5044         }
5045
5046         if (!done_init) {
5047                 /* The logfile can be set before this is invoked. Free it if so. */
5048                 if (Globals.szLogFile != NULL) {
5049                         string_free(&Globals.szLogFile);
5050                         Globals.szLogFile = NULL;
5051                 }
5052                 done_init = True;
5053         } else {
5054                 free_global_parameters();
5055         }
5056
5057         /* This memset and the free_global_parameters() above will
5058          * wipe out smb.conf options set with lp_set_cmdline().  The
5059          * apply_lp_set_cmdline() call puts these values back in the
5060          * table once the defaults are set */
5061         memset((void *)&Globals, '\0', sizeof(Globals));
5062
5063         for (i = 0; parm_table[i].label; i++) {
5064                 if ((parm_table[i].type == P_STRING ||
5065                      parm_table[i].type == P_USTRING) &&
5066                     parm_table[i].ptr)
5067                 {
5068                         string_set((char **)parm_table[i].ptr, "");
5069                 }
5070         }
5071
5072         string_set(&sDefault.fstype, FSTYPE_STRING);
5073         string_set(&sDefault.szPrintjobUsername, "%U");
5074
5075         init_printer_values(&sDefault);
5076
5077
5078         DEBUG(3, ("Initialising global parameters\n"));
5079
5080         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5081         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5082
5083         /* use the new 'hash2' method by default, with a prefix of 1 */
5084         string_set(&Globals.szManglingMethod, "hash2");
5085         Globals.mangle_prefix = 1;
5086
5087         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5088
5089         /* using UTF8 by default allows us to support all chars */
5090         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5091
5092 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5093         /* If the system supports nl_langinfo(), try to grab the value
5094            from the user's locale */
5095         string_set(&Globals.display_charset, "LOCALE");
5096 #else
5097         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5098 #endif
5099
5100         /* Use codepage 850 as a default for the dos character set */
5101         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5102
5103         /*
5104          * Allow the default PASSWD_CHAT to be overridden in local.h.
5105          */
5106         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5107
5108         set_global_myname(myhostname());
5109         string_set(&Globals.szNetbiosName,global_myname());
5110
5111         set_global_myworkgroup(WORKGROUP);
5112         string_set(&Globals.szWorkgroup, lp_workgroup());
5113
5114         string_set(&Globals.szPasswdProgram, "");
5115         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5116         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5117         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5118         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5119         string_set(&Globals.szSocketAddress, "0.0.0.0");
5120         /*
5121          * By default support explicit binding to broadcast
5122          * addresses.
5123          */
5124         Globals.bNmbdBindExplicitBroadcast = true;
5125
5126         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5127                 smb_panic("init_globals: ENOMEM");
5128         }
5129         string_set(&Globals.szServerString, s);
5130         SAFE_FREE(s);
5131         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5132                         DEFAULT_MINOR_VERSION) < 0) {
5133                 smb_panic("init_globals: ENOMEM");
5134         }
5135         string_set(&Globals.szAnnounceVersion, s);
5136         SAFE_FREE(s);
5137 #ifdef DEVELOPER
5138         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5139 #endif
5140
5141         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5142
5143         string_set(&Globals.szLogonDrive, "");
5144         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5145         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5146         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5147
5148         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5149         string_set(&Globals.szPasswordServer, "*");
5150
5151         Globals.AlgorithmicRidBase = BASE_RID;
5152
5153         Globals.bLoadPrinters = True;
5154         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
5155
5156         Globals.ConfigBackend = config_backend;
5157
5158         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5159         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5160         Globals.max_xmit = 0x4104;
5161         Globals.max_mux = 50;   /* This is *needed* for profile support. */
5162         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
5163         Globals.bDisableSpoolss = False;
5164         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5165         Globals.pwordlevel = 0;
5166         Globals.unamelevel = 0;
5167         Globals.deadtime = 0;
5168         Globals.getwd_cache = true;
5169         Globals.bLargeReadwrite = True;
5170         Globals.max_log_size = 5000;
5171         Globals.max_open_files = max_open_files();
5172         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5173         Globals.maxprotocol = PROTOCOL_NT1;
5174         Globals.minprotocol = PROTOCOL_CORE;
5175         Globals.security = SEC_USER;
5176         Globals.paranoid_server_security = True;
5177         Globals.bEncryptPasswords = True;
5178         Globals.bUpdateEncrypt = False;
5179         Globals.clientSchannel = Auto;
5180         Globals.serverSchannel = Auto;
5181         Globals.bReadRaw = True;
5182         Globals.bWriteRaw = True;
5183         Globals.bNullPasswords = False;
5184         Globals.bObeyPamRestrictions = False;
5185         Globals.syslog = 1;
5186         Globals.bSyslogOnly = False;
5187         Globals.bTimestampLogs = True;
5188         string_set(&Globals.szLogLevel, "0");
5189         Globals.bDebugPrefixTimestamp = False;
5190         Globals.bDebugHiresTimestamp = true;
5191         Globals.bDebugPid = False;
5192         Globals.bDebugUid = False;
5193         Globals.bDebugClass = False;
5194         Globals.bEnableCoreFiles = True;
5195         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
5196         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
5197         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
5198         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
5199         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
5200         Globals.lm_interval = 60;
5201         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5202 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5203         Globals.bNISHomeMap = False;
5204 #ifdef WITH_NISPLUS_HOME
5205         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5206 #else
5207         string_set(&Globals.szNISHomeMapName, "auto.home");
5208 #endif
5209 #endif
5210         Globals.bTimeServer = False;
5211         Globals.bBindInterfacesOnly = False;
5212         Globals.bUnixPasswdSync = False;
5213         Globals.bPamPasswordChange = False;
5214         Globals.bPasswdChatDebug = False;
5215         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5216         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
5217         Globals.bNTStatusSupport = True; /* Use NT status by default. */
5218         Globals.bStatCache = True;      /* use stat cache by default */
5219         Globals.iMaxStatCacheSize = 256; /* 256k by default */
5220         Globals.restrict_anonymous = 0;
5221         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
5222         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
5223         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
5224         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5225         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5226         /* Note, that we will use NTLM2 session security (which is different), if it is available */
5227
5228         Globals.map_to_guest = 0;       /* By Default, "Never" */
5229         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
5230         Globals.enhanced_browsing = true;
5231         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5232 #ifdef MMAP_BLACKLIST
5233         Globals.bUseMmap = False;
5234 #else
5235         Globals.bUseMmap = True;
5236 #endif
5237         Globals.bUnixExtensions = True;
5238         Globals.bResetOnZeroVC = False;
5239         Globals.bLogWriteableFilesOnExit = False;
5240         Globals.bCreateKrb5Conf = true;
5241
5242         /* hostname lookups can be very expensive and are broken on
5243            a large number of sites (tridge) */
5244         Globals.bHostnameLookups = False;
5245
5246         string_set(&Globals.szPassdbBackend, "tdbsam");
5247         string_set(&Globals.szLdapSuffix, "");
5248         string_set(&Globals.szLdapMachineSuffix, "");
5249         string_set(&Globals.szLdapUserSuffix, "");
5250         string_set(&Globals.szLdapGroupSuffix, "");
5251         string_set(&Globals.szLdapIdmapSuffix, "");
5252
5253         string_set(&Globals.szLdapAdminDn, "");
5254         Globals.ldap_ssl = LDAP_SSL_START_TLS;
5255         Globals.ldap_ssl_ads = False;
5256         Globals.ldap_deref = -1;
5257         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5258         Globals.ldap_delete_dn = False;
5259         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5260         Globals.ldap_follow_referral = Auto;
5261         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5262         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5263         Globals.ldap_page_size = LDAP_PAGE_SIZE;
5264
5265         Globals.ldap_debug_level = 0;
5266         Globals.ldap_debug_threshold = 10;
5267
5268         /* This is what we tell the afs client. in reality we set the token 
5269          * to never expire, though, when this runs out the afs client will 
5270          * forget the token. Set to 0 to get NEVERDATE.*/
5271         Globals.iAfsTokenLifetime = 604800;
5272         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5273
5274 /* these parameters are set to defaults that are more appropriate
5275    for the increasing samba install base:
5276
5277    as a member of the workgroup, that will possibly become a
5278    _local_ master browser (lm = True).  this is opposed to a forced
5279    local master browser startup (pm = True).
5280
5281    doesn't provide WINS server service by default (wsupp = False),
5282    and doesn't provide domain master browser services by default, either.
5283
5284 */
5285
5286         Globals.bMsAddPrinterWizard = True;
5287         Globals.os_level = 20;
5288         Globals.bLocalMaster = True;
5289         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
5290         Globals.bDomainLogons = False;
5291         Globals.bBrowseList = True;
5292         Globals.bWINSsupport = False;
5293         Globals.bWINSproxy = False;
5294
5295         TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5296         Globals.InitLogonDelay = 100; /* 100 ms default delay */
5297
5298         Globals.bDNSproxy = True;
5299
5300         /* this just means to use them if they exist */
5301         Globals.bKernelOplocks = True;
5302
5303         Globals.bAllowTrustedDomains = True;
5304         string_set(&Globals.szIdmapBackend, "tdb");
5305         Globals.bIdmapReadOnly = false;
5306
5307         string_set(&Globals.szTemplateShell, "/bin/false");
5308         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5309         string_set(&Globals.szWinbindSeparator, "\\");
5310
5311         string_set(&Globals.szCupsServer, "");
5312         string_set(&Globals.szIPrintServer, "");
5313
5314         string_set(&Globals.ctdbdSocket, "");
5315         Globals.szClusterAddresses = NULL;
5316         Globals.clustering = False;
5317         Globals.ctdb_timeout = 0;
5318         Globals.ctdb_locktime_warn_threshold = 0;
5319
5320         Globals.winbind_cache_time = 300;       /* 5 minutes */
5321         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
5322         Globals.winbind_max_clients = 200;
5323         Globals.bWinbindEnumUsers = False;
5324         Globals.bWinbindEnumGroups = False;
5325         Globals.bWinbindUseDefaultDomain = False;
5326         Globals.bWinbindTrustedDomainsOnly = False;
5327         Globals.bWinbindNestedGroups = True;
5328         Globals.winbind_expand_groups = 1;
5329         Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5330         Globals.bWinbindRefreshTickets = False;
5331         Globals.bWinbindOfflineLogon = False;
5332
5333         Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5334         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5335
5336         Globals.bPassdbExpandExplicit = False;
5337
5338         Globals.name_cache_timeout = 660; /* In seconds */
5339
5340         Globals.bUseSpnego = True;
5341         Globals.bClientUseSpnego = True;
5342
5343         Globals.client_signing = Auto;
5344         Globals.server_signing = False;
5345
5346         Globals.bDeferSharingViolations = True;
5347         string_set(&Globals.smb_ports, SMB_PORTS);
5348
5349         Globals.bEnablePrivileges = True;
5350         Globals.bHostMSDfs        = True;
5351         Globals.bASUSupport       = False;
5352
5353         /* User defined shares. */
5354         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5355                 smb_panic("init_globals: ENOMEM");
5356         }
5357         string_set(&Globals.szUsersharePath, s);
5358         SAFE_FREE(s);
5359         string_set(&Globals.szUsershareTemplateShare, "");
5360         Globals.iUsershareMaxShares = 0;
5361         /* By default disallow sharing of directories not owned by the sharer. */
5362         Globals.bUsershareOwnerOnly = True;
5363         /* By default disallow guest access to usershares. */
5364         Globals.bUsershareAllowGuests = False;
5365
5366         Globals.iKeepalive = DEFAULT_KEEPALIVE;
5367
5368         /* By default no shares out of the registry */
5369         Globals.bRegistryShares = False;
5370
5371         Globals.iminreceivefile = 0;
5372
5373         Globals.bMapUntrustedToDomain = false;
5374
5375         Globals.ismb2_max_read = 1024*1024;
5376         Globals.ismb2_max_write = 1024*1024;
5377         Globals.ismb2_max_trans = 1024*1024;
5378
5379         string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5380
5381         /* Now put back the settings that were set with lp_set_cmdline() */
5382         apply_lp_set_cmdline();
5383 }
5384
5385 /*******************************************************************
5386  Convenience routine to grab string parameters into temporary memory
5387  and run standard_sub_basic on them. The buffers can be written to by
5388  callers without affecting the source string.
5389 ********************************************************************/
5390
5391 static char *lp_string(const char *s)
5392 {
5393         char *ret;
5394         TALLOC_CTX *ctx = talloc_tos();
5395
5396         /* The follow debug is useful for tracking down memory problems
5397            especially if you have an inner loop that is calling a lp_*()
5398            function that returns a string.  Perhaps this debug should be
5399            present all the time? */
5400
5401 #if 0
5402         DEBUG(10, ("lp_string(%s)\n", s));
5403 #endif
5404         if (!s) {
5405                 return NULL;
5406         }
5407
5408         ret = talloc_sub_basic(ctx,
5409                         get_current_username(),
5410                         current_user_info.domain,
5411                         s);
5412         if (trim_char(ret, '\"', '\"')) {
5413                 if (strchr(ret,'\"') != NULL) {
5414                         TALLOC_FREE(ret);
5415                         ret = talloc_sub_basic(ctx,
5416                                         get_current_username(),
5417                                         current_user_info.domain,
5418                                         s);
5419                 }
5420         }
5421         return ret;
5422 }
5423
5424 /*
5425    In this section all the functions that are used to access the
5426    parameters from the rest of the program are defined
5427 */
5428
5429 #define FN_GLOBAL_STRING(fn_name,ptr) \
5430  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5431 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5432  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5433 #define FN_GLOBAL_LIST(fn_name,ptr) \
5434  const char **fn_name(void) {return(*(const char ***)(ptr));}
5435 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5436  bool fn_name(void) {return(*(bool *)(ptr));}
5437 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5438  char fn_name(void) {return(*(char *)(ptr));}
5439 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5440  int fn_name(void) {return(*(int *)(ptr));}
5441
5442 #define FN_LOCAL_STRING(fn_name,val) \
5443  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5444 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5445  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5446 #define FN_LOCAL_LIST(fn_name,val) \
5447  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5448 #define FN_LOCAL_BOOL(fn_name,val) \
5449  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5450 #define FN_LOCAL_INTEGER(fn_name,val) \
5451  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5452
5453 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5454  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5455 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5456  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5457 #define FN_LOCAL_CHAR(fn_name,val) \
5458  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5459
5460 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5461 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5462 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5463 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5464 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5465 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5466 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5467 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5468 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5469 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5470 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5471 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5472 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5473 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5474 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5475 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5476 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5477  * build process or in smb.conf, we use that value.  Otherwise they
5478  * default to the value of lp_lockdir(). */
5479 char *lp_statedir(void) {
5480         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5481             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5482                 return(lp_string(*(char **)(&Globals.szStateDir) ?
5483                     *(char **)(&Globals.szStateDir) : ""));
5484         else
5485                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5486                     *(char **)(&Globals.szLockDir) : ""));
5487 }
5488 char *lp_cachedir(void) {
5489         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5490             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5491                 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5492                     *(char **)(&Globals.szCacheDir) : ""));
5493         else
5494                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5495                     *(char **)(&Globals.szLockDir) : ""));
5496 }
5497 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5498 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5499 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5500 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5501 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5502 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5503 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5504 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5505 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5506 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5507 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5508 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5509 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5510 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5511 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5512 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5513 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5514 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5515 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5516 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5517 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5518 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5519 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5520 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5521 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5522 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5523 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5524 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5525 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5526 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5527 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5528 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5529 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5530 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5531 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5532  * lp_passdb_backend() should be replace by the this macro again after
5533  * some releases.
5534  * */
5535 const char *lp_passdb_backend(void)
5536 {
5537         char *delim, *quote;
5538
5539         delim = strchr( Globals.szPassdbBackend, ' ');
5540         /* no space at all */
5541         if (delim == NULL) {
5542                 goto out;
5543         }
5544
5545         quote = strchr(Globals.szPassdbBackend, '"');
5546         /* no quote char or non in the first part */
5547         if (quote == NULL || quote > delim) {
5548                 *delim = '\0';
5549                 goto warn;
5550         }
5551
5552         quote = strchr(quote+1, '"');
5553         if (quote == NULL) {
5554                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5555                 goto out;
5556         } else if (*(quote+1) == '\0') {
5557                 /* space, fitting quote char, and one backend only */
5558                 goto out;
5559         } else {
5560                 /* terminate string after the fitting quote char */
5561                 *(quote+1) = '\0';
5562         }
5563
5564 warn:
5565         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5566                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5567                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5568                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5569
5570 out:
5571         return Globals.szPassdbBackend;
5572 }
5573 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5574 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5575 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5576 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5577 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5578
5579 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5580 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5581 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5582 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5583 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5584 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5585
5586 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5587
5588 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5589 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5590 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5591 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5592
5593 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5594
5595 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5596 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5597 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5598 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5599 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5600 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5601 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5602 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5603 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5604 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5605 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5606 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5607 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5608 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5609 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5610 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5611
5612 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5613 FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
5614 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5615 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5616 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5617 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5618
5619 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5620 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5621 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5622 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5623 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5624 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5625 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5626 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5627 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5628 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5629 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5630 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5631 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5632 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5633 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5634 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5635 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5636 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5637 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5638 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5639
5640 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5641
5642 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5643 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5644 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5645 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5646 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5647 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5648                &Globals.bLogWriteableFilesOnExit)
5649 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5650 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5651 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5652 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5653 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5654 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5655 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5656 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5657 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5658 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5659 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5660 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5661 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5662 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5663 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5664 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5665 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5666 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5667 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5668 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5669 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5670 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5671 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5672 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5673 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5674 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5675 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5676 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5677 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5678 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5679 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5680 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5681 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5682 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5683 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5684 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5685 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5686 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5687 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5688 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5689 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5690 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5691 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5692 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5693 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5694 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5695 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5696 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5697 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5698 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5699 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5700 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5701 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5702 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5703 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5704 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5705 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5706 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5707 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5708 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5709 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5710 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5711 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5712 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5713 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5714 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5715 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5716 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5717 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5718 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5719 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5720 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5721 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5722 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5723 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5724 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5725 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5726 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5727 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5728 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5729 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5730 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5731 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5732 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5733 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5734 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5735 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5736 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5737 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5738 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5739 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5740 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5741 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5742 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5743 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5744 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5745 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5746
5747 FN_LOCAL_STRING(lp_preexec, szPreExec)
5748 FN_LOCAL_STRING(lp_postexec, szPostExec)
5749 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5750 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5751 FN_LOCAL_STRING(lp_servicename, szService)
5752 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5753 FN_LOCAL_STRING(lp_pathname, szPath)
5754 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5755 FN_LOCAL_STRING(lp_username, szUsername)
5756 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5757 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5758 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5759 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5760 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5761 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5762 int lp_cups_encrypt(void)
5763 {
5764         int result = 0;
5765 #ifdef HAVE_HTTPCONNECTENCRYPT
5766         switch (Globals.CupsEncrypt) {
5767                 case Auto:
5768                         result = HTTP_ENCRYPT_REQUIRED;
5769                         break;
5770                 case True:
5771                         result = HTTP_ENCRYPT_ALWAYS;
5772                         break;
5773                 case False:
5774                         result = HTTP_ENCRYPT_NEVER;
5775                         break;
5776         }
5777 #endif
5778         return result;
5779 }
5780 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5781 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5782 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5783 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5784 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5785 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5786 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5787 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5788 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5789 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5790 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5791 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5792 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5793 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5794 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5795 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5796 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5797 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5798 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5799 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5800 FN_LOCAL_STRING(lp_comment, comment)
5801 FN_LOCAL_STRING(lp_force_user, force_user)
5802 FN_LOCAL_STRING(lp_force_group, force_group)
5803 FN_LOCAL_LIST(lp_readlist, readlist)
5804 FN_LOCAL_LIST(lp_writelist, writelist)
5805 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5806 FN_LOCAL_STRING(lp_fstype, fstype)
5807 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5808 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5809 static FN_LOCAL_STRING(lp_volume, volume)
5810 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5811 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5812 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5813 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5814 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5815 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5816 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5817 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5818 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5819 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5820 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5821 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5822 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5823 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5824 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5825 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5826 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5827 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5828 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5829 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5830 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5831 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5832 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5833 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5834 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5835 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5836 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5837 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5838 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5839 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5840 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5841 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5842 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5843 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5844 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5845 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5846 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5847 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5848 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5849 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5850 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5851 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5852 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5853 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5854 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5855 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5856 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5857 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5858 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5859 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5860 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5861 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5862 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5863 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5864 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5865 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5866 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5867 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5868 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5869 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5870 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5871 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5872 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5873 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5874 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5875 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5876 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5877 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5878 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5879 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5880 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5881 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5882 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5883 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5884 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5885 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5886 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5887 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5888 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5889 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5890 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5891 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5892 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5893 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5894 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5895 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5896 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5897 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5898 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5899 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5900 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5901 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5902 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5903 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
5904 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5905 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5906 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5907 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5908 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5909 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5910
5911 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
5912
5913 /* local prototypes */
5914
5915 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5916 static const char *get_boolean(bool bool_value);
5917 static int getservicebyname(const char *pszServiceName,
5918                             struct service *pserviceDest);
5919 static void copy_service(struct service *pserviceDest,
5920                          struct service *pserviceSource,
5921                          struct bitmap *pcopymapDest);
5922 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5923                          void *userdata);
5924 static bool do_section(const char *pszSectionName, void *userdata);
5925 static void init_copymap(struct service *pservice);
5926 static bool hash_a_service(const char *name, int number);
5927 static void free_service_byindex(int iService);
5928 static void free_param_opts(struct param_opt_struct **popts);
5929 static void show_parameter(int parmIndex);
5930 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5931
5932 /*
5933  * This is a helper function for parametrical options support.  It returns a
5934  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5935  * parametrical functions are quite simple
5936  */
5937 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5938                                                 const char *option)
5939 {
5940         bool global_section = False;
5941         char* param_key;
5942         struct param_opt_struct *data;
5943
5944         if (snum >= iNumServices) return NULL;
5945
5946         if (snum < 0) { 
5947                 data = Globals.param_opt;
5948                 global_section = True;
5949         } else {
5950                 data = ServicePtrs[snum]->param_opt;
5951         }
5952
5953         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5954                 DEBUG(0,("asprintf failed!\n"));
5955                 return NULL;
5956         }
5957
5958         while (data) {
5959                 if (strwicmp(data->key, param_key) == 0) {
5960                         string_free(&param_key);
5961                         return data;
5962                 }
5963                 data = data->next;
5964         }
5965
5966         if (!global_section) {
5967                 /* Try to fetch the same option but from globals */
5968                 /* but only if we are not already working with Globals */
5969                 data = Globals.param_opt;
5970                 while (data) {
5971                         if (strwicmp(data->key, param_key) == 0) {
5972                                 string_free(&param_key);
5973                                 return data;
5974                         }
5975                         data = data->next;
5976                 }
5977         }
5978
5979         string_free(&param_key);
5980
5981         return NULL;
5982 }
5983
5984
5985 #define MISSING_PARAMETER(name) \
5986     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5987
5988 /*******************************************************************
5989 convenience routine to return int parameters.
5990 ********************************************************************/
5991 static int lp_int(const char *s)
5992 {
5993
5994         if (!s || !*s) {
5995                 MISSING_PARAMETER(lp_int);
5996                 return (-1);
5997         }
5998
5999         return (int)strtol(s, NULL, 0);
6000 }
6001
6002 /*******************************************************************
6003 convenience routine to return unsigned long parameters.
6004 ********************************************************************/
6005 static unsigned long lp_ulong(const char *s)
6006 {
6007
6008         if (!s || !*s) {
6009                 MISSING_PARAMETER(lp_ulong);
6010                 return (0);
6011         }
6012
6013         return strtoul(s, NULL, 0);
6014 }
6015
6016 /*******************************************************************
6017 convenience routine to return boolean parameters.
6018 ********************************************************************/
6019 static bool lp_bool(const char *s)
6020 {
6021         bool ret = False;
6022
6023         if (!s || !*s) {
6024                 MISSING_PARAMETER(lp_bool);
6025                 return False;
6026         }
6027
6028         if (!set_boolean(s, &ret)) {
6029                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6030                 return False;
6031         }
6032
6033         return ret;
6034 }
6035
6036 /*******************************************************************
6037 convenience routine to return enum parameters.
6038 ********************************************************************/
6039 static int lp_enum(const char *s,const struct enum_list *_enum)
6040 {
6041         int i;
6042
6043         if (!s || !*s || !_enum) {
6044                 MISSING_PARAMETER(lp_enum);
6045                 return (-1);
6046         }
6047
6048         for (i=0; _enum[i].name; i++) {
6049                 if (strequal(_enum[i].name,s))
6050                         return _enum[i].value;
6051         }
6052
6053         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6054         return (-1);
6055 }
6056
6057 #undef MISSING_PARAMETER
6058
6059 /* DO NOT USE lp_parm_string ANYMORE!!!!
6060  * use lp_parm_const_string or lp_parm_talloc_string
6061  *
6062  * lp_parm_string is only used to let old modules find this symbol
6063  */
6064 #undef lp_parm_string
6065  char *lp_parm_string(const char *servicename, const char *type, const char *option);
6066  char *lp_parm_string(const char *servicename, const char *type, const char *option)
6067 {
6068         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6069 }
6070
6071 /* Return parametric option from a given service. Type is a part of option before ':' */
6072 /* Parametric option has following syntax: 'Type: option = value' */
6073 /* the returned value is talloced on the talloc_tos() */
6074 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6075 {
6076         struct param_opt_struct *data = get_parametrics(snum, type, option);
6077
6078         if (data == NULL||data->value==NULL) {
6079                 if (def) {
6080                         return lp_string(def);
6081                 } else {
6082                         return NULL;
6083                 }
6084         }
6085
6086         return lp_string(data->value);
6087 }
6088
6089 /* Return parametric option from a given service. Type is a part of option before ':' */
6090 /* Parametric option has following syntax: 'Type: option = value' */
6091 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6092 {
6093         struct param_opt_struct *data = get_parametrics(snum, type, option);
6094
6095         if (data == NULL||data->value==NULL)
6096                 return def;
6097
6098         return data->value;
6099 }
6100
6101 /* Return parametric option from a given service. Type is a part of option before ':' */
6102 /* Parametric option has following syntax: 'Type: option = value' */
6103
6104 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6105 {
6106         struct param_opt_struct *data = get_parametrics(snum, type, option);
6107
6108         if (data == NULL||data->value==NULL)
6109                 return (const char **)def;
6110
6111         if (data->list==NULL) {
6112                 data->list = str_list_make_v3(NULL, data->value, NULL);
6113         }
6114
6115         return (const char **)data->list;
6116 }
6117
6118 /* Return parametric option from a given service. Type is a part of option before ':' */
6119 /* Parametric option has following syntax: 'Type: option = value' */
6120
6121 int lp_parm_int(int snum, const char *type, const char *option, int def)
6122 {
6123         struct param_opt_struct *data = get_parametrics(snum, type, option);
6124
6125         if (data && data->value && *data->value)
6126                 return lp_int(data->value);
6127
6128         return def;
6129 }
6130
6131 /* Return parametric option from a given service. Type is a part of option before ':' */
6132 /* Parametric option has following syntax: 'Type: option = value' */
6133
6134 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6135 {
6136         struct param_opt_struct *data = get_parametrics(snum, type, option);
6137
6138         if (data && data->value && *data->value)
6139                 return lp_ulong(data->value);
6140
6141         return def;
6142 }
6143
6144 /* Return parametric option from a given service. Type is a part of option before ':' */
6145 /* Parametric option has following syntax: 'Type: option = value' */
6146
6147 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6148 {
6149         struct param_opt_struct *data = get_parametrics(snum, type, option);
6150
6151         if (data && data->value && *data->value)
6152                 return lp_bool(data->value);
6153
6154         return def;
6155 }
6156
6157 /* Return parametric option from a given service. Type is a part of option before ':' */
6158 /* Parametric option has following syntax: 'Type: option = value' */
6159
6160 int lp_parm_enum(int snum, const char *type, const char *option,
6161                  const struct enum_list *_enum, int def)
6162 {
6163         struct param_opt_struct *data = get_parametrics(snum, type, option);
6164
6165         if (data && data->value && *data->value && _enum)
6166                 return lp_enum(data->value, _enum);
6167
6168         return def;
6169 }
6170
6171
6172 /***************************************************************************
6173  Initialise a service to the defaults.
6174 ***************************************************************************/
6175
6176 static void init_service(struct service *pservice)
6177 {
6178         memset((char *)pservice, '\0', sizeof(struct service));
6179         copy_service(pservice, &sDefault, NULL);
6180 }
6181
6182
6183 /**
6184  * free a param_opts structure.
6185  * param_opts handling should be moved to talloc;
6186  * then this whole functions reduces to a TALLOC_FREE().
6187  */
6188
6189 static void free_param_opts(struct param_opt_struct **popts)
6190 {
6191         struct param_opt_struct *opt, *next_opt;
6192
6193         if (popts == NULL) {
6194                 return;
6195         }
6196
6197         if (*popts != NULL) {
6198                 DEBUG(5, ("Freeing parametrics:\n"));
6199         }
6200         opt = *popts;
6201         while (opt != NULL) {
6202                 string_free(&opt->key);
6203                 string_free(&opt->value);
6204                 TALLOC_FREE(opt->list);
6205                 next_opt = opt->next;
6206                 SAFE_FREE(opt);
6207                 opt = next_opt;
6208         }
6209         *popts = NULL;
6210 }
6211
6212 /***************************************************************************
6213  Free the dynamically allocated parts of a service struct.
6214 ***************************************************************************/
6215
6216 static void free_service(struct service *pservice)
6217 {
6218         if (!pservice)
6219                 return;
6220
6221         if (pservice->szService)
6222                 DEBUG(5, ("free_service: Freeing service %s\n",
6223                        pservice->szService));
6224
6225         free_parameters(pservice);
6226
6227         string_free(&pservice->szService);
6228         TALLOC_FREE(pservice->copymap);
6229
6230         free_param_opts(&pservice->param_opt);
6231
6232         ZERO_STRUCTP(pservice);
6233 }
6234
6235
6236 /***************************************************************************
6237  remove a service indexed in the ServicePtrs array from the ServiceHash
6238  and free the dynamically allocated parts
6239 ***************************************************************************/
6240
6241 static void free_service_byindex(int idx)
6242 {
6243         if ( !LP_SNUM_OK(idx) ) 
6244                 return;
6245
6246         ServicePtrs[idx]->valid = False;
6247         invalid_services[num_invalid_services++] = idx;
6248
6249         /* we have to cleanup the hash record */
6250
6251         if (ServicePtrs[idx]->szService) {
6252                 char *canon_name = canonicalize_servicename(
6253                         talloc_tos(),
6254                         ServicePtrs[idx]->szService );
6255
6256                 dbwrap_delete_bystring(ServiceHash, canon_name );
6257                 TALLOC_FREE(canon_name);
6258         }
6259
6260         free_service(ServicePtrs[idx]);
6261 }
6262
6263 /***************************************************************************
6264  Add a new service to the services array initialising it with the given 
6265  service. 
6266 ***************************************************************************/
6267
6268 static int add_a_service(const struct service *pservice, const char *name)
6269 {
6270         int i;
6271         struct service tservice;
6272         int num_to_alloc = iNumServices + 1;
6273
6274         tservice = *pservice;
6275
6276         /* it might already exist */
6277         if (name) {
6278                 i = getservicebyname(name, NULL);
6279                 if (i >= 0) {
6280                         return (i);
6281                 }
6282         }
6283
6284         /* find an invalid one */
6285         i = iNumServices;
6286         if (num_invalid_services > 0) {
6287                 i = invalid_services[--num_invalid_services];
6288         }
6289
6290         /* if not, then create one */
6291         if (i == iNumServices) {
6292                 struct service **tsp;
6293                 int *tinvalid;
6294
6295                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6296                 if (tsp == NULL) {
6297                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6298                         return (-1);
6299                 }
6300                 ServicePtrs = tsp;
6301                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6302                 if (!ServicePtrs[iNumServices]) {
6303                         DEBUG(0,("add_a_service: out of memory!\n"));
6304                         return (-1);
6305                 }
6306                 iNumServices++;
6307
6308                 /* enlarge invalid_services here for now... */
6309                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6310                                              num_to_alloc);
6311                 if (tinvalid == NULL) {
6312                         DEBUG(0,("add_a_service: failed to enlarge "
6313                                  "invalid_services!\n"));
6314                         return (-1);
6315                 }
6316                 invalid_services = tinvalid;
6317         } else {
6318                 free_service_byindex(i);
6319         }
6320
6321         ServicePtrs[i]->valid = True;
6322
6323         init_service(ServicePtrs[i]);
6324         copy_service(ServicePtrs[i], &tservice, NULL);
6325         if (name)
6326                 string_set(&ServicePtrs[i]->szService, name);
6327
6328         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6329                 i, ServicePtrs[i]->szService));
6330
6331         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6332                 return (-1);
6333         }
6334
6335         return (i);
6336 }
6337
6338 /***************************************************************************
6339   Convert a string to uppercase and remove whitespaces.
6340 ***************************************************************************/
6341
6342 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6343 {
6344         char *result;
6345
6346         if ( !src ) {
6347                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6348                 return NULL;
6349         }
6350
6351         result = talloc_strdup(ctx, src);
6352         SMB_ASSERT(result != NULL);
6353
6354         strlower_m(result);
6355         return result;
6356 }
6357
6358 /***************************************************************************
6359   Add a name/index pair for the services array to the hash table.
6360 ***************************************************************************/
6361
6362 static bool hash_a_service(const char *name, int idx)
6363 {
6364         char *canon_name;
6365
6366         if ( !ServiceHash ) {
6367                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6368                 ServiceHash = db_open_rbt(NULL);
6369                 if ( !ServiceHash ) {
6370                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6371                         return False;
6372                 }
6373         }
6374
6375         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6376                 idx, name));
6377
6378         canon_name = canonicalize_servicename(talloc_tos(), name );
6379
6380         dbwrap_store_bystring(ServiceHash, canon_name,
6381                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6382                               TDB_REPLACE);
6383
6384         TALLOC_FREE(canon_name);
6385
6386         return True;
6387 }
6388
6389 /***************************************************************************
6390  Add a new home service, with the specified home directory, defaults coming
6391  from service ifrom.
6392 ***************************************************************************/
6393
6394 bool lp_add_home(const char *pszHomename, int iDefaultService,
6395                  const char *user, const char *pszHomedir)
6396 {
6397         int i;
6398
6399         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6400                         pszHomedir[0] == '\0') {
6401                 return false;
6402         }
6403
6404         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6405
6406         if (i < 0)
6407                 return (False);
6408
6409         if (!(*(ServicePtrs[iDefaultService]->szPath))
6410             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6411                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6412         }
6413
6414         if (!(*(ServicePtrs[i]->comment))) {
6415                 char *comment = NULL;
6416                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6417                         return false;
6418                 }
6419                 string_set(&ServicePtrs[i]->comment, comment);
6420                 SAFE_FREE(comment);
6421         }
6422
6423         /* set the browseable flag from the global default */
6424
6425         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6426         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6427
6428         ServicePtrs[i]->autoloaded = True;
6429
6430         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6431                user, ServicePtrs[i]->szPath ));
6432
6433         return (True);
6434 }
6435
6436 /***************************************************************************
6437  Add a new service, based on an old one.
6438 ***************************************************************************/
6439
6440 int lp_add_service(const char *pszService, int iDefaultService)
6441 {
6442         if (iDefaultService < 0) {
6443                 return add_a_service(&sDefault, pszService);
6444         }
6445
6446         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6447 }
6448
6449 /***************************************************************************
6450  Add the IPC service.
6451 ***************************************************************************/
6452
6453 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6454 {
6455         char *comment = NULL;
6456         int i = add_a_service(&sDefault, ipc_name);
6457
6458         if (i < 0)
6459                 return (False);
6460
6461         if (asprintf(&comment, "IPC Service (%s)",
6462                                 Globals.szServerString) < 0) {
6463                 return (False);
6464         }
6465
6466         string_set(&ServicePtrs[i]->szPath, tmpdir());
6467         string_set(&ServicePtrs[i]->szUsername, "");
6468         string_set(&ServicePtrs[i]->comment, comment);
6469         string_set(&ServicePtrs[i]->fstype, "IPC");
6470         ServicePtrs[i]->iMaxConnections = 0;
6471         ServicePtrs[i]->bAvailable = True;
6472         ServicePtrs[i]->bRead_only = True;
6473         ServicePtrs[i]->bGuest_only = False;
6474         ServicePtrs[i]->bAdministrative_share = True;
6475         ServicePtrs[i]->bGuest_ok = guest_ok;
6476         ServicePtrs[i]->bPrint_ok = False;
6477         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6478
6479         DEBUG(3, ("adding IPC service\n"));
6480
6481         SAFE_FREE(comment);
6482         return (True);
6483 }
6484
6485 /***************************************************************************
6486  Add a new printer service, with defaults coming from service iFrom.
6487 ***************************************************************************/
6488
6489 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6490 {
6491         const char *comment = "From Printcap";
6492         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6493
6494         if (i < 0)
6495                 return (False);
6496
6497         /* note that we do NOT default the availability flag to True - */
6498         /* we take it from the default service passed. This allows all */
6499         /* dynamic printers to be disabled by disabling the [printers] */
6500         /* entry (if/when the 'available' keyword is implemented!).    */
6501
6502         /* the printer name is set to the service name. */
6503         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6504         string_set(&ServicePtrs[i]->comment, comment);
6505
6506         /* set the browseable flag from the gloabl default */
6507         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6508
6509         /* Printers cannot be read_only. */
6510         ServicePtrs[i]->bRead_only = False;
6511         /* No share modes on printer services. */
6512         ServicePtrs[i]->bShareModes = False;
6513         /* No oplocks on printer services. */
6514         ServicePtrs[i]->bOpLocks = False;
6515         /* Printer services must be printable. */
6516         ServicePtrs[i]->bPrint_ok = True;
6517
6518         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6519
6520         return (True);
6521 }
6522
6523
6524 /***************************************************************************
6525  Check whether the given parameter name is valid.
6526  Parametric options (names containing a colon) are considered valid.
6527 ***************************************************************************/
6528
6529 bool lp_parameter_is_valid(const char *pszParmName)
6530 {
6531         return ((map_parameter(pszParmName) != -1) ||
6532                 (strchr(pszParmName, ':') != NULL));
6533 }
6534
6535 /***************************************************************************
6536  Check whether the given name is the name of a global parameter.
6537  Returns True for strings belonging to parameters of class
6538  P_GLOBAL, False for all other strings, also for parametric options
6539  and strings not belonging to any option.
6540 ***************************************************************************/
6541
6542 bool lp_parameter_is_global(const char *pszParmName)
6543 {
6544         int num = map_parameter(pszParmName);
6545
6546         if (num >= 0) {
6547                 return (parm_table[num].p_class == P_GLOBAL);
6548         }
6549
6550         return False;
6551 }
6552
6553 /**************************************************************************
6554  Check whether the given name is the canonical name of a parameter.
6555  Returns False if it is not a valid parameter Name.
6556  For parametric options, True is returned.
6557 **************************************************************************/
6558
6559 bool lp_parameter_is_canonical(const char *parm_name)
6560 {
6561         if (!lp_parameter_is_valid(parm_name)) {
6562                 return False;
6563         }
6564
6565         return (map_parameter(parm_name) ==
6566                 map_parameter_canonical(parm_name, NULL));
6567 }
6568
6569 /**************************************************************************
6570  Determine the canonical name for a parameter.
6571  Indicate when it is an inverse (boolean) synonym instead of a
6572  "usual" synonym.
6573 **************************************************************************/
6574
6575 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6576                                bool *inverse)
6577 {
6578         int num;
6579
6580         if (!lp_parameter_is_valid(parm_name)) {
6581                 *canon_parm = NULL;
6582                 return False;
6583         }
6584
6585         num = map_parameter_canonical(parm_name, inverse);
6586         if (num < 0) {
6587                 /* parametric option */
6588                 *canon_parm = parm_name;
6589         } else {
6590                 *canon_parm = parm_table[num].label;
6591         }
6592
6593         return True;
6594
6595 }
6596
6597 /**************************************************************************
6598  Determine the canonical name for a parameter.
6599  Turn the value given into the inverse boolean expression when
6600  the synonym is an invers boolean synonym.
6601
6602  Return True if parm_name is a valid parameter name and
6603  in case it is an invers boolean synonym, if the val string could
6604  successfully be converted to the reverse bool.
6605  Return false in all other cases.
6606 **************************************************************************/
6607
6608 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6609                                           const char *val,
6610                                           const char **canon_parm,
6611                                           const char **canon_val)
6612 {
6613         int num;
6614         bool inverse;
6615
6616         if (!lp_parameter_is_valid(parm_name)) {
6617                 *canon_parm = NULL;
6618                 *canon_val = NULL;
6619                 return False;
6620         }
6621
6622         num = map_parameter_canonical(parm_name, &inverse);
6623         if (num < 0) {
6624                 /* parametric option */
6625                 *canon_parm = parm_name;
6626                 *canon_val = val;
6627         } else {
6628                 *canon_parm = parm_table[num].label;
6629                 if (inverse) {
6630                         if (!lp_invert_boolean(val, canon_val)) {
6631                                 *canon_val = NULL;
6632                                 return False;
6633                         }
6634                 } else {
6635                         *canon_val = val;
6636                 }
6637         }
6638
6639         return True;
6640 }
6641
6642 /***************************************************************************
6643  Map a parameter's string representation to something we can use. 
6644  Returns False if the parameter string is not recognised, else TRUE.
6645 ***************************************************************************/
6646
6647 static int map_parameter(const char *pszParmName)
6648 {
6649         int iIndex;
6650
6651         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6652                 return (-1);
6653
6654         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6655                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6656                         return (iIndex);
6657
6658         /* Warn only if it isn't parametric option */
6659         if (strchr(pszParmName, ':') == NULL)
6660                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6661         /* We do return 'fail' for parametric options as well because they are
6662            stored in different storage
6663          */
6664         return (-1);
6665 }
6666
6667 /***************************************************************************
6668  Map a parameter's string representation to the index of the canonical
6669  form of the parameter (it might be a synonym).
6670  Returns -1 if the parameter string is not recognised.
6671 ***************************************************************************/
6672
6673 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6674 {
6675         int parm_num, canon_num;
6676         bool loc_inverse = False;
6677
6678         parm_num = map_parameter(pszParmName);
6679         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6680                 /* invalid, parametric or no canidate for synonyms ... */
6681                 goto done;
6682         }
6683
6684         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6685                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6686                         parm_num = canon_num;
6687                         goto done;
6688                 }
6689         }
6690
6691 done:
6692         if (inverse != NULL) {
6693                 *inverse = loc_inverse;
6694         }
6695         return parm_num;
6696 }
6697
6698 /***************************************************************************
6699  return true if parameter number parm1 is a synonym of parameter
6700  number parm2 (parm2 being the principal name).
6701  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6702  False otherwise.
6703 ***************************************************************************/
6704
6705 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6706 {
6707         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6708             (parm_table[parm1].flags & FLAG_HIDE) &&
6709             !(parm_table[parm2].flags & FLAG_HIDE))
6710         {
6711                 if (inverse != NULL) {
6712                         if ((parm_table[parm1].type == P_BOOLREV) &&
6713                             (parm_table[parm2].type == P_BOOL))
6714                         {
6715                                 *inverse = True;
6716                         } else {
6717                                 *inverse = False;
6718                         }
6719                 }
6720                 return True;
6721         }
6722         return False;
6723 }
6724
6725 /***************************************************************************
6726  Show one parameter's name, type, [values,] and flags.
6727  (helper functions for show_parameter_list)
6728 ***************************************************************************/
6729
6730 static void show_parameter(int parmIndex)
6731 {
6732         int enumIndex, flagIndex;
6733         int parmIndex2;
6734         bool hadFlag;
6735         bool hadSyn;
6736         bool inverse;
6737         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6738                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6739                 "P_ENUM", "P_SEP"};
6740         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6741                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6742                 FLAG_HIDE, FLAG_DOS_STRING};
6743         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6744                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6745                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6746
6747         printf("%s=%s", parm_table[parmIndex].label,
6748                type[parm_table[parmIndex].type]);
6749         if (parm_table[parmIndex].type == P_ENUM) {
6750                 printf(",");
6751                 for (enumIndex=0;
6752                      parm_table[parmIndex].enum_list[enumIndex].name;
6753                      enumIndex++)
6754                 {
6755                         printf("%s%s",
6756                                enumIndex ? "|" : "",
6757                                parm_table[parmIndex].enum_list[enumIndex].name);
6758                 }
6759         }
6760         printf(",");
6761         hadFlag = False;
6762         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6763                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6764                         printf("%s%s",
6765                                 hadFlag ? "|" : "",
6766                                 flag_names[flagIndex]);
6767                         hadFlag = True;
6768                 }
6769         }
6770
6771         /* output synonyms */
6772         hadSyn = False;
6773         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6774                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6775                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6776                                parm_table[parmIndex2].label);
6777                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6778                         if (!hadSyn) {
6779                                 printf(" (synonyms: ");
6780                                 hadSyn = True;
6781                         } else {
6782                                 printf(", ");
6783                         }
6784                         printf("%s%s", parm_table[parmIndex2].label,
6785                                inverse ? "[i]" : "");
6786                 }
6787         }
6788         if (hadSyn) {
6789                 printf(")");
6790         }
6791
6792         printf("\n");
6793 }
6794
6795 /***************************************************************************
6796  Show all parameter's name, type, [values,] and flags.
6797 ***************************************************************************/
6798
6799 void show_parameter_list(void)
6800 {
6801         int classIndex, parmIndex;
6802         const char *section_names[] = { "local", "global", NULL};
6803
6804         for (classIndex=0; section_names[classIndex]; classIndex++) {
6805                 printf("[%s]\n", section_names[classIndex]);
6806                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6807                         if (parm_table[parmIndex].p_class == classIndex) {
6808                                 show_parameter(parmIndex);
6809                         }
6810                 }
6811         }
6812 }
6813
6814 /***************************************************************************
6815  Check if a given string correctly represents a boolean value.
6816 ***************************************************************************/
6817
6818 bool lp_string_is_valid_boolean(const char *parm_value)
6819 {
6820         return set_boolean(parm_value, NULL);
6821 }
6822
6823 /***************************************************************************
6824  Get the standard string representation of a boolean value ("yes" or "no")
6825 ***************************************************************************/
6826
6827 static const char *get_boolean(bool bool_value)
6828 {
6829         static const char *yes_str = "yes";
6830         static const char *no_str = "no";
6831
6832         return (bool_value ? yes_str : no_str);
6833 }
6834
6835 /***************************************************************************
6836  Provide the string of the negated boolean value associated to the boolean
6837  given as a string. Returns False if the passed string does not correctly
6838  represent a boolean.
6839 ***************************************************************************/
6840
6841 bool lp_invert_boolean(const char *str, const char **inverse_str)
6842 {
6843         bool val;
6844
6845         if (!set_boolean(str, &val)) {
6846                 return False;
6847         }
6848
6849         *inverse_str = get_boolean(!val);
6850         return True;
6851 }
6852
6853 /***************************************************************************
6854  Provide the canonical string representation of a boolean value given
6855  as a string. Return True on success, False if the string given does
6856  not correctly represent a boolean.
6857 ***************************************************************************/
6858
6859 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6860 {
6861         bool val;
6862
6863         if (!set_boolean(str, &val)) {
6864                 return False;
6865         }
6866
6867         *canon_str = get_boolean(val);
6868         return True;
6869 }
6870
6871 /***************************************************************************
6872 Find a service by name. Otherwise works like get_service.
6873 ***************************************************************************/
6874
6875 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6876 {
6877         int iService = -1;
6878         char *canon_name;
6879         TDB_DATA data;
6880
6881         if (ServiceHash == NULL) {
6882                 return -1;
6883         }
6884
6885         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6886
6887         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6888
6889         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6890                 iService = *(int *)data.dptr;
6891         }
6892
6893         TALLOC_FREE(canon_name);
6894
6895         if ((iService != -1) && (LP_SNUM_OK(iService))
6896             && (pserviceDest != NULL)) {
6897                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6898         }
6899
6900         return (iService);
6901 }
6902
6903 /***************************************************************************
6904  Copy a service structure to another.
6905  If pcopymapDest is NULL then copy all fields
6906 ***************************************************************************/
6907
6908 /**
6909  * Add a parametric option to a param_opt_struct,
6910  * replacing old value, if already present.
6911  */
6912 static void set_param_opt(struct param_opt_struct **opt_list,
6913                           const char *opt_name,
6914                           const char *opt_value,
6915                           unsigned flags)
6916 {
6917         struct param_opt_struct *new_opt, *opt;
6918         bool not_added;
6919
6920         if (opt_list == NULL) {
6921                 return;
6922         }
6923
6924         opt = *opt_list;
6925         not_added = true;
6926
6927         /* Traverse destination */
6928         while (opt) {
6929                 /* If we already have same option, override it */
6930                 if (strwicmp(opt->key, opt_name) == 0) {
6931                         if ((opt->flags & FLAG_CMDLINE) &&
6932                             !(flags & FLAG_CMDLINE)) {
6933                                 /* it's been marked as not to be
6934                                    overridden */
6935                                 return;
6936                         }
6937                         string_free(&opt->value);
6938                         TALLOC_FREE(opt->list);
6939                         opt->value = SMB_STRDUP(opt_value);
6940                         opt->flags = flags;
6941                         not_added = false;
6942                         break;
6943                 }
6944                 opt = opt->next;
6945         }
6946         if (not_added) {
6947             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6948             new_opt->key = SMB_STRDUP(opt_name);
6949             new_opt->value = SMB_STRDUP(opt_value);
6950             new_opt->list = NULL;
6951             new_opt->flags = flags;
6952             DLIST_ADD(*opt_list, new_opt);
6953         }
6954 }
6955
6956 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6957                          struct bitmap *pcopymapDest)
6958 {
6959         int i;
6960         bool bcopyall = (pcopymapDest == NULL);
6961         struct param_opt_struct *data;
6962
6963         for (i = 0; parm_table[i].label; i++)
6964                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6965                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6966                         void *def_ptr = parm_table[i].ptr;
6967                         void *src_ptr =
6968                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6969                                                                     &sDefault);
6970                         void *dest_ptr =
6971                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6972                                                                   &sDefault);
6973
6974                         switch (parm_table[i].type) {
6975                                 case P_BOOL:
6976                                 case P_BOOLREV:
6977                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6978                                         break;
6979
6980                                 case P_INTEGER:
6981                                 case P_ENUM:
6982                                 case P_OCTAL:
6983                                         *(int *)dest_ptr = *(int *)src_ptr;
6984                                         break;
6985
6986                                 case P_CHAR:
6987                                         *(char *)dest_ptr = *(char *)src_ptr;
6988                                         break;
6989
6990                                 case P_STRING:
6991                                         string_set((char **)dest_ptr,
6992                                                    *(char **)src_ptr);
6993                                         break;
6994
6995                                 case P_USTRING:
6996                                         string_set((char **)dest_ptr,
6997                                                    *(char **)src_ptr);
6998                                         strupper_m(*(char **)dest_ptr);
6999                                         break;
7000                                 case P_LIST:
7001                                         TALLOC_FREE(*((char ***)dest_ptr));
7002                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
7003                                                       *(const char ***)src_ptr);
7004                                         break;
7005                                 default:
7006                                         break;
7007                         }
7008                 }
7009
7010         if (bcopyall) {
7011                 init_copymap(pserviceDest);
7012                 if (pserviceSource->copymap)
7013                         bitmap_copy(pserviceDest->copymap,
7014                                     pserviceSource->copymap);
7015         }
7016
7017         data = pserviceSource->param_opt;
7018         while (data) {
7019                 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7020                 data = data->next;
7021         }
7022 }
7023
7024 /***************************************************************************
7025 Check a service for consistency. Return False if the service is in any way
7026 incomplete or faulty, else True.
7027 ***************************************************************************/
7028
7029 bool service_ok(int iService)
7030 {
7031         bool bRetval;
7032
7033         bRetval = True;
7034         if (ServicePtrs[iService]->szService[0] == '\0') {
7035                 DEBUG(0, ("The following message indicates an internal error:\n"));
7036                 DEBUG(0, ("No service name in service entry.\n"));
7037                 bRetval = False;
7038         }
7039
7040         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7041         /* I can't see why you'd want a non-printable printer service...        */
7042         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7043                 if (!ServicePtrs[iService]->bPrint_ok) {
7044                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7045                                ServicePtrs[iService]->szService));
7046                         ServicePtrs[iService]->bPrint_ok = True;
7047                 }
7048                 /* [printers] service must also be non-browsable. */
7049                 if (ServicePtrs[iService]->bBrowseable)
7050                         ServicePtrs[iService]->bBrowseable = False;
7051         }
7052
7053         if (ServicePtrs[iService]->szPath[0] == '\0' &&
7054             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7055             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7056             ) {
7057                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7058                         ServicePtrs[iService]->szService));
7059                 ServicePtrs[iService]->bAvailable = False;
7060         }
7061
7062         /* If a service is flagged unavailable, log the fact at level 1. */
7063         if (!ServicePtrs[iService]->bAvailable)
7064                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7065                           ServicePtrs[iService]->szService));
7066
7067         return (bRetval);
7068 }
7069
7070 static struct smbconf_ctx *lp_smbconf_ctx(void)
7071 {
7072         WERROR werr;
7073         static struct smbconf_ctx *conf_ctx = NULL;
7074
7075         if (conf_ctx == NULL) {
7076                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
7077                 if (!W_ERROR_IS_OK(werr)) {
7078                         DEBUG(1, ("error initializing registry configuration: "
7079                                   "%s\n", win_errstr(werr)));
7080                         conf_ctx = NULL;
7081                 }
7082         }
7083
7084         return conf_ctx;
7085 }
7086
7087 static bool process_smbconf_service(struct smbconf_service *service)
7088 {
7089         uint32_t count;
7090         bool ret;
7091
7092         if (service == NULL) {
7093                 return false;
7094         }
7095
7096         ret = do_section(service->name, NULL);
7097         if (ret != true) {
7098                 return false;
7099         }
7100         for (count = 0; count < service->num_params; count++) {
7101                 ret = do_parameter(service->param_names[count],
7102                                    service->param_values[count],
7103                                    NULL);
7104                 if (ret != true) {
7105                         return false;
7106                 }
7107         }
7108         if (iServiceIndex >= 0) {
7109                 return service_ok(iServiceIndex);
7110         }
7111         return true;
7112 }
7113
7114 /**
7115  * load a service from registry and activate it
7116  */
7117 bool process_registry_service(const char *service_name)
7118 {
7119         WERROR werr;
7120         struct smbconf_service *service = NULL;
7121         TALLOC_CTX *mem_ctx = talloc_stackframe();
7122         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7123         bool ret = false;
7124
7125         if (conf_ctx == NULL) {
7126                 goto done;
7127         }
7128
7129         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7130
7131         if (!smbconf_share_exists(conf_ctx, service_name)) {
7132                 /*
7133                  * Registry does not contain data for this service (yet),
7134                  * but make sure lp_load doesn't return false.
7135                  */
7136                 ret = true;
7137                 goto done;
7138         }
7139
7140         werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7141         if (!W_ERROR_IS_OK(werr)) {
7142                 goto done;
7143         }
7144
7145         ret = process_smbconf_service(service);
7146         if (!ret) {
7147                 goto done;
7148         }
7149
7150         /* store the csn */
7151         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7152
7153 done:
7154         TALLOC_FREE(mem_ctx);
7155         return ret;
7156 }
7157
7158 /*
7159  * process_registry_globals
7160  */
7161 static bool process_registry_globals(void)
7162 {
7163         bool ret;
7164
7165         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7166
7167         ret = do_parameter("registry shares", "yes", NULL);
7168         if (!ret) {
7169                 return ret;
7170         }
7171
7172         return process_registry_service(GLOBAL_NAME);
7173 }
7174
7175 bool process_registry_shares(void)
7176 {
7177         WERROR werr;
7178         uint32_t count;
7179         struct smbconf_service **service = NULL;
7180         uint32_t num_shares = 0;
7181         TALLOC_CTX *mem_ctx = talloc_stackframe();
7182         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7183         bool ret = false;
7184
7185         if (conf_ctx == NULL) {
7186                 goto done;
7187         }
7188
7189         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7190         if (!W_ERROR_IS_OK(werr)) {
7191                 goto done;
7192         }
7193
7194         ret = true;
7195
7196         for (count = 0; count < num_shares; count++) {
7197                 if (strequal(service[count]->name, GLOBAL_NAME)) {
7198                         continue;
7199                 }
7200                 ret = process_smbconf_service(service[count]);
7201                 if (!ret) {
7202                         goto done;
7203                 }
7204         }
7205
7206         /* store the csn */
7207         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7208
7209 done:
7210         TALLOC_FREE(mem_ctx);
7211         return ret;
7212 }
7213
7214 #define MAX_INCLUDE_DEPTH 100
7215
7216 static uint8_t include_depth;
7217
7218 static struct file_lists {
7219         struct file_lists *next;
7220         char *name;
7221         char *subfname;
7222         time_t modtime;
7223 } *file_lists = NULL;
7224
7225 /*******************************************************************
7226  Keep a linked list of all config files so we know when one has changed 
7227  it's date and needs to be reloaded.
7228 ********************************************************************/
7229
7230 static void add_to_file_list(const char *fname, const char *subfname)
7231 {
7232         struct file_lists *f = file_lists;
7233
7234         while (f) {
7235                 if (f->name && !strcmp(f->name, fname))
7236                         break;
7237                 f = f->next;
7238         }
7239
7240         if (!f) {
7241                 f = SMB_MALLOC_P(struct file_lists);
7242                 if (!f)
7243                         return;
7244                 f->next = file_lists;
7245                 f->name = SMB_STRDUP(fname);
7246                 if (!f->name) {
7247                         SAFE_FREE(f);
7248                         return;
7249                 }
7250                 f->subfname = SMB_STRDUP(subfname);
7251                 if (!f->subfname) {
7252                         SAFE_FREE(f->name);
7253                         SAFE_FREE(f);
7254                         return;
7255                 }
7256                 file_lists = f;
7257                 f->modtime = file_modtime(subfname);
7258         } else {
7259                 time_t t = file_modtime(subfname);
7260                 if (t)
7261                         f->modtime = t;
7262         }
7263         return;
7264 }
7265
7266 /**
7267  * Free the file lists
7268  */
7269 static void free_file_list(void)
7270 {
7271         struct file_lists *f;
7272         struct file_lists *next;
7273
7274         f = file_lists;
7275         while( f ) {
7276                 next = f->next;
7277                 SAFE_FREE( f->name );
7278                 SAFE_FREE( f->subfname );
7279                 SAFE_FREE( f );
7280                 f = next;
7281         }
7282         file_lists = NULL;
7283 }
7284
7285
7286 /**
7287  * Utility function for outsiders to check if we're running on registry.
7288  */
7289 bool lp_config_backend_is_registry(void)
7290 {
7291         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7292 }
7293
7294 /**
7295  * Utility function to check if the config backend is FILE.
7296  */
7297 bool lp_config_backend_is_file(void)
7298 {
7299         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7300 }
7301
7302 /*******************************************************************
7303  Check if a config file has changed date.
7304 ********************************************************************/
7305
7306 bool lp_file_list_changed(void)
7307 {
7308         struct file_lists *f = file_lists;
7309
7310         DEBUG(6, ("lp_file_list_changed()\n"));
7311
7312         while (f) {
7313                 time_t mod_time;
7314
7315                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7316                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7317
7318                         if (conf_ctx == NULL) {
7319                                 return false;
7320                         }
7321                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7322                                             NULL))
7323                         {
7324                                 DEBUGADD(6, ("registry config changed\n"));
7325                                 return true;
7326                         }
7327                 } else {
7328                         char *n2 = NULL;
7329                         n2 = talloc_sub_basic(talloc_tos(),
7330                                               get_current_username(),
7331                                               current_user_info.domain,
7332                                               f->name);
7333                         if (!n2) {
7334                                 return false;
7335                         }
7336                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7337                                      f->name, n2, ctime(&f->modtime)));
7338
7339                         mod_time = file_modtime(n2);
7340
7341                         if (mod_time &&
7342                             ((f->modtime != mod_time) ||
7343                              (f->subfname == NULL) ||
7344                              (strcmp(n2, f->subfname) != 0)))
7345                         {
7346                                 DEBUGADD(6,
7347                                          ("file %s modified: %s\n", n2,
7348                                           ctime(&mod_time)));
7349                                 f->modtime = mod_time;
7350                                 SAFE_FREE(f->subfname);
7351                                 f->subfname = SMB_STRDUP(n2);
7352                                 TALLOC_FREE(n2);
7353                                 return true;
7354                         }
7355                         TALLOC_FREE(n2);
7356                 }
7357                 f = f->next;
7358         }
7359         return (False);
7360 }
7361
7362
7363 /***************************************************************************
7364  Run standard_sub_basic on netbios name... needed because global_myname
7365  is not accessed through any lp_ macro.
7366  Note: We must *NOT* use string_set() here as ptr points to global_myname.
7367 ***************************************************************************/
7368
7369 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7370 {
7371         bool ret;
7372         char *netbios_name = talloc_sub_basic(
7373                 talloc_tos(), get_current_username(), current_user_info.domain,
7374                 pszParmValue);
7375
7376         ret = set_global_myname(netbios_name);
7377         TALLOC_FREE(netbios_name);
7378         string_set(&Globals.szNetbiosName,global_myname());
7379
7380         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7381                global_myname()));
7382
7383         return ret;
7384 }
7385
7386 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7387 {
7388         if (strcmp(*ptr, pszParmValue) != 0) {
7389                 string_set(ptr, pszParmValue);
7390                 init_iconv();
7391         }
7392         return True;
7393 }
7394
7395
7396
7397 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7398 {
7399         bool ret;
7400
7401         ret = set_global_myworkgroup(pszParmValue);
7402         string_set(&Globals.szWorkgroup,lp_workgroup());
7403
7404         return ret;
7405 }
7406
7407 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7408 {
7409         bool ret;
7410
7411         ret = set_global_scope(pszParmValue);
7412         string_set(&Globals.szNetbiosScope,global_scope());
7413
7414         return ret;
7415 }
7416
7417 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7418 {
7419         TALLOC_FREE(Globals.szNetbiosAliases);
7420         Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7421         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7422 }
7423
7424 /***************************************************************************
7425  Handle the include operation.
7426 ***************************************************************************/
7427 static bool bAllowIncludeRegistry = true;
7428
7429 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7430 {
7431         char *fname;
7432
7433         if (include_depth >= MAX_INCLUDE_DEPTH) {
7434                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7435                           include_depth));
7436                 return false;
7437         }
7438
7439         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7440                 if (!bAllowIncludeRegistry) {
7441                         return true;
7442                 }
7443                 if (bInGlobalSection) {
7444                         bool ret;
7445                         include_depth++;
7446                         ret = process_registry_globals();
7447                         include_depth--;
7448                         return ret;
7449                 } else {
7450                         DEBUG(1, ("\"include = registry\" only effective "
7451                                   "in %s section\n", GLOBAL_NAME));
7452                         return false;
7453                 }
7454         }
7455
7456         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7457                                  current_user_info.domain,
7458                                  pszParmValue);
7459
7460         add_to_file_list(pszParmValue, fname);
7461
7462         string_set(ptr, fname);
7463
7464         if (file_exist(fname)) {
7465                 bool ret;
7466                 include_depth++;
7467                 ret = pm_process(fname, do_section, do_parameter, NULL);
7468                 include_depth--;
7469                 TALLOC_FREE(fname);
7470                 return ret;
7471         }
7472
7473         DEBUG(2, ("Can't find include file %s\n", fname));
7474         TALLOC_FREE(fname);
7475         return true;
7476 }
7477
7478 /***************************************************************************
7479  Handle the interpretation of the copy parameter.
7480 ***************************************************************************/
7481
7482 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7483 {
7484         bool bRetval;
7485         int iTemp;
7486         struct service serviceTemp;
7487
7488         string_set(ptr, pszParmValue);
7489
7490         init_service(&serviceTemp);
7491
7492         bRetval = False;
7493
7494         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7495
7496         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7497                 if (iTemp == iServiceIndex) {
7498                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7499                 } else {
7500                         copy_service(ServicePtrs[iServiceIndex],
7501                                      &serviceTemp,
7502                                      ServicePtrs[iServiceIndex]->copymap);
7503                         bRetval = True;
7504                 }
7505         } else {
7506                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7507                 bRetval = False;
7508         }
7509
7510         free_service(&serviceTemp);
7511         return (bRetval);
7512 }
7513
7514 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7515 {
7516         Globals.ldap_debug_level = lp_int(pszParmValue);
7517         init_ldap_debugging();
7518         return true;
7519 }
7520
7521 /***************************************************************************
7522  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7523  parameters is:
7524
7525  [global]
7526
7527         idmap uid = 1000-1999
7528         idmap gid = 700-899
7529
7530  We only do simple parsing checks here.  The strings are parsed into useful
7531  structures in the idmap daemon code.
7532
7533 ***************************************************************************/
7534
7535 /* Some lp_ routines to return idmap [ug]id information */
7536
7537 static uid_t idmap_uid_low, idmap_uid_high;
7538 static gid_t idmap_gid_low, idmap_gid_high;
7539
7540 bool lp_idmap_uid(uid_t *low, uid_t *high)
7541 {
7542         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7543                 return False;
7544
7545         if (low)
7546                 *low = idmap_uid_low;
7547
7548         if (high)
7549                 *high = idmap_uid_high;
7550
7551         return True;
7552 }
7553
7554 bool lp_idmap_gid(gid_t *low, gid_t *high)
7555 {
7556         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7557                 return False;
7558
7559         if (low)
7560                 *low = idmap_gid_low;
7561
7562         if (high)
7563                 *high = idmap_gid_high;
7564
7565         return True;
7566 }
7567
7568 /* Do some simple checks on "idmap [ug]id" parameter values */
7569
7570 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7571 {
7572         uint32 low, high;
7573
7574         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7575                 return False;
7576
7577         /* Parse OK */
7578
7579         string_set(ptr, pszParmValue);
7580
7581         idmap_uid_low = low;
7582         idmap_uid_high = high;
7583
7584         return True;
7585 }
7586
7587 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7588 {
7589         uint32 low, high;
7590
7591         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7592                 return False;
7593
7594         /* Parse OK */
7595
7596         string_set(ptr, pszParmValue);
7597
7598         idmap_gid_low = low;
7599         idmap_gid_high = high;
7600
7601         return True;
7602 }
7603
7604 /***************************************************************************
7605  Handle the DEBUG level list.
7606 ***************************************************************************/
7607
7608 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7609 {
7610         string_set(ptr, pszParmValueIn);
7611         return debug_parse_levels(pszParmValueIn);
7612 }
7613
7614 /***************************************************************************
7615  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7616 ***************************************************************************/
7617
7618 static const char *append_ldap_suffix( const char *str )
7619 {
7620         const char *suffix_string;
7621
7622
7623         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7624                                         Globals.szLdapSuffix );
7625         if ( !suffix_string ) {
7626                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7627                 return "";
7628         }
7629
7630         return suffix_string;
7631 }
7632
7633 const char *lp_ldap_machine_suffix(void)
7634 {
7635         if (Globals.szLdapMachineSuffix[0])
7636                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7637
7638         return lp_string(Globals.szLdapSuffix);
7639 }
7640
7641 const char *lp_ldap_user_suffix(void)
7642 {
7643         if (Globals.szLdapUserSuffix[0])
7644                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7645
7646         return lp_string(Globals.szLdapSuffix);
7647 }
7648
7649 const char *lp_ldap_group_suffix(void)
7650 {
7651         if (Globals.szLdapGroupSuffix[0])
7652                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7653
7654         return lp_string(Globals.szLdapSuffix);
7655 }
7656
7657 const char *lp_ldap_idmap_suffix(void)
7658 {
7659         if (Globals.szLdapIdmapSuffix[0])
7660                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7661
7662         return lp_string(Globals.szLdapSuffix);
7663 }
7664
7665 /****************************************************************************
7666  set the value for a P_ENUM
7667  ***************************************************************************/
7668
7669 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7670                               int *ptr )
7671 {
7672         int i;
7673
7674         for (i = 0; parm->enum_list[i].name; i++) {
7675                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7676                         *ptr = parm->enum_list[i].value;
7677                         return;
7678                 }
7679         }
7680         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7681                   pszParmValue, parm->label));
7682 }
7683
7684 /***************************************************************************
7685 ***************************************************************************/
7686
7687 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7688 {
7689         static int parm_num = -1;
7690         struct service *s;
7691
7692         if ( parm_num == -1 )
7693                 parm_num = map_parameter( "printing" );
7694
7695         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7696
7697         if ( snum < 0 )
7698                 s = &sDefault;
7699         else
7700                 s = ServicePtrs[snum];
7701
7702         init_printer_values( s );
7703
7704         return True;
7705 }
7706
7707
7708 /***************************************************************************
7709  Initialise a copymap.
7710 ***************************************************************************/
7711
7712 static void init_copymap(struct service *pservice)
7713 {
7714         int i;
7715
7716         TALLOC_FREE(pservice->copymap);
7717
7718         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7719         if (!pservice->copymap)
7720                 DEBUG(0,
7721                       ("Couldn't allocate copymap!! (size %d)\n",
7722                        (int)NUMPARAMETERS));
7723         else
7724                 for (i = 0; i < NUMPARAMETERS; i++)
7725                         bitmap_set(pservice->copymap, i);
7726 }
7727
7728 /***************************************************************************
7729  Return the local pointer to a parameter given a service struct and the
7730  pointer into the default structure.
7731 ***************************************************************************/
7732
7733 static void *lp_local_ptr(struct service *service, void *ptr)
7734 {
7735         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7736 }
7737
7738 /***************************************************************************
7739  Return the local pointer to a parameter given the service number and the 
7740  pointer into the default structure.
7741 ***************************************************************************/
7742
7743 void *lp_local_ptr_by_snum(int snum, void *ptr)
7744 {
7745         return lp_local_ptr(ServicePtrs[snum], ptr);
7746 }
7747
7748 /***************************************************************************
7749  Process a parameter for a particular service number. If snum < 0
7750  then assume we are in the globals.
7751 ***************************************************************************/
7752
7753 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7754 {
7755         int parmnum, i;
7756         void *parm_ptr = NULL;  /* where we are going to store the result */
7757         void *def_ptr = NULL;
7758         struct param_opt_struct **opt_list;
7759
7760         parmnum = map_parameter(pszParmName);
7761
7762         if (parmnum < 0) {
7763                 if (strchr(pszParmName, ':') == NULL) {
7764                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7765                                   pszParmName));
7766                         return (True);
7767                 }
7768
7769                 /*
7770                  * We've got a parametric option
7771                  */
7772
7773                 opt_list = (snum < 0)
7774                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7775                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7776
7777                 return (True);
7778         }
7779
7780         /* if it's already been set by the command line, then we don't
7781            override here */
7782         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7783                 return true;
7784         }
7785
7786         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7787                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7788                           pszParmName));
7789         }
7790
7791         def_ptr = parm_table[parmnum].ptr;
7792
7793         /* we might point at a service, the default service or a global */
7794         if (snum < 0) {
7795                 parm_ptr = def_ptr;
7796         } else {
7797                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7798                         DEBUG(0,
7799                               ("Global parameter %s found in service section!\n",
7800                                pszParmName));
7801                         return (True);
7802                 }
7803                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7804         }
7805
7806         if (snum >= 0) {
7807                 if (!ServicePtrs[snum]->copymap)
7808                         init_copymap(ServicePtrs[snum]);
7809
7810                 /* this handles the aliases - set the copymap for other entries with
7811                    the same data pointer */
7812                 for (i = 0; parm_table[i].label; i++)
7813                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7814                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7815         }
7816
7817         /* if it is a special case then go ahead */
7818         if (parm_table[parmnum].special) {
7819                 return parm_table[parmnum].special(snum, pszParmValue,
7820                                                    (char **)parm_ptr);
7821         }
7822
7823         /* now switch on the type of variable it is */
7824         switch (parm_table[parmnum].type)
7825         {
7826                 case P_BOOL:
7827                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7828                         break;
7829
7830                 case P_BOOLREV:
7831                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7832                         break;
7833
7834                 case P_INTEGER:
7835                         *(int *)parm_ptr = lp_int(pszParmValue);
7836                         break;
7837
7838                 case P_CHAR:
7839                         *(char *)parm_ptr = *pszParmValue;
7840                         break;
7841
7842                 case P_OCTAL:
7843                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7844                         if ( i != 1 ) {
7845                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7846                         }
7847                         break;
7848
7849                 case P_LIST:
7850                         TALLOC_FREE(*((char ***)parm_ptr));
7851                         *(char ***)parm_ptr = str_list_make_v3(
7852                                 NULL, pszParmValue, NULL);
7853                         break;
7854
7855                 case P_STRING:
7856                         string_set((char **)parm_ptr, pszParmValue);
7857                         break;
7858
7859                 case P_USTRING:
7860                         string_set((char **)parm_ptr, pszParmValue);
7861                         strupper_m(*(char **)parm_ptr);
7862                         break;
7863
7864                 case P_ENUM:
7865                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7866                         break;
7867                 case P_SEP:
7868                         break;
7869         }
7870
7871         return (True);
7872 }
7873
7874 /***************************************************************************
7875 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7876 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7877 ***************************************************************************/
7878
7879 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7880 {
7881         int parmnum;
7882         parmnum = map_parameter(pszParmName);
7883         if (parmnum >= 0) {
7884                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7885                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7886                         return false;
7887                 }
7888                 parm_table[parmnum].flags |= FLAG_CMDLINE;
7889
7890                 store_lp_set_cmdline(pszParmName, pszParmValue);
7891                 return true;
7892         }
7893
7894         /* it might be parametric */
7895         if (strchr(pszParmName, ':') != NULL) {
7896                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7897                 store_lp_set_cmdline(pszParmName, pszParmValue);
7898                 return true;
7899         }
7900
7901         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
7902         return true;
7903 }
7904
7905 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7906 {
7907         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7908 }
7909
7910 /***************************************************************************
7911  Process a parameter.
7912 ***************************************************************************/
7913
7914 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7915                          void *userdata)
7916 {
7917         if (!bInGlobalSection && bGlobalOnly)
7918                 return (True);
7919
7920         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7921
7922         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7923                                 pszParmName, pszParmValue));
7924 }
7925
7926 /*
7927   set a option from the commandline in 'a=b' format. Use to support --option
7928 */
7929 bool lp_set_option(const char *option)
7930 {
7931         char *p, *s;
7932         bool ret;
7933
7934         s = talloc_strdup(NULL, option);
7935         if (!s) {
7936                 return false;
7937         }
7938
7939         p = strchr(s, '=');
7940         if (!p) {
7941                 talloc_free(s);
7942                 return false;
7943         }
7944
7945         *p = 0;
7946
7947         ret = lp_set_cmdline(s, p+1);
7948         talloc_free(s);
7949         return ret;
7950 }
7951
7952 /**************************************************************************
7953  Print a parameter of the specified type.
7954 ***************************************************************************/
7955
7956 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7957 {
7958         int i;
7959         switch (p->type)
7960         {
7961                 case P_ENUM:
7962                         for (i = 0; p->enum_list[i].name; i++) {
7963                                 if (*(int *)ptr == p->enum_list[i].value) {
7964                                         fprintf(f, "%s",
7965                                                 p->enum_list[i].name);
7966                                         break;
7967                                 }
7968                         }
7969                         break;
7970
7971                 case P_BOOL:
7972                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7973                         break;
7974
7975                 case P_BOOLREV:
7976                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7977                         break;
7978
7979                 case P_INTEGER:
7980                         fprintf(f, "%d", *(int *)ptr);
7981                         break;
7982
7983                 case P_CHAR:
7984                         fprintf(f, "%c", *(char *)ptr);
7985                         break;
7986
7987                 case P_OCTAL: {
7988                         char *o = octal_string(*(int *)ptr);
7989                         fprintf(f, "%s", o);
7990                         TALLOC_FREE(o);
7991                         break;
7992                 }
7993
7994                 case P_LIST:
7995                         if ((char ***)ptr && *(char ***)ptr) {
7996                                 char **list = *(char ***)ptr;
7997                                 for (; *list; list++) {
7998                                         /* surround strings with whitespace in double quotes */
7999                                         if ( strchr_m( *list, ' ' ) )
8000                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8001                                         else
8002                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8003                                 }
8004                         }
8005                         break;
8006
8007                 case P_STRING:
8008                 case P_USTRING:
8009                         if (*(char **)ptr) {
8010                                 fprintf(f, "%s", *(char **)ptr);
8011                         }
8012                         break;
8013                 case P_SEP:
8014                         break;
8015         }
8016 }
8017
8018 /***************************************************************************
8019  Check if two parameters are equal.
8020 ***************************************************************************/
8021
8022 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8023 {
8024         switch (type) {
8025                 case P_BOOL:
8026                 case P_BOOLREV:
8027                         return (*((bool *)ptr1) == *((bool *)ptr2));
8028
8029                 case P_INTEGER:
8030                 case P_ENUM:
8031                 case P_OCTAL:
8032                         return (*((int *)ptr1) == *((int *)ptr2));
8033
8034                 case P_CHAR:
8035                         return (*((char *)ptr1) == *((char *)ptr2));
8036
8037                 case P_LIST:
8038                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8039
8040                 case P_STRING:
8041                 case P_USTRING:
8042                 {
8043                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8044                         if (p1 && !*p1)
8045                                 p1 = NULL;
8046                         if (p2 && !*p2)
8047                                 p2 = NULL;
8048                         return (p1 == p2 || strequal(p1, p2));
8049                 }
8050                 case P_SEP:
8051                         break;
8052         }
8053         return (False);
8054 }
8055
8056 /***************************************************************************
8057  Initialize any local varients in the sDefault table.
8058 ***************************************************************************/
8059
8060 void init_locals(void)
8061 {
8062         /* None as yet. */
8063 }
8064
8065 /***************************************************************************
8066  Process a new section (service). At this stage all sections are services.
8067  Later we'll have special sections that permit server parameters to be set.
8068  Returns True on success, False on failure. 
8069 ***************************************************************************/
8070
8071 static bool do_section(const char *pszSectionName, void *userdata)
8072 {
8073         bool bRetval;
8074         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8075                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8076         bRetval = False;
8077
8078         /* if we were in a global section then do the local inits */
8079         if (bInGlobalSection && !isglobal)
8080                 init_locals();
8081
8082         /* if we've just struck a global section, note the fact. */
8083         bInGlobalSection = isglobal;
8084
8085         /* check for multiple global sections */
8086         if (bInGlobalSection) {
8087                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8088                 return (True);
8089         }
8090
8091         if (!bInGlobalSection && bGlobalOnly)
8092                 return (True);
8093
8094         /* if we have a current service, tidy it up before moving on */
8095         bRetval = True;
8096
8097         if (iServiceIndex >= 0)
8098                 bRetval = service_ok(iServiceIndex);
8099
8100         /* if all is still well, move to the next record in the services array */
8101         if (bRetval) {
8102                 /* We put this here to avoid an odd message order if messages are */
8103                 /* issued by the post-processing of a previous section. */
8104                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8105
8106                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8107                     < 0) {
8108                         DEBUG(0, ("Failed to add a new service\n"));
8109                         return (False);
8110                 }
8111                 /* Clean all parametric options for service */
8112                 /* They will be added during parsing again */
8113                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8114         }
8115
8116         return (bRetval);
8117 }
8118
8119
8120 /***************************************************************************
8121  Determine if a partcular base parameter is currentl set to the default value.
8122 ***************************************************************************/
8123
8124 static bool is_default(int i)
8125 {
8126         if (!defaults_saved)
8127                 return False;
8128         switch (parm_table[i].type) {
8129                 case P_LIST:
8130                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
8131                                                 *(const char ***)parm_table[i].ptr);
8132                 case P_STRING:
8133                 case P_USTRING:
8134                         return strequal(parm_table[i].def.svalue,
8135                                         *(char **)parm_table[i].ptr);
8136                 case P_BOOL:
8137                 case P_BOOLREV:
8138                         return parm_table[i].def.bvalue ==
8139                                 *(bool *)parm_table[i].ptr;
8140                 case P_CHAR:
8141                         return parm_table[i].def.cvalue ==
8142                                 *(char *)parm_table[i].ptr;
8143                 case P_INTEGER:
8144                 case P_OCTAL:
8145                 case P_ENUM:
8146                         return parm_table[i].def.ivalue ==
8147                                 *(int *)parm_table[i].ptr;
8148                 case P_SEP:
8149                         break;
8150         }
8151         return False;
8152 }
8153
8154 /***************************************************************************
8155 Display the contents of the global structure.
8156 ***************************************************************************/
8157
8158 static void dump_globals(FILE *f)
8159 {
8160         int i;
8161         struct param_opt_struct *data;
8162
8163         fprintf(f, "[global]\n");
8164
8165         for (i = 0; parm_table[i].label; i++)
8166                 if (parm_table[i].p_class == P_GLOBAL &&
8167                     !(parm_table[i].flags & FLAG_META) &&
8168                     parm_table[i].ptr &&
8169                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8170                         if (defaults_saved && is_default(i))
8171                                 continue;
8172                         fprintf(f, "\t%s = ", parm_table[i].label);
8173                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
8174                         fprintf(f, "\n");
8175         }
8176         if (Globals.param_opt != NULL) {
8177                 data = Globals.param_opt;
8178                 while(data) {
8179                         fprintf(f, "\t%s = %s\n", data->key, data->value);
8180                         data = data->next;
8181                 }
8182         }
8183
8184 }
8185
8186 /***************************************************************************
8187  Return True if a local parameter is currently set to the global default.
8188 ***************************************************************************/
8189
8190 bool lp_is_default(int snum, struct parm_struct *parm)
8191 {
8192         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8193
8194         return equal_parameter(parm->type,
8195                                ((char *)ServicePtrs[snum]) + pdiff,
8196                                ((char *)&sDefault) + pdiff);
8197 }
8198
8199 /***************************************************************************
8200  Display the contents of a single services record.
8201 ***************************************************************************/
8202
8203 static void dump_a_service(struct service *pService, FILE * f)
8204 {
8205         int i;
8206         struct param_opt_struct *data;
8207
8208         if (pService != &sDefault)
8209                 fprintf(f, "[%s]\n", pService->szService);
8210
8211         for (i = 0; parm_table[i].label; i++) {
8212
8213                 if (parm_table[i].p_class == P_LOCAL &&
8214                     !(parm_table[i].flags & FLAG_META) &&
8215                     parm_table[i].ptr &&
8216                     (*parm_table[i].label != '-') &&
8217                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8218                 {
8219                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8220
8221                         if (pService == &sDefault) {
8222                                 if (defaults_saved && is_default(i))
8223                                         continue;
8224                         } else {
8225                                 if (equal_parameter(parm_table[i].type,
8226                                                     ((char *)pService) +
8227                                                     pdiff,
8228                                                     ((char *)&sDefault) +
8229                                                     pdiff))
8230                                         continue;
8231                         }
8232
8233                         fprintf(f, "\t%s = ", parm_table[i].label);
8234                         print_parameter(&parm_table[i],
8235                                         ((char *)pService) + pdiff, f);
8236                         fprintf(f, "\n");
8237                 }
8238         }
8239
8240                 if (pService->param_opt != NULL) {
8241                         data = pService->param_opt;
8242                         while(data) {
8243                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8244                                 data = data->next;
8245                         }
8246                 }
8247 }
8248
8249 /***************************************************************************
8250  Display the contents of a parameter of a single services record.
8251 ***************************************************************************/
8252
8253 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8254 {
8255         int i;
8256         bool result = False;
8257         parm_class p_class;
8258         unsigned flag = 0;
8259         fstring local_parm_name;
8260         char *parm_opt;
8261         const char *parm_opt_value;
8262
8263         /* check for parametrical option */
8264         fstrcpy( local_parm_name, parm_name);
8265         parm_opt = strchr( local_parm_name, ':');
8266
8267         if (parm_opt) {
8268                 *parm_opt = '\0';
8269                 parm_opt++;
8270                 if (strlen(parm_opt)) {
8271                         parm_opt_value = lp_parm_const_string( snum,
8272                                 local_parm_name, parm_opt, NULL);
8273                         if (parm_opt_value) {
8274                                 printf( "%s\n", parm_opt_value);
8275                                 result = True;
8276                         }
8277                 }
8278                 return result;
8279         }
8280
8281         /* check for a key and print the value */
8282         if (isGlobal) {
8283                 p_class = P_GLOBAL;
8284                 flag = FLAG_GLOBAL;
8285         } else
8286                 p_class = P_LOCAL;
8287
8288         for (i = 0; parm_table[i].label; i++) {
8289                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8290                     !(parm_table[i].flags & FLAG_META) &&
8291                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8292                     parm_table[i].ptr &&
8293                     (*parm_table[i].label != '-') &&
8294                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8295                 {
8296                         void *ptr;
8297
8298                         if (isGlobal) {
8299                                 ptr = parm_table[i].ptr;
8300                         } else {
8301                                 struct service *pService = ServicePtrs[snum];
8302                                 ptr = ((char *)pService) +
8303                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
8304                         }
8305
8306                         print_parameter(&parm_table[i],
8307                                         ptr, f);
8308                         fprintf(f, "\n");
8309                         result = True;
8310                         break;
8311                 }
8312         }
8313
8314         return result;
8315 }
8316
8317 /***************************************************************************
8318  Return info about the requested parameter (given as a string).
8319  Return NULL when the string is not a valid parameter name.
8320 ***************************************************************************/
8321
8322 struct parm_struct *lp_get_parameter(const char *param_name)
8323 {
8324         int num = map_parameter(param_name);
8325
8326         if (num < 0) {
8327                 return NULL;
8328         }
8329
8330         return &parm_table[num];
8331 }
8332
8333 /***************************************************************************
8334  Return info about the next parameter in a service.
8335  snum==GLOBAL_SECTION_SNUM gives the globals.
8336  Return NULL when out of parameters.
8337 ***************************************************************************/
8338
8339 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8340 {
8341         if (snum < 0) {
8342                 /* do the globals */
8343                 for (; parm_table[*i].label; (*i)++) {
8344                         if (parm_table[*i].p_class == P_SEPARATOR)
8345                                 return &parm_table[(*i)++];
8346
8347                         if (!parm_table[*i].ptr
8348                             || (*parm_table[*i].label == '-'))
8349                                 continue;
8350
8351                         if ((*i) > 0
8352                             && (parm_table[*i].ptr ==
8353                                 parm_table[(*i) - 1].ptr))
8354                                 continue;
8355
8356                         if (is_default(*i) && !allparameters)
8357                                 continue;
8358
8359                         return &parm_table[(*i)++];
8360                 }
8361         } else {
8362                 struct service *pService = ServicePtrs[snum];
8363
8364                 for (; parm_table[*i].label; (*i)++) {
8365                         if (parm_table[*i].p_class == P_SEPARATOR)
8366                                 return &parm_table[(*i)++];
8367
8368                         if (parm_table[*i].p_class == P_LOCAL &&
8369                             parm_table[*i].ptr &&
8370                             (*parm_table[*i].label != '-') &&
8371                             ((*i) == 0 ||
8372                              (parm_table[*i].ptr !=
8373                               parm_table[(*i) - 1].ptr)))
8374                         {
8375                                 int pdiff =
8376                                         PTR_DIFF(parm_table[*i].ptr,
8377                                                  &sDefault);
8378
8379                                 if (allparameters ||
8380                                     !equal_parameter(parm_table[*i].type,
8381                                                      ((char *)pService) +
8382                                                      pdiff,
8383                                                      ((char *)&sDefault) +
8384                                                      pdiff))
8385                                 {
8386                                         return &parm_table[(*i)++];
8387                                 }
8388                         }
8389                 }
8390         }
8391
8392         return NULL;
8393 }
8394
8395
8396 #if 0
8397 /***************************************************************************
8398  Display the contents of a single copy structure.
8399 ***************************************************************************/
8400 static void dump_copy_map(bool *pcopymap)
8401 {
8402         int i;
8403         if (!pcopymap)
8404                 return;
8405
8406         printf("\n\tNon-Copied parameters:\n");
8407
8408         for (i = 0; parm_table[i].label; i++)
8409                 if (parm_table[i].p_class == P_LOCAL &&
8410                     parm_table[i].ptr && !pcopymap[i] &&
8411                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8412                 {
8413                         printf("\t\t%s\n", parm_table[i].label);
8414                 }
8415 }
8416 #endif
8417
8418 /***************************************************************************
8419  Return TRUE if the passed service number is within range.
8420 ***************************************************************************/
8421
8422 bool lp_snum_ok(int iService)
8423 {
8424         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8425 }
8426
8427 /***************************************************************************
8428  Auto-load some home services.
8429 ***************************************************************************/
8430
8431 static void lp_add_auto_services(char *str)
8432 {
8433         char *s;
8434         char *p;
8435         int homes;
8436         char *saveptr;
8437
8438         if (!str)
8439                 return;
8440
8441         s = SMB_STRDUP(str);
8442         if (!s)
8443                 return;
8444
8445         homes = lp_servicenumber(HOMES_NAME);
8446
8447         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8448              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8449                 char *home;
8450
8451                 if (lp_servicenumber(p) >= 0)
8452                         continue;
8453
8454                 home = get_user_home_dir(talloc_tos(), p);
8455
8456                 if (home && home[0] && homes >= 0)
8457                         lp_add_home(p, homes, p, home);
8458
8459                 TALLOC_FREE(home);
8460         }
8461         SAFE_FREE(s);
8462 }
8463
8464 /***************************************************************************
8465  Auto-load one printer.
8466 ***************************************************************************/
8467
8468 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8469 {
8470         int printers = lp_servicenumber(PRINTERS_NAME);
8471         int i;
8472
8473         if (lp_servicenumber(name) < 0) {
8474                 lp_add_printer(name, printers);
8475                 if ((i = lp_servicenumber(name)) >= 0) {
8476                         string_set(&ServicePtrs[i]->comment, comment);
8477                         ServicePtrs[i]->autoloaded = True;
8478                 }
8479         }
8480 }
8481
8482 /***************************************************************************
8483  Have we loaded a services file yet?
8484 ***************************************************************************/
8485
8486 bool lp_loaded(void)
8487 {
8488         return (bLoaded);
8489 }
8490
8491 /***************************************************************************
8492  Unload unused services.
8493 ***************************************************************************/
8494
8495 void lp_killunused(bool (*snumused) (int))
8496 {
8497         int i;
8498         for (i = 0; i < iNumServices; i++) {
8499                 if (!VALID(i))
8500                         continue;
8501
8502                 /* don't kill autoloaded or usershare services */
8503                 if ( ServicePtrs[i]->autoloaded ||
8504                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8505                         continue;
8506                 }
8507
8508                 if (!snumused || !snumused(i)) {
8509                         free_service_byindex(i);
8510                 }
8511         }
8512 }
8513
8514 /**
8515  * Kill all except autoloaded and usershare services - convenience wrapper
8516  */
8517 void lp_kill_all_services(void)
8518 {
8519         lp_killunused(NULL);
8520 }
8521
8522 /***************************************************************************
8523  Unload a service.
8524 ***************************************************************************/
8525
8526 void lp_killservice(int iServiceIn)
8527 {
8528         if (VALID(iServiceIn)) {
8529                 free_service_byindex(iServiceIn);
8530         }
8531 }
8532
8533 /***************************************************************************
8534  Save the curent values of all global and sDefault parameters into the 
8535  defaults union. This allows swat and testparm to show only the
8536  changed (ie. non-default) parameters.
8537 ***************************************************************************/
8538
8539 static void lp_save_defaults(void)
8540 {
8541         int i;
8542         for (i = 0; parm_table[i].label; i++) {
8543                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8544                         continue;
8545                 switch (parm_table[i].type) {
8546                         case P_LIST:
8547                                 parm_table[i].def.lvalue = str_list_copy(
8548                                         NULL, *(const char ***)parm_table[i].ptr);
8549                                 break;
8550                         case P_STRING:
8551                         case P_USTRING:
8552                                 if (parm_table[i].ptr) {
8553                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8554                                 } else {
8555                                         parm_table[i].def.svalue = NULL;
8556                                 }
8557                                 break;
8558                         case P_BOOL:
8559                         case P_BOOLREV:
8560                                 parm_table[i].def.bvalue =
8561                                         *(bool *)parm_table[i].ptr;
8562                                 break;
8563                         case P_CHAR:
8564                                 parm_table[i].def.cvalue =
8565                                         *(char *)parm_table[i].ptr;
8566                                 break;
8567                         case P_INTEGER:
8568                         case P_OCTAL:
8569                         case P_ENUM:
8570                                 parm_table[i].def.ivalue =
8571                                         *(int *)parm_table[i].ptr;
8572                                 break;
8573                         case P_SEP:
8574                                 break;
8575                 }
8576         }
8577         defaults_saved = True;
8578 }
8579
8580 /***********************************************************
8581  If we should send plaintext/LANMAN passwords in the clinet
8582 ************************************************************/
8583
8584 static void set_allowed_client_auth(void)
8585 {
8586         if (Globals.bClientNTLMv2Auth) {
8587                 Globals.bClientLanManAuth = False;
8588         }
8589         if (!Globals.bClientLanManAuth) {
8590                 Globals.bClientPlaintextAuth = False;
8591         }
8592 }
8593
8594 /***************************************************************************
8595  JRA.
8596  The following code allows smbd to read a user defined share file.
8597  Yes, this is my intent. Yes, I'm comfortable with that...
8598
8599  THE FOLLOWING IS SECURITY CRITICAL CODE.
8600
8601  It washes your clothes, it cleans your house, it guards you while you sleep...
8602  Do not f%^k with it....
8603 ***************************************************************************/
8604
8605 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8606
8607 /***************************************************************************
8608  Check allowed stat state of a usershare file.
8609  Ensure we print out who is dicking with us so the admin can
8610  get their sorry ass fired.
8611 ***************************************************************************/
8612
8613 static bool check_usershare_stat(const char *fname,
8614                                  const SMB_STRUCT_STAT *psbuf)
8615 {
8616         if (!S_ISREG(psbuf->st_ex_mode)) {
8617                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8618                         "not a regular file\n",
8619                         fname, (unsigned int)psbuf->st_ex_uid ));
8620                 return False;
8621         }
8622
8623         /* Ensure this doesn't have the other write bit set. */
8624         if (psbuf->st_ex_mode & S_IWOTH) {
8625                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8626                         "public write. Refusing to allow as a usershare file.\n",
8627                         fname, (unsigned int)psbuf->st_ex_uid ));
8628                 return False;
8629         }
8630
8631         /* Should be 10k or less. */
8632         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8633                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8634                         "too large (%u) to be a user share file.\n",
8635                         fname, (unsigned int)psbuf->st_ex_uid,
8636                         (unsigned int)psbuf->st_ex_size ));
8637                 return False;
8638         }
8639
8640         return True;
8641 }
8642
8643 /***************************************************************************
8644  Parse the contents of a usershare file.
8645 ***************************************************************************/
8646
8647 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8648                         SMB_STRUCT_STAT *psbuf,
8649                         const char *servicename,
8650                         int snum,
8651                         char **lines,
8652                         int numlines,
8653                         char **pp_sharepath,
8654                         char **pp_comment,
8655                         char **pp_cp_servicename,
8656                         struct security_descriptor **ppsd,
8657                         bool *pallow_guest)
8658 {
8659         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8660         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8661         int us_vers;
8662         SMB_STRUCT_DIR *dp;
8663         SMB_STRUCT_STAT sbuf;
8664         char *sharepath = NULL;
8665         char *comment = NULL;
8666
8667         *pp_sharepath = NULL;
8668         *pp_comment = NULL;
8669
8670         *pallow_guest = False;
8671
8672         if (numlines < 4) {
8673                 return USERSHARE_MALFORMED_FILE;
8674         }
8675
8676         if (strcmp(lines[0], "#VERSION 1") == 0) {
8677                 us_vers = 1;
8678         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8679                 us_vers = 2;
8680                 if (numlines < 5) {
8681                         return USERSHARE_MALFORMED_FILE;
8682                 }
8683         } else {
8684                 return USERSHARE_BAD_VERSION;
8685         }
8686
8687         if (strncmp(lines[1], "path=", 5) != 0) {
8688                 return USERSHARE_MALFORMED_PATH;
8689         }
8690
8691         sharepath = talloc_strdup(ctx, &lines[1][5]);
8692         if (!sharepath) {
8693                 return USERSHARE_POSIX_ERR;
8694         }
8695         trim_string(sharepath, " ", " ");
8696
8697         if (strncmp(lines[2], "comment=", 8) != 0) {
8698                 return USERSHARE_MALFORMED_COMMENT_DEF;
8699         }
8700
8701         comment = talloc_strdup(ctx, &lines[2][8]);
8702         if (!comment) {
8703                 return USERSHARE_POSIX_ERR;
8704         }
8705         trim_string(comment, " ", " ");
8706         trim_char(comment, '"', '"');
8707
8708         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8709                 return USERSHARE_MALFORMED_ACL_DEF;
8710         }
8711
8712         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8713                 return USERSHARE_ACL_ERR;
8714         }
8715
8716         if (us_vers == 2) {
8717                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8718                         return USERSHARE_MALFORMED_ACL_DEF;
8719                 }
8720                 if (lines[4][9] == 'y') {
8721                         *pallow_guest = True;
8722                 }
8723
8724                 /* Backwards compatible extension to file version #2. */
8725                 if (numlines > 5) {
8726                         if (strncmp(lines[5], "sharename=", 10) != 0) {
8727                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
8728                         }
8729                         if (!strequal(&lines[5][10], servicename)) {
8730                                 return USERSHARE_BAD_SHARENAME;
8731                         }
8732                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8733                         if (!*pp_cp_servicename) {
8734                                 return USERSHARE_POSIX_ERR;
8735                         }
8736                 }
8737         }
8738
8739         if (*pp_cp_servicename == NULL) {
8740                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8741                 if (!*pp_cp_servicename) {
8742                         return USERSHARE_POSIX_ERR;
8743                 }
8744         }
8745
8746         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8747                 /* Path didn't change, no checks needed. */
8748                 *pp_sharepath = sharepath;
8749                 *pp_comment = comment;
8750                 return USERSHARE_OK;
8751         }
8752
8753         /* The path *must* be absolute. */
8754         if (sharepath[0] != '/') {
8755                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8756                         servicename, sharepath));
8757                 return USERSHARE_PATH_NOT_ABSOLUTE;
8758         }
8759
8760         /* If there is a usershare prefix deny list ensure one of these paths
8761            doesn't match the start of the user given path. */
8762         if (prefixdenylist) {
8763                 int i;
8764                 for ( i=0; prefixdenylist[i]; i++ ) {
8765                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8766                                 servicename, i, prefixdenylist[i], sharepath ));
8767                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8768                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8769                                         "usershare prefix deny list entries.\n",
8770                                         servicename, sharepath));
8771                                 return USERSHARE_PATH_IS_DENIED;
8772                         }
8773                 }
8774         }
8775
8776         /* If there is a usershare prefix allow list ensure one of these paths
8777            does match the start of the user given path. */
8778
8779         if (prefixallowlist) {
8780                 int i;
8781                 for ( i=0; prefixallowlist[i]; i++ ) {
8782                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8783                                 servicename, i, prefixallowlist[i], sharepath ));
8784                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8785                                 break;
8786                         }
8787                 }
8788                 if (prefixallowlist[i] == NULL) {
8789                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8790                                 "usershare prefix allow list entries.\n",
8791                                 servicename, sharepath));
8792                         return USERSHARE_PATH_NOT_ALLOWED;
8793                 }
8794         }
8795
8796         /* Ensure this is pointing to a directory. */
8797         dp = sys_opendir(sharepath);
8798
8799         if (!dp) {
8800                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8801                         servicename, sharepath));
8802                 return USERSHARE_PATH_NOT_DIRECTORY;
8803         }
8804
8805         /* Ensure the owner of the usershare file has permission to share
8806            this directory. */
8807
8808         if (sys_stat(sharepath, &sbuf, false) == -1) {
8809                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8810                         servicename, sharepath, strerror(errno) ));
8811                 sys_closedir(dp);
8812                 return USERSHARE_POSIX_ERR;
8813         }
8814
8815         sys_closedir(dp);
8816
8817         if (!S_ISDIR(sbuf.st_ex_mode)) {
8818                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8819                         servicename, sharepath ));
8820                 return USERSHARE_PATH_NOT_DIRECTORY;
8821         }
8822
8823         /* Check if sharing is restricted to owner-only. */
8824         /* psbuf is the stat of the usershare definition file,
8825            sbuf is the stat of the target directory to be shared. */
8826
8827         if (lp_usershare_owner_only()) {
8828                 /* root can share anything. */
8829                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8830                         return USERSHARE_PATH_NOT_ALLOWED;
8831                 }
8832         }
8833
8834         *pp_sharepath = sharepath;
8835         *pp_comment = comment;
8836         return USERSHARE_OK;
8837 }
8838
8839 /***************************************************************************
8840  Deal with a usershare file.
8841  Returns:
8842         >= 0 - snum
8843         -1 - Bad name, invalid contents.
8844            - service name already existed and not a usershare, problem
8845             with permissions to share directory etc.
8846 ***************************************************************************/
8847
8848 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8849 {
8850         SMB_STRUCT_STAT sbuf;
8851         SMB_STRUCT_STAT lsbuf;
8852         char *fname = NULL;
8853         char *sharepath = NULL;
8854         char *comment = NULL;
8855         char *cp_service_name = NULL;
8856         char **lines = NULL;
8857         int numlines = 0;
8858         int fd = -1;
8859         int iService = -1;
8860         TALLOC_CTX *ctx = talloc_stackframe();
8861         struct security_descriptor *psd = NULL;
8862         bool guest_ok = False;
8863         char *canon_name = NULL;
8864         bool added_service = false;
8865         int ret = -1;
8866
8867         /* Ensure share name doesn't contain invalid characters. */
8868         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8869                 DEBUG(0,("process_usershare_file: share name %s contains "
8870                         "invalid characters (any of %s)\n",
8871                         file_name, INVALID_SHARENAME_CHARS ));
8872                 goto out;
8873         }
8874
8875         canon_name = canonicalize_servicename(ctx, file_name);
8876         if (!canon_name) {
8877                 goto out;
8878         }
8879
8880         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8881         if (!fname) {
8882                 goto out;
8883         }
8884
8885         /* Minimize the race condition by doing an lstat before we
8886            open and fstat. Ensure this isn't a symlink link. */
8887
8888         if (sys_lstat(fname, &lsbuf, false) != 0) {
8889                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8890                         fname, strerror(errno) ));
8891                 goto out;
8892         }
8893
8894         /* This must be a regular file, not a symlink, directory or
8895            other strange filetype. */
8896         if (!check_usershare_stat(fname, &lsbuf)) {
8897                 goto out;
8898         }
8899
8900         {
8901                 TDB_DATA data = dbwrap_fetch_bystring(
8902                         ServiceHash, canon_name, canon_name);
8903
8904                 iService = -1;
8905
8906                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8907                         iService = *(int *)data.dptr;
8908                 }
8909         }
8910
8911         if (iService != -1 &&
8912             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8913                              &lsbuf.st_ex_mtime) == 0) {
8914                 /* Nothing changed - Mark valid and return. */
8915                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8916                         canon_name ));
8917                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8918                 ret = iService;
8919                 goto out;
8920         }
8921
8922         /* Try and open the file read only - no symlinks allowed. */
8923 #ifdef O_NOFOLLOW
8924         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8925 #else
8926         fd = sys_open(fname, O_RDONLY, 0);
8927 #endif
8928
8929         if (fd == -1) {
8930                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8931                         fname, strerror(errno) ));
8932                 goto out;
8933         }
8934
8935         /* Now fstat to be *SURE* it's a regular file. */
8936         if (sys_fstat(fd, &sbuf, false) != 0) {
8937                 close(fd);
8938                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8939                         fname, strerror(errno) ));
8940                 goto out;
8941         }
8942
8943         /* Is it the same dev/inode as was lstated ? */
8944         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8945                 close(fd);
8946                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8947                         "Symlink spoofing going on ?\n", fname ));
8948                 goto out;
8949         }
8950
8951         /* This must be a regular file, not a symlink, directory or
8952            other strange filetype. */
8953         if (!check_usershare_stat(fname, &sbuf)) {
8954                 goto out;
8955         }
8956
8957         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8958
8959         close(fd);
8960         if (lines == NULL) {
8961                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8962                         fname, (unsigned int)sbuf.st_ex_uid ));
8963                 goto out;
8964         }
8965
8966         if (parse_usershare_file(ctx, &sbuf, file_name,
8967                         iService, lines, numlines, &sharepath,
8968                         &comment, &cp_service_name,
8969                         &psd, &guest_ok) != USERSHARE_OK) {
8970                 goto out;
8971         }
8972
8973         /* Everything ok - add the service possibly using a template. */
8974         if (iService < 0) {
8975                 const struct service *sp = &sDefault;
8976                 if (snum_template != -1) {
8977                         sp = ServicePtrs[snum_template];
8978                 }
8979
8980                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8981                         DEBUG(0, ("process_usershare_file: Failed to add "
8982                                 "new service %s\n", cp_service_name));
8983                         goto out;
8984                 }
8985
8986                 added_service = true;
8987
8988                 /* Read only is controlled by usershare ACL below. */
8989                 ServicePtrs[iService]->bRead_only = False;
8990         }
8991
8992         /* Write the ACL of the new/modified share. */
8993         if (!set_share_security(canon_name, psd)) {
8994                  DEBUG(0, ("process_usershare_file: Failed to set share "
8995                         "security for user share %s\n",
8996                         canon_name ));
8997                 goto out;
8998         }
8999
9000         /* If from a template it may be marked invalid. */
9001         ServicePtrs[iService]->valid = True;
9002
9003         /* Set the service as a valid usershare. */
9004         ServicePtrs[iService]->usershare = USERSHARE_VALID;
9005
9006         /* Set guest access. */
9007         if (lp_usershare_allow_guests()) {
9008                 ServicePtrs[iService]->bGuest_ok = guest_ok;
9009         }
9010
9011         /* And note when it was loaded. */
9012         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9013         string_set(&ServicePtrs[iService]->szPath, sharepath);
9014         string_set(&ServicePtrs[iService]->comment, comment);
9015
9016         ret = iService;
9017
9018   out:
9019
9020         if (ret == -1 && iService != -1 && added_service) {
9021                 lp_remove_service(iService);
9022         }
9023
9024         TALLOC_FREE(lines);
9025         TALLOC_FREE(ctx);
9026         return ret;
9027 }
9028
9029 /***************************************************************************
9030  Checks if a usershare entry has been modified since last load.
9031 ***************************************************************************/
9032
9033 static bool usershare_exists(int iService, struct timespec *last_mod)
9034 {
9035         SMB_STRUCT_STAT lsbuf;
9036         const char *usersharepath = Globals.szUsersharePath;
9037         char *fname;
9038
9039         if (asprintf(&fname, "%s/%s",
9040                                 usersharepath,
9041                                 ServicePtrs[iService]->szService) < 0) {
9042                 return false;
9043         }
9044
9045         if (sys_lstat(fname, &lsbuf, false) != 0) {
9046                 SAFE_FREE(fname);
9047                 return false;
9048         }
9049
9050         if (!S_ISREG(lsbuf.st_ex_mode)) {
9051                 SAFE_FREE(fname);
9052                 return false;
9053         }
9054
9055         SAFE_FREE(fname);
9056         *last_mod = lsbuf.st_ex_mtime;
9057         return true;
9058 }
9059
9060 /***************************************************************************
9061  Load a usershare service by name. Returns a valid servicenumber or -1.
9062 ***************************************************************************/
9063
9064 int load_usershare_service(const char *servicename)
9065 {
9066         SMB_STRUCT_STAT sbuf;
9067         const char *usersharepath = Globals.szUsersharePath;
9068         int max_user_shares = Globals.iUsershareMaxShares;
9069         int snum_template = -1;
9070
9071         if (*usersharepath == 0 ||  max_user_shares == 0) {
9072                 return -1;
9073         }
9074
9075         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9076                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9077                         usersharepath, strerror(errno) ));
9078                 return -1;
9079         }
9080
9081         if (!S_ISDIR(sbuf.st_ex_mode)) {
9082                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9083                         usersharepath ));
9084                 return -1;
9085         }
9086
9087         /*
9088          * This directory must be owned by root, and have the 't' bit set.
9089          * It also must not be writable by "other".
9090          */
9091
9092 #ifdef S_ISVTX
9093         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9094 #else
9095         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9096 #endif
9097                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9098                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9099                         usersharepath ));
9100                 return -1;
9101         }
9102
9103         /* Ensure the template share exists if it's set. */
9104         if (Globals.szUsershareTemplateShare[0]) {
9105                 /* We can't use lp_servicenumber here as we are recommending that
9106                    template shares have -valid=False set. */
9107                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9108                         if (ServicePtrs[snum_template]->szService &&
9109                                         strequal(ServicePtrs[snum_template]->szService,
9110                                                 Globals.szUsershareTemplateShare)) {
9111                                 break;
9112                         }
9113                 }
9114
9115                 if (snum_template == -1) {
9116                         DEBUG(0,("load_usershare_service: usershare template share %s "
9117                                 "does not exist.\n",
9118                                 Globals.szUsershareTemplateShare ));
9119                         return -1;
9120                 }
9121         }
9122
9123         return process_usershare_file(usersharepath, servicename, snum_template);
9124 }
9125
9126 /***************************************************************************
9127  Load all user defined shares from the user share directory.
9128  We only do this if we're enumerating the share list.
9129  This is the function that can delete usershares that have
9130  been removed.
9131 ***************************************************************************/
9132
9133 int load_usershare_shares(void)
9134 {
9135         SMB_STRUCT_DIR *dp;
9136         SMB_STRUCT_STAT sbuf;
9137         SMB_STRUCT_DIRENT *de;
9138         int num_usershares = 0;
9139         int max_user_shares = Globals.iUsershareMaxShares;
9140         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9141         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9142         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9143         int iService;
9144         int snum_template = -1;
9145         const char *usersharepath = Globals.szUsersharePath;
9146         int ret = lp_numservices();
9147
9148         if (max_user_shares == 0 || *usersharepath == '\0') {
9149                 return lp_numservices();
9150         }
9151
9152         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9153                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9154                         usersharepath, strerror(errno) ));
9155                 return ret;
9156         }
9157
9158         /*
9159          * This directory must be owned by root, and have the 't' bit set.
9160          * It also must not be writable by "other".
9161          */
9162
9163 #ifdef S_ISVTX
9164         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9165 #else
9166         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9167 #endif
9168                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9169                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9170                         usersharepath ));
9171                 return ret;
9172         }
9173
9174         /* Ensure the template share exists if it's set. */
9175         if (Globals.szUsershareTemplateShare[0]) {
9176                 /* We can't use lp_servicenumber here as we are recommending that
9177                    template shares have -valid=False set. */
9178                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9179                         if (ServicePtrs[snum_template]->szService &&
9180                                         strequal(ServicePtrs[snum_template]->szService,
9181                                                 Globals.szUsershareTemplateShare)) {
9182                                 break;
9183                         }
9184                 }
9185
9186                 if (snum_template == -1) {
9187                         DEBUG(0,("load_usershare_shares: usershare template share %s "
9188                                 "does not exist.\n",
9189                                 Globals.szUsershareTemplateShare ));
9190                         return ret;
9191                 }
9192         }
9193
9194         /* Mark all existing usershares as pending delete. */
9195         for (iService = iNumServices - 1; iService >= 0; iService--) {
9196                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9197                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9198                 }
9199         }
9200
9201         dp = sys_opendir(usersharepath);
9202         if (!dp) {
9203                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9204                         usersharepath, strerror(errno) ));
9205                 return ret;
9206         }
9207
9208         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9209                         (de = sys_readdir(dp));
9210                         num_dir_entries++ ) {
9211                 int r;
9212                 const char *n = de->d_name;
9213
9214                 /* Ignore . and .. */
9215                 if (*n == '.') {
9216                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9217                                 continue;
9218                         }
9219                 }
9220
9221                 if (n[0] == ':') {
9222                         /* Temporary file used when creating a share. */
9223                         num_tmp_dir_entries++;
9224                 }
9225
9226                 /* Allow 20% tmp entries. */
9227                 if (num_tmp_dir_entries > allowed_tmp_entries) {
9228                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9229                                 "in directory %s\n",
9230                                 num_tmp_dir_entries, usersharepath));
9231                         break;
9232                 }
9233
9234                 r = process_usershare_file(usersharepath, n, snum_template);
9235                 if (r == 0) {
9236                         /* Update the services count. */
9237                         num_usershares++;
9238                         if (num_usershares >= max_user_shares) {
9239                                 DEBUG(0,("load_usershare_shares: max user shares reached "
9240                                         "on file %s in directory %s\n",
9241                                         n, usersharepath ));
9242                                 break;
9243                         }
9244                 } else if (r == -1) {
9245                         num_bad_dir_entries++;
9246                 }
9247
9248                 /* Allow 20% bad entries. */
9249                 if (num_bad_dir_entries > allowed_bad_entries) {
9250                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9251                                 "in directory %s\n",
9252                                 num_bad_dir_entries, usersharepath));
9253                         break;
9254                 }
9255
9256                 /* Allow 20% bad entries. */
9257                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9258                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9259                         "in directory %s\n",
9260                         num_dir_entries, usersharepath));
9261                         break;
9262                 }
9263         }
9264
9265         sys_closedir(dp);
9266
9267         /* Sweep through and delete any non-refreshed usershares that are
9268            not currently in use. */
9269         for (iService = iNumServices - 1; iService >= 0; iService--) {
9270                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9271                         if (conn_snum_used(iService)) {
9272                                 continue;
9273                         }
9274                         /* Remove from the share ACL db. */
9275                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9276                                 lp_servicename(iService) ));
9277                         delete_share_security(lp_servicename(iService));
9278                         free_service_byindex(iService);
9279                 }
9280         }
9281
9282         return lp_numservices();
9283 }
9284
9285 /********************************************************
9286  Destroy global resources allocated in this file
9287 ********************************************************/
9288
9289 void gfree_loadparm(void)
9290 {
9291         int i;
9292
9293         free_file_list();
9294
9295         /* Free resources allocated to services */
9296
9297         for ( i = 0; i < iNumServices; i++ ) {
9298                 if ( VALID(i) ) {
9299                         free_service_byindex(i);
9300                 }
9301         }
9302
9303         SAFE_FREE( ServicePtrs );
9304         iNumServices = 0;
9305
9306         /* Now release all resources allocated to global
9307            parameters and the default service */
9308
9309         free_global_parameters();
9310 }
9311
9312
9313 /***************************************************************************
9314  Allow client apps to specify that they are a client
9315 ***************************************************************************/
9316 void lp_set_in_client(bool b)
9317 {
9318     in_client = b;
9319 }
9320
9321
9322 /***************************************************************************
9323  Determine if we're running in a client app
9324 ***************************************************************************/
9325 bool lp_is_in_client(void)
9326 {
9327     return in_client;
9328 }
9329
9330 /***************************************************************************
9331  Load the services array from the services file. Return True on success, 
9332  False on failure.
9333 ***************************************************************************/
9334
9335 static bool lp_load_ex(const char *pszFname,
9336                        bool global_only,
9337                        bool save_defaults,
9338                        bool add_ipc,
9339                        bool initialize_globals,
9340                        bool allow_include_registry,
9341                        bool allow_registry_shares)
9342 {
9343         char *n2 = NULL;
9344         bool bRetval;
9345
9346         bRetval = False;
9347
9348         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9349
9350         bInGlobalSection = True;
9351         bGlobalOnly = global_only;
9352         bAllowIncludeRegistry = allow_include_registry;
9353
9354         init_globals(initialize_globals);
9355         debug_init();
9356
9357         free_file_list();
9358
9359         if (save_defaults) {
9360                 init_locals();
9361                 lp_save_defaults();
9362         }
9363
9364         free_param_opts(&Globals.param_opt);
9365
9366         /* We get sections first, so have to start 'behind' to make up */
9367         iServiceIndex = -1;
9368
9369         if (lp_config_backend_is_file()) {
9370                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9371                                         current_user_info.domain,
9372                                         pszFname);
9373                 if (!n2) {
9374                         smb_panic("lp_load_ex: out of memory");
9375                 }
9376
9377                 add_to_file_list(pszFname, n2);
9378
9379                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9380                 TALLOC_FREE(n2);
9381
9382                 /* finish up the last section */
9383                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9384                 if (bRetval) {
9385                         if (iServiceIndex >= 0) {
9386                                 bRetval = service_ok(iServiceIndex);
9387                         }
9388                 }
9389
9390                 if (lp_config_backend_is_registry()) {
9391                         /* config backend changed to registry in config file */
9392                         /*
9393                          * We need to use this extra global variable here to
9394                          * survive restart: init_globals uses this as a default
9395                          * for ConfigBackend. Otherwise, init_globals would
9396                          *  send us into an endless loop here.
9397                          */
9398                         config_backend = CONFIG_BACKEND_REGISTRY;
9399                         /* start over */
9400                         DEBUG(1, ("lp_load_ex: changing to config backend "
9401                                   "registry\n"));
9402                         init_globals(true);
9403                         lp_kill_all_services();
9404                         return lp_load_ex(pszFname, global_only, save_defaults,
9405                                           add_ipc, initialize_globals,
9406                                           allow_include_registry,
9407                                           allow_registry_shares);
9408                 }
9409         } else if (lp_config_backend_is_registry()) {
9410                 bRetval = process_registry_globals();
9411         } else {
9412                 DEBUG(0, ("Illegal config  backend given: %d\n",
9413                           lp_config_backend()));
9414                 bRetval = false;
9415         }
9416
9417         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9418                 bRetval = process_registry_shares();
9419         }
9420
9421         lp_add_auto_services(lp_auto_services());
9422
9423         if (add_ipc) {
9424                 /* When 'restrict anonymous = 2' guest connections to ipc$
9425                    are denied */
9426                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9427                 if ( lp_enable_asu_support() ) {
9428                         lp_add_ipc("ADMIN$", false);
9429                 }
9430         }
9431
9432         set_server_role();
9433         set_default_server_announce_type();
9434         set_allowed_client_auth();
9435
9436         bLoaded = True;
9437
9438         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9439         /* if bWINSsupport is true and we are in the client            */
9440         if (lp_is_in_client() && Globals.bWINSsupport) {
9441                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9442         }
9443
9444         init_iconv();
9445
9446         bAllowIncludeRegistry = true;
9447
9448         return (bRetval);
9449 }
9450
9451 bool lp_load(const char *pszFname,
9452              bool global_only,
9453              bool save_defaults,
9454              bool add_ipc,
9455              bool initialize_globals)
9456 {
9457         return lp_load_ex(pszFname,
9458                           global_only,
9459                           save_defaults,
9460                           add_ipc,
9461                           initialize_globals,
9462                           true,   /* allow_include_registry */
9463                           false); /* allow_registry_shares*/
9464 }
9465
9466 bool lp_load_initial_only(const char *pszFname)
9467 {
9468         return lp_load_ex(pszFname,
9469                           true,   /* global only */
9470                           false,  /* save_defaults */
9471                           false,  /* add_ipc */
9472                           true,   /* initialize_globals */
9473                           false,  /* allow_include_registry */
9474                           false); /* allow_registry_shares*/
9475 }
9476
9477 bool lp_load_with_registry_shares(const char *pszFname,
9478                                   bool global_only,
9479                                   bool save_defaults,
9480                                   bool add_ipc,
9481                                   bool initialize_globals)
9482 {
9483         return lp_load_ex(pszFname,
9484                           global_only,
9485                           save_defaults,
9486                           add_ipc,
9487                           initialize_globals,
9488                           true,  /* allow_include_registry */
9489                           true); /* allow_registry_shares*/
9490 }
9491
9492 /***************************************************************************
9493  Return the max number of services.
9494 ***************************************************************************/
9495
9496 int lp_numservices(void)
9497 {
9498         return (iNumServices);
9499 }
9500
9501 /***************************************************************************
9502 Display the contents of the services array in human-readable form.
9503 ***************************************************************************/
9504
9505 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9506 {
9507         int iService;
9508
9509         if (show_defaults)
9510                 defaults_saved = False;
9511
9512         dump_globals(f);
9513
9514         dump_a_service(&sDefault, f);
9515
9516         for (iService = 0; iService < maxtoprint; iService++) {
9517                 fprintf(f,"\n");
9518                 lp_dump_one(f, show_defaults, iService);
9519         }
9520 }
9521
9522 /***************************************************************************
9523 Display the contents of one service in human-readable form.
9524 ***************************************************************************/
9525
9526 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9527 {
9528         if (VALID(snum)) {
9529                 if (ServicePtrs[snum]->szService[0] == '\0')
9530                         return;
9531                 dump_a_service(ServicePtrs[snum], f);
9532         }
9533 }
9534
9535 /***************************************************************************
9536 Return the number of the service with the given name, or -1 if it doesn't
9537 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9538 getservicebyname()! This works ONLY if all services have been loaded, and
9539 does not copy the found service.
9540 ***************************************************************************/
9541
9542 int lp_servicenumber(const char *pszServiceName)
9543 {
9544         int iService;
9545         fstring serviceName;
9546
9547         if (!pszServiceName) {
9548                 return GLOBAL_SECTION_SNUM;
9549         }
9550
9551         for (iService = iNumServices - 1; iService >= 0; iService--) {
9552                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9553                         /*
9554                          * The substitution here is used to support %U is
9555                          * service names
9556                          */
9557                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9558                         standard_sub_basic(get_current_username(),
9559                                            current_user_info.domain,
9560                                            serviceName,sizeof(serviceName));
9561                         if (strequal(serviceName, pszServiceName)) {
9562                                 break;
9563                         }
9564                 }
9565         }
9566
9567         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9568                 struct timespec last_mod;
9569
9570                 if (!usershare_exists(iService, &last_mod)) {
9571                         /* Remove the share security tdb entry for it. */
9572                         delete_share_security(lp_servicename(iService));
9573                         /* Remove it from the array. */
9574                         free_service_byindex(iService);
9575                         /* Doesn't exist anymore. */
9576                         return GLOBAL_SECTION_SNUM;
9577                 }
9578
9579                 /* Has it been modified ? If so delete and reload. */
9580                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9581                                      &last_mod) < 0) {
9582                         /* Remove it from the array. */
9583                         free_service_byindex(iService);
9584                         /* and now reload it. */
9585                         iService = load_usershare_service(pszServiceName);
9586                 }
9587         }
9588
9589         if (iService < 0) {
9590                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9591                 return GLOBAL_SECTION_SNUM;
9592         }
9593
9594         return (iService);
9595 }
9596
9597 bool share_defined(const char *service_name)
9598 {
9599         return (lp_servicenumber(service_name) != -1);
9600 }
9601
9602 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9603                                       const char *sharename)
9604 {
9605         struct share_params *result;
9606         char *sname;
9607         int snum;
9608
9609         if (!(sname = SMB_STRDUP(sharename))) {
9610                 return NULL;
9611         }
9612
9613         snum = find_service(sname);
9614         SAFE_FREE(sname);
9615
9616         if (snum < 0) {
9617                 return NULL;
9618         }
9619
9620         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9621                 DEBUG(0, ("talloc failed\n"));
9622                 return NULL;
9623         }
9624
9625         result->service = snum;
9626         return result;
9627 }
9628
9629 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9630 {
9631         struct share_iterator *result;
9632
9633         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9634                 DEBUG(0, ("talloc failed\n"));
9635                 return NULL;
9636         }
9637
9638         result->next_id = 0;
9639         return result;
9640 }
9641
9642 struct share_params *next_share(struct share_iterator *list)
9643 {
9644         struct share_params *result;
9645
9646         while (!lp_snum_ok(list->next_id) &&
9647                (list->next_id < lp_numservices())) {
9648                 list->next_id += 1;
9649         }
9650
9651         if (list->next_id >= lp_numservices()) {
9652                 return NULL;
9653         }
9654
9655         if (!(result = TALLOC_P(list, struct share_params))) {
9656                 DEBUG(0, ("talloc failed\n"));
9657                 return NULL;
9658         }
9659
9660         result->service = list->next_id;
9661         list->next_id += 1;
9662         return result;
9663 }
9664
9665 struct share_params *next_printer(struct share_iterator *list)
9666 {
9667         struct share_params *result;
9668
9669         while ((result = next_share(list)) != NULL) {
9670                 if (lp_print_ok(result->service)) {
9671                         break;
9672                 }
9673         }
9674         return result;
9675 }
9676
9677 /*
9678  * This is a hack for a transition period until we transformed all code from
9679  * service numbers to struct share_params.
9680  */
9681
9682 struct share_params *snum2params_static(int snum)
9683 {
9684         static struct share_params result;
9685         result.service = snum;
9686         return &result;
9687 }
9688
9689 /*******************************************************************
9690  A useful volume label function. 
9691 ********************************************************************/
9692
9693 const char *volume_label(int snum)
9694 {
9695         char *ret;
9696         const char *label = lp_volume(snum);
9697         if (!*label) {
9698                 label = lp_servicename(snum);
9699         }
9700
9701         /* This returns a 33 byte guarenteed null terminated string. */
9702         ret = talloc_strndup(talloc_tos(), label, 32);
9703         if (!ret) {
9704                 return "";
9705         }               
9706         return ret;
9707 }
9708
9709 /*******************************************************************
9710  Set the server type we will announce as via nmbd.
9711 ********************************************************************/
9712
9713 static void set_default_server_announce_type(void)
9714 {
9715         default_server_announce = 0;
9716         default_server_announce |= SV_TYPE_WORKSTATION;
9717         default_server_announce |= SV_TYPE_SERVER;
9718         default_server_announce |= SV_TYPE_SERVER_UNIX;
9719
9720         /* note that the flag should be set only if we have a 
9721            printer service but nmbd doesn't actually load the 
9722            services so we can't tell   --jerry */
9723
9724         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9725
9726         switch (lp_announce_as()) {
9727                 case ANNOUNCE_AS_NT_SERVER:
9728                         default_server_announce |= SV_TYPE_SERVER_NT;
9729                         /* fall through... */
9730                 case ANNOUNCE_AS_NT_WORKSTATION:
9731                         default_server_announce |= SV_TYPE_NT;
9732                         break;
9733                 case ANNOUNCE_AS_WIN95:
9734                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9735                         break;
9736                 case ANNOUNCE_AS_WFW:
9737                         default_server_announce |= SV_TYPE_WFW;
9738                         break;
9739                 default:
9740                         break;
9741         }
9742
9743         switch (lp_server_role()) {
9744                 case ROLE_DOMAIN_MEMBER:
9745                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9746                         break;
9747                 case ROLE_DOMAIN_PDC:
9748                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9749                         break;
9750                 case ROLE_DOMAIN_BDC:
9751                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9752                         break;
9753                 case ROLE_STANDALONE:
9754                 default:
9755                         break;
9756         }
9757         if (lp_time_server())
9758                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9759
9760         if (lp_host_msdfs())
9761                 default_server_announce |= SV_TYPE_DFS_SERVER;
9762 }
9763
9764 /***********************************************************
9765  If we are PDC then prefer us as DMB
9766 ************************************************************/
9767
9768 bool lp_domain_master(void)
9769 {
9770         if (Globals.iDomainMaster == Auto)
9771                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9772
9773         return (bool)Globals.iDomainMaster;
9774 }
9775
9776 /***********************************************************
9777  If we are PDC then prefer us as DMB
9778 ************************************************************/
9779
9780 bool lp_domain_master_true_or_auto(void)
9781 {
9782         if (Globals.iDomainMaster) /* auto or yes */
9783                 return true;
9784
9785         return false;
9786 }
9787
9788 /***********************************************************
9789  If we are DMB then prefer us as LMB
9790 ************************************************************/
9791
9792 bool lp_preferred_master(void)
9793 {
9794         if (Globals.iPreferredMaster == Auto)
9795                 return (lp_local_master() && lp_domain_master());
9796
9797         return (bool)Globals.iPreferredMaster;
9798 }
9799
9800 /*******************************************************************
9801  Remove a service.
9802 ********************************************************************/
9803
9804 void lp_remove_service(int snum)
9805 {
9806         ServicePtrs[snum]->valid = False;
9807         invalid_services[num_invalid_services++] = snum;
9808 }
9809
9810 /*******************************************************************
9811  Copy a service.
9812 ********************************************************************/
9813
9814 void lp_copy_service(int snum, const char *new_name)
9815 {
9816         do_section(new_name, NULL);
9817         if (snum >= 0) {
9818                 snum = lp_servicenumber(new_name);
9819                 if (snum >= 0)
9820                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9821         }
9822 }
9823
9824
9825 /*******************************************************************
9826  Get the default server type we will announce as via nmbd.
9827 ********************************************************************/
9828
9829 int lp_default_server_announce(void)
9830 {
9831         return default_server_announce;
9832 }
9833
9834 /*******************************************************************
9835  Split the announce version into major and minor numbers.
9836 ********************************************************************/
9837
9838 int lp_major_announce_version(void)
9839 {
9840         static bool got_major = False;
9841         static int major_version = DEFAULT_MAJOR_VERSION;
9842         char *vers;
9843         char *p;
9844
9845         if (got_major)
9846                 return major_version;
9847
9848         got_major = True;
9849         if ((vers = lp_announce_version()) == NULL)
9850                 return major_version;
9851
9852         if ((p = strchr_m(vers, '.')) == 0)
9853                 return major_version;
9854
9855         *p = '\0';
9856         major_version = atoi(vers);
9857         return major_version;
9858 }
9859
9860 int lp_minor_announce_version(void)
9861 {
9862         static bool got_minor = False;
9863         static int minor_version = DEFAULT_MINOR_VERSION;
9864         char *vers;
9865         char *p;
9866
9867         if (got_minor)
9868                 return minor_version;
9869
9870         got_minor = True;
9871         if ((vers = lp_announce_version()) == NULL)
9872                 return minor_version;
9873
9874         if ((p = strchr_m(vers, '.')) == 0)
9875                 return minor_version;
9876
9877         p++;
9878         minor_version = atoi(p);
9879         return minor_version;
9880 }
9881
9882 /***********************************************************
9883  Set the global name resolution order (used in smbclient).
9884 ************************************************************/
9885
9886 void lp_set_name_resolve_order(const char *new_order)
9887 {
9888         string_set(&Globals.szNameResolveOrder, new_order);
9889 }
9890
9891 const char *lp_printername(int snum)
9892 {
9893         const char *ret = _lp_printername(snum);
9894         if (ret == NULL || (ret != NULL && *ret == '\0'))
9895                 ret = lp_const_servicename(snum);
9896
9897         return ret;
9898 }
9899
9900
9901 /***********************************************************
9902  Allow daemons such as winbindd to fix their logfile name.
9903 ************************************************************/
9904
9905 void lp_set_logfile(const char *name)
9906 {
9907         string_set(&Globals.szLogFile, name);
9908         debug_set_logfile(name);
9909 }
9910
9911 /*******************************************************************
9912  Return the max print jobs per queue.
9913 ********************************************************************/
9914
9915 int lp_maxprintjobs(int snum)
9916 {
9917         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9918         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9919                 maxjobs = PRINT_MAX_JOBID - 1;
9920
9921         return maxjobs;
9922 }
9923
9924 const char *lp_printcapname(void)
9925 {
9926         if ((Globals.szPrintcapname != NULL) &&
9927             (Globals.szPrintcapname[0] != '\0'))
9928                 return Globals.szPrintcapname;
9929
9930         if (sDefault.iPrinting == PRINT_CUPS) {
9931 #ifdef HAVE_CUPS
9932                 return "cups";
9933 #else
9934                 return "lpstat";
9935 #endif
9936         }
9937
9938         if (sDefault.iPrinting == PRINT_BSD)
9939                 return "/etc/printcap";
9940
9941         return PRINTCAP_NAME;
9942 }
9943
9944 static uint32 spoolss_state;
9945
9946 bool lp_disable_spoolss( void )
9947 {
9948         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9949                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9950
9951         return spoolss_state == SVCCTL_STOPPED ? True : False;
9952 }
9953
9954 void lp_set_spoolss_state( uint32 state )
9955 {
9956         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9957
9958         spoolss_state = state;
9959 }
9960
9961 uint32 lp_get_spoolss_state( void )
9962 {
9963         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9964 }
9965
9966 /*******************************************************************
9967  Ensure we don't use sendfile if server smb signing is active.
9968 ********************************************************************/
9969
9970 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9971 {
9972         bool sign_active = false;
9973
9974         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9975         if (get_Protocol() < PROTOCOL_NT1) {
9976                 return false;
9977         }
9978         if (signing_state) {
9979                 sign_active = smb_signing_is_active(signing_state);
9980         }
9981         return (_lp_use_sendfile(snum) &&
9982                         (get_remote_arch() != RA_WIN95) &&
9983                         !sign_active);
9984 }
9985
9986 /*******************************************************************
9987  Turn off sendfile if we find the underlying OS doesn't support it.
9988 ********************************************************************/
9989
9990 void set_use_sendfile(int snum, bool val)
9991 {
9992         if (LP_SNUM_OK(snum))
9993                 ServicePtrs[snum]->bUseSendfile = val;
9994         else
9995                 sDefault.bUseSendfile = val;
9996 }
9997
9998 /*******************************************************************
9999  Turn off storing DOS attributes if this share doesn't support it.
10000 ********************************************************************/
10001
10002 void set_store_dos_attributes(int snum, bool val)
10003 {
10004         if (!LP_SNUM_OK(snum))
10005                 return;
10006         ServicePtrs[(snum)]->bStoreDosAttributes = val;
10007 }
10008
10009 void lp_set_mangling_method(const char *new_method)
10010 {
10011         string_set(&Globals.szManglingMethod, new_method);
10012 }
10013
10014 /*******************************************************************
10015  Global state for POSIX pathname processing.
10016 ********************************************************************/
10017
10018 static bool posix_pathnames;
10019
10020 bool lp_posix_pathnames(void)
10021 {
10022         return posix_pathnames;
10023 }
10024
10025 /*******************************************************************
10026  Change everything needed to ensure POSIX pathname processing (currently
10027  not much).
10028 ********************************************************************/
10029
10030 void lp_set_posix_pathnames(void)
10031 {
10032         posix_pathnames = True;
10033 }
10034
10035 /*******************************************************************
10036  Global state for POSIX lock processing - CIFS unix extensions.
10037 ********************************************************************/
10038
10039 bool posix_default_lock_was_set;
10040 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10041
10042 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10043 {
10044         if (posix_default_lock_was_set) {
10045                 return posix_cifsx_locktype;
10046         } else {
10047                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10048         }
10049 }
10050
10051 /*******************************************************************
10052 ********************************************************************/
10053
10054 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10055 {
10056         posix_default_lock_was_set = True;
10057         posix_cifsx_locktype = val;
10058 }
10059
10060 int lp_min_receive_file_size(void)
10061 {
10062         if (Globals.iminreceivefile < 0) {
10063                 return 0;
10064         }
10065         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10066 }
10067
10068 /*******************************************************************
10069  If socket address is an empty character string, it is necessary to 
10070  define it as "0.0.0.0". 
10071 ********************************************************************/
10072
10073 const char *lp_socket_address(void)
10074 {
10075         char *sock_addr = Globals.szSocketAddress;
10076
10077         if (sock_addr[0] == '\0'){
10078                 string_set(&Globals.szSocketAddress, "0.0.0.0");
10079         }
10080         return  Globals.szSocketAddress;
10081 }
10082
10083 void lp_set_passdb_backend(const char *backend)
10084 {
10085         string_set(&Globals.szPassdbBackend, backend);
10086 }
10087
10088 /*******************************************************************
10089  Safe wide links checks.
10090  This helper function always verify the validity of wide links,
10091  even after a configuration file reload.
10092 ********************************************************************/
10093
10094 static bool lp_widelinks_internal(int snum)
10095 {
10096         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10097                         sDefault.bWidelinks);
10098 }
10099
10100 void widelinks_warning(int snum)
10101 {
10102         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10103                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10104                         "These parameters are incompatible. "
10105                         "Wide links will be disabled for this share.\n",
10106                         lp_servicename(snum) ));
10107         }
10108 }
10109
10110 bool lp_widelinks(int snum)
10111 {
10112         /* wide links is always incompatible with unix extensions */
10113         if (lp_unix_extensions()) {
10114                 return false;
10115         }
10116
10117         return lp_widelinks_internal(snum);
10118 }
10119
10120 bool lp_writeraw(void)
10121 {
10122         if (lp_async_smb_echo_handler()) {
10123                 return false;
10124         }
10125         return _lp_writeraw();
10126 }
10127
10128 bool lp_readraw(void)
10129 {
10130         if (lp_async_smb_echo_handler()) {
10131                 return false;
10132         }
10133         return _lp_readraw();
10134 }