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