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